Contract-Development

如何訪問由另一個(已部署)合約部署的合約?

  • December 31, 2018

我目前正在研究以特定選舉制度為模型的投票契約。

我的意圖是首先手動部署 MasterConstituency 合約,並讓該合約部署 BaseConstituency 合約的多個實例。最終,我會將 BaseConstituencies 的所有權轉移到獨立運營的不同地址。

我有兩份契約;即

主選區.sol

pragma solidity ^0.4.24;

import "./Ownable.sol";
import "./BaseConstituency.sol";

contract MasterConstituency is Ownable {
   enum ConstituencyType {FEDERAL, STATE}
   uint totalVotes;

   modifier isValidConstituencyType(uint _constituencyType){
       require(uint(ConstituencyType.STATE) >= _constituencyType);
       _;
   }

   modifier isUniqueParty(string _name){
       for (uint x = 0; x < parties.length; x++) {
           if (compareStrings(parties[x].name, _name)) {
               revert();
           }
       }
       _;
   }

   struct Party {
       string name;
       string abbreviation;
   }

   struct Candidate {
       string name;
       uint numVotes;
       bool validCandidate;
   }

   struct Voter {
       bool hasVoted;
       bool validFederalVote;
       bool validStateVote;
       uint federalCandidateVote;
       uint stateCandidateVote;
   }

   Candidate[] candidates;
   Party[] parties;

   mapping(string => Voter) votes;
   mapping(string => address) constituencies;
   mapping(uint => uint) candidateToParty;

   function initialiseConstituency(
       uint _constituencyType,
       string _constituencyCode,
       string _constituencyName) public onlyOwner() isValidConstituencyType(_constituencyType) returns (address) {
       address constituency = new BaseConstituency(_constituencyType, _constituencyName);
       constituencies[_constituencyCode] = constituency;

       return constituency;
   }

   function registerParty(string _name, string _abbreviation) public onlyOwner() isUniqueParty(_name) {
       parties.push(Party(_name, _abbreviation));
   }

   function getConstituencyAddress(string _constituencyCode) public view returns (address) {
       return constituencies[_constituencyCode];
   }

   function compareStrings(string a, string b) public pure returns (bool){
       bytes32 c = keccak256(abi.encodePacked(a));
       bytes32 d = keccak256(abi.encodePacked(b));

       return c == d;
   }
}

基本選區.sol

pragma solidity ^0.4.24;

import "./Ownable.sol";

contract BaseConstituency is Ownable {
   uint numVotes;
   uint constituencyType;
   string constituencyName;

   struct Candidate {
       string name;
       uint numVotes;
       bool validCandidate;
   }

   struct Voter {
       bool hasVoted;
       bool validVote;
       uint candidateVote;
   }

   Candidate[] candidates;

   constructor(uint _constituencyType, string _constituencyName) public{
       numVotes = 0;
       constituencyType = _constituencyType;
       constituencyName = _constituencyName;
   }

   function getStuff() public view returns(uint, string){
       return (constituencyType, constituencyName);
   }

}

我正在使用的 Ownable 合約: https ://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/ownership/Ownable.sol

它仍在進行中,我還沒有實現正確的智能合約所需的所有功能。我目前正在 Remix IDE 和 Ganache(當然使用 MetaMask)上開發和測試智能合約,但我面臨的問題是在 Rinkeby 測試網上模擬的。

目前,我正在嘗試與通過 Remix 部署的 BaseConstituency 合約進行互動。initialiseConstituency當我打電話並隨後獲取已部署的 BaseConstituency 合約的地址時,就會出現我面臨的問題。

使用參數初始化選區:{“0”,“foo”,“foobar”} 並檢索到地址:0x97114Ffc3f8D9556Ef250F15B416038f393504b0

我在 Remix 中載入了檢索到的 BaseConstituency 合約地址,但這是顯示的內容:

不是應該顯示 BaseConstituency 嗎?

通過 Remix,地址似乎沒有指向預期的 BaseConstituency 合約,而是指向 MasterConstituency 合約。

我期待在 Rinkeby Etherscan 上看到這樣的內容:

而不是這個…

但相反,我看到了這個:

我什麼也沒看見。

我還意識到部署的 BaseConstituency 合約的所有者是 MasterConstituency 合約的地址,但這可以通過將所有權轉移給 MasterConstituency 的所有者來糾正。

**我想知道為什麼會這樣。**我是否必須通過 MasterConstituency 進行溝通才能到達 BaseConstituency?我對契約到契約部署的理解很可能是錯誤的,因此對我目前設計的任何建議或建議都表示讚賞。

PS我為很長的文章道歉,但我相信對問題的詳細描述是最好的方法。

答案相當簡單。

在混音程式碼編輯器中擁有兩個合約的程式碼。

在點擊“地址”之前,請務必從下拉菜單中選擇正確的合約。

在此處輸入圖像描述

在此處輸入圖像描述

說明:與已部署的合約互動需要 2 項:地址和應用程序二進制介面(ABI)。

ABI 是一個 JS 對象,它描述了合約上所有可用的方法簽名。

ABI 是由編譯器生成的,所以我猜 remix 會在編輯器中編譯程式碼並在後台使用生成的 ABI。

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