我目前正在尝试写两个聪明的合同。以下是第一个:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Token {
mapping(address => uint) public userBalances;
function buy() public payable {
require(msg.value > 0, "Not enough coins sent");
userBalances[msg.sender] += msg.value;
}
function withdrawBalance() public {
uint amountToWithdraw = userBalances[msg.sender];
// contains reentrancy attack vector here
(bool success, ) = msg.sender.call{value: amountToWithdraw}("");
require(success);
userBalances[msg.sender] = 0;
}
}第二个例子是:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "./Token.sol";
contract Attacker {
Token public tokenContract;
constructor(Token tokenContract) {
tokenContract = tokenContract;
}
function buy() public payable {
tokenContract.buy{ value: msg.value }();
}
}攻击者应通过合同转发以太,以购买一些令牌。然而,当调用攻击者契约的buy函数时,我遇到了问题。
这就是我在混音中得到的错误信息。
transact to Attacker.buy errored: VM error: revert.
revert
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.我不知道这里出了什么问题。有人知道吗?
发布于 2022-01-24 10:00:09
我告诉你出了什么问题:屏幕前的开发(facepalm)
攻击者契约的构造函数中的参数使用tokenContract作为名称。这将隐藏状态变量,从而导致问题。在这里,更正的代码:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "./Token.sol";
contract Attacker {
Token public tokenContract;
constructor(Token _token) {
tokenContract = _token;
}
function buy() public payable {
tokenContract.buy{ value: msg.value }();
}
}https://ethereum.stackexchange.com/questions/119555
复制相似问题