科普|NFT铸造及购买过程技术详解,科学家是如何抢购NFT的?
作者:@iamcatcher
本文基于自己近期的学习以及和群友讨论总结,作为一个记录,最后是自己对 NFT 行业现状一点思考,刚接触区块链和以太坊编程难免有错误,欢迎大家指正和交流。
NFT 购买过程
简单来说购买过程就是你的钱包和 NFT 合约进行交互,从你的钱包转账 0.176ETH 到合约,调用合约 mint 方法后,生成两个 NFT 代币,代币转移到你的钱包,你获得这个 NFT。
关于 NFT 合约的内容可以参考以下文章:NFT 及 OpenSea 交易背后的技术分享—Mirror
NFT 购买过程详解
将你从项目方的官方网站上点击 mint 按钮,从浏览器到以太网网络端到端交互过程详细打开:
NFT 购买过程
1、点击 Mint 按钮
大家登陆项目网站,Chrome 上连接自己的钱包,然后点击 mint 按钮。网页上的 JavaScript 代码基于项目的 mint 价格,合约地址等生成 raw transaction 数据,主要包含以下几个关键字段
2、TX 签名
网页代码与 Metamask 交互,会弹出窗口让你确认本次交易。点击确认后,Metamask 会使用你的钱包私钥进行签名,以确保这个交易是你本身授权的,后续以太坊网络会进行校验。
3、发送 TX 到 node 验证
交易 TX 被 Metamask 发送到 Metamask 的以太坊 node(默认配置),node 对 TX 进行校验,确保交易不被仿冒。
4、广播 TX 到以太坊网络
交易 TX 被发送到以太坊网络的相邻节点,然后再相互广播到相邻接点。这时你的交易就可以在 etherscan.io 上查看到,状态是 pending 状态。
5、矿工 node 接收到 TX
矿工 node 会将同步过来的 tx 都放到一个叫 Txpool/Mempool 地方,这个地方是很多事情的关键,需要展开来讲一下:
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
GasWar:发生热门交易时,大家为了自己的 TX 可以被优先处理,争相提升 Gas 费的场景
6、矿工出块 TX 被打包
矿工选取 TX 后开始挖矿,再找到一个区块的 Solution 后广播到以太坊网络。
7、出块被验证
在其他矿工节点验证后,该区块正式上链,这事我们 TX 结果可以在 etherscan.io 上查看到。
8、TX 状态同步
相关状态返回本地,可以在 Metamask 上查询到。
参考文档:
Life Cycle of an Ethereum Transaction
Transaction lifecycle on the Ethereum blockchain
The Influence Factors on Ethereum Transaction Fees
合约是如何被执行的
简单说我们发送的交易会被转换成一个 Message 对象传入 EVM,而 EVM 则会根据 Message 生成一个 Contract 对象以便后续执行。基于我们转入的 Data 转为合约的 input 调用 mint 函数。
详细看 EVM 介绍参考如下文档:
easy-evm
learnblockchain.cn
NFT 预售与公开销售
预售只是针对特定用户才能购买,公开销售就是大家都可以抢购。
这里主要需要回答两个技术问题:
1、如何限制特定钱包才能 mint?
2、预售和公开销售之间是如何状态切换的?
白名单机制
白名单现在普遍使用默克尔树来实现,简单来说将所有白名单钱包地址作为默克尔树的叶子节点,生成一个 Root hash。在合约中只需要存储 Root hash 值,在调用 mint 函数时网页的 JS 代码基于钱包地址生成 proof(地址的上级父节点 hash),合约就可以校验该地址是否属于白名单。
以 C01 的合约为例:
0x6fd053bff10512d743fa36c859e49351a4920df6
在预售和公开销售时通过 SetRoot 更新 hash(C01 两次销售都采用白名单方式,公开销售采取验资抽奖的方式)
详细原理和代码参考下面文章:Using Merkle Trees for NFT Whitelists
销售状态切换
常用两种方式:
1)通过在合约判断时间点,比如 2022-01-01 18:00 UTC 开始公开销售
2)通过状态判断,及在合约设置状态变量,比如以 XRC 的合约为例,判断 Status.PublicSale 状态,这个是调用合约中 SetStatus 进行设置。
科学家如何抢够 NFT
科学家使用程序抢购 NFT,就是使用各种手段使自己的交易 TX 可以先于别人被矿工打包,在售罄前完成 NFT mint。同时科学家都是追求完美的,最完美的结果当然是自己的 TX 出现在第一个满足公开销售状态的区块里,也就是抢 Block0。
两种场景的 Block0 如下图,同时做到 Block0 还可以避免后续大家抢购发生的 Gaswar,减少抢购成本。但现在越来越卷,Block0 也会发生 Gaswar,比如 XRC 公开销售不到 200 个,进入 Block0 的科学家 TX 数>200,也有不少因为 Gas 给低了执行靠后没有抢到。
两种场景下的 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。
YOKAI 合约代码,没有限制一个地址可以 mint 多少个,只限制一次 tx 只能 mint 2 个。所以被科学家包场了。
神器 Flashbots
Flashbots 详解见伟总这篇精彩介绍和官方文档:Flashbots:如何从没有 ETH 的钱包取出资产或交互合约—Mirror
使用 Flashbots 的有几点好处:
1)可以批量打包 TX 一起提交,可以自主控制打包 TX 的先后顺序。
2)Flashbots 提交的 TX 不会出现在 Txpool,出现在链上之后才会被大家看到。这样就提供了 TX 的隐秘性,所以很多 DeFi 量化交易平台宣传自己接入 Flashbots。(个人认为这只是暂时的,随着 Flashbots 广泛使用,Flashbots 提交的 TX 还是会被监控)
3)通过 Flashbots mint 失败了不会被收 Gas 费
Flashbots 抢购我们以冷兔 XRC 的公售为例:
易老板发推说公售不会科学家公售,但结果是在 block=14020984 Block0 解决战斗,全部科学家包场。
项目方发送的 setStatus TX 在 14020982 时在 TXpool 被监听到
然后有科学家把 setStatus TX 和自己的 mint tx 一起用 flashbots 打包了,发送给矿工。这里科学家把 setStatus TX 放到了第一,虽然它 Gas 低,将自己的 mint tx 排在后面,最终 tx 在 984 块入链。
Flashbots 打包查询链接
烧区块
简单说就是一直不停的发 tx,发得多 mint 成功的概率就大,撞大运还可能会挤进 Block0。这个方案问题在于会很消耗 Gas 费,属于有钱任性的玩法。烧区块一般考虑开始时间,每次 Tx 间隔,发送次数,gas 费用等,这个一般都是大家根据项目时间,监控 pending tx,链上出块速度等考虑。
冷兔公售抢购时就有大量科学家使用烧区块的方式抢购成功,可考察这个钱包
如何防科学家
随着科学家抢购的出现,越来越多的项目开始用各种办法防科学家抢购,这些方法的本质都是限制科学家直接调用合约 mint,让项目方选定的人才能 mint
1、只通过白名单方式发售
项目发售全部使用白名单机制,这样项目方通过规则筛选出认为是真正欣赏项目的人。
但有规则就有对策,等级+邀请人数,就出现了聊天机器人和工作室养号卖邀请人头;创作艺术就出现淘宝找人代画;现在发展到限时邀请进 Discord;让大家猜谜做任务等各种玩法。
项目方是绞尽脑汁和刷白名单的工作室斗智斗勇,普通 NFT 玩家也被各种规则耍得团团转。
2、公售采用验资抽奖方式
如 NFT 公售时,提前验证钱包需要一定金额的 ETH,然后通过系统抽奖给出中奖名单。但很多项目方为了省事不愿意做一个 1:1 的抽奖系统,最后公售名单大幅超售,最后还是大家抢购。
3、在服务端签名验证 mint
类似最近火热的 HAPE 的做法,公开的 NFT 合约限制只能一个私有的闭源的合约才能 mint。闭源合约后项目方后台服务器交互,这个方案从技术上来说还是走 web2 中心化思路和 web3 去中心化的理念好像有点冲突。
NFT 未来如何发展
肝过白名单人都觉得现在 NFT 行业很不健康,但 NFT 行业还在早期,有问题就有市场肯定会有人出来解决问题。
NFT 发售需要公开公证透明,个人觉得解决的思路还是可以借鉴现实生活的大家熟悉的两个场景:
1、新股发售,交易所进行账户交易时长、验资等门槛,然后摇号抽奖发售。
2、京东茅台抢购,京东平台进行账户认证、抢购公平性保证等
这两个场景都是通过平台的权威性来保证公平,但在 web3 应该会有基于区块链合约的新方案来实现类似的功能,就像现在 DeFi 市场的各种交易协议,不久将来可能会出现 NFT 发售协议,提供一种公平公证透明的发售模式。具体怎么做我还在学习思考中,也欢迎大家指导讨论。
未来应该是 NFT 项目方接入一个 NFT 发射平台,项目方更专注于艺术创作和路线图的演进,投资者更专注于项目的内容和前景,而发射平台通过技术解决现在 NFT 发售的各种问题。