1. 程式人生 > >solidity 學習筆記(5)call 函式

solidity 學習筆記(5)call 函式

call() 方法

call()是一個底層的介面,用來向一個合約傳送訊息,也就是說如果你想實現自己的訊息傳遞,可以使用這個函式。函式支援傳入任意型別的任意引數,並將引數打包成32位元組,相互拼接後向合約傳送這段資料。

 

簡單說 根據地址呼叫指定合約的方法。

 

pragma solidity ^0.4.24;
 
contract cat{
    
    function eat(uint a) public view returns(uint){
        return a;
    }
    
}
 
 
contract Animal{
    
    cat c;
    constructor(address _add){
        c 
= cat(_add); } function test()public view returns(uint) { //普通例項化合約呼叫 return c.eat(1); } function test2()public view returns(bool) { //通過call方法呼叫 return c.call(bytes32(keccak256("eat()")),2);//通過bytes32(keccak256("eat()"指定方法,後面的是引數
} }

由於向另一個合約傳送資料時,找不到對應的方法簽名,會預設呼叫fallback()

函式,所以我們可以通過這個來看看call()傳的具體資料。

 
    bytes fail;
    
    function(){
        fail = msg.data;
    }

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

 

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

call()

的返回結果即使成功,並不能說操作成功了,只是沒有出現異常,有可能呼叫到了fallback()函式。

 

delegatecall()

calldelegatecall的功能類似,區別僅在於後者僅使用給定地址的程式碼,其它資訊則使用當前合約(如儲存,餘額等等)。

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

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

 

二者執行程式碼的上下文環境的不同,當使用call呼叫其它合約的函式時,程式碼是在被呼叫的合約的環境裡執行,對應的,使用delegatecall進行函式呼叫時程式碼則是在呼叫函式的合約的環境裡執行。