Created
September 4, 2019 23:09
-
-
Save alexytiger/925bcb2bf0213d40d7236b45293b7cac to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pragma solidity 0.5.11; | |
| import "./HitchensUnorderedKeySet.sol"; | |
| contract FleaMarket { | |
| using HitchensUnorderedKeySetLib for HitchensUnorderedKeySetLib.Set; | |
| HitchensUnorderedKeySetLib.Set widgetSet; | |
| struct WidgetStruct { | |
| address contractAddress; | |
| } | |
| mapping(bytes32 => WidgetStruct) widgets; | |
| string public name; | |
| address public lastContractAddress; | |
| constructor() public { | |
| name = "FleaMarket Smart Contract"; | |
| } | |
| event logNewPurchaseContract(address contractAddress); | |
| event logRemovePurchaseContract(address sender, bytes32 key); | |
| function createPurchaseContract(bytes32 key, string memory title, string memory ipfsHash) | |
| public payable returns(bool createResult) | |
| { | |
| widgetSet.insert(key); // Note that this will fail automatically if the key already exists. | |
| WidgetStruct storage w = widgets[key]; | |
| SafeRemotePurchase c = (new SafeRemotePurchase).value(msg.value)(msg.sender, key, title, ipfsHash); | |
| lastContractAddress = address(c); | |
| w.contractAddress = lastContractAddress; | |
| emit logNewPurchaseContract(lastContractAddress); | |
| return true; | |
| } | |
| function getContractCount() public view returns(uint contractCount) { | |
| return widgetSet.count(); | |
| } | |
| function getContractKeyAtIndex(uint index) public view returns(bytes32 key) { | |
| return widgetSet.keyAtIndex(index); | |
| } | |
| function getContractByKey(bytes32 key) public view returns(address contractAddress) { | |
| require(widgetSet.exists(key), "Can't get a widget that doesn't exist."); | |
| WidgetStruct storage w = widgets[key]; | |
| return(w.contractAddress); | |
| } | |
| function removeContractByKey(bytes32 key) public { | |
| // Note that this will fail automatically if the key doesn't exist | |
| widgetSet.remove(key); | |
| delete widgets[key]; | |
| emit logRemovePurchaseContract(msg.sender, key); | |
| } | |
| } | |
| contract SafeRemotePurchase { | |
| address payable public seller; | |
| address payable public buyer; | |
| uint public price; | |
| bytes32 public key; //unique string identifier | |
| string public title; | |
| string public ipfsHash; | |
| enum State { Created, Locked, Inactive } | |
| State public state; | |
| // Contract created by the seller | |
| // Ensure that `msg.value` is an even number. | |
| // Division will truncate if it is an odd number. | |
| // Check via multiplication that it wasn't an odd number. | |
| constructor( | |
| address payable _contractSeller, | |
| bytes32 _key, | |
| string memory _title, | |
| string memory _ipfxHash) public payable { | |
| seller = _contractSeller; | |
| key = _key; | |
| ipfsHash = _ipfxHash; | |
| title = _title; | |
| price = msg.value / 2; | |
| //to verify that it does not represent an empty string. | |
| require(_key[0] != 0); | |
| require(bytes(_title).length > 0); | |
| // Require a valid price | |
| require(price > 0); | |
| require((price * 2) == msg.value, "Value has to be even."); | |
| } | |
| modifier condition(bool _condition) { | |
| require(_condition, "Condition is false"); | |
| _; | |
| } | |
| modifier onlyBuyer() { | |
| require(msg.sender == buyer, "Only buyer can call this."); | |
| _; | |
| } | |
| modifier onlySeller() { | |
| require(msg.sender == seller, "Only seller can call this."); | |
| _; | |
| } | |
| modifier inState(State _state) { | |
| require(state == _state, "Invalid state."); | |
| _; | |
| } | |
| event Aborted(); | |
| event PurchaseConfirmed(); | |
| event ItemReceived(); | |
| // Confirm the purchase as buyer. | |
| // Transaction has to include `2 * value` ether. | |
| // The ether will be locked until confirmReceived | |
| // is called. | |
| function buyerConfirmPurchase() public inState(State.Created) | |
| condition(msg.value == (price * 2)) | |
| payable | |
| { | |
| emit PurchaseConfirmed(); | |
| buyer = msg.sender; | |
| state = State.Locked; | |
| } | |
| // Confirm that you (the buyer) received the item. | |
| // This will release the locked ether. | |
| function buyerConfirmReceived() public onlyBuyer | |
| inState(State.Locked) | |
| { | |
| emit ItemReceived(); | |
| state = State.Inactive; | |
| buyer.transfer(price); | |
| seller.transfer(balanceOf()); | |
| } | |
| // The seller has changed his mind and does not want to sell the item | |
| // Abort the purchase and reclaim the ether. | |
| // Can only be called by the seller if the contract is Created | |
| function abortBySeller() public onlySeller | |
| inState(State.Created) | |
| { | |
| emit Aborted(); | |
| state = State.Inactive; | |
| seller.transfer(balanceOf()); | |
| } | |
| //get balance of the contract | |
| function balanceOf() view public returns(uint){ | |
| return address(this).balance; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment