ethers.js/docs/v5/migration/ethers-v4/index.html
2021-02-08 15:26:10 -05:00

250 lines
20 KiB
HTML

<!DOCTYPE html>
<html class="paged">
<head>
<title>Migration: From Ethers v4</title>
<link rel="stylesheet" type="text/css" href="/v5/static/style.css">
<meta property="og:title" content="Migration: From Ethers v4"/>
<meta property="og:description" content="Documentation for ethers, a complete, tiny and simple Ethereum library."/>
<meta property="og:image" content="/v5/static/social.jpg"/>
</head>
<body>
<div class="sidebar">
<div class="header">
<div class="logo"><a href="/v5/"><div class="image"></div><div class="name">ethers</div><div class="version">v5.0</div></a></div>
<div class="search"><form action="/v5/search/" method="GET"><input name="search" id="search" /></form><span class="search-icon">&#9906;</span></div>
</div>
<div class="toc"><div>
<div class="link title"><a href="/v5/">Documentation</a></div><div class="base show link depth-1"><a href="/v5/getting-started/">Getting Started</a></div><div class="base show link depth-1"><a href="/v5/concepts/">Ethereum Basics</a></div><div class="hide link depth-2"><a href="/v5/concepts/events/">Events</a></div><div class="hide link depth-2"><a href="/v5/concepts/gas/">Gas</a></div><div class="hide link depth-2"><a href="/v5/concepts/security/">Security</a></div><div class="hide link depth-2"><a href="/v5/concepts/best-practices/">Best Practices</a></div><div class="base show link depth-1"><a href="/v5/api-keys/">Provider API Keys</a></div><div class="base show link depth-1"><a href="/v5/api/">Application Programming Interface</a></div><div class="hide link depth-2"><a href="/v5/api/providers/">Providers</a></div><div class="hide link depth-3"><a href="/v5/api/providers/provider/">Provider</a></div><div class="hide link depth-3"><a href="/v5/api/providers/jsonrpc-provider/">JsonRpcProvider</a></div><div class="hide link depth-3"><a href="/v5/api/providers/api-providers/">API Providers</a></div><div class="hide link depth-3"><a href="/v5/api/providers/other/">Other Providers</a></div><div class="hide link depth-3"><a href="/v5/api/providers/types/">Types</a></div><div class="hide link depth-2"><a href="/v5/api/signer/">Signers</a></div><div class="hide link depth-2"><a href="/v5/api/contract/">Contract Interaction</a></div><div class="hide link depth-3"><a href="/v5/api/contract/contract/">Contract</a></div><div class="hide link depth-3"><a href="/v5/api/contract/contract-factory/">ContractFactory</a></div><div class="hide link depth-3"><a href="/v5/api/contract/example/">Example: ERC-20 Contract</a></div><div class="hide link depth-2"><a href="/v5/api/utils/">Utilities</a></div><div class="hide link depth-3"><a href="/v5/api/utils/abi/">Application Binary Interface</a></div><div class="hide link depth-4"><a href="/v5/api/utils/abi/coder/">AbiCoder</a></div><div class="hide link depth-4"><a href="/v5/api/utils/abi/formats/">ABI Formats</a></div><div class="hide link depth-4"><a href="/v5/api/utils/abi/fragments/">Fragments</a></div><div class="hide link depth-4"><a href="/v5/api/utils/abi/interface/">Interface</a></div><div class="hide link depth-3"><a href="/v5/api/utils/address/">Addresses</a></div><div class="hide link depth-3"><a href="/v5/api/utils/bignumber/">BigNumber</a></div><div class="hide link depth-3"><a href="/v5/api/utils/bytes/">Byte Manipulation</a></div><div class="hide link depth-3"><a href="/v5/api/utils/constants/">Constants</a></div><div class="hide link depth-3"><a href="/v5/api/utils/display-logic/">Display Logic and Input</a></div><div class="hide link depth-3"><a href="/v5/api/utils/encoding/">Encoding Utilities</a></div><div class="hide link depth-3"><a href="/v5/api/utils/fixednumber/">FixedNumber</a></div><div class="hide link depth-3"><a href="/v5/api/utils/hashing/">Hashing Algorithms</a></div><div class="hide link depth-3"><a href="/v5/api/utils/hdnode/">HD Wallet</a></div><div class="hide link depth-3"><a href="/v5/api/utils/logger/">Logging</a></div><div class="hide link depth-3"><a href="/v5/api/utils/properties/">Property Utilities</a></div><div class="hide link depth-3"><a href="/v5/api/utils/signing-key/">Signing Key</a></div><div class="hide link depth-3"><a href="/v5/api/utils/strings/">Strings</a></div><div class="hide link depth-3"><a href="/v5/api/utils/transactions/">Transactions</a></div><div class="hide link depth-3"><a href="/v5/api/utils/web/">Web Utilities</a></div><div class="hide link depth-3"><a href="/v5/api/utils/wordlists/">Wordlists</a></div><div class="hide link depth-2"><a href="/v5/api/other/">Other Libraries</a></div><div class="hide link depth-3"><a href="/v5/api/other/assembly/">Assembly</a></div><div class="hide link depth-4"><a href="/v5/api/other/assembly/dialect/">Ethers ASM Dialect</a></div><div class="hide link depth-4"><a href="/v5/api/other/assembly/api/">Utilities</a></div><div class="hide link depth-4"><a href="/v5/api/other/assembly/ast/">Abstract Syntax Tree</a></div><div class="hide link depth-3"><a href="/v5/api/other/hardware/">Hardware Wallets</a></div><div class="hide link depth-2"><a href="/v5/api/experimental/">Experimental</a></div><div class="base show link depth-1"><a href="/v5/cli/">Command Line Interfaces</a></div><div class="hide link depth-2"><a href="/v5/cli/ethers/">Sandbox Utility</a></div><div class="hide link depth-2"><a href="/v5/cli/asm/">Assembler</a></div><div class="hide link depth-2"><a href="/v5/cli/ens/">Ethereum Naming Service</a></div><div class="hide link depth-2"><a href="/v5/cli/typescript/">TypeScript</a></div><div class="hide link depth-2"><a href="/v5/cli/plugin/">Making Your Own</a></div><div class="base show link depth-1"><a href="/v5/cookbook/">Cookbook</a></div><div class="hide link depth-2"><a href="/v5/cookbook/react-native/">React Native (and ilk)</a></div><div class="base ancestor show link depth-1"><a href="/v5/migration/">Migration Guide</a></div><div class="show link depth-2"><a href="/v5/migration/web3/">Migration: From Web3.js</a></div><div class="myself ancestor ancestor show link depth-2"><a href="/v5/migration/ethers-v4/">Migration: From Ethers v4</a></div><div class="link show child depth-3"><a href="#migration-v4--bignumber">BigNumber</a></div><div class="link show child depth-3"><a href="#migration-v4--contracts">Contracts</a></div><div class="link show child depth-3"><a href="#migration-v4--errors">Errors</a></div><div class="link show child depth-3"><a href="#migration-v4--interface">Interface</a></div><div class="link show child depth-3"><a href="#migration-v4--wallet">Wallet</a></div><div class="base show link depth-1"><a href="/v5/testing/">Testing</a></div><div class="base show link depth-1"><a href="/v5/contributing/">Contributing and Hacking</a></div><div class="base show link depth-1"><a href="/v5/other-resources/">Other Resources</a></div><div class="base show link depth-1"><a href="/v5/documentation/">Flatworm Docs</a></div><div class="base show link depth-1"><a href="/v5/license/">License and Copyright</a></div>
</div></div>
<div class="footer">
<a href="/v5/single-page/">Single Page</a>
</div>
</div>
<div class="content">
<div class="breadcrumbs"><a href="/v5/">Documentation</a>&nbsp;&nbsp;&raquo;&nbsp;&nbsp;<a href="/v5/migration/">Migration Guide</a>&nbsp;&nbsp;&raquo;&nbsp;&nbsp;<span class="current">Migration: From Ethers v4</span></div>
<a name="migration-v4"></a><a name="migration-v4"></a><h1 class="show-anchors"><div>Migration: From Ethers v4<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4"></a></div></div></h1><p>This document only covers the features present in v4 which have changed in some important way in v5.</p>
<p>It does not cover all the new additional features that have been added and mainly aims to help those updating their older scripts and applications to retain functional parity.</p>
<p>If you encounter any missing changes, please let me know and I'll update this guide.</p>
<a name="migration-v4--bignumber"></a><h2 class="show-anchors"><div>BigNumber<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--bignumber"></a></div></div></h2>
<a name="migration-v4--bignumber--namespace"></a><h3 class="show-anchors"><div>Namespace<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--bignumber--namespace"></a></div></div></h3><p>Since <a href="/v5/api/utils/bignumber/">BigNumber</a> is used quite frequently, it has been moved to the top level of the umbrella package.</p>
<div class="code"><span class="comment">// v4
</span>ethers.utils.BigNumber
ethers.utils.BigNumberish
<span class="comment">// v5
</span>ethers.BigNumber
ethers.BigNumberish
</div><a name="migration-v4--bignumber--creating-instances"></a><h3 class="show-anchors"><div>Creating Instances<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--bignumber--creating-instances"></a></div></div></h3><p>The <code class="inline">bigNumberify</code> method was always preferred over the constructor since it could short-circuit an object instantiation for [[BigNumber] objects (since they are immutable). This has been moved to a static <code class="inline">from</code> class method.</p>
<div class="code"><span class="comment">// v4
</span>new ethers.utils.BigNumber(someValue)
ethers.utils.bigNumberify(someValue);
<span class="comment">// v5
</span><span class="comment">// - Constructor is private
</span><span class="comment">// - Removed `bigNumberify`
</span>ethers.BigNumber.from(someValue)
</div><a name="migration-v4--contracts"></a><h2 class="show-anchors"><div>Contracts<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--contracts"></a></div></div></h2>
<a name="migration-v4--contracts--ens-name-resolution"></a><h3 class="show-anchors"><div>ENS Name Resolution<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--contracts--ens-name-resolution"></a></div></div></h3><p>The name of the resolved address has changed. If the address passed into the constructor was an ENS name, the address will be resolved before any calls are made to the contract.</p>
<p>The name of the property where the resolved address has changed from <code class="inline">addressPromise</code> to <code class="inline">resolvedAddress</code>.</p>
<div class="code-title"><div>Resolved ENS Names</div></div><div class="code"><span class="comment">// v4
</span>contract.addressPromise
<span class="comment">// v5
</span>contract.resolvedAddress
</div><a name="migration-v4--contracts--gas-estimation"></a><h3 class="show-anchors"><div>Gas Estimation<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--contracts--gas-estimation"></a></div></div></h3><p>The only difference in gas estimation is that the bucket has changed its name from <code class="inline">estimate</code> to <code class="inline">estimateGas</code>.</p>
<div class="code-title"><div>Gas Estimation</div></div><div class="code"><span class="comment">// v4
</span>contract.estimate.transfer(toAddress, amount)
<span class="comment">// v5
</span>contract.estimateGas.transfer(toAddress, amount)
</div><a name="migration-v4--contracts--functions"></a><h3 class="show-anchors"><div>Functions<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--contracts--functions"></a></div></div></h3><p>In a contract in ethers, there is a <code class="inline">functions</code> bucket, which exposes all the methods of a contract.</p>
<p>All these functions are available on the root contract itself as well and historically there was no difference between <code class="inline">contact.foo</code> and <code class="inline">contract.functions.foo</code>. The original reason for the <code class="inline">functions</code> bucket was to help when there were method names that collided with other buckets, which is rare.</p>
<p>In v5, the <code class="inline">functions</code> 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.</p>
<p>The main difference will occur when a contract method only returns a single item. The root method will dereference this automatically while the <code class="inline">functions</code> bucket will preserve it as an <a href="/v5/api/utils/abi/interface/#Result">Result</a>.</p>
<p>If a method returns multiple items, there is no difference.</p>
<p>This helps when creating a framework, since the result will always be known to have the same number of components as the <a href="/v5/api/utils/abi/fragments/#Fragment">Fragment</a> outputs, without having to handle the special case of a single return value.</p>
<div class="code-title"><div>Functions Bucket</div></div><div class="code">const abi = [
<span class="comment"> // Returns a single value
</span> "function single() view returns (uint8)",
<span class="comment"> // Returns two values
</span> "function double() view returns (uint8, uint8)",
];
<span class="comment">// v4
</span>await contract.single()
<span class="comment">// 123
</span>await contract.functions.single()
<span class="comment">// 123
</span>
<span class="comment">// v5 (notice the change in the .function variant)
</span>await contract.single()
<span class="comment">// 123
</span>await contract.functions.single()
<span class="comment">// [ 123 ]
</span>
<span class="comment">// v4
</span>await contract.double()
<span class="comment">// [ 123, 5 ]
</span>await contract.functions.double()
<span class="comment">// [ 123, 5 ]
</span>
<span class="comment">// v5 (no difference from v4)
</span>await contract.double()
<span class="comment">// [ 123, 5 ]
</span>await contract.functions.double()
<span class="comment">// [ 123, 5 ]
</span></div><a name="migration-v4--errors"></a><h2 class="show-anchors"><div>Errors<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--errors"></a></div></div></h2>
<a name="migration-v4--errors--namespace"></a><h3 class="show-anchors"><div>Namespace<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--errors--namespace"></a></div></div></h3><p>All errors now belong to the <a href="/v5/api/utils/logger/#Logger">Logger</a> class and the related functions have been moved to <a href="/v5/api/utils/logger/#Logger">Logger</a> instances, which can include a per-package version string.</p>
<p>Global error functions have been moved to <a href="/v5/api/utils/logger/#Logger">Logger</a> class methods.</p>
<div class="code"><span class="comment">// v4
</span>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(...)
<span class="comment">// v5
</span>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(...)
</div><a name="migration-v4--interface"></a><h2 class="show-anchors"><div>Interface<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--interface"></a></div></div></h2><p>The <a href="/v5/api/utils/abi/interface/">Interface</a> object has undergone the most dramatic changes.</p>
<p>It is no longer a meta-class and now has methods that simplify handling contract interface operations without the need for object inspection and special edge cases.</p>
<a name="migration-v4--interface--functions"></a><h3 class="show-anchors"><div>Functions<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--interface--functions"></a></div></div></h3>
<div class="code"><span class="comment">// v4 (example: "transfer(address to, uint amount)")
</span>interface.functions.transfer.encode(to, amount)
interface.functions.transfer.decode(callData)
<span class="comment">// v5
</span>interface.encodeFunctionData("transfer", [ to, amount ])
interface.decodeFunctionResult("transfer", data)
<span class="comment">// Or you can use any compatible signature or Fragment objects.
</span><span class="comment">// Notice that signature normalization is performed for you,
</span><span class="comment">// e.g. "uint" and "uint256" will be automatically converted
</span>interface.encodeFunctionData("transfer(address,uint)", [ to, amount ])
interface.decodeFunctionResult("transfer(address to, uint256 amount)", data)
</div><a name="migration-v4--interface--events"></a><h3 class="show-anchors"><div>Events<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--interface--events"></a></div></div></h3>
<div class="code"><span class="comment">// v4 (example: Transfer(address indexed, address indexed, uint256)
</span>interface.events.Transfer.encodeTopics(values)
interface.events.Transfer.decode(data, topics)
<span class="comment">// v5
</span>interface.encodeFilterTopics("Transfer", values)
interface.decodeEventLog("Transfer", data, topics)
</div><a name="migration-v4--interface--inspection"></a><h3 class="show-anchors"><div>Inspection<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--interface--inspection"></a></div></div></h3><p>Interrogating properties about a function or event can now (mostly) be done directly on the <a href="/v5/api/utils/abi/fragments/#Fragment">Fragment</a> object.</p>
<div class="code">// 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)</div><a name="migration-v4--wallet"></a><h2 class="show-anchors"><div>Wallet<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--wallet"></a></div></div></h2>
<a name="migration-v4--wallet--mnemonic-phrases"></a><h3 class="show-anchors"><div>Mnemonic Phrases<div class="anchors"><a class="self" href="/v5/migration/ethers-v4/#migration-v4--wallet--mnemonic-phrases"></a></div></div></h3><p>The <b>mnemonic</b> phrase and related properties have been merged into a single <code class="inline">mnemonic</code> object, which also now includes the <code class="inline">locale</code>.</p>
<div class="code"><span class="comment">// v4
</span>wallet.mnemonic
wallet.path
<span class="comment">// v5
</span><span class="comment">// - Mnemonic phrase and path are a Mnemonic object
</span><span class="comment">// - Note: wallet.mnemonic is null if there is no mnemonic
</span>wallet.mnemonic.phrase
wallet.mnemonic.path
</div>
<div class="footer">
<div class="nav previous"><a href="/v5/migration/web3/"><span class="arrow">&larr;</span>Migration: From Web3.js</a></div>
<div class="nav next"><a href="/v5/testing/">Testing<span class="arrow">&rarr;</span></a></div>
</div>
<div class="copyright">The content of this site is licensed under the <a href="https://choosealicense.com/licenses/cc-by-4.0/">Creative Commons License</a>. Generated on February 8, 2021, 3:25pm.</div>
</div>
<script src="/v5/static/script.js" type="text/javascript"></script>
<!--EXTRASCRIPT-->
</body>
</html>