微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

可重用的智能合约

如何解决可重用的智能合约

我目前正在尝试开发一个简单的智能合约

相对较新,多对用户可以同时与合约交互并从托管中受益(它会为每一对实例化一个新版本吗)?

它本质上是一个托管合同,将保留交易的资金,直到买卖双方都接受了释放。此外,如果他们中的任何一个不接受资金,智能合约将在 30 天内扣留资金。 另外,如果交易成功,我如何添加最初部署智能的地址并将总存款的 3% 转移到该地址?

这是我目前尝试过的:

pragma solidity 0.7.0;

contract NewEscrow {


enum State {AWAITING_FUNDS,AWAITING_CLaim,CLaim,COMPLETE}

State public currentState; 


address payable public buyer; 
address payable public seller; 
address payable public owner; 

uint256 public agreementDay; 

mapping (address => uint256) deposits;




// checks if msg.sender is equal to buyer
modifier onlyBuyer (){
    require(msg.sender == buyer);
    _; 
}


// checks if msg.sender is equal to seller
modifier onlySeller(){
    require(msg.sender == seller);
    _; 
}


constructor (){
    owner = msg.sender; 
}


function setvariables (address payable _buyer,address payable _seller,uint256 _agreementDay) public {
    buyer = _buyer; 
    seller = _seller; 
    agreementDay = _agreementDay + 30 days; 
    currentState = State.AWAITING_FUNDS;
}



function deposit() public onlyBuyer payable {
    require(currentState == State.AWAITING_FUNDS);
    uint256 amount = msg.value;
    deposits[seller] = deposits[seller] + amount; 
    currentState = State.AWAITING_CLaim;
}


function claim () public onlySeller {
    require(currentState == State.AWAITING_CLaim);
    currentState = State.CLaim;
}


function confirm () public onlyBuyer {
    uint256 payment = deposits[seller];
    deposits[seller] = 0; 
    seller.transfer(payment); 
    currentState = State.COMPLETE;
}



function cancelPayement () public onlySeller  {
    uint256 payment = deposits[seller];
    deposits[seller] = 0; 
    buyer.transfer(payment); 
    currentState = State.COMPLETE;
}


function release() public{
    
    
        // funds cannot be retrieved before release day
        require (agreementDay < block.timestamp);
        uint256 payment = deposits[seller];
        deposits[seller] = 0; 
        buyer.transfer(payment);
        revert('funds returned');
    }
}

解决方法

  1. 可以多对用户同时与合约交互并从托管中受益

    目前没有。只有第一对用户可以使用它,因为目前 buyerseller 变量只能保存一个值。

    如果您想针对多对进行缩放,则需要制作一个表示 buyerseller 连接的结构体数组。从我的头顶看,它看起来像:

    struct Pair {
       address buyer;
       address seller;
    }
    
    Pair[] pairs;
    

    或者另一种方法,其中数组的公共索引显示 buyerseller 是连接的。

    address[] buyers;
    address[] sellers;
    

    这种缩放还意味着扩展当前的大部分逻辑以验证输入 buyerseller 是否已连接。

  2. 如果其中任何一个不接受,智能合约将扣留资金 30 天

    您需要创建一个新函数来检查存款是否已被提取以及是否是(存款日期 + 30 天)以及一些验证谁可以实际提取这笔钱。

    address constant contractOwner = '0x123'
    
    function withdrawOwner() external {
        require(msg.sender == contractOwner); // validate who can withdraw
        require(agreementDay + 30 days <= block.timestamp); // check if 30 days has passed since the deposit date
        require(deposits[seller] > 0); // check that it hasn't been withdrawn
        uint256 amount = deposits[seller]; // make sure the contract is not vulnerable to reentrancy
        deposits[seller] = 0;
        payable(contractOwner).transfer(amount); // withdraw the money
    }
    
  3. 如何添加最初部署 smart 的地址并转移总存款的 3%

    让我们展开第二点并使用 contractOwner。您需要更新 deposit 函数:

    function deposit() public onlyBuyer payable {
        require(currentState == State.AWAITING_FUNDS);
        uint256 amount = msg.value;
    
    
        // these lines calculate the fee,update the amount and send the fee to the contract owner
        // make sure you're not vulnerable to overflow
        uint256 fee = (amount / 100) * 3;
        payable(contractOwner).transfer(fee); // transfer 3% to the contract owner
        amount -= fee; // substract the fee from the amount that is going to be saved
    
    
        deposits[seller] = deposits[seller] + amount; 
        currentState = State.AWAITING_CLAIM;
    }
    

    确保您不会受到 integer overflow 的攻击。想象一个场景:

    1. 买方存款 1 wei
    2. 费用计算为 3 wei
    3. 合约有足够的 ETH,因此它将 3 wei 发送给所有者
    4. 但是 3 wei 是从 amount 中的 1 中减去的,所以结果是 2^256 - 3 而不是 -2

    如果发生下溢/上溢,Solidity 0.8+ 会自动恢复事务。如果您使用的是旧版 Solidity,则可以使用例如 OpenZeppelin 的 SafeMath 库。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。