Events

在 web3j 中恢復 Solidity 函式事件

  • February 4, 2019
EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, userContract.getContractAddress().substring(2));

我正在嘗試恢復可靠智能合約返回給我的事件響應。在網上搜尋我發現here post。並且有效,但問題是我現在不需要呼叫什麼方法來僅返回契約發送給我的字元串。

就像是:

System.out.println(filter.getMessage());

好吧,讓我們從頭開始。

假設您有一個非常簡單的合約,它遞增和遞減部署到地址的計數器CONTRACT_X

pragma solidity ^0.4.20;

contract Counter {
   int counter; // Global state

   event CounterIncremented(address indexed _by, int _newValue);
   event CounterDecremented(address indexed _by, int _newValue);

   function increment(int _value) public {
       counter = counter + _value;
       emit CounterIncremented(msg.sender, counter);
   }

   function deincrement(int _value) public {
       counter = counter - _value;
       emit CounterDecremented(msg.sender, counter);
   }
}

一世。事件定義雜湊

首先,您必須定義每個事件(定義),以便計算在網路上代表該事件的唯一雜湊。

// Definition of event CounterIncremented(address indexed _by, int _newValue)
public static final Event INCREMENT_EVENT = new Event("CounterIncremented", 
   Arrays.<TypeReference<?>>asList(new TypeReference<Address>(true) {}, new TypeReference<Int>(false) {}}));

// Definition of event CounterDecremented(address indexed _by, int _newValue)
public static final Event DECREMENT_EVENT = new Event("CounterDecremented", 
   Arrays.<TypeReference<?>>asList(new TypeReference<Address>(true) {}, new TypeReference<Int>(false) {}}));

然後要計算事件的雜湊,你只需要做:

private static final String INCREMENT_EVENT_HASH = EventEncoder.encode(INCREMENT_EVENT);

private static final String DECREMENT_EVENT_HASH = EventEncoder.encode(DECREMENT_EVENT);

ii. 篩選

在訂閱事件之前,可以應用過濾器,因為根據定義,可以查詢乙太坊事件日誌(網路所有智能合約的所有事件)。

  • 按區塊範圍和智能合約過濾

返回智能合約的所有不同類型的事件CONTRACT_X。在我們的例子中,我們將獲取CounterIncrementedCounterDecremented事件。

EthFilter filter = new EthFilter(
   DefaultBlockParameterName.EARLIEST, // From block 0
   DefaultBlockParameterName.LATEST,  // To last block
   CONTRACT_X); // Unique Smart Contract

EthFilter filter = new EthFilter(
   DefaultBlockParameterName.LATEST, // only the latest block  
   DefaultBlockParameterName.LATEST,  // 
   CONTRACT_X); // Unique Smart Contract

EthFilter filter = new EthFilter(
   DefaultBlockParameterName.valueOf("2222"), // From block no 2222
   DefaultBlockParameterName.LATEST,  // To latest
   Arrays.asList(address1, address2, address3)); // List of Smart Contracts

LATEST 意味著您將在訂閱期間提取事件

  • 按事件過濾

如果要按事件類型過濾,例如只獲取CounterIncremented事件,可以使用屬性addSingleTopic

EthFilter filter = new EthFilter(
   DefaultBlockParameterName.EARLIEST, // From block 0 
   DefaultBlockParameterName.LATEST,  // To latest
   CONTRACT_X) // Unique Smart Contract
.addSingleTopic(INCREMENT_EVENT_HASH);
  • 按事件參數過濾

最後,您可能希望按事件參數過濾,例如CounterIncremented由給定地址觸發的所有事件(_by按事件參數過濾CounterIncremented

EthFilter filter = new EthFilter(
   DefaultBlockParameterName.EARLIEST, // From block 0
   DefaultBlockParameterName.LATEST,  // To latest
   CONTRACT_X) // Unique Smart Contract
.addSingleTopic(INCREMENT_EVENT_HASH)
.addOptionalTopic("0xdDd6427Aaf3766DC97A9cA9deDD3e7911b085B6B");

事件參數過濾器僅適用於“索引”參數。

iii. 訂閱活動

最後,最後一步是為節點訂閱事件:

web3.ethLogFlowable(filter).subscribe(event -> { 
   event.getAddress(); // Smart contract address
   event.getBlockNumber(); // Block number
   event.getTransactionHash(); // Transaction that emitted the event
   event.getTopics().get(0); // Event hash
   event.getTopics().get(1-n); // Event parameter (1) _by, (2) _value
});  

引用自:https://ethereum.stackexchange.com/questions/66379