ethers.js/docs.wrm/api/utils/abi/interface.wrm

468 lines
15 KiB
Plaintext
Raw Normal View History

2020-05-08 10:24:40 +03:00
_section: Interface @<Interface> @SRC<abi/interface:class.Interface>
2020-02-25 22:57:11 +03:00
The **Interface** Class abstracts the encoding and decoding required
to interact with contracts on the Ethereum network.
Many of the standards organically evolved along side the [[link-solidity]]
2020-10-03 19:30:15 +03:00
language, which other languages have adopted to remain compatible with
2020-02-25 22:57:11 +03:00
existing deployed contracts.
The EVM itself does not understand what the ABI is. It is simply an agreed
upon set of formats to encode various types of data which each contract can
expect so they can interoperate with each other.
2020-06-12 10:38:55 +03:00
_subsection: Creating Instances @<Interface--creating>
2020-02-25 22:57:11 +03:00
_property: new ethers.utils.Interface(abi) @SRC<abi/interface:constructor.Interface>
Create a new **Interface** from a JSON string or object representing
//abi//.
The //abi// may be a JSON string or the parsed Object (using JSON.parse)
which is emitted by the [Solidity compiler](link-solc-output) (or compatible languages).
The //abi// may also be a [Human-Readable Abi](link-ricmoo-humanreadableabi),
which is a format the Ethers created to simplify manually typing the ABI
into the source and so that a Contract ABI can also be referenced easily
within the same source file.
_code: Creating an Interface instance @lang<javascript>
//_hide: const Interface = ethers.utils.Interface;
// This interface is used for the below examples
const iface = new Interface([
"constructor(string symbol, string name)",
"function transferFrom(address from, address to, uint amount)",
"function balanceOf(address owner) view returns (uint)",
"function mint(uint amount) payable",
"event Transfer(address indexed from, address indexed to, uint256 amount)",
"error AccountLocked(address owner, uint256 balance)"
]);
//_hide: _page.iface = iface;
2020-06-12 10:38:55 +03:00
_subsection: Properties @<Interface--properties>
2020-02-25 22:57:11 +03:00
2020-05-08 10:24:40 +03:00
_property: interface.fragments => Array<[[Fragment]]>
All the [Fragments](Fragment) in the interface.
2020-02-25 22:57:11 +03:00
_property: interface.errors => Array<[[ErrorFragment]]>
All the [Error Fragments](ErrorFragment) in the interface.
2020-05-08 10:24:40 +03:00
_property: interface.events => Array<[[EventFragment]]>
All the [Event Fragments](EventFragment) in the interface.
2020-02-25 22:57:11 +03:00
2020-05-08 10:24:40 +03:00
_property: interface.functions => Array<[[FunctionFragment]]>
All the [Function Fragments](FunctionFragment) in the interface.
2020-02-25 22:57:11 +03:00
2020-05-08 10:24:40 +03:00
_property: interface.deploy => [[ConstructorFragment]]
The [Constructor Fragments](ConstructorFragment) for the interface.
2020-02-25 22:57:11 +03:00
2020-06-12 10:38:55 +03:00
_subsection: Formatting @<Interface--formatting>
2020-02-25 22:57:11 +03:00
_property: interface.format( [ format ]) => string | Array<string> @SRC<abi/interface>
Return the formatted **Interface**. If the format type is ``json`` a
single string is returned, otherwise an Array of the human-readable
strings is returned.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
const FormatTypes = ethers.utils.FormatTypes;
//_result:
iface.format(FormatTypes.json)
//_log:
//_result:
iface.format(FormatTypes.full)
//_log:
//_result:
iface.format(FormatTypes.minimal)
//_log:
2020-02-25 22:57:11 +03:00
2020-06-12 10:38:55 +03:00
_subsection: Fragment Access @<Interface--fragments>
2020-02-25 22:57:11 +03:00
2020-05-08 10:24:40 +03:00
_property: interface.getFunction(fragment) => [[FunctionFragment]] @SRC<abi/interface>
Returns the [[FunctionFragment]] for //fragment// (see [[Interface--specifying-fragments]]).
2020-02-25 22:57:11 +03:00
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// By method signature, which is normalized so whitespace
// and superfluous attributes are ignored
iface.getFunction("transferFrom(address, address, uint256)");
// By name; this ONLY works if the method is non-ambiguous
iface.getFunction("transferFrom");
// By method selector
iface.getFunction("0x23b872dd");
// Throws if the method does not exist
//_throws:
iface.getFunction("doesNotExist()");
//_log:
_property: interface.getError(fragment) => [[ErrorFragment]] @SRC<abi/interface>
Returns the [[ErrorFragment]] for //fragment// (see [[Interface--specifying-fragments]]).
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// By error signature, which is normalized so whitespace
// and superfluous attributes are ignored
iface.getError("AccountLocked(address, uint256)");
// By name; this ONLY works if the error is non-ambiguous
iface.getError("AccountLocked");
// By error selector
iface.getError("0xf7c3865a");
// Throws if the error does not exist
//_throws:
iface.getError("DoesNotExist()");
//_log:
2020-05-08 10:24:40 +03:00
_property: interface.getEvent(fragment) => [[EventFragment]] @SRC<abi/interface>
Returns the [[EventFragment]] for //fragment// (see [[Interface--specifying-fragments]]).
2020-02-25 22:57:11 +03:00
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// By event signature, which is normalized so whitespace
// and superfluous attributes are ignored
iface.getEvent("Transfer(address, address, uint256)");
// By name; this ONLY works if the event is non-ambiguous
iface.getEvent("Transfer");
// By event topic hash
iface.getEvent("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef");
// Throws if the event does not exist
//_throws:
iface.getEvent("DoesNotExist()");
//_log:
2020-02-25 22:57:11 +03:00
2020-06-12 10:38:55 +03:00
_subsection: Signature and Topic Hashes @<Interface--selectors>
2020-02-25 22:57:11 +03:00
2020-05-08 10:24:40 +03:00
_property: interface.getSighash(fragment) => string<[[DataHexString]]<4>> @SRC<abi/interface:method.Interface.getSighash>
Return the sighash (or Function Selector) for //fragment// (see [[Interface--specifying-fragments]]).
2020-02-25 22:57:11 +03:00
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_result:
iface.getSighash("balanceOf");
//_log:
//_result:
iface.getSighash("balanceOf(address)");
//_log:
const fragment = iface.getFunction("balanceOf")
//_result:
iface.getSighash(fragment);
//_log:
2020-05-08 10:24:40 +03:00
_property: interface.getEventTopic(fragment) => string<[[DataHexString]]<32>> @SRC<abi/interface:method.Interface.getEventTopic>
Return the topic hash for //fragment// (see [[Interface--specifying-fragments]]).
2020-02-25 22:57:11 +03:00
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_result:
iface.getEventTopic("Transfer");
//_log:
//_result:
iface.getEventTopic("Transfer(address, address, uint)");
//_log:
const fragment = iface.getEvent("Transfer")
//_result:
iface.getEventTopic(fragment);
//_log:
2020-02-25 22:57:11 +03:00
2020-06-12 10:38:55 +03:00
_subsection: Encoding Data @<Interface--encoding>
2020-02-25 22:57:11 +03:00
2020-05-08 10:24:40 +03:00
_property: interface.encodeDeploy([ values ]) => string<[[DataHexString]]> @SRC<abi/interface>
2020-02-25 22:57:11 +03:00
Return the encoded deployment data, which can be concatenated to the
deployment bytecode of a contract to pass //values// into the contract
constructor.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_hide: const parseEther = ethers.utils.parseEther;
// The data that should be appended to the bytecode to pass
// parameters to the constructor during deployment
//_result:
iface.encodeDeploy([ "SYM", "Some Name" ])
//_log:
_property: interface.encodeFilterTopics(fragment, values) => Array<topic | Array<topic>> @SRC<abi/interface>
2020-02-25 22:57:11 +03:00
Returns the encoded topic filter, which can be passed to getLogs for //fragment//
2020-05-08 10:24:40 +03:00
(see [[Interface--specifying-fragments]]) for the given //values//.
2020-02-25 22:57:11 +03:00
2020-05-08 10:24:40 +03:00
Each //topic// is a 32 byte (64 nibble) [[DataHexString]].
2020-02-25 22:57:11 +03:00
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_hide: const parseEther = ethers.utils.parseEther;
// Filter that matches all Transfer events
//_result:
iface.encodeFilterTopics("Transfer", [])
//_log:
// Filter that matches the sender
//_result:
iface.encodeFilterTopics("Transfer", [
"0x8ba1f109551bD432803012645Ac136ddd64DBA72"
])
//_log:
// Filter that matches the receiver
//_result:
iface.encodeFilterTopics("Transfer", [
null,
"0x8ba1f109551bD432803012645Ac136ddd64DBA72"
])
//_log:
2020-05-08 10:24:40 +03:00
_property: interface.encodeFunctionData(fragment [ , values ]) => string<[[DataHexString]]> @SRC<abi/interface>
2020-02-25 22:57:11 +03:00
Returns the encoded data, which can be used as the data for a transaction for
2020-05-08 10:24:40 +03:00
//fragment// (see [[Interface--specifying-fragments]]) for the given //values//.
2020-02-25 22:57:11 +03:00
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_hide: const parseEther = ethers.utils.parseEther;
// Encoding data for the tx.data of a call or transaction
//_result:
iface.encodeFunctionData("transferFrom", [
"0x8ba1f109551bD432803012645Ac136ddd64DBA72",
"0xaB7C8803962c0f2F5BBBe3FA8bf41cd82AA1923C",
parseEther("1.0")
])
//_log:
2020-05-08 10:24:40 +03:00
_property: interface.encodeFunctionResult(fragment [ , values ]) => string<[[DataHexString]]> @SRC<abi/interface>
2020-02-25 22:57:11 +03:00
Returns the encoded result, which would normally be the response from a call for
2020-05-08 10:24:40 +03:00
//fragment// (see [[Interface--specifying-fragments]]) for the given //values//.
2020-02-25 22:57:11 +03:00
Most developers will not need this method, but may be useful for authors of a mock blockchain.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_hide: const parseEther = ethers.utils.parseEther;
// Encoding result data (like is returned by eth_call)
//_result:
iface.encodeFunctionResult("balanceOf", [
"0x8ba1f109551bD432803012645Ac136ddd64DBA72"
])
//_log:
2020-02-25 22:57:11 +03:00
2020-06-12 10:38:55 +03:00
_subsection: Decoding Data @<Interface--decoding>
2020-02-25 22:57:11 +03:00
2020-05-08 10:24:40 +03:00
_property: interface.decodeEventLog(fragment, data [ , topics ]) => [[Result]] @SRC<abi/interface>
2020-02-25 22:57:11 +03:00
Returns the decoded event values from an event log for
2020-05-08 10:24:40 +03:00
//fragment// (see [[Interface--specifying-fragments]]) for the given //data//
2020-02-25 22:57:11 +03:00
with the optional //topics//.
If //topics// is not specified, placeholders will be inserted into the result.
Most develoeprs will find the [parsing methods](Interface--parsing) more
convenient for decoding event data, as they will automatically detect the
matching event.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// Decoding log data and topics (the entries in a receipt)
const data = "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000";
const topics = [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72",
"0x000000000000000000000000ab7c8803962c0f2f5bbbe3fa8bf41cd82aa1923c"
];
//_result:
iface.decodeEventLog("Transfer", data, topics);
//_log:
2020-05-08 10:24:40 +03:00
_property: interface.decodeFunctionData(fragment, data) => [[Result]] @SRC<abi/interface>
2020-02-25 22:57:11 +03:00
Returns the decoded values from transaction data for
2020-05-08 10:24:40 +03:00
//fragment// (see [[Interface--specifying-fragments]]) for the given //data//.
2020-02-25 22:57:11 +03:00
Most developers will not need this method, but may be useful for debugging
or inspecting transactions.
Most develoeprs will also find the [parsing methods](Interface--parsing) more
convenient for decoding transation data, as they will automatically detect the
matching function.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// Decoding function data (the value of tx.data)
const txData = "0x23b872dd0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72000000000000000000000000ab7c8803962c0f2f5bbbe3fa8bf41cd82aa1923c0000000000000000000000000000000000000000000000000de0b6b3a7640000";
//_result:
iface.decodeFunctionData("transferFrom", txData);
//_log:
2020-05-08 10:24:40 +03:00
_property: interface.decodeFunctionResult(fragment, data) => [[Result]] @SRC<abi/interface>
2020-02-25 22:57:11 +03:00
Returns the decoded values from the result of a call for
2020-05-08 10:24:40 +03:00
//fragment// (see [[Interface--specifying-fragments]]) for the given //data//.
2020-02-25 22:57:11 +03:00
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// Decoding result data (e.g. from an eth_call)
const resultData = "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000";
//_result:
iface.decodeFunctionResult("balanceOf", resultData)
//_log:
// Decoding result data which was caused by a revert
// Throws a CALL_EXCEPTION, with extra details
const errorData = "0xf7c3865a0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba720000000000000000000000000000000000000000000000000de0b6b3a7640000";
//_throws:
iface.decodeFunctionResult("balanceOf", errorData)
//_log:
2020-06-12 10:38:55 +03:00
_subsection: Parsing @<Interface--parsing>
2020-02-25 22:57:11 +03:00
The functions are generally the most useful for most developers. They will
automatically search the ABI for a matching Event or Function and decode
the components as a fully specified description.
2020-05-08 10:24:40 +03:00
_property: interface.parseLog(log) => [[LogDescription]] @SRC<abi/interface>
2020-02-25 22:57:11 +03:00
Search the event that matches the //log// topic hash and parse the values
the log represents.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
const data = "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000";
const topics = [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72",
"0x000000000000000000000000ab7c8803962c0f2f5bbbe3fa8bf41cd82aa1923c"
];
//_result:
iface.parseLog({ data, topics });
//_hide: _.eventFragment = createClass("EventFragment");
//_log:
2020-05-08 10:24:40 +03:00
_property: interface.parseTransaction(transaction) => [[TransactionDescription]] @SRC<abi/interface>
2020-02-25 22:57:11 +03:00
Search for the function that matches the //transaction// data sighash
and parse the transaction properties.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_hide: const parseEther = ethers.utils.parseEther;
const data = "0x23b872dd0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72000000000000000000000000ab7c8803962c0f2f5bbbe3fa8bf41cd82aa1923c0000000000000000000000000000000000000000000000000de0b6b3a7640000";
const value = parseEther("1.0");
//_result:
iface.parseTransaction({ data, value });
//_hide: _.functionFragment = createClass("FunctionFragment");
//_log:
2020-02-25 22:57:11 +03:00
2020-06-12 10:38:55 +03:00
_subsection: Types @<Interface--types>
2020-02-25 22:57:11 +03:00
2020-05-08 10:24:40 +03:00
_heading: Result @<Result> @INHERIT<Array\<any\>>
2020-02-25 22:57:11 +03:00
A **Result** is an array, so each value can be accessed as a positional
argument.
Additionally, if values are named, the identical object as its positional
value can be accessed by its name.
The name ``length`` is however reserved as it is part of the Array, so
any named value for this key is renamed to ``_length``. If there is a
name collision, only the first is available by its key.
2020-05-08 10:24:40 +03:00
_heading: LogDescription @<LogDescription>
2020-02-25 22:57:11 +03:00
2020-05-08 10:24:40 +03:00
_property: logDescription.args => [[Result]]
2020-02-25 22:57:11 +03:00
The values of the input parameters of the event.
2020-05-08 10:24:40 +03:00
_property: logDescription.eventFragment => [[EventFragment]]
The [[EventFragment]] which matches the topic in the Log.
2020-02-25 22:57:11 +03:00
_property: logDescription.name => string
The event name. (e.g. ``Transfer``)
_property: logDescription.signature => string
The event signature. (e.g. ``Transfer(address,address,uint256)``)
_property: logDescription.topic => string
The topic hash.
2020-05-08 10:24:40 +03:00
_heading: TransactionDescription @<TransactionDescription>
2020-02-25 22:57:11 +03:00
2020-05-08 10:24:40 +03:00
_property: transactionDescription.args => [[Result]]
2020-02-25 22:57:11 +03:00
The decoded values from the transaction data which were passed
as the input parameters.
2020-05-08 10:24:40 +03:00
_property: transactionDescription.functionFragment => [[FunctionFragment]]
The [[FunctionFragment]] which matches the sighash in the transaction data.
2020-02-25 22:57:11 +03:00
_property: transactionDescription.name => string
The name of the function. (e.g. ``transfer``)
_property: transactionDescription.sighash => string
The sighash (or function selector) that matched the transaction data.
_property: transactionDescription.signature => string
The signature of the function. (e.g. ``transfer(address,uint256)``)
2020-05-08 10:24:40 +03:00
_property: transactionDescription.value => [[BigNumber]]
2020-02-25 22:57:11 +03:00
The value from the transaction.
2020-05-08 10:24:40 +03:00
_subsection: Specifying Fragments @<Interface--specifying-fragments>
2020-02-25 22:57:11 +03:00
When specifying a fragment to any of the functions in an **Interface**,
any of the following may be used:
2020-04-17 05:25:05 +03:00
- The **name** of the event or function, if it is unique and non-ambiguous
2020-02-25 22:57:11 +03:00
within the ABI (e.g. ``transfer``)
2020-04-17 05:25:05 +03:00
- The **signature** of the event or function. The signature is normalized,
2020-02-25 22:57:11 +03:00
so, for example, ``uint`` and ``uint256`` are equivalent (e.g. ``transfer(address, uint)``)
2020-04-17 05:25:05 +03:00
- The **sighash** or **topichash** of the function. The sighash is often referred
2020-02-25 22:57:11 +03:00
to the function selector in Solidity (e.g. ``0xa9059cbb``)
2020-05-08 10:24:40 +03:00
- A [[Fragment]]