Acceda a la variable de estado público con getter, no funciona

He estado trabajando con el ejemplo del contrato de votación y he estado probando unidades con Truffle y Javascript. Hasta ahora he logrado probar todas las funciones de mi contrato con éxito. Pero cuando traté de recuperar la propiedad de lista de candidatos, no funcionó. Parte del archivo de prueba

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

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

Cuando ejecuto la prueba anterior, truffle muestra lo siguiente

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)

Lo que no entiendo es por qué si la función getter se genera automáticamente, web3 arroja este mensaje. Tengo Trufa v4.1.7 (núcleo: 4.1.7); Solidez v0.4.23 (solc-js); Geth/v1.8.1-stable-1e67410e/linux-amd64/go1.9.4"; API de versión web3: '0.20.6',

A continuación se muestra el archivo del contrato, así como el archivo de prueba.

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");

Este es el archivo de prueba:

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);
});

});

Respuestas (1)

En su código Solidity, agregue:

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

En su código Javascript agregue:

let cands = [];
let length = Number(await voting.candidateListLength());
for (let i = 0; i < length; i++)
    cands.push(await voting.candidateList(i));
¡Funcionó, gracias! Para que quede claro, cada vez que desee acceder a la variable de matriz de un contrato. Debe proporcionar un índice específico para obtener, ¿no se admite la obtención de toda la matriz?