如何解决可重用的智能合约
我目前正在尝试开发一个简单的智能合约
相对较新,多对用户可以同时与合约交互并从托管中受益(它会为每一对实例化一个新版本吗)?
它本质上是一个托管合同,将保留交易的资金,直到买卖双方都接受了释放。此外,如果他们中的任何一个不接受资金,智能合约将在 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');
}
}
解决方法
-
可以多对用户同时与合约交互并从托管中受益
目前没有。只有第一对用户可以使用它,因为目前
buyer
和seller
变量只能保存一个值。如果您想针对多对进行缩放,则需要制作一个表示
buyer
和seller
连接的结构体数组。从我的头顶看,它看起来像:struct Pair { address buyer; address seller; } Pair[] pairs;
或者另一种方法,其中数组的公共索引显示
buyer
和seller
是连接的。address[] buyers; address[] sellers;
这种缩放还意味着扩展当前的大部分逻辑以验证输入
buyer
和seller
是否已连接。 -
如果其中任何一个不接受,智能合约将扣留资金 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 }
-
如何添加最初部署 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 wei
- 费用计算为 3 wei
- 合约有足够的 ETH,因此它将 3 wei 发送给所有者
- 但是 3 wei 是从
amount
中的 1 中减去的,所以结果是2^256 - 3
而不是-2
如果发生下溢/上溢,Solidity 0.8+ 会自动恢复事务。如果您使用的是旧版 Solidity,则可以使用例如 OpenZeppelin 的 SafeMath 库。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。