I modified your code just to change the Solidity version to match my environment:
pragma solidity ^0.4.2;
contract Ballot {
// 投票人结构体
struct Voter {
bytes32 name;
bool voted; // 是否已经投过票
uint vote; // 投给谁了
uint givenRightTime; // 被授权时间
uint votetime; // 投票时间
}
// 候选项结构体
struct Proposal {
bytes32 name;
uint voteCount;
}
address public chairperson; // 投票发起人
mapping(address => Voter) public voters; // 投票群众
Proposal[] public proposals; // 候选选项
event voteCast(address from, bytes32 proposal, uint voteTime);
// 构造方法
function Ballot(bytes32[] proposalNames) {
chairperson = msg.sender;
// 初始化候选项
for(uint i = 0; i < proposalNames.length; i++) {
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
}
function giveRightToVote(address voter, bytes32 voterName) {
// 如果不是投票发起人分配,或者分配的地址已经投过,抛异常
if(msg.sender != chairperson || voters[voter].voted) {
//throw;
}
voters[voter].name = voterName;
voters[voter].voted = false;
voters[voter].votetime = 0;
voters[voter].givenRightTime = now;
}
// 投票
function vote(uint proposalIndex) {
Voter sender = voters[msg.sender];
// 检查是否已经投过
if(sender.voted) {
throw;
}
proposals[proposalIndex].voteCount += 1;
// 修改状态
sender.voted = true;
sender.votetime = now;
sender.vote = proposalIndex;
voteCast(msg.sender, proposals[proposalIndex].name, now);
}
// 获取获胜者编号
function winningProposalIndex() constant
returns (uint winningProposalIndex)
{
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
winningProposalIndex = p;
}
}
}
// 获取获胜者姓名
function winnerName() constant
returns (bytes32 winnerName)
{
winnerName = proposals[winningProposalIndex()].name;
}
}
And loaded your code into Browser Solidity, connected to my --dev
geth
instance with eth.accounts[0]
unlocked.

I executed the transaction giveRightToVote(...)
with the parameters "0x0014060ff383c9b21c6840a3b14aab06741e5c49","xiaoB"
where the address is my eth.accounts[1]
.
The then called the autogenerated function voters(...)
with the parameter "0x0014060ff383c9b21c6840a3b14aab06741e5c49"
and it returned the expected results:

In geth
, I confirmed the returned value from voters(...)
using the command:
> web3.toUtf8("0x7869616f42000000000000000000000000000000000000000000000000000000")
"xiaoB"
I then ran the following in geth
:
> var abi = [{"constant":false,"inputs":[{"name":"proposalIndex","type":"uint256"}],"name":"vote","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"name","type":"bytes32"},{"name":"voteCount","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"chairperson","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"winningProposalIndex","outputs":[{"name":"winningProposalIndex","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"voters","outputs":[{"name":"name","type":"bytes32"},{"name":"voted","type":"bool"},{"name":"vote","type":"uint256"},{"name":"givenRightTime","type":"uint256"},{"name":"votetime","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"winnerName","outputs":[{"name":"winnerName","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"voter","type":"address"},{"name":"voterName","type":"bytes32"}],"name":"giveRightToVote","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"proposalNames","type":"bytes32[]"}],"type":"constructor","payable":true},{"anonymous":false,"inputs":[{"indexed":false,"name":"from","type":"address"},{"indexed":false,"name":"proposal","type":"bytes32"},{"indexed":false,"name":"voteTime","type":"uint256"}],"name":"voteCast","type":"event"}];
undefined
> var addr = "0x0d41ff746994e76fd0ad575ca852e447559e8089";
undefined
> var ballot1 = eth.contract(abi).at(addr);
undefined
> ballot1.giveRightToVote.sendTransaction(eth.accounts[2], 'account2user', {from:eth.accounts[0]});
"0x07c24de5b92499f05570a2c648bc8f30ae7a23676bddf29ad00aea4a8b21da58"
// Wait for the transaction to be mined, then check it worked correctly
> eth.getTransactionReceipt("0x07c24de5b92499f05570a2c648bc8f30ae7a23676bddf29ad00aea4a8b21da58")
{
blockHash: "0xf11c183e434266199912cfbb97984c7a527f0c0858dd238dd5bca290cf8c4190",
blockNumber: 30084,
contractAddress: null,
cumulativeGasUsed: 74723,
from: "0x000d1009bd8f0b1301cc5edc28ed1222a3ce671e",
gasUsed: 74723,
logs: [],
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
root: "0x6095d7e4c505418b78d12034270b4d88c27d4921c71cbd1767d525cb3c8c5319",
to: "0x0d41ff746994e76fd0ad575ca852e447559e8089",
transactionHash: "0x07c24de5b92499f05570a2c648bc8f30ae7a23676bddf29ad00aea4a8b21da58",
transactionIndex: 0
}
> ballot1.voters(eth.accounts[2]);
["0x6163636f756e7432757365720000000000000000000000000000000000000000", false, 0, 1482575492, 0]
> web3.toUtf8("0x6163636f756e7432757365720000000000000000000000000000000000000000");
"account2user"
Your code is working as expected. Just follow the steps above. As @Edmund Edgar
has stated, you will need to pass the account parameter to ballot1.voters(...)
.
Update Responding To Comment Below
As you are sending your transaction from from eth.accounts[0]
, you only have to unlock eth.accounts[0]
.
You may want to try Browser Solidity - it's a bit easier to interactively work out what is going on. To do this:
- Point your browser to https://github.com/ethereum/browser-solidity.
- Change Branch on the top left from master to gh-pages.
- Download the .zip file onto your computer. The current .zip file has the name
browser-solidity-6698a74.zip
.
- Unzip the .zip file into a subdirectory on your computer.
- Navigate to the new subdirectory.
- Load
index.html
in this subdirectory in your web browser.
- In Browser Solidity, select the cube icon on the top right.
- Click on Web3 Provider and confirm that you want to connect to your local Ethereum node.
- Load your Solidity code in the left pane.
- Click on the Create button after specifying your contract's constructor parameters on the input box to the right of the Create button.
- Click on the giveRightToVote button after specifying the parameters - see the screenprint I've attached.
- Click on the voters button after specifying the parameters - see the screenprint I've attached.
ballot1.giveRightToVote.sendTransaction(eth.accounts[1], 'xiaoB', {from:eth.accounts[0], gas:200000})