Ethereum JavaScript 資料庫:web3.js 和 ethers.js (第一部分)

Web3.js 和 ethers.js 是 JavaScript 資料庫,可讓開發人員與 Ethereum 區塊鏈互動。這些都是很實用的資料庫,兩種都可以滿足大多數 Ethereum 開發人員的需求。本文將比較 web3.js 和 ethers.js,並著眼於其相似點與不同處,讓您可以更了解資料庫的細微差異。本文的撰寫是為了協助開發人員了解兩種資料庫之間的權衡,以便決定哪種資料庫最符合自己的特定需求。本文包含相關資源,或可為初次接觸區塊鏈開發或程式設計的人士提供相關協助。

TL;DR:兩種資料庫皆可使用。如果您要使用,建議您選擇一種資料庫即可。

Web3.js 有使用者社群,並有與 Ethereum Foundation 相關的維護人員。這種有良好的 API 參照。此資料庫自 2015 年起即已啟用,而且許多專案都大幅採用。因此,在許多「建立您的第一個 dApp」教學課程中都「一定」會使用此資料庫。

Ethers.js 非常優秀,因為這是個小型、精簡的資料庫,卻有大量的測試案例。這有良好的「入門」文件內容,因此非常適合新使用者使用。開發人員通常都會用「簡單」和「直觀」來描述他們使用 ethers.js 的體驗,而且過去兩年以來也有越來越多人選擇使用此資料庫,下載次數不但增加,也有越來越多的專案選擇使用。

什麼是 web3.js?

web3.js 資料庫是 JavaScript 資料庫的開放原始碼 (GNU較寬鬆公共授權條款版本 3),由 Ethereum Foundation 建立製作,而且包含可透過 JavaScript Object Notation - Remote Procedure Call (JSON-RPC) 通訊協定與 Ethereum 節點通訊的功能。也就是說,這是一種 JavaScript 資料庫,可讓開發人員與 Ethereum 區塊鏈互動。Web3.js 目前版本事 1.2.9,也是本文參考使用的版本。Web3.js 以四種模組組成。

什麼是模組?

在 JavaScript 中,模組就是較大型程式中有特定功能的程式碼。模組應為獨立,如此當您從資料庫、程式或應用程式中移除模組時,整體資料庫、程式或應用程式也不會停止運作。如果您對於 Python 或 Java 很熟悉,那麼您或許對於與模組類似的「類別」也很熟悉。如果是初次接觸 JavaScript,FreeCodeCamp 就提供了非常詳盡的 JavaScript 模組說明

web3.js 由哪些模組組成?

Web3.js 的主要類別稱為 web3。您可以在此類別中找到資料庫的大量功能。組成 web3js 的另外五種模組是:

  1. web3-eth
  2. web3-shh
  3. web3-bzz
  4. web3-net
  5. web3-utils

web3-eth 的功能是什麼?

web3-eth 模組包含的功能,可讓 web3.js 的使用者與 Ethereum 區塊鏈互動。特別是這些功能可與智慧型合約、外部擁有的帳戶、節點、採礦區塊和交易互動。以下是三個示意範例:

  • web3.eth.getBalance 可讓您取得特定區塊中某個位址的 ETH 餘額
  • web3.eth.signTransaction 可讓您簽署交易
  • web3.eth.sendSignedTransaction 可讓您傳送已簽署交易至 Ethereum 區塊鏈。

web3-shh 的功能是什麼?

web3-shh 模組可讓您與 Whisper 通訊協定互動。Whisper 是一種訊息通訊鞋動,專為輕鬆廣播訊息所設計,並且適合低層級的非同步通訊使用。以下是兩個示意範例:

  • web3.shh.post 會在網路中張貼 Whisper 訊息
  • web3.shh.subscribe 可建立傳入 Whisper 訊息的訂閱

web3-bzz 的功能是什麼?

web3-bzz 模組可讓您與 Swarm 互動。Swarm 是分散式儲存平台及內容發布服務,可供儲存您分散式應用程式 (Dapp) 的圖片或影片等檔案。以下是兩個示意範例:

  • web3.bzz.upload 可讓您上傳檔案和資料夾至 Swarm
  • Web3.bzz.download 可讓您從 Swarm 下載檔案和資料夾

web3-net 的功能是什麼?

web3-net 模組可讓您與 Ethereum 節點的網路屬性互動。使用 web3-net,您就可以在您想要取得相關資訊的通訊協定後加入 .net,找到節點的相關資訊 (這裡以 * 指定,代表 web.eth.net、web3.shh.net 或 web3.bzz.net 的選擇)。以下是兩個示意範例:

  • web3.*.net.getID 可傳回網路 ID
  • web3.* .net.getPeerCount 可傳回節點連接的同儕節點數目

web3-utils 的功能是什麼?

web3-utils 模組可為您提供公用程式功能,您可以在 Ethereum Dapp 中使用,也可以搭配其他 web3.js 模組使用。公用程式功能是可重複使用的功能,讓撰寫程式碼變得更容易,也是 JavaScript 和其他程式設計語言中常見的功能 (如需 JavaScript JQuery 資料庫中現有的供應程式功能描述,請參閱see JavaScript:權威指南,第 6 版,作者:Dave Flanagan)。Web3-utils 包含公用程式功能,可轉換數字、驗證值是否符合特定條件及搜尋資料集。以下是三個示意範例:

  • web3.utils.toWei 可將乙太轉換成 Wei
  • web3.utils.hexToNumberString 可將十六進位值轉換成字串web3.utils.isAddress 會檢查特定字串是否為有效的 Ethereum 位址。

什麼是 ethers.js?

Ethers.js 是一種 JavaScript 資料庫,可讓開發人員與 Ethereum 區塊鏈互動。資料庫包含 JavaScript 和 TypeScript 中的公用程式,並且具備 Ethereum 錢包的所有功能。Ethers.js 目前最新版本是 5.0.3。Ethers.js 是由 Ethers 所建立,並且是透過 MIT License 的開放原始碼。

ethers.js 與 web3.js 類似,應用程式設計介面 (API) 由四個模組組成。

  1. Ethers.provider
  2. Ethers.contract
  3. Ethers.utils
  4. Ethers.wallets

ethers.provider 的功能是什麼?

Ethers.provider 可讓您擷取與 Ethereum 區塊鏈的連線。這可用於發出查詢和傳送會變更區塊鏈狀態的已簽署交易。以下是三個示意範例:

  • ethers.providers.InfuraProvider 可讓您連接 Ethereum 節點的 Infura 託管網路
  • ethers.provider.getBalance 可讓您取得區塊鏈中位址或區塊的 ETH 餘額
  • ethers.provider.resolve 會解析傳送至 Ethereum 位址的 Ethereum Name Service (ENS) 名稱 (透過 Promise;如果您是初次接觸 JavaScript,建議您進一步閱讀以了解「Promises」,因為這在未來可於計算後傳回資料)。

注意:web3.js 也有適合此目的的提供者,而且採用 web3 式模組。Ethers.js web3.js 的組織方式相當不同,因此不一定總是會有模組間的明確對應,即使兩種資料庫的功能非常類似也是如此。

ethers.contract 的功能是什麼?

Ethers.contract 可讓您部署智慧型合約並與之互動。特別是此模組中的功能可讓您聆聽智慧型合約發出的事件、呼叫智慧型合約提供的功能、取得智慧型合約的相關資訊以及部署智慧型合約。以下是兩個示意範例:

  • ethers.ContractFactory.fromSolidity 會建立「處理站」,以便從 Solidity Compiler 的編譯器輸出,或是從 Truffle 產生的 JSON 檔案部署智慧型合約ethers.Contract 可讓您在部署智慧型合約後與之互動。

ethers.utils 的功能是什麼?

Ethers.utils 可提供格式化資料,以及處理使用者輸入使用的公用程式功能。Ethers.utils 的功能與 web3-utils 類似,而且可讓建立分散式應用程式變得更簡單。以下是三個範例:

  • ethers.utils.getContractAddress 會從部署智慧型合約使用的交易擷取智慧型合約位址
  • ethers.utils.computeAddress 會透過傳送與位址相關連的公開或不公開金鑰功能來計算位址ethers.utils.formatEther 會將傳入的 Wei 格式化為乙太的十進位

ethers.wallet 的功能是什麼?

Ethers.wallet 提供的功能,與我們目前為止討論過的其他模組不同。Ethers.wallet 可讓您連接至現有的錢包 (Ethereum 位址)、建立新的錢包並簽署交易。以下是三個範例:

  • ethers.wallet.createRandom 會隨機建立新帳戶。
  • ethers.wallet.sign 會簽署交易,並以十六進位字串傳回已簽署交易 (透過 Promise;如果您是初次接觸 JavaScript,建議您進一步閱讀以了解「Promises」,因為這在未來可於計算後傳回資料)。
  • ethers.wallet.getBalance 可讓我們取得錢包位址的 ETH 餘額。

