Невозможно получить значение от вызова постоянной функции с помощью web3js и Metamask

У меня есть чрезвычайно простой контракт, развернутый на Ropsten:

pragma solidity ^0.4.16;

contract hypergrowth {
  uint256 public someNumber = 5;

  function hypergrowth() public {}

  function changeNumber(uint256 number) public {
    someNumber = number;
  }

  function getNumber() public constant returns (uint256 someNumber) {
    return someNumber;
  }
}

Я использую web3js и Metamask для взаимодействия с развернутым контрактом.

Я могу инициализировать web3. Я могу получить основную учетную запись от Metamask. Но я всегда получаю 0, когда вызываю getNumber(). Вот функции, которые я использую с web3:

function getNumberFromContract(contract) {
  contract.getNumber( (err, res) => {
    console.log(res.toNumber());
  });
}

function setNumberFromContract(contract) {
  contract.changeNumber(10, function(err,res){
    console.log("done");
  });
}

Я не понимаю, почему я получаю 0... Я даже не вижу, работает ли setNumber().

Что я делаю неправильно?

ОБНОВЛЯТЬ:

Я использую этот код, чтобы дождаться выполнения функции getNumber:

var deferred = new $.Deferred();
  setTimeout(function () {
    deferred.resolve(getNumberFromContract(hyperContract));
  }, 5000);

И все равно получить 0.

ОБНОВЛЕНИЕ 2:

Вот как я получаю контракт:

var address = '0xbabd1c95906d4ebec8977a7d0f32410ecba1103f';
var abi = [
  {
    "constant": true,
    "inputs": [],
    "name": "getNumber",
    "outputs": [
      {
        "name": "",
        "type": "uint256"
      }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
  },
  {
    "constant": false,
    "inputs": [
      {
        "name": "number",
        "type": "uint256"
      }
    ],
    "name": "changeNumber",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "constructor"
  }
];
var hyperContract = getContract(abi, web3.eth.accounts[0], web3);

Функция getContractтакова:

function getContract(ABI, address, web3) {
  return web3.eth.contract(ABI).at(address);
}

Ответы (3)

Мне кажется, что вы вызываете свою функцию «getContract» с адресом EOA, а не с адресом контракта!

изменять :

var hyperContract = getContract(abi, web3.eth.accounts[0], web3);

к :

var hyperContract = getContract(abi, address, web3); // (As address var is defined above)

Вам нужно дождаться завершения транзакции.

Эта строка:

console.log("done");

следует точнее читать:

console.log("sent");

Вы можете вывести квитанцию ​​о транзакции для хихиканья ( res). Следующим шагом является периодическая проверка, чтобы убедиться, что транзакция заминирована. После того, как он будет добыт/подтвержден, вы можете продолжить работу со своим геттером, и, основываясь на простом просмотре кода, похоже, что он будет работать.

Вот суть, которая показывает, как дождаться подтверждения, прежде чем перейти к следующему шагу.

https://gist.github.com/xavierlepretre/88682e871f4ad07be4534ae560692ee6

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

Я попытался с отложенным объектом и подождал 5 секунд. Все еще не работает. Я обновил свой вопрос с кодом

Другая проблема с вашей функцией заключается в том, что возвращаемая переменная someNumberзатеняет глобальную переменную с тем же именем someNumber.

uint256 public someNumber = 5;

// ..

function getNumber() public constant returns (uint256 someNumber) {
    return someNumber;    //   <---  Here someNumber is 0
}