W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
目前,遠(yuǎn)程采購商品需要多方相互信任。最簡單的配置涉及賣方和買方。買方希望從賣方那里收到一件物品,而賣方希望得到金錢(或等價物)作為回報。有問題的部分是這里的貨物:無法確定該物品是否到達(dá)了買家手中。
有多種方法可以解決這個問題,但都以一種或另一種方式達(dá)不到要求。在以下示例中,雙方必須將項(xiàng)目價值的兩倍作為托管服務(wù)存入合同。一旦發(fā)生這種情況,這筆錢將被鎖定在合同中,直到買家確認(rèn)他們收到了物品。之后,買方將獲得價值(押金的一半),賣方獲得三倍的價值(押金加上價值)。這背后的想法是,雙方都有解決問題的動力,否則他們的錢將被永遠(yuǎn)鎖定。
該合約當(dāng)然不能解決問題,但概述了如何在合約中使用類似狀態(tài)機(jī)的構(gòu)造。
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.4; contract Purchase { uint public value; address payable public seller; address payable public buyer; enum State { Created, Locked, Release, Inactive } // The state variable has a default value of the first member, `State.created` State public state; modifier condition(bool condition_) { require(condition_); _; } /// Only the buyer can call this function. error OnlyBuyer(); /// Only the seller can call this function. error OnlySeller(); /// The function cannot be called at the current state. error InvalidState(); /// The provided value has to be even. error ValueNotEven(); modifier onlyBuyer() { if (msg.sender != buyer) revert OnlyBuyer(); _; } modifier onlySeller() { if (msg.sender != seller) revert OnlySeller(); _; } modifier inState(State state_) { if (state != state_) revert InvalidState(); _; } event Aborted(); event PurchaseConfirmed(); event ItemReceived(); event SellerRefunded(); // 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() payable { seller = payable(msg.sender); value = msg.value / 2; if ((2 * value) != msg.value) revert ValueNotEven(); } /// Abort the purchase and reclaim the ether. /// Can only be called by the seller before /// the contract is locked. function abort() external onlySeller inState(State.Created) { emit Aborted(); state = State.Inactive; // We use transfer here directly. It is // reentrancy-safe, because it is the // last call in this function and we // already changed the state. seller.transfer(address(this).balance); } /// Confirm the purchase as buyer. /// Transaction has to include `2 * value` ether. /// The ether will be locked until confirmReceived /// is called. function confirmPurchase() external inState(State.Created) condition(msg.value == (2 * value)) payable { emit PurchaseConfirmed(); buyer = payable(msg.sender); state = State.Locked; } /// Confirm that you (the buyer) received the item. /// This will release the locked ether. function confirmReceived() external onlyBuyer inState(State.Locked) { emit ItemReceived(); // It is important to change the state first because // otherwise, the contracts called using `send` below // can call in again here. state = State.Release; buyer.transfer(value); } /// This function refunds the seller, i.e. /// pays back the locked funds of the seller. function refundSeller() external onlySeller inState(State.Release) { emit SellerRefunded(); // It is important to change the state first because // otherwise, the contracts called using `send` below // can call in again here. state = State.Inactive; seller.transfer(3 * value); } }
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: