Domina la redacción de compras online DAPP

El proceso general del contrato
Primero, el vendedor implementa el contrato de la mercancía, declara la dirección de su cuenta, el precio de la mercancía y el tiempo de entrega prometido.
El comprador despliega el contrato de pedido a través del contrato de mercancía (tenga en cuenta que el remitente del mensaje del contrato de pedido es la dirección del contrato de mercancía) y paga el precio de la mercancía p + depósito p. El comprador espera a que el vendedor acepte la orden. Durante este período, el comprador puede cancelar la compra y reembolsar 2p.
Si el vendedor acepta el pedido, debe pagar un depósito por valor de p y, al mismo tiempo, debe entregar la mercancía dentro del tiempo de entrega prometido. Si el pedido es rechazado, el contrato devuelve el dinero al comprador.
Si el vendedor no entrega los productos dentro del tiempo prometido, el comprador puede llamar a checkLate para devolver el depósito. Al mismo tiempo, como penalización, el depósito del vendedor no se recuperará (¿quizás haya una forma de recuperarlo?) .
Cuando el vendedor confirma la entrega, debe completar el número de hoja de ruta (logística). Para verificar el número de pedido, la empresa de logística debe acceder a Ethereum y proporcionar una interfaz. Esto no se simula aquí y la verificación se omite. directamente. Del mismo modo, el proceso de firma también es perezoso y omitido.
Luego, el comprador confirma el recibo. Para evitar una no confirmación maliciosa o que el comprador se olvide de confirmar, el vendedor puede confirmar por sí mismo 10 días después de la firma.
Finalmente, el comprador evalúa el pedido. El contrato no implementa funciones como la devolución.

