简而言之,如果一个区块的交易信息被改变,那么该区块体、区块的哈希值也将被改变,该区块之后区块的哈希值也将被改变。如果想让后面的区块还能连接到它后面所有的区块必须全部同时修改,否则被改之后的区块就全部脱离了区块链。
区块链最重要的功能,就是建立一种价值共识,而这个“共识”,主要基于“价值量化的能力”和“价值安全的过程”两个方面。先是“价值量化能力”:把一件事通过数字化的方式描述清楚,就是一个价值量化的过程。
其次是“价值安全的过程”:通过数字化的方式描述清楚后,还要保护数据不被篡改,并可以随时随地地查询。,这两个方面叠加起来,就形成了价值共识。所以,区块链在数据互通机制、信用体系的搭建上,必将发挥非常重要的作用。
常规实现中,Transfer定义如下:
event Transfer(address indexed _from,address indexed _to,uint256 indexed _tokenId);
1
来自EIP-721标准原文
我们可以看到此事件抛出了3个topic,但事实上Transfer作为事件名称也需要占用一个topic,所以此处使用了log4操作码。
此操作码需要的变量如下:
offset抛出内容位于内存的起始位置
size抛出内容的长度(与offset参数共同使用)
topic1抛出的的变量
topic2
topic3
topic4
补充函数
在ERC721A的实现中,开发者提供了一些其他的mint函数实现,这些实现的主体逻辑与_mint类似,但提供了一些特别的功能或者符合一些特定的ERC标准。
我们首先分析_mintERC2309函数,此函数根据ERC 2309标准编写。在介绍函数具体实现前,我们简单介绍一下ERC 2309的具体内容。
ERC 2309主要解决在大规模铸造和代币转账过程中释放过多event的问题。如在标准_mint函数实现中,我们在最后使用了while循环以逐一释放事件。这显然是低效的,且无法用于大规模代币铸造。
为解决这一问题,ERC 2309的开发者设计了一个新的事件:
event ConsecutiveTransfer(uint256 indexed fromTokenId,uint256 toTokenId,address indexed fromAddress,address indexed toAddress);
基于此事件,我们可以一次性释放所有代币转移的事件,大大降低了gas消耗。
对于_mintERC2309具体实现,与_mint基本一致,除了增加了以下代码:
ERC2309最大转移量检查
if(quantity>_MAX_MINT_ERC2309_QUANTITY_LIMIT)_revert(MintERC2309QuantityExceedsLimit.selector);
用于判断单次转移量是否超过5000
ConsecutiveTransfer事件抛出
emit ConsecutiveTransfer(startTokenId,startTokenId+quantity-1,address(0),to);
由于使用了solidity语法编写,所以此处也减少了大量安全性代码编写(如上文的address到uint256转化等)。
另一个实现mint功能的函数是_safeMint函数,此函数会判断NFT接收地址to的属性,以避免NFT接受方不具有接受NFT的能力。
unchecked{
if(to.code.length!=0){
uint256 end=_currentIndex;
uint256 index=end-quantity;
do{
if(!_checkContractOnERC721Received(address(0),to,index++,_data)){
_revert(TransferToNonERC721ReceiverImplementer.selector);
}
}while(index<end);
//Reentrancy protection.
if(_currentIndex!=end)_revert(bytes4(0));
}
}