了解合約之間的 nameReg.call(‘register’, ‘MyName’) 風格呼叫
這是關於地址類型方法(具體方法)的solidity docs的範例:
call
地址名稱Reg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;
nameReg.call(“註冊”, “MyName”);
nameReg.call(bytes4(sha3(“fun(uint256)”)), a);
我無法理解第二行的作用。它是否使用這兩個參數呼叫回退函式?或者它是否將字元串MyName傳遞給****nameReg合約上的函式註冊?
從問題的連結中,重要的部分
nameReg.call("register", "MyName")
是(粗體我的):**為了與不遵守 ABI 的合約互動,**提供了該函式,該函式
call
接受任意數量的任何類型的參數。這些參數被填充到 32 個字節並連接起來。請參閱此處的註釋:
注意:ABI 是一種抽象,不屬於乙太坊核心協議的一部分。任何人都可以為其合約定義自己的 ABI,並且此類合約的任何呼叫者都必須遵守該 ABI 才能獲得有意義的結果。但是,對於所有開發人員來說,使用都符合上述 ABI 的 Solidity、Serpent 和 web3.js 會更簡單。
nameReg.call("register", "MyName")
不會呼叫Solidity 編譯register
的合約。nameReg
原因是 Solidity 不使用“寄存器”來查找“函式”(它使用前 4 個字節作為方法 id。例如 Solidity 生成的 EVM 虛擬碼,請參閱此)。這是快速測試的程式碼:contract NameReg { bytes32 public nn; bytes public calldata; function register(bytes32 name) { nn = name; } function() { calldata = msg.data; } function doesNotCallRegister() { this.call("register", "MyName"); } }
使用
nameReg
Solidity 編譯的合約,nameReg.call("register", "MyName")
將呼叫回退函式,其中msg.data
將“註冊”、“MyName”填充到 32 個字節並連接:0x72656769737465720000000000000000000000000000000000000000000000004d794e616d650000000000000000000000000000000000000000000000000000
。