智能合约语言 Solidity 教程系列8 - Solidity API
這是Solidity教程系列文章第8篇介紹Solidity API,它們主要表現(xiàn)為內(nèi)置的特殊的變量及函數(shù),存在于全局命名空間里。
<!-- more -->
寫在前面
Solidity 是以太坊智能合約編程語言,閱讀本文前,你應(yīng)該對以太坊、智能合約有所了解,
如果你還不了解,建議你先看以太坊是什么
歡迎訂閱區(qū)塊鏈技術(shù)專欄閱讀更全面的分析文章。
Solidity API 主要表現(xiàn)為Solidity 內(nèi)置的特殊的變量及函數(shù),他們存在于全局命名空間里,主要分為以下幾類:
下面詳細(xì)講解下
區(qū)塊和交易的屬性(Block And Transaction Properties)
用來提供一些區(qū)塊鏈當(dāng)前的信息。
- block.blockhash(uint blockNumber) returns (bytes32):返回給定區(qū)塊號的哈希值,只支持最近256個區(qū)塊,且不包含當(dāng)前區(qū)塊。
- block.coinbase (address): 當(dāng)前塊礦工的地址。
- block.difficulty (uint):當(dāng)前塊的難度。
- block.gaslimit (uint):當(dāng)前塊的gaslimit。
- block.number (uint):當(dāng)前區(qū)塊的塊號。
- block.timestamp (uint): 當(dāng)前塊的Unix時間戳(從1970/1/1 00:00:00 UTC開始所經(jīng)過的秒數(shù))
- msg.data (bytes): 完整的調(diào)用數(shù)據(jù)(calldata)。
- msg.gas (uint): 當(dāng)前還剩的gas。
- msg.sender (address): 當(dāng)前調(diào)用發(fā)起人的地址。
- msg.sig (bytes4):調(diào)用數(shù)據(jù)(calldata)的前四個字節(jié)(例如為:函數(shù)標(biāo)識符)。
- msg.value (uint): 這個消息所附帶的以太幣,單位為wei。
- now (uint): 當(dāng)前塊的時間戳(block.timestamp的別名)
- tx.gasprice (uint) : 交易的gas價格。
- tx.origin (address): 交易的發(fā)送者(全調(diào)用鏈)
注意:
msg的所有成員值,如msg.sender,msg.value的值可以因為每一次外部函數(shù)調(diào)用,或庫函數(shù)調(diào)用發(fā)生變化(因為msg就是和調(diào)用相關(guān)的全局變量)。
不應(yīng)該依據(jù) block.timestamp, now 和 block.blockhash來產(chǎn)生一個隨機(jī)數(shù)(除非你確實需要這樣做),這幾個值在一定程度上被礦工影響(比如在賭博合約里,不誠實的礦工可能會重試去選擇一個對自己有利的hash)。
對于同一個鏈上連續(xù)的區(qū)塊來說,當(dāng)前區(qū)塊的時間戳(timestamp)總是會大于上一個區(qū)塊的時間戳。
為了可擴(kuò)展性的原因,你只能查最近256個塊,所有其它的將返回0.
錯誤處理
- assert(bool condition)
用于判斷內(nèi)部錯誤,條件不滿足時拋出異常
- require(bool condition):
用于判斷輸入或外部組件錯誤,條件不滿足時拋出異常
- revert():
終止執(zhí)行并還原改變的狀態(tài)
數(shù)學(xué)及加密功能
- addmod(uint x, uint y, uint k) returns (uint):
計算(x + y) % k,加法支持任意的精度且不會在2**256處溢出,從0.5.0版本開始斷言k != 0。
- mulmod(uint x, uint y, uint k) returns (uint):
計算 (x y) % k, 乘法支持任意的精度且不會在2*256處溢出, 從0.5.0版本開始斷言k != 0。
- keccak256(...) returns (bytes32):
使用以太坊的(Keccak-256)計算HASH值。緊密打包參數(shù)。
- sha256(...) returns (bytes32):
使用SHA-256計算hash值,緊密打包參數(shù)。
- sha3(...) returns (bytes32):
keccak256的別名
- ripemd160(...) returns (bytes20):
使用RIPEMD-160計算HASH值。緊密打包參數(shù)。
- ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address):
通過橢圓曲線簽名來恢復(fù)與公鑰關(guān)聯(lián)的地址,或者在錯誤時返回零。可用于簽名數(shù)據(jù)的校驗,如果返回結(jié)果是簽名者的公匙地址,那么說明數(shù)據(jù)是正確的。
ecrecover函數(shù)需要四個參數(shù),需要被簽名數(shù)據(jù)的哈希結(jié)果值,r,s,v分別來自簽名結(jié)果串。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。
用javascript表達(dá)如下:
var msg = '0x8CbaC5e4d803bE2A3A5cd3DbE7174504c6DD0c1C'var hash = web3.sha3(msg)var sig = web3.eth.sign(address, h).slice(2)var r = `0x${sig.slice(0, 64)}`var s = `0x${sig.slice(64, 128)}`var v = web3.toDecimal(sig.slice(128, 130)) + 27訂閱區(qū)塊鏈技術(shù)專欄可以參考到完整的使用例子。
<!--
例子:
-->
緊密打包參數(shù)(tightly packed)意思是說參數(shù)不會補(bǔ)位,是直接連接在一起的,下面幾個是相等的。
keccak256("ab", "c") keccak256("abc")keccak256(0x616263) // hex keccak256(6382179) keccak256(97, 98, 99) //ascii如果需要填充,可以使用顯式類型轉(zhuǎn)換:keccak256("x00x12") 與keccak256(uint16(0x12))相同。
注意,常量將使用存儲它們所需的最少字節(jié)數(shù)來打包,例如keccak256(0) == keccak256(uint8(0))和keccak256(0x12345678) == keccak256(uint32(0x12345678))
在私鏈(private blockchain)上運行sha256,ripemd160或ecrecover可能會出現(xiàn)Out-Of-Gas報錯。因為私鏈實現(xiàn)了一種預(yù)編譯合約,合約要在收到第一個消息后才會真正存在(雖然他們的合約代碼是硬編碼的)。而向一個不存在的合約發(fā)送消息,所以才會導(dǎo)致Out-Of-Gas的問題。一種解決辦法(workaround)是每個在你真正使用它們之前先發(fā)送1 wei到這些合約上來完成初始化。在官方和測試鏈上沒有這個問題。
地址相關(guān)
- <address>.balance (uint256):
Address的余額,以wei為單位。
- <address>.transfer(uint256 amount):
發(fā)送給定數(shù)量的ether到某個地址,以wei為單位。失敗時拋出異常。
- <address>.send(uint256 amount) returns (bool):
發(fā)送給定數(shù)量的ether到某個地址,以wei為單位, 失敗時返回false。
- <address>.call(...) returns (bool):
發(fā)起底層的call調(diào)用。失敗時返回false。
- <address>.callcode(...) returns (bool):
發(fā)起底層的callcode調(diào)用,失敗時返回false。
不鼓勵使用,未來可能會移除。
- <address>.delegatecall(...) returns (bool):
發(fā)起底層的delegatecall調(diào)用,失敗時返回false
更多信息參考地址篇。
警告:send() 執(zhí)行有一些風(fēng)險:如果調(diào)用棧的深度超過1024或gas耗光,交易都會失敗。因此,為了保證安全,必須檢查send的返回值,如果交易失敗,會回退以太幣。如果用transfer會更好。
合約相關(guān)
- this(當(dāng)前合約的類型):
表示當(dāng)前合約,可以顯式的轉(zhuǎn)換為Address
- selfdestruct(address recipient):
銷毀當(dāng)前合約,并把它所有資金發(fā)送到給定的地址。
- suicide(address recipient):
selfdestruct的別名
另外,當(dāng)前合約里的所有函數(shù)均可支持調(diào)用,包括當(dāng)前函數(shù)本身。
參考視頻
我們也推出了目前市面上最全的視頻教程:深入詳解以太坊智能合約語言Solidity
目前我們也在招募體驗師,可以點擊鏈接了解。
參考文檔
- Special Variables and Functions
深入淺出區(qū)塊鏈 - 系統(tǒng)學(xué)習(xí)區(qū)塊鏈,打造最好的區(qū)塊鏈技術(shù)博客。
如果想與我有更密切的交流可以選擇加入我的知識星球(星球成員可加入微信技術(shù)交流群)
總結(jié)
以上是生活随笔為你收集整理的智能合约语言 Solidity 教程系列8 - Solidity API的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: keepalived 服务器内存持续升高
- 下一篇: 「镁客早报」韩国将支持数字加密货币的正常