iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 25
1
Blockchain

區塊練起來-智能合約與DApp開發系列 第 25

[區塊練起來-智能合約與DApp開發] DAY 25 - web3.js 訂閱Event

貼心小語

上一篇成功透過 web3.js 來呼叫合約中的函式。我們之前設計的函式只要會變更狀態變數的操作都會記錄 log ,也就是觸發 event ,那要怎麼去監聽 event 就是我們今天的重點~!


為什麼需要監聽Event?

我們回憶一下,當交易在 pending 的時候還沒有正式的寫入區塊鏈中,而當交易完成後我們要如何優雅的得知交易已經完成呢?前面有提到 log 是存在收據中,而收據是在交易完成後所產生,所以我們只要監聽 log 是否寫入就可以得知交易是否完成,並在前端處理後續動作。另一個用途就是寫 log 的成本相對低很多,但智能合約無法去存取 log 裡的資料,所以透過前端監聽來取得 log 資訊,再做其他的處理。

多種監聽方式

監聽 Event 有很多種函式可以使用,還可以設置 options 來針對訂閱的內容做過濾等動作,提供的參數有:

  • filter :過濾指定條件的事件,如: { myIndexedParam: [20,23] } ,是指 myIndexedParam 為20或23的事件,型別為 Object
  • fromBlock :指定從第幾個區塊開始,輸入值為區塊編號,型別為 number
  • toBlock :指定取至第幾個區塊結束,輸入值為區塊編號,預設是最新的區塊,型別為 number
  • topics :指定 topics ,型別為 Array

topics 在後方會有較詳細的說明!

為了方便管理,我們新增一個 type 在 contract.ts 中,用來定義 options 的參數格式:

export interface EventLogOptions {
    filter?: Object;
    fromBlock?: number;
    toBlock?: number;
    topics?: Array<any>;
}

once

訂閱事件,取得一項資料後取消訂閱,與 rxjstake(1) 意思相同。我們在 app.component.ts 中使用,要訂閱 Event 就要取得合約實例後透過實例來訂閱。我們的合約僅有一個 done 事件,所以就將該事件名稱作為第一個參數,若要設置 options 則放在第二個參數,最後一個為 callback ,用來執行收到監聽結果後的操作。

constructor(private provider: ProviderService) {
    const resume = this.provider.getResume('0x1Ff192E4bA1b23bdb586A290C525b6037f8859a8');
    resume.once('done', (err, event) => {
        console.log(event);
    });
}

然後透過 Truffle 來呼叫合約,再打開開發人員工具來看(我把主題換深色系了/images/emoticon/emoticon37.gif):
https://ithelp.ithome.com.tw/upload/images/20190913/20119338pZHEb2L6au.png
可以看到 returnValues 裡面就是 log 的資料。

一般的事件監聽

從實例的 events 中取出要監聽的事件並訂閱,與 once 不同的就是會不斷監聽直到關閉:

constructor(private provider: ProviderService) {
    const resume = this.provider.getResume('0x1Ff192E4bA1b23bdb586A290C525b6037f8859a8');
    resume.events.done()
    .on('data', event => {
        console.log(event);
    });
}

取得過去事件

可以取得過去已經發生的事件,我們設置 options 來取得區塊0到最新區塊的所有事件,回傳的會是陣列:

constructor(private provider: ProviderService) {
    const resume = this.provider.getResume('0x1Ff192E4bA1b23bdb586A290C525b6037f8859a8');
    const eventOption = {
        fromBlock: 0
    } as EventLogOptions;
    resume.getPastEvents('done', eventOption, (err, events) => {
        console.log(events);
    });
}

執行結果:
https://ithelp.ithome.com.tw/upload/images/20190913/201193389uUdJuYVvC.png


今日小結

能夠監聽事件來判斷是否交易完成,並取用 log 中的資訊。其實 Event 對於 DApp 來說就像是一種溝通的橋樑,能夠讓區塊鏈與應用程式用較低的成本做到互動的效果,也算是很重要的功能之一!


參考資料

官方文檔


上一篇
[區塊練起來-智能合約與DApp開發] DAY 24 - web3.js 呼叫合約
下一篇
[區塊練起來-智能合約與DApp開發] DAY 26 - web3.js 解碼 log 資訊
系列文
區塊練起來-智能合約與DApp開發31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言