深度解析Solidity合約調用call,callcode,及delegatecall函數

三個方法都是用來進行合約交互的方法。由于沒有進行更進一步的封裝,不是最好的選擇,一般不會直接使用到它們;另外一個顯著的問題由于可以使用任意參數類型,在語言層面不能保證類型安全,所以不推薦使用。

call() 方法

call()是一個底層的接口,用來向一個合約發送消息[1],也就是說如果你想實現自己的消息傳遞,可以使用這個函數。函數支持傳入任意類型的任意參數,并將參數打包成32字節,相互拼接后向合約發送這段數據。

函數的傳輸的數據

由于向另一個合約發送數據時,找不到對應的方法簽名,會默認調用fallback()函數[2],所以我們可以通過這個來看看call()傳的具體數據。

pragma solidity ^0.4.0;

contract Person{
    
    bytes fail;
    
    function(){
        fail = msg.data;
    }
    
    function getFail() returns (bytes){
        return fail;
    }
    
}


contract CallTest{
    
    function callData(address addr) returns (bool){
        return addr.call("abc", 256);
    }
    
}

下圖實際操作演示。


test

可以看到,由于沒有找到對應的函數調用,最終調用的是fallback()函數,通過fail字段,我們看到了收到msg.data

0x61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100

前32字節為abc對應的acii編碼值,后32位為256的對應編碼值[3]

call指定函數

如果第一個參數剛好是四個字節,會認為這四個字節指定的是函數簽名的序號值,生成方式參見ABI協議的函數選擇器[4]。由如果你只是想傳個參數值,而不是想指定一個函數序號,應避免第一個參數剛好是四個字節。

pragma solidity ^0.4.0;

contract Person{
    uint age = 10;
     
    
    function increaseAge(string name, uint num) returns (uint){
        return ++age;
    }
    
    function getAge() returns (uint){
        return age;
    }

}


contract CallTest{
    
    function callByFun(address addr)returns (bool){
        bytes4 methodId = bytes4(keccak256("increaseAge(string,uint256)"));
        return addr.call(methodId,"jack", 1);
    }
}


通過下圖的gif可以看看操作演示:


test1

函數的結果

call()的返回結果是一個bool,表示是否成功的調用,或者是失敗引起了EVM異常。該方法無法直接訪問函數返回結果(因為需要事前知道編碼和返回結果大小)。

call()的返回結果即使成功,并不能說操作成功了,只是沒有出現異常,比如我們第一個例子中,實際是調用到了fallback()函數。

delegatecall()

calldelegatecall的功能類似,區別僅在于后者僅使用給定地址的代碼,其它信息則使用當前合約(如存儲,余額等等)。

函數的設計目的是為了使用存儲在另一個合約的庫代碼。

所以開發者在提供這樣的庫時,就要如何安排存儲來達到這樣的目的。

參考資料

關于作者

專注基于以太坊的相關區塊鏈技術,了解以太坊,Solidity,Truffle。
博客:http://me.tryblockchain.org


  1. 關于這個的詳細說明,可以參考這里。http://ethereum.stackexchange.com/questions/8168/understanding-namereg-callregister-myname-style-call-between-contracts ?

  2. 類似構造函數的定義方式。 ?

  3. 參數編碼格式與ABI的編碼格式一致,直接參考ABI。 ?

  4. 詳細了解ABI格式,可以參考:【文檔翻譯系列】ABI詳解 ?

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

推薦閱讀更多精彩內容

  • 原文地址:C語言函數調用棧(一)C語言函數調用棧(二) 0 引言 程序的執行過程可看作連續的函數調用。當一個函數執...
    小豬啊嗚閱讀 4,649評論 1 19
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,775評論 18 139
  • 本文翻譯自:https://github.com/ConsenSys/smart-contract-best-pr...
    tolak閱讀 4,983評論 4 21
  • 第5章 引用類型(返回首頁) 本章內容 使用對象 創建并操作數組 理解基本的JavaScript類型 使用基本類型...
    大學一百閱讀 3,259評論 0 4
  • 今天被一個群里一個發R語言的生信小哥哥炸了回來。 自從考研,我就退出簡書一大段時間了,期間還有些原因是因為首頁那些...
    邱天閱讀 144評論 0 0