Solidity

“掌握乙太坊:建構智能合約和 DApps”中的程式碼範例不起作用

  • July 22, 2019

我正在閱讀 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。將其addressaddress(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"`

進去。

引用自:https://ethereum.stackexchange.com/questions/66537