早上起来发现好多朋友又薅到了@WomenUniteNFT的毛,LaserCat397.eth 给大家还做了简单的视频教学,教大家如何在metamask里用十六进制数据直接调用合约。
所以这里就跟大家分享一下十六进制数据调用合约背后的原理,希望对大家有所帮助。
大家知道每次和以太坊网络交互,不管是直接转账还是调用合约其实都是向以太坊网络发起了一笔Transaction,这个Transaction通过Metamask签名并发送至以太坊节点后,以太坊的矿工就会执行这笔transaction。
Transaction中有以下几个比较重要的字段:
以这笔WomenUniteNFT的Mint交易为例,tx=0x64c55a520934460ef87a1bd5f0e86c837babae86897ddf285ae4dc2feafa166d, 可以看到from是mint这哥们的钱包,to是WomenUniteNFT合约地址,value是0,代表没花钱(但有gas),data就是他传入的十六进制的数据。
昨天推特上的朋友通过反编译代码,找到了WomenUniteNFT合约中“def mint(uint256 _wad) payable:”方法有漏洞,因此只要调用此方法并传入需要mint的数量,就可以免费mint到输入数量的NFT。
下面就聊聊如何拼凑出这十六进制的Input Data去调用合约。
还是以上面这笔交易的Input Data “0xa0712d6800000000000000000000000000000000000000000000000000000000000000fa”为例。
首先合约中有漏洞的方法是“def mint(uint256 _wad) payable:”,用keccak256算出”mint(uint256)”的哈希值的十六进制,同时取前八位就能得到Input Data的方法名标识“a0712d68”了。(注意计算的哈希只需要是函数名+参数类型)
方法标识确认之后,就需要传入mint数量,如果需要一次mint 250个,那传入250的十六进制“fa”。
上述mint方法中的参数是uint256类型的,在拼入参的时候需要占用对应位数,uint256类型的参数如果换成16进制的话总共需要64位,所以将“fa”补0到64位即为“00000000000000000000000000000000000000000000000000000000000000fa”。
这时与之前算好的方法名标识“a0712d68”拼一块,就可以得到“a0712d6800000000000000000000000000000000000000000000000000000000000000fa”的Input Data数据了,与上面Mint的这笔交易的Input Data相同。(如果有多个参数,按照参数类型的长度接着后面继续拼就行)
将此Input Data数据在Metamask给合约地址转账时输入,以太坊矿工节点就知道执行该合约的哪个方法以及传入什么样参数了。
大家如果还是不太理解的话,就在Etherscan上多对比下合约以及transaction的InputData,实际上都可以自己算出来。
最后祝大家之后遇到这样机会的时候能够抓住啦~