BanaCat NFT Contract(2/3)

关于BanaCatNFT

BanaCat一期项目是一个部署在polygon区块链上的头像数字艺术品

项目链接:BanaCato_O - Collection | OpenSea

合约源码地址:https://polygonscan.com/address/0xd2bc5c3990c06ccd26f10a3e9d93b19450136c8d#code

同时,基于这款数字艺术品也设计了配套的表情包周边,目前已经有一款已经上架到微信表情包商城,表情包链接:香蕉猫看戏篇


“写”函数会改变合约的状态,每一笔交易都会消耗一定的gas。

因为要用自己的私钥为每一笔交易签名,所以在与合约交互之前,要先链接上自己的钱包。


approve():将单个NFT的授权给某个operator,让其可以代理NFT的拥有者进行转出操作,后面会有实例说明。

Untitled

Untitled

_tokenApprovals 是一个tokenIDoperator地址的映射表,approve()函数正是以此为依据将NFT授权给某个地址。

Untitled

Untitled


mint(): NFT铸造函数,NFT项目在宣发阶段,无论是白名单铸造还是公售阶段,都是直接或者间接调用mint()函数。币圈中“合约层铸造”就是指跳过项目方官网的铸造流程,直接在区块链浏览器或者通过本地RPC调用的方式直接与合约交互铸造NFT。特别重要的函数,这是NFT发行的起点。

第一个参数mint是指要支付的代币总量;

_mintAmount():一次性铸造NFT的数量;

根据有无白名单,铸造的单价会有不同,但是 总价 = 单价 * 数量,合约会从铸造者账户中扣除总价的代币(gas另算);

Untitled


mint()函数中会对_mintAmount的数值做合法性检测,要求_mintAmount大于0且不大于要求的单次最大铸造量maxMintAmount

同时要求本次铸造的数量_mintAmount加上已经铸造的数量totalsupply不大于合约NFT的最大供应量maxSupply

之后会对铸造者随交易发送来的代币总数不小于NFT铸造总价;

最后会用循环调用_safeMint()函数挨个给用户铸造NFT。(这种循环调用的方式很容易理解,但是单次批量铸造成本会比较高,Azuki 提出的ERC721A协议在单次批量铸造的时候会节省gas,这个我们后面再说)

Untitled

_safeMint() 函数之所以“safe”,是因为它会对铸造者的身份做审查,要是铸造者是个合约,则要求这个合约必须实现IERC721Receiver接口,关于IERC721Receiver可以参考A大的文章:

WTF Solidity极简入门 ERC721专题:1. ERC721相关库

Untitled

有一个小细节:_checkOn721Received()的第一个参数 from 在 _safeMint() 调用的时候传入的是 address(0)0x0000000000000000000000000000000000000000,意思是代表这个交NFT是从0地址发来的,后面_mint()函数里触发Transfer事件,用来记录一个NFT从from 地址转移到 to 地址,这里的 from也是*address(0),虽然所有的NFT都是从合约中铸造的,但是NFT最初的来源地址却不是合约地址,对于这一现象,我的理解是 烧掉burn()一个NFT其实就是将其发送到0地址,代表一个NFT被销毁,从此失去流动性,可能这也包含着着“从哪里来,就到哪里去”的哲理吧。*

Untitled

_mint()函数中触发事件Transfer()在区块链上生成一条日志文件

Untitled

Untitled


pause():设置是否暂停mint活动 true表示暂停,flase表示可以mint

Untitled

Untitled


renounceOwnership():项目方放弃合约的控制权,将合约的owner设置为address(0),意味着再也没有谁能控制合约,就像宇宙中的尘埃。

如果合约的余额再也无法取出。高危函数(危险等级:最高⚠︎⚠︎⚠︎⚠︎⚠︎)

Untitled

Untitled


safeTransferFrom():NFT的转移函数,将一个编号为输入tokenID的NFT从from地址转移到to地址。

Untitled

Untitled


safeTransferFrom():NFT的转移函数,将一个编号为输入tokenID的NFT从from地址转移到to地址,只不多多了一些附加性质的data,可以做一些说明性的活动(比如往区块链上写一些永久存档的文字)。

Untitled

Untitled

Untitled

名字为什么叫safeTransferFrom而不是safeTransfer?看似只是名字少了一个from,其实是涉及到代理权的问题。

ERC721合约中一共有两类角色可以将NFT转移走:一是NFT的owner,二是当前NFT的授权代理。函数名称中的“from“ 就是代表从哪个账户中将NFT转移走,很多时候转移走NFT的地址不一定是NFT的实际拥有者。我们接下来举个小例子说明这个现象。

_safeTransferFrom()使用代理转移NFT (1)

但是操作的目的是啥呢?

我个人的理解是,NFT从出生起就带有金融属性,授权操作给NFT的质押提供了可行方法,授权者可以通过质押拿到贷款,放贷机构可以拿着质押得到的NFT发行NFT衍生金融资产……NFT的应用空间远超我的想象!


setApprovalForAll():将owner地址下的所有NFT一次性授权给operator

高危函数(危险等级:⚠︎⚠︎⚠︎⚠︎)

Untitled

_operatorApprovals 是一个( ownerAddress ⇒( operatorAddress ⇒ bool))的二级映射表,setApprovalForAll()通过修改bool值来设定是否将自己的NFT全部授权给operator

Untitled

Untitled

setApprovalForAll()的实例


setBaseExtension():设置Metadata文件的扩展名,一般不用这个函数,扩展名默认为“json”

Untitled

Untitled


setBaseURI():设置NFT的BaseURI,高危函数(危险等级:⚠︎⚠︎⚠︎)一般只用作项目开图,开图之后不再使用。

Untitled

Untitled


setCost():设置公售NFT时的mint价格

Untitled

Untitled

Untitled


transferFrom():NFT的转移函数,将一个编号为输入tokenID的NFT从from地址转移到to地址。不会对to地址做风险检测,所以也不在”safe“

Untitled

Untitled


transferOwnership():将合约的归属权移交给新地址。

高危函数(危险等级:⚠︎⚠︎⚠︎⚠︎)

Untitled

Ownable.sol扩展文件中的功能函数,详情看以下链接:

openzeppelin-contracts/Ownable.sol at master · OpenZeppelin/openzeppelin-contracts

Untitled


withdraw():将合约中的余额转给合约的owner。估计绝大多数的项目方都在等这最后一下吧。

Untitled

Untitled

下一篇会介绍BanaCatNFT合约中设计的一种密码白名单机制