Solidity
“掌握乙太坊:建構智能合約和 DApps”中的程式碼範例不起作用
我正在閱讀 Gavin Wood 的乙太坊書籍,當我嘗試用 truffle 編譯它時,下面的程式碼範例給出了一條錯誤消息:
pragma solidity ^0.4.22; contract calledContract { event callEvent(address sender, address origin, address from); function calledFunction() public { emit callEvent(msg.sender, tx.origin, this); } } library calledLibrary { event callEvent(address sender, address origin, address from); function calledFunction() public { emit callEvent(msg.sender, tx.origin, this); } } contract caller { function make_calls(calledContract _calledContract) public { // Calling calledContract and calledLibrary directly _calledContract.calledFunction(); calledLibrary.calledFunction(); // Low-level calls using the address object for calledContract require(address(_calledContract). call(bytes4(keccak256("calledFunction()")))); require(address(_calledContract). delegatecall(bytes4(keccak256("calledFunction()")))); } }
https://github.com/ethereumbook/ethereumbook/tree/develop/code/truffle/CallExamples
它給出以下錯誤消息:
類型錯誤
$$ ERR_INVALID_ARG_TYPE $$: 第一個參數必須是 string、Buffer、ArrayBuffer、Array 或 Array-like Object 類型之一。接收類型未定義 有任何想法嗎?
它在 solidity 0.4.22 下完美編譯,但您可能使用的是帶有重大更改的較新版本。
確定您的編譯器版本
$ truffle version
你應該看到類似的東西
solc: 0.5.x
大多數重大更改都來自 5.x。
- 第 6 行:
this
不再隱式轉換為address
。將其address
與address(this)
- 第 13 行:相同
我對
make_calls()
.
functionSig
用於abi.encodePacked
處理從bytes4
固定長度到動態的顯式轉換bytes
。這是相當多的,所以我把它作為一個單獨的可讀性問題來分開。require()
不適用於響應,因為它們返回一個空的元組bytes
。我將這種擔憂分解為一個單獨的步驟。- 添加了一個事件發射器來檢查響應。
我不確定這是處理所有事情的最優雅的方式。可能有人會提出另一種解決方案。如果您確保
pragma
與您實際使用的編譯器匹配,它應該在 5.x 下編譯乾淨。pragma solidity 0.5.1; contract calledContract { event callEvent(address sender, address origin, address from); function calledFunction() public { emit callEvent(msg.sender, tx.origin, address(this)); } } library calledLibrary { event callEvent(address sender, address origin, address from); function calledFunction() public { emit callEvent(msg.sender, tx.origin, address(this)); } } contract caller { event LogLowLevelCalls(address sender, bool success, bytes response); function make_calls(calledContract _calledContract) public { // Calling calledContract and calledLibrary directly _calledContract.calledFunction(); calledLibrary.calledFunction(); // Low-level calls using the address object for calledContract bool success; bytes memory response; bytes memory functionSig = abi.encodePacked(bytes4(keccak256("calledFunction()"))); (success, response) = address(_calledContract).call(functionSig); require(success); emit LogLowLevelCalls(msg.sender, success, response); (success, response) = address(_calledContract).delegatecall(functionSig); require(success); emit LogLowLevelCalls(msg.sender, success, response); } }
這是在 Remix 中展示它的編譯和工作。
希望能幫助到你。
十分感謝你的幫助。但這不是錯誤的原因,因為它不會在 truffle 下與 github 上文件夾的配置文件一起出現。但感謝一位朋友,我找到了解決方案:
在項目根目錄中創建 .env
放
ROPSTEN_PRIVATE_KEY="your key" MAINNET_PRIVATE_KEY="your key"`
進去。