Solidity

TypeError:基礎的定義必須先於派生合約的定義

  • April 7, 2020

在我的 DAPP 中,我有 3 個契約,我想做這樣的事情。

pragma solidity ^0.4.13;

import "./z2.sol";

contract z1 {

   uint example;

   function z1 (){ example = 33;}


   function createZ2() returns(z2){
       z2 newZ2 = new z2();
       return newZ2;
   }

   function getZ1example() returns(uint){
       return example;
   }

}

在 z1 中,我想返回一個 z2 合約。

pragma solidity ^0.4.13;

import "./z3.sol";

contract z2 is z3{

   function z2 (){}

   function createZ3() returns(z3){
       z3 newZ3 = new z3();
       return newZ3;
   }



}

在 z2 中,我想返回一個 z3 契約。

pragma solidity ^0.4.13;

import "./z1.sol";

contract z3 is z1  {


   function z3 (){}

   function getZ3example() returns(uint){
       return (z1.getZ1example());
   }


}

在 z3 中,我想從 z1 合約中呼叫一個函式。

我在 Remix 上嘗試這個,我得到“TypeError:base 的定義必須先於派生合約的定義。”

知道如何解決這個問題嗎?謝謝!

它太糾結了,無法在幾個動作中解決。主要的事情似乎是你混合介面和繼承的方式。您不想使用繼承僅僅與另一個合約對話,甚至從模板創建另一個合約。

我把你的三個概念重命名為“Storage”、“Client”和“ClientFactory”。以下是解決所有三個獨立問題的“簡潔”方式。

pragma solidity 0.4.13;

contract Storage {

   mapping(uint => bytes32) public byteMap;

   function setStorage(uint key, bytes32 value) public returns(bool success) {
       byteMap[key] = value;
       return true;
   }

   function getStorage(uint key) public constant returns(bytes32 value) {
       return byteMap[key];
   }
}

contract Client {

   Storage datastore;

   function Client(address storageAddress) public {
       datastore = Storage(storageAddress);
   }

   function setValue(uint key, bytes32 value) public returns(bool success) {
       datastore.setStorage(key, value);
       return true;
   }

   function getValue(uint key) public constant returns(bytes32 value) {
       return datastore.getStorage(key);
   }
}

contract ClientFactory {

   event LogNewClientCreated(address sender, address newClient);

   function createClient(address storageContract) public returns(address newClient) {
       Client c = new Client(storageContract);
       LogNewClientCreated(msg.sender, c);
       return c;
   }
}

我使用了 Remix,它非常適合膚淺的測試和實驗。

  1. 部署“儲存”並複制地址。客戶需要知道該地址才能找到它並與之通信。那不是繼承。發生的情況是客戶端被編譯為字節碼,在這樣做的同時,編譯器可以“看到”引用的儲存原始碼並找出客戶端將用來與之對話的函式簽名。由於客戶端還需要知道實際部署的地址(部署的實例),我們將把該資訊傳遞給客戶端的建構子。將儲存合約地址複製到剪貼板以進行第 3 步。
  2. 部署一個“ClientFactory”。
  3. 使用 ClientFactorycreateClient()功能,使其部署一個新的客戶端。客戶端的建構子需要一個 Storage 實例的地址(來自步驟 1)。將其傳遞給函式(用引號括起來)。工廠只是相信它是真實的,並盲目地傳遞它。新的客戶契約地址已記錄,因此您可以立即查看。
  4. 向上滾動到客戶契約。就 Remix 而言,從未部署過任何“客戶端”。使用AT按鈕粘貼您從第 3 步獲得的已部署合約地址(無引號)。你基本上是在說,“你知道界面應該是什麼樣子。你會在這個地址找到一個實例。”
  5. 在客戶端中使用 set/get 函式。他們依靠儲存合約來實現持久性。

希望能幫助到你。

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