Solidity远程购买示例学习笔记

该示例中买家支付并确认交易后,交易进入锁定状态,待买家确认收货后,交易完成,合约将退回押金给买家和转账交易金额给卖家。其中在不同的交易环节过程中会触发不同的事件发生。

与中心化交易相比,由于失去了类似某宝的中间人角色,需要在交易中添加对买卖双方的保障:

  • 对于买方而已,在支付交易金额后,交易会进入锁定状态,交易金额会被冻结,只有在买家确认满意收货后,卖方才会收到货款;
  • 对于卖方而已,买方需要在支付交易金额的同时多支付一倍的押金,俗称“买一押一”,同时卖方可以根据情况在交易锁定前提出取消交易。


pragma solidity ^0.4.21;//定义变量:押金、卖家、买家、交易状态
contract Purchase {uint public value;address public seller;address public buyer;enum State { Created, Locked, Inactive }State public state;//押金方式设置为"押一付一",即对应value = msg.value / 2//确保 `msg.value` 是一个偶数。如果它是一个奇数,则它将被截断function Purchase() public payable {seller = msg.sender;value = msg.value / 2;require((2 * value) == msg.value);}//定义函数修饰符//条件状态、购买者确认、售卖者确认、交易状态确认modifier condition(bool _condition) {require(_condition);_;}modifier onlyBuyer() {require(msg.sender == buyer);_;}modifier onlySeller() {require(msg.sender == seller);_;}modifier inState(State _state) {require(state == _state);_;}//定义事件//取消交易、确认交易、确认收货event Aborted();event PurchaseConfirmed();event ItemReceived();///取消交易并回收以太币///只能在合约被锁定之前由卖家调用function abort()publiconlySellerinState(State.Created){emit Aborted();state = State.Inactive;seller.transfer(this.balance);}/// 买家确认购买/// 交易必须包含 `2 * value` 个以太币(押一付一)/// 以太币会被锁定,直到 confirmReceived 被调用function confirmPurchase()publicinState(State.Created)condition(msg.value == (2 * value))payable{emit PurchaseConfirmed();buyer = msg.sender;state = State.Locked;}/// 买家确认已经收到商品/// 退回买家押金/// 发送货款给卖家function confirmReceived()publiconlyBuyerinState(State.Locked){emit ItemReceived();// 首先修改状态很重要,否则的话,由 `transfer` 所调用的合约可以回调进这里(再次接收以太币)。state = State.Inactive;// 注意: 这实际上允许买方和卖方阻止退款 - 应该使用取回模式。buyer.transfer(value);seller.transfer(this.balance);}
}

文章参考