iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 26
1
Blockchain

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

[區塊練起來-智能合約與DApp開發] DAY 26 - web3.js 解碼 log 資訊

貼心小語

上一篇我們提到如何監聽 Event,並從中取得 log 資訊,但如果要從交易的收據中取得 log 資訊該如何做呢?讓我們繼續看下去~


收據裡的 log

我們透過 ProviderService 中的 getReceipt(txHash: string) 來取得收據資訊,並看看 logs 中的資料:
https://ithelp.ithome.com.tw/upload/images/20190913/20119338lbFGWxCOK5.png
會發現 data 是 hex 格式的,我們根本無法用肉眼判斷到底 log 寫了些什麼,那我們到底要怎麼樣才能夠轉換成我們看得懂的資訊呢?答案就是 web3.js 有提供解碼的功能讓我們進行解碼。

解碼 log

在解碼 log 之前,我們回頭看 logs 裡面的資料,會發現有一個 topics 的東西,這個在上一篇有稍微提到,但並沒有說明,因為我覺得在這裡做說明效果會比較好,所以原諒我前面沒有解釋/images/emoticon/emoticon16.gif

topics

這個可以當作是log的索引,可能有多個 topic ,也可能只有一個,但不可能都沒有,因為 **第一個 topic 為 Event 經過雜湊運算後的hash值 ** ,而後面其他的 topic 都是 Event 中有 indexed 的參數,如果沒有特別設置 indexed 就不會有,而我們的 done 沒有特別設置。

實作解碼方法

我們將解碼的方法定義在 Web3Utils 中。先將 web3-eth-abi 引入:

import * as ABI from 'web3-eth-abi';

設計回傳的型別為 Observable 。由於解碼 log 需要使用到該 Event 的 ABI ,所以要從 Resume 的 ABI 找出事件名稱相符且類型為 event 的資料,如果沒有找到的話,就透過 rxjsthrowError 拋出錯誤;找到的話就依序將 Event 的 inputs 、 logs 中的 data 以及 topics 帶入 decodeLog() 中,並用 rxjsof 來傳出資料:

import { Observable, throwError, of } from 'rxjs';

public static decodeLog(eventName: string, receipt: any): Observable<any> {
    const abi = ResumeContract.abi.find(item => item.name === eventName && item.type === 'event');
    if (!abi) {
        return throwError(`Not found event: ${ eventName }`);
    }
    const inputs = abi.inputs;
    const logs = receipt.logs;
    return of(ABI.decodeLog(inputs, logs[0].data, logs[0].topics));
}

查看結果

app.component.ts 中做測試:

constructor(private provider: ProviderService {
    const tx = '0xb22815db37363b7695adabc536e3a45ec4e76d6837b7cdaaa4cdde955e27e232';
    this.provider.getReceipt(tx).pipe(
        mergeMap(receipt => Web3Utils.decodeLog('done', receipt))
    ).subscribe(
        log => console.log(log),
        err => console.error(err)
    );
}

從開發人員工具看結果:
https://ithelp.ithome.com.tw/upload/images/20190914/201193388oVzLHacz6.png


今日小結

透過 web3.js 提供的解碼功能讓收據中的 log 資訊變得可讀,這個功能可以應用在觀看交易內容時,順帶把解碼後的 log 資訊呈現出來,十分好用的功能!


上一篇
[區塊練起來-智能合約與DApp開發] DAY 25 - web3.js 訂閱Event
下一篇
[區塊練起來-智能合約與DApp開發] DAY 27 - 實戰DApp!區塊鏈履歷應用(1)
系列文
區塊練起來-智能合約與DApp開發31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
wl30304
iT邦新手 5 級 ‧ 2020-09-12 14:32:48

你好,最近重新實作(想將其改成自己所需的作品),但不知為何BN以及decodeLog這兩個會顯示錯誤
https://ithelp.ithome.com.tw/upload/images/20200912/20129209LCDQRILuUQ.jpg

https://ithelp.ithome.com.tw/upload/images/20200912/20129209eopN855iCC.jpg

看更多先前的回應...收起先前的回應...
wl30304 iT邦新手 5 級 ‧ 2020-09-12 14:34:12 檢舉

直接把您的原檔解壓縮一樣會發生上述情形

HAO iT邦研究生 3 級 ‧ 2020-09-12 23:05:17 檢舉

你能夠說明一下你的安裝步驟嗎?
我這邊重新跑一遍是沒有問題的,想了解一下會不會是安裝的過程有疏漏?

wl30304 iT邦新手 5 級 ‧ 2020-09-13 08:49:58 檢舉

npm install -g @angular/cli
解壓縮檔案,而後進入其資料夾
npm install web3
npm install bootstrap
npm install @ng-bootstrap/ng-bootstrap
npm run patch-webpack
npm install @truffle/contract
這樣

wl30304 iT邦新手 5 級 ‧ 2020-09-13 14:53:40 檢舉

發現了一個問題所在,我在前次安裝的時候,把web3安裝在前一個資料夾,所以程式碼搜尋不到
(就是我是在C槽下,ng新的專案,但install的時候還沒切入新的資料夾中)
問題已解決

HAO iT邦研究生 3 級 ‧ 2020-09-14 09:08:04 檢舉

有找出問題就好,加油!

tytom2003 iT邦新手 5 級 ‧ 2021-03-10 22:13:02 檢舉

我檔案結構是如下:
Resume folder
|-e2e
|-node_modules
|-plugins
|-src
|-truffle

但是,我跟你的程式去做,它仍然出現"Property ‘decodeLog’ does not exit on type typeof import",是否我安裝web3去了錯誤位置?
我在node_modules/web3-utils/types/index.d.ts,它是有export decodeLog。但是,我不明白我的程式怎樣會是找不到呢?
Thank you very much.

HAO iT邦研究生 3 級 ‧ 2021-03-13 09:45:04 檢舉

你好,看起來是新版的 web3 更改了作法,要改成下方這樣:

import { AbiCoder } from 'web3-eth-abi';

然後將其實例化:

private static ABI = new AbiCoder();

並在方法中調用:

this.ABI.decodeLog(inputs, logs[0].data, logs[0].topics);

感謝你的提醒!

tytom2003 iT邦新手 5 級 ‧ 2021-03-14 22:15:02 檢舉

當我在web3-utils.ts加入private static ABI = new AbiCoder();後去compile,它會出現"
Uncaught TypeError: web3_eth_abi__WEBPACK_IMPORTED_MODULE_4__.AbiCoder is not a constructor
ts web3-utils.ts:19"

private static ABI = new AbiCoder();是不是不是加入去web3-utils.ts?

thank you very much.

HAO iT邦研究生 3 級 ‧ 2021-03-22 15:04:06 檢舉

你好,我這邊用新版 web3 去編譯是可以過的。

我要留言

立即登入留言