0

I am currently working on voting contracts modeled after a particular electoral system.

My intention is to first deploy the MasterConstituency contract manually and to have that contract deploy multiple instances of the BaseConstituency contract. Eventually, I will transfer ownership of BaseConstituencies to separate addresses that will be operated independently.

I have two contracts; namely

MasterConstituency.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;
    }
}

BaseConstituency.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);
    }

}

The Ownable contract I'm using: https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/ownership/Ownable.sol

It is still a work in progress and I have not implemented all the functions necessary for a proper smart contract. I'm currently developing and testing the smart contract on the Remix IDE and Ganache (with MetaMask of course), but the issue I'm facing is emulated on the Rinkeby testnet.

Currently, I'm attempting to interact with the BaseConstituency contract deployed through Remix. The issue I'm facing arises when I call initialiseConstituency and subsequently obtain the address of the deployed BaseConstituency contract.

Initialise constituency with parameters: {"0","foo","foobar"} and retrieved address: 0x97114Ffc3f8D9556Ef250F15B416038f393504b0

I load the retrieved BaseConstituency contract address in Remix, but this is what is shown instead:

Isn't BaseConstituency supposed to be shown instead?

Through Remix, it appears the address does not point to the expected BaseConstituency contract, but the MasterConstituency contract instead.

I was expecting to see something like this on Rinkeby Etherscan:

Instead of this...

But instead, I see this:

I see nothing.

I also realised that the owner of the deployed BaseConstituency contract is the address of the MasterConstituency contract, but that can be rectified by transferring ownership to the owner of MasterConstituency.

I would like to know why this is so. Do I have to communicate through MasterConstituency to get to BaseConstituency? It is probable that my understanding of contract-to-contract deployment is erroneous, hence any recommendation or advice to my current design is appreciated.

P.S. I apologise for the very long post, but I believe a detailed description of the issue is the best way to go.

1

The answer is fairly straightforward.

Have the code for BOTH contracts in the remix code editor.

Be sure to select the correct contract from the drop down menu before clicking "at address".

enter image description here

enter image description here

Explanation: 2 items are requires to interact with a deployed contract: the address and the Application Binary Interface (ABI).

The ABI is a JS object which describes all method signatures available on the contract.

The ABI is generated by the compiler, so I'm guessing that remix compiles the code in the editor and uses the resulting ABI under the hood.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.