Web3.js 的套件與 web3.eth 模組中稱為 web3.eth.accounts 的套件類似。但是,在此套件的相關文件中,此套件會顯示:「此套件尚未通過審查,可能不安全。為保安全,在生產過程中使用前請正確清除記憶體、安全儲存不公開金鑰並正確測試接收和傳送交易。」的訊息。

我要如何決定在我的分散式應用程式中使用 web3.js 還是 ethers.js?這兩者之間有何差異?

首先,如果您是要建立樣板應用程式或完成教學課程,不論樣板或教學課程推薦的是 web3.js 或 ethers.js,您都可以使用。這樣您不但可以更輕鬆,使用教學課程的過程也會更為順暢。記得一定要使用教學課程中指定的 web3.js 或 ethers.js 版本。坊間有許多教學課程都尚未更新,因此除非教學課程中有特別指定,否則您不一定可使用最新版本的資料庫。

如果您要從頭開始製作應用程式,並要決定使用的資料庫是哪一種,Andres Canal 在他的文章《Using Quill,js to Build a WYSIWYG Editor for your Website》中提到有一種軟體評估程序,可協助您評估應使用哪一種文字編輯工具。

當您在決定最適合自己的資料庫時,請參考以下 9 個問題,另外還有一些內容和資訊可以協助您回答這些問題。

1.) 資料庫的熱門程度是否很重要?

根據 Andres Canal 的定義,

「Github 的熱門專案,就是真正的熱門專案。換句話說,就是有很多人提問、貢獻資源和提供支援。這樣的軟體通常都會比較可靠。您可以看看專案有幾顆星、有多少問題、有多少提取要求尚待處理,以及專案中有多少參與者來了解專案的熱門程度。」

截至此網誌文章撰寫之時,Web3.js 有將近 8,800 顆星星,而 ethers.js 有將近 1,500 顆星星。在 GitHub 中,有 51,300 個存放庫使用 Web3.js,相較之下 ethers.js 有 18,500 個。Web3.js 較早出現,這也是 web3.js 是較熱門資料庫的其中一個原因

2.) 資料庫的維護是否很重要?

我們希望使用經常更新的資料庫,這樣錯誤才可以減少,而且也可以加入新的功能。雖然不盡完美,但是以每個月 (或兩個月) 一次的開發改善、修正的問題、現有的問題及期間內負責維護的人員數目來看,就可以了解開放原始碼專案的優缺點。這也可以讓我們了解維護的模式,讓資料庫使用者可以深入了解何時更新、錯誤通常會何時進行修正,而且這些資料也可做為資料庫維護的 Proxy 衡量標準。在 GitHub 中查看資料庫 (web3.js / ethers.js) 的每月動態以了解統計資料。

ethers.js 維護人員 Richard Moore 所做的開發改善和問題解決數目非常驚人,值得嘉獎。Web3.js 共有 12 名維護人員,其中三名完成了幾乎所有的功能開發與改善。其實哪一種都好,但是在選擇資料庫時,記得參考統計資料,這樣您才能決定所需的維護程度,然後依照自己的需求選擇最合適的資料庫。

3.) 誰負責資料庫的開發?有多少專案使用此資料庫?

Web3.js 是非營利組織 Ethereum Foundation 的專案,而此組織的成立宗旨就是研究並組織通訊協定層級開發。Ethers.js 的建立,是為了打造「完整、簡單且檔案小的資料庫,最終取代 web3 和 ethereum.js」。由 Richard Moore 開發的 ethers.js,是源自於他在建立和維護資料庫時所做的工作。

雖然有些專案會公開其使用的資料庫,但我們認為顯示資料可讓大家知道兩種都非常熱門。請參閱 web3.jsethers.js 相依性圖表,以了解專案信賴使用的資料庫,或是否同時使用/支援兩種資料庫。

4.) 資料庫的測試是否很重要?

如果對您的專案而言預寫測試很重要,那麼依照過去的記錄來看,ethers.js 就會勝出。在本文撰寫之時,Ethers.js 之前就在 GitHub 有 3.0 版的明確測試記錄,但該文件記錄在 5.0 版卻尚未更新。Web3.js 沒有相容測試文件記錄。如果未來幾週內測試文件記錄有更新,ethers.js 將仍是有較好測試和相關文件記錄的資料庫。今天由於 ethers.js 測試套件尚未更新,所以我們暫時無法評斷。

