iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 20
1
Blockchain

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

[區塊練起來-智能合約與DApp開發] DAY 20 - web3.js 公用函式

  • 分享至 

  • xImage
  •  

貼心小語

上一篇我們設計了取得帳戶列表與區塊資訊,這一篇會來探討 web3.js 中一些 公用函式(Utility Functions)


設置 Util 類別

公用函式不需依賴 Provider 即可使用,為了方便管理,我們在 Angular 專案中也設置一個 Utils 類別來處理 web3.js 提供的公用函式。透過 AngularCLI 產生類別:

ng g class utils/web3-utils

做一個 index.ts 來統一管理所有的 Utils 類別,先將 Web3Utils 從此處 export

export * from './web3-utils';

再來我們只需要在 Web3Utils 中設置靜態方法來調用 web3.js 中的公用函式即可!

隨機Hex字串(randomHex)

可以隨機生成特定 bytes 大小之十六進位字串,最高上限為 32bytes 。我們在 Web3Utils 中新增靜態方法來調用:

public static randomHex(bytesSize: number): string {
    return web3.randomHex(bytesSize);
}

大數(BN)

在 web3.js 中,很多時候都會碰到 BN 型別的資料,因為在 JavaScript 中處理 BN 是不容易的,所以 web3.js 依賴 BN.js 來處理 BN 問題。

將 BN 用變數裝起來並 export ,這樣在調用時可以較簡潔,目前 Web3Utils 內容如下:

import * as web3 from 'web3-utils';

export const BN = web3.BN;

export class Web3Utils {
    public static randomHex(bytesSize: number): string {
        return web3.randomHex(bytesSize);
    }
}

如果是較新版的 web3,則需要透過此方法引入:

import * as bn from 'bn.js';
export const BN = bn;

可以在 app.component.ts 中測試:

import { Web3Utils, BN } from './utils';
constructor() {
    console.log(new BN(Web3Utils.randomHex(2)));
    console.log(new BN('12').add(new BN('1')).toString());
}

SHA3

將字串透過 SHA3 演算法來產生雜湊值。

public static sha3(message: string): string {
    return web3.sha3(message);
}

檢測型別

web3.js 有提供很多檢測資料型別的函式,防止資料格式不正確的問題。

isBN

檢查是否為 BN 型別。

public static isBN(bn): boolean {
    return web3.isBN(bn);
}

isHex

檢查是否為 hex 字串,此條件較寬鬆,不用加 0x 前綴的 hex 字串或是符合 hex 格式的字串都能通過。

public static isHex(message: string): boolean {
    return web3.isHex(message);
}

isHexStrict

檢查是否為 hex 字串,此條件較嚴謹, hex 字串必須加 0x 前綴,建議使用此方法。

public static isHexStrict(message: string): boolean {
    return web3.isHexStrict(message);
}

isAddress

檢查是否符合以太坊的 Address 格式。

public static isAddress(address: string): boolean {
    return web3.isAddress(address);
}

轉換型別

web3.js 提供很多轉換資料型別的函式。

toHex

轉換為十六進位的字串,若參數為 string 則會被當作是 UTF-8 字串。

public static toHex(message): string {
    return web3.toHex(message);
}

toBN

將資料轉換為 BN

public static toBN(num: number|string): any {
    return web3.toBN(num);
}

hexToUtf8

將 hex 字串轉換為 UTF-8 格式的字串。

public static hexToAscii(hex: string): string {
    return web3.hexToAscii(hex);
}

utf8ToHex

將 UTF-8 字串轉換為 hex 字串。

public static utf8ToHex(message: string): string {
    return web3.utf8ToHex(message);
}

asciiToHex

將 ascii 字串轉換成 hex 字串。

public static asciiToHex(message: string): string {
    return web3.asciiToHex(message);
}

hexToBytes

將 hex 字串轉換為 bytes 。

public static hexToBytes(hex: string): Array<any> {
    return web3.hexToBytes(hex);
}

bytesToHex

將 bytes 轉換為 hex 字串。

public static bytesToHex(bytesArray: Array<any>): string {
    return web3.bytesToHex(bytesArray);
}

toWei

將指定以太幣單位及數量轉換為 Wei 單位,是轉帳經常使用的函式。不過以太幣的單位實在很多,這邊就設計一個 type 來當作單位的查詢,新增一個 type 資料夾並新增 ether-unit.ts

export const EtherUnit = {
    noether: 'noether', // 0
    wei: 'wei', // 1
    Kwei: 'Kwei', // 1000
    babbage: 'babbage', // 1000
    femtoether: 'femtoether', // 1000
    Mwei: 'Mwei', // 1000000
    lovelace: 'lovelace', // 1000000
    picoether: 'picoether', // 1000000
    Gwei: 'Gwei', // 1000000000
    shannon: 'shannon', // 1000000000
    nanoether: 'nanoether', // 1000000000
    nano: 'nano', // 1000000000
    szabo: 'szabo', // 1000000000000
    microether: 'microether', // 1000000000000
    micro: 'micro', // 1000000000000
    finney: 'finney', // 1000000000000000
    milliether: 'milliether', // 1000000000000000
    milli: 'milli', // 1000000000000000
    ether: 'ether', // 1000000000000000000
    kether: 'kether', // 1000000000000000000000
    grand: 'grand', // 1000000000000000000000
    mether: 'mether', // 1000000000000000000000000
    gether: 'gether', // 1000000000000000000000000000
    tether: 'tether', // 1000000000000000000000000000000
};

為了方便 type 統一管理,所以用 index.tsexport

export * from './ether-unit';

設計我們的靜態類別:

public static toWei(value: any, uint: string): any {
    return EtherUnit[uint] ? web3.toWei(value, EtherUnit[uint]) : web3.toWei(value, 'ether');
}

今日小結

了解部分 web3.js 所提供的公用函式,因為實在太多了,所以這邊只列出幾個比較基本、常用的,若有興趣的話可以看看參考資料中的官方文檔喔!


參考資料

官方文檔


上一篇
[區塊練起來-智能合約與DApp開發] DAY 19 - web3.js 取得 Accounts 及 Block 資訊
下一篇
[區塊練起來-智能合約與DApp開發] DAY 21 - web3.js 取得交易及收據
系列文
區塊練起來-智能合約與DApp開發31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
tytom2003
iT邦新手 5 級 ‧ 2021-03-04 22:38:12

export const BN = web3.BN;
這一行,會顯示"Property 'BN' does not exit on type 'typeof import'".
如果我在provider.service.ts 輸入"this.web3.utils.BN;"這一句,它是沒有顯示錯誤.
但我已經安裝了bn.js, 而且試了bn能夠輸出。請問我是否還未設定其他,所以就不能夠用?
還是我直接用bn.js去代替web3.utils.BN去繼續看你的教學學習.
thank you very much.

HAO iT邦研究生 1 級 ‧ 2021-03-05 13:40:24 檢舉

看起來是 web3 後來改版拿掉了,我使用的是 1.2.1 版。
比較新版的要從 bn.js 匯入:

import * as BN from 'bn.js';

我的文章會再針對這部分做調整,謝謝提醒!

我要留言

立即登入留言