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