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()
        public
        onlySeller
        inState(State.Created)
    {
        emit Aborted();
        state = State.Inactive;
        seller.transfer(this.balance);
    }

    /// 买家确认购买
    /// 交易必须包含 `2 * value` 个以太币(押一付一)
    /// 以太币会被锁定,直到 confirmReceived 被调用
    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();
        // 首先修改状态很重要,否则的话,由 `transfer` 所调用的合约可以回调进这里(再次接收以太币)。
        state = State.Inactive;

        // 注意: 这实际上允许买方和卖方阻止退款 - 应该使用取回模式。
        buyer.transfer(value);
        seller.transfer(this.balance);
    }
}

文章参考
https://blog.csdn.net/qq_33829547/article/details/80377386

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值