📅  最后修改于: 2020-11-04 04:28:08             🧑  作者: Mango
提款方式可确保不会进行直接转接呼叫,这会构成安全威胁。以下合同显示不安全地使用转移电话发送以太币。
pragma solidity ^0.5.0;
contract Test {
address payable public richest;
uint public mostSent;
constructor() public payable {
richest = msg.sender;
mostSent = msg.value;
}
function becomeRichest() public payable returns (bool) {
if (msg.value > mostSent) {
// Insecure practice
richest.transfer(msg.value);
richest = msg.sender;
mostSent = msg.value;
return true;
} else {
return false;
}
}
}
通过使最丰富的合同成为后备函数失败的合同,可以使上述合同处于无法使用的状态。当后备函数失败时,beginRichest()函数也会失败,并且合同将永远卡住。为了减轻这个问题,我们可以使用提款方式。
在提款方式中,我们将在每次转帐之前重置待处理金额。这将确保只有主叫方合同失败。
pragma solidity ^0.5.0;
contract Test {
address public richest;
uint public mostSent;
mapping (address => uint) pendingWithdrawals;
constructor() public payable {
richest = msg.sender;
mostSent = msg.value;
}
function becomeRichest() public payable returns (bool) {
if (msg.value > mostSent) {
pendingWithdrawals[richest] += msg.value;
richest = msg.sender;
mostSent = msg.value;
return true;
} else {
return false;
}
}
function withdraw() public {
uint amount = pendingWithdrawals[msg.sender];
pendingWithdrawals[msg.sender] = 0;
msg.sender.transfer(amount);
}
}