iT邦幫忙

2021 iThome 鐵人賽

DAY 17
0
Modern Web

All In One NFT Website Development系列 第 17

Day 17【ethers.js】ETHER. ETHER EVERYWHERE.

1iaqng.jpg

【前言】
這兩天來記錄 ethers.js 我覺得蠻重要的一些學習筆記,今天主要聚焦在一些常見名詞,還有連動的基本設定。省略了大部分的東西因為篇幅還有時間有限!

【ethers.js】
ethers.js 是一個完整的 JavaScript 套裝 library,是專門使用於與以太坊區塊鏈和相關生態系連動。此套件原本是特別設計在使用 ethers.io上,最後擴展至更全面性的套件。

Ethers.io is an collection of Libraries, Web Tools, Command-Line Utilities and Server Components to assist in the development, deployment, hosting and sharing of Ethereum applications.

What is Ethers? - ethers.io 0.0.1 documentation

下載套件:

npm install --save ethers

導入套件:

// Node.js
const { ethers } = require("ethers");
import { ethers } from "ethers";

常見術語:

  • Provider: (在 ethers 之中)Provider 是一個類別,抽象地說他可以被用來連結以太坊的網路,並且提供一個唯讀的條件來查看區塊鏈及其狀態。
  • Signer: (在 ethers 之中)Signer 是一個類別,通常會使用一些方法直接地或間接地存取私鑰,可以被用於簽核資訊及交易,並授權給網絡來呈現不同需求。
  • Contract: 此處的 Contract 代表與以太坊網路上特定合約的連結,因此這些應用可以像是普通 JavaScript 物件一樣被普遍的使用。

【Connection】

Connecting to Ethereum: Metamask

如果要開始體驗或開發以太坊,最快又最簡單的方式就是使用 MetaMask。

  • 連接以太坊網路 (Provider)
  • 持有使用者的私鑰並以此簽核 (Signer)
// A Web3Provider wraps a standard Web3 provider, which is
// what Metamask injects as window.ethereum into each page
const provider = new ethers.providers.Web3Provider(window.ethereum)

// The Metamask plugin also allows signing transactions to
// send ether and pay to change state within the blockchain.
// For this, you need the account signer...
const signer = provider.getSigner()

Connecting to Ethereum: RPC
另外一個著名連動以太坊的方法就是使用 JSON-RPC API,其也可以實作在任何主要的以太坊節點應用 (e.g. Geth and Parity) ,以及許多第三方網頁服務上 (e.g. INFURA)。

  • 連接以太坊網路 (Provider)
  • 持有使用者的私鑰並以此簽核 (Signer)
// If you don't specify a //url//, Ethers connects to the default 
// (i.e. ``http:/\/localhost:8545``)
const provider = new ethers.providers.JsonRpcProvider();

// The provider also allows signing transactions to
// send ether and pay to change state within the blockchain.
// For this, we need the account signer...
const signer = provider.getSigner()

【Provider API - Etherscan Provider】

Provider API Keys:

當我們使用某些可作為 Provider 的 API service (例如 AlchemyEtherscan or INFURA),我們將會需要 API KEY 來允許每一個用來追蹤各種目標的服務。

此外,ethers.js 對於每個服務都提供預設的 API keys,因此每個 Provider 都是開箱即用的。 這些 API keys 被提供用來作為社會資源,像是低流量企劃或仍在草創期的企劃。當然因為他們被所有使用者共用,所以如果被越頻繁的使用就會使 response 更慢。

The ethers 強烈建議使用者針對每個服務都申請一個免費的 API keys,因為每個免費的 API keys 都有免付費額度,而其有以下優點:

  • 更多的額度以及同時使用 API 的用量上限
  • 更快速的 responses ,擁有更小的延遲
  • 更有效的追蹤方法,讓使用者可以去分析顧客的行為
  • 可以使用更進階的 APIs,像是使用更高階的函式和索取某些資料

Etherscan:

Etherscan.io 是一個以太坊區塊的觀察者。是所有用來建設區塊和 debug 的開發者工具裡面最有用的,並提供額外的 API 終端來連動以太坊區塊鏈。

Sign up for a free API key on Etherscan

【Application Binary Interface】

Application Binary Interface (ABI) 是一個統合介面,專門用來描述如何與智能合約裡面元件連動。也就是 Fragments 的統合介面,有 Error, Events, Function 和 Constructor。大部分開發者並不會使用這個比較低階 (encoding 和 decoding) 的介面來處理網路上的二進位資料,更多的是會使用智能合約裡面原本就定義好的介面。

