# NFT购买过程详细分析以及科学家如何抢购NFT

By [iamcatcher](https://paragraph.com/@iamcatcher) · 2022-01-23

---

本文基于自己近期的学习以及和群友讨论总结，作为一个记录，最后是自己对NFT行业现状一点思考，刚接触区块链和以太坊编程难免有错误，欢迎大家指正和交流。

NFT购买过程
-------

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

简单来说购买过程就是你的钱包和NFT 合约进行交互，从你的钱包转账0.176ETH到合约，调用合约mint方法后，生成两个NFT代币，代币转移到你的钱包，你获得这个NFT。

关于NFT合约的内容可以参考以下文章：

[https://mirror.xyz/0x8eC46A6d1AFda45f5A334Fe85016FB39D9D8Caee/O3hpbibMf9vLNz6p80YUriU8Bf3bEaJWvRL49FGAgAc](https://mirror.xyz/0x8eC46A6d1AFda45f5A334Fe85016FB39D9D8Caee/O3hpbibMf9vLNz6p80YUriU8Bf3bEaJWvRL49FGAgAc)

NFT购买过程详解
---------

将你从项目方的官方网站上点击mint按钮，从浏览器到以太网网络端到端交互过程详细打开：

![NFT购买过程](https://storage.googleapis.com/papyrus_images/d54b06b3dd379ca4d5870ed2d899dfd38f543d6b20bee1f22363dc7f63a5a992.png)

NFT购买过程

**1、点击Mint按钮**

大家登陆项目网站，Chrome上连接自己的钱包，然后点击mint按钮。网页上的JavaScript代码基于项目的mint价格，合约地址等生成raw transaction数据，主要包含以下几个关键字段

    nonce: nonce, 
    gasLimit: "21000",
    maxFeePerGas: "300",
    maxPriorityFeePerGas: "10",
    to: "0x198478f870d97d62d640368d111b979d7ca3c38f", 
    value: "176000000000000000", 
    data: "0xa0712d680000000000000000000000
    000000000000000000000000000000000000000002"
    

*   `gasLimit` – 交易可以消耗的 Gas 的最大数量。单位gwei
    
*   `to` – 接收地址（这里是NFT的合约地址，交易将执行合约代码）
    
*   `nonce` – 用于跟踪账户已执行的交易总数
    
*   `value` – 从转账 ETH 的金额 （以 WEI 为单位，这里为0.176 ETH购买NFT）
    
*   `data` – 和合约交互，调度mint函数，mint数量2个
    
        Function: mint(uint256 tokenQuantity)
        MethodID: 0xa0712d68
        [0]:  00000000000000000000000000000
        00000000000000000000000000000000002
        
    
*   `maxPriorityFeePerGas` - 作为矿工小费包含的最大 gas 数量
    
*   `maxFeePerGas` - 愿意为交易支付的最大 gas 数量
    

**2、TX签名**

网页代码与Metamask交互，会弹出窗口让你确认本次交易。点击确认后，Metamask会使用你的钱包私钥进行签名，以确保这个交易是你本身授权的，后续以太坊网络会进行校验。

**3、发送TX到node验证**

交易TX被Metamask发送到Metamask的以太坊node（默认配置），node对TX进行校验，确保交易不被仿冒。

**4、广播TX到以太坊网络**

交易TX被发送到以太坊网络的相邻节点，然后再相互广播到相邻接点。这时你的交易就可以在[etherscan.io](https://etherscan.io/)上查看到，状态是pending状态。

**5、矿工node接收到TX**

矿工node会将同步过来的tx都放到一个叫Txpool/Mempool地方，这个地方是很多事情的关键，需要展开来讲一下：

![Txpool代码流程（借用以太坊源码分析之txpool的图）](https://storage.googleapis.com/papyrus_images/d3ed8480a7197f0f9dfc2dad800adafdbdae252039ff0cd960a9f617cab5e928.jpg)

Txpool代码流程（借用以太坊源码分析之txpool的图）

`Txpool`的数据来源主要来自： **_本地提交_**，也就是第三方应用通过调用本地以太坊节点的`RPC`服务所提交的交易； **_远程同步_**，是指通过广播同步的形式，将其他以太坊节点的交易数据同步至本地节点;

Txpool中分了Queue和Pending两个队列，首先新收到TX会基于规则判断后先放到Queue这个队列，然后再添加Pending队列等待挖矿加入新增的块。 **主要规则如下：** 1）优先处理Gasprice高的TX 2）本地TX优先处理，过于远程同步 3）每个节点会设置最低Gasprice，低于这个值的远程TX会被丢弃 Pending中的TX，被`Miner`模块获取并验证，用于挖矿；挖矿成功后写进区块并被广播。`Miner`取走交易是复制，Txpool中的TX并不减少。TX被写进链后才从`Txpool`删除。 Gas过低的TX，会被一直卡在Txpool得不到处理，需要可以提高Gas让它被处理。

详细代码分析可以参考[死磕以太坊源码分析之txpool](https://github.com/blockchainGuide/blockchainguide/blob/main/source_code_analysis/ethereum/%E4%BB%A5%E5%A4%AA%E5%9D%8A%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/%E6%AD%BB%E7%A3%95%E4%BB%A5%E5%A4%AA%E5%9D%8A%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E4%B9%8Btxpool-12.md)

`GasWar`：发生热门交易时，大家为了自己的TX可以被优先处理，争相提升Gas费的场景

**6、矿工出块TX被打包**

矿工选取TX后开始挖矿，再找到一个区块的Solution后广播到以太坊网络。

**7、出块被验证**

在其他矿工节点验证后，该区块正式上链，这事我们TX结果可以在[etherscan.io](https://etherscan.io/)上查看到。

**8、TX状态同步**

相关状态返回本地，可以在Metamask上查询到。

**参考文档：**

[Life Cycle of an Ethereum Transaction](https://medium.com/blockchannel/life-cycle-of-an-ethereum-transaction-e5c66bae0f6e) [Transaction lifecycle on the Ethereum blockchain](https://medium.com/@roberto.g.infante/transaction-life-cycle-on-the-ethereum-blockchain-b0d92fa73fb1) [The Influence Factors on Ethereum Transaction Fees](https://hal.inria.fr/hal-02403098/document)

### 合约是如何被执行的

简单说我们发送的交易会被转换成一个Message对象传入EVM，而EVM则会根据Message生成一个Contract对象以便后续执行。基于我们转入的Data转为合约的input调用mint函数。

详细看EVM介绍参考如下文档：

[https://learnblockchain.cn/2019/04/09/easy-evm](https://learnblockchain.cn/2019/04/09/easy-evm)

NFT预售与公开销售
----------

预售只是针对特定用户才能购买，公开销售就是大家都可以抢购。 这里主要需要回答两个技术问题： 1、如何限制特定钱包才能mint？ 2、预售和公开销售之间是如何状态切换的？

### 白名单机制

白名单现在普遍使用默克尔树来实现，简单来说将所有白名单钱包地址作为默克尔树的叶子节点，生成一个Root hash。在合约中只需要存储Root hash值，在调用mint函数时网页的JS代码基于钱包地址生成proof（地址的上级父节点hash），合约就可以校验该地址是否属于白名单。

以C01的合约为例：[0x6fd053bff10512d743fa36c859e49351a4920df6](https://etherscan.io/address/0x6fd053bff10512d743fa36c859e49351a4920df6#code)

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

在预售和公开销售时通过 SetRoot更新hash（C01两次销售都采用白名单方式，公开销售采取验资抽奖的方式）

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

详细原理和代码参考下面文章：

[https://medium.com/@ItsCuzzo/using-merkle-trees-for-nft-whitelists-523b58ada3f9](https://medium.com/@ItsCuzzo/using-merkle-trees-for-nft-whitelists-523b58ada3f9)

### 销售状态切换

常用两种方式：1）通过在合约判断时间点，比如2022-01-01 18:00 UTC开始公开销售2）通过状态判断，及在合约设置状态变量，比如以XRC的合约为例，判断Status.PublicSale状态，这个是调用合约中SetStatus进行设置。

![](https://storage.googleapis.com/papyrus_images/112ace2dc662bae511db33dc3ef0d4b933e749b3c80b1b4f6cb003bf44fd1522.jpg)

科学家如何抢够NFT
----------

科学家使用程序抢购NFT，就是使用各种手段使自己的交易TX可以先于别人被矿工打包，在售罄前完成NFT mint。同时科学家都是追求完美的，最完美的结果当然是自己的TX出现在第一个满足公开销售状态的区块里，也就是**抢Block0**。

两种场景的Block0如下图，同时做到Block0还可以避免后续大家抢购发生的Gaswar，减少抢购成本。但现在越来越卷，Block0也会发生Gaswar，比如XRC公开销售不到200个，进入Block0的科学家TX数>200，也有不少因为Gas给低了执行靠后没有抢到。

![两种场景下的Block0](https://storage.googleapis.com/papyrus_images/adf94351b44dbe20432b9c054ab82cb4e2e8d109ae78bd4c6641c30d4144dcd6.png)

两种场景下的Block0

科学家用的手段总结大概以下三点： **1、信息获取时延更低**

类似金融量化交易，基金都是期望自己的服务器和交易所通信的时延更低。区块链也是类似，比如CEX大家都会就近接入中心化交易所的服务器。NFT mint和DeFi的交易发生在以太坊网络中，大家追求的更快的以太坊Node或者接入大矿池的网络，更快监控到Txpool的pending TX，获取需要的信息让程序及时执行。

**2、交易走的路径更短**

1）、直接看了上面的TX交互过程，科学家的选择肯定直接通过程序和NFT的合约进行交互。 2）、通过在链上部署自己的合约，通过私有合约和NFT合约交互。虽然私有合约需要外部TX触发，但合约可以批量化购买，特别适合不限制mint数量的NFT。（现在越来越多的NFT限制调用方是合约）

**3、批量提交交易**

除了上面提到通过私有合约mint之外，如果项目限制了每个地址的mint个数，可以通过Flashbots打包多个TX一起提交。

### 合约mint

一个合约抢购的例子，YOKAI公开发售后。科学家利用私有合约，一共抢购了mint750个。详细见[TX](https://etherscan.io/tx/0xc7bcba3c1b0bd313a7c16cf3c383373730d9a50de1359908920f56bbecd33cd2) 。 YOKAI合约代码，没有限制一个地址可以mint多少个，只限制一次tx只能mint 2个。所以被科学家包场了。

![](https://storage.googleapis.com/papyrus_images/8f4e1adf34942f429a5f52d6de1c3caa62dc96e2aaf453dda8543f16f150f6e6.jpg)

### 神器Flashbots

Flashbots详解见伟总这篇精彩介绍和官方文档

[https://mirror.xyz/dfarm.eth/tYE\_xzUJSaP2N\_NElM0gpOmzZonb75EdC4QTiu0FK1M](https://mirror.xyz/dfarm.eth/tYE_xzUJSaP2N_NElM0gpOmzZonb75EdC4QTiu0FK1M)

使用Flashbots的有几点好处：

1）可以批量打包TX一起提交，可以自主控制打包TX的先后顺序。2）Flashbots提交的TX不会出现在Txpool，出现在链上之后才会被大家看到。这样就提供了TX的隐秘性，所以很多DeFi量化交易平台宣传自己接入Flashbots。（个人认为这只是暂时的，随着Flashbots广泛使用，Flashbots提交的TX还是会被监控） 3）通过Flashbots mint失败了不会被收Gas费

Flashbots抢购我们以冷兔XRC的公售为例：

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

易老板发推说公售不会科学家公售，但结果是在[block=14020984](https://etherscan.io/txs?block=14020984&p=10) Block0解决战斗，全部科学家包场。

项目方发送的setStatus TX在14020982时在TXpool被监听到

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

然后有科学家把setStatus TX和自己的mint tx一起用flashbots打包了，发送给矿工。这里科学家把setStatus TX放到了第一，虽然它Gas低，将自己的mint tx排在后面，最终tx在984块入链。

Flashbots打包[查询链接](https://flashbots-explorer.marto.lol/?block=14020984)

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

### 烧区块

简单说就是一直不停的发tx，发得多mint成功的概率就大，撞大运还可能会挤进Block0。这个方案问题在于会很消耗Gas费，属于有钱任性的玩法。烧区块一般考虑开始时间，每次Tx间隔，发送次数，gas费用等，这个一般都是大家根据项目时间，监控pending tx，链上出块速度等考虑。

冷兔公售抢购时就有大量科学家使用烧区块的方式抢购成功，可考察这个[钱包](https://etherscan.io/address/0x3fe2ad9d4744f5007dc4cfae1e5dede3e4066b69)

如何防科学家
------

随着科学家抢购的出现，越来越多的项目开始用各种办法防科学家抢购，这些方法的本质都是限制科学家直接调用合约mint，让项目方选定的人才能mint

**1、只通过白名单方式发售**

项目发售全部使用白名单机制，这样项目方通过规则筛选出认为是真正欣赏项目的人。

但有规则就有对策，等级+邀请人数，就出现了聊天机器人和工作室养号卖邀请人头；创作艺术就出现淘宝找人代画；现在发展到限时邀请进Discord；让大家猜谜做任务等各种玩法。

项目方是绞尽脑汁和刷白名单的工作室斗智斗勇，普通NFT玩家也被各种规则耍得团团转。

**2、公售采用验资抽奖方式**

如NFT公售时，提前验证钱包需要一定金额的ETH，然后通过系统抽奖给出中奖名单。但很多项目方为了省事不愿意做一个1:1的抽奖系统，最后公售名单大幅超售，最后还是大家抢购。

**3、在服务端签名验证mint**

类似最近火热的HAPE的做法，公开的NFT合约限制只能一个私有的闭源的合约才能mint。闭源合约后项目方后台服务器交互， 这个方案从技术上来说还是走web2中心化思路和web3去中心化的理念好像有点冲突。

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

NFT未来如何发展
---------

肝过白名单人都觉得现在NFT行业很不健康，但NFT行业还在早期，有问题就有市场肯定会有人出来解决问题。

NFT发售需要公开公证透明，个人觉得解决的思路还是可以借鉴现实生活的大家熟悉的两个场景：

1、新股发售，交易所进行账户交易时长、验资等门槛，然后摇号抽奖发售。

2、京东茅台抢购，京东平台进行账户认证、抢购公平性保证等

这两个场景都是通过平台的权威性来保证公平，但在web3应该会有基于区块链合约的新方案来实现类似的功能，就像现在DeFi市场的各种交易协议，不久将来可能会出现NFT发售协议，提供一种公平公证透明的发售模式。具体怎么做我还在学习思考中，也欢迎大家指导讨论。

未来应该是NFT项目方接入一个NFT发射平台，项目方更专注于艺术创作和路线图的演进，投资者更专注于项目的内容和前景，而发射平台通过技术解决现在NFT发售的各种问题。

---

*Originally published on [iamcatcher](https://paragraph.com/@iamcatcher/nft-nft)*
