pragma solidity ^0.4.24; // // Purchase Conract // contract Purchase { // Storage Listing public listingContract; // listing that is being purchased uint24 public start; // Slot when we begin uint24 public end; // Slot when we end Purchase public nextPurchase; // Next purchase in time (linked list) // ...all the other Purchase stuff. Price, Stage, etc... /// Constructor constructor( Listing _listingContract, uint24 _start, uint24 _end, Purchase _nextPurchase // Purchase that comes next in time (non-overlapping) ) public { require(_start < _end, "End must be after start"); listingContract = _listingContract; start = _start; end = _end; nextPurchase = _nextPurchase; } /// Setter for nextPurchase function setNext(Purchase _newNext) public { require(msg.sender == address(listingContract), "Only Listing can call setNext()"); nextPurchase = _newNext; } } // // Listing Conract // contract Listing { // // Storage // // Purchases Ordered Linked List Purchase public headPurchase; // Head of linked list Purchase public currentPurchase; // First purchase not completely in past NYI // ... all the other usual Listing stuff. IPFS hash, etc... // // Functions // /// Buy a listing /// Note: For first one, set _afterPurchase = 0x0000000000000000000000000000000000000000 function buyListing(uint24 _start, uint24 _end, Purchase _afterPurchase) public { // *Verify we're inserting with no overlap* require( (_afterPurchase == address(0x00) && headPurchase == address(0x00)) || // Inserting at head or... (_start > _afterPurchase.end()), // Starts after previous purchase end "New purchase must start after _afterPurchase's end" ); require( (_afterPurchase == address(0x00)) || // Inserting at head or... (_afterPurchase.nextPurchase() == address(0x00)) || // Inserting at tail or... (_end < _afterPurchase.nextPurchase().start()), // Ends before purchase to come next "New purchase must end before _afterPurchase.next's start" ); // Create the purchase Purchase newPurchase = new Purchase( this, _start, _end, (_afterPurchase == address(0x00) ? Purchase(0x00) : // Insert at head _afterPurchase.nextPurchase()) // Normal insert ); // Connect to list if (_afterPurchase == address(0x00)) { headPurchase = newPurchase; // Inserting at head } else { _afterPurchase.setNext(newPurchase); // Inserting after another } } /// Old-fashioned plain insert. Left for completeness. /// @param _newPurchase The new purchase to be inserted /// @param _afterPurchase Insert new purchase after this one function insert(Purchase _newPurchase, Purchase _afterPurchase) public { if (_afterPurchase == address(0x00) && headPurchase == address(0x00)) { // Special case: Very first insert headPurchase = _newPurchase; return; } // Verify we're inserting in right place with no overlap require( _newPurchase.start() > _afterPurchase.end(), "New node must start after after_node's end"); require( _newPurchase.end() < _afterPurchase.nextPurchase().start(), "New node must end before after_node.next's start"); // Insert into list _newPurchase.setNext(_afterPurchase.nextPurchase()); _afterPurchase.setNext(_newPurchase); } }
0.4.24