Problem beim Abrufen von Daten aus dem Vertrag mit Web3 1.0

Ich habe das Gefühl, dass ich hier etwas Triviales übersehen muss. Ich habe einen intelligenten Vertrag, der eine Reihe von Strukturen füllt, die unten gezeigt werden. Wenn Sie versuchen anzurufen, addNewQuestion('0x12345')oder getQuestionListSize()es scheint, als würde nie eine neue Question-Struktur zu hinzugefügt questionList. Beim Aufrufen getQuestionListSize()sollte der Zähler zurückgegeben werden, den ich benannt habe questionId, aber er gibt immer nur "1" zurück. Jede Hilfe sehr geschätzt.

Vertrag:

pragma solidity ^0.4.11;

contract EthUpVoting {

  struct Question {
    bytes32 ipfsHash;
    uint upvotes;
    address user;
  }

  uint private questionId;
  mapping (uint => Question) public questionList;

  event AddedQuestion(bytes32 ipfs_hash, uint qId);

  function EthUpVoting() public {
    questionId = 1;
    questionList[questionId] = Question({
        ipfsHash: "Hello, World!",
        upvotes: 0,
        user: msg.sender
    });
  }

  function addNewQuestion(bytes32 questionHash) public {
      questionId += 1;
      questionList[questionId] = Question({
          ipfsHash: questionHash,
          upvotes: 0,
          user: msg.sender
      });
      AddedQuestion(questionHash, questionId);
  }

  function voteForQuestion(uint qId) public {    
    questionList[qId].upvotes += 1;
    questionId += 1;
  }

  function getQuestionTextAtIndex(uint qId) public constant returns (bytes32 ipfsHashReturn) {
      return questionList[qId].ipfsHash;
  }

   function getQuestionListSize() public constant returns (uint size) {
      return questionId;
  }

}

NodeJS:

const web3 = new Web3(Web3.givenProvider || "ws://127.0.0.1:8546")
const ethUpVotingContract = new web3.eth.Contract(config.eth.abi, config.eth.contractAddr);

ethUpVotingContract.methods.addNewQuestion('foo').send(ethOptions, (err, resp) => {
    if (err) {
      console.log(err) 
    } else {
      // successfully returns transaction hash 
      console.log(resp);
    }
}).then(resp => {
    // successfully returns transaction receipt
    console.log(resp);
});

ethUpVotingContract.methods.getQuestionListSize().call().then(function (resp) {
    // this always returns "1"
    console.log(resp);
});
Warum verwenden Sie ethUpVotingContract.methods. nicht nur ethUpVotingContract
Ich habe nur die Dokumentation befolgt: web3js.readthedocs.io/en/1.0/…
In einer früheren Version funktionierte der 'ws'-Provider nicht, ich würde 'http' und/oder 'ipc' versuchen, um zu überprüfen, ob sie funktionieren, web3 v1.0 ist noch in der Beta-Phase, daher werden einige Dinge nicht funktionieren und andere haben Fehler.
@Ismael, also ist diese Methodensache Teil von web3js 1.0 als neue Funktionen?
@Etherkimist Ja, web3 v1.0 ist eine Refaktorisierung aus dem alten Stable v0.20. Ich würde sagen, lernen Sie web3 v1.0, weil es zukunftssicherer ist, aber wenn Sie etwas produktionsreifes brauchen, würde ich vorerst bei v0.20 bleiben. Hoffentlich wird v1.0 bald veröffentlicht.
Versucht, den httpAnbieter zu verwenden, dieselben Symptome.

Antworten (1)

Ich habe Ihren Vertrag ausprobiert und ein paar Probleme festgestellt:

ethUpVotingContract.methods.addNewQuestion('foo')
.send(ethOptions, (err, resp) => {

Wird mit scheitern

throw new Error('Angegebener Parameter sind keine Bytes: "'+ value + '"');

Fehler: Angegebener Parameter ist nicht Bytes: "foo" bei SolidityTypeBytes.formatInputBytes [as _inputFormatter]

Durch die Konvertierung in Bytes wird es funktionieren

const question = web3.utils.asciiToHex('foo');

ethUpVotingContract.methods.addNewQuestion(question)
.send(options, (err, hash) => {

Das andere Problem ist, dass Sie jetzt ein Versprechen zurückgeben send. callWas ist los? Wenn das callVersprechen mit der Ausführung beginnt, bevor das sendbeendet ist, werden die vorherigen Daten so angezeigt, als ob das sendnie erfolgreich gewesen wäre.

Um dies zu beheben, müssen Sie das callInnere der then-Klausel von machen send, um sicherzustellen, dass es fertig ist

const message = web3.utils.asciiToHex('foo');

ethUpVotingContract.methods.addNewQuestion(message)
.send(options, (err, hash) => {
  if (err) {
    console.log(err);
  }
  console.log(`TxHash: ${hash}`);
})
.then((result) => {
  console.log('Send has completed');
  // Here we are guarantee `send` has finished
  // and we can query the data
  ethUpVotingContract.methods.getQuestionListSize().call()
  .then((result) => {
    console.log('Call has returned');
    console.log(result);
  });
});

// If we call here perhaps `send` didn't finish yet
console.log('Send was called');
Vielen Dank, dass Sie sich die Zeit genommen haben, den Fehler zu finden und alles zu erklären, sehr hilfreich.