# 复刻 MyCoinTool

By [0xKISS](https://paragraph.com/@0xkiss) · 2022-06-06

---

写在前面
----

本文是对 [mycointool](https://mycointool.com/nft/minting) 的简单复刻、实现分析（纯后端版本）。旨在于记录作者自己的学习过程，代码开源在 [github](https://github.com/neal-zhu/mintbot.git)，后续的文章内容不会讲解具体的实现代码。

非常感谢类似 MyCoinTool 这样优秀的工具，为每一个冲图狗的勇士保驾护航。还没有使用过 MyCoinTool 的同学，也非常建议去体验一下。

拆解页面：
-----

主要组件分为两部分，其中左边的部分是按照区块展示的所有 ERC721 相关的 mint 交易，其中包括的元素有:

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

区块高度

1.  项目名称，（ERC721 name)
    
2.  交易 gas price & value
    
3.  opensea 项目相关链接
    
4.  etherscan tx 链接
    
5.  项目展示图片
    
6.  xN 代表此交易共 mint 了多少 nft
    
7.  每个交易都有一键暴富，点击此按钮，前端就会拉起小狐狸，使用对应交易参数进行重复，帮助使用者无脑冲图。这个只需要重放交易的 input 即可
    

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

右边的部分主要是对过去一段时间 mint 情况的统计

其中包含有：

1.  3m,5m,30m,1h 的 mint 情况统计
    
2.  每个项目的共有多少个独立钱包数量
    
3.  mint 次数
    
4.  etherscan contract 链接
    

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

右侧本质上是一个统计结果，可以从若干单独的 mint 交易聚合得到（即左侧数据）。所以我们主要的工作都放在对左侧数据的获取、存储上。

粗略看一眼，大概可以勾勒出一个代码框架：

1.  一个后台线程不停的轮询处理最新区块
    
2.  将区块内的所有交易进行解析
    
3.  过滤出所有 mint 交易
    
4.  解析 mint 交易相关信息（包括 mint NFT 的数量，gas price，value，input 等）
    
5.  获取合约相关的展示信息（etherscan 链接，opensea 链接，图片等）
    
6.  聚合查询（按照时间维度和区块高度）
    

架构其实非常简单，下面让我们来逐个击破一些关键问题：

什么是 mint 交易？
------------

[ERC721 标准](https://eips.ethereum.org/EIPS/eip-721) 本身并未对 mint 有任何定义，所以 mint 交易本身千奇百怪（abi 不统一，是否需要支付 ETH 也没有标准，能 mint 几个 NFT 更是除了看代码无从知晓）。好在标准在关于 event Transfer 中有明确注释：

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

除在合约创造时候的 NFT 所有权转移，其他情况下，当一个 NFT 被创造（mint） 的时候，要触发一个 event Transfer，且其 from == 0x0，有了这个我们就可以定义 mint 交易了：

1.  交易交互对象是一个 erc721 合约
    
2.  交易触发了 event Transfer & from == 0x0
    

请注意 Transfer 并不是 erc721 专属，所以我们还是需要去验证一个合约是否为 erc721 。

如何判断一个合约是 ERC721
----------------

这个主要参考的是 ethereumetl\_airflow 中的实现，通过 get\_code 获取合约字节码之后，进行反编译。通过解析反编译之后的结果，获取所有 PUSH4 对应的 selector，如果满足 ERC721 标准的接口则为 ERC721。

合约相关信息的获取
---------

打图狗，我们只挑开源的！（这里所谓的开源其实是指在 etherscan 上 verify 合约这一过程。请区别于区块链的公开透明）。

我们主要通过 [etherscan 的 contract api](https://docs.etherscan.io/api-endpoints/contracts) 来验证一个合约是否开源。

同时我们需要借助 [opensea contract API](https://docs.opensea.io/reference/retrieving-a-single-contract) 来获取某个合约对应的 opensea 相关信息（包括 opensea 链接，项目图片，项目主页（非必需））。

注意，上述两家的服务均需要申请 API\_KEY，且免费版均有限速问题。

警惕 mint to
----------

一个潜在的坑是所谓的 mint to 交易。即 nft 最终转移的钱包，并不是交易的发起者。这种情况如果没有进行识别并且特殊处理，则会导致交易重放的结果是使用者将 NFT mint 到了其他钱包。

这一个行为主要是根据 event Transfer 中的接受者（to）与调用发起者是一个人来判断。如果不是一个人，那么需要对 input 进行修改，将其中指定的地址参数替换为发起者的地址。

数据保存
----

其实大多数程序的质量在数据结构确定的时候，已经确定下来了，把这个最重要的部分放在最后写实属不该。

处于性能和灵活考虑，代码中选择使用 redis 作为数据存储工具。

数据主要包括两部分：

1.  合约信息。这个就是一个简单的从合约地址到相关信息的映射。value 中包含有 opensea 链接、展示图片 url，合约 name 等信息
    
2.  mint 交易集合。这个选择使用 redis zset 存储，同时将 tx 对应的 timestamp 作为 entry score。这样设计，可以很容易的实现页面中右侧按照过去 3m,5m,30m,1h 进行统计的需求

---

*Originally published on [0xKISS](https://paragraph.com/@0xkiss/mycointool)*
