Greifen Sie mit Getter auf die öffentliche Zustandsvariable zu, funktioniert nicht

Ich habe mit dem Abstimmungsvertragsbeispiel gearbeitet und es mit Truffle und Javascript getestet. Bisher habe ich es geschafft, jede Funktion aus meinem Vertrag mit Erfolg zu testen. Aber als ich versuchte, die Eigenschaft CandidateList abzurufen, funktionierte es nicht. Teil der Testdatei

...
it('returns every candidate', async () => {
    let fundRaise = await Voting.new(['Alice', 'Bob', 'Rick']);

    const cands = await voting.candidateList();
    Console.log(cands);
});
...

Wenn ich den obigen Test durchführe, zeigt Truffle Folgendes

1) Contract: Voting returns every candidate:
 Error: Invalid number of arguments to Solidity function
  at Object.InvalidNumberOfSolidityArgs (/usr/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/errors.js:25:1)
  at SolidityFunction.validateArgs (/usr/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/function.js:74:1)
  at SolidityFunction.toPayload (/usr/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/function.js:90:1)
  at SolidityFunction.call (/usr/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/function.js:131:1)
  at SolidityFunction.execute (/usr/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/function.js:260:1)
  at /usr/lib/node_modules/truffle/build/webpack:/~/truffle-contract/contract.js:135:1
  at new Promise (<anonymous>)
  at /usr/lib/node_modules/truffle/build/webpack:/~/truffle-contract/contract.js:126:1
  at <anonymous>
  at process._tickDomainCallback (internal/process/next_tick.js:228:7)

Was ich nicht verstehe, ist, warum web3 diese Nachricht ausgibt, wenn die Getter-Funktion automatisch generiert wird. Ich habe Truffle v4.1.7 (Kern: 4.1.7); Solidität v0.4.23 (solc-js); Geth/v1.8.1-stable-1e67410e/linux-amd64/go1.9.4"; Web3-Version api: '0.20.6',

Unten ist die Vertragsdatei sowie die Testdatei.

pragma solidity ^0.4.17;

contract Voting {

mapping (bytes32 => uint8) public votesReceived;
bytes32[] public candidateList;

constructor(bytes32[] _candidates) public {
    candidateList = _candidates;
}

function voteForCandidate(bytes32 _name) public returns (uint8) {
    require(validateCandidate(_name));
    votesReceived[_name] += 1;
    //return votesReceived[_name];
    return totalVotesFor(_name);
}

function validateCandidate(bytes32 _name) view public returns (bool){
    for (uint8 i = 0; i < candidateList.length; i++) {
        if(candidateList[i] == _name){
            return true;
        }
    }
    return false;
}

function totalVotesFor(bytes32 name) view public returns (uint8){
    require(validateCandidate(name));
    return votesReceived[name];
}

function addCandidate(bytes32 _name) public returns (bool) {
    candidateList.push(_name);
    return validateCandidate(_name);
}


const assert = require('assert');
var Voting = artifacts.require("Voting");

Dies ist die Testdatei:

contract('Voting', function(accounts) {

let voting;

beforeEach(async () => {
    voting = await Voting.deployed();
});

it('votes for valid candidate', async () => {

    const voto = await voting.voteForCandidate.call('Andrea');

    assert.equal(voto.toNumber(),1, 'Cannot vote for valid candidate');
});

it('Does not vote for invalid candidate', async () => {
    const voto = await voting.voteForCandidate.call('Bacilio');

    assert.equal(voto.toNumber(), 0, 'Allowed to vote for invalid candidate');
});

it('Adds new candidate', async () => {
    const voto = await voting.addCandidate.call('Segismundo');
    assert.equal(voto, true, 'Did not allow to add new candidate');
});

it('allows to obtain votes casted for a candidate', async () => {

    const expected_votes = 2;

    //vote twice for the same candidate
    await voting.voteForCandidate('Roberto');
    await voting.voteForCandidate('Roberto');

    let casted_votes = await voting.totalVotesFor.call('Roberto');
    assert.equal(casted_votes.toNumber(), expected_votes, 'Did not got casted votes')

});

it('returns every candidate', async () => {
    let fundRaise = await Voting.new(['Segismundo', 'Ocatvia']);

    const cands = await voting.candidateList();
    Console.log(cands);
});

});

Antworten (1)

Fügen Sie in Ihrem Solidity-Code Folgendes hinzu:

function candidateListLength() external view returns (uint) {
    return candidateList.length;
}

Fügen Sie in Ihrem Javascript-Code Folgendes hinzu:

let cands = [];
let length = Number(await voting.candidateListLength());
for (let i = 0; i < length; i++)
    cands.push(await voting.candidateList(i));
Es hat funktioniert, danke! Nur um das klarzustellen, wann immer Sie auf die Array-Variable eines Vertrags zugreifen möchten. Sie müssen einen bestimmten Index zum Abrufen angeben, das Abrufen des gesamten Arrays wird nicht unterstützt?