ERC721项目发行分析

从庖丁解牛说起,懂了刀法之后就要开了这头牛了。

从区块链浏览器来看看 项目方的动作以及用户的东西还是很有意思的一件事情

这里使用Legend Maps Adventurers (LMA) 这个项目,自己蛮喜欢的一个 NFT项目。是做的链上的像素地牢。

这篇文章就简单的把这个NFT 的生命周期来分析一下。

正文

正文顺序就是直接按照合约的交互顺序来进行分析。

deploy

TX:0xc6520011946abdf7577a6224a12d663556c836dbfd71d6fa4f802b3e2f186619

内容在Data字段,对应的是合约的编译后的 EVM操作码,实际上对应的就是合约。

set Base URI

TX: 0x511692fe76c4c6a325bc47edc7d464269405dd498be608e8fa0744bbf74c3c16

在这里设置 NFT 的资源的BaseURI

Function: setBaseURI(string baseURI_)

MethodID: 0x55f804b3

涉及到的函数是下面这部分

solidity
function setBaseURI(string memory baseURI_) external onlyOwner {
tokenBaseURI = baseURI;
}

设置的 baseURI 解码出来之后是 是一个 ipfs 的存储链接

  • ipfs://QmZETTY2oveA2vi7Z3op8PZLmaLTtMsCyab1WxjXWfKxdZ/

我们可以通过ipfs 的网关来进行访问

  • https://ipfs.io/ipfs/QmZETTY2oveA2vi7Z3op8PZLmaLTtMsCyab1WxjXWfKxdZ

这里项目方犯了一个错误,BASE设置错误了,所以项目方里面用下面这比交易修改

TX: 0x0379fddc8c43c35a3f7dd4403003cc44424e742f7aa0b9bf514c07702c21e1e2

Reserve

交易TX: 0x7f8962455056175e720abf68e8bd89a3ba468ec3ded33567ec9a20c239d103b7

项目方调用合约来进行批量的NFT 预留。直接safemint 50个,到Owner自己的账户下。

Function: reserve(uint256 count)

MethodID: 0x819b25ba

solidity
function reserve(uint256 count) external onlyOwner {
_safeMint(msg.sender, count);
}

Set Root

因为NFT项目有 白名单机制存在,所以这里存在白名单的存在,这里设置的是验证用的默克尔根.

TX: 0xe4bbbcb007714283b1b5f856182b92c721a2206a29eddadfc1f70436cce77bda

Function: setRoot(bytes32 _merkleRoot)

MethodID: 0xdab5f340

solidity
function setRoot(bytes32 _merkleRoot) external onlyOwner {
merkleRoot = _merkleRoot;
}

具体的白名单的验证机制可以参考前面那篇《浅析白名单校验原理》,这里就不多赘述了。

Toggle Whitelist

前面完成了Nft的前置工作,这里就需要用来打开NFT的销售了,函数体如下,对一个布尔型的变量来进行翻转。相关的函数在执行的前会对此变量进行检查。

solidity
function toggleWhitelist() external onlyOwner {
whitelistLive = !whitelistLive;
}

WitheListMint/Mint

往后就是白名单用户mint nft的过程了。Data 体如下

Function: whitelistMint(uint256 mintsRequested, uint256 maxMints, bytes32[] proof)
MethodID: 0xc4be5b59

参数如下,白名单用户用来进行NFTmint。

# Name Type Data
0 mintsRequested uint256 1
1 maxMints uint256 1
2 proof bytes32[] 0x81d11c76c7c32b2b50661fd8229ecf630931561d3d91a02f348922df10137d1d 0xc1a63c4382704770fe5934e02ff4eab858916d886a83e744ffb129eff8bcb671 0x8f59c0bfe3333c3cc061c7aa14a5b6ad084ef17aebaaea58853a9c06c2fdece4 0x5a9b150be6f0b92b8a5d43bb6b6d18f8e212775a2091dc6a5f7a10dee0bee3e7 0xa933d009bf907da72c6d80b07542ee17dfcd9c45058ee26b90e03f764be136db 0x1d820661b4757898910f649713aa65187285ded6c806e05a059a9a76e9b6c363 0xa47e08712d386837163539eeef27ec99b09ec2ef7fe7c39b8367ab8ef8127a51 0x58d35888281d8a07d7c647bc7696bc64f0a3ef2a79f1f34beb2e4845a46b3f04 0xd70c5761a2ea2911a8bd3cadd5c5ae7c1098510826489534ba038c6d1f7be75b 0xe032926596c53e7b631faa7b32fdfb28b37f396dba911a78d6e51522419c57c6 0xd6578e7e17eed4cb89d5a926006dd5ac9a9d65c5d5eb39a4c83712a08e6b99fb 0x41016b9029d6a35712918df2c4bd8632204aea1dc33b75a28c1fe2531c49a5e1

proof 这里是用户的 默克尔路径,具体的验证方式还是在《浅析白名单校验原理》这个文章里说明。目前基本上都是标准的函数。函数体如下,在里面补充备注说明

function whitelistMint(uint256 mintsRequested, uint256 maxMints, bytes32[] calldata proof) external payable {
    uint256 remainingMints = maxMints - whiteListPurchases[msg.sender];
    // 检查mint是否进行
    require(!saleLive && whitelistLive, "WHITELIST_CLOSED");
    // 检查默克尔路径
    require(_verify(_leaf(msg.sender, maxMints), proof), "UNAUTHORIZED");
    // mint逻辑
    require(totalSupply() + mintsRequested <= LMA_SUPPLY, "EXCEEDS_SUPPLY");
    require(LMA_PRICE * mintsRequested <= msg.value, "INSUFFICIENT_ETH");
    require(mintsRequested <= remainingMints, "EXCEEDS_ALLOCATION");
    require(remainingMints > 0, "MINTS_CONSUMED");
<pre><code>whiteListPurchases[msg.sender] += mintsRequested;

_safeMint(msg.sender, mintsRequested);
</code></pre>
}

function mint(uint256 mintsRequested) external payable {
    require(saleLive, "SALE_CLOSED");
    require(!whitelistLive, "WHITELIST_ONLY");
    require(LMA_PRICE * mintsRequested <= msg.value, "INSUFFICIENT_ETH");
    require(totalSupply() + mintsRequested <= LMA_SUPPLY, "EXCEEDS_SUPPLY");
        // mint 逻辑一致,去掉白名单验证逻辑
    _safeMint(msg.sender, mintsRequested);
}

ERC721 Transfer

前面的过程完成了Nft的mint 过程。后面的的话就是用户侧的操作了,主要有 approve 和 转移。

  • setApprovalForAll
  • safeTransferFrom

这里是 ERC721的标准函数,就不再这里展开分析了。

通过分析一些链上的交互来学习链上原理还是蛮不错的过程,这样可以看清楚项目的链上运作流程,还有像是看到项目方操作失误这种有意思的事件。