《Solidity 教程》特殊變數和函數

在全域命名空間中已經存在了(預設了)一些特殊的變數和函數,他們主要用來提供關於區塊鏈的資訊或一些通用的工具函數。

區塊和交易屬性

  • block.chainid (uint): 當前鏈 id
  • block.coinbase ( address): 挖出當前區塊的礦工位址
  • block.difficulty ( uint): 當前區塊難度
  • block.gaslimit ( uint): 當前區塊 gas 限額
  • block.number ( uint): 當前區塊號
  • block.timestamp ( uint): 自 unix epoch 起始當前區塊以秒計的時間戳
  • msg.data ( bytes): 完整的 calldata
  • msg.sender ( address): 訊息發送者(當前呼叫)
  • msg.sig ( bytes4): calldata 的前 4 位元組(也就是函數識別子)
  • msg.value ( uint): 隨消息發送的 wei 的數量
  • tx.gasprice (uint): 交易的 gas 價格
  • tx.origin (address payable): 交易發起者(完全的調用鏈)

以上這些都經常會使用到,請牢記這些每個的含義,以 Azuki.sol 為例

  • block.timestamp 會用來判斷目前的區塊時間使否已經某個特定時間,例如當區塊時間超過拍賣開啟時間後,拍賣的 mint 函數才能成功被使用者呼叫
  • msg.value 會用來判斷使用者給的 eth 數量是否足夠,例如公售的鑄造最低價格為0.1 eth,假設鑄造者只給了 0.05 eth,他理應不能鑄造
  • msg.sender 則代表該呼叫者,大多需要與鏈上交互的函數都會需要使用到這個值

ABI 編碼及解碼函數

  • abi.decode(bytes memory encodedData, (...)) returns (...): 對給定的數據進行ABI解碼,而數據的類型在括弧中第二個參數給出 。 例如:

    (uint a, uint[2] memory b, bytes memory c) = 
    	abi.decode(data, (uint, uint[2], bytes))
    
  • abi.encode(...) returns (bytes): ABI - 對給定參數進行編碼

  • abi.encodePacked(...) returns (bytes):對給定參數執行 緊打包編碼 ,注意,可以不明確打包編碼。

  • abi.encodeWithSelector(bytes4 selector, ...) returns (bytes): ABI - 對給定第二個開始的參數進行編碼,並以給定的函數選擇器作為起始的 4 位元組數據一起返回

  • abi.encodeWithSignature(string signature, ...) returns (bytes):等價於 abi.encodeWithSelector(bytes4(keccak256(signature), ...)

更多詳情請參考 ABI 和 緊打包編碼

錯誤處理

  • **assert(bool condition)**如果不滿足條件,則會導致Panic 錯誤,則撤銷狀態更改 - 用於檢查內部錯誤
  • **require(bool condition)**如果條件不滿足則撤銷狀態更改 - 用於檢查由輸入或者外部元件引起的錯誤
  • **require(bool condition, string memory message)**如果條件不滿足則撤銷狀態更改 - 用於檢查由輸入或者外部元件引起的錯誤,可以同時提供一個錯誤消息
  • **revert()**終止運行並撤銷狀態更改
  • **revert(string memory reason)**終止運行並撤銷狀態更改,可以同時提供一個解釋性的字串

數學和密碼學函數

  • addmod(uint x, uint y, uint k) returns (uint)
    計算(x + y) % k ,加法會在任意精度下執行,並且加法的結果即使超過 2**256也不會被截取。 從 0.5.0 版本的編譯器開始會加入對k != 0 的校驗(assert)
  • mulmod(uint x, uint y, uint k) returns (uint)
    計算 (x * y) % k,乘法會在任意精度下執行,並且乘法的結果即使超過 2**256也不會被截取。 從 0.5.0 版本的編譯器開始會加入對k != 0 的校驗(assert)
  • **keccak256((bytes memory) returns (bytes32)**計算 Keccak256 哈希,Keccak256 在 solidity 的使用範例
  • **sha256(bytes memory) returns (bytes32)**計算參數的SHA-256哈希
  • **ripemd160(bytes memory) returns (bytes20)**計算參數的 RIPEMD-160 哈希
  • **ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)**利用橢圓曲線簽名恢復與公鑰相關的地址,錯誤返回零值

地址成員

  • **<address>.balance (uint256)**以 Wei 為單位的 位址類型 Address 的餘額。
  • **<address>.code (bytes memory)**在 位址類型 Address 上的代碼(可以為空)
  • <address>.codehash (bytes32):Address 的 codehash
  • **<address payable>.transfer(uint256 amount)**向 位址類型 Address 發送數量為 amount 的 Wei,失敗時拋出異常,使用固定(不可調節)的 2300 gas 的礦工費
  • **<address payable>.send(uint256 amount) returns (bool)**向 位址類型 Address 發送數量為amount的 Wei,失敗時傳回 false,發送 2300 gas 的礦工費用,不可調節
  • **<address>.call(bytes memory) returns (bool, bytes memory)**用给定的有效payload發出低級CALL 調用,返回成功狀態及數據,發送所有可用 gas,也可以調節 gas。
  • **<address>.delegatecall(bytes memory) returns (bool, bytes memory)**用给定的有效payload發出低级 DELEGATECALL调用 ,返回成功狀態并返回數據,發送所有可用 gas,也可以調節 gas。 發出低级函數DELEGATECALL ,失敗时返回 false,發送所有可用 gas,可調節
  • **<address>.staticcall(bytes memory) returns (bool, bytes memory)**用给定的有效payload發出低級STATICCALL 調用,返回成功狀態及數據,發送所有可用 gas,也可以調節 gas

合約相關

  • **this ( 目前的合約型態 )**當前合約,可以顯示轉換為 位址類型 Address
  • **selfdestruct(address payable recipient)**銷毀合約,並把餘額發送到指定 位址類型 Address ,請注意, selfdestruct具有從EVM繼承的一些特性:
    • 接收合約的 receive 函數 不會執行
    • 合約僅在交易結束時才真正被銷毀,並且 revert可能會「撤銷」銷毀

此外,當前合約內的所有函數都可以被直接調用,包括當前函數。

類型資訊

表達式type(X) 可用於檢索參數X的類型資訊。 目前,此功能還比較有限( X僅能是合約和整型),但是未來應該會擴展

用於合約類型 C支援以下屬性:

  • type(C).name : 獲得合約名
  • type(C).creationCode : 獲得包含創建合同位元組碼的記憶體位元組陣組。 它可以在內聯彙編中構建自定義創建例程,尤其是使用 create2操作碼。 不能在合同本身或派生的合同訪問此屬性。 因為會引起迴圈引用。
  • type(C).runtimeCode : 獲得合同的運行時位元組碼的記憶體位元組陣組。 這是通常由C的構造函數部署的代碼。 如果 C有一個使用內聯彙編的構造函數,那麼可能與實際部署的位元元組碼不同。 還要注意庫在部署時修改其運行時位元組碼以防範定期調用(guard against regular calls)。 與.creationCode 有相同的限制,不能在合同本身或派生的合同訪問此屬性。 因為會引起迴圈引用。

除上面的屬性, 下面的屬性在介面類型 I 下可使用:

  • **type(I).interfaceId:**返回介面Ibytes4類型的介面 ID,介面 ID 參考: EIP-165 定義

對於整型 T有下面的屬性可訪問:

  • type(T).min : T 的最小值
  • type(T).max : T 的最大值
Subscribe to Samumu.eth
Receive the latest updates directly to your inbox.
Verification
This entry has been permanently stored onchain and signed by its creator.