摘要:地址類型的成員屬性及函數這里是地址類型相關成員的快速索引用來查詢賬戶余額,用來發送以太幣以為單位。因此,為了保證安全,必須檢查的返回值,如果交易失敗,會回退以太幣。
本文首發于深入淺出區塊鏈社區
原文鏈接:智能合約語言 Solidity 教程系列2 - 地址類型介紹原文已更新,請讀者前往原文閱讀
Solidity教程系列第二篇 - Solidity地址類型介紹.
Solidity 系列完整的文章列表請查看分類-Solidity。
Solidity是以太坊智能合約編程語言,閱讀本文前,你應該對以太坊、智能合約有所了解,如果你還不了解,建議你先看以太坊是什么
本文前半部分是參考Solidity官方文檔(當前最新版本:0.4.20)進行翻譯,后半部分是結合實際合約代碼實例說明類型的使用(僅針對專欄訂閱用戶)。
地址類型(Address)地址類型address是一個值類型,
地址: 20字節(一個以太坊地址的長度),地址類型也有成員,地址是所有合約的基礎
支持的運算符:
<=, <, ==, !=, >= 和 >
注意:從0.5.0開始,合約不再繼承自地址類型,但仍然可以顯式轉換為地址。地址類型的成員
balance 屬性及transfer() 函數
這里是地址類型相關成員的快速索引
balance用來查詢賬戶余額,transfer()用來發送以太幣(以wei為單位)。
如:
address x = 0x123; address myAddress = this; if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);
注解:如果x是合約地址,合約的回退函數(fallback 函數)會隨transfer調用一起執行(這個是EVM特性),如果因gas耗光或其他原因失敗,轉移交易會還原并且合約會拋異常停止。
關于回退函數(fallback 函數),簡單來說它是合約中無函數名函數,下面代碼事例中,進進一步講解回退函數(fallback) 的使用。
send() 函數
send 與transfer對應,但更底層。如果執行失敗,transfer不會因異常停止,而send會返回false。
警告:send() 執行有一些風險:如果調用棧的深度超過1024或gas耗光,交易都會失敗。因此,為了保證安全,必須檢查send的返回值,如果交易失敗,會回退以太幣。如果用transfer會更好。
call(), callcode() 和 delegatecall() 函數
為了和非ABI協議的合約進行交互,可以使用call() 函數, 它用來向另一個合約發送原始數據,支持任何類型任意數量的參數,每個參數會按規則(ABI協議)打包成32字節并一一拼接到一起。一個例外是:如果第一個參數恰好4個字節,在這種情況下,會被認為根據ABI協議定義的函數器指定的函數簽名而直接使用。如果僅想發送消息體,需要避免第一個參數是4個字節。如下面的例子:
address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2; nameReg.call("register", "MyName"); nameReg.call(bytes4(keccak256("fun(uint256)")), a);
call函數返回一個bool值,以表明執行成功與否。正常結束返回true,異常終止返回false。但無法獲取到結果數據,因為需要提前知道返回的數據的編碼和數據大小(因不知道對方使用的協議格式,所以也不會知道返回的結果如何解析)。
還可以提供.gas()修飾器進行調用:
namReg.call.gas(1000000)("register", "MyName");
類似還可以提供附帶以太幣:
nameReg.call.value(1 ether)("register", "MyName");
修飾器可以混合使用,修飾器調用順序無所謂。
nameReg.call.gas(1000000).value(1 ether)("register", "MyName");
注解:目前還不能在重載函數上使用gas或value修飾符,A workaround is to introduce a special case for gas and value and just re-check whether they are present at the point of overload resolution.(這句我怕翻譯的不準確,引用原文)
同樣我們也可以使用delegatecall(),它與call方法的區別在于,僅僅是代碼會執行,而其它方面,如(存儲,余額等)都是用的當前的合約的數據。delegatecall()方法的目的是用來執行另一個合約中的庫代碼。所以開發者需要保證兩個合約中的存儲變量能兼容,來保證delegatecall()能順利執行。在homestead階段之前,僅有一個受限的callcode()方法可用,但callcode未提供對msg.sender,msg.value的訪問權限。
上面的這三個方法call(),delegatecall(),callcode()都是底層的消息傳遞調用,最好僅在萬不得已才進行使用,因為他們破壞了Solidity的類型安全。
.gas() 在call(), callcode() 和 delegatecall() 函數下都可以使用, delegatecall()不支持.value()
注解:所有合約都繼承了address的成員,因此可以使用this.balance查詢余額。地址常量(Address Literals)
callcode不鼓勵使用,以后會移除。警告:上述的函數都是底層的函數,使用時要異常小心。當調用一個未知的,可能是惡意的合約時,當你把控制權交給它,它可能回調回你的合約,所以要準備好在調用返回時,應對你的狀態變量可能被惡意篡改的情況。
一個能通過地址合法性檢查(address checksum test)十六進制常量就會被認為是地址,如0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF。而不能通過地址合法性檢查的39到41位長的十六進制常量,會提示一個警告,被視為普通的有理數常量。
地址合法性檢查定義在EIP-55合約事例講解 合約事例代碼
pragma solidity ^0.4.0; contract AddrTest{ event logdata(bytes data); function() payable { logdata(msg.data); } function getBalance() returns (uint) { return this.balance; } uint score = 0; function setScore(uint s) public { score = s; } function getScore() returns ( uint){ return score; } } contract CallTest{ function deposit() payable { } event logSendEvent(address to, uint value); function transferEther(address towho) payable { towho.transfer(10); logSendEvent(towho, 10); } function callNoFunc(address addr) returns (bool){ return addr.call("tinyxiong", 1234); } function callfunc(address addr) returns (bool){ bytes4 methodId = bytes4(keccak256("setScore(uint256)")); return addr.call(methodId, 100); } function getBalance() returns (uint) { return this.balance; } }代碼運行及講解
代碼運行及講解,請訂閱區塊鏈技術查看。
參考視頻我們也推出了目前市面上最全的視頻教程:深入詳解以太坊智能合約語言Solidity
目前我們也在招募體驗師,可以點擊鏈接了解。
Solidity官方文檔-類型
? 深入淺出區塊鏈 - 系統學習區塊鏈,打造最好的區塊鏈技術博客。
? 我的知識星球為各位解答區塊鏈技術問題,歡迎加入討論。
? 關注公眾號“深入淺出區塊鏈技術”第一時間獲取區塊鏈技術信息。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/24114.html
摘要:本文首發于深入淺出區塊鏈社區原文鏈接智能合約語言教程系列地址類型介紹原文已更新,請讀者前往原文閱讀現在的中文文檔,要么翻譯的太爛,要么太舊,決定重新翻譯下。枚舉類型應至少有一名成員。 本文首發于深入淺出區塊鏈社區原文鏈接:智能合約語言 Solidity 教程系列2 - 地址類型介紹原文已更新,請讀者前往原文閱讀 現在的Solidity中文文檔,要么翻譯的太爛,要么太舊,決定重新翻譯下。...
摘要:本文首發于深入淺出區塊鏈社區原文鏈接智能合約語言教程系列函數類型原文已更新,請讀者前往原文閱讀教程系列第三篇函數類型介紹。函數類型函數也是一種類型,且屬于值類型。但以此相反,合約中函數本身默認是的,僅僅是當作類型名使用時默認是的。 本文首發于深入淺出區塊鏈社區原文鏈接:智能合約語言Solidity教程系列3 - 函數類型原文已更新,請讀者前往原文閱讀 Solidity 教程系列第三篇 ...
摘要:本文首發于深入淺出區塊鏈社區原文鏈接智能合約語言教程系列錯誤處理原文已更新,請讀者前往原文閱讀這是教程系列文章第篇介紹錯誤處理。如果合約沒有修飾符的的函數在接收以太幣時包括構造函數,和回退函數。如果合約通過一個的函數接收以太幣。 本文首發于深入淺出區塊鏈社區原文鏈接:智能合約語言 Solidity 教程系列9 - 錯誤處理原文已更新,請讀者前往原文閱讀 這是Solidity教程系列文章...
摘要:狀態變量合約內聲明的公有變量還有一個存儲位置是,用來存儲函數參數,是只讀的,不會永久存儲的一個數據位置。稱這個為狀態改變,這也是合約級變量稱為狀態變量的原因。 本文首發于深入淺出區塊鏈社區原文鏈接:智能合約語言 Solidity 教程系列4 - 數據存儲位置分析原文已更新,請讀者前往原文閱讀 Solidity教程系列第4篇 - Solidity數據位置分析。 寫在前面 Solidity...
閱讀 2755·2021-09-24 09:47
閱讀 4378·2021-08-27 13:10
閱讀 3028·2019-08-30 15:44
閱讀 1293·2019-08-29 12:56
閱讀 2600·2019-08-28 18:07
閱讀 2622·2019-08-26 14:05
閱讀 2578·2019-08-26 13:41
閱讀 1272·2019-08-26 13:33