案例, 货物买卖合约

Par @Martin dans le
Tags :

    这是 2015 年以太坊开发者大会上的案例, 一个很简单的货物买卖合约, 大致需求如下:

    有一个人 (seller) 想要将某个商品 (commodity) 卖给另一个人 (buyer), 通过智能合约怎么实现?

    1. 当产生买卖需求时, 由 seller 创建合约, 并向其充值 2x commodity price 作为保证金;
      a. 如果卖家恶意违约, 保证金将补偿给 buyer
      b. 如果交易取消, 保证金将全额退还给 seller
    2. buyer 也需要向合约支付 2x commodity price, 其中 1x 是要支付给卖家的, 另 1x 是保证金
      a. 如果买家恶意违约, 保证金将补偿给 seller
      b. 如果交易取消, 保证金将全额退还给 buyer
    3. 现在合约里有 4x commodity price, buyer 收到商品
      a. 如果 buyer 满意交易, 确认收货, 1x 的保证金将退还给 buyer, 3x 将退还给 seller
      b. 如果 buyer 不满意交易, 发起退货流程
      i. buyer 发起退货
      ii. seller 收到商品, 确认退货, 2x 退还给 buyer, 2x 退还给 seller

    遗留问题:
    - 如果 buyer 迟迟不确认收货, 超过一定时间后, 应该自动完成收货程式.
    - 如果 buyer/seller 卖家有人报有恶意怎么办? 例如 buyer 损坏商品后还想要退货怎么办?

    pragma solidity ^0.4.11;
    
    contract ElectronicBusiness {
      uint price;  // 商品价格
      address seller;  // 卖家
      address buyer;  // 买家
      enum CommodityState { Created, Locked }  // 商品状态
      CommodityState commodityState;
      event aborted(string);
    
      function ElectronicBusiness() payable {
        seller = msg.sender;  // 由卖家创建合约
        price = msg.value / 2;  // 卖家需要支付 2x 的商品价格, 所以要除 2 才是原价
        commodityState = CommodityState.Created;
      }
    
      // 卖家放弃交易
      function abort() {
        if(msg.sender == seller && commodityState == CommodityState.Created) {
          // seller.transfer(this.balance);  // 返回当前合约全部余额
          aborted("交易放弃");
          selfdestruct(seller); // 销毁合约 + 转移金额?
          }
        }
    
        // 买家购买商品
        function buy() payable {
          if(commodityState == CommodityState.Created) {
            if(msg.value != 2 * price) {  // 买家必须支付 2 倍商品价格
              throw;
            }
            buyer = msg.sender;
            commodityState = CommodityState.Locked;  // 买家支付成功, 锁定商品
          }
        }
    
        // 买家完成交易
        function confirmTransaction {
          if(msg.sender == buyer && commodityState == CommodityState.Locked) {
            buyer.transfer(price);  // 返回 1x
            seller.transfer(this.balance);  // 返回剩余金额
            // 这里没有用 selfdestruct, 是为了保留交易信息
          }
        }
    }
    


    案例参考: 以太坊开发者大会.pdf