【Contract】

Contract 是一段以太坊區塊鏈中的程式碼。Contract 物件使鏈上的合約可以像普通的 JavaScript 物件一樣被使用 ( with the methods mapped to encoding and decoding data )。這個概念有點像資料庫裏面的 Object Relational Mapper (ORM)。

為了要與鏈上的智能合約連動,這個被稱為 Contract 的類別需要知道在智能合約裡面有什麼方法可以被 encode 和 decode 成 data,也就是 ABI 所提供的功能。此外我們在使用 Contract 物件的時候,也可以忽視智能合約裡面我們不需要的方法,或稱函式。也就是說我們可以把這個 Contract 物件當作 ABI 的子集合。

通常 ABI 都是來自於 Solidity 或 Vyper 的編譯器,但使用者可以在程式碼裡面使用 Human-Readable ABI,像是以下的例子:

// You can also use an ENS name for the contract address
const daiAddress = "dai.tokens.ethers.eth";

// The ERC-20 Contract ABI, which is a common contract interface
// for tokens (this is the Human-Readable ABI format)
const daiAbi = [
  // Some details about the token
  "function name() view returns (string)",
  "function symbol() view returns (string)",

  // Get the account balance
  "function balanceOf(address) view returns (uint)",

  // Send some of your tokens to someone else
  "function transfer(address to, uint amount)",

  // An event triggered whenever anyone transfers to someone else
  "event Transfer(address indexed from, address indexed to, uint amount)"
];

// The Contract object
const daiContract = new ethers.Contract(daiAddress, daiAbi, provider);

4nou9vfuod271.jpg

【ethers.erc20】

所謂的 meta-class 是一個在 run-time 時就被定義的類別。而 Contract 則是被 Application Binary Interface (ABI) 宣告其應該擁有的方法和事件。這些宣告也是在 run-time 時就被創造並加入的。所以我們可以說 Contract 物件是一個屬於 meta-class 的類別。

Connecting to a Contract

利用現有的智能合約的地址,並創造一個新的 Contract 物件來與其連接,其 ABI 通常為  Provider 或 Signer。如果是使用 Provider 的話,這些智能合約就會在唯讀的情況下被讀取,如果是 Signer 則可存取或使用其他更進階的方法。

// A Human-Readable ABI; for interacting with the contract, we
// must include any fragment we wish to use
const abi = [
    // Read-Only Functions
    "function balanceOf(address owner) view returns (uint256)",
    "function decimals() view returns (uint8)",
    "function symbol() view returns (string)",

    // Authenticated Functions
    "function transfer(address to, uint amount) returns (bool)",

    // Events
    "event Transfer(address indexed from, address indexed to, uint amount)"
];

// This can be an address or an ENS name
const address = "0x4f3b15e4421902c09895fB12c8e0B8821134eA39";

// Read-Only; By connecting to a Provider, allows:
// - Any constant function
// - Querying Filters
// - Populating Unsigned Transactions for non-constant methods
// - Estimating Gas for non-constant (as an anonymous sender)
// - Static Calling non-constant methods (as anonymous sender)
const erc20 = new ethers.Contract(address, abi, provider);

// Read-Write; By connecting to a Signer, allows:
// - Everything from Read-Only (except as Signer, not anonymous)
// - Sending transactions for non-constant functions
const erc20_rw = new ethers.Contract(address, abi, signer);

這邊我印象最深刻的函式是 erc20.balanceOf ( owner [ , overrides ] )

⇒ Promise< BigNumber >;其會 Return 這個 owner 所持有的 ERC-20 token 數量。

await erc20.balanceOf(signer.getAddress())
// { BigNumber: "100000000000000000000" }

【小結】
今天感覺篇幅有點短哈哈哈哈哈哈哈哈,反正東西多到永遠學不完,重點就是!大家在使用的時候要記得不要在網站裡面亂 call Private Key 喔!

f27d9778b62826005ea18939e05d4942.jfif

【參考資料】
Documentation
ethereum(Docker)


上一篇
Day 16【web3.js】I KNOW BINARY AND HEXADECIMAL
下一篇
Day 18【Opensea.js】我的這把刀可是塗滿了毒藥的毒刃
系列文
All In One NFT Website Development30

尚未有邦友留言

立即登入留言