The ethers.js library aims to be a complete and compact library for interacting with the Ethereum Blockchain and its ecosystem.
It is often used to create decentralized applications (dapps), wallets (such as MetaMask and Tally) and other tools and simple scripts that require reading and writing to the blockchain.
These docs are still under construction, and are being expanded every day.
Developers new to Ethers should be sure to read through the Getting Started section.
And the Application Programming Interface is available for drilling down into more details about the entire Application Programming Interface.
This is a very short introduction to Ethers, but covers many of the most common operations that developers require and provides a starting point for those newer to Ethereum.
Everything in Ethers is exported from its root as well as on the ethers object. There are also exports in the package.json to facilitate more fine-grained importing.
Generally this documentation will presume all exports from ethers have been imported in the code examples, but you may import the necessary objects any way you wish.
To begin, it is useful to have a basic understanding of the types of objects available and what they are responsible for, at a high level.
A Provider is a read-only connection to the blockchain, which allows querying the blockchain state, such as account, block or transaction details, querying event logs or evaluating read-only code using call.
If you are coming from Web3.js, you are used to a Provider offering both read and write access. In Ethers, all write operations are further abstracted into another Object, the Signer.
A Signer wraps all operations that interact with an account. An account generally has a private key located somewhere, which can be used to sign a variety of types of payloads.
The private key may be located in memory (using a Wallet) or protected via some IPC layer, such as MetaMask which proxies interaction from a website to a browser plug-in, which keeps the private key out of the reach of the website and only permits interaction after requesting permission from the user and receiving authorization.
To make any state changes to the blockchain, a transaction is required, which requires a fee be paid, where the fee covers the associated costs with executing the transaction (such as reading the disk and performing maths) and storing the updated information.
If a transaction reverts, a fee must still be paid, since the validator still had to expend resources to try running the transaction to determine that it reverted and the details of its failure are still be recorded.
Transactions include sending ether from one user to another, deploying a Contract or executing a state-changing operation against a Contract.
A Contract is a program that has been deployed to the blockchain, which includes some code and has allocated storage which it can read from and write to.
It may be read from when it is connected to a Provider or state-changing operations can be called when connected to a Signer.
Once a Transaction has been submitted to the blockchain, it is placed in the memory pool (mempool) until a validator decides to include it.
A transaction's changes are only made once it has been included in the blockchain, at which time a receipt is available, which includes details about the transaction, such as which block it was included in, the actual fee paid, gas used, all the events that it emitted and whether it was successful or reverted.
This very first thing needed to begin interacting with the blockchain is connecting to it using a Provider.
The quickest and easiest way to experiment and begin developing on Ethereum is to use MetaMask, which is a browser extension that injects objects into the window, providing:
- read-only access to the Ethereum network (a Provider)
- authenticated write access backed by a private key (a Signer)
When requesting access to the authenticated methods, such as sending a transaction or even requesting the private key address, MetaMask will show a pop-up to the user asking for permission.
If you are running your own Ethereum node (e.g. Geth) or using a custom third-party service (e.g. INFURA), you can use the JsonRpcProvider directly, which communicates using the link-jsonrpc protocol.
When using your own Ethereum node or a developer-base blockchain, such as Hardhat or Ganache, you can get access the accounts with JsonRpcProvider-getSigner.
All units in Ethereum tend to be integer values, since dealing with decimals and floating points can lead to imprecise and non-obvious results when performing mathematic operations.
As a result, the internal units used (e.g. wei) which are suited for machine-readable purposes and maths are often very large and not terribly human-readable.
For example, imagine dealing with dollars and cents; you would show values like "$2.56". In the blockchain world we would keep all values as cents, so that would be 256 cents, internally.
So, when accepting data that a user types, it must be converted from its decimal string representation (e.g. "2.56") to its lowest-unit integer representation (e.g. 256). And when displaying a value to a user the opposite operation is necessary.
In Ethereum, one ether is equal to 10 ** 18 wei and one gwei is equal to 10 ** 9 wei, so the values get very large very quickly, so some convenience functions are provided to help convert between representations.
Once you have a Provider, you have a read-only connection to the data on the blockchain. This can be used to query the current account state, fetch historic logs, look up contract code and so on.
To write to the blockchain you require access to a private key which controls some account. In most cases, those private keys are not accessible directly to your code, and instead you make requests via a Signer, which dispatches the request to a service (such as MetaMask) which provides strictly gated access and requires feedback to the user to approve or reject operations.
A Contract is a meta-class, which means that its definition its derived at run-time, based on the ABI it is passed, which then determined what methods and properties are available on it.
Since all operations that occur on the blockchain must be encoded as binary data, we need a concise way to define how to convert between common objects (like strings and numbers) and its binary representation, as well as encode the ways to call and interpret the Contract.
For any method, event or error you wish to use, you must include a Fragment to inform Ethers how it should encode the request and decode the result.
Any methods or events that are not needed can be safely excluded.
There are several common formats available to describe an ABI. The Solidity compiler usually dumps a JSON representation but when typing an ABI by hand it is often easier (and more readable) to use the human-readable ABI, which is just the Solidity signature.
A read-only method is one which cannot change the state of the blockchain, but often provide a simple interface to get important data about a Contract.
When adding event listeners for a named event, the event parameters are destructed for the listener.
There is always one additional parameter passed to a listener, which is an EventPayload, which includes more information about the event including the filter and a method to remove that listener.
When querying within a large range of blocks, some backends may be prohibitively slow, may return an error or may truncate the results without any indication. This is at the discretion of each backend.
A private key can do a lot more than just sign a transaction to authorize it. It can also be used to sign other forms of data, which are then able to be validated for other purposes.
For example, signing a message can be used to prove ownership of an account which a website could use to authenticate a user and log them in.
An Interface abstracts many of the low-level details for encoding and decoding the data on the blockchain.
An ABI provides information on how to encode data to send to a Contract, how to decode the results and events and how to interpret revert errors.
The ABI can be specified by any supported format.
Decodes the result data (e.g. from an eth_call) for the specified error (see getError for valid values for key).
Most developers should prefer the parseCallResult method instead, which will automatically detect a CALL_EXCEPTION and throw the corresponding error.
Decodes the data from a transaction tx.data for the function specified (see getFunction for valid values for fragment).
Most developers should prefer the parseTransaction method instead, which will automatically detect the fragment.
Decodes the result data (e.g. from an eth_call) for the specified function (see getFunction for valid values for key).
Most developers should prefer the parseCallResult method instead, which will automatically detect a CALL_EXCEPTION and throw the corresponding error.
Encodes the transaction revert data for a call result that reverted from the the Contract with the sepcified error (see getError for valid values for fragment) with the values.
This is generally not used by most developers, unless trying to mock a result from a Contract.
Encodes the tx.data for a transaction that calls the function specified (see getFunction for valid values for fragment) with the values.
Encodes the result data (e.g. from an eth_call) for the specified function (see getFunction for valid values for fragment) with values.
This is generally not used by most developers, unless trying to mock a result from a Contract.
Get the ErrorFragment for key, which may be an error selector, error name or error signature that belongs to the ABI.
If values is provided, it will use the Typed API to handle ambiguous cases where multiple errors match by name.
If the key and values do not refine to a single error in the ABI, this will throw.
Get the EventFragment for key, which may be a topic hash, event name or event signature that belongs to the ABI.
If values is provided, it will use the Typed API to handle ambiguous cases where multiple events match by name.
If the key and values do not refine to a single event in the ABI, this will throw.
Get the FunctionFragment for key, which may be a function selector, function name or function signature that belongs to the ABI.
If values is provided, it will use the Typed API to handle ambiguous cases where multiple functions match by name.
If the key and values do not refine to a single function in the ABI, this will throw.
When sending values to or receiving values from a Contract, the data is generally encoded using the ABI standard.
The AbiCoder provides a utility to encode values to ABI data and decode values from ABI data.
Most of the time, developers should favour the Contract class, which further abstracts a lot of the finer details of ABI data.
Returns the shared singleton instance of a default AbiCoder.
Returns an ethers-compatible CallExceptionError Error for the given result data for the CallExceptionAction action against the Transaction tx.
The type of a Fragment.
When walking asynchronously a ParamType, this is called on each component.
Returns true if value is a ConstructorFragment.
Returns true if value is an ErrorFragment.
Returns true if value is an EventFragment.
Returns true if value is a FunctionFragment.
Returns true if value is a StructFragment.
Each input and output of a Fragment is an Array of PAramType.
Returns true if this is an Array type.
This provides a type gaurd ensuring that arrayChildren and arrayLength are non-null.
Returns true if this is an Indexable type.
This provides a type gaurd ensuring that indexed is non-null.
Returns true if this is a Tuple type.
This provides a type gaurd ensuring that components is non-null.
Addresses are a fundamental part of interacting with Ethereum. They represent the gloabal identity of Externally Owned Accounts (accounts backed by a private key) and contracts.
The Ethereum Naming Service (ENS) provides an interconnected ecosystem of contracts, standards and libraries which enable looking up an address for an ENS name.
These functions help convert between various formats, validate addresses and safely resolve ENS names.
Returns a normalized and checksumed address for address. This accepts non-checksum addresses, checksum addresses and getIcapAddress formats.
The checksum in Ethereum uses the capitalization (upper-case vs lower-case) of the characters within an address to encode its checksum, which offers, on average, a checksum of 15-bits.
If address contains both upper-case and lower-case, it is assumed to already be a checksum address and its checksum is validated, and if the address fails its expected checksum an error is thrown.
If you wish the checksum of address to be ignore, it should be converted to lower-case (i.e. .toLowercase()) before being passed in. This should be a very rare situation though, that you wish to bypass the safegaurds in place to protect against an address that has been incorrectly copied from another source.
Returns the address that would result from a CREATE2 operation with the given from, salt and initCodeHash.
To compute the initCodeHash from a contract's init code, use the keccak256 function.
For a quick overview and example of CREATE2, see Wisps: The Magical World of Create2.
Returns the address that would result from a CREATE for tx.
This can be used to compute the address a contract will be deployed to by an EOA when sending a deployment transaction (i.e. when the to address is null).
This can also be used to compute the address a contract will be deployed to by a contract, by using the contract's address as the to and the contract's nonce.
The ICAP Address format format is an early checksum format which attempts to be compatible with the banking industry IBAN format for bank accounts.
Returns true if value is an object which implements the Addressable interface.
Resolves to an address for the target, which may be any supported address type, an Addressable or a Promise which resolves to an address.
If an ENS name is provided, but that name has not been correctly configured a UnconfiguredNameError is thrown.
Resolve to the address for the ENS name.
Resolves to null if the name is unconfigued. Use resolveAddress (passing this object as resolver) to throw for names that are unconfigured.
Compute the cryptographic KECCAK256 hash of data.
The data must be a data representation, to compute the hash of UTF-8 data use the id function.
An HMAC enables verification that a given key was used to authenticate a payload.
See: link-wiki-hmac
Return the PBKDF2 for keylen bytes for password using the salt and using iterations of algo.
This PBKDF is outdated and should not be used in new projects, but is required to decrypt older files.
The scrypt PBKDF uses a memory and cpu hard method of derivation to increase the resource cost to brute-force a password for a given key.
This means this algorithm is intentionally slow, and can be tuned to become slower. As computation and memory speed improve over time, increasing the difficulty maintains the cost of an attacker.
For example, if a target time of 5 seconds is used, a legitimate user which knows their password requires only 5 seconds to unlock their account. A 6 character password has 68 billion possibilities, which would require an attacker to invest over 10,000 years of CPU time. This is of course a crude example (as password generally aren't random), but demonstrates to value of imposing large costs to decryption.
For this reason, if building a UI which involved decrypting or encrypting datsa using scrypt, it is recommended to use a ProgressCallback (as event short periods can seem lik an eternity if the UI freezes). Including the phrase "decrypting" in the UI can also help, assuring the user their waiting is for a good reason.
Provides a synchronous variant of scrypt.
This will completely lock up and freeze the UI in a browser and will prevent any event loop from progressing. For this reason, it is preferred to use the async variant.
The EIP-2098 compact representation of the yParity and s compacted into a single bytes32.
Compute the v for a chain ID for a legacy EIP-155 transactions.
Legacy transactions which use EIP-155 hijack the v property to include the chain ID.
Compute the normalized legacy transaction v from a yParirty, a legacy transaction v or a legacy EIP-155 transaction.
Returns the ECDH shared secret between this private key and the other key.
The other key may be any type of key, a raw public key, a compressed/uncompressed pubic key or aprivate key.
Best practice is usually to use a cryptographic hash on the returned value before using it as a symetric secret.
Returns the point resulting from adding the ellipic curve points p0 and p1.
This is not a common function most developers should require, but can be useful for certain privacy-specific techniques.
For example, it is used by HDNodeWallet to compute child addresses from parent public keys and chain codes.
Computes the EIP-191 personal-sign message digest to sign.
This prefixes the message with MessagePrefix and the decimal length of message and computes the keccak256 digest.
If message is a string, it is converted to its UTF-8 bytes first. To compute the digest of a DataHexString, it must be converted to bytes.
A simple hashing function which operates on UTF-8 strings to compute an 32-byte irentifier.
This simply computes the UTF-8 bytes and computes the keccak256.
Computes the Non-Standard Packed Mode representation of values respectively to their types.
Computes the Non-Standard Packed Mode keccak256 hash of values respectively to their types.
Computes the Non-Standard Packed Mode sha256 hash of values respectively to their types.
The maximum fee to pay per gas.
The base fee per gas is defined by the network and based on congestion, increasing the cost during times of heavy load and lowering when less busy.
The actual fee per gas will be the base fee for the block and the priority fee, up to the max fee per gas.
This will be null on legacy networks (i.e. pre-EIP-1559)
The additional amout to pay per gas to encourage a validator to include the transaction.
The purpose of this is to compensate the validator for the adjusted risk for including a given transaction.
This will be null on legacy networks (i.e. pre-EIP-1559)
An Interface to indicate a Block has been included in the blockchain. This asserts a Type Guard that necessary properties are non-null.
A Provider is the primary method to interact with the read-only content on Ethereum.
It allows access to details about accounts, blocks and transactions and the ability to query event logs and simulate contract execution.
Account data includes the balance, transaction count, code and state trie storage.
Simulating execution can be used to call, estimate gas and get transaction results.
The broadcastTransaction is the only method which allows updating the blockchain, but it is usually accessed by a Signer, since a private key must be used to sign the transaction before it can be broadcast.
This is part of the necessary API for executing a contract, as it provides a common property on any ContractRunner that can be used to access the read-only portion of the runner.
Simulate the execution of tx. If the call reverts, it will throw a CallExceptionError which includes the revert data.
Get the account balance (in wei) of address. If blockTag is specified and the node supports archive access for that blockTag, the balance is as of that BlockTag.
Resolves to the block for blockHashOrBlockTag.
If prefetchTxs, and the backend supports including transactions with block requests, all transactions will be included and the Block object will not need to make remote calls for getting transactions.
Get the number of transactions ever sent for address, which is used as the nonce when sending a transaction. If blockTag is specified and the node supports archive access for that blockTag, the transaction count is as of that BlockTag.
A Signer represents an account on the Ethereum Blockchain, and is most often backed by a private key represented by a mnemonic or residing on a Hardware Wallet.
The API remains abstract though, so that it can deal with more advanced exotic Signing entities, such as Smart Contract Wallets or Virtual Wallets (where the private key may not be known).
Evaluates the tx by running it against the current Blockchain state. This cannot change state and has no cost in ether, as it is effectively simulating execution.
This can be used to have the Blockchain perform computations based on its state (e.g. running a Contract's getters) or to simulate the effect of a transaction before actually performing an operation.
Estimates the required gas required to execute tx on the Blockchain. This will be the expected amount a transaction will require as its gasLimit to successfully run all the necessary computations and store the needed state that the transaction intends.
Keep in mind that this is best efforts, since the state of the Blockchain is in flux, which could affect transaction gas requirements.
Prepares a {@link TransactionRequest} for sending to the network by populating any missing properties:
- resolves to and from addresses
- if from is specified , check that it matches this Signer
- populates nonce via signer.getNonce("pending")
- populates gasLimit via signer.estimateGas(tx)
- populates chainId via signer.provider.getNetwork()
- populates type and relevant fee data for that type (gasPrice for legacy transactions, maxFeePerGas for EIP-1559, etc)
Signers an EIP-191 prefixed personal message.
If the message is a string, it is signed as UTF-8 encoded bytes. It is not interpretted as a BytesLike; so the string "0x1234" is signed as six characters, not two bytes.
To sign that example as two bytes, the Uint8Array should be used (i.e. new Uint8Array([ 0x12, 0x34 ])).
Signs the EIP-712 typed data.
The EIP-2930 access list for transaction types that support it, otherwise null.
The sender of this transaction. It is implicitly computed from the transaction pre-image hash (as the digest) and the signature using ecrecover.
The gas price can have various values, depending on the network.
In modern networks, for transactions that are included this is the effective gas price (the fee per gas that was actually charged), while for transactions that have not been included yet is the maxFeePerGas.
For legacy transactions, or transactions on legacy networks, this is the fee that will be charged per unit of gas the transaction consumes.
The nonce, which is used to prevent replay attacks and offer a method to ensure transactions from a given sender are explicitly ordered.
When sending a transaction, this must be equal to the number of transactions ever sent by from.
The receiver of this transaction.
If null, then the transaction is an initcode transaction. This means the result of executing the data will be deployed as a new contract on chain (assuming it does not revert) and the address may be computed using getCreateAddress.
The EIP-2718 transaction envelope type. This is 0 for legacy transactions types.
The value, in wei. Use formatEther to format this value as ether.
Returns true if the transaction is a Berlin (i.e. type == 1) transaction. See EIP-2930.
This provides a Type Guard that this transaction will have the null-ness for hardfork-specific properties set correctly.
Returns true if the transaction is a London (i.e. type == 2) transaction. See EIP-1559.
This provides a Type Guard that this transaction will have the null-ness for hardfork-specific properties set correctly.
Returns true if this transaction has been included.
This is effective only as of the time the TransactionResponse was instantiated. To get up-to-date information, use getTransaction.
This provides a Type Guard that this transaction will have non-null property values for properties that are null for unmined transactions.
Returns a new TransactionResponse instance which has the ability to detect (and throw an error) if the transaction is replaced, which will begin scanning at startBlock.
This should generally not be used by developers and is intended primarily for internal use. Setting an incorrect startBlock can have devastating performance consequences if used incorrectly.
A Networkish can be used to allude to a Network, by specifing:
- a Network object
- a well-known (or registered) network name
- a well-known (or registered) chain ID
- an object with sufficient details to describe a network
Resolves to the avatar url or null if the avatar is either unconfigured or incorrectly configured (e.g. references an NFT not owned by the address).
If diagnosing issues with configurations, the _getAvatar method may be useful.
Additional options to configure a FallbackProvider.
A configuration entry for how to use a Provider.