区块链学习之叁
损耗送:纵欲也是修行的一种,水木之气先行;
ethernaut - Gatekeeper Two
description
1 | // This gatekeeper introduces a few new challenges. Register as an entrant to pass this level. |
source
1 | // SPDX-License-Identifier: MIT |
直接看gateTwo()
;
乍一看gateOne()
与gateTwo()
好像冲突,因为gateOne()
要求用第三方合约调用函数,而gateTwo()
要求caller()
(等价于msg.sender
)没有代码;
只有不存在的合约和钱包合约是没有代码的;
然而,在合约构造函数执行过程中,caller()
是还没有被部署到目标 block 上的,此时调用extcodesize(caller())
就可以得到0
,因此可以在构造函数中调用enter()
成功绕过gateTwo()
;
再看gateThree()
,一个异或,能 pass 的_gatekey
值应当是:
1 | uint64(bytes8(keccak256(abi.encodePacked(msg.sender)))) ^ type(uint64).max |
题解
attack contract
1 | // SPDX-License-Identifier: MIT |
部署即可;
ethernaut - Naught Coin
description
1 | // NaughtCoin is an ERC20 token and you're already holding all of them. The catch is that you'll only be able to transfer them after a 10 year lockout period. Can you figure out how to get them out to another address so that you can transfer them freely? Complete this level by getting your token balance to 0. |
source
1 | // SPDX-License-Identifier: MIT |
用 ERC20 标准定义了以上合约;
lockTokens()
这个 modifer 决定自合约被部署的开始往后十年内,transfer
函数对 player
禁用;
查看 ERC20 ,发现可以用另外一个函数transferFrom()
进行转账操作,看一下这个函数有哪些限制:
part of ERC20 source
1 | function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { |
所以可以先用player
调approve()
把所有额度给第三个合约,然后再用第三方合约调transferFrom()
把balance()
悉数转出去;
题解
approve
1 | // 注意这个控制台操作传字符串,大数 js 处理不动 |
attack contract (0x142bB6fE56436bcB1DA7788AceB35b34899ea3C2)
1 | // SPDX-License-Identifier: MIT |
莫
只肖数日便忘掉了人生的所有伤痛,就好像它们未曾来过。