Können Sie in web3.js filtern und nach einer Methode zum Ändern des Vertragsstatus suchen?

Nehmen wir an, ich habe einen sehr einfachen Vertrag:

 contract basicStorage {
     uint storedData;

     function set(uint x) {
        storedData = x;
     }

     function get() constant returns (uint) {
        return storedData;
     }
 }

Ich möchte auf Änderungen an set() achten, von denen ich glaube, dass sie den Vertragsstatus ändern. Ist es möglich, filter/watch in web3.js zu verwenden?

Antworten (1)

Ich würde empfehlen, Ereignisse zu verwenden.

Smart-Contract - Ereignisse protokollieren

pragma solidity ^0.4.15;

contract basicStorage {
    uint storedData;

    event SetEvent(
        address indexed _from,
        uint _x
    );

    function set(uint x) {
        storedData = x;

        // Log event
        SetEvent(msg.sender, x);
    }

    function get() constant returns (uint) {
        return storedData;
    }
}

Der obige Code protokolliert jedes Mal ein Ereignis, wenn die Funktion set(x)ausgeführt wird. Das Protokoll enthält die Absenderadresse und das Argument x .

Web3 - Ereignisse ansehen

var Web3 = require('web3');
var abi = [...];
var address = '0xxxxxxxxxxxxxxxxxxxx'

var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
var basicStorageContract = web3.eth.contract(abi);
var basicStorageContractInstance = basicStorageContract.at(address);

// watch for changes
var myEvent = basicStorageContractInstance.SetEvent({}, {fromBlock: 0, toBlock: 'latest'});

console.log("Start watching events"); 
myEvent.watch(function(error, result){
    if (!error) {
        console.log(result);
    } else {
        console.log(error);  
    }
});



// Send a transaction to call Set
console.log("set(10)"); 
basicStorageContractInstance.set(10, {from: '0xxxxxxxxxxxxxxxxxxxx'});

console.log("set(20)"); 
basicStorageContractInstance.set(20, {from: '0xxxxxxxxxxxxxxxxxxxx'});

Dieser Code kompiliert den Vertrag und ruft ein myEventObjekt ab, das verwendet werden kann, um nach einem Ereignis zu suchen (das in unserem Fall eine Zustandsänderung darstellt).

Sendet dann zwei Transaktionen und prüft, ob einige Protokolle gedruckt werden.

Ergebnis

{ logIndex: 0,
  transactionIndex: 0,
  transactionHash: '0x0dc9c421f4d15baa00249f8d1d55d75ea267bc4c82b9654e3c24daf69f9c529d',
  blockHash: '0x2814a29a8c3e32d66063472c6e1d9e5c8eee159f7d19d5da6ecc4bdeeeb9449c',
  blockNumber: 22,
  address: '0xa07ddaff6d8b7aabf91ac6f82bf89455eb9784f4',
  type: 'mined',
  event: 'SetEvent',
  args:
   { _from: '0x13a0674c16f6a5789bff26188c63422a764d9a39',
     _x: { [String: '20'] s: 1, e: 1, c: [Array] } } }

{ logIndex: 0,
  transactionIndex: 0,
  transactionHash: '0x62d888d67e4392b7d218cc7a678b7f3168bcdd2fd77b5a51507e2bf62948273d',
  blockHash: '0x737fce60e8a2012f25eca24d8e56a13eeb127641cc89938f5ec3d8764131f7c7',
  blockNumber: 23,
  address: '0xa07ddaff6d8b7aabf91ac6f82bf89455eb9784f4',
  type: 'mined',
  event: 'SetEvent',
  args:
   { _from: '0x13a0674c16f6a5789bff26188c63422a764d9a39',
     _x: { [String: '30'] s: 1, e: 1, c: [Array] } } }

Sie können weitere Informationen finden

Das ist so ziemlich die einzige Antwort. Ich nehme an, es ist möglich, den Vertrag für eine Statusänderung abzufragen, aber warum sich die Mühe machen?
Ich hätte angeben sollen, dass, obwohl mir Ereignisse bekannt sind, die Dokumentation und andere Online-Beispiele irgendwie darauf hinweisen, was @OneChillDude sagt, nach txHash abfragt und dann beim Setzen einen Getter aufruft. Ich hoffe, diese Antwort hilft anderen, wenn sie endgültig ist.
@Keno Es macht für mich keinen Sinn, Polling über Ereignisse zu verwenden. Ereignisse werden ausgegeben, können durchsucht/indiziert werden, während Polling nur mehr Overhead bedeutet, den Sie selbst verwalten müssen
Ja sorry für den doppelten Abschnitt. Ich habe die Antwort bearbeitet. Ich stimme @OneChillDude zu, wenn er sagt, dass es einen Overhead gibt, den Vertrag abzufragen. Event sind hier speziell für diesen Zweck.