# 简单科普Ethereum的Transaction Input Data-十六进制Mint解释

By [Xing](https://paragraph.com/@xing824) · 2022-04-08

---

早上起来发现好多朋友又薅到了[@WomenUniteNFT](https://twitter.com/WomenUniteNFT)的毛，[**LaserCat397.eth**](https://twitter.com/BitCloutCat) 给大家还做了简单的[视频教学](https://twitter.com/BitCloutCat/status/1512064817422802947)，教大家如何在metamask里用十六进制数据直接调用合约。

![Metamask中通过输入十六进制数据去调用合约](https://storage.googleapis.com/papyrus_images/d721f2e7f9aec8582cddd85de9706b0dbb1482412d7d06eef4cf4fb55490e9ab.png)

Metamask中通过输入十六进制数据去调用合约

所以这里就跟大家分享一下十六进制数据调用合约背后的原理，希望对大家有所帮助。

Transaction主要字段
===============

大家知道每次和以太坊网络交互，不管是直接转账还是调用合约其实都是向以太坊网络发起了一笔Transaction，这个Transaction通过Metamask签名并发送至以太坊节点后，以太坊的矿工就会执行这笔transaction。

Transaction中有以下几个比较重要的字段：

*   from：代表谁发起的这笔Transaction，一般是你的钱包地址
    
*   to：向谁发送。如果是转账，to就是你要转账的目标钱包地址；如果这笔交易是调用合约，to就是要调用的合约地址
    
*   value：发送多少ETH
    
*   Input Data：输入数据。如果是转账，Input Data就是0x为空，不用传入，因为“from”、“to”和“value”字段已经可以确定这笔交易由“谁”，转“多少ETH”，到“谁”去了；但如果这笔交易是调用合约，Input Data中就需要包括你所需要调用合约所需的所有信息，例如合约方法、参数（上述截图中的十六进制数据，所输入的其实就是Input Data）
    

以这笔WomenUniteNFT的Mint[交易](https://etherscan.io/tx/0x64c55a520934460ef87a1bd5f0e86c837babae86897ddf285ae4dc2feafa166d)为例，tx=0x64c55a520934460ef87a1bd5f0e86c837babae86897ddf285ae4dc2feafa166d， 可以看到from是mint这哥们的钱包，to是WomenUniteNFT合约地址，value是0，代表没花钱（但有gas），data就是他传入的十六进制的数据。

![该笔Transaction的具体数据结构](https://storage.googleapis.com/papyrus_images/1d73d6067d4aa13fcbcf35c91cdb9636d0e06a40ab45e2f862113e47c9a349a9.png)

该笔Transaction的具体数据结构

昨天推特上的朋友通过[反编译代码](https://etherscan.io/bytecode-decompiler?a=0xBEE7Cb80DFD21a9eAAe714208F361601F68eB746)，找到了WomenUniteNFT合约中“def mint(uint256 \_wad) payable:”方法有漏洞，因此只要调用此方法并传入需要mint的数量，就可以免费mint到输入数量的NFT。

下面就聊聊如何拼凑出这十六进制的Input Data去调用合约。

Input Data解析
============

还是以上面这笔交易的Input Data “0xa0712d6800000000000000000000000000000000000000000000000000000000000000fa”为例。

### 方法标识

首先合约中有漏洞的方法是“def mint(uint256 \_wad) payable:”，用keccak256算出”mint(uint256)”的哈希值的十六进制，同时取前八位就能得到Input Data的方法名标识“a0712d68”了。（注意计算的哈希只需要是函数名+参数类型）

![计算“def mint(uint256 _wad) payable:”的方法标识](https://storage.googleapis.com/papyrus_images/22fa9cbb7ee985611d3ffe65aa6c813d0c10313e9199e15eb4a5d2262c383d16.png)

计算“def mint(uint256 \_wad) payable:”的方法标识

### 方法参数

方法标识确认之后，就需要传入mint数量，如果需要一次mint 250个，那传入250的十六进制“fa”。

![250的十进制转换为十六进制](https://storage.googleapis.com/papyrus_images/8371f4f087abed018af790b882ed27ffaf206683b8e150d00508037baab00f2c.png)

250的十进制转换为十六进制

上述mint方法中的参数是uint256类型的，在拼入参的时候需要占用对应位数，uint256类型的参数如果换成16进制的话总共需要64位，所以将“fa”补0到64位即为“00000000000000000000000000000000000000000000000000000000000000fa”。

### 拼凑得到Input Data

这时与之前算好的方法名标识“a0712d68”拼一块，就可以得到“a0712d6800000000000000000000000000000000000000000000000000000000000000fa”的Input Data数据了，与上面Mint的这笔[交易](https://etherscan.io/tx/0x64c55a520934460ef87a1bd5f0e86c837babae86897ddf285ae4dc2feafa166d)的Input Data相同。（如果有多个参数，按照参数类型的长度接着后面继续拼就行）

将此Input Data数据在Metamask给合约地址转账时输入，以太坊矿工节点就知道执行该合约的哪个方法以及传入什么样参数了。

最后
==

大家如果还是不太理解的话，就在Etherscan上多对比下合约以及transaction的InputData，实际上都可以自己算出来。

最后祝大家之后遇到这样机会的时候能够抓住啦～

---

*Originally published on [Xing](https://paragraph.com/@xing824/ethereum-transaction-input-data-mint)*
