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

前言

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

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

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

1汹粤、有關(guān)區(qū)塊和交易的屬性
2箩做、有關(guān)錯(cuò)誤處理
3虫腋、有關(guān)數(shù)學(xué)及加密功能
4骄酗、地址相關(guān)
5、合約相關(guān)

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

  • block.blockhash(uint blockNumber) returns (bytes32):返回給定區(qū)塊號(hào)的哈希值悦冀,只支持最近256個(gè)區(qū)塊趋翻,且不包含當(dāng)前區(qū)塊。

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

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

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

  • block.number (uint): 當(dāng)前區(qū)塊的塊號(hào)

  • block.timestamp (uint): 當(dāng)前塊的Unix時(shí)間戳(從1970/1/1 00:00:00 UTC開(kāi)始所經(jīng)過(guò)的秒數(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):當(dāng)前調(diào)用發(fā)起人的地址

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

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

  • now (uint):當(dāng)前塊的時(shí)間戳(block.timestamp的別名)

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

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

注意以下幾點(diǎn):

1历等、msg的所有成員值讨惩,包括 msg.sendermsg.value都可以因?yàn)槊恳淮?external 函數(shù)(或library庫(kù)函數(shù))的調(diào)用被改變。

2募闲、不應(yīng)該依據(jù) block.timestamp(時(shí)間戳), nowblock.blockhash(區(qū)塊哈希)來(lái)產(chǎn)生一個(gè)隨機(jī)數(shù)步脓,除非你確實(shí)需要這樣做愿待。
block.timestamp(時(shí)間戳)block.blockhash(區(qū)塊哈希)在一定程度上會(huì)受礦工的影響浩螺。比如在賭博合約里,不誠(chéng)實(shí)的礦工可能會(huì)嘗試去選擇一個(gè)對(duì)自己有利的hash仍侥。

3要出、對(duì)于同一個(gè)鏈上連續(xù)的區(qū)塊來(lái)說(shuō),當(dāng)前區(qū)塊的時(shí)間戳(timestamp)必然是大于上一個(gè)區(qū)塊的時(shí)間戳农渊。

4患蹂、由于可擴(kuò)展性的原因,你只能查到最近的256個(gè)區(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ù)可以在不實(shí)際調(diào)用函數(shù)的情況下传于,為函數(shù)調(diào)用創(chuàng)建數(shù)據(jù)。此外醉顽,keccak256(abi.encodePacked(a, b))是計(jì)算keccak256(a, b)更明確的方式沼溜,keccak256(a, b)在以后的版本中會(huì)被廢棄。

關(guān)于編碼的信息游添,大家可以參考ABI
tightly packed encoding的文檔

錯(cuò)誤處理(Error Handling)

assert(bool condition)
用于判斷內(nèi)部錯(cuò)誤系草,如果條件不滿(mǎn)足時(shí),會(huì)使事物無(wú)效(拋出異常)
require(bool condition)
用于判斷輸入或外部組件錯(cuò)誤唆涝,如果條件不滿(mǎn)足時(shí)找都,會(huì)回滾
require(bool condition, string message)
用于判斷輸入或外部組件錯(cuò)誤,如果條件不滿(mǎn)足時(shí)廊酣,會(huì)回滾能耻。同時(shí)會(huì)顯示錯(cuò)誤信息
revert():
終止執(zhí)行并恢復(fù)改變的狀態(tài)
revert(string reason)
終止執(zhí)行并恢復(fù)改變的狀態(tài),并且會(huì)提供一個(gè)解釋的信息

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

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

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

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

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

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

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

ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address):
通過(guò)橢圓曲線(xiàn)簽名來(lái)恢復(fù)與公鑰關(guān)的地址诫睬,或者在錯(cuò)誤時(shí)返回0(參考示例
)。
可用于簽名數(shù)據(jù)的校驗(yàn)帕涌,如果返回結(jié)果是簽名者的公匙地址摄凡,那么說(shuō)明數(shù)據(jù)是正確的。

