Migration: From Ethers v4
这份文件只涵盖了v4中存在的、在v5中发生了一些重要变化的功能。
它没有涵盖所有已添加的新特性,主要目的是帮助那些更新他们的旧脚本和应用程序的人保持功能的一致性。
如果你遇到任何遗漏的变化,请告诉我,我将更新本指南。
由于大数(BigNumber)使用的相当频繁, 它已经被移到the top level of the umbrella package.
ethers.utils.BigNumber
ethers.utils.BigNumberish
ethers.BigNumber
ethers.BigNumberish
bigNumberify
总是优先于构造函数,因为它可以缩短[[BigNumber]对象的对象实例化(因为它们是不可变的)这已经被移动到了静态的from
类方法中.
new ethers.utils.BigNumber(someValue)
ethers.utils.bigNumberify(someValue);
ethers.BigNumber.from(someValue)
解析的地址的名称已更改。如果传递给构造函数的地址是一个ENS名称,那么在对合约进行任何调用之前,该地址将被解析。
解析地址的属性名称从addressPromise
改为了resolvedAddress
。
contract.addressPromise
contract.resolvedAddress
The only difference in gas estimation is that the bucket has changed its name from estimate
to estimateGas
.
contract.estimate.transfer(toAddress, amount)
contract.estimateGas.transfer(toAddress, amount)
In a contract in ethers, there is a functions
bucket, which exposes all the methods of a contract.
All these functions are available on the root contract itself as well and historically there was no difference between contact.foo
and contract.functions.foo
. The original reason for the functions
bucket was to help when there were method names that collided with other buckets, which is rare.
In v5, the functions
bucket is now intended to help with frameworks and for the new error recovery API, so most users should use the methods on the root contract.
The main difference will occur when a contract method only returns a single item. The root method will dereference this automatically while the functions
bucket will preserve it as an Result.
如果一个方法返回多个项,则没有区别。
This helps when creating a framework, since the result will always be known to have the same number of components as the Fragment outputs, without having to handle the special case of a single return value.
const abi = [
"function single() view returns (uint8)",
"function double() view returns (uint8, uint8)",
];
await contract.single()
await contract.functions.single()
await contract.single()
await contract.functions.single()
await contract.double()
await contract.functions.double()
await contract.double()
await contract.functions.double()
所有错误现在属于Logger类,相关的函数已经转移到Logger实例中, 它可以包括每个包的版本字符串
全局错误函数已经被移至Logger类方法中。
ethers.errors.UNKNOWN_ERROR
ethers.errors.*
errors.setCensorship(censorship, permanent)
errors.setLogLevel(logLevel)
errors.checkArgumentCount(count, expectedCount, suffix)
errors.checkNew(self, kind)
errors.checkNormalize()
errors.throwError(message, code, params)
errors.warn(...)
errors.info(...)
ethers.utils.Logger.errors.UNKNOWN_ERROR
ethers.utils.Logger.errors.*
Logger.setCensorship(censorship, permanent)
Logger.setLogLevel(logLevel)
const logger = new ethers.utils.Logger(version);
logger.checkArgumentCount(count, expectedCount, suffix)
logger.checkNew(self, kind)
logger.checkNormalize()
logger.throwError(message, code, params)
logger.warn(...)
logger.info(...)
[[接口]]对象经历了最具戏剧性的变化。
它不再是一个元类,现在有一些方法可以简化处理合约接口操作,而不需要进行对象检查和特殊的临界情况
interface.functions.transfer.encode(to, amount)
interface.functions.transfer.decode(callData)
interface.encodeFunctionData("transfer", [ to, amount ])
interface.decodeFunctionResult("transfer", data)
interface.encodeFunctionData("transfer(address,uint)", [ to, amount ])
interface.decodeFunctionResult("transfer(address to, uint256 amount)", data)
interface.events.Transfer.encodeTopics(values)
interface.events.Transfer.decode(data, topics)
interface.encodeFilterTopics("Transfer", values)
interface.decodeEventLog("Transfer", data, topics)
现在(大部分)关于一个函数或者事件的查询可以直接在Fragment对象上完成
// v4
interface.functions.transfer.name
interface.functions.transfer.inputs
interface.functions.transfer.outputs
interface.functions.transfer.payable
interface.functions.transfer.gas
// v5
const functionFragment = interface.getFunction("transfer")
functionFragment.name
functionFragment.inputs
functionFragment.outputs
functionFragment.payable
functionFragment.gas
// v4; type is "call" or "transaction"
interface.functions.transfer.type
// v5; constant is true (i.e. "call") or false (i.e. "transaction")
functionFragment.constant
// v4
interface.events.Transfer.anonymous
interface.events.Transfer.inputs
interface.events.Transfer.name
// v5
const eventFragment = interface.getEvent("Transfer");
eventFragment.anonymous
eventFragment.inputs
eventFragment.name
// v4
const functionSig = interface.functions.transfer.signature
const sighash = interface.functions.transfer.sighash
const eventSig = interface.events.Transfer.signature
const topic = interface.events.Transfer.topic
// v5
const functionSig = functionFragment.format()
const sighash = interface.getSighash(functionFragment)
const eventSig = eventFragment.format()
const topic = interface.getTopic(eventFragment)
mnemonic短语和相关属性已经合并为一个mnemonic
对象,它现在也包括locale
.
wallet.mnemonic
wallet.path
wallet.mnemonic.phrase
wallet.mnemonic.path