3

I have been testing a contract using the Solidity Browser, but when I deploy the same contract on my private node, it doesn't seem to work the same as in the Solidity Browser. I have tried manually compiling the code of the contract and it didn't make any difference.

Here is the contract:

pragma solidity ^0.4.2;

contract Mortal {
address owner;

event Killed(address indexed from);

function Mortal() {
    owner = msg.sender;
}

function kill() {
    if (msg.sender == owner) {
        Killed(owner);
        suicide(owner);
    }
}
}

contract Voting is Mortal {
struct Voter {
    address voterAddress;
    uint hasRightToVote;
    uint voted;
    address delegate;
}

struct Slide {
    uint number;
    uint voteCount;
    uint score;
    uint avgScore;
}

address public chairperson;

mapping(address => Voter) public voters;
mapping(uint => Slide) public slides;

uint public totalSlides;
uint public totalVotes;
uint public totalVoters;


event GivenRightToVote(address indexed chairperson, address indexed voter);
event hasVoted(address indexed voter, uint indexed slideNumber, uint indexed slideScore);
event hasDelegated(address indexed voter, address indexed delegate);
event VoterAlreadyExists(address indexed voter);
event VoterCreated(address indexed voter);
event VoterNotExists(address indexed voter);
event SenderNotChairperson(address indexed sender);
event callInitVoter(address indexed voter, address indexed sender);
event invalidVoter(address indexed voter);
event callGiveRightToVote(address indexed voterAddr);
event initSlideVote(address indexed voterAddr, uint indexed slide);
event VoterNoRightToVote(address indexed voter);

function Voting(uint numberSlides) {
    uint i;
    for (i = 0; i < numberSlides; i++) {
        slides[i] = Slide(i, 0, 0, 0);
    }
    chairperson = msg.sender;
    initVoter(msg.sender);
    voters[msg.sender].hasRightToVote = 1;
    totalSlides = numberSlides;
    totalVoters = 1;
}

function getSlide(uint slideNumber) returns (uint number, uint score, uint voteCount) {
    score = slides[slideNumber].score;
    voteCount = slides[slideNumber].voteCount;
    number = slides[slideNumber].number;
    return(number, score, voteCount);
}

function getSlideVoteCount(uint slideNumber) returns (uint voteCount) {
    voteCount = slides[slideNumber].voteCount;
    return voteCount;
}

function initVoter(address voterAddr) {
    callInitVoter(voterAddr, msg.sender);
    if(voterAddr == address(0)) {
        invalidVoter(voterAddr);
    }
    if(msg.sender == chairperson) {
        if(voters[voterAddr].voterAddress == voterAddr) {
            VoterAlreadyExists(voterAddr);
        } else {
            VoterNotExists(voterAddr);
            voters[voterAddr] = Voter(voterAddr, 0, 0, address(0));
            totalVoters += 1;
        }
        VoterCreated(voterAddr);
    } else {
        SenderNotChairperson(msg.sender);
    }
}

event unauthorizedCallerGiveRightToVote(address indexed voter);
function giveRightToVote(address voterAddr) {
    callGiveRightToVote(voterAddr);
    if(msg.sender == chairperson) {
        if(voters[voterAddr].voterAddress == 0x0000000000000000000000000000000000000000) {
            VoterNotExists(voterAddr);
            initVoter(voterAddr);
        } else {
            VoterAlreadyExists(voterAddr);
        }
        voters[voterAddr].hasRightToVote = 1;
        GivenRightToVote(chairperson, voterAddr);
    } else {
        unauthorizedCallerGiveRightToVote(voterAddr);
    }
}

event callVote(address indexed voter, uint indexed slide, uint256 indexed score);
event VoterNotAllowedToVote(address indexed voter);
event VoterAllowedToVote(address indexed voter);
event ChairpersonNotAllowedToVote(address indexed voter);
event VoterExists(address indexed voter);
function vote(uint slide, uint256 score) {
    Voter voter;
    callVote(msg.sender, slide, score);
    if(msg.sender == chairperson) {
        ChairpersonNotAllowedToVote(msg.sender);
    } else {
        if(msg.sender == address(0)) {
            VoterNotExists(msg.sender);
        } else {
            voter = voters[msg.sender];
            if(voter.hasRightToVote != 1) {
                VoterNoRightToVote(msg.sender);
            } 
            if(voter.hasRightToVote == 1) {
                VoterExists(msg.sender);
                VoterAllowedToVote(msg.sender);
                voter.voted += 1;
                totalVotes ++;
                slides[slide].voteCount += 1;
                slides[slide].score += score;
                hasVoted(msg.sender, slide, score);
            }
        }
    }
}

function vote2(uint slide, uint score) {
    Voter voter;
    callVote(msg.sender, slide, score);
    voter = voters[msg.sender];
    if(voter.voterAddress != address(0)) {
        VoterExists(msg.sender);
        if(msg.sender != chairperson) {
            if(voter.hasRightToVote == 1) {
                VoterAllowedToVote(msg.sender);
                voter.voted ++;
                totalVotes ++;
                slides[slide].voteCount ++;
                slides[slide].score += score;
                hasVoted(msg.sender, slide, score);
            } else {
                VoterNoRightToVote(msg.sender);
            }
        } else {
            ChairpersonNotAllowedToVote(msg.sender);
        }
    } else {
        VoterNotExists(msg.sender);
    }
}

function vote3(uint slide, uint score) {
    Voter voter = voters[msg.sender];
    callVote(msg.sender, slide, score);
    VoterExists(msg.sender);
    VoterAllowedToVote(msg.sender);
    voter.voted += 1;
    totalVotes += 1;
    slides[slide].voteCount += 1;
    slides[slide].score += score;
    hasVoted(msg.sender, slide, score);
}

function winningSlide() constant returns (uint winningSlide) {
    uint winningScore = 0;
    for (uint p = 0; p < totalSlides; p++) {
        if (slides[p].score > winningScore) {
            winningScore = slides[p].score;
            winningSlide = p;
        }
    }
    return(winningSlide);
}

// Calls winningProposal() function to get the index
// of the winner contained in the proposals array and then
// returns the name of the winner
function winnerCount() constant returns (uint voteCount) {
    uint winnerSlide;
    winnerSlide = winningSlide();
    voteCount = slides[winnerSlide].voteCount;
    return(voteCount);
}

function winnerScore() constant returns (uint score) {
    uint winnerSlide = winningSlide();
    score = slides[winnerSlide].score;
    return(score);
}

    // Delegate vote to address _to_
function delegate(address to) {
    Voter sender = voters[msg.sender];
    if (sender.voted != 0) throw;

    while (voters[to].delegate != address(0) &&
           voters[to].delegate != msg.sender)
        to = voters[to].delegate;

    if (to == msg.sender)
        throw;

    for (uint i = 0; i < totalSlides; i++) sender.voted += 1;

    sender.delegate = to;
    Voter delegate = voters[to];
    hasDelegated(msg.sender, to);
}
}

