Wie verwendet man Ereignisse, um Daten aus einer Transaktion abzurufen? PRIVATE KETTE

Ich verwende GETH für die Architektur und Bereitstellung meines Vertrags in einer privaten Kette und es funktioniert ziemlich gut, aber leider möchte ich Daten von einer Transaktionsfunktion zurückgeben, und das macht mich verrückt. Ich weiß, dass das Lesen des zurückgegebenen Werts von Transaktionen notwendig ist, um Solidity-Ereignisse einzubeziehen, und dann können wir sie über WEB3 lesen. Ich zeige meine detaillierten Schritte zum Lesen von Ereignissen, aber nichts funktioniert überhaupt. Jede Art von Hilfe wäre sehr willkommen. Dies ist der Code, den ich sammeln muss:

This is the event declaration right above the contract constructor

event Accessed(string _msg,address _add, uint _time);


function transfer(bytes32 _ID) public returns (address)
{
    // Only the current owner can transfer the token.
    if (ID == _ID)
        {    
                owner = msg.sender;
                taddr.push(msg.sender); //taddr is an array used for storing address of whoever call the
                                        //transfer function
                ttime.push(now);        //same but it stores the timestamp
                Accessed("someone executed the transfer function",owner,now);
                return(owner); 
        } 
}
 function getOwners() view public returns (address[],uint[]) //this should print the two above arrays and return them
{

     return (taddr,ttime);

}

Was ich also möchte, ist hauptsächlich, die 2 Arrays als Rückgabe zu erhalten oder zumindest jeden Aufruf der Funktion transaction() zu lesen.

Nach der Bereitstellung verwende ich

var myContract = web3.eth.contract([ABI]);
var meta = myContract.at("address");
var Transfer = meta.Accessed({}, {fromBlock: 0, toBlock: 'latest'});
Transfer.watch(function(err, e) {
   if (err) {
      console.log(err);
} else {
      console.log("new Transfer executed from", e);
}
});

Mit diesem Snippet warte ich auf jeder Knotenkonsole auf jeden Aufruf der Funktion Transfer(), aber es passiert nichts. Dies ist, was ich als Antwort der Ereignisuhr bekomme

 {
 callbacks: [],
 filterId: "0x1b2e43d107ba5d1426df7243a74e6c04",
 getLogsCallbacks: [],
 implementation: {
 getLogs: function(),
 newFilter: function(),
 poll: function(),
 uninstallFilter: function()
 },
 options: {
 address: "0x18776b68d09660c4ddbfda8e71f67906c7147edf",
 from: undefined,
 fromBlock: "0x0",
 to: undefined,
 toBlock: "latest",
 topics:["0xa938469e072f18fc99f2e[...]", 
 null, null, null]
 },
 pollFilters: [],
 requestManager: {
 polls: {
 0x3ef60ce0d464242fac329bd3e1720427: {
    data: {...},
    id: "0x3ef60ce0d464242fac329bd3e1720427",
    callback: function(error, messages),
    uninstall: function()
  },
  0x80efdb3c4df0b69c53f1f9ce47d527bb: {
    data: {...},
    id: "0x80efdb3c4df0b69c53f1f9ce47d527bb",
    callback: function(error, messages),
    uninstall: function()
  },
  0xb62a9e7d2148f67acf56a96aca3046f2: {
    data: {...},
    id: "0xb62a9e7d2148f67acf56a96aca3046f2",
    callback: function(error, messages),
    uninstall: function()
  },
  0xe63a8aea7e45a2576b0852dd129c37d7: {
    data: {...},
    id: "0xe63a8aea7e45a2576b0852dd129c37d7",
    callback: function(error, messages),
    uninstall: function()
  }
},
provider: {
  newAccount: function(),
  openWallet: function(),
  send: function github.com/ethereum/go-ethereum/console.(*bridge).Send-fm(),
  sendAsync: function github.com/ethereum/go-ethereum/console.(*bridge).Send-fm(),
  sign: function(),
  unlockAccount: function()
},
timeout: {},
poll: function(),
reset: function(keepIsSyncing),
send: function(data),
sendAsync: function(data, callback),
sendBatch: function(data, callback),
setProvider: function(p),
startPolling: function(data, pollId, callback, uninstall),
stopPolling: function(pollId)
},
formatter: function(),
get: function(callback),
stopWatching: function(callback),
watch: function(callback)
}

Dasselbe passiert mit event.get()

SO was ist Ihrer Meinung nach das Problem? Übersehe ich etwas?

Vielen Dank

Antworten (2)

contract ExampleContract {
  event ReturnValue(address indexed _from, int256 _value);

function foo(int256 _value) returns (int256) {
    ReturnValue(msg.sender, _value);
    return _value;
  }
}

Ein Frontend kann dann den Rückgabewert erhalten:

var exampleEvent = exampleContract.ReturnValue({_from: web3.eth.coinbase});
exampleEvent.watch(function(err, result) {
  if (err) {
    console.log(err)
    return;
  }
  console.log(result.args._value)
  // check that result.args._from is web3.eth.coinbase then
  // display result.args._value in the UI and call    
  // exampleEvent.stopWatching()
})


exampleContract.foo.sendTransaction(2, {from: web3.eth.coinbase})

Wenn die Transaktion, die foo aufruft, abgebaut wird, wird der Rückruf innerhalb der Uhr ausgelöst. Dies ermöglicht es dem Frontend effektiv, Rückgabewerte von foo zu erhalten.

In Ihrem Fall drucken Sie das Ergebnis direkt ein der Konsole. Ich empfehle Ihnen, e.args._addden beabsichtigten Wert in der Konsole zu drucken.

Weitere Informationen finden Sie in diesem Artikel

Danke, Sir, für die Erläuterung und das Beispiel. Ich habe Ihr Beispiel ausprobiert und es hat funktioniert, der gleiche Ansatz gilt für mich, nicht. Dies führt dazu, dass ich den Code ein wenig anpasse, möglicherweise stimmt etwas nicht. Übrigens ist Ihr Problem etwas anders, weil Ihre Transaktion keine richtige Transaktion ist, sondern eher ein Anruf. Sie ändern den Status des EVM nicht, sodass der Rückgabewert vollständig für die Rückgabe verfügbar ist. Im Gegenteil, mein Ereignis ist in einem SET aufgebaut, sodass die Rückgabe nicht ausgeführt werden kann. Haben Sie Vorschläge, dass ich meinen Code ausprobieren kann, um zu sehen, ob er funktioniert?

Ihnen fehlt das Keyword emitvor Ihrem Event. So:

function transfer(bytes32 _ID) public returns (address) {
    // Only the current owner can transfer the token.
    if (ID == _ID) {    
      owner = msg.sender;
      taddr.push(msg.sender);
      ttime.push(now);        //same but it stores the timestamp
      emit Accessed("someone executed the transfer function",owner,now);
      
      return(owner); 
    } 
}

Außerdem block.timestampsollte generell anstelle von verwendet werden now. nowist in Version 0.7.0 offiziell veraltet, aber selbst wenn Sie eine frühere Version verwenden, block.timestamphilft die Verwendung bei der Wiederverwendbarkeit für andere Verträge in der Zukunft.

Die am häufigsten verwendete Solidity-Version im Jahr 2018 war 0.4, wo die Verwendung emitnicht erforderlich war. Wenn es einen Fehler gab, war es etwas anderes.