Не могу добавить числа в массив на Solidity

у меня есть функция, которая получает число, autentic оценивает, находится ли оно уже в массиве, если это так, оно должно возвращать false, если нет, возвращать true. Тогда onlyOneVote добавит число в массив, если оно истинно, а не ложно. Проблема в том, что функция никогда ничего не добавляет в массив.

uint32[100] public people;
uint8 public counter;

function onlyOneVote(uint32 ida) public returns(bool) {
  bool a = autentic(ida);
  if (a == true) {
    people[counter] = ida;
    counter = counter + 1;
  }
  return a;
}

function autentic(uint32 idb) public returns(bool) {
  bool b;
  for(uint i = 0; i< people.length; i++) {
    if (people[i] == idb) {
      b = false;
      break;
    } else {
      b = true;
    }
  }
  return b;
} 

Ответы (2)

Я думаю, можно с уверенностью сказать, что ваш код можно сократить до этого:

uint32[100] public people;
uint8 public counter;

mapping (uint32 => bool) public alreadyVoted;

function vote(uint32 id) public returns(bool) {
  if (alreadyVoted[id]) return(false);
  alreadyVoted[id] = true;
  people[counter] = id;
  counter = counter + 1;
  return(true);
}

Назовите это с помощью web3 следующим образом:

contractInstance.vote.sendTransaction(id, {from: _from});

где _fromнаходится адрес вашей учетной записи (возможно, web3.eth.accounts[0]).

все та же проблема. при тестировании с идентификаторами в массиве нет новых идентификаторов, он все еще пуст после теста: > contractInstance.vote.call(1) true > contractInstance.vote.call(1) true
В Ethereum вы можете вызывать функции в контрактах, используя два разных метода: call() или sendTransaction(). Когда функция изменяет состояние блокчейна (и это относится к этой функции), вы должны использовать sendTransaction().
Спасибо. У меня последний вопрос, о каком «адресе счета» вы говорите? не понимаю эту часть.. Извините за столько вопросов XD
Адрес счета, с которого происходит транзакция. Вы можете использовать аккаунты[0]
он отправляет мне «Ошибка ссылки: учетные записи не определены
Извините, моя ошибка, я имел в виду web3.eth.accounts[0].

Этот код сделает это, он протестирован и вот вам адрес для взаимодействия с ним на Kovan: 0xc807caebda01eaffd7998ab7fd9fcc4a2cf5730c

pragma solidity ^0.4.18; 


contract Test {

uint32[100] public people;
uint256 public counter; // Is uint256 because the on the array[100], 100 is a uint256 variable.
mapping(uint32 => bool) public voteVerifier; //mapping saves you so much gas at checking if it's in the array


function onlyOneVote(uint32 ida) public returns(bool) {
  require(!voteVerifier[ida]); //If false, enter to add the uint32 to array.

    people[counter] = ida; //Add the ida to the array
    counter = counter + 1;

    voteVerifier[ida] = true;//Set on the mapping that this uint32 is now on the array.
  return true;
}

}

Несколько вещей, чтобы прокомментировать:

  • Гораздо лучше использовать сопоставление, чтобы проверить, находится ли число в массиве, потому что это не зависящий от времени поиск . Поиск параметров в массивах заставляет вас работать гораздо больше, чем больше становится массив . Но с сопоставлениями поиск длится и стоит столько же, даже если в массив включены миллионы значений .

Здесь у вас есть информация: http://solidity.readthedocs.io/en/v0.4.21/types.html#mappings

Этот код:people[counter] = ida; //Add the ida to the array counter = counter + 1;

Можно заменить, чтобы быть точнее и дешевле по расходу газа:people.push(ida)//Puts on the last array's position the item ida;

Надеюсь, поможет!!

Вы не можете нажать на массив с определенным размером. people.push(id) не будет компилироваться.
Я знаю, поэтому его нет в коде решения, это просто совет :)
Спасибо за полезные советы по картированию, чтобы использовать намного меньше газа. я мог бы использовать определенный массив или сопоставление «не по размеру», потому что проблема с бесконечным циклом, и в этом случае я знаю количество избирателей, я начал использовать push, но не компилировал.
Как сказал bordalix, push можно использовать только с динамическими массивами, а не с фиксированными. Таким образом, чтобы ограничить количество голосов, если вы знаете, что оно равно 100, сделайте требование к функции, которая добавляет числа в массив, управляющий им.