本文是对 mycointool 的简单复刻、实现分析(纯后端版本)。旨在于记录作者自己的学习过程,代码开源在 github,后续的文章内容不会讲解具体的实现代码。
非常感谢类似 MyCoinTool 这样优秀的工具,为每一个冲图狗的勇士保驾护航。还没有使用过 MyCoinTool 的同学,也非常建议去体验一下。
主要组件分为两部分,其中左边的部分是按照区块展示的所有 ERC721 相关的 mint 交易,其中包括的元素有:

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

右边的部分主要是对过去一段时间 mint 情况的统计
其中包含有:
3m,5m,30m,1h 的 mint 情况统计
每个项目的共有多少个独立钱包数量
mint 次数
etherscan contract 链接

右侧本质上是一个统计结果,可以从若干单独的 mint 交易聚合得到(即左侧数据)。所以我们主要的工作都放在对左侧数据的获取、存储上。
粗略看一眼,大概可以勾勒出一个代码框架:
一个后台线程不停的轮询处理最新区块
将区块内的所有交易进行解析
过滤出所有 mint 交易
解析 mint 交易相关信息(包括 mint NFT 的数量,gas price,value,input 等)
获取合约相关的展示信息(etherscan 链接,opensea 链接,图片等)
聚合查询(按照时间维度和区块高度)
架构其实非常简单,下面让我们来逐个击破一些关键问题:
ERC721 标准 本身并未对 mint 有任何定义,所以 mint 交易本身千奇百怪(abi 不统一,是否需要支付 ETH 也没有标准,能 mint 几个 NFT 更是除了看代码无从知晓)。好在标准在关于 event Transfer 中有明确注释:

除在合约创造时候的 NFT 所有权转移,其他情况下,当一个 NFT 被创造(mint) 的时候,要触发一个 event Transfer,且其 from == 0x0,有了这个我们就可以定义 mint 交易了:
交易交互对象是一个 erc721 合约
交易触发了 event Transfer & from == 0x0
请注意 Transfer 并不是 erc721 专属,所以我们还是需要去验证一个合约是否为 erc721 。
这个主要参考的是 ethereumetl_airflow 中的实现,通过 get_code 获取合约字节码之后,进行反编译。通过解析反编译之后的结果,获取所有 PUSH4 对应的 selector,如果满足 ERC721 标准的接口则为 ERC721。
打图狗,我们只挑开源的!(这里所谓的开源其实是指在 etherscan 上 verify 合约这一过程。请区别于区块链的公开透明)。
我们主要通过 etherscan 的 contract api 来验证一个合约是否开源。
同时我们需要借助 opensea contract API 来获取某个合约对应的 opensea 相关信息(包括 opensea 链接,项目图片,项目主页(非必需))。
注意,上述两家的服务均需要申请 API_KEY,且免费版均有限速问题。
一个潜在的坑是所谓的 mint to 交易。即 nft 最终转移的钱包,并不是交易的发起者。这种情况如果没有进行识别并且特殊处理,则会导致交易重放的结果是使用者将 NFT mint 到了其他钱包。
这一个行为主要是根据 event Transfer 中的接受者(to)与调用发起者是一个人来判断。如果不是一个人,那么需要对 input 进行修改,将其中指定的地址参数替换为发起者的地址。
其实大多数程序的质量在数据结构确定的时候,已经确定下来了,把这个最重要的部分放在最后写实属不该。
处于性能和灵活考虑,代码中选择使用 redis 作为数据存储工具。
数据主要包括两部分:
合约信息。这个就是一个简单的从合约地址到相关信息的映射。value 中包含有 opensea 链接、展示图片 url,合约 name 等信息
mint 交易集合。这个选择使用 redis zset 存储,同时将 tx 对应的 timestamp 作为 entry score。这样设计,可以很容易的实现页面中右侧按照过去 3m,5m,30m,1h 进行统计的需求