5.) 資料庫的下載次數是否很重要?

由於 web3.js 較早出現,因此下載次數也較多 (截至 5 月 20 日止有 14,703,432 次),而 ethers.js 的次數則較少 (截至 5 月 20 日止有 8,500,336 次),但如果以每週下載次數來看,ethers.js 的下載次數 (截至 5 月 20 日止有 184,798 次) 則比 web3.js 高 (截至 5 月 20 日止有 175,661 次),ethers.js 也是目前較常有人下載的資料庫。以最近來看,Ethers.js 的下載次數較多,但總下載次數而言則是 web3.js 較多。

6.) 網路效能有多重要?

如果您很重視網路效能,那麼 ethers.js 或許是效能較好的資料庫。ethers.js 資料庫聲稱未壓縮是 284 kb,但是在 NPM 刊登的資料是未壓縮 3.5 MB。Web3.js 則是至少大了一個等級,未壓縮是 10.6 MB。因此,ethers.js 比 web3.js 小,以這個邏輯來看,如果是相同的應用程式,使用 ethers.js 的的載入時間應會比使用 web3.js 要來得快。這是因為不論使用的是哪一種資料庫,資料庫都會與網路應用程式中其他資產一起載入。我們尚未測試過相同應用程式使用 web3.js 或 ethers.js 的載入時間,因此這個部分尚待證實。如果檔案大小對您的應用程式而言有差別,那麼 ethers.js 就是檔案較小的資料庫。

7.) 文件的品質是否很重要?

文件的品質是一種主觀衡量指標,但是衡量文件品質的其中一種方式,是閱讀文件並查看文件是否容易理解。理想情況下,撰寫文件是為了讓新使用者可以了解如何使用資料庫。文件也應加以組織整理,方便經驗豐富的使用者可以快速找到所需內容。

Web3.js 有豐富的 API 參照,非常實用。這是文件中最重要的部分。「入門」內容應簡短易懂。經驗豐富的使用者可能會喜歡這一點,但是卻缺少 web3.js 新使用者適合的內容資訊。

Ethers.js 包含「入門」部分,也有豐富的 API 參照。這些非常實用,也讓 ethers.js 比 web3.js 更有優勢,特別是對於 Ethereum 生態系統中資歷較淺的開發人員而言更是如此。ethers.js 的文件中有部分尚未完成,因此不容易使用 (Ethereum 基礎知識部分及過去廣獲好評,而且開發人員都會使用的常用程式碼範例「Cookbook」”,都還沒有在 5.0 中更新,您必須返回 4.0 版文件才能找到這些非常實用的資訊)。Ethers.js 也提供使用 ethers.js 的優勢相關明確資訊。

兩種資料庫的文件都不甚完美,因此如果您很重視文件,請花一點時間仔細探索,然後才決定是否有足夠的資訊可讓您實作想要建立的功能。

8.) 資料庫的整體使用是否很重要?

web3.js 較早出現,因此下載次數與 GitHub 星數都較多,但 ethers.js 現在已逐漸變得更為熱門。最終還是必須由您決定各個資料庫的哪些部分比較重要。

9.) 授權有多重要?

視您的使用目的而定,開放原始碼軟體授權對您而言可能很重要。Web3.js 有 LGPLv3 授權 (如 NPM 中所列,但不在其 GitHub 存放庫中),而 ethers.js 有 MIT 授權 (如其 GitHub 存放庫中所列)。如需更多有關授權的詳細資料,請聯絡此主題的法律專家。此外,Slava Todavchich 也在《Understanding open-source and free software licensing》一文中對於這個主題提供了有趣的內容觀點。

結論

如我們在一開頭就提到的,兩個資料庫都具備足夠的功能。Ethers.js 在過去兩年以來變得越來越熱門,下載次數與專案使用也越來越多。Web3.js 一直以來都是標準,至今仍有許多開發人員選擇使用。

未來我們將在接下來的教學課程中發布第二部分,讓您了解如何連接至 Infura API,並使用 web3.js ethers.js 傳送翻譯,敬請期待。

非常感謝 Thomas HayAkua Nti Sean Brennan 在本指南中提供的豐富知識與詳細介紹。如需更多 Web3 教學,請參閱《Infura 網誌》和 ConsenSys Academy

檢視我們的開發人員文件,探索與 Infura 互動以讀取和撰寫 Ethereum 資料的不同方式。初次使用 Infura 嗎?註冊並免費開始使用!