【Solidity智能合約系列】08--Solidity API

前言

這一節(jié)主要會介紹一些Solidity API,也就是一些特殊的變量及函數(shù)。

特殊的變量和函數(shù)(Special Variables and Functions)

Solidity的API中內(nèi)置了一些特殊的變量及函數(shù),他們存在于全局命名空間(namespace)里,主要用于提供區(qū)塊鏈(blockchain)相關的信息,或者是一些通用的函數(shù)。大概分為如下幾類:

1、有關區(qū)塊和交易的屬性
2、有關錯誤處理
3、有關數(shù)學及加密功能
4、地址相關
5、合約相關

區(qū)塊和交易屬性(Block And Transaction Properties)

  • block.blockhash(uint blockNumber) returns (bytes32):返回給定區(qū)塊號的哈希值,只支持最近256個區(qū)塊,且不包含當前區(qū)塊。

  • block.coinbase (address):當前區(qū)塊的礦工地址

  • block.difficulty (uint): 當前區(qū)塊的難度值

  • block.gaslimit (uint): 當前區(qū)塊的gaslimit

  • block.number (uint): 當前區(qū)塊的塊號

  • block.timestamp (uint): 當前塊的Unix時間戳(從1970/1/1 00:00:00 UTC開始所經(jīng)過的秒數(shù))

  • gasleft() returns (uint256):剩余的gas

  • msg.data (bytes):完整的調(diào)用數(shù)據(jù)calldata

  • msg.gas (uint):剩余的gas,在0.4.21版本中已經(jīng)棄用,并有gasleft()代替

  • msg.sender (address):當前調(diào)用發(fā)起人的地址

  • msg.sig (bytes4):調(diào)用數(shù)據(jù)(calldata)的前四個字節(jié)(例如為:函數(shù)標識符)

  • msg.value (uint):發(fā)送這個消息所附帶的以太幣的數(shù)量,單位是wei

  • now (uint):當前塊的時間戳(block.timestamp的別名)

  • tx.gasprice (uint):交易的gas價格

  • tx.origin (address):交易發(fā)送者的地址(full call chain)

注意以下幾點:

1、msg的所有成員值,包括 msg.sendermsg.value都可以因為每一次 external 函數(shù)(或library庫函數(shù))的調(diào)用被改變。

2、不應該依據(jù) block.timestamp(時間戳), nowblock.blockhash(區(qū)塊哈希)來產(chǎn)生一個隨機數(shù),除非你確實需要這樣做。
block.timestamp(時間戳)block.blockhash(區(qū)塊哈希)在一定程度上會受礦工的影響。比如在賭博合約里,不誠實的礦工可能會嘗試去選擇一個對自己有利的hash。

3、對于同一個鏈上連續(xù)的區(qū)塊來說,當前區(qū)塊的時間戳(timestamp)必然是大于上一個區(qū)塊的時間戳。

4、由于可擴展性的原因,你只能查到最近的256個區(qū)塊的hash值,所有其它的將返回0.

ABI編碼函數(shù)(ABI Encoding Functions)

  • abi.encode(...) returns (bytes):

  • abi.encodePacked(...) returns (bytes):

  • abi.encodeWithSelector(bytes4 selector, ...) returns (bytes):

  • abi.encodeWithSignature(string signature, ...) returns (bytes):

注意:
這些編碼函數(shù)可以在不實際調(diào)用函數(shù)的情況下,為函數(shù)調(diào)用創(chuàng)建數(shù)據(jù)。此外,keccak256(abi.encodePacked(a, b))是計算keccak256(a, b)更明確的方式,keccak256(a, b)在以后的版本中會被廢棄。

關于編碼的信息,大家可以參考ABI
tightly packed encoding的文檔

錯誤處理(Error Handling)

assert(bool condition)
用于判斷內(nèi)部錯誤,如果條件不滿足時,會使事物無效(拋出異常)
require(bool condition)
用于判斷輸入或外部組件錯誤,如果條件不滿足時,會回滾
require(bool condition, string message)
用于判斷輸入或外部組件錯誤,如果條件不滿足時,會回滾。同時會顯示錯誤信息
revert():
終止執(zhí)行并恢復改變的狀態(tài)
revert(string reason)
終止執(zhí)行并恢復改變的狀態(tài),并且會提供一個解釋的信息

數(shù)學及加密函數(shù)(Mathematical and Cryptographic Functions)

addmod(uint x, uint y, uint k) returns (uint):
計算(x + y) % k,加法支持任意的精度且不會在2**256(2的256次方)處溢出,從0.5.0版本開始插入 assert(k != 0)

