# 通过metamask调用闭源合约教程

By [🐖 猪猪Bang](https://paragraph.com/@balcke) · 2023-08-02

---

简介
==

首先如果可以的话，感谢大家关注一下我的推特

[https://twitter.com/0xblackecn](https://twitter.com/0xblackecn)

直接合约调用有什么好处？ 举个最简单的例子，在空投发下来的时候，官网打不开页面，但是此时我们可以直接去合约里面，直接使用智能合约的调用，快人一步。

很多人都应该直接如何调用开源合约了，步骤很简单

① 打开 etherscan

② 搜索合约地址

③ 点击 Contract，点解 write Contract

④ 链接钱包，然后调用方法即可

![](https://storage.googleapis.com/papyrus_images/cd6c8178c9f62b5f4f419d273960cb16ec11c809f42161ef2e73c438771289a2.png)

但是呢，对于闭源的合约我们就不能通过这个办法去操作了，因为在闭源合约上，我们是无法直接链接钱包后进行点击操作的

所以我打算写个闭源合约的调用教程

对于闭源合约的调用，我总结下来就是： **猜参数**， 只要猜到了参数，那调用的简单了

调用流程
====

首先，对于闭源合约调用，我们有两个前提

① 知道合约地址

② 别人已经成功调用过一次

**如果没这两个前提，我们就该干嘛干嘛去，别想着去调用了**

如果有这两个前提了，我们就可以开始着手去调用智能合约了，调用的流程总结为：

① 打开 etherscan，搜索合约地址

② 找到别人的成功交易案例

③ 查看交易HEX

④ 若是不需要参数，直接用metamask进行 十六进制发送做合约交互

⑤ 若需要参数，则猜测参数的传递，并且转为 十六进制HEX发送做合约交互

**调用不需要传递参数的智能合约**

首先，我们先说 **调用不需要传递参数的智能合约** ，以一个简单的例子，就是前几天很火的 $HAMA 的空投领取

如，我们关注到推特为：@hamajing\_erc20 ，然后在他们的简介中找到了他们代币的地址为：0x86f61e980Eda9e2B5846589B4Ad6aB1eC584905D

我们模拟此时官网已经打不开，所以无法去官网claim空投，但是我们知道地址，所以开始我们的步骤

① 打开ethscan，搜索合约地址

[https://etherscan.io/address/0x86f61e980eda9e2b5846589b4ad6ab1ec584905d](https://etherscan.io/address/0x86f61e980eda9e2b5846589b4ad6ab1ec584905d)

② 由于方法有很多，所以我们可以选择性的筛选方法，点击右上角的 `advanced-filter`，然后再去点击 `method` 上方的漏斗，我们看下有没有带有 `claim` 关键字的方法，如果有的话，说明 `claim` 也是同合约，直接筛选出来即可

![](https://storage.googleapis.com/papyrus_images/c57e55227df98e142c7b33bc057d419ae877e41977a33a8858bba5790323e073.png)

![](https://storage.googleapis.com/papyrus_images/e2648262495791dd10f25114cf1936b1e1fd0813e5c863586970ec91c2d03201.png)

③ 若发现没有 `claim` 等关键字的话，可能 领取合约不是这个合约，那此时我们就需要想其他办法，如，我们看到已经有人 Approve 或 Transfer 了， 此时我们就可以点进去找到发送的地址，查看他们的币是从哪里来的

![](https://storage.googleapis.com/papyrus_images/935a33acb2869e89196196ad7db45c50bae1a89c3bae8f743c6bbf0bffaebd3b.png)

![](https://storage.googleapis.com/papyrus_images/15d5554ebee95bc425989b7c2941cad1bb06a752eec8b90e659962f369e71422.png)

![](https://storage.googleapis.com/papyrus_images/4e51830b6a25336dc576f802818f07abb6048c4918a000ffd6bfc4d4fb17f091.png)

![](https://storage.googleapis.com/papyrus_images/408b4d1c2daf863d9be6ec0208a0c8dd3fd449e48e530afae9d101cb9a4fdcca.png)

④ 最终我们可以发现，claim的合约地址和原地址不一样，claim的合约地址是：

0xf64292beEb69632Ca850525c9F80cd606C831a7a， 所以此时我们应该是跟这个合约地址进行交易

⑤ 此时我们应该去看，传递了什么参数

![](https://storage.googleapis.com/papyrus_images/f05ec43250714f1914a680f09dd53684b7e2105e9d0f84210cc40e23d7a083e9.png)

![](https://storage.googleapis.com/papyrus_images/12cae5e5ee3700f35629c6dfb94068d2d4541169cd9ace0432c778c2d26058a3.png)

![](https://storage.googleapis.com/papyrus_images/442a33e2fd5e55aa9116bbdb583f3a57ed5102076a55d5fa9eb7f87fea32c547.png)

⑥ 对于这种不需要传递参数的，最简单，我们只需要将 Original 里面的内容，全部复制，然后打开 metamask，给合约地址发送十六进制数据就行

![](https://storage.googleapis.com/papyrus_images/dcceb49b692f3c80246b1b66d4feda77a9943a6416831e6b347994f7ea15ef4d.png)

此时我们就完成了 claim 的闭源交易了，这是最简单的一种方法。

**调用需要传递参数的智能合约**

**调用需要传递参数的智能合约** 是比较麻烦的事情，并且，还不一定能调用成功，确实只能靠猜。

**首先，默认认为看到这里已经是会如何找到调用地址以及调用参数了**

然后我们开始猜参数，先简单一点，如我要调用以下这个方法

![](https://storage.googleapis.com/papyrus_images/6d3c84786af8d8c2ba81d53a251c12f65c2cf2706e320fd2647377b8a26145ba.png)

注：有的时候可能不会直接把Function给出来，而是给一个 MethodID，此时我们就这样做

打开链接：

[https://www.4byte.directory/](https://www.4byte.directory/)

搜索方法id

![](https://storage.googleapis.com/papyrus_images/9f3c1ee0fef71679698a60e00070472bfacf3dc1c95437a3540faca347f0681a.png)

然后就可以看到，大概我们需要传递什么参数了

目前我们直接 看这个方法 `Function: approve(address guy, uint256 wad)` 可以看到，需要传递两个参数， 分别是 guy (类型为address)， wad（类型为uint256）

首先我们知道我们自己为什么去调用这个方法，比如claim，我们知道是领取代币，那 guy可能是代表领取代币的地址， wad是代表领取的数量。比如当前这个approve，有可能就是给guy授权wad数量的值。

那我们这个时候怎么构造出参数呢

打开remix的链接：

[http://remix.ethereum.org/](http://remix.ethereum.org/)

然后直接最简单的创建个同方法的solidity

![](https://storage.googleapis.com/papyrus_images/424325dedab70037ad45ca3cc02bfa01e1f57fa69ee40bbc08f2e3a3f0b7f502.png)

在右侧点击 deploy 部署，记得在测试节点上部署

![](https://storage.googleapis.com/papyrus_images/829ce31c36e5a9bd870c4578b3689e3934dc129b38633e2a846623d11a5a763a.png)

部署成功后，输入完后直接复制参数即可

![](https://storage.googleapis.com/papyrus_images/22687a2437228afa22d87b282188e536e079c28c415f5e4f9b6e680e90bafc65.png)

得到的参数为：0x000000000000000000000000a1faee23f9f4a91deef42b5c01c853b2ede27db900000000000000000000000000000000000000000000000000000000000003e8

然后把原本开头的 0x，替换为 methodId 0x095ea7b3最终得到的参数结果为0x095ea7b3000000000000000000000000a1faee23f9f4a91deef42b5c01c853b2ede27db900000000000000000000000000000000000000000000000000000000000003e8

得到参数之后，此时我们就可以继续用metamask，给合约地址发送十六进制的参数了。

总结
==

对于调用闭源合约的话，局限性还是挺大的，比如有些复杂参数你是根本不知道如何传递的，比如这个

[https://twitter.com/0xblackecn/status/1686394689040285696?s=20](https://twitter.com/0xblackecn/status/1686394689040285696?s=20)

但是对于简单一点来说的话，还是挺好用的，毕竟有的时候 领空投的官网在那么多人的压力下，总会崩溃。

---

*Originally published on [🐖 猪猪Bang](https://paragraph.com/@balcke/metamask)*
