多次调用时,Solidity 代码会给出 VM 异常错误
Solidity code gives VM exception error when called multiple times
让我们从我的 solidity 代码开始:
pragma solidity ^0.4.18;
contract Voting {
address mainAddress;
bytes32[] candidateNames;
mapping(bytes32 => uint) candidateVotes;
mapping(bytes32 => bytes32) candidatesDetails;
address[] voters;
function Voting() public {
mainAddress = msg.sender;
}
modifier isMainAddress {
if (msg.sender == mainAddress) {
_;
}
}
function getAllCandidates() public view returns (bytes32[]) {
return candidateNames;
}
function setCandidate(bytes32 newCandidate) isMainAddress public {
candidateNames.push(newCandidate);
}
function setVote(bytes32 candidate) public {
require(validVoters());
candidateVotes[candidate] = candidateVotes[candidate] + 1;
voters.push(msg.sender);
}
function getVote(bytes32 candidate) public view returns (uint) {
return candidateVotes[candidate];
}
function setDescrption(bytes32 candidateName, bytes32 candidatesDesc) isMainAddress public {
candidatesDetails[candidateName] = candidatesDesc;
}
function getDescription(bytes32 candidateName) public view returns (bytes32){
return candidatesDetails[candidateName];
}
function getCurrentAddress() public view returns (address) {
return msg.sender;
}
function validVoters() public view returns (bool) {
for(uint i = 0; i < voters.length ; i++){
if (voters[i] == msg.sender) {
return false;
}
}
return true;
}
}
函数:Voting()、getAllCandidates()、setCandidate()、getVote()、setDescription()、getDescription()、getCurrentAddress() 在多次调用时工作正常次。所以,我想我们现在可以忽略它们了。
函数 setVote() 在第一次执行 时运行良好。当一个人投票一次。当同一个人第二次尝试投票时,问题就出现了。它给出以下错误:
这可能是初学者的错误,但我连续 2 天都在尝试解决这个问题,现在我真的需要帮助。
此外,
我使用 Remix - 基于浏览器 IDE 到 run/check 我的 solidity 代码。
我使用 Ganache 作为测试账户。
谢谢。
有问题的函数:
function setVote(bytes32 candidate) public {
require(validVoters());
candidateVotes[candidate] = candidateVotes[candidate] + 1;
voters.push(msg.sender);
}
请注意 validVoters()
必须 return true
才能使此功能成功。如果它 returns false
,require
将失败并恢复交易。另请注意,在函数的末尾,msg.sender
被添加到数组 voters
.
我们来看看validVoters()
:
function validVoters() public view returns (bool) {
for(uint i = 0; i < voters.length ; i++){
if (voters[i] == msg.sender) {
return false;
}
}
return true;
}
这个函数returns false
如果msg.sender
在voters
,我们知道账户投票一次后就会这样。
所以第二次通过,validVoters()
returns false
,这导致 setVote()
中的 require(validVoters())
恢复交易。
让我们从我的 solidity 代码开始:
pragma solidity ^0.4.18;
contract Voting {
address mainAddress;
bytes32[] candidateNames;
mapping(bytes32 => uint) candidateVotes;
mapping(bytes32 => bytes32) candidatesDetails;
address[] voters;
function Voting() public {
mainAddress = msg.sender;
}
modifier isMainAddress {
if (msg.sender == mainAddress) {
_;
}
}
function getAllCandidates() public view returns (bytes32[]) {
return candidateNames;
}
function setCandidate(bytes32 newCandidate) isMainAddress public {
candidateNames.push(newCandidate);
}
function setVote(bytes32 candidate) public {
require(validVoters());
candidateVotes[candidate] = candidateVotes[candidate] + 1;
voters.push(msg.sender);
}
function getVote(bytes32 candidate) public view returns (uint) {
return candidateVotes[candidate];
}
function setDescrption(bytes32 candidateName, bytes32 candidatesDesc) isMainAddress public {
candidatesDetails[candidateName] = candidatesDesc;
}
function getDescription(bytes32 candidateName) public view returns (bytes32){
return candidatesDetails[candidateName];
}
function getCurrentAddress() public view returns (address) {
return msg.sender;
}
function validVoters() public view returns (bool) {
for(uint i = 0; i < voters.length ; i++){
if (voters[i] == msg.sender) {
return false;
}
}
return true;
}
}
函数:Voting()、getAllCandidates()、setCandidate()、getVote()、setDescription()、getDescription()、getCurrentAddress() 在多次调用时工作正常次。所以,我想我们现在可以忽略它们了。
函数 setVote() 在第一次执行 时运行良好。当一个人投票一次。当同一个人第二次尝试投票时,问题就出现了。它给出以下错误:
这可能是初学者的错误,但我连续 2 天都在尝试解决这个问题,现在我真的需要帮助。
此外,
我使用 Remix - 基于浏览器 IDE 到 run/check 我的 solidity 代码。
我使用 Ganache 作为测试账户。
谢谢。
有问题的函数:
function setVote(bytes32 candidate) public {
require(validVoters());
candidateVotes[candidate] = candidateVotes[candidate] + 1;
voters.push(msg.sender);
}
请注意 validVoters()
必须 return true
才能使此功能成功。如果它 returns false
,require
将失败并恢复交易。另请注意,在函数的末尾,msg.sender
被添加到数组 voters
.
我们来看看validVoters()
:
function validVoters() public view returns (bool) {
for(uint i = 0; i < voters.length ; i++){
if (voters[i] == msg.sender) {
return false;
}
}
return true;
}
这个函数returns false
如果msg.sender
在voters
,我们知道账户投票一次后就会这样。
所以第二次通过,validVoters()
returns false
,这导致 setVote()
中的 require(validVoters())
恢复交易。