Table of contents
Open Table of contents
Big Numbers
v6 中最大的变化之一是 BigNumber 类已被现代 JavaScript 环境提供的内置 ES2020 BigInt 取代。
可以在 MDN 这里查看 JavaScript ES2020 BigInt 的具体用法。
初始化 BigNumber
// BigNumber in v5
value = BigNumber.from("1000");
// Using BigInt in v6 (using literal notation).
// Notice the suffix n
value = 1000n;
// Using the BigInt function for strings
value = BigInt("1000");
简单计算
// Adding two values in v5
sum = value1.add(value2);
// Using BigInt in v6; keep in mind, both values
// must be a BigInt
sum = value1 + value2;
数字比较
// Checking equality in v5
isEqual = value1.eq(value2);
// Using BigInt in v6
isEqaul = value1 == value2;
Contracts
Contract 就是一个 ES6 的 Proxy, 这意味着它可以在运行时解析方法名称。
未知命名的函数
- v5
abi = ["function foo(address bar)", "function foo(uint160 bar)"];
contract = new Contract(address, abi, provider);
// In v5 it was necessary to specify the fully-qualified normalized
// signature to access the desired method. For example:
contract["foo(address)"](addr);
// These would fail, since there signature is not normalized:
contract["foo(address )"](addr);
contract["foo(address addr)"](addr);
// This would fail, since the method is ambiguous:
contract.foo(addr);
- v6
abi = ["function foo(address bar)", "function foo(uint160 bar)"];
contract = new Contract(address, abi, provider);
// Any of these work fine:
contract["foo(address)"](addr);
contract["foo(address )"](addr);
contract["foo(address addr)"](addr);
// This still fails, since there is no way to know which
// method was intended
contract.foo(addr);
// However, the Typed API makes things a bit easier, since it
// allows providing typing information to the Contract:
contract.foo(Typed.address(addr));
其他方法
- v5
// The default action chooses send or call base on method
// type (pure, view, constant, non-payable or payable)
contract.foo(addr);
// This would perform the default action, but return a Result
// object, instead of destructing the value
contract.functions.foo(addr);
// Forces using call
contract.staticCall.foo(addr);
// Estimate the gas
contract.estimateGas.foo(addr);
// Populate a transaction
contract.populateTransaction.foo(addr);
- v6
// Still behaves the same
contract.foo(addr);
// Perform a call, returning a Result object directly
contract.foo.staticCallResult(addr);
// Forces using call (even for payable and non-payable)
contract.foo.staticCall(addr);
// Forces sending a transaction (even for pure and view)
contract.foo.send(addr);
// Estimate the gas
contract.foo.estimateGas(addr);
// Populate a transaction
contract.foo.populateTransaction(addr);
Importing
v5 版本 ethers.js 使用 sub-package 方式管理 和 monorepo 比较相似
在 v6 版本所有 import
都可以在根 package 里面导入
v5 导入
// Many things (but not all) we available on the root package
import { ethers } from "ethers";
// But some packages were grouped behind an additional property
import { providers } from "ethers";
const { InfuraProvider } = providers;
// For granular control, importing from the sub-package
// was necessary
import { InfuraProvider } from "@ethersproject/providers";
v6 导入
// Many things (but not all) we available on the root package
import { ethers } from "ethers";
// But some packages were grouped behind an additional property
import { providers } from "ethers";
const { InfuraProvider } = providers;
// For granular control, importing from the sub-package
// was necessary
import { InfuraProvider } from "@ethersproject/providers";
Providers
之前所有 ethers.providers.*
转变成 ethers.*
// v5
provider = new ethers.providers.Web3Provider(window.ethereum);
// v6:
provider = new ethers.BrowserProvider(window.ethereum);
Signatures
v6 版本的 Signature 将是一个类,可以方便地进行解析和序列化操作。
// v5
splitSig = splitSignature(sigBytes);
sigBytes = joinSignature(splitSig);
// v6
splitSig = ethers.Signature.from(sigBytes);
sigBytes = ethers.Signature.from(splitSig).serialized;
Transactions
v5 版本中的 transaction 相关方法现在被封装到了 Transaction 类中,该类可以处理任何支持的交易格式以进一步进行处理。
// v5
tx = parseTransaction(txBytes);
txBytes = serializeTransaction(tx);
txBytes = serializeTransaction(tx, sig);
// v6
tx = Transaction.from(txBytes);
// v6 (the tx can optionally include the signature)
txBytes = Transaction.from(tx).serialized;
Utilities
Bytes32 string helpers
// In v5:
bytes32 = ethers.utils.formatBytes32String(text);
text = ethers.utils.parseBytes32String(bytes32);
// In v6:
bytes32 = ethers.encodeBytes32String(text);
text = ethers.decodeBytes32String(bytes32);
constants
// v5:
ethers.constants.AddressZero;
ethers.constants.HashZero;
// v6:
ethers.ZeroAddress;
ethers.ZeroHash;
data manipulation
// v5
slice = ethers.utils.hexDataSlice(value, start, end);
padded = ethers.utils.hexZeroPad(value, length);
// v5; converting numbers to hexstrings
hex = hexlify(35);
// v6
slice = ethers.dataSlice(value, start, end);
padded = ethers.zeroPadValue(value, length);
// v6; converting numbers to hexstrings
hex = toBeHex(35);
defaultAbiCoder
// In v5, it is a property of AbiCoder
coder = AbiCoder.defaultAbiCoder;
// In v6, it is a static function on AbiCoder, which uses
// a singleton pattern; the first time it is called, the
// AbiCoder is created and on subsequent calls that initial
// instance is returned.
coder = AbiCoder.defaultAbiCoder();
hex conversion
// v5
hex = ethers.utils.hexValue(value);
array = ethers.utils.arrayify(value);
// v6
hex = ethers.toQuantity(value);
array = ethers.getBytes(value);
solidity non-standard packed
// v5
ethers.utils.solidityPack(types, values);
// v6
ethers.solidityPacked(types, values);
property manipulation
// v5
ethers.utils.defineReadOnly(obj, "name", value);
// v6
ethers.defineProperties(obj, { name: value });