ecrecover函數(shù)需要四個(gè)參數(shù)蚓曼,需要被簽名數(shù)據(jù)的哈希結(jié)果值亲澡,r,s纫版,v分別來(lái)自簽名結(jié)果串床绪。
r = signature[0:64]
s = signature[64:128]
v = signature[128:130]
其中v取出來(lái)的值或者是00或01。要使用時(shí)其弊,我們先要將其轉(zhuǎn)為整型癞己,再加上27,所以我們將得到27或28梭伐。在調(diào)用函數(shù)時(shí)v將填入27或28痹雅。

在上面,“tightly packed”意思是說(shuō)參數(shù)不會(huì)補(bǔ)位糊识,是直接連接在一起的绩社,下面幾個(gè)是相等的。

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

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

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

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

在私有鏈(private blockchain)上運(yùn)行sha256,ripemd160ecrecover可能會(huì)出現(xiàn)Out-Of-Gas錯(cuò)誤。因?yàn)樗芥湆?shí)現(xiàn)了一種預(yù)編譯合約鸠真,合約要在收到第一個(gè)消息后才會(huì)真正存在(即使它們的合約代碼是硬編碼的)悯仙。向一個(gè)不存在的合約發(fā)送消息時(shí)非常昂貴的,并且會(huì)導(dǎo)致Out-Of-Gas的問(wèn)題吠卷。一種解決辦法是在你真正使用這些合約之前锡垄,給每個(gè)合約地址發(fā)送1 wei。在官方和測(cè)試鏈上沒(méi)有這個(gè)問(wèn)題祭隔。

地址相關(guān)(Address Related)

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

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

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

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

<address>.callcode(...) returns (bool):
發(fā)起底層的callcode調(diào)用鞠呈,失敗時(shí)返回false,會(huì)花費(fèi)掉所有可用的gas右钾,可以調(diào)節(jié)蚁吝。不鼓勵(lì)使用,未來(lái)可能會(huì)移除舀射。

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

更多的信息庙曙,參考Address.

警告:
使用send()會(huì)有一些危險(xiǎn):如果調(diào)用棧的深度超過(guò)1024或接收方耗光了gas空镜,交易都會(huì)失敗浩淘。所以,為了確保Ether交易安全吴攒,必須檢查send的返回值张抄,如果交易失敗,會(huì)回退以太幣洼怔。使用transfer或許是更好的選擇署惯。

合約相關(guān)(Contract Related)

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

selfdestruct(address recipient):
銷(xiāo)毀當(dāng)前合約镣隶,并把所有資金發(fā)送到指定的地址极谊。

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

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

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市域那,隨后出現(xiàn)的幾起案子咙边,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件败许,死亡現(xiàn)場(chǎng)離奇詭異王带,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)市殷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)愕撰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人醋寝,你說(shuō)我怎么就攤上這事盟戏。” “怎么了甥桂?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵柿究,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我黄选,道長(zhǎng)蝇摸,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任办陷,我火速辦了婚禮貌夕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘民镜。我一直安慰自己啡专,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布制圈。 她就那樣靜靜地躺著们童,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鲸鹦。 梳的紋絲不亂的頭發(fā)上慧库,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天,我揣著相機(jī)與錄音馋嗜,去河邊找鬼齐板。 笑死,一個(gè)胖子當(dāng)著我的面吹牛葛菇,可吹牛的內(nèi)容都是我干的甘磨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼眯停,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼济舆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起庵朝,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤吗冤,失蹤者是張志新(化名)和其女友劉穎又厉,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體椎瘟,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡覆致,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肺蔚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片煌妈。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宣羊,靈堂內(nèi)的尸體忽然破棺而出璧诵,到底是詐尸還是另有隱情,我是刑警寧澤仇冯,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布之宿,位于F島的核電站,受9級(jí)特大地震影響苛坚,放射性物質(zhì)發(fā)生泄漏比被。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一泼舱、第九天 我趴在偏房一處隱蔽的房頂上張望等缀。 院中可真熱鬧,春花似錦娇昙、人聲如沸尺迂。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)噪裕。三九已至,卻和暖如春宋渔,著一層夾襖步出監(jiān)牢的瞬間州疾,已是汗流浹背辜限。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工皇拣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人薄嫡。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓氧急,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親毫深。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吩坝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

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