defi/dapp/lp/ido/dao智能合約流動性質押挖礦分紅系統(tǒng)開發(fā)(開發(fā)說明)及案例源碼
區(qū)塊鏈通過時間戳保證每個區(qū)塊依次順序相連,而這個時間戳就像數據的生產日期,證明這個數據在什么時間點就已經存在,時間戳是區(qū)塊元數據的一部分,這使得區(qū)塊具有天然的時間屬性。
隨著區(qū)塊鏈架構體系的不斷發(fā)展,越來越多的研究對區(qū)塊進行改造從而實現(xiàn)了對空間屬性的支持。因此,區(qū)塊鏈技術可以為數據打上時空標簽,通過在區(qū)塊中加入數據的時間和空間信息,將同樣內容的數據集標識為不同的數據集個體,從而解決了數據要素流通中數據集可以被無限復制而無法辨識的難題,實現(xiàn)數據來源可確認。
區(qū)塊鏈的可追溯性來源于區(qū)塊鏈數據結構的特殊性。開發(fā)需求及案例唯:yy625019,在區(qū)塊鏈系統(tǒng)中,它的鏈式結構是從創(chuàng)世區(qū)塊開始的,其后系統(tǒng)產生的所有區(qū)塊都通過父區(qū)塊的哈希值前后相連,并最終能追溯到創(chuàng)世區(qū)塊。
由于每個區(qū)塊都包含一段時間內系統(tǒng)進行的所有交易數據,因此完整的區(qū)塊鏈數據包含了自創(chuàng)世區(qū)塊以來,系統(tǒng)所有進行的交易及交易前后的關聯(lián)信息。同時,得益于區(qū)塊鏈信息的不可篡改特性,使得這種可追溯性是可靠可信的。
function _checkContractOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
)private returns(bool){
try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(),from,tokenId,_data)returns(
bytes4 retval
){
return retval==ERC721A__IERC721Receiver(to).onERC721Received.selector;
}catch(bytes memory reason){
if(reason.length==0){
_revert(TransferToNonERC721ReceiverImplementer.selector);
}
assembly{
revert(add(32,reason),mload(reason))
}
}
}
我們在深入解析Safe多簽錢包智能合約:Fallback合約內已經對onERC721Received的相關內容進行了分析,讀者可自行閱讀理解。此處,我們主要對try/catch這一少見的solidity關鍵詞進行分析。
try關鍵詞后必須為一個外部函數調用,在此處為
ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(),from,tokenId,_data),即調用了外部ERC721A__IERC721Receiver的onERC721Received函數。return會將外部調用的返回值封裝為特定的函數名,此處為retval。
如果外部調用和返回值封裝沒有出現(xiàn)錯誤,就會運行第一個語句塊的語句,此處為
return retval==ERC721A__IERC721Receiver(to).onERC721Received.selector;
該語句塊較為簡單,不再具體分析。
catch用來捕獲錯誤,solidity提供了以下catch語句:
catch Error(string memory reason){...}用于捕獲revert("reasonString")或require(false,"reasonString")等語句造成的錯誤
catch Panic(uint errorCode){...}用于捕獲panic類型錯誤,如assert、除以0等錯誤
catch(bytes memory lowLevelData){...}用于直接捕獲底層錯誤信息,涵蓋所有類型錯誤
在真實場景下,顯然我們無法保證調用的合約使用solidity編寫,所以使用最后一張catch方法是有必要的。
顯然,此處使用的是最后一種catch語句。在捕獲到底層錯誤后,我們首先使用if語句判斷此錯誤信息是否長度為0,如果長度為0,則意味著我們沒有具體的錯誤信息,采取直接拋出TransferToNonERC721ReceiverImplementer.selector的策略。
此處使用了_revert函數,此函數是對revert包裝,定義如下:
function _revert(bytes4 errorSelector)internal pure{
assembly{
mstore(0x00,errorSelector)
revert(0x00,0x04)
}
}