`pragma solidity^0.4.22;
// 商品合约
contract Product {
    
    
    bool public enable;         // 当前商品是否有效
    address public sellerAddr;  // 卖家的地址
    uint public price;          // 商品的单价
    uint public commitTime;     // 卖家承诺发货时间
    address[] public orders;    // 所有订单的地址
    address public lastOrder;   // 最新订单的地址
    modifier onlySeller() {
    
    
        require(
            sellerAddr == msg.sender,
            "卖家账号地址错误!"
        );
        _;
    }
    constructor(bool _enable, uint _price, uint _commitTime)
        public
    {
    
    
        require(
            _price != 0 && _commitTime != 0,
            "参数信息不完整"
        );
        sellerAddr = msg.sender;
        enable = _enable;
        price = _price;
        commitTime = _commitTime;}
    function setEnable(bool _enable)
        public
        onlySeller
    {
    
    
        enable = _enable;
    }
    function setPrice(uint _price)
        public
        onlySeller
    {
    
    
        price = _price;
    }
    function setCommitTime(uint _commitTime)
        public
        onlySeller
    {
    
    
        commitTime = _commitTime;
    }
    function getOrderCount()
        public
        view
        returns(uint _count)
    {
    
    
        return orders.length;
    }
    // 买家创建订单,输入购买数量和两倍原价的msg.value
    event NewOrder(address _orderAddr);
    function newOrder(uint amount)
        public
        payable
    {
    
    
        require(
            enable == true,
            "产品当前无法下单"
        );
        require(
            amount != 0,
            "购买数量不能为0"
        );
        Order order = (new Order).value(msg.value)(msg.sender, sellerAddr, price * amount, commitTime);
        orders.push(order);
        lastOrder = order;
        emit NewOrder(order);
    }
}
// 订单合约
contract Order {
    
    
    // 已支付,已接单,已发货,已签收,已收货,已失效
    enum Status {
    
    
        Paid, Taken, Shipped, Signed, Received, Inactive
    }
    address public buyerAddr;      // 买家的地址
    address public sellerAddr;     // 卖家的地址
    uint public price;             // 商品的总价
    uint public commitTime;        // 卖家承诺发货时间
    Status public status;          // 订单的状态
    uint public createTime;        // 订单的创建(支付)时间
    uint public signTime;          // 订单的签收时间
    string public trackingNumber;  // 订单的物流号
    uint8 public score;            // 订单的评分
    string public assession;       // 订单的评价
    modifier inStatus(Status _status) {
    
    
        require(
            status == _status,
            "订单的状态不可操作"
        );
        _;
    }
    modifier onlyBuyer() {
    
    
        require(
            buyerAddr == msg.sender,
            "买家账号地址错误!"
        );
        _;
    }
    modifier onlySeller() {
    
    
        require(
            sellerAddr == msg.sender,
            "卖家账号地址错误!"
        );
        _;
    }
    function getBalance()
        public
        view
        returns(uint _balance)
    {
    
    
        return address(this).balance;
    }
    constructor(address _buyerAddr, address _sellerAddr, uint _price, uint _commitTime)
        public
        payable
    {
    
    
        require(
            msg.value == _price * 2,
            "买家需要额外支付与商品价格等价的金额作为押金"
        );
        buyerAddr = _buyerAddr;
        sellerAddr = _sellerAddr;
        price = _price;
        commitTime = _commitTime;
        status = Status.Paid;
        createTime = now;
    }
    // 卖家接单之前用户可以取消购买
    function abort()
        public
        onlyBuyer
        payable
        inStatus(Status.Paid)
    {
    
    
        status = Status.Inactive;
        buyerAddr.transfer(price * 2);
    }
    // 卖家选择接单或拒绝接单
    function take(bool _takeOrder)
        public
        onlySeller
        payable
        inStatus(Status.Paid)
    {
    
    
        if (_takeOrder) {
    
    
            require(
                msg.value == price,
                "卖家需要支付与商品价格等价的金额作为押金"
            );
            status = Status.Taken;
        }
        else {
    
    
            status = Status.Inactive;
            buyerAddr.transfer(price * 2);
        }
    }

    // 买家检查卖家是否没按时发货,如果是则退还买家钱,同时作为惩罚,卖家的押金被锁定在合约里了
    function checkLate()
        public
        onlyBuyer
        inStatus(Status.Taken)
    {
    
    
        require(
            now - createTime > commitTime,
            "尚未到卖家发货截止期限"
        );
        status = Status.Inactive;
        buyerAddr.transfer(price * 2);
    }
    // 卖家输入运单号,确认发货
    function ship(string _trackingNumber)
        public
        onlySeller
        payable
        inStatus(Status.Taken)
    {
    
    
        // todo: 检查运单号是否真实存在
        status = Status.Shipped;
        trackingNumber = _trackingNumber;
        sellerAddr.transfer(price); // 卖家发货后退回押金
    }
    // 确认签收
    function sign()
        public
        inStatus(Status.Shipped)
    {
    
    
        // todo: 通过运单号查询物流信息,判断是否签收并获取签收时间
        status = Status.Signed;
        // signTime = getSignTime();
        signTime = now; // 测试用
    }
    // 买家确认收货
    function receive()
        public
        onlyBuyer
        payable
        inStatus(Status.Signed)
    {
    
    
        status = Status.Received;
        buyerAddr.transfer(price);
        sellerAddr.transfer(price);
    }
    // 过了10天买家没确认收货,则卖家可以自己确认
    function confirmBySeller()
        public
        onlySeller
        payable
        inStatus(Status.Signed)
    {
    
    
        require(
            now - signTime > 10 days,
            "卖家超过10天才可以确认"
        );
        status = Status.Received;
        buyerAddr.transfer(price);
        sellerAddr.transfer(price);
    }
    // 买家对订单进行评价
    function assess(uint8 _score, string _assession)
        public
        onlyBuyer
        inStatus(Status.Received)
    {
    
    
        require(
            _score >= 1 && _score <= 5,
            "评分只能是1~5之间的整数"
        );
        score = _score;
        assession = _assession;
        status = Status.Inactive;
    }
}

Demostración:
1) La compra y venta de mercancías requiere dos partes, por lo que hemos construido dos contratos.
2) Primero, el vendedor despliega el contrato de commodities y establece si está disponible para la compra, el precio y el tiempo de envío. (Si se puede vender se representa con 0 y 1)
inserte la descripción de la imagen aquí

3) Después de implementar el contrato, el vendedor puede modificar el precio, ya sea para comprar o vender y el tiempo de envío a través de las funciones setPrice, setEnable y setCommitTime.
inserte la descripción de la imagen aquí

4) El comprador despliega el contrato, y la dirección, el precio y la hora del comprador y del vendedor deben ingresarse antes del despliegue. Tenga en cuenta que la cantidad que es el doble del precio del producto se completa en el valor.inserte la descripción de la imagen aquí

5) El vendedor puede usar la función de tomar para juzgar si se venden todos los productos. Aquí, la cantidad de la mercancía equivalente debe ingresarse en el valor como depósito.
inserte la descripción de la imagen aquí

6) Después de vender el producto, el comprador puede usar la función checkLate para verificar si la entrega no llega a tiempo. Si es así, se reembolsará el dinero del comprador. Al mismo tiempo, como penalización, el depósito del vendedor se bloquea en el contrato
inserte la descripción de la imagen aquí

7) El vendedor ingresa el número de hoja de ruta a través de la función de envío para confirmar la entrega
inserte la descripción de la imagen aquí

8) Después de que el comprador reciba los productos, firme por ellos a través de la función de firma.
inserte la descripción de la imagen aquí

9) El comprador confirma la recepción a través de la función de recepción.
inserte la descripción de la imagen aquí

10) Los compradores usan la función de evaluación para calificar y evaluar.
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/mlynb/article/details/127816821
Recomendado
Clasificación