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);
});
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
. call
Was ist los? Wenn das call
Versprechen mit der Ausführung beginnt, bevor das send
beendet ist, werden die vorherigen Daten so angezeigt, als ob das send
nie erfolgreich gewesen wäre.
Um dies zu beheben, müssen Sie das call
Innere 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');
Etherkimist
Mann aus Reno
Ismael
Etherkimist
Ismael
Mann aus Reno
http
Anbieter zu verwenden, dieselben Symptome.