The biggest issue has been with the vote functions (vote, vote2 and vote3). I started with vote and couldn't get it to work, so I ended up creating a simpler version of it, which is vote3. Whenever I execute it against my private node, it doesn't send any event. I can see the transaction being mined, but I get no Event despite having defined a listener for all the events. I can see Events from other functions, such as initVoter, but I can't get the vote, vote2 or vote3 functions to work. In my mind, vote3 should trigger the event the callVote event, but it doesn't seem to.

If I run the > voting.initVoter(eth.accounts[1], {from: eth.accounts[0]});, I get the following events:

> callInitVoter:{"sender":"0xdf5642b3889f4a90a2d9e0c8475e30337cb8ba4f","voter":"0xbc006b353770becc7fdecfd11eff9633a3ea651f"}
VoterNotExists: {"voter":"0xbc006b353770becc7fdecfd11eff9633a3ea651f"}
VoterCreated: {"voter":"0xbc006b353770becc7fdecfd11eff9633a3ea651f"}

If I run > voting.giveRightToVote(eth.accounts[1], {from: eth.accounts[0]});, I get the following events:

> callGiveRightToVote: {"voterAddr":"0xbc006b353770becc7fdecfd11eff9633a3ea651f"}
VoterAlreadyExists: {"voter":"0xbc006b353770becc7fdecfd11eff9633a3ea651f"}
GivenRightToVote: {"chairperson":"0xdf5642b3889f4a90a2d9e0c8475e30337cb8ba4f","voter":"0xbc006b353770becc7fdecfd11eff9633a3ea651f"}

but if I run > voting.vote3(1, 123, {from: eth.accounts[0]});, I get nothing, no events whatsoever.

If I check some of the variables being updated by the functions, they are not being updated. The reason for so many events is that I have been using them to troubleshoot the code.

In the Solidity Browser, though, it shows all the Events being triggered and the variables as being updated.

I am pretty new at this and i have no idea what is happening here.

My private node is runnning geth version 1.5.3-unstable, but I have also tried it on a separate node running geth version 1.4.8-stable and i had the same issue. The Solidity version is 0.4.4+commit.4633f3de.Linux.g++ .

As an aside, I have also ran the contract through Mist and it works perfectly fine. All the events are being triggered and the variables updated.

I am at a total loss.

Thanks a lot in advance for the help, Bertrand.

Edit: I figured it out. The contract was working perfectly well, but the transactions were running out of gas, so they weren't completing, hence why the events never got triggered. By specifying the gas: option, it worked fine.

  • Your solidity version? – niksmac Nov 29 '16 at 15:02
  • I am using Solidity version 0.4.4+commit.4633f3de.Linux.g++. I have tried setting the Solidity version in the Solidity Browser to the same version and it still works fine there, but not on my private node. – dbblackdiamond Nov 29 '16 at 16:39
  • Welcome to Ethereum! Please don't delete content from Ethereum Stack Exchange, if you found a solution for your problem, you can always self-answer your question explaining how you did it. – Waqar Lim Jan 6 '17 at 12:32

Your Answer

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

Browse other questions tagged or ask your own question.