mulmod(uint x, uint y, uint k) returns (uint):
計算 (x * y) % k, 乘法支持任意的精度且不會在2*256處溢出, 從0.5.0版本開始插入 assert(k != 0)

keccak256(…) returns (bytes32):
計算 (tightly packed) argumentsEthereum-SHA-3 (Keccak-256) hash值

sha256(…) returns (bytes32):
使用SHA-256計算tightly packed) arguments
的hash值

sha3(…) returns (bytes32):
keccak256的別名

ripemd160(…) returns (bytes20):
使用RIPEMD-160計算(tightly packed) arguments
的HASH值

ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address):
通過橢圓曲線簽名來恢復與公鑰關的地址,或者在錯誤時返回0(參考示例
)。
可用于簽名數(shù)據(jù)的校驗,如果返回結果是簽名者的公匙地址,那么說明數(shù)據(jù)是正確的。

ecrecover函數(shù)需要四個參數(shù),需要被簽名數(shù)據(jù)的哈希結果值,r,s,v分別來自簽名結果串。
r = signature[0:64]
s = signature[64:128]
v = signature[128:130]
其中v取出來的值或者是00或01。要使用時,我們先要將其轉(zhuǎn)為整型,再加上27,所以我們將得到27或28。在調(diào)用函數(shù)時v將填入27或28。

在上面,“tightly packed”意思是說參數(shù)不會補位,是直接連接在一起的,下面幾個是相等的。

keccak256("ab", "c")
keccak256("abc")

keccak256(0x616263)  // hex16進制數(shù)
keccak256(6382179)
keccak256(97, 98, 99)   //ascii碼,97代表a

如果需要填充,可以使用顯式類型轉(zhuǎn)換:keccak256(“\x00\x12”) 與keccak256(uint16(0x12))相同。

注意,常量將使用存儲它們所需的最少字節(jié)數(shù)來打包,例如keccak256(0) == keccak256(uint8(0))和keccak256(0x12345678) == keccak256(uint32(0x12345678))

在私有鏈(private blockchain)上運行sha256,ripemd160ecrecover可能會出現(xiàn)Out-Of-Gas錯誤。因為私鏈實現(xiàn)了一種預編譯合約,合約要在收到第一個消息后才會真正存在(即使它們的合約代碼是硬編碼的)。向一個不存在的合約發(fā)送消息時非常昂貴的,并且會導致Out-Of-Gas的問題。一種解決辦法是在你真正使用這些合約之前,給每個合約地址發(fā)送1 wei。在官方和測試鏈上沒有這個問題。

地址相關(Address Related)

<address>.balance (uint256):
指定以太坊地址的余額,單位是wei

<address>.transfer(uint256 amount):
發(fā)送給定數(shù)量的ether到某個地址,以wei為單位。失敗時拋出異常,還會轉(zhuǎn)發(fā)2300 gas,這是不可調(diào)節(jié)的。

<address>.send(uint256 amount) returns (bool):
發(fā)送給定數(shù)量的ether到某個地址,以wei為單位, 失敗時返回false,還會轉(zhuǎn)發(fā)2300 gas,這是不可調(diào)節(jié)的。

<address>.call(...) returns (bool):
發(fā)起底層的call調(diào)用,失敗時返回false,會花費掉所有可用的gas,可以調(diào)節(jié)

<address>.callcode(...) returns (bool):
發(fā)起底層的callcode調(diào)用,失敗時返回false,會花費掉所有可用的gas,可以調(diào)節(jié)。不鼓勵使用,未來可能會移除

<address>.delegatecall(...) returns (bool):
發(fā)起底層的delegatecall調(diào)用,失敗時返回false,會花費掉所有可用的gas,可以調(diào)節(jié)

更多的信息,參考Address.

警告:
使用send()會有一些危險:如果調(diào)用棧的深度超過1024或接收方耗光了gas,交易都會失敗。所以,為了確保Ether交易安全,必須檢查send的返回值,如果交易失敗,會回退以太幣。使用transfer或許是更好的選擇。

合約相關(Contract Related)

this (current contract’s type):
表示當前合約,可以顯式的轉(zhuǎn)換為Address

selfdestruct(address recipient):
銷毀當前合約,并把所有資金發(fā)送到指定的地址。

suicide(address recipient):
selfdestruct的別名(廢棄)

此外,當前合約里的所有函數(shù)均可支持調(diào)用,包括當前函數(shù)本身。

參考:
https://solidity.readthedocs.io/en/develop/units-and-global-variables.html#units-and-globally-available-variables

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,530評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,407評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,981評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,759評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,204評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,415評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,955評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,650評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,892評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,675評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內(nèi)容