數(shù)字藏品系統(tǒng)開(kāi)發(fā)(NFT數(shù)字藏品)詳細(xì)及分析丨NFT數(shù)字藏品系統(tǒng)開(kāi)發(fā)(數(shù)字藏品源碼)
數(shù)字藏品其實(shí)是NFT的一種應(yīng)用形式,即使用區(qū)塊鏈技術(shù),對(duì)應(yīng)特定的作品、藝術(shù)品生成的唯一數(shù)字憑證,在保護(hù)其數(shù)字版權(quán)的基礎(chǔ)上,實(shí)現(xiàn)真實(shí)可信的數(shù)字化發(fā)行、購(gòu)買(mǎi)、收藏和使用。
各數(shù)藏平臺(tái)一般將數(shù)字藏品定義為:一種限量發(fā)行的虛擬文化商品,包括但不限于數(shù)字畫(huà)作、圖片、音樂(lè)、視頻、3D模型等各種形式,它使用區(qū)塊鏈技術(shù)記錄其鏈上確權(quán)、發(fā)行、購(gòu)買(mǎi)、使用等流程。每一份數(shù)字藏品對(duì)應(yīng)特定的作品、開(kāi)發(fā)功能威:MrsFu123,藝術(shù)品,擁有鏈上獨(dú)一無(wú)二的序列號(hào)作為唯一所有權(quán)憑證,不可篡改、不可拆分、不可復(fù)制。
鑄造
基本函數(shù)
鑄造使用了_mint函數(shù),其函數(shù)定義是:
function _mint(address to,uint256 quantity)internal virtual
1
該函數(shù)規(guī)定了以下參數(shù):
to鑄造NFT接受地址
quantity鑄造的NFT數(shù)量
由于ERC721A只能鑄造固定數(shù)量的NFT,所以無(wú)法指定鑄造NFT的tokenID
其函數(shù)的運(yùn)行邏輯簡(jiǎn)單如下:
運(yùn)行_beforeTokenTransfers,此函數(shù)應(yīng)根據(jù)具體目的編寫(xiě)
設(shè)置_packedOwnerships,以方便查詢NFT的擁有者
設(shè)置_packedAddressData,方便查詢某一用戶的所有NFT
釋放Transfer事件
運(yùn)行_afterTokenTransfers,此函數(shù)應(yīng)根據(jù)具體目的編寫(xiě)
接下來(lái),我們將結(jié)合代碼進(jìn)行分析。
最先運(yùn)行的_beforeTokenTransfers和最后運(yùn)行的
_afterTokenTransfers都是由用戶自定義的函數(shù),用于實(shí)現(xiàn)白名單等功能。函數(shù)具體定義如下:
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
)internal virtual{}
function _afterTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
)internal virtual{}
讀者可根據(jù)自身需求,通過(guò)繼承覆蓋的方式定義這兩個(gè)函數(shù)。
接下來(lái),我們?cè)O(shè)置一些核心數(shù)據(jù),這些數(shù)據(jù)的設(shè)置是_mint函數(shù)的核心。值得注意的是,這些函數(shù)都定義在unchecked代碼塊中,因?yàn)镹FT的各個(gè)參數(shù)設(shè)置不會(huì)產(chǎn)生溢出情況,通過(guò)unchecked可以避免編譯過(guò)程中插入溢出檢查代碼以減少gas消耗。
簡(jiǎn)而言之,在某些已經(jīng)確定不會(huì)出現(xiàn)數(shù)據(jù)溢出的場(chǎng)景中使用unchecked包裹代碼可以減少gas消耗
最開(kāi)始,我們?cè)O(shè)置表示NFT所有者的_packOwnershipData數(shù)據(jù)結(jié)構(gòu),具體設(shè)置方法如下:
_packedOwnerships[startTokenId]=_packOwnershipData(
to,
_nextInitializedFlag(quantity)|_nextExtraData(address(0),to,0)
);
為方便讀者理解代碼,在此處,我們給出_packedOwnerships的定義:
//Bits Layout:
//-[0..159]`addr`
//-[160..223]`startTimestamp`
//-[224]`burned`
//-[225]`nextInitialized`
//-[232..255]`extraData`
mapping(uint256=>uint256)private _packedOwnerships;