美文网首页
ETH 005 无第三方担保的买卖订单

ETH 005 无第三方担保的买卖订单

作者: 三文鱼的一生 | 来源:发表于2018-12-02 18:49 被阅读0次

5.1 介绍

我们试图使用以太坊来实现一个没有第三方担保的买卖合同。

5.2 实现

//声明使用的SOLIDITY 版本号
pragma solidity >=0.4.22 <0.6.0;

//购买合同 
contract Purchase {
    // 商品价格
    uint public value;  
    //卖方
    address payable public seller;
     //卖方
    address payable public buyer;

    //声明一个商品状态的枚举:创建,锁定,已处理
    enum State { Created, Locked, Inactive }
    
    //当前合同商品的状态
    State public state;

   //构造函数payable  表示在部署这个合约的时候 可以发送以太币
    constructor() public payable { 
        //创建合约的人就是卖方
        seller = msg.sender;
        //msg.value 表示创建合约的时候,卖方压得以太币数量。 押金必须是价格的双倍,且是偶数。
        value = msg.value / 2;
        require((2 * value) == msg.value, "Value has to be even.");
    }
    
//modifier  是以太坊的关键字,你可以理解为过滤器,其可以用来修饰函数。
    modifier condition(bool _condition) {
        require(_condition);
        _; // 表示继续执行
    }

//只能是买方调用
    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 (事件) 的以太坊的关键字,他其实是以logs日记的形式记录信息。
    event Aborted();
    event PurchaseConfirmed();
    event ItemReceived();

    /// 赎回操作。卖方可以撤回押金,改变商品状态为已经处理。
   // 该函数 会触发两个拦截器 onlySeller  inState 
    function abort()  public  onlySeller  inState(State.Created)
    {   
       //调用事件。log日记中记录了一个Aborted 行为。
        emit Aborted();
        state = State.Inactive;
        seller.transfer(address(this).balance);
    }

    /// 下单。  condition过滤器声明 下单金额必须是商品的两倍价格
    function confirmPurchase()
        public
        inState(State.Created)
        condition(msg.value == (2 * value))
        payable
    {
        emit PurchaseConfirmed();
        buyer = msg.sender;
       //改变商品的状态为锁定中
        state = State.Locked;
    }

    /// 点击已收货
    function confirmReceived()
        public
        onlyBuyer
        inState(State.Locked)
    {
        emit ItemReceived();
        
        state = State.Inactive;

        //将 买方的押金 退回
        buyer.transfer(value); 
       //剩余的资金退回卖方账号。
        seller.transfer(address(this).balance);
    }
}

5.3 思考

大家可以去思考下 在去中心化的以太坊网络中,该应用是如何实现的无担保。

5.4 transfer / send 两个函数

transfer 和 send 在功能上并没有什么区别,只是对于错误发生的时候处理方式不同。
send 在转账失败的时候回返回 boolean 而 transfer 会直接终止合约的执行。 某种意义上来说 transfer 就是加了事务。

因此在使用send有一些风险:如果调用栈深度超过1024或是gas不够,所有的转让操作都会失败,为了更安全的以太币转移,如果用send就必须每次都要检查返回值,使用transfer方法会更好;

相关文章

网友评论

      本文标题:ETH 005 无第三方担保的买卖订单

      本文链接:https://www.haomeiwen.com/subject/vqojcqtx.html