0

I have a contract ElectionMaster that contains an array with all elections available in the network. When I create a new Election it calls a function addElection from ElectionMaster and registers itself. Everything used to work just fine in my private network, but suddenly it fails all the time. It still works in remix by using the JavaScriptVM but it fails when it tries the first interaction with ElectionMaster. Here are the simplified contracts (It successfully deploys ElectionMaster, but any attempt on Election fails at the second line in the constructor, when I check whether the user is an organiser or not, at STATIC CALL opcode). The weird part is that it used to work, but now it works only in JavaScriptVM. And of course that I checked the address of ElectionMaster and it is the correct one:

pragma solidity 0.5.4;
contract ElectionsMaster {

address private ownerMasterAddress = msg.sender;

address[] private elections;
bytes32[] private electionsNames;

mapping(address => uint8) private organizersMapping;

constructor() public {
    organizersMapping[msg.sender] = 1;
}

modifier isMasterAccount(address senderAddress) {
    require(senderAddress == ownerMasterAddress, "Master privileges required");
    _;
}

modifier isOrganizer(address senderAddress) {
    require(organizersMapping[senderAddress] != 0, "Organizer privilleges required");
    _;
}

function () external payable {
}

function changeOwnerMasterAccount(address newOwnerMasterAccount) public isMasterAccount(msg.sender) {
    organizersMapping[newOwnerMasterAccount] = 0;
    ownerMasterAddress = newOwnerMasterAccount;
    organizersMapping[newOwnerMasterAccount] = 1;
}

function addOrganizer(address newOrganizer) public isMasterAccount(msg.sender) {
    organizersMapping[newOrganizer] = 1;
}

function getBalance() public view isMasterAccount(msg.sender) returns(uint) {
    return address(this).balance;
}

function addElection(address electionAddress,
                    bytes32 electionName,
                    address organizerAddress) public isOrganizer(organizerAddress) {
    elections.push(electionAddress);
    electionsNames.push(electionName);
}

function getElectionAddresses() public view returns(address[] memory) {
    return elections;
}

function getElectionNames() public view returns(bytes32[] memory) {
    return electionsNames;
}

function canAddressDeployContract(address organizerAddress) public view returns(bool) {
    return (organizersMapping[organizerAddress] == 1);
}

}

and Election:

pragma solidity 0.5.4;

contract ElectionMaster {
function addElection(address electionAddress,
    bytes32 electionName,
    address organizerAddress) public {}

function canAddressDeployContract(address organizerAddress) public view returns(bool) {}
}

contract Election {

ElectionMaster private electionMaster;
mapping(address => uint8) private voters;
bytes32 private electionName;

constructor(address masterContractAddress, bytes32 nameOfElection) public {
    electionMaster = ElectionMaster(masterContractAddress);
    bool canDeploy = electionMaster.canAddressDeployContract(msg.sender);
    require(canDeploy == true, "Organizer permissions required to deploy a contract.");
    electionMaster.addElection(address(this), nameOfElection, msg.sender);

    electionName = nameOfElection;
}
}
  • There are two ElectionMaster implementations hre. Which one are you using, and why have you posted the other one? – goodvibration Jun 15 at 7:22
  • The small implementation provides the api of ElectionMaster to Election (they are in separate files). So far I was able to solve the problem by upgrading both Go Ethereum and Solidity (1.8.25 and 5.7) and recreating the network with Byzantium and Constantinople blocks in genesis.json. The interesting part is that 1 month ago (before taking a break from the project) it worked awesome, and today it just simply failed to execute the transactions that used to work. I didn't update any component so I can't explain what happened. – Bogdan Jun 15 at 7:52
  • So your post is misleading. This is not an api, but an actual implementation. For it to be an api, those functions should end with ;, not with {}. – goodvibration Jun 15 at 8:04
  • This is the tutorial that I followed: medium.com/@blockchain101/… . Here it uses { } instead of ; . It should work with both situations. – Bogdan Jun 15 at 8:20
0

So I managed to solve the problem by upgrading both Go Ethereum (1.8.25) and Solidity (0.5.7) and recreating the network, this time using Byzantium and Constantinople blocks in genesis.json. Here is how it looks right now:

{
    "config": {
    "chainId": 2019,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    // the following blocks were not specified in the previous version of genesis.json
    "byzantiumBlock": 0,
    "constantinopleBlock": 0
    },
    "difficulty": "400",
    "gasLimit": "200000000000",
    "alloc": {
           ...
    }
 }

The interesting part is that I didn't touch the project for 1 month and it used to work just fine at that moment. I was using Go Ethereum 1.8.22 and Solidity 0.5.4 without Byzantium and Constantinople.

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.