Compare commits
87 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bde861436e | ||
|
|
6e8a39ec35 | ||
|
|
ecae793edf | ||
|
|
bac684c5a0 | ||
|
|
53671d0b17 | ||
|
|
25c8b8b3e6 | ||
|
|
a0fa92c075 | ||
|
|
72feee8f58 | ||
|
|
71b7547f10 | ||
|
|
4970385e7b | ||
|
|
0364dd9368 | ||
|
|
e95708eedc | ||
|
|
ba6854bdd5 | ||
|
|
1e31b34a5a | ||
|
|
7deb4c174a | ||
|
|
f053a7ad58 | ||
|
|
b1affdbc10 | ||
|
|
c2c0ce7503 | ||
|
|
7efc36df29 | ||
|
|
720bde7719 | ||
|
|
319987ec3e | ||
|
|
2a7ce0e72a | ||
|
|
8ba64af29f | ||
|
|
17af9f812f | ||
|
|
d001901c8c | ||
|
|
91951dc825 | ||
|
|
8277f5a62a | ||
|
|
e615e51fbf | ||
|
|
99422c1c7c | ||
|
|
e8a0144b7a | ||
|
|
f9d09645e7 | ||
|
|
91fff1449d | ||
|
|
c5bca7767e | ||
|
|
79c5bf6bcb | ||
|
|
412bbe2939 | ||
|
|
ee82e86ccc | ||
|
|
376cf3cdbf | ||
|
|
89bae3bd63 | ||
|
|
a6e128f5cc | ||
|
|
5456c35924 | ||
|
|
be20e28de1 | ||
|
|
30c0c97270 | ||
|
|
4e6d121fb8 | ||
|
|
bfcd05fcbb | ||
|
|
819b1ace5c | ||
|
|
4b331148d9 | ||
|
|
7adcf3b154 | ||
|
|
630656e949 | ||
|
|
8681cd5969 | ||
|
|
470551e4ee | ||
|
|
7a12216cfb | ||
|
|
d395d16fa3 | ||
|
|
8077ce0aae | ||
|
|
2fe78ad7e3 | ||
|
|
5f1f2c5e2c | ||
|
|
3c79ee8cef | ||
|
|
772067a3c9 | ||
|
|
621897f249 | ||
|
|
d3b7130ed6 | ||
|
|
dad3829c2e | ||
|
|
de4d683f6d | ||
|
|
ebe4cc90f5 | ||
|
|
35e3bf9d11 | ||
|
|
2d717dcef8 | ||
|
|
3316468e3e | ||
|
|
5144acf456 | ||
|
|
aadc5cd3d6 | ||
|
|
6e088099ad | ||
|
|
b6370f1360 | ||
|
|
26464c5425 | ||
|
|
37a9c77ab2 | ||
|
|
4898e7baac | ||
|
|
c71bbbe7db | ||
|
|
c8fecbbc29 | ||
|
|
b4df28dddd | ||
|
|
483d67f55c | ||
|
|
987bec87af | ||
|
|
a9cdbe1238 | ||
|
|
4e9abfdee4 | ||
|
|
3bb5fbf533 | ||
|
|
cadccc3060 | ||
|
|
65196097f6 | ||
|
|
8e22e0260e | ||
|
|
de7da421b3 | ||
|
|
a9f7957550 | ||
|
|
bd2d44eecf | ||
|
|
bd05aed070 |
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: Bug report
|
||||
name: Bug Report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: investigate
|
||||
@@ -9,6 +9,8 @@ assignees: ''
|
||||
|
||||
Note: Not all sections may be relevant, but please be as thorough while remaining concise as possible. Remove this Notice and any sections that don't feel pertinent.
|
||||
|
||||
If you are unsure if something is a bug, start a thread in the *"discussions"* tab above..
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
@@ -19,4 +21,4 @@ Please include code snippets, with console.log output, any contract ABI, contrac
|
||||
Please include anything that may be useful in diagnosing the issue. Node vs Browser? Geth vs Parity vs Ganache? Third Party tools, like Hardhat? Mobile vs. Desktop?
|
||||
|
||||
**Search Terms**
|
||||
Often similar issues have come up before. Include any search terms you have tried in this repository's Issues (including closed issues) and Discussions, so if there are matching issues, we can be sure to add those keywords to make it easier for people to find in the future.
|
||||
Often similar issues have come up before. Include any search terms you have tried in this repository's Issues (including closed issues) and *"Discussions"*, so if there are matching issues, we can be sure to add those keywords and link this issue to it, making it easier for people to find in the future.
|
||||
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
16
.github/ISSUE_TEMPLATE/documentation.md
vendored
Normal file
16
.github/ISSUE_TEMPLATE/documentation.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: Documentation
|
||||
about: Documentation request or suggestion
|
||||
title: ''
|
||||
labels: documentation
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please include anything about the [documentation](https://docs.ethers.io) you would like to see improved.
|
||||
|
||||
- Missing information or details?
|
||||
- Wrong Information?
|
||||
- Dead or wrong links?
|
||||
- Something needs code examples?
|
||||
- General feedback or anything else?
|
||||
16
.github/ISSUE_TEMPLATE/other.md
vendored
Normal file
16
.github/ISSUE_TEMPLATE/other.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: Other
|
||||
about: Something else
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Generally this issue template should be used.
|
||||
|
||||
If your issue is **not** a **Feature Request**, a **Bug Report** or problem with the **Documentation** you should probably be using the *"Discussion"* tab at the top.
|
||||
|
||||
But for truly exceptional issues, please include the details here.
|
||||
|
||||
Please also include any search terms you used when searching issues and discussions, so we can better tag those in the future.
|
||||
62
CHANGELOG.md
62
CHANGELOG.md
@@ -3,6 +3,68 @@ Changelog
|
||||
|
||||
This change log is managed by `admin/cmds/update-versions` but may be manually updated.
|
||||
|
||||
ethers/v5.4.1 (2021-07-02 01:47)
|
||||
--------------------------------
|
||||
|
||||
- Added Pocket back into Homestead defaultProvider and skip certain EtherscanProvider tests affected by outage. ([6e8a39e](https://github.com/ethers-io/ethers.js/commit/6e8a39ec35123e681e47807f54ef9b9122635ea0))
|
||||
- Fixed EtherscanProvider NONCE_EXPIRED matching string update. ([ecae793](https://github.com/ethers-io/ethers.js/commit/ecae793edff172a885e5ee014a8ad0b28b68c1e5))
|
||||
- Fixed explicit EIP-1559 keys for JsonRpcSigner. ([72feee8](https://github.com/ethers-io/ethers.js/commit/72feee8f5841febdab0d15f09baa69539d95e199))
|
||||
|
||||
ethers/v5.4.0 (2021-06-26 01:50)
|
||||
--------------------------------
|
||||
|
||||
- Added EIP-1559 support. ([#1610](https://github.com/ethers-io/ethers.js/issues/1610); [319987e](https://github.com/ethers-io/ethers.js/commit/319987ec3e1d0e8787f98f525e5fc07875bf5570), [91fff14](https://github.com/ethers-io/ethers.js/commit/91fff1449df5e337fd3b4681b5a04b151d92f5a1), [c5bca77](https://github.com/ethers-io/ethers.js/commit/c5bca7767e3f3d43e3d0bd3c9e9420321ee9907a), [5456c35](https://github.com/ethers-io/ethers.js/commit/5456c359245d9eef5d2abdc05ccedb5269576c94), [7a12216](https://github.com/ethers-io/ethers.js/commit/7a12216cfbd3f86b917451924957471b8be21a8b), [e95708e](https://github.com/ethers-io/ethers.js/commit/e95708eedc130aeb92820a2234398970a987c507))
|
||||
- Added effectiveGasPrice to receipt. ([ba6854b](https://github.com/ethers-io/ethers.js/commit/ba6854bdd5a912fe873d5da494cb5c62c190adde))
|
||||
- Fixed ENS names for JsonRpcSigner. ([1e31b34](https://github.com/ethers-io/ethers.js/commit/1e31b34a5a3a269867a45b519662db85f0c86654))
|
||||
- Added EIP-2930 and EIP-1559 transaction tests. ([7deb4c1](https://github.com/ethers-io/ethers.js/commit/7deb4c174a30b75f8419b8661829add4e5cb69d6))
|
||||
- Added ConstructorFragment to exports. ([7efc36d](https://github.com/ethers-io/ethers.js/commit/7efc36df294ddd333e37793cad712cbd587bc686))
|
||||
- Added error utilities to Interface. ([720bde7](https://github.com/ethers-io/ethers.js/commit/720bde7719d9a2fbc7e859f8952b7918e7164b87), [f053a7a](https://github.com/ethers-io/ethers.js/commit/f053a7ad58866c8192a64e1e335a2613358385be))
|
||||
- merged master including transaction type 0 legacy constant. ([#1610](https://github.com/ethers-io/ethers.js/issues/1610); [2a7ce0e](https://github.com/ethers-io/ethers.js/commit/2a7ce0e72a1e0c9469e10392b0329e75e341cf18))
|
||||
- Added type to TransactionResponse and TrnsactionReceipt. ([#1687](https://github.com/ethers-io/ethers.js/issues/1687); [d001901](https://github.com/ethers-io/ethers.js/commit/d001901c8c0541c823eb9638b9b309a316b00757))
|
||||
- Trap CALL_EXCEPTION errors when resolving ENS entries. ([#1690](https://github.com/ethers-io/ethers.js/issues/1690); [91951dc](https://github.com/ethers-io/ethers.js/commit/91951dc825af42d4440d2d3b43cfa7a601b20342))
|
||||
- Fixed transaction serialization with explicit null type. ([#1628](https://github.com/ethers-io/ethers.js/issues/1628); [8277f5a](https://github.com/ethers-io/ethers.js/commit/8277f5a62a6739a05ae6682da6956fb490b81e4a))
|
||||
- Fix issue with loading JSON ABI with internalType property. ([#728](https://github.com/ethers-io/ethers.js/issues/728); [e8a0144](https://github.com/ethers-io/ethers.js/commit/e8a0144b7aa95add967578d9629d70bf01fc55cf))
|
||||
|
||||
ethers/v5.3.1 (2021-06-10 18:28)
|
||||
--------------------------------
|
||||
|
||||
- Fixed replacement transaction detection for JsonRpcSigner. ([#1658](https://github.com/ethers-io/ethers.js/issues/1658); [ee82e86](https://github.com/ethers-io/ethers.js/commit/ee82e86ccc439825259d20825a00050217890ad3))
|
||||
- Added Matic testnet info to networks. ([#1546](https://github.com/ethers-io/ethers.js/issues/1546); [376cf3c](https://github.com/ethers-io/ethers.js/commit/376cf3cdbf6d2281331d36c5742414a425927318))
|
||||
- Match Solidity identifier regex. ([#1657](https://github.com/ethers-io/ethers.js/issues/1657); [a6e128f](https://github.com/ethers-io/ethers.js/commit/a6e128f5cc566d291b722cca1734ba41aae6c548))
|
||||
|
||||
ethers/v5.3.0 (2021-05-31 18:41)
|
||||
--------------------------------
|
||||
|
||||
- Added MinInt256 and MaxInt256 constants. ([#1576](https://github.com/ethers-io/ethers.js/issues/1576); [bfcd05f](https://github.com/ethers-io/ethers.js/commit/bfcd05fcbb132d456d6f22f70c8ac9cf5b1826f7))
|
||||
- Version bumps for bn.js and hash.js to match elliptic and fix some build tools. ([#1478](https://github.com/ethers-io/ethers.js/issues/1478); [819b1ac](https://github.com/ethers-io/ethers.js/commit/819b1ace5c9b16e29dc354ad80e0e5b71ac63c52))
|
||||
- Removed Hangul checks in shims which crashes Android. ([#1519](https://github.com/ethers-io/ethers.js/issues/1519); [4b33114](https://github.com/ethers-io/ethers.js/commit/4b331148d980e3056ceaabdcd6e50a2aa1beb40d))
|
||||
- Fixed ENS namehash with leading and trailing dots. ([#1605](https://github.com/ethers-io/ethers.js/issues/1605); [7adcf3b](https://github.com/ethers-io/ethers.js/commit/7adcf3b154669d9d1a0a66d5e15dabfbf6618180))
|
||||
- Fixed broken variable in template string. ([#1624](https://github.com/ethers-io/ethers.js/issues/1624), [#1626](https://github.com/ethers-io/ethers.js/issues/1626); [630656e](https://github.com/ethers-io/ethers.js/commit/630656e949a8ffd940e4b66ec93ec07cd6ec2634))
|
||||
- Fixed FixedNumber rounding for non-default formats. ([#1629](https://github.com/ethers-io/ethers.js/issues/1629); [8681cd5](https://github.com/ethers-io/ethers.js/commit/8681cd59698d02d040871aa889fc6ccc8550df98))
|
||||
- Update ws dependency version to fix security. ([#1633](https://github.com/ethers-io/ethers.js/issues/1633), [#1634](https://github.com/ethers-io/ethers.js/issues/1634); [470551e](https://github.com/ethers-io/ethers.js/commit/470551e4ee3f1e343a26fc0775f9d9f7489129f8))
|
||||
|
||||
ethers/v5.2.0 (2021-05-17 16:18)
|
||||
--------------------------------
|
||||
|
||||
- More aggresively check for mempool transactions sent from JsonRpcSigner. ([3316468](https://github.com/ethers-io/ethers.js/commit/3316468e3e0a5925cbecad85d894cc7d622394e7))
|
||||
- Added initial support for detecting replacement transactions. ([#1477](https://github.com/ethers-io/ethers.js/issues/1477); [987bec8](https://github.com/ethers-io/ethers.js/commit/987bec87afaa365f291290a0136cedbc2b1992f2), [5144acf](https://github.com/ethers-io/ethers.js/commit/5144acf456b51c95bbe3950bd37609abecc7ebc7))
|
||||
- Added convenience method for HD path derivation. ([aadc5cd](https://github.com/ethers-io/ethers.js/commit/aadc5cd3d65421e13ebd4e4d7c293ac3ece5e178))
|
||||
- Added mnemonicPath option to cli. ([6e08809](https://github.com/ethers-io/ethers.js/commit/6e088099adabd7c5d2e6710062ebc62b316ba0f1))
|
||||
- Added some popular Ethereum-compatible chains to networks. ([b6370f1](https://github.com/ethers-io/ethers.js/commit/b6370f13600a0c444342cbf16a83f010a929976b))
|
||||
- Added debug event to Web3Provider. ([26464c5](https://github.com/ethers-io/ethers.js/commit/26464c54258f98c321638475d6cf11595186e76d))
|
||||
- Abstracted EtherscanProivder to more easily fascilitate other Etherscan-supported chains. ([#1204](https://github.com/ethers-io/ethers.js/issues/1204), [#1473](https://github.com/ethers-io/ethers.js/issues/1473); [37a9c77](https://github.com/ethers-io/ethers.js/commit/37a9c77ab2acb7f75e1fc4cc918810d2fe59dd76))
|
||||
- Added Custom Contract Errors. ([#1498](https://github.com/ethers-io/ethers.js/issues/1498); [6519609](https://github.com/ethers-io/ethers.js/commit/65196097f6626401638d85cf19e3d628a6223d5d), [483d67f](https://github.com/ethers-io/ethers.js/commit/483d67f55c15a76bcd853e889a0e35815d9850f7))
|
||||
- More flexible FixedNumber input and output for strings with no decimals. ([#1019](https://github.com/ethers-io/ethers.js/issues/1019), [#1291](https://github.com/ethers-io/ethers.js/issues/1291), [#1463](https://github.com/ethers-io/ethers.js/issues/1463); [a9cdbe1](https://github.com/ethers-io/ethers.js/commit/a9cdbe1238c149a7167c6bb1a78f314805b52755))
|
||||
- Added hex support for bigint. ([#1472](https://github.com/ethers-io/ethers.js/issues/1472); [4e9abfd](https://github.com/ethers-io/ethers.js/commit/4e9abfdee478a8423da4d55feea8c1aae78a8eb4))
|
||||
- Added support for null entries in EventFilter. ([#1499](https://github.com/ethers-io/ethers.js/issues/1499); [3bb5fbf](https://github.com/ethers-io/ethers.js/commit/3bb5fbf533107e880377ecc14f30f314a5028e56))
|
||||
- Add bigint to allowed BigNumberish types. ([#1472](https://github.com/ethers-io/ethers.js/issues/1472); [cadccc3](https://github.com/ethers-io/ethers.js/commit/cadccc3060b88ab2ca64aeb302717d2d1c95a897))
|
||||
- Minor version bump. ([8e22e02](https://github.com/ethers-io/ethers.js/commit/8e22e0260eb70713c943c9e99ee8d66d71ebe56d))
|
||||
|
||||
ethers/v5.1.4 (2021-04-22 06:33)
|
||||
--------------------------------
|
||||
|
||||
- Do not throw on ABI "error" type. ([#1493](https://github.com/ethers-io/ethers.js/issues/1493), [#1497](https://github.com/ethers-io/ethers.js/issues/1497); [bd05aed](https://github.com/ethers-io/ethers.js/commit/bd05aed070ac9e1421a3e2bff2ceea150bedf9b7))
|
||||
|
||||
ethers/v5.1.3 (2021-04-19 21:01)
|
||||
--------------------------------
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ Installing
|
||||
**browser (UMD)**
|
||||
|
||||
```
|
||||
<script src="https://cdn.ethers.io/lib/ethers-5.0.umd.min.js" type="text/javascript">
|
||||
<script src="https://cdn.ethers.io/lib/ethers-5.1.umd.min.js" type="text/javascript">
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -52,7 +52,7 @@ Installing
|
||||
|
||||
```
|
||||
<script type="module">
|
||||
import { ethers } from "https://cdn.ethers.io/lib/ethers-5.0.esm.min.js";
|
||||
import { ethers } from "https://cdn.ethers.io/lib/ethers-5.1.esm.min.js";
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
@@ -78,12 +78,9 @@ override the endowment ``value``, transaction ``nonce``, ``gasLimit`` or
|
||||
|
||||
_code: Deploying a Contract @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const signer = localSigner;
|
||||
const ContractFactory = ethers.ContractFactory;
|
||||
const bytecode = "608060405234801561001057600080fd5b5060405161012e38038061012e8339818101604052604081101561003357600080fd5b81019080805190602001909291908051906020019092919050505081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060008190555050506088806100a66000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80633fa4f24514602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000805490509056fea2646970667358221220926465385af0e8706644e1ff3db7161af699dc063beaadd55405f2ccd6478d7564736f6c63430007040033";
|
||||
// </hide>
|
||||
|
||||
//_hide: const signer = localSigner;
|
||||
//_hide: const ContractFactory = ethers.ContractFactory;
|
||||
//_hide: const bytecode = "608060405234801561001057600080fd5b5060405161012e38038061012e8339818101604052604081101561003357600080fd5b81019080805190602001909291908051906020019092919050505081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060008190555050506088806100a66000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80633fa4f24514602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000805490509056fea2646970667358221220926465385af0e8706644e1ff3db7161af699dc063beaadd55405f2ccd6478d7564736f6c63430007040033";
|
||||
|
||||
// If your contract constructor requires parameters, the ABI
|
||||
// must include the constructor
|
||||
@@ -97,25 +94,26 @@ factory = new ContractFactory(abi, bytecode, signer)
|
||||
|
||||
// Deploy an instance of the contract
|
||||
contract = await factory.deploy("ricmoo.eth", 42);
|
||||
//<hide>
|
||||
//! async contract
|
||||
//</hide>
|
||||
|
||||
// The address is available immediately, but the contract
|
||||
// is NOT deployed yet
|
||||
//_result:
|
||||
contract.address
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// The transaction that the signer sent to deploy
|
||||
//_result:
|
||||
contract.deployTransaction
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Wait until the transaction is mined (i.e. contract is deployed)
|
||||
// - returns the receipt
|
||||
// - throws on failure (the reciept is on the error)
|
||||
contract.deployTransaction.wait()
|
||||
//!
|
||||
//_result:
|
||||
await contract.deployTransaction.wait()
|
||||
//_log:
|
||||
|
||||
// Now the contract is safe to interact with
|
||||
contract.value()
|
||||
//!
|
||||
//_result:
|
||||
await contract.value()
|
||||
//_log:
|
||||
|
||||
@@ -132,7 +132,7 @@ The //overrides// object for a read-only method may include any of:
|
||||
- ``overrides.from`` - the ``msg.sender`` (or ``CALLER``) to use during the
|
||||
execution of the code
|
||||
- ``overrides.value`` - the ``msg.value`` (or ``CALLVALUE``) to use during the
|
||||
exectuiont of the code
|
||||
execution of the code
|
||||
- ``overrides.gasPrice`` - the price to pay per gas (theoretically); since there
|
||||
is no transaction, there is not going to be any fee charged, but the EVM still
|
||||
requires a value to report to ``tx.gasprice`` (or ``GASPRICE``);
|
||||
|
||||
@@ -5,6 +5,10 @@ to be included in the base library. The API should not be considered
|
||||
stable and does not follow [[link-semver]] versioning, so applications
|
||||
requiring it should specify the //exact version// needed.
|
||||
|
||||
These features are not available in the core ethers package, so to use them
|
||||
you must install the ``@ethersproject/experimental`` package and import them
|
||||
from that.
|
||||
|
||||
_subsection: BrainWallet @<experimental-brainwallet> @INHERIT<[[Wallet]]>
|
||||
|
||||
Ethers removed support for BrainWallets in v4, since they are unsafe and
|
||||
@@ -19,6 +23,14 @@ the generated wallet has a mnemonic.
|
||||
_property: BrainWallet.generateLegacy(username, password [ , progressCallback ]) => [[experimental-brainwallet]]
|
||||
Generate a brain wallet which is compatible with the ethers v3 and earlier.
|
||||
|
||||
_code: Importing @lang<script>
|
||||
|
||||
// Node
|
||||
const { BrainWallet } = require("@ethersproject/experimental");
|
||||
|
||||
// ESM/TypeScript
|
||||
import { BrainWallet } from "@ethersproject/experimental";
|
||||
|
||||
|
||||
_subsection: EIP1193Bridge @<experimental-eip1193bridge> @INHERIT<[[link-npm-events]]>
|
||||
|
||||
@@ -26,6 +38,14 @@ The **EIP1193Bridge** allows a normal Ethers [[Signer]] and [[Provider]] to be
|
||||
exposed in as a standard [EIP-1193 Provider](link-eip-1193), which may be useful
|
||||
when interacting with other libraries.
|
||||
|
||||
_code: Importing @lang<script>
|
||||
|
||||
// Node
|
||||
const { Eip1193Bridge } = require("@ethersproject/experimental");
|
||||
|
||||
// ESM/TypeScript
|
||||
import { Eip1193Bridge } from "@ethersproject/experimental";
|
||||
|
||||
|
||||
_subsection: NonceManager @<experimental-noncemanager> @INHERIT<[[Signer]]>
|
||||
|
||||
@@ -63,3 +83,11 @@ Bump the current transaction count (nonce) by //count//.
|
||||
|
||||
This may be useful in interacting with the signer outside of using
|
||||
this class.
|
||||
|
||||
_code: Importing @lang<script>
|
||||
|
||||
// Node
|
||||
const { NonceManager } = require("@ethersproject/experimental");
|
||||
|
||||
// ESM/TypeScript
|
||||
import { NonceManager } from "@ethersproject/experimental";
|
||||
|
||||
@@ -47,10 +47,8 @@ _definition: **Supported Networks**
|
||||
|
||||
_code: Etherscan Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const EtherscanProvider = ethers.providers.EtherscanProvider;
|
||||
const apiKey = "...";
|
||||
// </hide>
|
||||
//_hide: const EtherscanProvider = ethers.providers.EtherscanProvider;
|
||||
//_hide: const apiKey = "...";
|
||||
|
||||
// Connect to mainnet (homestead)
|
||||
provider = new EtherscanProvider();
|
||||
@@ -59,12 +57,9 @@ provider = new EtherscanProvider();
|
||||
provider = new EtherscanProvider("rinkeby");
|
||||
provider = new EtherscanProvider(4);
|
||||
|
||||
const network = ethers.providers.getNetwork("rinkeby");
|
||||
// <hide>
|
||||
delete network._defaultProvider;
|
||||
network
|
||||
// </hide>
|
||||
//!
|
||||
network = ethers.providers.getNetwork("rinkeby");
|
||||
//_hide: delete network._defaultProvider;
|
||||
//_log: network
|
||||
|
||||
provider = new EtherscanProvider(network);
|
||||
|
||||
@@ -119,11 +114,9 @@ _definition: **Supported Networks**
|
||||
|
||||
_code: INFURA Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const InfuraProvider = ethers.providers.InfuraProvider;
|
||||
const projectId = "...";
|
||||
const projectSecret = "...";
|
||||
// </hide>
|
||||
//_hide: const InfuraProvider = ethers.providers.InfuraProvider;
|
||||
//_hide: const projectId = "...";
|
||||
//_hide: const projectSecret = "...";
|
||||
|
||||
// Connect to mainnet (homestead)
|
||||
provider = new InfuraProvider();
|
||||
@@ -144,9 +137,7 @@ provider = new InfuraProvider("homestead", {
|
||||
|
||||
// Connect to the INFURA WebSocket endpoints with a WebSocketProvider
|
||||
provider = InfuraProvider.getWebSocketProvider()
|
||||
// <hide>
|
||||
provider.destroy();
|
||||
// </hide>
|
||||
//_hide: await provider.destroy();
|
||||
|
||||
|
||||
_subsection: AlchemyProvider @<AlchemyProvider> @inherit<[[UrlJsonRpcProvider]]> @src<providers:class.AlchemyProvider>
|
||||
@@ -178,10 +169,8 @@ _definition: **Supported Networks**
|
||||
|
||||
_code: Alchemy Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const AlchemyProvider = ethers.providers.AlchemyProvider;
|
||||
const apiKey = "...";
|
||||
// </hide>
|
||||
//_hide: const AlchemyProvider = ethers.providers.AlchemyProvider;
|
||||
//_hide: const apiKey = "...";
|
||||
|
||||
// Connect to mainnet (homestead)
|
||||
provider = new AlchemyProvider();
|
||||
@@ -196,9 +185,7 @@ provider = new AlchemyProvider("homestead", apiKey);
|
||||
|
||||
// Connect to the Alchemy WebSocket endpoints with a WebSocketProvider
|
||||
provider = AlchemyProvider.getWebSocketProvider()
|
||||
// <hide>
|
||||
provider.destroy();
|
||||
// </hide>
|
||||
//_hide: provider.destroy();
|
||||
|
||||
|
||||
_subsection: CloudflareProvider @<CloudflareProvider> @inherit<[[UrlJsonRpcProvider]]> @src<providers:class.CloudflareProvider>
|
||||
@@ -214,9 +201,7 @@ _definition: **Supported Networks**
|
||||
|
||||
_code: Cloudflare Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const CloudflareProvider = ethers.providers.CloudflareProvider;
|
||||
// </hide>
|
||||
//_hide: const CloudflareProvider = ethers.providers.CloudflareProvider;
|
||||
|
||||
// Connect to mainnet (homestead)
|
||||
provider = new CloudflareProvider();
|
||||
|
||||
@@ -77,9 +77,33 @@ _subsection: Networks
|
||||
There are several official common Ethereum networks as well as custom
|
||||
networks and other compatible projects.
|
||||
|
||||
Any API that accept a [[providers-Networkish]] can be passed a common name (such as
|
||||
``"mainnet"`` or ``"ropsten"``) to use that network definition or may specify
|
||||
custom parameters.
|
||||
Any API that accept a [[providers-Networkish]] can be passed a common
|
||||
name (such as ``"mainnet"`` or ``"ropsten"``) or chain ID to use that
|
||||
network definition or may specify custom parameters.
|
||||
|
||||
_property: ethers.providers.getNetwork(aNetworkish) => [[providers-Network]]
|
||||
|
||||
Returns the full [[providers-Network]] for the given standard
|
||||
//aNetworkish// [[providers-Networkish]].
|
||||
|
||||
This is useful for functions and classes which wish to accept [[providers-Networkish]]
|
||||
as an input parameter.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const getNetwork = ethers.providers.getNetwork;
|
||||
|
||||
// By Chain Name
|
||||
//_result:
|
||||
getNetwork("homestead");
|
||||
//_hide: delete _._defaultProvider;
|
||||
//_log:
|
||||
|
||||
// By Chain ID
|
||||
//_result:
|
||||
getNetwork(1);
|
||||
//_hide: delete _._defaultProvider;
|
||||
//_log:
|
||||
|
||||
_heading: Custom ENS Contract
|
||||
|
||||
@@ -96,6 +120,7 @@ const network = {
|
||||
ensAddress: customEnsAddress
|
||||
};
|
||||
|
||||
|
||||
_subsection: Provider Documentation
|
||||
|
||||
_toc:
|
||||
|
||||
@@ -99,7 +99,7 @@ application to ethers by wrapping an existing Web3-compatible (such as a
|
||||
[Web3WsProvider](link-web3-ws)) and exposing it as an ethers.js [[Provider]]
|
||||
which can then be used with the rest of the library.
|
||||
|
||||
This may also be used to wrap a standard [EIP-1193 Provider](link-eip-1193].
|
||||
This may also be used to wrap a standard [EIP-1193 Provider](link-eip-1193).
|
||||
|
||||
_property: new ethers.providers.Web3Provider(externalProvider [, network ])
|
||||
Create a new **Web3Provider**, which wraps an [EIP-1193 Provider](link-eip-1193) or
|
||||
|
||||
@@ -21,35 +21,41 @@ _subsection: Accounts Methods @<Provider--account-methods>
|
||||
_property: provider.getBalance(address [ , blockTag = latest ]) => Promise<[[BigNumber]]> @<Provider-getBalance> @SRC<providers/base-provider>
|
||||
Returns the balance of //address// as of the //blockTag// block height.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getBalance("ricmoo.eth");
|
||||
//_log:
|
||||
|
||||
_property: provider.getCode(address [ , blockTag = latest ]) => Promise<string<[[DataHexString]]>> @<Provider-getCode> @SRC<providers/base-provider>
|
||||
Returns the contract code of //address// as of the //blockTag// block height. If there is
|
||||
no contract currently deployed, the result is ``0x``.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getCode("registrar.firefly.eth");
|
||||
//_log:
|
||||
|
||||
_property: provider.getStorageAt(addr, pos [ , blockTag = latest ]) => Promise<string<[[DataHexString]]>> @<Provider-getStorageAt> @SRC<providers/base-provider>
|
||||
Returns the ``Bytes32`` value of the position //pos// at address //addr//, as of the //blockTag//.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getStorageAt("registrar.firefly.eth", 0)
|
||||
//_log:
|
||||
|
||||
_property: provider.getTransactionCount(address [ , blockTag = latest ]) => Promise<number> @<Provider-getTransactionCount> @SRC<providers/base-provider>
|
||||
Returns the number of transactions //address// has ever **sent**, as of //blockTag//.
|
||||
This value is required to be the nonce for the next transaction from //address//
|
||||
sent to the network.
|
||||
|
||||
_code: Account Examples @lang<javascript>
|
||||
_code: @lang<javascript>
|
||||
|
||||
// Get the balance for an account...
|
||||
provider.getBalance("ricmoo.firefly.eth");
|
||||
//!
|
||||
|
||||
// Get the code for a contract...
|
||||
provider.getCode("registrar.firefly.eth");
|
||||
//!
|
||||
|
||||
// Get the storage value at position 0...
|
||||
provider.getStorageAt("registrar.firefly.eth", 0)
|
||||
//!
|
||||
|
||||
// Get transaction count of an account...
|
||||
provider.getTransactionCount("ricmoo.firefly.eth");
|
||||
//!
|
||||
//_result:
|
||||
await provider.getTransactionCount("ricmoo.eth");
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Blocks Methods @<Provider--block-methods>
|
||||
@@ -58,17 +64,21 @@ _property: provider.getBlock(block) => Promise<[[providers-Block]]> @<Provider-
|
||||
Get the //block// from the network, where the ``result.transactions`` is a list
|
||||
of transaction hashes.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getBlock(100004)
|
||||
//_log:
|
||||
|
||||
_property: provider.getBlockWithTransactions(block) => Promise<[[providers-BlockWithTransactions]]> @<Provider-getBlockWithTransactions> @SRC<providers/base-provider>
|
||||
Get the //block// from the network, where the ``result.transactions`` is
|
||||
an Array of [[providers-TransactionResponse]] objects.
|
||||
|
||||
_code: Block Examples @lang<javascript>
|
||||
_code: @lang<javascript>
|
||||
|
||||
provider.getBlock(100004)
|
||||
//!
|
||||
|
||||
provider.getBlockWithTransactions(100004)
|
||||
//!
|
||||
//_result:
|
||||
await provider.getBlockWithTransactions(100004)
|
||||
//_log:
|
||||
|
||||
_subsection: Ethereum Naming Service (ENS) Methods @<Provider--ens-methods>
|
||||
|
||||
@@ -90,25 +100,39 @@ _property: provider.getResolver(name) => Promise<[[EnsResolver]]>
|
||||
Returns an EnsResolver instance which can be used to further inquire
|
||||
about specific entries for an ENS name.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: provider = ethers.getDefaultProvider();
|
||||
|
||||
// See below (Resolver) for examples of using this object
|
||||
const resolver = await provider.getResolver("ricmoo.eth");
|
||||
|
||||
//_hide: _page.resolver = resolver;
|
||||
|
||||
_property: provider.lookupAddress(address) => Promise<string> @<Provider-lookupAddress> @SRC<providers/base-provider>
|
||||
Performs a reverse lookup of the //address// in ENS using the
|
||||
//Reverse Registrar//. If the name does not exist, or the
|
||||
forward lookup does not match, ``null`` is returned.
|
||||
|
||||
An ENS name requries additional configuration to setup a reverse
|
||||
record, they are not automatically set up.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.lookupAddress("0x5555763613a12D8F3e73be831DFf8598089d3dCa");
|
||||
//_log:
|
||||
|
||||
_property: provider.resolveName(name) => Promise<string<[Address](address)>> @<Provider-ResolveName> @SRC<providers/base-provider>
|
||||
Looks up the address of //name//. If the name is not owned, or
|
||||
does not have a //Resolver// configured, or the //Resolver// does
|
||||
not have an address configured, ``null`` is returned.
|
||||
|
||||
_code: ENS Examples @lang<javascript>
|
||||
_code: @lang<javascript>
|
||||
|
||||
// Reverse lookup of an ENS by address...
|
||||
provider.lookupAddress("0x6fC21092DA55B392b045eD78F4732bff3C580e2c");
|
||||
//!
|
||||
|
||||
// Lookup an address of an ENS name...
|
||||
provider.resolveName("ricmoo.firefly.eth");
|
||||
//!
|
||||
//_result:
|
||||
await provider.resolveName("ricmoo.eth");
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: EnsResolver @<EnsResolver>
|
||||
@@ -124,12 +148,51 @@ Returns a Promise which resolves to the [[link-eip-2304]] multicoin address
|
||||
stored for the //coinType//. By default an Ethereum [[address]]
|
||||
(``coinType = 60``) will be returned.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const resolver = _page.resolver;
|
||||
|
||||
// By default, looks up the Ethereum address
|
||||
// (this will match provider.resolveName)
|
||||
//_result:
|
||||
await resolver.getAddress();
|
||||
//_log:
|
||||
|
||||
// Specify the coinType for other coin addresses (0 = Bitcoin)
|
||||
//_result:
|
||||
await resolver.getAddress(0);
|
||||
//_log:
|
||||
|
||||
_property: resolver.getContentHash() => Promise<string>
|
||||
Returns a Promise which resolves to any stored [[link-eip-1577]] content hash.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const resolver = _page.resolver;
|
||||
|
||||
//_result:
|
||||
await resolver.getContentHash();
|
||||
//_log:
|
||||
|
||||
_property: resolver.getText(key) => Promise<string>
|
||||
Returns a Promise which resolves to any stored [[link-eip-634]] text entry for //key//.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const resolver = _page.resolver;
|
||||
|
||||
//_result:
|
||||
await resolver.getText("email");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
await resolver.getText("url");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
await resolver.getText("com.twitter");
|
||||
//_log:
|
||||
|
||||
_subsection: Logs Methods @<Provider--log-methods>
|
||||
|
||||
_property: provider.getLogs(filter) => Promise<Array<[[providers-Log]]>> @<Provider-getLogs> @SRC<providers/base-provider>
|
||||
@@ -145,12 +208,38 @@ _subsection: Network Status Methods @<Provider--network-methods>
|
||||
_property: provider.getNetwork() => Promise<[[providers-Network]]> @<Provider-getNetwork> @SRC<providers/base-provider:method.BaseProvider.getNetwork>
|
||||
Returns the [[providers-Network]] this Provider is connected to.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getNetwork()
|
||||
//_hide: _ = utils.shallowCopy(_);
|
||||
//_hide: delete _._defaultProvider;
|
||||
//_log:
|
||||
|
||||
_property: provider.getBlockNumber() => Promise<number> @<Provider-getBlockNumber> @SRC<providers/base-provider>
|
||||
Returns the block number (or height) of the most recently mined block.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getBlockNumber()
|
||||
//_log:
|
||||
|
||||
_property: provider.getGasPrice() => Promise<[[BigNumber]]> @<Provider-getGasPrice> @SRC<providers/base-provider>
|
||||
Returns a //best guess// of the [[gas-price]] to use in a transaction.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
// The gas price (in wei)...
|
||||
gasPrice = await provider.getGasPrice()
|
||||
//_log: gasPrice
|
||||
|
||||
// ...often this gas price is easier to understand or
|
||||
// display to the user in gwei
|
||||
//_result:
|
||||
utils.formatUnits(gasPrice, "gwei")
|
||||
//_log:
|
||||
|
||||
_property: provider.ready => Promise<[[providers-Network]]> @<Provider-ready> @src<providers/base-provider>
|
||||
Returns a Promise which will stall until the network has heen established,
|
||||
ignoring errors due to the target node not being active yet.
|
||||
@@ -158,31 +247,6 @@ ignoring errors due to the target node not being active yet.
|
||||
This can be used for testing or attaching scripts to wait until the node is
|
||||
up and running smoothly.
|
||||
|
||||
_code: Network Status Examples @lang<javascript>
|
||||
|
||||
// The network information
|
||||
provider.getNetwork()
|
||||
// <hide>
|
||||
//!
|
||||
network = utils.shallowCopy(_)
|
||||
delete network._defaultProvider
|
||||
network
|
||||
// </hide>
|
||||
//!
|
||||
|
||||
// The current block number
|
||||
provider.getBlockNumber()
|
||||
//!
|
||||
|
||||
// Get the current suggested gas price (in wei)...
|
||||
gasPrice = await provider.getGasPrice()
|
||||
//! async gasPrice
|
||||
|
||||
// ...often this gas price is easier to understand or
|
||||
// display to the user in gwei (giga-wei, or 1e9 wei)
|
||||
utils.formatUnits(gasPrice, "gwei")
|
||||
//!
|
||||
|
||||
|
||||
_subsection: Transactions Methods @<Provider--transaction-methods>
|
||||
|
||||
@@ -191,6 +255,18 @@ Returns the result of executing the //transaction//, using //call//. A call
|
||||
does not require any ether, but cannot change any state. This is useful
|
||||
for calling getters on Contracts.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.call({
|
||||
// ENS public resovler address
|
||||
to: "0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41",
|
||||
|
||||
// `function addr(namehash("ricmoo.eth")) view returns (address)`
|
||||
data: "0x3b3b57debf074faa138b72c65adbdcfb329847e4f2c04bde7f7dd7fcad5a52d2f395a558"
|
||||
});
|
||||
//_log:
|
||||
|
||||
_property: provider.estimateGas(transaction) => Promise<[[BigNumber]]> @<Provider-estimateGas> @SRC<providers/base-provider>
|
||||
Returns an estimate of the amount of gas that would be required to submit //transaction//
|
||||
to the network.
|
||||
@@ -199,6 +275,23 @@ An estimate may not be accurate since there could be another transaction
|
||||
on the network that was not accounted for, but after being mined affected
|
||||
relevant state.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const parseEther = ethers.utils.parseEther;
|
||||
|
||||
//_result:
|
||||
await provider.estimateGas({
|
||||
// Wrapped ETH address
|
||||
to: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
||||
|
||||
// `function deposit() payable`
|
||||
data: "0xd0e30db0",
|
||||
|
||||
// 1 ether
|
||||
value: parseEther("1.0")
|
||||
});
|
||||
//_log:
|
||||
|
||||
_property: provider.getTransaction(hash) => Promise<[[providers-TransactionResponse]]> @<Provider-getTransaction> @src<providers/base-provider>
|
||||
Returns the transaction with //hash// or null if the transaction is unknown.
|
||||
|
||||
@@ -207,6 +300,12 @@ pool. Various backends may have more restrictive transaction pool access (e.g.
|
||||
if the gas price is too low or the transaction was only recently sent and not
|
||||
yet indexed) in which case this method may also return null.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getTransaction("0x5b73e239c55d790e3c9c3bbb84092652db01bb8dbf49ccc9e4a318470419d9a0");
|
||||
//_log:
|
||||
|
||||
_property: provider.getTransactionReceipt(hash) => Promise<[[providers-TransactionReceipt]]> @<Provider-getTransactionReceipt> @src<providers/base-provider>
|
||||
Returns the transaction receipt for //hash// or null if the transaction
|
||||
has not been mined.
|
||||
@@ -214,11 +313,31 @@ has not been mined.
|
||||
To stall until the transaction has been mined, consider the ``waitForTransaction``
|
||||
method below.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getTransactionReceipt("0x5b73e239c55d790e3c9c3bbb84092652db01bb8dbf49ccc9e4a318470419d9a0");
|
||||
//_log:
|
||||
|
||||
_property: provider.sendTransaction(transaction) => Promise<[[providers-TransactionResponse]]> @<Provider-sendTransaction> @SRC<providers/base-provider>
|
||||
Submits //transaction// to the network to be mined. The //transaction// **must** be signed,
|
||||
and be valid (i.e. the nonce is correct and the account has sufficient balance to pay
|
||||
for the transaction).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const provider = localProvider;
|
||||
//_hide: const wallet = new ethers.Wallet(ethers.utils.id("HelloWorld"), provider);
|
||||
//_hide: const fundTx = await localSigner.sendTransaction({
|
||||
//_hide: to: wallet.address,
|
||||
//_hide: value: ethers.utils.parseEther("2.0")
|
||||
//_hide: });
|
||||
//_hide: await fundTx.wait();
|
||||
|
||||
//_result:
|
||||
await provider.sendTransaction("0xf86e808502540be400825208948ba1f109551bd432803012645ac136ddd64dba72880de0b6b3a764000080820a96a0f0c5bcb11e5a16ab116c60a0e5837ae98ec36e7f217740076572e8183002edd2a01ed1b4411c2840b9793e8be5415a554507f1ea320069be6dcecabd7b9097dbd4");
|
||||
//_log:
|
||||
|
||||
_property: provider.waitForTransaction(hash [ , confirms = 1 [ , timeout ] ]) => Promise<[TxReceipt](providers-TransactionReceipt)> @<Provider-waitForTransaction> @SRC<providers/base-provider>
|
||||
Returns a Promise which will not resolve until //transactionHash// is mined.
|
||||
|
||||
@@ -331,11 +450,9 @@ $Debug: each Provider may use this to emit useful debugging information
|
||||
|
||||
_code: Events Example @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const txHash = utils.id("dummy-data");
|
||||
const myAddress = ethers.constants.HashZero;
|
||||
const myOtherAddress = ethers.constants.HashZero;
|
||||
// </hide>
|
||||
//_hide: const txHash = utils.id("dummy-data");
|
||||
//_hide: const myAddress = ethers.constants.HashZero;
|
||||
//_hide: const myOtherAddress = ethers.constants.HashZero;
|
||||
|
||||
provider.on("block", (blockNumber) => {
|
||||
// Emitted on every block change
|
||||
@@ -385,10 +502,7 @@ provider.on("error", (tx) => {
|
||||
// Emitted when any error occurs
|
||||
});
|
||||
|
||||
// <hide>
|
||||
// Make sure our documentation builds without waiting forever
|
||||
provider.removeAllListeners()
|
||||
// </hide>
|
||||
//_hide: provider.removeAllListeners() /* Make sure the docs build without waiting forever */
|
||||
|
||||
_subsection: Inspection Methods @<Provider--inspection-methods>
|
||||
|
||||
|
||||
@@ -245,13 +245,28 @@ has been included in the chain for //confirms// blocks. If //confirms//
|
||||
is 0, and the transaction has not been mined, ``null`` is returned.
|
||||
|
||||
If the transaction execution failed (i.e. the receipt status is ``0``),
|
||||
a [CALL_EXCEPTION](errors--call-exception) Error will be rejected with
|
||||
a [CALL_EXCEPTION](errors--call-exception) error will be rejected with
|
||||
the following properties:
|
||||
|
||||
- ``error.transaction`` - the original transaction
|
||||
- ``error.transactionHash`` - the hash of the transaction
|
||||
- ``error.receipt`` - the actual receipt, with the status of ``0``
|
||||
|
||||
If the transaction is replaced by another transaction, a
|
||||
[TRANSACTION_REPLACED](errors--transaction-replaced) error will be rejected
|
||||
with the following properties:
|
||||
|
||||
- ``error.hash`` - the hash of the original transaction which was replaced
|
||||
- ``error.reason`` - a string reason; one of ``"repriced"``, ``"cancelled"`` or ``"replaced"``
|
||||
- ``error.cancelled`` - a boolean; a ``"repriced"`` transaction is not considered cancelled, but ``"cancelled"`` and ``"replaced"`` are
|
||||
- ``error.replacement`` - the replacement transaction (a [[providers-TransactionResponse]])
|
||||
- ``error.receipt`` - the receipt of the replacement transaction (a [[providers-TransactionReceipt]])
|
||||
|
||||
Transactions are replaced when the user uses an option in their client to
|
||||
send a new transaction from the same account with the original ``nonce``.
|
||||
This is usually to speed up a transaction or to cancel one, by bribing
|
||||
miners with additional fees to prefer the new transaction over the original one.
|
||||
|
||||
_property: transactionRequest.type => null | number
|
||||
|
||||
The [[link-eip-2718]] type of this transaction envelope, or ``null``
|
||||
@@ -371,7 +386,8 @@ _code: equivalent to the AccessList example below @lang<javascript>
|
||||
|
||||
// Option 2:
|
||||
// Array< [ Address, Array<Bytes32> ] >
|
||||
[
|
||||
//_hide: ;
|
||||
accessList = [
|
||||
[
|
||||
"0x0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
|
||||
[
|
||||
@@ -385,17 +401,11 @@ _code: equivalent to the AccessList example below @lang<javascript>
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
]
|
||||
]
|
||||
]
|
||||
// <hide>
|
||||
;
|
||||
// </hide>
|
||||
];
|
||||
|
||||
// Option 3:
|
||||
// Record<Address, Array<Bytes32>>
|
||||
// <hide>
|
||||
(
|
||||
// </hide>
|
||||
{
|
||||
accessList = {
|
||||
"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e": [
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000004",
|
||||
"0x0bcad17ecf260d6506c6b97768bdc2acfb6694445d27ffd3f9c1cfbee4a9bd6d"
|
||||
@@ -403,10 +413,7 @@ _code: equivalent to the AccessList example below @lang<javascript>
|
||||
"0x5FfC014343cd971B7eb70732021E26C35B744cc4": [
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
]
|
||||
}
|
||||
// <hide>
|
||||
)
|
||||
// </hide>
|
||||
};
|
||||
|
||||
|
||||
_heading: AccessList @<providers-AccessList>
|
||||
@@ -427,7 +434,7 @@ _code: example access list
|
||||
// storageKey: Array< DataHexString< 32 > >
|
||||
// }
|
||||
|
||||
[
|
||||
accessList = [
|
||||
{
|
||||
address: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
|
||||
storageKeys: [
|
||||
@@ -441,4 +448,4 @@ _code: example access list
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
]
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
@@ -39,7 +39,7 @@ asynchronous source, such as hardware wallets.
|
||||
Sub-classes **must** implement this.
|
||||
|
||||
_property: Signer.isSigner(object) => boolean @<Signer-isSigner> @SRC<abstract-signer>
|
||||
Returns true if an only if //object// is a **Signer**.
|
||||
Returns true if and only if //object// is a **Signer**.
|
||||
|
||||
_heading: Blockchain Methods @<Signer--blockchain-methods>
|
||||
|
||||
@@ -74,6 +74,12 @@ _property: signer.signMessage(message) => Promise<string<[RawSignature](signatur
|
||||
This returns a Promise which resolves to the [[signature-raw]]
|
||||
of //message//.
|
||||
|
||||
A signed message is prefixd with ``"\\x19Ethereum signed message:\\n"`` and
|
||||
the length of the message, using the [hashMessage](utils-hashMessage)
|
||||
method, so that it is [EIP-191](link-eip-191) compliant. If recovering
|
||||
the address in Solidity, this prefix will be required to create a matching
|
||||
hash.
|
||||
|
||||
Sub-classes **must** implement this, however they may throw if signing a
|
||||
message is not supported, such as in a Contract-based Wallet or
|
||||
Meta-Transaction-based Wallet.
|
||||
@@ -126,9 +132,7 @@ it has been used in the field a bit.
|
||||
|
||||
_code: Typed Data Example @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
signer = new Wallet("0x1234567890123456789012345678901234567890123456789012345678901234");
|
||||
// </hide>
|
||||
//_hide: signer = new Wallet("0x1234567890123456789012345678901234567890123456789012345678901234");
|
||||
|
||||
// All properties on a domain are optional
|
||||
const domain = {
|
||||
@@ -164,9 +168,9 @@ const value = {
|
||||
contents: 'Hello, Bob!'
|
||||
};
|
||||
|
||||
|
||||
const signature = await signer._signTypedData(domain, types, value);
|
||||
//! async signature
|
||||
//_result:
|
||||
signature = await signer._signTypedData(domain, types, value);
|
||||
//_log:
|
||||
|
||||
|
||||
_heading: Sub-Classes @<Signer--subclassing>
|
||||
@@ -281,35 +285,43 @@ walletMnemonic = Wallet.fromMnemonic(mnemonic)
|
||||
// ...or from a private key
|
||||
walletPrivateKey = new Wallet(walletMnemonic.privateKey)
|
||||
|
||||
//_result:
|
||||
walletMnemonic.address === walletPrivateKey.address
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// The address as a Promise per the Signer API
|
||||
walletMnemonic.getAddress()
|
||||
//!
|
||||
//_result:
|
||||
await walletMnemonic.getAddress()
|
||||
//_log:
|
||||
|
||||
// A Wallet address is also available synchronously
|
||||
//_result:
|
||||
walletMnemonic.address
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// The internal cryptographic components
|
||||
//_result:
|
||||
walletMnemonic.privateKey
|
||||
//!
|
||||
//_log:
|
||||
//_result:
|
||||
walletMnemonic.publicKey
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// The wallet mnemonic
|
||||
//_result:
|
||||
walletMnemonic.mnemonic
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Note: A wallet created with a private key does not
|
||||
// have a mnemonic (the derivation prevents it)
|
||||
//_result:
|
||||
walletPrivateKey.mnemonic
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Signing a message
|
||||
walletMnemonic.signMessage("Hello World")
|
||||
//!
|
||||
//_result:
|
||||
await walletMnemonic.signMessage("Hello World")
|
||||
//_log:
|
||||
|
||||
tx = {
|
||||
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
||||
@@ -317,24 +329,29 @@ tx = {
|
||||
}
|
||||
|
||||
// Signing a transaction
|
||||
walletMnemonic.signTransaction(tx)
|
||||
//!
|
||||
//_result:
|
||||
await walletMnemonic.signTransaction(tx)
|
||||
//_log:
|
||||
|
||||
// The connect method returns a new instance of the
|
||||
// Wallet connected to a provider
|
||||
//_result:
|
||||
wallet = walletMnemonic.connect(provider)
|
||||
//_null:
|
||||
|
||||
// Querying the network
|
||||
wallet.getBalance();
|
||||
//!
|
||||
wallet.getTransactionCount();
|
||||
//!
|
||||
//_result:
|
||||
await wallet.getBalance();
|
||||
//_log:
|
||||
//_result:
|
||||
await wallet.getTransactionCount();
|
||||
//_log:
|
||||
|
||||
// Sending ether
|
||||
wallet.sendTransaction(tx)
|
||||
// <hide>
|
||||
//! error
|
||||
// </hide>
|
||||
//_hide: wallet = localSigner; /* prevent insufficient funds error from blowing up the docs */
|
||||
//_result:
|
||||
await wallet.sendTransaction(tx)
|
||||
//_log:
|
||||
|
||||
|
||||
|
||||
@@ -367,12 +384,10 @@ abi = [
|
||||
]
|
||||
contract = new ethers.Contract("dai.tokens.ethers.eth", abi, signer)
|
||||
|
||||
// <hide>
|
||||
//!
|
||||
// </hide>
|
||||
// Get the number of tokens for this account
|
||||
//_result:
|
||||
tokens = await contract.balanceOf(signer.getAddress())
|
||||
//! async tokens
|
||||
//_log:
|
||||
|
||||
//
|
||||
// Pre-flight (check for revert) on DAI from the signer
|
||||
@@ -384,12 +399,14 @@ tokens = await contract.balanceOf(signer.getAddress())
|
||||
//
|
||||
|
||||
// This will pass since the token balance is available
|
||||
contract.callStatic.transfer("donations.ethers.eth", tokens)
|
||||
//!
|
||||
//_result:
|
||||
await contract.callStatic.transfer("donations.ethers.eth", tokens)
|
||||
//_log:
|
||||
|
||||
// This will fail since it is greater than the token balance
|
||||
contract.callStatic.transfer("donations.ethers.eth", tokens.add(1))
|
||||
//! error
|
||||
//_throws:
|
||||
await contract.callStatic.transfer("donations.ethers.eth", tokens.add(1))
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: ExternallyOwnedAccount @<ExternallyOwnedAccount>
|
||||
|
||||
@@ -1,11 +1,289 @@
|
||||
_section: ABI Formats @<abi-formats>
|
||||
|
||||
@TODO: Expand this section
|
||||
There are several formats available to specify an ABI for
|
||||
a Smart Contract, which specifies to the under-lying library
|
||||
what methods, events and errors exist so that encoding and
|
||||
decoding the data from and to the network can be handled by
|
||||
the library.
|
||||
|
||||
The supports ABI types are:
|
||||
|
||||
- [Human-Readable ABI](abi-formats--human-readable-abi)
|
||||
- [Solidity JSON ABI](abi-formats--solidity)
|
||||
- [Solidity Object ABI](abi-formats--object)
|
||||
|
||||
_subsection: Human-Readable ABI @<abi-formats--human-readable-abi>
|
||||
|
||||
See [Human-Readable Abi](link-ricmoo-humanreadableabi).
|
||||
The **Human-Readable ABI** was [introduced early by ethers](link-ricmoo-humanreadableabi),
|
||||
which allows for a Solidity signatures to be used to describe each
|
||||
method, event and error.
|
||||
|
||||
It is important to note that a Solidity signature **fully describes**
|
||||
all the properties the ABI requires:
|
||||
|
||||
- name
|
||||
- type (constructor, event, function)
|
||||
- inputs (types, nested structures and optionally names)
|
||||
- outputs (types nested structures and optionally names)
|
||||
- state mutability (for constructors and methods)
|
||||
- payability (for constructors and methods)
|
||||
- whether inputs are indexed (for events)
|
||||
|
||||
This allows for a simple format which is both machine-readalbe (since
|
||||
the parser is a machine) and human-readable (at least **developer-readable**),
|
||||
as well as simple for humans to type and inline into code, which improves
|
||||
code readability. The Human-Readable ABI is also considerably smaller, which
|
||||
helps reduce code size.
|
||||
|
||||
A Huamn-Readable ABI is simple an array of strings, where each string is
|
||||
the Solidity signature.
|
||||
|
||||
Signatures may be minimally specified (i.e. names of inputs and outputs
|
||||
may be omitted) or fully specified (i.e. with all property names) and
|
||||
whitespace is ignored.
|
||||
|
||||
Several modifiers available in Solidity are dropped internally, as they
|
||||
are not required for the ABI and used old by Solidity's semantic checking
|
||||
system, such as input parameter data location like ``"calldata"``
|
||||
and ``"memory"``. As such, they can be safely dropped in the ABI as well.
|
||||
|
||||
_code: Human-Readable ABI Example @lang<javascript>
|
||||
|
||||
const humanReadableAbi = [
|
||||
|
||||
// Simple types
|
||||
"constructor(string symbol, string name)",
|
||||
"function transferFrom(address from, address to, uint value)",
|
||||
"function balanceOf(address owner) view returns (uint balance)",
|
||||
"event Transfer(address indexed from, address indexed to, address value)",
|
||||
"error InsufficientBalance(account owner, uint balance)",
|
||||
|
||||
// Some examples with the struct type, we use the tuple keyword:
|
||||
// (note: the tuple keyword is optional, simply using additional
|
||||
// parentheses accomplishes the same thing)
|
||||
// struct Person {
|
||||
// string name;
|
||||
// uint16 age;
|
||||
// }
|
||||
"function addPerson(tuple(string name, uint16 age) person)",
|
||||
"function addPeople(tuple(string name, uint16 age)[] person)",
|
||||
"function getPerson(uint id) view returns (tuple(string name, uint16 age))",
|
||||
|
||||
"event PersonAdded(uint indexed id, tuple(string name, uint16 age) person)"
|
||||
];
|
||||
|
||||
//_hide: _page.humanReadableAbi = humanReadableAbi;
|
||||
|
||||
|
||||
_subsection: Solidity JSON ABI @<abi-formats--solidity>
|
||||
|
||||
See [Solidity compiler](link-solc-output).
|
||||
The **Solidity JSON ABI** is a standard format that many tools export,
|
||||
including the Solidity compiler. For the full specification, see
|
||||
the [Solidity compiler documentation](link-solc-output).
|
||||
|
||||
Various versions include slightly different keys and values. For example,
|
||||
early compilers included only a boolean ``"constant"`` to indicate mutability,
|
||||
while newer versions include a string ``"mutabilityState"``, which encompasses
|
||||
several older properties.
|
||||
|
||||
When creating an instance of a [Fragment](Fragment) using a JSON ABI, it will
|
||||
automatically infer all legacy properties for new-age ABIs and for legacy
|
||||
ABIs will infer the new-age properties. All properties will be populated, so
|
||||
it will match the equivalent created using a Human-Readable ABI fragment.
|
||||
|
||||
_code: The same ABI as JSON ABI @lang<javascript>
|
||||
|
||||
const jsonAbi = `[
|
||||
{
|
||||
"type": "constructor",
|
||||
"payable": false,
|
||||
"inputs": [
|
||||
{ "type": "string", "name": "symbol" },
|
||||
{ "type": "string", "name": "name" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "transferFrom",
|
||||
"constant": false,
|
||||
"payable": false,
|
||||
"inputs": [
|
||||
{ "type": "address", "name": "from" },
|
||||
{ "type": "address", "name": "to" },
|
||||
{ "type": "uint256", "name": "value" }
|
||||
],
|
||||
"outputs": [ ]
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "balanceOf",
|
||||
"constant":true,
|
||||
"stateMutability": "view",
|
||||
"payable":false, "inputs": [
|
||||
{ "type": "address", "name": "owner"}
|
||||
],
|
||||
"outputs": [
|
||||
{ "type": "uint256"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "event",
|
||||
"anonymous": false,
|
||||
"name": "Transfer",
|
||||
"inputs": [
|
||||
{ "type": "address", "name": "from", "indexed":true},
|
||||
{ "type": "address", "name": "to", "indexed":true},
|
||||
{ "type": "address", "name": "value"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "error",
|
||||
"name": "InsufficientBalance",
|
||||
"inputs": [
|
||||
{ "type": "account", "name": "owner"},
|
||||
{ "type": "uint256", "name": "balance"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "addPerson",
|
||||
"constant": false,
|
||||
"payable": false,
|
||||
"inputs": [
|
||||
{
|
||||
"type": "tuple",
|
||||
"name": "person",
|
||||
"components": [
|
||||
{ "type": "string", "name": "name" },
|
||||
{ "type": "uint16", "name": "age" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "addPeople",
|
||||
"constant": false,
|
||||
"payable": false,
|
||||
"inputs": [
|
||||
{
|
||||
"type": "tuple[]",
|
||||
"name": "person",
|
||||
"components": [
|
||||
{ "type": "string", "name": "name" },
|
||||
{ "type": "uint16", "name": "age" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "getPerson",
|
||||
"constant": true,
|
||||
"stateMutability": "view",
|
||||
"payable": false,
|
||||
"inputs": [
|
||||
{ "type": "uint256", "name": "id" }
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "tuple",
|
||||
"components": [
|
||||
{ "type": "string", "name": "name" },
|
||||
{ "type": "uint16", "name": "age" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "event",
|
||||
"anonymous": false,
|
||||
"name": "PersonAdded",
|
||||
"inputs": [
|
||||
{ "type": "uint256", "name": "id", "indexed": true },
|
||||
{
|
||||
"type": "tuple",
|
||||
"name": "person",
|
||||
"components": [
|
||||
{ "type": "string", "name": "name", "indexed": false },
|
||||
{ "type": "uint16", "name": "age", "indexed": false }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]`;
|
||||
|
||||
//_hide: _page.jsonAbi = jsonAbi;
|
||||
|
||||
_subsection: Solidity Object ABI @<abi-formats--object>
|
||||
|
||||
The output from parsing (using JSON.parse) a Solidity JSON ABI
|
||||
is also fully compatible with the [[Interface]] class and each
|
||||
method, event and error from that object are compatible with
|
||||
the [[Fragment]] class.
|
||||
|
||||
Some developers may prefer this as it allows access to the ABI
|
||||
properties as normal JavaScript objects, and closely matches the
|
||||
JSON ABI that those familiar with the Solidity ABI will recognize.
|
||||
|
||||
_subsection: Converting Between Formats
|
||||
|
||||
The [[Fragment]] object makes it simple to reformat a single
|
||||
method, event or error, however most developers will be interested
|
||||
in converting an entire ABI.
|
||||
|
||||
For production code it is recommended to inline the Human-Readable
|
||||
ABI as it makes it easy to see at a glance which methods, events
|
||||
and errors are available. It is also highly recommend to strip out
|
||||
unused parts of the ABI (such as admin methods) to further reduce
|
||||
code size.
|
||||
|
||||
_code: Converting to Full Human-Readable ABI @lang<javascript>
|
||||
|
||||
//_hide: const Interface = ethers.utils.Interface;
|
||||
//_hide: const FormatTypes = ethers.utils.FormatTypes;
|
||||
//_hide: jsonAbi = _page.jsonAbi;
|
||||
|
||||
// Using the "full" format will ensure the Result objects
|
||||
// have named properties, which improves code readability
|
||||
const iface = new Interface(jsonAbi);
|
||||
//_result:
|
||||
iface.format(FormatTypes.full);
|
||||
//_log:
|
||||
|
||||
_code: Converting to Minimal Human-Readable ABI @lang<javascript>
|
||||
|
||||
//_hide: const Interface = ethers.utils.Interface;
|
||||
//_hide: const FormatTypes = ethers.utils.FormatTypes;
|
||||
//_hide: jsonAbi = _page.jsonAbi;
|
||||
|
||||
// Using the "minimal" format will save a small amount of
|
||||
// space, but is generally not worth it as named properties
|
||||
// on Results will not be available
|
||||
const iface = new Interface(jsonAbi);
|
||||
//_result:
|
||||
iface.format(FormatTypes.minimal);
|
||||
//_log:
|
||||
|
||||
_code: Converting to JSON ABI @lang<javascript>
|
||||
|
||||
//_hide: const Interface = ethers.utils.Interface;
|
||||
//_hide: const FormatTypes = ethers.utils.FormatTypes;
|
||||
//_hide: humanReadableAbi = _page.humanReadableAbi;
|
||||
|
||||
// Sometimes you may need to export a Human-Readable ABI to
|
||||
// JSON for tools that do not have Human-Readable support
|
||||
|
||||
// For compactness, the JSON is kept with minimal white-space
|
||||
const iface = new Interface(humanReadableAbi);
|
||||
//_result:
|
||||
jsonAbi = iface.format(FormatTypes.json);
|
||||
//_log:
|
||||
|
||||
// However it is easy to use JSON.parse and JSON.stringify
|
||||
// with formatting parameters to assist with readability
|
||||
//_result:
|
||||
JSON.stringify(JSON.parse(jsonAbi), null, 2);
|
||||
//_log:
|
||||
|
||||
@@ -5,7 +5,6 @@ Explain an ABI.
|
||||
_subsection: Formats
|
||||
|
||||
_heading: JSON String ABI (Solidity Output JSON)
|
||||
|
||||
The **JSON ABI Format** is the format that is
|
||||
[output from the Solidity compiler](link-solc-output).
|
||||
|
||||
@@ -15,50 +14,74 @@ of Objects, where each Object has various properties describing the [[Fragment]]
|
||||
The deserialized JSON string (which is a normal JavaScript Object) may
|
||||
also be passed into any function which accepts a JSON String ABI.
|
||||
|
||||
_heading: Humanb-Readable ABI
|
||||
_heading: Humanb-Readable ABI @<human-readable-abi>
|
||||
The Human-Readable ABI was introduced by ethers in [this article](link-ricmoo-humanreadableabi)
|
||||
and has since gained wider adoption.
|
||||
|
||||
The Human-Readable ABI was @TODO
|
||||
The ABI is described by using an array of strings, where each string is the
|
||||
Solidity signature of the **constructor**, **function**, **event** or **error**.
|
||||
|
||||
[article](link-ricmoo-humanreadableabi)
|
||||
When parsing a fragment, all inferred properties will be injected (e.g. a //payable//
|
||||
method will have its ``constant`` proeprty set to false).
|
||||
|
||||
Tuples can be specified by using the ``tuple(...)`` syntax or with bare (additional)
|
||||
parenthesis, ``(...)``.
|
||||
|
||||
_code: Example Human-Readable ABI
|
||||
|
||||
const ABI = [
|
||||
// Constructor
|
||||
"constructor(address ens)",
|
||||
|
||||
// Constant functions (pure or view)
|
||||
"function balanceOf(address owner) view returns (uint)",
|
||||
|
||||
// State-mutating functions (payable or non-payable)
|
||||
"function mint(uint amount) payable",
|
||||
"function transfer(address to, uint amount) returns (bool)",
|
||||
|
||||
// Events
|
||||
"event Transfer(address indexed from, address indexed to, uint amount)",
|
||||
|
||||
// Errors
|
||||
"error InsufficientFunds(address from, uint balance)",
|
||||
]
|
||||
|
||||
|
||||
_heading: Output Formats @<fragments--output-formats> @SRC<abi/fragments:FormatTypes>
|
||||
|
||||
Each [[Fragment]] and [[ParamType]] may be output using its ``format``
|
||||
method.
|
||||
|
||||
_property: ethers.utils.FragmentTypes.full => string
|
||||
|
||||
_property: ethers.utils.FormatTypes.full => string
|
||||
This is a full human-readable string, including all parameter names, any
|
||||
optional modifiers (e.g. ``indexed``, ``public``, etc) and white-space
|
||||
to aid in human readability.
|
||||
|
||||
_property: ethers.utils.FragmentTypes.minimal => string
|
||||
|
||||
_property: ethers.utils.FormatTypes.minimal => string
|
||||
This is similar to ``full``, except with no unnecessary whitespace or parameter
|
||||
names. This is useful for storing a minimal string which can still fully
|
||||
reconstruct the original Fragment using [Fragment . from](Fragment-from).
|
||||
|
||||
_property: ethers.utils.FragmentTypes.json => string
|
||||
|
||||
_property: ethers.utils.FormatTypes.json => string
|
||||
This returns a JavaScript Object which is safe to call ``JSON.stringify``
|
||||
on to create a JSON string.
|
||||
|
||||
_property: ethers.utils.FragmentTypes.sighash => string
|
||||
|
||||
_property: ethers.utils.FormatTypes.sighash => string
|
||||
This is a minimal output format, which is used by Solidity when computing a
|
||||
signature hash or an event topic hash.
|
||||
|
||||
_warning: Note
|
||||
|
||||
The ``sighash`` format is **insufficient** to re-create the original [[Fragment]],
|
||||
since it discards modifiers such as indexed, anonymous, stateMutability, etc.
|
||||
|
||||
It is only useful for computing the selector for a Fragment, and cannot
|
||||
be used to format an Interface.
|
||||
|
||||
|
||||
_subsection: Fragment @<Fragment> @SRC<abi/fragments:class.Fragment>
|
||||
|
||||
An ABI is a collection of **Fragments**, where each fragment specifies:
|
||||
|
||||
- An [Error](ErrorFragment)
|
||||
- An [Event](EventFragment)
|
||||
- A [Function](FunctionFragment)
|
||||
- A [Constructor](ConstructorFragment)
|
||||
@@ -66,12 +89,10 @@ An ABI is a collection of **Fragments**, where each fragment specifies:
|
||||
_heading: Properties
|
||||
|
||||
_property: fragment.name => string
|
||||
|
||||
This is the name of the Event or Function. This will be null for
|
||||
a [[ConstructorFragment]].
|
||||
|
||||
_property: fragment.type => string
|
||||
|
||||
This is a string which indicates the type of the [[Fragment]]. This
|
||||
will be one of:
|
||||
|
||||
@@ -80,19 +101,20 @@ will be one of:
|
||||
- ``function``
|
||||
|
||||
_property: fragment.inputs => Array<[[ParamType]]>
|
||||
|
||||
This is an array of each [[ParamType]] for the input parameters to
|
||||
the Constructor, Event of Function.
|
||||
|
||||
_heading: Methods
|
||||
|
||||
_property: ethers.utils.Fragment.from(objectOrString) => [[Fragment]] @<Fragment-from> @SRC<abi/fragments:Fragment.from>
|
||||
_property: fragment.format([ format = sighash]) => string @<Fragment-format> @SRC<abi/fragments:Fragment.format>
|
||||
Creates a string representation of the Fragment using the available
|
||||
[output formats](fragments--output-formats).
|
||||
|
||||
Returns a
|
||||
_property: ethers.utils.Fragment.from(objectOrString) => [[Fragment]] @<Fragment-from> @SRC<abi/fragments:Fragment.from>
|
||||
Creates a new **Fragment** sub-class from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.Fragment.isFragment(object) => boolean @<Fragment-isFragment> @SRC<abi/fragments:Fragment.isFragment>
|
||||
|
||||
Tra lal al
|
||||
Returns true if //object// is a **Fragment**.
|
||||
|
||||
|
||||
_subsection: ConstructorFragment @<ConstructorFragment> @INHERIT<[[Fragment]]> @SRC<abi/fragments:class.ConstructorFragment>
|
||||
@@ -100,17 +122,14 @@ _subsection: ConstructorFragment @<ConstructorFragment> @INHERIT<[[Fragment]]> @
|
||||
_heading: Properties
|
||||
|
||||
_property: fragment.gas => [[BigNumber]]
|
||||
|
||||
This is the gas limit that should be used during deployment. It may be
|
||||
null.
|
||||
|
||||
_property: fragment.payable => boolean
|
||||
|
||||
This is whether the constructor may receive ether during deployment as
|
||||
an endowment (i.e. msg.value != 0).
|
||||
|
||||
_property: fragment.stateMutability => string
|
||||
|
||||
This is the state mutability of the constructor. It can be any of:
|
||||
|
||||
- ``nonpayable``
|
||||
@@ -119,12 +138,21 @@ This is the state mutability of the constructor. It can be any of:
|
||||
_heading: Methods
|
||||
|
||||
_property: ethers.utils.ConstructorFragment.from(objectOrString) => [[ConstructorFragment]] @<ConstructorFragment-from> @SRC<abi/fragments:ConstructorFragment.from>
|
||||
|
||||
Tra la la...
|
||||
Creates a new **ConstructorFragment** from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.ConstructorFragment.isConstructorFragment(object) => boolean @<ConstructorFragment-isConstructorFragment> @SRC<abi/fragments:ConstructorFragment.isConstructorFragment>
|
||||
Returns true if //object// is a **ConstructorFragment**.
|
||||
|
||||
Tra lal al
|
||||
|
||||
_subsection: ErrorFragment @<ErrorFragment> @INHERIT<[[Fragment]]> @SRC<abi/fragments:class.ErrorFragment>
|
||||
|
||||
_heading: Methods
|
||||
|
||||
_property: ethers.utils.ErrorFragment.from(objectOrString) => [[ErrorFragment]] @<ErrorFragment-from> @SRC<abi/fragments:ErrorFragment.from>
|
||||
Creates a new **ErrorFragment** from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.ErrorFragment.isErrorFragment(object) => boolean @<ErrorFragment-isErrorFragment> @SRC<abi/fragments:ErrorFragment.isErrorFragment>
|
||||
Returns true if //object// is an **ErrorFragment**.
|
||||
|
||||
|
||||
_subsection: EventFragment @<EventFragment> @INHERIT<[[Fragment]]> @SRC<abi/fragments:class.EventFragment>
|
||||
@@ -132,19 +160,16 @@ _subsection: EventFragment @<EventFragment> @INHERIT<[[Fragment]]> @SRC<abi/frag
|
||||
_heading: Properties
|
||||
|
||||
_property: fragment.anonymous => boolean
|
||||
|
||||
This is whether the event is anonymous. An anonymous Event does not inject its
|
||||
topic hash as topic0 when creating a log.
|
||||
|
||||
_heading: Methods
|
||||
|
||||
_property: ethers.utils.EventFragment.from(objectOrString) => [[EventFragment]] @<EventFragment-from> @SRC<abi/fragments:EventFragment.from>
|
||||
|
||||
Tra la la...
|
||||
Creates a new **EventFragment** from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.EventFragment.isEventFragment(object) => boolean @<EventFragment-isEventFragment> @SRC<abi/fragments:EventFragment.isEventFragment>
|
||||
|
||||
Tra lal al
|
||||
Returns true if //object// is an **EventFragment**.
|
||||
|
||||
|
||||
_subsection: FunctionFragment @<FunctionFragment> @INHERIT<[[ConstructorFragment]]> @SRC<abi/fragments:class.FunctionFragment>
|
||||
@@ -152,12 +177,10 @@ _subsection: FunctionFragment @<FunctionFragment> @INHERIT<[[ConstructorFragment
|
||||
_heading: Properties
|
||||
|
||||
_property: fragment.constant => boolean
|
||||
|
||||
This is whether the function is constant (i.e. does not change state). This
|
||||
is true if the state mutability is ``pure`` or ``view``.
|
||||
|
||||
_property: fragment.stateMutability => string
|
||||
|
||||
This is the state mutability of the constructor. It can be any of:
|
||||
|
||||
- ``nonpayable``
|
||||
@@ -166,22 +189,18 @@ This is the state mutability of the constructor. It can be any of:
|
||||
- ``view``
|
||||
|
||||
_property: fragment.outputs => Array<[[ParamType]]>
|
||||
|
||||
A list of the Function output parameters.
|
||||
|
||||
_heading: Method
|
||||
_heading: Methods
|
||||
|
||||
_property: ethers.utils.FunctionFragment.from(objectOrString) => [[FunctionFragment]] @<FunctionFragment-from> @SRC<abi/fragments:ConstructorFragment.from>
|
||||
|
||||
Tra la la...
|
||||
Creates a new **FunctionFragment** from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.FunctionFragment.isFunctionFragment(object) => boolean @<FunctionFragment-isFunctionFragment> @SRC<abi/fragments:FunctionFragment.isFunctionFragment>
|
||||
|
||||
Tra lal al
|
||||
Returns true if //object// is a **FunctionFragment**.
|
||||
|
||||
|
||||
_subsection: ParamType @<ParamType> @SRC<abi/fragments:class.ParamType>
|
||||
|
||||
The following examples will represent the Solidity parameter:
|
||||
|
||||
``string foobar``
|
||||
@@ -189,53 +208,42 @@ The following examples will represent the Solidity parameter:
|
||||
_heading: Properties
|
||||
|
||||
_property: paramType.name => string @<ParamType-name>
|
||||
|
||||
The local parameter name. This may be null for unnamed parameters. For example,
|
||||
the parameter definition ``string foobar`` would be ``foobar``.
|
||||
|
||||
_property: paramType.type => string @<ParamType-type>
|
||||
|
||||
The full type of the parameter, including tuple and array symbols. This may be null
|
||||
for unnamed parameters. For the above example, this would be ``foobar``.
|
||||
|
||||
_property: paramType.baseType => string @<ParamType-baseType>
|
||||
|
||||
The base type of the parameter. For primitive types (e.g. ``address``, ``uint256``, etc)
|
||||
this is equal to [type](ParamType-type). For arrays, it will be the string ``array`` and for
|
||||
a tuple, it will be the string ``tuple``.
|
||||
|
||||
_property: paramType.indexed => boolean @<ParamType-indexed>
|
||||
|
||||
Whether the parameter has been marked as indexed. This **only** applies
|
||||
to parameters which are part of an [[EventFragment]].
|
||||
|
||||
_property: paramType.arrayChildren => [[ParamType]] @<ParamType-arrayChildren>
|
||||
|
||||
The type of children of the array. This is null for any parameter
|
||||
which is not an array.
|
||||
|
||||
_property: paramType.arrayLength => number @<ParamType-arrayLength>
|
||||
|
||||
The length of the array, or ``-1`` for dynamic-length arrays. This is
|
||||
null for parameters which are not arrays.
|
||||
|
||||
_property: paramType.components => Array<[[ParamType]]> @<ParamType-components>
|
||||
|
||||
The components of a tuple. This is null for non-tuple parameters.
|
||||
|
||||
|
||||
_heading: Methods
|
||||
|
||||
Tra la la...
|
||||
|
||||
_property: paramType.format([ outputType = sighash ])
|
||||
|
||||
Tra la la...
|
||||
Creates a string representation of the Fragment using the available
|
||||
[output formats](fragments--output-formats).
|
||||
|
||||
_property: ethers.utils.ParamType.from(objectOrString) => [[ParamType]] @<ParamType-from> @SRC<abi/fragments:ParamType.from>
|
||||
|
||||
Tra la la...
|
||||
Creates a new **ParamType** from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.ParamType.isParamType(object) => boolean @<ParamType-isParamType> @SRC<abi/fragments:ParamType.isParamType>
|
||||
|
||||
Tra la la...
|
||||
Returns true if //object// is a **ParamType**.
|
||||
|
||||
@@ -26,11 +26,47 @@ 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
|
||||
"constructor(string symbol, string name)",
|
||||
|
||||
// State mutating method
|
||||
"function transferFrom(address from, address to, uint amount)",
|
||||
|
||||
// State mutating method, which is payable
|
||||
"function mint(uint amount) payable",
|
||||
|
||||
// Constant method (i.e. "view" or "pure")
|
||||
"function balanceOf(address owner) view returns (uint)",
|
||||
|
||||
// An Event
|
||||
"event Transfer(address indexed from, address indexed to, uint256 amount)",
|
||||
|
||||
// A Custom Solidity Error
|
||||
"error AccountLocked(address owner, uint256 balance)",
|
||||
|
||||
// Examples with structured types
|
||||
"function addUser(tuple(string name, address addr) user) returns (uint id)",
|
||||
"function addUsers(tuple(string name, address addr)[] user) returns (uint[] id)",
|
||||
"function getUser(uint id) view returns (tuple(string name, address addr) user)"
|
||||
]);
|
||||
|
||||
//_hide: _page.iface = iface;
|
||||
|
||||
_subsection: Properties @<Interface--properties>
|
||||
|
||||
_property: interface.fragments => Array<[[Fragment]]>
|
||||
All the [Fragments](Fragment) in the interface.
|
||||
|
||||
_property: interface.errors => Array<[[ErrorFragment]]>
|
||||
All the [Error Fragments](ErrorFragment) in the interface.
|
||||
|
||||
_property: interface.events => Array<[[EventFragment]]>
|
||||
All the [Event Fragments](EventFragment) in the interface.
|
||||
|
||||
@@ -48,24 +84,133 @@ 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:
|
||||
|
||||
_subsection: Fragment Access @<Interface--fragments>
|
||||
|
||||
_property: interface.getFunction(fragment) => [[FunctionFragment]] @SRC<abi/interface>
|
||||
Returns the [[FunctionFragment]] for //fragment// (see [[Interface--specifying-fragments]]).
|
||||
|
||||
_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:
|
||||
|
||||
_property: interface.getEvent(fragment) => [[EventFragment]] @SRC<abi/interface>
|
||||
Returns the [[EventFragment]] for //fragment// (see [[Interface--specifying-fragments]]).
|
||||
|
||||
_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:
|
||||
|
||||
_subsection: Signature and Topic Hashes @<Interface--selectors>
|
||||
|
||||
_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]]).
|
||||
|
||||
_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:
|
||||
|
||||
_property: interface.getEventTopic(fragment) => string<[[DataHexString]]<32>> @SRC<abi/interface:method.Interface.getEventTopic>
|
||||
Return the topic hash for //fragment// (see [[Interface--specifying-fragments]]).
|
||||
|
||||
_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:
|
||||
|
||||
_subsection: Encoding Data @<Interface--encoding>
|
||||
|
||||
@@ -74,22 +219,103 @@ Return the encoded deployment data, which can be concatenated to the
|
||||
deployment bytecode of a contract to pass //values// into the contract
|
||||
constructor.
|
||||
|
||||
_property: interface.encodeFilterTopics(fragment [ , values ]) => Array<topic | Array<topic>> @SRC<abi/interface>
|
||||
_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>
|
||||
Returns the encoded topic filter, which can be passed to getLogs for //fragment//
|
||||
(see [[Interface--specifying-fragments]]) for the given //values//.
|
||||
|
||||
Each //topic// is a 32 byte (64 nibble) [[DataHexString]].
|
||||
|
||||
_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:
|
||||
|
||||
_property: interface.encodeFunctionData(fragment [ , values ]) => string<[[DataHexString]]> @SRC<abi/interface>
|
||||
Returns the encoded data, which can be used as the data for a transaction for
|
||||
//fragment// (see [[Interface--specifying-fragments]]) for the given //values//.
|
||||
|
||||
_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:
|
||||
|
||||
// Encoding structured data (using positional Array)
|
||||
user = [
|
||||
"Richard Moore",
|
||||
"0x8ba1f109551bD432803012645Ac136ddd64DBA72"
|
||||
];
|
||||
//_result:
|
||||
iface.encodeFunctionData("addUser", [ user ]);
|
||||
//_log:
|
||||
|
||||
// Encoding structured data, using objects. Only available
|
||||
// if paramters are named.
|
||||
user = {
|
||||
name: "Richard Moore",
|
||||
addr: "0x8ba1f109551bD432803012645Ac136ddd64DBA72"
|
||||
};
|
||||
//_result:
|
||||
iface.encodeFunctionData("addUser", [ user ]);
|
||||
//_log:
|
||||
|
||||
_property: interface.encodeFunctionResult(fragment [ , values ]) => string<[[DataHexString]]> @SRC<abi/interface>
|
||||
Returns the encoded result, which would normally be the response from a call for
|
||||
//fragment// (see [[Interface--specifying-fragments]]) for the given //values//.
|
||||
|
||||
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:
|
||||
|
||||
|
||||
_subsection: Decoding Data @<Interface--decoding>
|
||||
|
||||
@@ -100,6 +326,26 @@ 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:
|
||||
|
||||
_property: interface.decodeFunctionData(fragment, data) => [[Result]] @SRC<abi/interface>
|
||||
Returns the decoded values from transaction data for
|
||||
//fragment// (see [[Interface--specifying-fragments]]) for the given //data//.
|
||||
@@ -107,11 +353,62 @@ Returns the decoded values from transaction data for
|
||||
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:
|
||||
|
||||
_property: interface.decodeFunctionResult(fragment, data) => [[Result]] @SRC<abi/interface>
|
||||
Returns the decoded values from the result of a call for
|
||||
//fragment// (see [[Interface--specifying-fragments]]) for the given //data//.
|
||||
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const iface = _page.iface;
|
||||
|
||||
// Decoding result data (e.g. from an eth_call)
|
||||
resultData = "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000";
|
||||
//_result:
|
||||
iface.decodeFunctionResult("balanceOf", resultData)
|
||||
//_log:
|
||||
|
||||
// Decoding result data which was caused by a revert
|
||||
// Throws a CALL_EXCEPTION, with extra details
|
||||
errorData = "0xf7c3865a0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba720000000000000000000000000000000000000000000000000de0b6b3a7640000";
|
||||
//_throws:
|
||||
iface.decodeFunctionResult("balanceOf", errorData)
|
||||
//_log:
|
||||
|
||||
// Decoding structured data returns a Result object, which
|
||||
// will include all values positionally and if the ABI
|
||||
// included names, values will additionally be available
|
||||
// by their name.
|
||||
resultData = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000400000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72000000000000000000000000000000000000000000000000000000000000000d52696368617264204d6f6f726500000000000000000000000000000000000000";
|
||||
//_result:
|
||||
result = iface.decodeFunctionResult("getUser", resultData);
|
||||
//_log:
|
||||
|
||||
// Access positionally:
|
||||
// The 0th output parameter, the 0th proerty of the structure
|
||||
//_result:
|
||||
result[0][0];
|
||||
//_log:
|
||||
|
||||
// Access by name: (only avilable because parameters were named)
|
||||
//_result:
|
||||
result.user.name
|
||||
//_log:
|
||||
|
||||
_subsection: Parsing @<Interface--parsing>
|
||||
|
||||
The functions are generally the most useful for most developers. They will
|
||||
@@ -122,10 +419,38 @@ _property: interface.parseLog(log) => [[LogDescription]] @SRC<abi/interface>
|
||||
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:
|
||||
|
||||
_property: interface.parseTransaction(transaction) => [[TransactionDescription]] @SRC<abi/interface>
|
||||
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:
|
||||
|
||||
_subsection: Types @<Interface--types>
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ of errors introduced from typing an address or cut and paste issues.
|
||||
|
||||
All functions that return an Address will return a Checksum Address.
|
||||
|
||||
|
||||
_heading: ICAP Address @<address-icap>
|
||||
|
||||
The **ICAP Address Format** was an early attempt to introduce a checksum
|
||||
@@ -49,13 +48,72 @@ the checksum is invalid, an [INVALID_ARGUMENT](errors--invalid-argument) Error i
|
||||
|
||||
The value of //address// may be any supported address format.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const getAddress = ethers.utils.getAddress;
|
||||
|
||||
// Injects the checksum (via upper-casing specific letters)
|
||||
//_result:
|
||||
getAddress("0x8ba1f109551bd432803012645ac136ddd64dba72");
|
||||
//_log:
|
||||
|
||||
// Converts and injects the checksum
|
||||
//_result:
|
||||
getAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36");
|
||||
//_log:
|
||||
|
||||
// Throws if a checksummed address is provided, but a
|
||||
// letter is the wrong case
|
||||
// ------------v (should be lower-case)
|
||||
//_throws:
|
||||
getAddress("0x8Ba1f109551bD432803012645Ac136ddd64DBA72")
|
||||
//_log:
|
||||
|
||||
// Throws if the ICAP/IBAN checksum fails
|
||||
//_throws:
|
||||
getIcapAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK37");
|
||||
//_log:
|
||||
|
||||
// Throws if the address is invalid, in general
|
||||
//_throws:
|
||||
getIcapAddress("I like turtles!");
|
||||
//_log:
|
||||
|
||||
|
||||
_property: ethers.utils.getIcapAddress(address) => string<[IcapAddress](address-icap)> @<utils-getIcapAddress> @SRC<address>
|
||||
Returns //address// as an [ICAP address](link-icap).
|
||||
Supports the same restrictions as [getAddress](utils-getAddress).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const getIcapAddress = ethers.utils.getIcapAddress;
|
||||
|
||||
//_result:
|
||||
getIcapAddress("0x8ba1f109551bd432803012645ac136ddd64dba72");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
getIcapAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36");
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.isAddress(address) => boolean @<utils-isAddress> @SRC<address>
|
||||
Returns true if //address// is valid (in any supported format).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const isAddress = ethers.utils.isAddress;
|
||||
|
||||
//_result:
|
||||
isAddress("0x8ba1f109551bd432803012645ac136ddd64dba72");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
isAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
isAddress("I like turtles.");
|
||||
//_log:
|
||||
|
||||
_subsection: Derivation @<utils--address-derivation>
|
||||
|
||||
@@ -64,10 +122,49 @@ Returns the address for //publicOrPrivateKey//. A public key may be
|
||||
compressed or uncompressed, and a private key will be converted
|
||||
automatically to a public key for the derivation.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const computeAddress = ethers.utils.computeAddress;
|
||||
|
||||
// Private Key
|
||||
//_result:
|
||||
computeAddress("0xb976778317b23a1385ec2d483eda6904d9319135b89f1d8eee9f6d2593e2665d");
|
||||
//_log:
|
||||
|
||||
// Public Key (compressed)
|
||||
//_result:
|
||||
computeAddress("0x0376698beebe8ee5c74d8cc50ab84ac301ee8f10af6f28d0ffd6adf4d6d3b9b762");
|
||||
//_log:
|
||||
|
||||
// Public Key (uncompressed)
|
||||
//_result:
|
||||
computeAddress("0x0476698beebe8ee5c74d8cc50ab84ac301ee8f10af6f28d0ffd6adf4d6d3b9b762d46ca56d3dad2ce13213a6f42278dabbb53259f2d92681ea6a0b98197a719be3");
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.recoverAddress(digest, signature) => string<[[address]]> @<utils-recoverAddress> @SRC<transactions>
|
||||
Use [[link-wiki-ecrecover]] to determine the address that signed //digest// to
|
||||
which generated //signature//.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const recoverAddress = ethers.utils.recoverAddress;
|
||||
|
||||
const digest = "0x7c5ea36004851c764c44143b1dcb59679b11c9a68e5f41497f6cf3d480715331";
|
||||
|
||||
// Using an expanded Signature
|
||||
//_result:
|
||||
recoverAddress(digest, {
|
||||
r: "0x528459e4aec8934dc2ee94c4f3265cf6ce00d47cf42bb106afda3642c72e25eb",
|
||||
s: "0x42544137118256121502784e5a6425e6183ca964421ecd577db6c66ba9bccdcf",
|
||||
v: 27
|
||||
});
|
||||
//_log:
|
||||
|
||||
// Using a flat Signature
|
||||
const signature = "0x528459e4aec8934dc2ee94c4f3265cf6ce00d47cf42bb106afda3642c72e25eb42544137118256121502784e5a6425e6183ca964421ecd577db6c66ba9bccdcf1b";
|
||||
//_result:
|
||||
recoverAddress(digest, signature);
|
||||
//_log:
|
||||
|
||||
_subsection: Contracts Addresses @<utils--contract-addresses>
|
||||
|
||||
@@ -75,9 +172,33 @@ _property: ethers.utils.getContractAddress(transaction) => string<[[address]]>
|
||||
Returns the contract address that would result if //transaction// was
|
||||
used to deploy a contract.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const getContractAddress = ethers.utils.getContractAddress;
|
||||
|
||||
const from = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
|
||||
const nonce = 5;
|
||||
|
||||
//_result:
|
||||
getContractAddress({ from, nonce });
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.getCreate2Address(from, salt, initCodeHash) => string<[[address]]> @<utils-getCreate2Address> @SRC<address>
|
||||
Returns the contract address that would result from the given
|
||||
[CREATE2](link-eip-1014) call.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const getCreate2Address = ethers.utils.getCreate2Address;
|
||||
//_hide: const keccak256 = ethers.utils.keccak256;
|
||||
|
||||
const from = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
|
||||
const salt = "0x7c5ea36004851c764c44143b1dcb59679b11c9a68e5f41497f6cf3d480715331";
|
||||
const initCode = "0x6394198df16000526103ff60206004601c335afa6040516060f3";
|
||||
const initCodeHash = keccak256(initCode);
|
||||
|
||||
//_result:
|
||||
getCreate2Address(from, salt, initCodeHash);
|
||||
//_log:
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
_section: BigNumber @<BigNumber>
|
||||
|
||||
Many operations in Ethereum operation on numbers which are
|
||||
Many operations in Ethereum operate on numbers which are
|
||||
[outside the range of safe values](BigNumber--notes-safenumbers) to use
|
||||
in JavaScript.
|
||||
|
||||
@@ -49,43 +49,52 @@ _heading: Examples: @<>
|
||||
_code: @lang<javascript>
|
||||
|
||||
// From a decimal string...
|
||||
//_result:
|
||||
BigNumber.from("42")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From a HexString...
|
||||
//_result:
|
||||
BigNumber.from("0x2a")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From a negative HexString...
|
||||
//_result:
|
||||
BigNumber.from("-0x2a")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From an Array (or Uint8Array)...
|
||||
//_result:
|
||||
BigNumber.from([ 42 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From an existing BigNumber...
|
||||
let one1 = constants.One;
|
||||
let one2 = BigNumber.from(one1)
|
||||
|
||||
//_result:
|
||||
one2
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// ...which returns the same instance
|
||||
//_result:
|
||||
one1 === one2
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From a (safe) number...
|
||||
//_result:
|
||||
BigNumber.from(42)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From a ES2015 BigInt... (only on platforms with BigInt support)
|
||||
//_result:
|
||||
BigNumber.from(42n)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Numbers outside the safe range fail:
|
||||
//_throws:
|
||||
BigNumber.from(Number.MAX_SAFE_INTEGER);
|
||||
//! error
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Methods @<BigNumber--methods>
|
||||
@@ -186,8 +195,9 @@ _code: @lang<javascript>
|
||||
let a = BigNumber.from(42);
|
||||
let b = BigNumber.from("91");
|
||||
|
||||
//_result:
|
||||
a.mul(b);
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Notes @<BigNumber--notes>
|
||||
@@ -214,8 +224,9 @@ To demonstrate how this may be an issue in your code, consider:
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
(Number.MAX_SAFE_INTEGER + 2 - 2) == (Number.MAX_SAFE_INTEGER)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
_null:
|
||||
|
||||
|
||||
@@ -86,28 +86,34 @@ zeros.
|
||||
_code: Examples @lang<javascript>
|
||||
|
||||
// Convert a hexstring to a Uint8Array
|
||||
//_result:
|
||||
arrayify("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Convert an Array to a hexstring
|
||||
//_result:
|
||||
hexlify([1, 2, 3, 4])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Convert an Object to a hexstring
|
||||
//_result:
|
||||
hexlify({ length: 2, "0": 1, "1": 2 })
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Convert an Array to a hexstring
|
||||
//_result:
|
||||
hexlify([ 1 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Convert a number to a stripped hex value
|
||||
//_result:
|
||||
hexValue(1)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Convert an Array to a stripped hex value
|
||||
//_result:
|
||||
hexValue([ 1, 2 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Array Manipulation
|
||||
@@ -170,15 +176,18 @@ Return a copy of //array// shuffled using [[link-wiki-shuffle]].
|
||||
|
||||
_code: Examples @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.randomBytes(8)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
const data = [ 1, 2, 3, 4, 5, 6, 7 ];
|
||||
|
||||
// Returns a new Array
|
||||
//_result:
|
||||
utils.shuffled(data);
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// The Original is unscathed...
|
||||
//_result:
|
||||
data
|
||||
//!
|
||||
//_log:
|
||||
|
||||
@@ -53,6 +53,13 @@ _heading: Formatting @<display-logic--formatting>
|
||||
_property: ethers.utils.commify(value) => string @<utils-commify> @SRC<units>
|
||||
Returns a string with value grouped by 3 digits, separated by ``,``.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const commify = ethers.utils.commify;
|
||||
|
||||
//_result:
|
||||
commify("-1000.3000");
|
||||
//_log:
|
||||
|
||||
_heading: Conversion @<unit-conversion>
|
||||
|
||||
@@ -60,13 +67,88 @@ _property: ethers.utils.formatUnits(value [ , unit = "ether" ] ) => string @<ut
|
||||
Returns a string representation of //value// formatted with //unit//
|
||||
digits (if it is a number) or to the unit specified (if a string).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const formatUnits = ethers.utils.formatUnits;
|
||||
//_hide: const BigNumber = ethers.BigNumber;
|
||||
|
||||
const oneGwei = BigNumber.from("1000000000");
|
||||
const oneEther = BigNumber.from("1000000000000000000");
|
||||
|
||||
//_result:
|
||||
formatUnits(oneGwei, 0);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
formatUnits(oneGwei, "gwei");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
formatUnits(oneGwei, 9);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
formatUnits(oneEther);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
formatUnits(oneEther, 18);
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.formatEther(value) => string @<utils-formatEther> @SRC<units>
|
||||
The equivalent to calling ``formatUnits(value, "ether")``.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const formatEther = ethers.utils.formatEther;
|
||||
//_hide: const BigNumber = ethers.BigNumber;
|
||||
|
||||
const value = BigNumber.from("1000000000000000000");
|
||||
|
||||
//_result:
|
||||
formatEther(value);
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.parseUnits(value [ , unit = "ether" ] ) => [BigNumber](BigNumber) @<utils-parseUnits> @SRC<units>
|
||||
Returns a [BigNumber](BigNumber) representation of //value//, parsed with
|
||||
//unit// digits (if it is a number) or from the unit specified (if
|
||||
a string).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const parseUnits = ethers.utils.parseUnits;
|
||||
|
||||
//_result:
|
||||
parseUnits("1.0");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
parseUnits("1.0", "ether");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
parseUnits("1.0", 18);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
parseUnits("121.0", "gwei");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
parseUnits("121.0", 9);
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.parseEther(value) => [BigNumber](BigNumber) @<utils-parseEther> @SRC<units>
|
||||
The equivalent to calling ``parseUnits(value, "ether")``.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const parseEther = ethers.utils.parseEther;
|
||||
|
||||
//_result:
|
||||
parseEther("1.0");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
parseEther("-0.5");
|
||||
//_log:
|
||||
|
||||
@@ -2,23 +2,63 @@ _section: Encoding Utilities @<encoding>
|
||||
|
||||
_subsection: Base58 @<Bse58> @SRC<basex:Base58>
|
||||
|
||||
_property: ethers.utils.base58.decode(textData) => Uin8Array
|
||||
_property: ethers.utils.base58.decode(textData) => Uint8Array
|
||||
Return a typed Uint8Array representation of //textData// decoded using
|
||||
base-58 encoding.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const base58 = ethers.utils.base58;
|
||||
|
||||
//_result:
|
||||
base58.decode("TzMhH");
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.base58.encode(aBytesLike) => string
|
||||
Return //aBytesLike// encoded as a string using the base-58 encoding.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const base58 = ethers.utils.base58;
|
||||
|
||||
//_result:
|
||||
base58.encode("0x12345678");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
base58.encode([ 0x12, 0x34, 0x56, 0x78 ]);
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Base64 @<Base64>
|
||||
|
||||
_property: ethers.utils.base64.decode(textData) => Uin8Array @SRC<base64>
|
||||
_property: ethers.utils.base64.decode(textData) => Uint8Array @SRC<base64>
|
||||
Return a typed Uint8Array representation of //textData// decoded using
|
||||
base-64 encoding.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const base64 = ethers.utils.base64;
|
||||
|
||||
//_result:
|
||||
base64.decode("EjQ=");
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.base64.encode(aBytesLike) => string @SRC<base64>
|
||||
Return //aBytesLike// encoded as a string using the base-64 encoding.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const base64 = ethers.utils.base64;
|
||||
|
||||
//_result:
|
||||
base64.encode("0x1234");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
base64.encode([ 0x12, 0x34 ]);
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Recursive-Length Prefix @<rlp--methods>
|
||||
|
||||
@@ -26,15 +66,53 @@ The [[link-rlp]] encoding is used throughout Ethereum to serialize nested
|
||||
structures of Arrays and data.
|
||||
|
||||
_property: ethers.utils.RLP.encode(dataObject) => string<[[DataHexString]]> @<utils-rlpEncode> @SRC<rlp>
|
||||
Encode a structured Data Object into its RLP-encoded representation.
|
||||
Encode a structured [Data Object](rlp--dataobject) into its RLP-encoded representation.
|
||||
|
||||
Each Data component may be a valid [[BytesLike]].
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const RLP = ethers.utils.RLP;
|
||||
|
||||
//_result:
|
||||
RLP.encode("0x12345678");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.encode([ "0x12345678" ]);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.encode([ new Uint8Array([ 0x12, 0x34, 0x56, 0x78 ]) ]);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.encode([ [ "0x42", [ "0x43" ] ], "0x12345678", [ ] ]);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.encode([ ]);
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.RLP.decode(aBytesLike) => [DataObject](rlp--dataobject) @<utils.rlpDecode> @SRC<rlp>
|
||||
Decode an RLP-encoded //aBytesLike// into its structured Data Object.
|
||||
Decode an RLP-encoded //aBytesLike// into its structured [Data Object](rlp--dataobject).
|
||||
|
||||
All Data components will be returned as a [[DataHexString]].
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const RLP = ethers.utils.RLP;
|
||||
|
||||
//_result:
|
||||
RLP.decode("0x8412345678");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.decode("0xcac342c1438412345678c0");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.decode("0xc0");
|
||||
//_log:
|
||||
|
||||
_heading: Data Object @<rlp--dataobject>
|
||||
|
||||
A **Data Object** is a recursive structure which is used to serialize many
|
||||
|
||||
@@ -27,14 +27,17 @@ Returns the [SHA2-512](link-wiki-sha2) digest of //aBytesLike//.
|
||||
|
||||
_code: KECCAK256 @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.keccak256([ 0x12, 0x34 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.keccak256("0x")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.keccak256("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// The value MUST be data, such as:
|
||||
// - an Array of numbers
|
||||
@@ -42,16 +45,19 @@ utils.keccak256("0x1234")
|
||||
// - a Uint8Array
|
||||
|
||||
// Do NOT use UTF-8 strings that are not a DataHexstring
|
||||
//_throws:
|
||||
utils.keccak256("hello world")
|
||||
//! error
|
||||
//_log:
|
||||
|
||||
// If needed, convert strings to bytes first:
|
||||
//_result:
|
||||
utils.keccak256(utils.toUtf8Bytes("hello world"))
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Or equivalently use the identity function:
|
||||
//_result:
|
||||
utils.id("hello world")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Keep in mind that the string "0x1234" represents TWO
|
||||
// bytes (i.e. [ 0x12, 0x34 ]. If you wish to compute the
|
||||
@@ -61,48 +67,56 @@ utils.id("hello world")
|
||||
// Consider the following examples:
|
||||
|
||||
// Hash of TWO (2) bytes:
|
||||
//_result:
|
||||
utils.keccak256("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Hash of TWO (2) bytes: (same result)
|
||||
//_result:
|
||||
utils.keccak256([ 0x12, 0x34 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
const bytes = utils.toUtf8Bytes("0x1234")
|
||||
// <hide>
|
||||
bytes
|
||||
// </hide>
|
||||
//!
|
||||
//_result:
|
||||
bytes = utils.toUtf8Bytes("0x1234")
|
||||
//_log:
|
||||
|
||||
// Hash of SIX (6) characters (different than above)
|
||||
//_result:
|
||||
utils.keccak256(bytes)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Hash of SIX (6) characters (same result)
|
||||
//_result:
|
||||
utils.id("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
_code: RIPEMD160 @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.ripemd160("0x")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.ripemd160("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
_code: SHA-2 @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.sha256("0x")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.sha256("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.sha512("0x")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.sha512("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: HMAC @<utils--hmac>
|
||||
@@ -123,8 +137,9 @@ _code: HMAC @lang<javascript>
|
||||
|
||||
const key = "0x0102"
|
||||
const data = "0x1234"
|
||||
//_result:
|
||||
utils.computeHmac("sha256", key, data)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Hashing Helpers @<utils--hashing-helpers>
|
||||
@@ -137,12 +152,14 @@ and the length of //message//.
|
||||
_code: Hashing Messages @lang<javascript>
|
||||
|
||||
// Hashing a string message
|
||||
//_result:
|
||||
utils.hashMessage("Hello World")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Hashing binary data (also "Hello World", but as bytes)
|
||||
//_result:
|
||||
utils.hashMessage( [ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// NOTE: It is important to understand how strings and binary
|
||||
// data is handled differently. A string is ALWAYS processed
|
||||
@@ -151,18 +168,21 @@ utils.hashMessage( [ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 ])
|
||||
|
||||
// Hashing a hex string is the same as hashing a STRING
|
||||
// Note: this is the hash of the 4 characters [ '0', 'x', '4', '2' ]
|
||||
//_result:
|
||||
utils.hashMessage("0x42")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Hashing the binary data
|
||||
// Note: this is the hash of the 1 byte [ 0x42 ]
|
||||
//_result:
|
||||
utils.hashMessage([ 0x42 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Hashing the binary data
|
||||
// Note: similarly, this is the hash of the 1 byte [ 0x42 ]
|
||||
//_result:
|
||||
utils.hashMessage(utils.arrayify("0x42"))
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_property: ethers.utils.namehash(name) => string<[[DataHexString]]<32>> @<utils-namehash> @SRC<hash>
|
||||
@@ -170,17 +190,21 @@ Returns the [ENS Namehash](link-namehash) of //name//.
|
||||
|
||||
_code: Namehash @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.namehash("")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.namehash("eth")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.namehash("ricmoo.firefly.eth")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.namehash("ricmoo.xyz")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
_heading: Typed Data Encoder @<TypedDataEncoder> @SRC<hash:class.TypedDataEncoder>
|
||||
|
||||
@@ -244,19 +268,17 @@ been recursively replacedwith the value of calling //resolveName// with that val
|
||||
|
||||
_code: Typed Data Example @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
TypedDataEncoder = ethers.utils._TypedDataEncoder
|
||||
// </hide>
|
||||
//_hide: TypedDataEncoder = ethers.utils._TypedDataEncoder
|
||||
|
||||
const domain = {
|
||||
domain = {
|
||||
name: 'Ether Mail',
|
||||
version: '1',
|
||||
chainId: 1,
|
||||
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
|
||||
}
|
||||
};
|
||||
|
||||
// The named list of all type definitions
|
||||
const types = {
|
||||
types = {
|
||||
Person: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'wallet', type: 'address' }
|
||||
@@ -266,10 +288,10 @@ const types = {
|
||||
{ name: 'to', type: 'Person' },
|
||||
{ name: 'contents', type: 'string' }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// The data to sign
|
||||
const value = {
|
||||
value = {
|
||||
from: {
|
||||
name: 'Cow',
|
||||
wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826'
|
||||
@@ -279,23 +301,27 @@ const value = {
|
||||
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'
|
||||
},
|
||||
contents: 'Hello, Bob!'
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//_result:
|
||||
TypedDataEncoder.encode(domain, types, value)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
TypedDataEncoder.getPayload(domain, types, value)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
TypedDataEncoder.getPrimaryType(types)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
TypedDataEncoder.hash(domain, types, value)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
TypedDataEncoder.hashDomain(domain)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Solidity Hashing Algorithms @<utils--solidity-hashing>
|
||||
@@ -318,17 +344,21 @@ according to their respective type in //types//.
|
||||
|
||||
_code: Solidity Hashing @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "int16", "uint48" ], [ -1, 12 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "string", "uint8" ], [ "Hello", 3 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.solidityKeccak256([ "int16", "uint48" ], [ -1, 12 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.soliditySha256([ "int16", "uint48" ], [ -1, 12 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// As a short example of the non-distinguished nature of
|
||||
// Solidity tight-packing (which is why it is inappropriate
|
||||
@@ -336,14 +366,18 @@ utils.soliditySha256([ "int16", "uint48" ], [ -1, 12 ])
|
||||
// the following examples are all equal, despite representing
|
||||
// very different values and layouts.
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "string", "string" ], [ "hello", "world01" ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "string", "string" ], [ "helloworld", "01" ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "string", "string", "uint16" ], [ "hell", "oworld", 0x3031 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "uint96" ], [ "32309054545061485574011236401" ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
@@ -216,6 +216,22 @@ it deals with unmined transactions, and can be configured by each node, however
|
||||
to ensure a transaction is propagated to a miner it is best practice to follow
|
||||
the defaults most nodes have enabled.
|
||||
|
||||
_property: Logger.errors.TRANSACTION_REPLACED @<errors--transaction-replaced>
|
||||
When a transaction has been replaced by the user, by broadcasting a new transaction
|
||||
with the same nonce as an existing in-flight (unmined) transaction in the mempool,
|
||||
this error will occur while waiting if the transaction being waited for has become
|
||||
invalidated by that other transaction.
|
||||
|
||||
This can happen for several reasons, but most commonly because the user has increased
|
||||
the gas price (which changes the transaction hash) to "speed up" a transaction or if
|
||||
a user has "cancelled" the transaction in their client. In either case this is
|
||||
usually accomplished by bribing the miners with a higher gas priced transaction.
|
||||
|
||||
This error will have the additional properties, ``cancelled``, ``hash``, ``reason``,
|
||||
``receipt`` and ``replacement``.
|
||||
|
||||
See the [[providers-TransactionResponse]] for the ``wait`` method for more details.
|
||||
|
||||
_property: Logger.errors.UNPREDICTABLE_GAS_LIMIT @<errors--unpredicatable-gas-limit>
|
||||
When estimating the required amount of gas for a transaction, a node is queried for
|
||||
its best guess.
|
||||
|
||||
@@ -57,13 +57,11 @@ $TopicABaCD: **[** (topic[0] = A) **OR** (topic[0] = B) **]** **AND**
|
||||
|
||||
_code: ERC-20 Transfer Filter Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const tokenAddress = ethers.constants.AddressZero;
|
||||
const myAddress = ethers.constants.AddressZero;
|
||||
const myOtherAddress = ethers.constants.AddressZero;
|
||||
const id = ethers.utils.id;
|
||||
const hexZeroPad = ethers.utils.hexZeroPad;
|
||||
// </hide>
|
||||
//_hide: const tokenAddress = ethers.constants.AddressZero;
|
||||
//_hide: const myAddress = ethers.constants.AddressZero;
|
||||
//_hide: const myOtherAddress = ethers.constants.AddressZero;
|
||||
//_hide: const id = ethers.utils.id;
|
||||
//_hide: const hexZeroPad = ethers.utils.hexZeroPad;
|
||||
|
||||
// Short example of manually creating filters for an ERC-20
|
||||
// Transfer event.
|
||||
@@ -96,7 +94,7 @@ filter = {
|
||||
id("Transfer(address,address,uint256)"),
|
||||
hexZeroPad(myAddress, 32)
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// List all token transfers *to* myAddress:
|
||||
filter = {
|
||||
@@ -106,7 +104,7 @@ filter = {
|
||||
null,
|
||||
hexZeroPad(myAddress, 32)
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// List all token transfers *to* myAddress or myOtherAddress:
|
||||
filter = {
|
||||
@@ -119,7 +117,7 @@ filter = {
|
||||
hexZeroPad(myOtherAddress, 32),
|
||||
]
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
_null:
|
||||
|
||||
@@ -128,35 +126,37 @@ To simplify life, ..., explain here, the contract API
|
||||
|
||||
_code: ERC-20 Contract Filter Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const tokenAddress = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; // DAI
|
||||
const myAddress = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
|
||||
const otherAddress = "0xEA517D5a070e6705Cc5467858681Ed953d285Eb9";
|
||||
const provider = ethers.getDefaultProvider();
|
||||
const Contract = ethers.Contract;
|
||||
// </hide>
|
||||
//_hide: const tokenAddress = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; /* DAI */
|
||||
//_hide: const myAddress = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
|
||||
//_hide: const otherAddress = "0xEA517D5a070e6705Cc5467858681Ed953d285Eb9";
|
||||
//_hide: const provider = ethers.getDefaultProvider();
|
||||
//_hide: const Contract = ethers.Contract;
|
||||
|
||||
const abi = [
|
||||
abi = [
|
||||
"event Transfer(address indexed src, address indexed dst, uint val)"
|
||||
];
|
||||
|
||||
const contract = new Contract(tokenAddress, abi, provider);
|
||||
contract = new Contract(tokenAddress, abi, provider);
|
||||
|
||||
// List all token transfers *from* myAddress
|
||||
//_result:
|
||||
contract.filters.Transfer(myAddress)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// List all token transfers *to* myAddress:
|
||||
//_result:
|
||||
contract.filters.Transfer(null, myAddress)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// List all token transfers *from* myAddress *to* otherAddress:
|
||||
//_result:
|
||||
contract.filters.Transfer(myAddress, otherAddress)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// List all token transfers *to* myAddress OR otherAddress:
|
||||
//_result:
|
||||
contract.filters.Transfer(null, [ myAddress, otherAddress ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Solidity Topics @<events-solidity>
|
||||
|
||||
@@ -1,5 +1,82 @@
|
||||
_section: Security @<security>
|
||||
|
||||
While security should be a concern for all developers, in the
|
||||
blockchain space developers must be additionally conscious of
|
||||
many areas which can be exploited.
|
||||
|
||||
Once a problem has an economic incentives to exploit it, there
|
||||
is a much larger risk and with blockchain apps it can become
|
||||
quite valuable to attack.
|
||||
|
||||
In addition to many of the other security issues app developers
|
||||
may have to worry about, there are a few additional vectors
|
||||
that JavaScript developers should be aware of.
|
||||
|
||||
_subsection: Side-Channel Attacks
|
||||
|
||||
A [Side-Channel Attack](link-wiki-side-channel-attack) occurs
|
||||
when something orthogonal to the implementation of the algorithm
|
||||
used can be exploited to learn more about secure or private
|
||||
information.
|
||||
|
||||
_heading: Released Data (Strings, Uint8Arrays, Buffers)
|
||||
|
||||
In JavaScript, memory may not be securely allocated, or more
|
||||
importantly securely released.
|
||||
|
||||
[Historically](https://github.com/nodejs/node/issues/4660),
|
||||
``new Buffer(16)`` would re-use old memory that had been
|
||||
released. This would mean that code runnint later, may have
|
||||
access to data that was discarded.
|
||||
|
||||
As an example of the dangers, imagine if you had used a Buffer
|
||||
to store a private key, signed data and then returned from the
|
||||
function, allowing the Buffer to be de-allocated. A future
|
||||
function may be able to request a new Buffer, which would still
|
||||
have that left-over private key, which it could then use to
|
||||
steal the funds from that account.
|
||||
|
||||
There are also many debugging tools and systems designed to
|
||||
assist develoeprs inspect the memory contents of JavaScript
|
||||
programs. In these cases, any //private key// or //mnemonic//
|
||||
siiting in memory may be visible to other users on the system,
|
||||
or malicious scripts.
|
||||
|
||||
_heading: Timing Attack
|
||||
|
||||
Timing attacks allow a malicious user or script to determine
|
||||
private data through analysing how long an operation requires
|
||||
to execute.
|
||||
|
||||
In JavaScript, //Garbage Collection// occurs periodically when the
|
||||
system determines it is required. Each JavaScript implementation
|
||||
is different, with a variety of strategies and and abilities.
|
||||
|
||||
Most Garbage Collection requires "stopping the world", or pausing
|
||||
all code being executed while it runs. This adds a large delay
|
||||
to any code that was currently running.
|
||||
|
||||
This can be exploited by attackers to "condition cause a delay".
|
||||
They will set up a scenario where the system is on the edge of
|
||||
needing to garbage collect, and call your code with two paths,
|
||||
a simple path and complex path. The simple path won't stir things
|
||||
up enough to cause a garbage collection, while the complex one
|
||||
will. By timing how long the code took to execute, they now know
|
||||
whether garbage collection occured and therefore whether the simple
|
||||
or complex path was taken.
|
||||
|
||||
Advancced timing attacks are very difficult to mitigate in any
|
||||
garbage-collection-based language. Most libraries where this
|
||||
matters will hopefully mitigated this for you as much as possible,
|
||||
but it is still good to be aware of.
|
||||
|
||||
_heading: General Concerns
|
||||
|
||||
- [Cross-Site Scripting](link-wiki-xss)
|
||||
- [Cross-Site Request Forgery](link-wiki-csrf)
|
||||
- [Phishing](link-wiki-phishing)
|
||||
|
||||
|
||||
_subsection: Key Derivation Functions @<security--pbkdf>
|
||||
|
||||
This is not specific to Ethereum, but is a useful technique
|
||||
|
||||
@@ -142,12 +142,35 @@ function codeContextify(context) {
|
||||
return `{ BigNumber: ${JSON.stringify(this.toString()) } }`;
|
||||
}
|
||||
|
||||
context.createClass = function(name) {
|
||||
let C = class{ }
|
||||
Object.defineProperty(C, "name", { value: name })
|
||||
return C;
|
||||
}
|
||||
|
||||
|
||||
context._inspect = function(value, depth) {
|
||||
if (toString.call(value) === '[object Error]') {
|
||||
// Not an error from ethers...
|
||||
if (ethers.utils.Logger.errors[value.code] == null) {
|
||||
return `Error: ${ value.message }`;
|
||||
}
|
||||
|
||||
// Trim the ethers errors down on their verbosity for the docs...
|
||||
if (value.message) {
|
||||
value.message = value.message.split(" (")[0];
|
||||
}
|
||||
value.stack = undefined;
|
||||
}
|
||||
|
||||
if (value && value.constructor && value.constructor.name === "Uint8Array") {
|
||||
return `Uint8Array [ ${ Array.prototype.join.call(value, ", ") } ]`;
|
||||
}
|
||||
|
||||
if (typeof(value) === "string" && value.indexOf("\n") >= 0) {
|
||||
return "`" + value + "`";
|
||||
}
|
||||
|
||||
//return JSON.stringify(value);
|
||||
return inspect(value, {
|
||||
compact: false,
|
||||
@@ -156,12 +179,20 @@ function codeContextify(context) {
|
||||
sorted: true,
|
||||
});
|
||||
}
|
||||
|
||||
context._startup = function() {
|
||||
console.log("Startup");
|
||||
}
|
||||
|
||||
context._shutdown = function() {
|
||||
console.log("Shutdown");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
title: "ethers",
|
||||
subtitle: "v5.0",
|
||||
subtitle: "v5.3",
|
||||
description: "Documentation for ethers, a complete, tiny and simple Ethereum library.",
|
||||
logo: "logo.svg",
|
||||
|
||||
@@ -204,7 +235,8 @@ module.exports = {
|
||||
"link-rtd": "https:/\/github.com/readthedocs/sphinx_rtd_theme",
|
||||
"link-semver": { name: "semver", url: "https:/\/semver.org" },
|
||||
"link-solidity": { name: "Solidity" , url: "https:/\/solidity.readthedocs.io/" },
|
||||
"link-solidity-events": "https:/\/docs.soliditylang.org/en/v0.8.1/abi-spec.html#events",
|
||||
"link-solidity-errors": "https:/\/docs.soliditylang.org/en/v0.8.4/abi-spec.html#errors",
|
||||
"link-solidity-events": "https:/\/docs.soliditylang.org/en/v0.8.4/abi-spec.html#events",
|
||||
"link-sphinx": { name: "Sphinx", url: "https:/\/www.sphinx-doc.org/" },
|
||||
|
||||
"link-alchemy-signup": "https:/\/dashboard.alchemyapi.io/signup?referral=55a35117-028e-4b7c-9e47-e275ad0acc6d",
|
||||
@@ -246,7 +278,7 @@ module.exports = {
|
||||
|
||||
"link-ethersio": "https:/\/ethers.io/",
|
||||
"link-ethers-docs": "https:/\/docs.ethers.io/",
|
||||
"link-ethers-js": "https:/\/cdn.ethers.io/lib/ethers-5.0.esm.min.js",
|
||||
"link-ethers-js": "https:/\/cdn.ethers.io/lib/ethers-5.1.esm.min.js",
|
||||
"link-ethers-npm": "https:/\/www.npmjs.com/search?q=%40ethersproject%2F",
|
||||
"link-ethers-asm-grammar": "https:/\/github.com/ethers-io/ethers.js/blob/master/packages/asm/grammar.jison",
|
||||
|
||||
@@ -291,12 +323,14 @@ module.exports = {
|
||||
"link-wiki-bloomfilter": { name: "Bloom Filter", url: "https:/\/en.wikipedia.org/wiki/Bloom_filter" },
|
||||
"link-wiki-bruteforce": "https:/\/en.wikipedia.org/wiki/Brute-force_attack",
|
||||
"link-wiki-cryptographichash": "https:/\/en.wikipedia.org/wiki/Cryptographic_hash_function",
|
||||
"link-wiki-csrf": "https:/\/en.wikipedia.org/wiki/Cross-site_request_forgery",
|
||||
"link-wiki-ecrecover": { name: "ECDSA Public Key Recovery", url: "https:/\/en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Public_key_recovery" },
|
||||
"link-wiki-homoglyph": "https:/\/en.wikipedia.org/wiki/IDN_homograph_attack",
|
||||
"link-wiki-hmac": "https:/\/en.wikipedia.org/wiki/HMAC",
|
||||
"link-wiki-iban": "https:/\/en.wikipedia.org/wiki/International_Bank_Account_Number",
|
||||
"link-wiki-ieee754": "https:/\/en.wikipedia.org/wiki/Double-precision_floating-point_format",
|
||||
"link-wiki-observer-pattern": { name: "Obeserver Pattern", url: "https:/\/en.wikipedia.org/wiki/Observer_pattern" },
|
||||
"link-wiki-phishing": "https:/\/en.wikipedia.org/wiki/Phishing",
|
||||
"link-wiki-ripemd": "https:/\/en.m.wikipedia.org/wiki/RIPEMD",
|
||||
"link-wiki-sha2": "https:/\/en.wikipedia.org/wiki/SHA-2",
|
||||
"link-wiki-twoscomplement": "https:/\/en.wikipedia.org/wiki/Two%27s_complement",
|
||||
@@ -304,9 +338,11 @@ module.exports = {
|
||||
"link-wiki-utf8-overlong": "https:/\/en.wikipedia.org/wiki/UTF-8#Overlong_encodings",
|
||||
"link-wiki-utf8-replacement": "https:/\/en.wikipedia.org/wiki/Specials_%28Unicode_block%29#Replacement_character",
|
||||
"link-wiki-scrypt": "https:/\/en.wikipedia.org/wiki/Scrypt",
|
||||
"link-wiki-side-channel-attack": "https:/\/en.wikipedia.org/wiki/Side-channel_attack",
|
||||
"link-wiki-sha3": "https:/\/en.wikipedia.org/wiki/SHA-3",
|
||||
"link-wiki-shuffle": { name: "Fisher-Yates Shuffle", url: "https:/\/en.wikipedia.org/wiki/Fisher-Yates_shuffle" },
|
||||
"link-wiki-overflow": { name: "overflow", url: "https:/\/en.wikipedia.org/wiki/Integer_overflow" },
|
||||
"link-wiki-underflow": { name: "arithmetic underflow", url: "https:/\/en.wikipedia.org/wiki/Arithmetic_underflow" },
|
||||
"link-wiki-xss": "https:/\/en.wikipedia.org/wiki/Cross-site_scripting",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -219,58 +219,64 @@ for displaying code samples.
|
||||
|
||||
_heading: JavaScript Evaluation @<flatworm--code-eval>
|
||||
|
||||
For JavaScript files, the file is executed with some simple substitution.
|
||||
For JavaScript files, the file is transpiled and executed in a VM,
|
||||
allowiung output (or exceptions) of blocks to be included in the
|
||||
fragment output.
|
||||
|
||||
A bare ``\/\/!`` on a line is replaced with the result of the last
|
||||
statement. Building will fail if an error is thrown.
|
||||
The entire **code fragment** source is included in an async IIFE,
|
||||
whick means ``await`` is allowed, and several special comment
|
||||
directives are allowed.
|
||||
|
||||
A bare ``\/\/!error`` is replaced with the throw error. Building will
|
||||
fail if an error is not thrown.
|
||||
A ``/\/_hide:`` will include any following code directly into the
|
||||
output, but will not include it in the generated output for the fragment.
|
||||
|
||||
Also any code included between the lines **``\/\/ <hide>``** and
|
||||
**``\/\/ </hide>``** will be omitted from the output, which can be used
|
||||
to setup variables.
|
||||
A ``/\/_log:`` will include the value of any following expression in the
|
||||
output, prefixed with a ``/\/ ``. Renderers will mark output in different
|
||||
style if possible.
|
||||
|
||||
A ``/\/_result:`` will begin a block, assigning the contents to ``_``. The
|
||||
block can be ended with a ``/\/_log:`` or ``/\/_null:``, if no value is given
|
||||
to log, then ``_`` is assumed. If an error occurs, generation fails.
|
||||
|
||||
A ``/\/_throws:`` will begin a block, which is expected to throw assigning
|
||||
the error to ``_``. The block can be ended with a ``/\/_log:`` or ``/\/_null:``,
|
||||
if no value is given to log, then ``_`` is assumed. If an error do not occur,
|
||||
generation fails.
|
||||
|
||||
_code: Code Evaluation Example @lang<text>
|
||||
|
||||
\_code: Result of Code Example @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const url = require("url");
|
||||
// </hide>
|
||||
//_hide: const url = require("url");
|
||||
|
||||
//_result:
|
||||
url.parse("https://www.ricmoo.com/").protocol
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_throws:
|
||||
url.parse(45)
|
||||
//! error
|
||||
//_log:
|
||||
|
||||
// You want to assign (doesn't emit eval) AND display the value
|
||||
const foo = 4 + 5;
|
||||
// <hide>
|
||||
foo
|
||||
// </hide>
|
||||
//!
|
||||
//_log: foo
|
||||
|
||||
|
||||
_code: Result of Code Example @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const url = require("url");
|
||||
// </hide>
|
||||
//_hide: const url = require("url");
|
||||
|
||||
//_result:
|
||||
url.parse("https://www.ricmoo.com/").protocol
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_throws:
|
||||
url.parse(45)
|
||||
//! error
|
||||
//_log:
|
||||
|
||||
// You want to assign (doesn't emit eval) AND display the value
|
||||
const foo = 4 + 5;
|
||||
// <hide>
|
||||
foo
|
||||
// </hide>
|
||||
//!
|
||||
//_log: foo
|
||||
|
||||
|
||||
_heading: Languages
|
||||
|
||||
@@ -39,14 +39,14 @@ Web Applications from our CDN.
|
||||
_code: ES6 in the Browser @lang<html>
|
||||
|
||||
<script type="module">
|
||||
import { ethers } from "https://cdn.ethers.io/lib/ethers-5.0.esm.min.js";
|
||||
import { ethers } from "https://cdn.ethers.io/lib/ethers-5.2.esm.min.js";
|
||||
// Your code here...
|
||||
</script>
|
||||
|
||||
|
||||
_code: ES3 (UMD) in the Browser @lang<html>
|
||||
|
||||
<script src="https://cdn.ethers.io/lib/ethers-5.0.umd.min.js"
|
||||
<script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js"
|
||||
type="application/javascript"></script>
|
||||
|
||||
|
||||
@@ -123,22 +123,26 @@ logs, look up deployed code and so on.
|
||||
_code: Basic Queries @lang<javascript>
|
||||
|
||||
// Look up the current block number
|
||||
provider.getBlockNumber()
|
||||
//!
|
||||
//_result:
|
||||
await provider.getBlockNumber()
|
||||
//_log:
|
||||
|
||||
// Get the balance of an account (by address or ENS name, if supported by network)
|
||||
//_result:
|
||||
balance = await provider.getBalance("ethers.eth")
|
||||
//! async balance
|
||||
//_log:
|
||||
|
||||
// Often you need to format the output to something more user-friendly,
|
||||
// such as in ether (instead of wei)
|
||||
//_result:
|
||||
ethers.utils.formatEther(balance)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// If a user enters a string in an input field, you may need
|
||||
// to convert it from ether (as a string) to wei (as a BigNumber)
|
||||
//_result:
|
||||
ethers.utils.parseEther("1.0")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_heading: Writing to the Blockchain @<getting-started--sending>
|
||||
@@ -204,38 +208,33 @@ const daiAbi = [
|
||||
// The Contract object
|
||||
const daiContract = new ethers.Contract(daiAddress, daiAbi, provider);
|
||||
|
||||
//_hide: _page.daiAbi = daiAbi;
|
||||
//_hide: _page.daiContract = daiContract;
|
||||
|
||||
_heading: Read-Only Methods @<getting-started--reading>
|
||||
|
||||
_code: Querying the DAI Contract @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const daiAbi = [
|
||||
// Some simple details about the token
|
||||
"function name() view returns (string)",
|
||||
"function symbol() view returns (string)",
|
||||
|
||||
// Get the account balance
|
||||
"function balanceOf(address) view returns (uint)",
|
||||
];
|
||||
const daiContract = new ethers.Contract("dai.tokens.ethers.eth", daiAbi, provider);
|
||||
// </hide>
|
||||
//_hide: const daiContract = _page.daiContract;
|
||||
|
||||
// Get the ERC-20 token name
|
||||
daiContract.name()
|
||||
//!
|
||||
//_result:
|
||||
await daiContract.name()
|
||||
//_log:
|
||||
|
||||
// Get the ERC-20 token symbol (for tickers and UIs)
|
||||
daiContract.symbol()
|
||||
//!
|
||||
//_result:
|
||||
await daiContract.symbol()
|
||||
//_log:
|
||||
|
||||
// Get the balance of an address
|
||||
balance = await daiContract.balanceOf("ricmoo.firefly.eth")
|
||||
//! async balance
|
||||
//_log: balance
|
||||
|
||||
// Format the DAI for displaying to the user
|
||||
//_result:
|
||||
ethers.utils.formatUnits(balance, 18)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_heading: State Changing Methods @<getting-started--writing>
|
||||
@@ -258,13 +257,8 @@ _heading: Listening to Events @<getting-started--events>
|
||||
|
||||
_code: Listening to Events @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const daiAbi = [
|
||||
"event Transfer(address indexed, address indexed, uint256)"
|
||||
];
|
||||
const daiContract = new ethers.Contract("dai.tokens.ethers.eth", daiAbi, provider);
|
||||
const formatEther = ethers.utils.formatEther;
|
||||
// </hide>
|
||||
//_hide: const daiContract = _page.daiContract;
|
||||
//_hide: const formatEther = ethers.utils.formatEther;
|
||||
|
||||
// Receive an event when ANY transfer occurs
|
||||
daiContract.on("Transfer", (from, to, amount, event) => {
|
||||
@@ -277,10 +271,7 @@ daiContract.on("Transfer", (from, to, amount, event) => {
|
||||
// A filter for when a specific address receives tokens
|
||||
myAddress = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
|
||||
filter = daiContract.filters.Transfer(null, myAddress)
|
||||
// <hide>
|
||||
filter
|
||||
// </hide>
|
||||
//!
|
||||
//_log: filter
|
||||
|
||||
// Receive an event when that filter occurs
|
||||
daiContract.on(filter, (from, to, amount, event) => {
|
||||
@@ -288,46 +279,32 @@ daiContract.on(filter, (from, to, amount, event) => {
|
||||
console.log(`I got ${ formatEther(amount) } from ${ from }.`);
|
||||
});
|
||||
|
||||
// <hide>
|
||||
// Don't want to block the docs from compiling...
|
||||
daiContract.removeAllListeners();
|
||||
// </hide>
|
||||
//_hide: daiContract.removeAllListeners(); /* Don't want to block the docs from compiling... */
|
||||
|
||||
|
||||
_heading: Query Historic Events @<getting-started--history>
|
||||
|
||||
_code: Filtering Historic Events @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const signer = new ethers.VoidSigner("0x8ba1f109551bD432803012645Ac136ddd64DBA72");
|
||||
const daiAbi = [
|
||||
"event Transfer(address indexed, address indexed, uint256)"
|
||||
];
|
||||
const daiContract = new ethers.Contract("dai.tokens.ethers.eth", daiAbi, provider);
|
||||
//!
|
||||
// </hide>
|
||||
//_hide: const signer = new ethers.VoidSigner("0x8ba1f109551bD432803012645Ac136ddd64DBA72");
|
||||
//_hide: const daiContract = _page.daiContract;
|
||||
|
||||
// Get the address of the Signer
|
||||
myAddress = await signer.getAddress()
|
||||
//! async myAddress
|
||||
//_log: myAddress
|
||||
|
||||
// Filter for all token transfers from me
|
||||
filterFrom = daiContract.filters.Transfer(myAddress, null);
|
||||
// <hide>
|
||||
filterFrom
|
||||
// </hide>
|
||||
//!
|
||||
//_log: filterFrom
|
||||
|
||||
// Filter for all token transfers to me
|
||||
filterTo = daiContract.filters.Transfer(null, myAddress);
|
||||
// <hide>
|
||||
filterTo
|
||||
// </hide>
|
||||
//!
|
||||
//_log: filterTo
|
||||
|
||||
// List all transfers sent from me a specific block range
|
||||
daiContract.queryFilter(filterFrom, 9843470, 9843480)
|
||||
//!
|
||||
//_result:
|
||||
await daiContract.queryFilter(filterFrom, 9843470, 9843480)
|
||||
//_log:
|
||||
|
||||
//
|
||||
// The following have had the results omitted due to the
|
||||
@@ -335,26 +312,22 @@ daiContract.queryFilter(filterFrom, 9843470, 9843480)
|
||||
//
|
||||
|
||||
// List all transfers sent in the last 10,000 blocks
|
||||
daiContract.queryFilter(filterFrom, -10000)
|
||||
await daiContract.queryFilter(filterFrom, -10000)
|
||||
|
||||
// List all transfers ever sent to me
|
||||
daiContract.queryFilter(filterTo)
|
||||
|
||||
await daiContract.queryFilter(filterTo)
|
||||
|
||||
_subsection: Signing Messages @<getting-started--signing>
|
||||
|
||||
_code: Signing Messages @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const signer = ethers.Wallet.createRandom();
|
||||
//!
|
||||
// </hide>
|
||||
//_hide: const signer = ethers.Wallet.createRandom();
|
||||
|
||||
// To sign a simple string, which are used for
|
||||
// logging into a service, such as CryptoKitties,
|
||||
// pass the string in.
|
||||
signature = await signer.signMessage("Hello World");
|
||||
//! async signature
|
||||
//_log: signature
|
||||
|
||||
//
|
||||
// A common case is also signing a hash, which is 32
|
||||
@@ -367,8 +340,8 @@ message = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
|
||||
|
||||
// This array representation is 32 bytes long
|
||||
messageBytes = ethers.utils.arrayify(message);
|
||||
//!
|
||||
//_log: messageBytes
|
||||
|
||||
// To sign a hash, you most often want to sign the bytes
|
||||
signature = await signer.signMessage(messageBytes)
|
||||
//! async signature
|
||||
//_log: signature
|
||||
|
||||
@@ -7,7 +7,7 @@ of uses.
|
||||
|
||||
_heading: MIT License
|
||||
|
||||
//Copyright © 2019 [Richard Moore](mailto:me@ricmoo.com).//
|
||||
//Copyright © 2019-2021 [Richard Moore](mailto:me@ricmoo.com).//
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -35,7 +35,12 @@ module.exports = function(config) {
|
||||
// Cloudflare will block (on the testnet endpoints) any traffic
|
||||
// from a headless chome (based on the user agent), so we lie
|
||||
// This was take from Safari, because that is what I had on-hand
|
||||
'--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15']
|
||||
'--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15',
|
||||
|
||||
// https://stackoverflow.com/questions/58484124/karma-disconnectedreconnect-failed-before-timeout-of-with-chromeheadless
|
||||
'--disable-gpu',
|
||||
'--no-sandbox'
|
||||
],
|
||||
}
|
||||
},
|
||||
/*
|
||||
|
||||
@@ -36,7 +36,12 @@ module.exports = function(config) {
|
||||
// Cloudflare will block (on the testnet endpoints) any traffic
|
||||
// from a headless chome (based on the user agent), so we lie
|
||||
// This was take from Safari, because that is what I had on-hand
|
||||
'--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15']
|
||||
'--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15',
|
||||
|
||||
// https://stackoverflow.com/questions/58484124/karma-disconnectedreconnect-failed-before-timeout-of-with-chromeheadless
|
||||
'--disable-gpu',
|
||||
'--no-sandbox'
|
||||
]
|
||||
}
|
||||
},
|
||||
/*
|
||||
|
||||
@@ -25,15 +25,15 @@ const Words = fs_1.default.readFileSync("/usr/share/dict/words").toString().spli
|
||||
accessing addresses aligned autofill called cancelled changed censored
|
||||
clamping compiled computed configured consumed creating decoded decoding
|
||||
decreased decrypt decrypted decrypting deployed deploying deprecated detected
|
||||
discontinued earliest email enabled encoded encoder encoding encrypt
|
||||
discontinued earliest email emitted enabled encoded encoder encoding encrypt
|
||||
encrypted encrypting entries euro exceeded existing expected
|
||||
expired failed fetches formatted formatting funding generated
|
||||
hardened has highly ignoring implemented implementer imported including instantiate
|
||||
joined keyword labelled larger lookup matches mined modified modifies multi
|
||||
named needed nested neutered numeric offline optimizer overriding owned packed
|
||||
padded parsed parsing passed payload placeholder processing properties prototyping reached
|
||||
recommended recovered redacted remaining replaced required reverted
|
||||
serializes shared signed signing skipped stored supported tagging targetted
|
||||
recommended recovered redacted remaining replaced repriced required reverted
|
||||
serializes shared signed signing skipped stats stored supported tagging targetted
|
||||
throttled transactions typed uninstall unstake unsubscribe untyped
|
||||
using verifies verifying website
|
||||
|
||||
@@ -41,7 +41,7 @@ using verifies verifying website
|
||||
bech BIP BIP39 BIP44 btc bzz crypto eip etc hashes hmac icap
|
||||
keccak ltc namehash ripemd RLP scrypt secp sha xdai
|
||||
|
||||
blockhash
|
||||
blockhash bnb bnbt ethprice matic txlist
|
||||
|
||||
bitcoin ethereum finney gwei kwei mwei satoshi szabo wei weth
|
||||
|
||||
@@ -75,7 +75,7 @@ apikey asc endblock startblock
|
||||
alchemyapi Cloudflare Etherscan INFURA IPFS MetaMask Nodesmith
|
||||
Trezor ledgerhq axic bitcoinjs browserify easyseed ethereumjs
|
||||
goerli homestead kotti kovan mainnet morden mordor rinkeby
|
||||
ropsten testnet lb
|
||||
ropsten testnet lb maticmum
|
||||
|
||||
// Demo words
|
||||
args foo eth foo foobar ll localhost passwd ricmoo tx xxx yna
|
||||
|
||||
@@ -73,7 +73,7 @@ function _getUrl(href, options) {
|
||||
options = {};
|
||||
}
|
||||
// @TODO: Once we drop support for node 8, we can pass the href
|
||||
// firectly into request and skip adding the components
|
||||
// directly into request and skip adding the components
|
||||
// to this request object
|
||||
const url = url_1.parse(href);
|
||||
const request = {
|
||||
|
||||
@@ -16,15 +16,15 @@ const Words = fs.readFileSync("/usr/share/dict/words").toString().split("\n").re
|
||||
accessing addresses aligned autofill called cancelled changed censored
|
||||
clamping compiled computed configured consumed creating decoded decoding
|
||||
decreased decrypt decrypted decrypting deployed deploying deprecated detected
|
||||
discontinued earliest email enabled encoded encoder encoding encrypt
|
||||
discontinued earliest email emitted enabled encoded encoder encoding encrypt
|
||||
encrypted encrypting entries euro exceeded existing expected
|
||||
expired failed fetches formatted formatting funding generated
|
||||
hardened has highly ignoring implemented implementer imported including instantiate
|
||||
joined keyword labelled larger lookup matches mined modified modifies multi
|
||||
named needed nested neutered numeric offline optimizer overriding owned packed
|
||||
padded parsed parsing passed payload placeholder processing properties prototyping reached
|
||||
recommended recovered redacted remaining replaced required reverted
|
||||
serializes shared signed signing skipped stored supported tagging targetted
|
||||
recommended recovered redacted remaining replaced repriced required reverted
|
||||
serializes shared signed signing skipped stats stored supported tagging targetted
|
||||
throttled transactions typed uninstall unstake unsubscribe untyped
|
||||
using verifies verifying website
|
||||
|
||||
@@ -32,7 +32,7 @@ using verifies verifying website
|
||||
bech BIP BIP39 BIP44 btc bzz crypto eip etc hashes hmac icap
|
||||
keccak ltc namehash ripemd RLP scrypt secp sha xdai
|
||||
|
||||
blockhash
|
||||
blockhash bnb bnbt ethprice matic txlist
|
||||
|
||||
bitcoin ethereum finney gwei kwei mwei satoshi szabo wei weth
|
||||
|
||||
@@ -66,7 +66,7 @@ apikey asc endblock startblock
|
||||
alchemyapi Cloudflare Etherscan INFURA IPFS MetaMask Nodesmith
|
||||
Trezor ledgerhq axic bitcoinjs browserify easyseed ethereumjs
|
||||
goerli homestead kotti kovan mainnet morden mordor rinkeby
|
||||
ropsten testnet lb
|
||||
ropsten testnet lb maticmum
|
||||
|
||||
// Demo words
|
||||
args foo eth foo foobar ll localhost passwd ricmoo tx xxx yna
|
||||
|
||||
@@ -79,7 +79,7 @@ async function _getUrl(href: string, options?: Options): Promise<GetUrlResponse>
|
||||
if (options == null) { options = { }; }
|
||||
|
||||
// @TODO: Once we drop support for node 8, we can pass the href
|
||||
// firectly into request and skip adding the components
|
||||
// directly into request and skip adding the components
|
||||
// to this request object
|
||||
const url = parse(href);
|
||||
|
||||
|
||||
1409
package-lock.json
generated
1409
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -67,9 +67,9 @@
|
||||
"aes-js": "3.0.0",
|
||||
"aws-sdk": "2.137.0",
|
||||
"diff": "4.0.1",
|
||||
"flatworm": "0.0.2-beta.5",
|
||||
"flatworm": "0.0.2-beta.6",
|
||||
"jison": "0.4.18",
|
||||
"karma": "5.2.3",
|
||||
"karma": "6.3.2",
|
||||
"karma-chrome-launcher": "3.1.0",
|
||||
"karma-mocha": "2.0.1",
|
||||
"libnpmpublish": "3.0.1",
|
||||
@@ -92,13 +92,13 @@
|
||||
"@types/mocha": "^5.2.0",
|
||||
"aes-js": "3.0.0",
|
||||
"bech32": "1.1.4",
|
||||
"bn.js": "^4.4.0",
|
||||
"bn.js": "^4.11.9",
|
||||
"elliptic": "6.5.4",
|
||||
"hash.js": "1.1.3",
|
||||
"hash.js": "1.1.7",
|
||||
"js-sha3": "0.5.7",
|
||||
"scrypt-js": "3.0.1",
|
||||
"solc": "0.7.1",
|
||||
"tiny-inflate": "1.0.3",
|
||||
"ws": "7.2.3"
|
||||
"ws": "7.4.6"
|
||||
}
|
||||
}
|
||||
|
||||
2
packages/abi/lib.esm/_version.d.ts
vendored
2
packages/abi/lib.esm/_version.d.ts
vendored
@@ -1,2 +1,2 @@
|
||||
export declare const version = "abi/5.1.1";
|
||||
export declare const version = "abi/5.4.0";
|
||||
//# sourceMappingURL=_version.d.ts.map
|
||||
@@ -1,2 +1,2 @@
|
||||
export const version = "abi/5.1.1";
|
||||
export const version = "abi/5.4.0";
|
||||
//# sourceMappingURL=_version.js.map
|
||||
8
packages/abi/lib.esm/fragments.d.ts
vendored
8
packages/abi/lib.esm/fragments.d.ts
vendored
@@ -3,6 +3,7 @@ export interface JsonFragmentType {
|
||||
readonly name?: string;
|
||||
readonly indexed?: boolean;
|
||||
readonly type?: string;
|
||||
readonly internalType?: any;
|
||||
readonly components?: ReadonlyArray<JsonFragmentType>;
|
||||
}
|
||||
export interface JsonFragment {
|
||||
@@ -74,4 +75,11 @@ export declare class FunctionFragment extends ConstructorFragment {
|
||||
static fromString(value: string): FunctionFragment;
|
||||
static isFunctionFragment(value: any): value is FunctionFragment;
|
||||
}
|
||||
export declare class ErrorFragment extends Fragment {
|
||||
format(format?: string): string;
|
||||
static from(value: ErrorFragment | JsonFragment | string): ErrorFragment;
|
||||
static fromObject(value: ErrorFragment | JsonFragment): ErrorFragment;
|
||||
static fromString(value: string): ErrorFragment;
|
||||
static isErrorFragment(value: any): value is ErrorFragment;
|
||||
}
|
||||
//# sourceMappingURL=fragments.d.ts.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"fragments.d.ts","sourceRoot":"","sources":["../src.ts/fragments.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"fragments.d.ts","sourceRoot":"","sources":["../src.ts/fragments.ts"],"names":[],"mappings":"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"}
|
||||
@@ -354,6 +354,8 @@ export class Fragment {
|
||||
return EventFragment.fromObject(value);
|
||||
case "constructor":
|
||||
return ConstructorFragment.fromObject(value);
|
||||
case "error":
|
||||
return ErrorFragment.fromObject(value);
|
||||
case "fallback":
|
||||
case "receive":
|
||||
// @TODO: Something? Maybe return a FunctionFragment? A custom DefaultFunctionFragment?
|
||||
@@ -375,6 +377,9 @@ export class Fragment {
|
||||
else if (value.split("(")[0].trim() === "constructor") {
|
||||
return ConstructorFragment.fromString(value.trim());
|
||||
}
|
||||
else if (value.split(" ")[0] === "error") {
|
||||
return ErrorFragment.fromString(value.substring(5).trim());
|
||||
}
|
||||
return logger.throwArgumentError("unsupported fragment", "value", value);
|
||||
}
|
||||
static isFragment(value) {
|
||||
@@ -730,10 +735,74 @@ export class FunctionFragment extends ConstructorFragment {
|
||||
return (value && value._isFragment && value.type === "function");
|
||||
}
|
||||
}
|
||||
//export class ErrorFragment extends Fragment {
|
||||
//}
|
||||
//export class StructFragment extends Fragment {
|
||||
//}
|
||||
function checkForbidden(fragment) {
|
||||
const sig = fragment.format();
|
||||
if (sig === "Error(string)" || sig === "Panic(uint256)") {
|
||||
logger.throwArgumentError(`cannot specify user defined ${sig} error`, "fragment", fragment);
|
||||
}
|
||||
return fragment;
|
||||
}
|
||||
export class ErrorFragment extends Fragment {
|
||||
format(format) {
|
||||
if (!format) {
|
||||
format = FormatTypes.sighash;
|
||||
}
|
||||
if (!FormatTypes[format]) {
|
||||
logger.throwArgumentError("invalid format type", "format", format);
|
||||
}
|
||||
if (format === FormatTypes.json) {
|
||||
return JSON.stringify({
|
||||
type: "error",
|
||||
name: this.name,
|
||||
inputs: this.inputs.map((input) => JSON.parse(input.format(format))),
|
||||
});
|
||||
}
|
||||
let result = "";
|
||||
if (format !== FormatTypes.sighash) {
|
||||
result += "error ";
|
||||
}
|
||||
result += this.name + "(" + this.inputs.map((input) => input.format(format)).join((format === FormatTypes.full) ? ", " : ",") + ") ";
|
||||
return result.trim();
|
||||
}
|
||||
static from(value) {
|
||||
if (typeof (value) === "string") {
|
||||
return ErrorFragment.fromString(value);
|
||||
}
|
||||
return ErrorFragment.fromObject(value);
|
||||
}
|
||||
static fromObject(value) {
|
||||
if (ErrorFragment.isErrorFragment(value)) {
|
||||
return value;
|
||||
}
|
||||
if (value.type !== "error") {
|
||||
logger.throwArgumentError("invalid error object", "value", value);
|
||||
}
|
||||
const params = {
|
||||
type: value.type,
|
||||
name: verifyIdentifier(value.name),
|
||||
inputs: (value.inputs ? value.inputs.map(ParamType.fromObject) : [])
|
||||
};
|
||||
return checkForbidden(new ErrorFragment(_constructorGuard, params));
|
||||
}
|
||||
static fromString(value) {
|
||||
let params = { type: "error" };
|
||||
let parens = value.match(regexParen);
|
||||
if (!parens) {
|
||||
logger.throwArgumentError("invalid error signature", "value", value);
|
||||
}
|
||||
params.name = parens[1].trim();
|
||||
if (params.name) {
|
||||
verifyIdentifier(params.name);
|
||||
}
|
||||
params.inputs = parseParams(parens[2], false);
|
||||
return checkForbidden(ErrorFragment.fromObject(params));
|
||||
}
|
||||
static isErrorFragment(value) {
|
||||
return (value && value._isFragment && value.type === "error");
|
||||
}
|
||||
}
|
||||
function verifyType(type) {
|
||||
// These need to be transformed to their full description
|
||||
if (type.match(/^uint($|[^1-9])/)) {
|
||||
@@ -745,7 +814,8 @@ function verifyType(type) {
|
||||
// @TODO: more verification
|
||||
return type;
|
||||
}
|
||||
const regexIdentifier = new RegExp("^[A-Za-z_][A-Za-z0-9_]*$");
|
||||
// See: https://github.com/ethereum/solidity/blob/1f8f1a3db93a548d0555e3e14cfc55a10e25b60e/docs/grammar/SolidityLexer.g4#L234
|
||||
const regexIdentifier = new RegExp("^[a-zA-Z$_][a-zA-Z0-9$_]*$");
|
||||
function verifyIdentifier(value) {
|
||||
if (!value || !value.match(regexIdentifier)) {
|
||||
logger.throwArgumentError(`invalid identifier "${value}"`, "value", value);
|
||||
|
||||
File diff suppressed because one or more lines are too long
4
packages/abi/lib.esm/index.d.ts
vendored
4
packages/abi/lib.esm/index.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import { ConstructorFragment, EventFragment, FormatTypes, Fragment, FunctionFragment, JsonFragment, JsonFragmentType, ParamType } from "./fragments";
|
||||
import { ConstructorFragment, ErrorFragment, EventFragment, FormatTypes, Fragment, FunctionFragment, JsonFragment, JsonFragmentType, ParamType } from "./fragments";
|
||||
import { AbiCoder, CoerceFunc, defaultAbiCoder } from "./abi-coder";
|
||||
import { checkResultErrors, Indexed, Interface, LogDescription, Result, TransactionDescription } from "./interface";
|
||||
export { ConstructorFragment, EventFragment, Fragment, FunctionFragment, ParamType, FormatTypes, AbiCoder, defaultAbiCoder, Interface, Indexed, CoerceFunc, JsonFragment, JsonFragmentType, Result, checkResultErrors, LogDescription, TransactionDescription };
|
||||
export { ConstructorFragment, ErrorFragment, EventFragment, Fragment, FunctionFragment, ParamType, FormatTypes, AbiCoder, defaultAbiCoder, Interface, Indexed, CoerceFunc, JsonFragment, JsonFragmentType, Result, checkResultErrors, LogDescription, TransactionDescription };
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACrJ,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEpH,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,WAAW,EAEX,QAAQ,EACR,eAAe,EAEf,SAAS,EACT,OAAO,EAKP,UAAU,EACV,YAAY,EACZ,gBAAgB,EAEhB,MAAM,EACN,iBAAiB,EAEjB,cAAc,EACd,sBAAsB,EACzB,CAAC"}
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACpK,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEpH,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,WAAW,EAEX,QAAQ,EACR,eAAe,EAEf,SAAS,EACT,OAAO,EAKP,UAAU,EACV,YAAY,EACZ,gBAAgB,EAEhB,MAAM,EACN,iBAAiB,EAEjB,cAAc,EACd,sBAAsB,EACzB,CAAC"}
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
import { ConstructorFragment, EventFragment, FormatTypes, Fragment, FunctionFragment, ParamType } from "./fragments";
|
||||
import { ConstructorFragment, ErrorFragment, EventFragment, FormatTypes, Fragment, FunctionFragment, ParamType } from "./fragments";
|
||||
import { AbiCoder, defaultAbiCoder } from "./abi-coder";
|
||||
import { checkResultErrors, Indexed, Interface, LogDescription, TransactionDescription } from "./interface";
|
||||
export { ConstructorFragment, EventFragment, Fragment, FunctionFragment, ParamType, FormatTypes, AbiCoder, defaultAbiCoder, Interface, Indexed, checkResultErrors, LogDescription, TransactionDescription };
|
||||
export { ConstructorFragment, ErrorFragment, EventFragment, Fragment, FunctionFragment, ParamType, FormatTypes, AbiCoder, defaultAbiCoder, Interface, Indexed, checkResultErrors, LogDescription, TransactionDescription };
|
||||
//# sourceMappingURL=index.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAkC,SAAS,EAAE,MAAM,aAAa,CAAC;AACrJ,OAAO,EAAE,QAAQ,EAAc,eAAe,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAU,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEpH,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,WAAW,EAEX,QAAQ,EACR,eAAe,EAEf,SAAS,EACT,OAAO,EAUP,iBAAiB,EAEjB,cAAc,EACd,sBAAsB,EACzB,CAAC"}
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAkC,SAAS,EAAE,MAAM,aAAa,CAAC;AACpK,OAAO,EAAE,QAAQ,EAAc,eAAe,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAU,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEpH,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,WAAW,EAEX,QAAQ,EACR,eAAe,EAEf,SAAS,EACT,OAAO,EAUP,iBAAiB,EAEjB,cAAc,EACd,sBAAsB,EACzB,CAAC"}
|
||||
19
packages/abi/lib.esm/interface.d.ts
vendored
19
packages/abi/lib.esm/interface.d.ts
vendored
@@ -3,7 +3,7 @@ import { BytesLike } from "@ethersproject/bytes";
|
||||
import { Description } from "@ethersproject/properties";
|
||||
import { AbiCoder } from "./abi-coder";
|
||||
import { checkResultErrors, Result } from "./coders/abstract-coder";
|
||||
import { ConstructorFragment, EventFragment, Fragment, FunctionFragment, JsonFragment, ParamType } from "./fragments";
|
||||
import { ConstructorFragment, ErrorFragment, EventFragment, Fragment, FunctionFragment, JsonFragment, ParamType } from "./fragments";
|
||||
export { checkResultErrors, Result };
|
||||
export declare class LogDescription extends Description<LogDescription> {
|
||||
readonly eventFragment: EventFragment;
|
||||
@@ -20,6 +20,13 @@ export declare class TransactionDescription extends Description<TransactionDescr
|
||||
readonly sighash: string;
|
||||
readonly value: BigNumber;
|
||||
}
|
||||
export declare class ErrorDescription extends Description<ErrorDescription> {
|
||||
readonly errorFragment: ErrorFragment;
|
||||
readonly name: string;
|
||||
readonly args: Result;
|
||||
readonly signature: string;
|
||||
readonly sighash: string;
|
||||
}
|
||||
export declare class Indexed extends Description<Indexed> {
|
||||
readonly hash: string;
|
||||
readonly _isIndexed: boolean;
|
||||
@@ -28,7 +35,7 @@ export declare class Indexed extends Description<Indexed> {
|
||||
export declare class Interface {
|
||||
readonly fragments: ReadonlyArray<Fragment>;
|
||||
readonly errors: {
|
||||
[name: string]: any;
|
||||
[name: string]: ErrorFragment;
|
||||
};
|
||||
readonly events: {
|
||||
[name: string]: EventFragment;
|
||||
@@ -46,15 +53,18 @@ export declare class Interface {
|
||||
format(format?: string): string | Array<string>;
|
||||
static getAbiCoder(): AbiCoder;
|
||||
static getAddress(address: string): string;
|
||||
static getSighash(functionFragment: FunctionFragment): string;
|
||||
static getSighash(fragment: ErrorFragment | FunctionFragment): string;
|
||||
static getEventTopic(eventFragment: EventFragment): string;
|
||||
getFunction(nameOrSignatureOrSighash: string): FunctionFragment;
|
||||
getEvent(nameOrSignatureOrTopic: string): EventFragment;
|
||||
getSighash(functionFragment: FunctionFragment | string): string;
|
||||
getError(nameOrSignatureOrSighash: string): ErrorFragment;
|
||||
getSighash(fragment: ErrorFragment | FunctionFragment | string): string;
|
||||
getEventTopic(eventFragment: EventFragment | string): string;
|
||||
_decodeParams(params: ReadonlyArray<ParamType>, data: BytesLike): Result;
|
||||
_encodeParams(params: ReadonlyArray<ParamType>, values: ReadonlyArray<any>): string;
|
||||
encodeDeploy(values?: ReadonlyArray<any>): string;
|
||||
decodeErrorResult(fragment: ErrorFragment | string, data: BytesLike): Result;
|
||||
encodeErrorResult(fragment: ErrorFragment | string, values?: ReadonlyArray<any>): string;
|
||||
decodeFunctionData(functionFragment: FunctionFragment | string, data: BytesLike): Result;
|
||||
encodeFunctionData(functionFragment: FunctionFragment | string, values?: ReadonlyArray<any>): string;
|
||||
decodeFunctionResult(functionFragment: FunctionFragment | string, data: BytesLike): Result;
|
||||
@@ -73,6 +83,7 @@ export declare class Interface {
|
||||
topics: Array<string>;
|
||||
data: string;
|
||||
}): LogDescription;
|
||||
parseError(data: BytesLike): ErrorDescription;
|
||||
static isInterface(value: any): value is Interface;
|
||||
}
|
||||
//# sourceMappingURL=interface.d.ts.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../src.ts/interface.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../src.ts/interface.ts"],"names":[],"mappings":"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"}
|
||||
@@ -16,11 +16,17 @@ export class LogDescription extends Description {
|
||||
}
|
||||
export class TransactionDescription extends Description {
|
||||
}
|
||||
export class ErrorDescription extends Description {
|
||||
}
|
||||
export class Indexed extends Description {
|
||||
static isIndexed(value) {
|
||||
return !!(value && value._isIndexed);
|
||||
}
|
||||
}
|
||||
const BuiltinErrors = {
|
||||
"0x08c379a0": { signature: "Error(string)", name: "Error", inputs: ["string"], reason: true },
|
||||
"0x4e487b71": { signature: "Panic(uint256)", name: "Panic", inputs: ["uint256"] }
|
||||
};
|
||||
function wrapAccessError(property, error) {
|
||||
const wrap = new Error(`deferred error during ABI decoding triggered accessing ${property}`);
|
||||
wrap.error = error;
|
||||
@@ -78,6 +84,9 @@ export class Interface {
|
||||
//checkNames(fragment, "input", fragment.inputs);
|
||||
bucket = this.events;
|
||||
break;
|
||||
case "error":
|
||||
bucket = this.errors;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -118,8 +127,8 @@ export class Interface {
|
||||
static getAddress(address) {
|
||||
return getAddress(address);
|
||||
}
|
||||
static getSighash(functionFragment) {
|
||||
return hexDataSlice(id(functionFragment.format()), 0, 4);
|
||||
static getSighash(fragment) {
|
||||
return hexDataSlice(id(fragment.format()), 0, 4);
|
||||
}
|
||||
static getEventTopic(eventFragment) {
|
||||
return id(eventFragment.format());
|
||||
@@ -183,12 +192,53 @@ export class Interface {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// Get the sighash (the bytes4 selector) used by Solidity to identify a function
|
||||
getSighash(functionFragment) {
|
||||
if (typeof (functionFragment) === "string") {
|
||||
functionFragment = this.getFunction(functionFragment);
|
||||
// Find a function definition by any means necessary (unless it is ambiguous)
|
||||
getError(nameOrSignatureOrSighash) {
|
||||
if (isHexString(nameOrSignatureOrSighash)) {
|
||||
const getSighash = getStatic(this.constructor, "getSighash");
|
||||
for (const name in this.errors) {
|
||||
const error = this.errors[name];
|
||||
if (nameOrSignatureOrSighash === getSighash(error)) {
|
||||
return this.errors[name];
|
||||
}
|
||||
}
|
||||
logger.throwArgumentError("no matching error", "sighash", nameOrSignatureOrSighash);
|
||||
}
|
||||
return getStatic(this.constructor, "getSighash")(functionFragment);
|
||||
// It is a bare name, look up the function (will return null if ambiguous)
|
||||
if (nameOrSignatureOrSighash.indexOf("(") === -1) {
|
||||
const name = nameOrSignatureOrSighash.trim();
|
||||
const matching = Object.keys(this.errors).filter((f) => (f.split("(" /* fix:) */)[0] === name));
|
||||
if (matching.length === 0) {
|
||||
logger.throwArgumentError("no matching error", "name", name);
|
||||
}
|
||||
else if (matching.length > 1) {
|
||||
logger.throwArgumentError("multiple matching errors", "name", name);
|
||||
}
|
||||
return this.errors[matching[0]];
|
||||
}
|
||||
// Normlize the signature and lookup the function
|
||||
const result = this.errors[FunctionFragment.fromString(nameOrSignatureOrSighash).format()];
|
||||
if (!result) {
|
||||
logger.throwArgumentError("no matching error", "signature", nameOrSignatureOrSighash);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// Get the sighash (the bytes4 selector) used by Solidity to identify a function
|
||||
getSighash(fragment) {
|
||||
if (typeof (fragment) === "string") {
|
||||
try {
|
||||
fragment = this.getFunction(fragment);
|
||||
}
|
||||
catch (error) {
|
||||
try {
|
||||
fragment = this.getError(fragment);
|
||||
}
|
||||
catch (_) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
return getStatic(this.constructor, "getSighash")(fragment);
|
||||
}
|
||||
// Get the topic (the bytes32 hash) used by Solidity to identify an event
|
||||
getEventTopic(eventFragment) {
|
||||
@@ -206,6 +256,25 @@ export class Interface {
|
||||
encodeDeploy(values) {
|
||||
return this._encodeParams(this.deploy.inputs, values || []);
|
||||
}
|
||||
decodeErrorResult(fragment, data) {
|
||||
if (typeof (fragment) === "string") {
|
||||
fragment = this.getError(fragment);
|
||||
}
|
||||
const bytes = arrayify(data);
|
||||
if (hexlify(bytes.slice(0, 4)) !== this.getSighash(fragment)) {
|
||||
logger.throwArgumentError(`data signature does not match error ${fragment.name}.`, "data", hexlify(bytes));
|
||||
}
|
||||
return this._decodeParams(fragment.inputs, bytes.slice(4));
|
||||
}
|
||||
encodeErrorResult(fragment, values) {
|
||||
if (typeof (fragment) === "string") {
|
||||
fragment = this.getError(fragment);
|
||||
}
|
||||
return hexlify(concat([
|
||||
this.getSighash(fragment),
|
||||
this._encodeParams(fragment.inputs, values || [])
|
||||
]));
|
||||
}
|
||||
// Decode the data for a function call (e.g. tx.data)
|
||||
decodeFunctionData(functionFragment, data) {
|
||||
if (typeof (functionFragment) === "string") {
|
||||
@@ -234,6 +303,8 @@ export class Interface {
|
||||
}
|
||||
let bytes = arrayify(data);
|
||||
let reason = null;
|
||||
let errorArgs = null;
|
||||
let errorName = null;
|
||||
let errorSignature = null;
|
||||
switch (bytes.length % this._abiCoder._getWordSize()) {
|
||||
case 0:
|
||||
@@ -242,18 +313,34 @@ export class Interface {
|
||||
}
|
||||
catch (error) { }
|
||||
break;
|
||||
case 4:
|
||||
if (hexlify(bytes.slice(0, 4)) === "0x08c379a0") {
|
||||
errorSignature = "Error(string)";
|
||||
reason = this._abiCoder.decode(["string"], bytes.slice(4))[0];
|
||||
case 4: {
|
||||
const selector = hexlify(bytes.slice(0, 4));
|
||||
const builtin = BuiltinErrors[selector];
|
||||
if (builtin) {
|
||||
errorArgs = this._abiCoder.decode(builtin.inputs, bytes.slice(4));
|
||||
errorName = builtin.name;
|
||||
errorSignature = builtin.signature;
|
||||
if (builtin.reason) {
|
||||
reason = errorArgs[0];
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
const error = this.getError(selector);
|
||||
errorArgs = this._abiCoder.decode(error.inputs, bytes.slice(4));
|
||||
errorName = error.name;
|
||||
errorSignature = error.format();
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return logger.throwError("call revert exception", Logger.errors.CALL_EXCEPTION, {
|
||||
method: functionFragment.format(),
|
||||
errorSignature: errorSignature,
|
||||
errorArgs: [reason],
|
||||
reason: reason
|
||||
errorArgs, errorName, errorSignature, reason
|
||||
});
|
||||
}
|
||||
// Encode the result for a function call (e.g. for eth_call)
|
||||
@@ -459,6 +546,8 @@ export class Interface {
|
||||
value: BigNumber.from(tx.value || "0"),
|
||||
});
|
||||
}
|
||||
// @TODO
|
||||
//parseCallResult(data: BytesLike): ??
|
||||
// Given an event log, find the matching event fragment (if any) and
|
||||
// determine all its properties and values
|
||||
parseLog(log) {
|
||||
@@ -477,6 +566,20 @@ export class Interface {
|
||||
args: this.decodeEventLog(fragment, log.data, log.topics)
|
||||
});
|
||||
}
|
||||
parseError(data) {
|
||||
const hexData = hexlify(data);
|
||||
let fragment = this.getError(hexData.substring(0, 10).toLowerCase());
|
||||
if (!fragment) {
|
||||
return null;
|
||||
}
|
||||
return new ErrorDescription({
|
||||
args: this._abiCoder.decode(fragment.inputs, "0x" + hexData.substring(10)),
|
||||
errorFragment: fragment,
|
||||
name: fragment.name,
|
||||
signature: fragment.format(),
|
||||
sighash: this.getSighash(fragment),
|
||||
});
|
||||
}
|
||||
/*
|
||||
static from(value: Array<Fragment | string | JsonAbi> | string | Interface) {
|
||||
if (Interface.isInterface(value)) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
packages/abi/lib/_version.d.ts
vendored
2
packages/abi/lib/_version.d.ts
vendored
@@ -1,2 +1,2 @@
|
||||
export declare const version = "abi/5.1.1";
|
||||
export declare const version = "abi/5.4.0";
|
||||
//# sourceMappingURL=_version.d.ts.map
|
||||
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.version = void 0;
|
||||
exports.version = "abi/5.1.1";
|
||||
exports.version = "abi/5.4.0";
|
||||
//# sourceMappingURL=_version.js.map
|
||||
8
packages/abi/lib/fragments.d.ts
vendored
8
packages/abi/lib/fragments.d.ts
vendored
@@ -3,6 +3,7 @@ export interface JsonFragmentType {
|
||||
readonly name?: string;
|
||||
readonly indexed?: boolean;
|
||||
readonly type?: string;
|
||||
readonly internalType?: any;
|
||||
readonly components?: ReadonlyArray<JsonFragmentType>;
|
||||
}
|
||||
export interface JsonFragment {
|
||||
@@ -74,4 +75,11 @@ export declare class FunctionFragment extends ConstructorFragment {
|
||||
static fromString(value: string): FunctionFragment;
|
||||
static isFunctionFragment(value: any): value is FunctionFragment;
|
||||
}
|
||||
export declare class ErrorFragment extends Fragment {
|
||||
format(format?: string): string;
|
||||
static from(value: ErrorFragment | JsonFragment | string): ErrorFragment;
|
||||
static fromObject(value: ErrorFragment | JsonFragment): ErrorFragment;
|
||||
static fromString(value: string): ErrorFragment;
|
||||
static isErrorFragment(value: any): value is ErrorFragment;
|
||||
}
|
||||
//# sourceMappingURL=fragments.d.ts.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"fragments.d.ts","sourceRoot":"","sources":["../src.ts/fragments.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"fragments.d.ts","sourceRoot":"","sources":["../src.ts/fragments.ts"],"names":[],"mappings":"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"}
|
||||
@@ -15,7 +15,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FunctionFragment = exports.ConstructorFragment = exports.EventFragment = exports.Fragment = exports.ParamType = exports.FormatTypes = void 0;
|
||||
exports.ErrorFragment = exports.FunctionFragment = exports.ConstructorFragment = exports.EventFragment = exports.Fragment = exports.ParamType = exports.FormatTypes = void 0;
|
||||
var bignumber_1 = require("@ethersproject/bignumber");
|
||||
var properties_1 = require("@ethersproject/properties");
|
||||
var logger_1 = require("@ethersproject/logger");
|
||||
@@ -373,6 +373,8 @@ var Fragment = /** @class */ (function () {
|
||||
return EventFragment.fromObject(value);
|
||||
case "constructor":
|
||||
return ConstructorFragment.fromObject(value);
|
||||
case "error":
|
||||
return ErrorFragment.fromObject(value);
|
||||
case "fallback":
|
||||
case "receive":
|
||||
// @TODO: Something? Maybe return a FunctionFragment? A custom DefaultFunctionFragment?
|
||||
@@ -394,6 +396,9 @@ var Fragment = /** @class */ (function () {
|
||||
else if (value.split("(")[0].trim() === "constructor") {
|
||||
return ConstructorFragment.fromString(value.trim());
|
||||
}
|
||||
else if (value.split(" ")[0] === "error") {
|
||||
return ErrorFragment.fromString(value.substring(5).trim());
|
||||
}
|
||||
return logger.throwArgumentError("unsupported fragment", "value", value);
|
||||
};
|
||||
Fragment.isFragment = function (value) {
|
||||
@@ -769,10 +774,80 @@ var FunctionFragment = /** @class */ (function (_super) {
|
||||
return FunctionFragment;
|
||||
}(ConstructorFragment));
|
||||
exports.FunctionFragment = FunctionFragment;
|
||||
//export class ErrorFragment extends Fragment {
|
||||
//}
|
||||
//export class StructFragment extends Fragment {
|
||||
//}
|
||||
function checkForbidden(fragment) {
|
||||
var sig = fragment.format();
|
||||
if (sig === "Error(string)" || sig === "Panic(uint256)") {
|
||||
logger.throwArgumentError("cannot specify user defined " + sig + " error", "fragment", fragment);
|
||||
}
|
||||
return fragment;
|
||||
}
|
||||
var ErrorFragment = /** @class */ (function (_super) {
|
||||
__extends(ErrorFragment, _super);
|
||||
function ErrorFragment() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
ErrorFragment.prototype.format = function (format) {
|
||||
if (!format) {
|
||||
format = exports.FormatTypes.sighash;
|
||||
}
|
||||
if (!exports.FormatTypes[format]) {
|
||||
logger.throwArgumentError("invalid format type", "format", format);
|
||||
}
|
||||
if (format === exports.FormatTypes.json) {
|
||||
return JSON.stringify({
|
||||
type: "error",
|
||||
name: this.name,
|
||||
inputs: this.inputs.map(function (input) { return JSON.parse(input.format(format)); }),
|
||||
});
|
||||
}
|
||||
var result = "";
|
||||
if (format !== exports.FormatTypes.sighash) {
|
||||
result += "error ";
|
||||
}
|
||||
result += this.name + "(" + this.inputs.map(function (input) { return input.format(format); }).join((format === exports.FormatTypes.full) ? ", " : ",") + ") ";
|
||||
return result.trim();
|
||||
};
|
||||
ErrorFragment.from = function (value) {
|
||||
if (typeof (value) === "string") {
|
||||
return ErrorFragment.fromString(value);
|
||||
}
|
||||
return ErrorFragment.fromObject(value);
|
||||
};
|
||||
ErrorFragment.fromObject = function (value) {
|
||||
if (ErrorFragment.isErrorFragment(value)) {
|
||||
return value;
|
||||
}
|
||||
if (value.type !== "error") {
|
||||
logger.throwArgumentError("invalid error object", "value", value);
|
||||
}
|
||||
var params = {
|
||||
type: value.type,
|
||||
name: verifyIdentifier(value.name),
|
||||
inputs: (value.inputs ? value.inputs.map(ParamType.fromObject) : [])
|
||||
};
|
||||
return checkForbidden(new ErrorFragment(_constructorGuard, params));
|
||||
};
|
||||
ErrorFragment.fromString = function (value) {
|
||||
var params = { type: "error" };
|
||||
var parens = value.match(regexParen);
|
||||
if (!parens) {
|
||||
logger.throwArgumentError("invalid error signature", "value", value);
|
||||
}
|
||||
params.name = parens[1].trim();
|
||||
if (params.name) {
|
||||
verifyIdentifier(params.name);
|
||||
}
|
||||
params.inputs = parseParams(parens[2], false);
|
||||
return checkForbidden(ErrorFragment.fromObject(params));
|
||||
};
|
||||
ErrorFragment.isErrorFragment = function (value) {
|
||||
return (value && value._isFragment && value.type === "error");
|
||||
};
|
||||
return ErrorFragment;
|
||||
}(Fragment));
|
||||
exports.ErrorFragment = ErrorFragment;
|
||||
function verifyType(type) {
|
||||
// These need to be transformed to their full description
|
||||
if (type.match(/^uint($|[^1-9])/)) {
|
||||
@@ -784,7 +859,8 @@ function verifyType(type) {
|
||||
// @TODO: more verification
|
||||
return type;
|
||||
}
|
||||
var regexIdentifier = new RegExp("^[A-Za-z_][A-Za-z0-9_]*$");
|
||||
// See: https://github.com/ethereum/solidity/blob/1f8f1a3db93a548d0555e3e14cfc55a10e25b60e/docs/grammar/SolidityLexer.g4#L234
|
||||
var regexIdentifier = new RegExp("^[a-zA-Z$_][a-zA-Z0-9$_]*$");
|
||||
function verifyIdentifier(value) {
|
||||
if (!value || !value.match(regexIdentifier)) {
|
||||
logger.throwArgumentError("invalid identifier \"" + value + "\"", "value", value);
|
||||
|
||||
File diff suppressed because one or more lines are too long
4
packages/abi/lib/index.d.ts
vendored
4
packages/abi/lib/index.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import { ConstructorFragment, EventFragment, FormatTypes, Fragment, FunctionFragment, JsonFragment, JsonFragmentType, ParamType } from "./fragments";
|
||||
import { ConstructorFragment, ErrorFragment, EventFragment, FormatTypes, Fragment, FunctionFragment, JsonFragment, JsonFragmentType, ParamType } from "./fragments";
|
||||
import { AbiCoder, CoerceFunc, defaultAbiCoder } from "./abi-coder";
|
||||
import { checkResultErrors, Indexed, Interface, LogDescription, Result, TransactionDescription } from "./interface";
|
||||
export { ConstructorFragment, EventFragment, Fragment, FunctionFragment, ParamType, FormatTypes, AbiCoder, defaultAbiCoder, Interface, Indexed, CoerceFunc, JsonFragment, JsonFragmentType, Result, checkResultErrors, LogDescription, TransactionDescription };
|
||||
export { ConstructorFragment, ErrorFragment, EventFragment, Fragment, FunctionFragment, ParamType, FormatTypes, AbiCoder, defaultAbiCoder, Interface, Indexed, CoerceFunc, JsonFragment, JsonFragmentType, Result, checkResultErrors, LogDescription, TransactionDescription };
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACrJ,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEpH,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,WAAW,EAEX,QAAQ,EACR,eAAe,EAEf,SAAS,EACT,OAAO,EAKP,UAAU,EACV,YAAY,EACZ,gBAAgB,EAEhB,MAAM,EACN,iBAAiB,EAEjB,cAAc,EACd,sBAAsB,EACzB,CAAC"}
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACpK,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEpH,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,WAAW,EAEX,QAAQ,EACR,eAAe,EAEf,SAAS,EACT,OAAO,EAKP,UAAU,EACV,YAAY,EACZ,gBAAgB,EAEhB,MAAM,EACN,iBAAiB,EAEjB,cAAc,EACd,sBAAsB,EACzB,CAAC"}
|
||||
@@ -1,8 +1,9 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TransactionDescription = exports.LogDescription = exports.checkResultErrors = exports.Indexed = exports.Interface = exports.defaultAbiCoder = exports.AbiCoder = exports.FormatTypes = exports.ParamType = exports.FunctionFragment = exports.Fragment = exports.EventFragment = exports.ConstructorFragment = void 0;
|
||||
exports.TransactionDescription = exports.LogDescription = exports.checkResultErrors = exports.Indexed = exports.Interface = exports.defaultAbiCoder = exports.AbiCoder = exports.FormatTypes = exports.ParamType = exports.FunctionFragment = exports.Fragment = exports.EventFragment = exports.ErrorFragment = exports.ConstructorFragment = void 0;
|
||||
var fragments_1 = require("./fragments");
|
||||
Object.defineProperty(exports, "ConstructorFragment", { enumerable: true, get: function () { return fragments_1.ConstructorFragment; } });
|
||||
Object.defineProperty(exports, "ErrorFragment", { enumerable: true, get: function () { return fragments_1.ErrorFragment; } });
|
||||
Object.defineProperty(exports, "EventFragment", { enumerable: true, get: function () { return fragments_1.EventFragment; } });
|
||||
Object.defineProperty(exports, "FormatTypes", { enumerable: true, get: function () { return fragments_1.FormatTypes; } });
|
||||
Object.defineProperty(exports, "Fragment", { enumerable: true, get: function () { return fragments_1.Fragment; } });
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb,yCAAqJ;AAKjJ,oGALK,+BAAmB,OAKL;AACnB,8FAN0B,yBAAa,OAM1B;AAIb,4FAVyC,uBAAW,OAUzC;AAHX,yFAPsD,oBAAQ,OAOtD;AACR,iGARgE,4BAAgB,OAQhE;AAChB,0FATkH,qBAAS,OASlH;AARb,yCAAoE;AAWhE,yFAXK,oBAAQ,OAWL;AACR,gGAZ2B,2BAAe,OAY3B;AAXnB,yCAAoH;AAwBhH,kGAxBK,6BAAiB,OAwBL;AAVjB,wFAdwB,mBAAO,OAcxB;AADP,0FAbiC,qBAAS,OAajC;AAaT,+FA1B4C,0BAAc,OA0B5C;AACd,uGA3BoE,kCAAsB,OA2BpE"}
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb,yCAAoK;AAKhK,oGALK,+BAAmB,OAKL;AACnB,8FAN0B,yBAAa,OAM1B;AACb,8FAPyC,yBAAa,OAOzC;AAIb,4FAXwD,uBAAW,OAWxD;AAHX,yFARqE,oBAAQ,OAQrE;AACR,iGAT+E,4BAAgB,OAS/E;AAChB,0FAViI,qBAAS,OAUjI;AATb,yCAAoE;AAYhE,yFAZK,oBAAQ,OAYL;AACR,gGAb2B,2BAAe,OAa3B;AAZnB,yCAAoH;AAyBhH,kGAzBK,6BAAiB,OAyBL;AAVjB,wFAfwB,mBAAO,OAexB;AADP,0FAdiC,qBAAS,OAcjC;AAaT,+FA3B4C,0BAAc,OA2B5C;AACd,uGA5BoE,kCAAsB,OA4BpE"}
|
||||
19
packages/abi/lib/interface.d.ts
vendored
19
packages/abi/lib/interface.d.ts
vendored
@@ -3,7 +3,7 @@ import { BytesLike } from "@ethersproject/bytes";
|
||||
import { Description } from "@ethersproject/properties";
|
||||
import { AbiCoder } from "./abi-coder";
|
||||
import { checkResultErrors, Result } from "./coders/abstract-coder";
|
||||
import { ConstructorFragment, EventFragment, Fragment, FunctionFragment, JsonFragment, ParamType } from "./fragments";
|
||||
import { ConstructorFragment, ErrorFragment, EventFragment, Fragment, FunctionFragment, JsonFragment, ParamType } from "./fragments";
|
||||
export { checkResultErrors, Result };
|
||||
export declare class LogDescription extends Description<LogDescription> {
|
||||
readonly eventFragment: EventFragment;
|
||||
@@ -20,6 +20,13 @@ export declare class TransactionDescription extends Description<TransactionDescr
|
||||
readonly sighash: string;
|
||||
readonly value: BigNumber;
|
||||
}
|
||||
export declare class ErrorDescription extends Description<ErrorDescription> {
|
||||
readonly errorFragment: ErrorFragment;
|
||||
readonly name: string;
|
||||
readonly args: Result;
|
||||
readonly signature: string;
|
||||
readonly sighash: string;
|
||||
}
|
||||
export declare class Indexed extends Description<Indexed> {
|
||||
readonly hash: string;
|
||||
readonly _isIndexed: boolean;
|
||||
@@ -28,7 +35,7 @@ export declare class Indexed extends Description<Indexed> {
|
||||
export declare class Interface {
|
||||
readonly fragments: ReadonlyArray<Fragment>;
|
||||
readonly errors: {
|
||||
[name: string]: any;
|
||||
[name: string]: ErrorFragment;
|
||||
};
|
||||
readonly events: {
|
||||
[name: string]: EventFragment;
|
||||
@@ -46,15 +53,18 @@ export declare class Interface {
|
||||
format(format?: string): string | Array<string>;
|
||||
static getAbiCoder(): AbiCoder;
|
||||
static getAddress(address: string): string;
|
||||
static getSighash(functionFragment: FunctionFragment): string;
|
||||
static getSighash(fragment: ErrorFragment | FunctionFragment): string;
|
||||
static getEventTopic(eventFragment: EventFragment): string;
|
||||
getFunction(nameOrSignatureOrSighash: string): FunctionFragment;
|
||||
getEvent(nameOrSignatureOrTopic: string): EventFragment;
|
||||
getSighash(functionFragment: FunctionFragment | string): string;
|
||||
getError(nameOrSignatureOrSighash: string): ErrorFragment;
|
||||
getSighash(fragment: ErrorFragment | FunctionFragment | string): string;
|
||||
getEventTopic(eventFragment: EventFragment | string): string;
|
||||
_decodeParams(params: ReadonlyArray<ParamType>, data: BytesLike): Result;
|
||||
_encodeParams(params: ReadonlyArray<ParamType>, values: ReadonlyArray<any>): string;
|
||||
encodeDeploy(values?: ReadonlyArray<any>): string;
|
||||
decodeErrorResult(fragment: ErrorFragment | string, data: BytesLike): Result;
|
||||
encodeErrorResult(fragment: ErrorFragment | string, values?: ReadonlyArray<any>): string;
|
||||
decodeFunctionData(functionFragment: FunctionFragment | string, data: BytesLike): Result;
|
||||
encodeFunctionData(functionFragment: FunctionFragment | string, values?: ReadonlyArray<any>): string;
|
||||
decodeFunctionResult(functionFragment: FunctionFragment | string, data: BytesLike): Result;
|
||||
@@ -73,6 +83,7 @@ export declare class Interface {
|
||||
topics: Array<string>;
|
||||
data: string;
|
||||
}): LogDescription;
|
||||
parseError(data: BytesLike): ErrorDescription;
|
||||
static isInterface(value: any): value is Interface;
|
||||
}
|
||||
//# sourceMappingURL=interface.d.ts.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../src.ts/interface.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../src.ts/interface.ts"],"names":[],"mappings":"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"}
|
||||
@@ -15,7 +15,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Interface = exports.Indexed = exports.TransactionDescription = exports.LogDescription = exports.checkResultErrors = void 0;
|
||||
exports.Interface = exports.Indexed = exports.ErrorDescription = exports.TransactionDescription = exports.LogDescription = exports.checkResultErrors = void 0;
|
||||
var address_1 = require("@ethersproject/address");
|
||||
var bignumber_1 = require("@ethersproject/bignumber");
|
||||
var bytes_1 = require("@ethersproject/bytes");
|
||||
@@ -45,6 +45,14 @@ var TransactionDescription = /** @class */ (function (_super) {
|
||||
return TransactionDescription;
|
||||
}(properties_1.Description));
|
||||
exports.TransactionDescription = TransactionDescription;
|
||||
var ErrorDescription = /** @class */ (function (_super) {
|
||||
__extends(ErrorDescription, _super);
|
||||
function ErrorDescription() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return ErrorDescription;
|
||||
}(properties_1.Description));
|
||||
exports.ErrorDescription = ErrorDescription;
|
||||
var Indexed = /** @class */ (function (_super) {
|
||||
__extends(Indexed, _super);
|
||||
function Indexed() {
|
||||
@@ -56,6 +64,10 @@ var Indexed = /** @class */ (function (_super) {
|
||||
return Indexed;
|
||||
}(properties_1.Description));
|
||||
exports.Indexed = Indexed;
|
||||
var BuiltinErrors = {
|
||||
"0x08c379a0": { signature: "Error(string)", name: "Error", inputs: ["string"], reason: true },
|
||||
"0x4e487b71": { signature: "Panic(uint256)", name: "Panic", inputs: ["uint256"] }
|
||||
};
|
||||
function wrapAccessError(property, error) {
|
||||
var wrap = new Error("deferred error during ABI decoding triggered accessing " + property);
|
||||
wrap.error = error;
|
||||
@@ -115,6 +127,9 @@ var Interface = /** @class */ (function () {
|
||||
//checkNames(fragment, "input", fragment.inputs);
|
||||
bucket = _this.events;
|
||||
break;
|
||||
case "error":
|
||||
bucket = _this.errors;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -155,8 +170,8 @@ var Interface = /** @class */ (function () {
|
||||
Interface.getAddress = function (address) {
|
||||
return address_1.getAddress(address);
|
||||
};
|
||||
Interface.getSighash = function (functionFragment) {
|
||||
return bytes_1.hexDataSlice(hash_1.id(functionFragment.format()), 0, 4);
|
||||
Interface.getSighash = function (fragment) {
|
||||
return bytes_1.hexDataSlice(hash_1.id(fragment.format()), 0, 4);
|
||||
};
|
||||
Interface.getEventTopic = function (eventFragment) {
|
||||
return hash_1.id(eventFragment.format());
|
||||
@@ -220,12 +235,53 @@ var Interface = /** @class */ (function () {
|
||||
}
|
||||
return result;
|
||||
};
|
||||
// Get the sighash (the bytes4 selector) used by Solidity to identify a function
|
||||
Interface.prototype.getSighash = function (functionFragment) {
|
||||
if (typeof (functionFragment) === "string") {
|
||||
functionFragment = this.getFunction(functionFragment);
|
||||
// Find a function definition by any means necessary (unless it is ambiguous)
|
||||
Interface.prototype.getError = function (nameOrSignatureOrSighash) {
|
||||
if (bytes_1.isHexString(nameOrSignatureOrSighash)) {
|
||||
var getSighash = properties_1.getStatic(this.constructor, "getSighash");
|
||||
for (var name_5 in this.errors) {
|
||||
var error = this.errors[name_5];
|
||||
if (nameOrSignatureOrSighash === getSighash(error)) {
|
||||
return this.errors[name_5];
|
||||
}
|
||||
}
|
||||
logger.throwArgumentError("no matching error", "sighash", nameOrSignatureOrSighash);
|
||||
}
|
||||
return properties_1.getStatic(this.constructor, "getSighash")(functionFragment);
|
||||
// It is a bare name, look up the function (will return null if ambiguous)
|
||||
if (nameOrSignatureOrSighash.indexOf("(") === -1) {
|
||||
var name_6 = nameOrSignatureOrSighash.trim();
|
||||
var matching = Object.keys(this.errors).filter(function (f) { return (f.split("(" /* fix:) */)[0] === name_6); });
|
||||
if (matching.length === 0) {
|
||||
logger.throwArgumentError("no matching error", "name", name_6);
|
||||
}
|
||||
else if (matching.length > 1) {
|
||||
logger.throwArgumentError("multiple matching errors", "name", name_6);
|
||||
}
|
||||
return this.errors[matching[0]];
|
||||
}
|
||||
// Normlize the signature and lookup the function
|
||||
var result = this.errors[fragments_1.FunctionFragment.fromString(nameOrSignatureOrSighash).format()];
|
||||
if (!result) {
|
||||
logger.throwArgumentError("no matching error", "signature", nameOrSignatureOrSighash);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
// Get the sighash (the bytes4 selector) used by Solidity to identify a function
|
||||
Interface.prototype.getSighash = function (fragment) {
|
||||
if (typeof (fragment) === "string") {
|
||||
try {
|
||||
fragment = this.getFunction(fragment);
|
||||
}
|
||||
catch (error) {
|
||||
try {
|
||||
fragment = this.getError(fragment);
|
||||
}
|
||||
catch (_) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
return properties_1.getStatic(this.constructor, "getSighash")(fragment);
|
||||
};
|
||||
// Get the topic (the bytes32 hash) used by Solidity to identify an event
|
||||
Interface.prototype.getEventTopic = function (eventFragment) {
|
||||
@@ -243,6 +299,25 @@ var Interface = /** @class */ (function () {
|
||||
Interface.prototype.encodeDeploy = function (values) {
|
||||
return this._encodeParams(this.deploy.inputs, values || []);
|
||||
};
|
||||
Interface.prototype.decodeErrorResult = function (fragment, data) {
|
||||
if (typeof (fragment) === "string") {
|
||||
fragment = this.getError(fragment);
|
||||
}
|
||||
var bytes = bytes_1.arrayify(data);
|
||||
if (bytes_1.hexlify(bytes.slice(0, 4)) !== this.getSighash(fragment)) {
|
||||
logger.throwArgumentError("data signature does not match error " + fragment.name + ".", "data", bytes_1.hexlify(bytes));
|
||||
}
|
||||
return this._decodeParams(fragment.inputs, bytes.slice(4));
|
||||
};
|
||||
Interface.prototype.encodeErrorResult = function (fragment, values) {
|
||||
if (typeof (fragment) === "string") {
|
||||
fragment = this.getError(fragment);
|
||||
}
|
||||
return bytes_1.hexlify(bytes_1.concat([
|
||||
this.getSighash(fragment),
|
||||
this._encodeParams(fragment.inputs, values || [])
|
||||
]));
|
||||
};
|
||||
// Decode the data for a function call (e.g. tx.data)
|
||||
Interface.prototype.decodeFunctionData = function (functionFragment, data) {
|
||||
if (typeof (functionFragment) === "string") {
|
||||
@@ -271,6 +346,8 @@ var Interface = /** @class */ (function () {
|
||||
}
|
||||
var bytes = bytes_1.arrayify(data);
|
||||
var reason = null;
|
||||
var errorArgs = null;
|
||||
var errorName = null;
|
||||
var errorSignature = null;
|
||||
switch (bytes.length % this._abiCoder._getWordSize()) {
|
||||
case 0:
|
||||
@@ -279,18 +356,34 @@ var Interface = /** @class */ (function () {
|
||||
}
|
||||
catch (error) { }
|
||||
break;
|
||||
case 4:
|
||||
if (bytes_1.hexlify(bytes.slice(0, 4)) === "0x08c379a0") {
|
||||
errorSignature = "Error(string)";
|
||||
reason = this._abiCoder.decode(["string"], bytes.slice(4))[0];
|
||||
case 4: {
|
||||
var selector = bytes_1.hexlify(bytes.slice(0, 4));
|
||||
var builtin = BuiltinErrors[selector];
|
||||
if (builtin) {
|
||||
errorArgs = this._abiCoder.decode(builtin.inputs, bytes.slice(4));
|
||||
errorName = builtin.name;
|
||||
errorSignature = builtin.signature;
|
||||
if (builtin.reason) {
|
||||
reason = errorArgs[0];
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
var error = this.getError(selector);
|
||||
errorArgs = this._abiCoder.decode(error.inputs, bytes.slice(4));
|
||||
errorName = error.name;
|
||||
errorSignature = error.format();
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return logger.throwError("call revert exception", logger_1.Logger.errors.CALL_EXCEPTION, {
|
||||
method: functionFragment.format(),
|
||||
errorSignature: errorSignature,
|
||||
errorArgs: [reason],
|
||||
reason: reason
|
||||
errorArgs: errorArgs, errorName: errorName, errorSignature: errorSignature, reason: reason
|
||||
});
|
||||
};
|
||||
// Encode the result for a function call (e.g. for eth_call)
|
||||
@@ -501,6 +594,8 @@ var Interface = /** @class */ (function () {
|
||||
value: bignumber_1.BigNumber.from(tx.value || "0"),
|
||||
});
|
||||
};
|
||||
// @TODO
|
||||
//parseCallResult(data: BytesLike): ??
|
||||
// Given an event log, find the matching event fragment (if any) and
|
||||
// determine all its properties and values
|
||||
Interface.prototype.parseLog = function (log) {
|
||||
@@ -519,6 +614,20 @@ var Interface = /** @class */ (function () {
|
||||
args: this.decodeEventLog(fragment, log.data, log.topics)
|
||||
});
|
||||
};
|
||||
Interface.prototype.parseError = function (data) {
|
||||
var hexData = bytes_1.hexlify(data);
|
||||
var fragment = this.getError(hexData.substring(0, 10).toLowerCase());
|
||||
if (!fragment) {
|
||||
return null;
|
||||
}
|
||||
return new ErrorDescription({
|
||||
args: this._abiCoder.decode(fragment.inputs, "0x" + hexData.substring(10)),
|
||||
errorFragment: fragment,
|
||||
name: fragment.name,
|
||||
signature: fragment.format(),
|
||||
sighash: this.getSighash(fragment),
|
||||
});
|
||||
};
|
||||
/*
|
||||
static from(value: Array<Fragment | string | JsonAbi> | string | Interface) {
|
||||
if (Interface.isInterface(value)) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"author": "Richard Moore <me@ricmoo.com>",
|
||||
"dependencies": {
|
||||
"@ethersproject/address": "^5.1.0",
|
||||
"@ethersproject/bignumber": "^5.1.0",
|
||||
"@ethersproject/bytes": "^5.1.0",
|
||||
"@ethersproject/constants": "^5.1.0",
|
||||
"@ethersproject/hash": "^5.1.0",
|
||||
"@ethersproject/keccak256": "^5.1.0",
|
||||
"@ethersproject/logger": "^5.1.0",
|
||||
"@ethersproject/properties": "^5.1.0",
|
||||
"@ethersproject/strings": "^5.1.0"
|
||||
"@ethersproject/address": "^5.4.0",
|
||||
"@ethersproject/bignumber": "^5.4.0",
|
||||
"@ethersproject/bytes": "^5.4.0",
|
||||
"@ethersproject/constants": "^5.4.0",
|
||||
"@ethersproject/hash": "^5.4.0",
|
||||
"@ethersproject/keccak256": "^5.4.0",
|
||||
"@ethersproject/logger": "^5.4.0",
|
||||
"@ethersproject/properties": "^5.4.0",
|
||||
"@ethersproject/strings": "^5.4.0"
|
||||
},
|
||||
"description": "Utilities and Classes for parsing, formatting and managing Ethereum ABIs.",
|
||||
"ethereum": "donations.ethers.eth",
|
||||
@@ -43,7 +43,7 @@
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"tarballHash": "0x070ed6a837106528848f7ee9e3b1289bf4619f37d865653cbf2e6c839288b49b",
|
||||
"tarballHash": "0xc245561411575102d5bd84bff62e1db56c49c8dcd4e99be2a6dba67007a29d7e",
|
||||
"types": "./lib/index.d.ts",
|
||||
"version": "5.1.1"
|
||||
"version": "5.4.0"
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const version = "abi/5.1.1";
|
||||
export const version = "abi/5.4.0";
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface JsonFragmentType {
|
||||
readonly name?: string;
|
||||
readonly indexed?: boolean;
|
||||
readonly type?: string;
|
||||
readonly internalType?: any; // @TODO: in v6 reduce type
|
||||
readonly components?: ReadonlyArray<JsonFragmentType>;
|
||||
}
|
||||
|
||||
@@ -30,7 +31,6 @@ export interface JsonFragment {
|
||||
readonly gas?: string;
|
||||
};
|
||||
|
||||
|
||||
const _constructorGuard = { };
|
||||
|
||||
// AST Node parser state
|
||||
@@ -445,6 +445,8 @@ export abstract class Fragment {
|
||||
return EventFragment.fromObject(value);
|
||||
case "constructor":
|
||||
return ConstructorFragment.fromObject(value);
|
||||
case "error":
|
||||
return ErrorFragment.fromObject(value);
|
||||
case "fallback":
|
||||
case "receive":
|
||||
// @TODO: Something? Maybe return a FunctionFragment? A custom DefaultFunctionFragment?
|
||||
@@ -466,6 +468,8 @@ export abstract class Fragment {
|
||||
return FunctionFragment.fromString(value.substring(8).trim());
|
||||
} else if (value.split("(")[0].trim() === "constructor") {
|
||||
return ConstructorFragment.fromString(value.trim());
|
||||
} else if (value.split(" ")[0] === "error") {
|
||||
return ErrorFragment.fromString(value.substring(5).trim());
|
||||
}
|
||||
|
||||
return logger.throwArgumentError("unsupported fragment", "value", value);
|
||||
@@ -927,12 +931,90 @@ export class FunctionFragment extends ConstructorFragment {
|
||||
}
|
||||
}
|
||||
|
||||
//export class ErrorFragment extends Fragment {
|
||||
//}
|
||||
|
||||
//export class StructFragment extends Fragment {
|
||||
//}
|
||||
|
||||
function checkForbidden(fragment: ErrorFragment): ErrorFragment {
|
||||
const sig = fragment.format();
|
||||
if (sig === "Error(string)" || sig === "Panic(uint256)") {
|
||||
logger.throwArgumentError(`cannot specify user defined ${ sig } error`, "fragment", fragment);
|
||||
}
|
||||
return fragment;
|
||||
}
|
||||
|
||||
export class ErrorFragment extends Fragment {
|
||||
|
||||
format(format?: string): string {
|
||||
if (!format) { format = FormatTypes.sighash; }
|
||||
if (!FormatTypes[format]) {
|
||||
logger.throwArgumentError("invalid format type", "format", format);
|
||||
}
|
||||
|
||||
if (format === FormatTypes.json) {
|
||||
return JSON.stringify({
|
||||
type: "error",
|
||||
name: this.name,
|
||||
inputs: this.inputs.map((input) => JSON.parse(input.format(format))),
|
||||
});
|
||||
}
|
||||
|
||||
let result = "";
|
||||
|
||||
if (format !== FormatTypes.sighash) {
|
||||
result += "error ";
|
||||
}
|
||||
|
||||
result += this.name + "(" + this.inputs.map(
|
||||
(input) => input.format(format)
|
||||
).join((format === FormatTypes.full) ? ", ": ",") + ") ";
|
||||
|
||||
return result.trim();
|
||||
}
|
||||
|
||||
static from(value: ErrorFragment | JsonFragment | string): ErrorFragment {
|
||||
if (typeof(value) === "string") {
|
||||
return ErrorFragment.fromString(value);
|
||||
}
|
||||
return ErrorFragment.fromObject(value);
|
||||
}
|
||||
|
||||
static fromObject(value: ErrorFragment | JsonFragment): ErrorFragment {
|
||||
if (ErrorFragment.isErrorFragment(value)) { return value; }
|
||||
|
||||
if (value.type !== "error") {
|
||||
logger.throwArgumentError("invalid error object", "value", value);
|
||||
}
|
||||
|
||||
const params: TypeCheck<_Fragment> = {
|
||||
type: value.type,
|
||||
name: verifyIdentifier(value.name),
|
||||
inputs: (value.inputs ? value.inputs.map(ParamType.fromObject): [])
|
||||
};
|
||||
|
||||
return checkForbidden(new ErrorFragment(_constructorGuard, params));
|
||||
}
|
||||
|
||||
static fromString(value: string): ErrorFragment {
|
||||
let params: any = { type: "error" };
|
||||
|
||||
let parens = value.match(regexParen);
|
||||
if (!parens) {
|
||||
logger.throwArgumentError("invalid error signature", "value", value);
|
||||
}
|
||||
|
||||
params.name = parens[1].trim();
|
||||
if (params.name) { verifyIdentifier(params.name); }
|
||||
|
||||
params.inputs = parseParams(parens[2], false);
|
||||
|
||||
return checkForbidden(ErrorFragment.fromObject(params));
|
||||
}
|
||||
|
||||
static isErrorFragment(value: any): value is ErrorFragment {
|
||||
return (value && value._isFragment && value.type === "error");
|
||||
}
|
||||
}
|
||||
|
||||
function verifyType(type: string): string {
|
||||
|
||||
// These need to be transformed to their full description
|
||||
@@ -947,7 +1029,8 @@ function verifyType(type: string): string {
|
||||
return type;
|
||||
}
|
||||
|
||||
const regexIdentifier = new RegExp("^[A-Za-z_][A-Za-z0-9_]*$");
|
||||
// See: https://github.com/ethereum/solidity/blob/1f8f1a3db93a548d0555e3e14cfc55a10e25b60e/docs/grammar/SolidityLexer.g4#L234
|
||||
const regexIdentifier = new RegExp("^[a-zA-Z$_][a-zA-Z0-9$_]*$");
|
||||
function verifyIdentifier(value: string): string {
|
||||
if (!value || !value.match(regexIdentifier)) {
|
||||
logger.throwArgumentError(`invalid identifier "${ value }"`, "value", value);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
import { ConstructorFragment, EventFragment, FormatTypes, Fragment, FunctionFragment, JsonFragment, JsonFragmentType, ParamType } from "./fragments";
|
||||
import { ConstructorFragment, ErrorFragment, EventFragment, FormatTypes, Fragment, FunctionFragment, JsonFragment, JsonFragmentType, ParamType } from "./fragments";
|
||||
import { AbiCoder, CoerceFunc, defaultAbiCoder } from "./abi-coder";
|
||||
import { checkResultErrors, Indexed, Interface, LogDescription, Result, TransactionDescription } from "./interface";
|
||||
|
||||
export {
|
||||
ConstructorFragment,
|
||||
ErrorFragment,
|
||||
EventFragment,
|
||||
Fragment,
|
||||
FunctionFragment,
|
||||
|
||||
@@ -9,7 +9,7 @@ import { defineReadOnly, Description, getStatic } from "@ethersproject/propertie
|
||||
|
||||
import { AbiCoder, defaultAbiCoder } from "./abi-coder";
|
||||
import { checkResultErrors, Result } from "./coders/abstract-coder";
|
||||
import { ConstructorFragment, EventFragment, FormatTypes, Fragment, FunctionFragment, JsonFragment, ParamType } from "./fragments";
|
||||
import { ConstructorFragment, ErrorFragment, EventFragment, FormatTypes, Fragment, FunctionFragment, JsonFragment, ParamType } from "./fragments";
|
||||
|
||||
import { Logger } from "@ethersproject/logger";
|
||||
import { version } from "./_version";
|
||||
@@ -34,6 +34,14 @@ export class TransactionDescription extends Description<TransactionDescription>
|
||||
readonly value: BigNumber;
|
||||
}
|
||||
|
||||
export class ErrorDescription extends Description<ErrorDescription> {
|
||||
readonly errorFragment: ErrorFragment;
|
||||
readonly name: string;
|
||||
readonly args: Result;
|
||||
readonly signature: string;
|
||||
readonly sighash: string;
|
||||
}
|
||||
|
||||
export class Indexed extends Description<Indexed> {
|
||||
readonly hash: string;
|
||||
readonly _isIndexed: boolean;
|
||||
@@ -43,6 +51,11 @@ export class Indexed extends Description<Indexed> {
|
||||
}
|
||||
}
|
||||
|
||||
const BuiltinErrors: Record<string, { signature: string, inputs: Array<string>, name: string, reason?: boolean }> = {
|
||||
"0x08c379a0": { signature: "Error(string)", name: "Error", inputs: [ "string" ], reason: true },
|
||||
"0x4e487b71": { signature: "Panic(uint256)", name: "Panic", inputs: [ "uint256" ] }
|
||||
}
|
||||
|
||||
function wrapAccessError(property: string, error: Error): Error {
|
||||
const wrap = new Error(`deferred error during ABI decoding triggered accessing ${ property }`);
|
||||
(<any>wrap).error = error;
|
||||
@@ -65,7 +78,7 @@ function checkNames(fragment: Fragment, type: "input" | "output", params: Array<
|
||||
export class Interface {
|
||||
readonly fragments: ReadonlyArray<Fragment>;
|
||||
|
||||
readonly errors: { [ name: string ]: any };
|
||||
readonly errors: { [ name: string ]: ErrorFragment };
|
||||
readonly events: { [ name: string ]: EventFragment };
|
||||
readonly functions: { [ name: string ]: FunctionFragment };
|
||||
readonly structs: { [ name: string ]: any };
|
||||
@@ -118,6 +131,9 @@ export class Interface {
|
||||
//checkNames(fragment, "input", fragment.inputs);
|
||||
bucket = this.events;
|
||||
break;
|
||||
case "error":
|
||||
bucket = this.errors;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -167,8 +183,8 @@ export class Interface {
|
||||
return getAddress(address);
|
||||
}
|
||||
|
||||
static getSighash(functionFragment: FunctionFragment): string {
|
||||
return hexDataSlice(id(functionFragment.format()), 0, 4);
|
||||
static getSighash(fragment: ErrorFragment | FunctionFragment): string {
|
||||
return hexDataSlice(id(fragment.format()), 0, 4);
|
||||
}
|
||||
|
||||
static getEventTopic(eventFragment: EventFragment): string {
|
||||
@@ -240,13 +256,55 @@ export class Interface {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get the sighash (the bytes4 selector) used by Solidity to identify a function
|
||||
getSighash(functionFragment: FunctionFragment | string): string {
|
||||
if (typeof(functionFragment) === "string") {
|
||||
functionFragment = this.getFunction(functionFragment);
|
||||
// Find a function definition by any means necessary (unless it is ambiguous)
|
||||
getError(nameOrSignatureOrSighash: string): ErrorFragment {
|
||||
if (isHexString(nameOrSignatureOrSighash)) {
|
||||
const getSighash = getStatic<(f: ErrorFragment | FunctionFragment) => string>(this.constructor, "getSighash");
|
||||
for (const name in this.errors) {
|
||||
const error = this.errors[name];
|
||||
if (nameOrSignatureOrSighash === getSighash(error)) {
|
||||
return this.errors[name];
|
||||
}
|
||||
}
|
||||
logger.throwArgumentError("no matching error", "sighash", nameOrSignatureOrSighash);
|
||||
}
|
||||
|
||||
return getStatic<(f: FunctionFragment) => string>(this.constructor, "getSighash")(functionFragment);
|
||||
// It is a bare name, look up the function (will return null if ambiguous)
|
||||
if (nameOrSignatureOrSighash.indexOf("(") === -1) {
|
||||
const name = nameOrSignatureOrSighash.trim();
|
||||
const matching = Object.keys(this.errors).filter((f) => (f.split("("/* fix:) */)[0] === name));
|
||||
if (matching.length === 0) {
|
||||
logger.throwArgumentError("no matching error", "name", name);
|
||||
} else if (matching.length > 1) {
|
||||
logger.throwArgumentError("multiple matching errors", "name", name);
|
||||
}
|
||||
|
||||
return this.errors[matching[0]];
|
||||
}
|
||||
|
||||
// Normlize the signature and lookup the function
|
||||
const result = this.errors[FunctionFragment.fromString(nameOrSignatureOrSighash).format()];
|
||||
if (!result) {
|
||||
logger.throwArgumentError("no matching error", "signature", nameOrSignatureOrSighash);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get the sighash (the bytes4 selector) used by Solidity to identify a function
|
||||
getSighash(fragment: ErrorFragment | FunctionFragment | string): string {
|
||||
if (typeof(fragment) === "string") {
|
||||
try {
|
||||
fragment = this.getFunction(fragment);
|
||||
} catch (error) {
|
||||
try {
|
||||
fragment = this.getError(<string>fragment);
|
||||
} catch (_) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getStatic<(f: ErrorFragment | FunctionFragment) => string>(this.constructor, "getSighash")(fragment);
|
||||
}
|
||||
|
||||
// Get the topic (the bytes32 hash) used by Solidity to identify an event
|
||||
@@ -271,6 +329,31 @@ export class Interface {
|
||||
return this._encodeParams(this.deploy.inputs, values || [ ]);
|
||||
}
|
||||
|
||||
decodeErrorResult(fragment: ErrorFragment | string, data: BytesLike): Result {
|
||||
if (typeof(fragment) === "string") {
|
||||
fragment = this.getError(fragment);
|
||||
}
|
||||
|
||||
const bytes = arrayify(data);
|
||||
|
||||
if (hexlify(bytes.slice(0, 4)) !== this.getSighash(fragment)) {
|
||||
logger.throwArgumentError(`data signature does not match error ${ fragment.name }.`, "data", hexlify(bytes));
|
||||
}
|
||||
|
||||
return this._decodeParams(fragment.inputs, bytes.slice(4));
|
||||
}
|
||||
|
||||
encodeErrorResult(fragment: ErrorFragment | string, values?: ReadonlyArray<any>): string {
|
||||
if (typeof(fragment) === "string") {
|
||||
fragment = this.getError(fragment);
|
||||
}
|
||||
|
||||
return hexlify(concat([
|
||||
this.getSighash(fragment),
|
||||
this._encodeParams(fragment.inputs, values || [ ])
|
||||
]));
|
||||
}
|
||||
|
||||
// Decode the data for a function call (e.g. tx.data)
|
||||
decodeFunctionData(functionFragment: FunctionFragment | string, data: BytesLike): Result {
|
||||
if (typeof(functionFragment) === "string") {
|
||||
@@ -304,9 +387,11 @@ export class Interface {
|
||||
functionFragment = this.getFunction(functionFragment);
|
||||
}
|
||||
|
||||
let bytes = arrayify(data);
|
||||
let bytes = arrayify(data);
|
||||
|
||||
let reason: string = null;
|
||||
let errorArgs: Result = null;
|
||||
let errorName: string = null;
|
||||
let errorSignature: string = null;
|
||||
switch (bytes.length % this._abiCoder._getWordSize()) {
|
||||
case 0:
|
||||
@@ -315,19 +400,31 @@ export class Interface {
|
||||
} catch (error) { }
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (hexlify(bytes.slice(0, 4)) === "0x08c379a0") {
|
||||
errorSignature = "Error(string)";
|
||||
reason = this._abiCoder.decode([ "string" ], bytes.slice(4))[0];
|
||||
case 4: {
|
||||
const selector = hexlify(bytes.slice(0, 4));
|
||||
const builtin = BuiltinErrors[selector];
|
||||
if (builtin) {
|
||||
errorArgs = this._abiCoder.decode(builtin.inputs, bytes.slice(4));
|
||||
errorName = builtin.name;
|
||||
errorSignature = builtin.signature;
|
||||
if (builtin.reason) { reason = errorArgs[0]; }
|
||||
} else {
|
||||
try {
|
||||
const error = this.getError(selector);
|
||||
errorArgs = this._abiCoder.decode(error.inputs, bytes.slice(4));
|
||||
errorName = error.name;
|
||||
errorSignature = error.format();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return logger.throwError("call revert exception", Logger.errors.CALL_EXCEPTION, {
|
||||
method: functionFragment.format(),
|
||||
errorSignature: errorSignature,
|
||||
errorArgs: [ reason ],
|
||||
reason: reason
|
||||
errorArgs, errorName, errorSignature, reason
|
||||
});
|
||||
}
|
||||
|
||||
@@ -547,6 +644,9 @@ export class Interface {
|
||||
});
|
||||
}
|
||||
|
||||
// @TODO
|
||||
//parseCallResult(data: BytesLike): ??
|
||||
|
||||
// Given an event log, find the matching event fragment (if any) and
|
||||
// determine all its properties and values
|
||||
parseLog(log: { topics: Array<string>, data: string}): LogDescription {
|
||||
@@ -568,6 +668,21 @@ export class Interface {
|
||||
});
|
||||
}
|
||||
|
||||
parseError(data: BytesLike): ErrorDescription {
|
||||
const hexData = hexlify(data);
|
||||
let fragment = this.getError(hexData.substring(0, 10).toLowerCase())
|
||||
|
||||
if (!fragment) { return null; }
|
||||
|
||||
return new ErrorDescription({
|
||||
args: this._abiCoder.decode(fragment.inputs, "0x" + hexData.substring(10)),
|
||||
errorFragment: fragment,
|
||||
name: fragment.name,
|
||||
signature: fragment.format(),
|
||||
sighash: this.getSighash(fragment),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
static from(value: Array<Fragment | string | JsonAbi> | string | Interface) {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export declare const version = "abstract-provider/5.1.0";
|
||||
export declare const version = "abstract-provider/5.4.0";
|
||||
//# sourceMappingURL=_version.d.ts.map
|
||||
@@ -1,2 +1,2 @@
|
||||
export const version = "abstract-provider/5.1.0";
|
||||
export const version = "abstract-provider/5.4.0";
|
||||
//# sourceMappingURL=_version.js.map
|
||||
13
packages/abstract-provider/lib.esm/index.d.ts
vendored
13
packages/abstract-provider/lib.esm/index.d.ts
vendored
@@ -15,6 +15,8 @@ export declare type TransactionRequest = {
|
||||
chainId?: number;
|
||||
type?: number;
|
||||
accessList?: AccessListish;
|
||||
maxPriorityFeePerGas?: BigNumberish;
|
||||
maxFeePerGas?: BigNumberish;
|
||||
};
|
||||
export interface TransactionResponse extends Transaction {
|
||||
hash: string;
|
||||
@@ -38,6 +40,7 @@ interface _Block {
|
||||
gasUsed: BigNumber;
|
||||
miner: string;
|
||||
extraData: string;
|
||||
baseFeePerGas?: null | BigNumber;
|
||||
}
|
||||
export interface Block extends _Block {
|
||||
transactions: Array<string>;
|
||||
@@ -70,12 +73,19 @@ export interface TransactionReceipt {
|
||||
blockNumber: number;
|
||||
confirmations: number;
|
||||
cumulativeGasUsed: BigNumber;
|
||||
effectiveGasPrice: BigNumber;
|
||||
byzantium: boolean;
|
||||
type: number;
|
||||
status?: number;
|
||||
}
|
||||
export interface FeeData {
|
||||
maxFeePerGas: null | BigNumber;
|
||||
maxPriorityFeePerGas: null | BigNumber;
|
||||
gasPrice: null | BigNumber;
|
||||
}
|
||||
export interface EventFilter {
|
||||
address?: string;
|
||||
topics?: Array<string | Array<string>>;
|
||||
topics?: Array<string | Array<string> | null>;
|
||||
}
|
||||
export interface Filter extends EventFilter {
|
||||
fromBlock?: BlockTag;
|
||||
@@ -110,6 +120,7 @@ export declare abstract class Provider implements OnceBlockable {
|
||||
abstract getNetwork(): Promise<Network>;
|
||||
abstract getBlockNumber(): Promise<number>;
|
||||
abstract getGasPrice(): Promise<BigNumber>;
|
||||
getFeeData(): Promise<FeeData>;
|
||||
abstract getBalance(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<BigNumber>;
|
||||
abstract getTransactionCount(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<number>;
|
||||
abstract getCode(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<string>;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,16 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
import { BigNumber } from "@ethersproject/bignumber";
|
||||
import { isHexString } from "@ethersproject/bytes";
|
||||
import { Description, defineReadOnly } from "@ethersproject/properties";
|
||||
import { Description, defineReadOnly, resolveProperties } from "@ethersproject/properties";
|
||||
import { Logger } from "@ethersproject/logger";
|
||||
import { version } from "./_version";
|
||||
const logger = new Logger(version);
|
||||
@@ -64,6 +74,27 @@ export class Provider {
|
||||
logger.checkAbstract(new.target, Provider);
|
||||
defineReadOnly(this, "_isProvider", true);
|
||||
}
|
||||
getFeeData() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { block, gasPrice } = yield resolveProperties({
|
||||
block: this.getBlock("latest"),
|
||||
gasPrice: this.getGasPrice().catch((error) => {
|
||||
// @TODO: Why is this now failing on Calaveras?
|
||||
//console.log(error);
|
||||
return null;
|
||||
})
|
||||
});
|
||||
let maxFeePerGas = null, maxPriorityFeePerGas = null;
|
||||
if (block && block.baseFeePerGas) {
|
||||
// We may want to compute this more accurately in the future,
|
||||
// using the formula "check if the base fee is correct".
|
||||
// See: https://eips.ethereum.org/EIPS/eip-1559
|
||||
maxPriorityFeePerGas = BigNumber.from("1000000000");
|
||||
maxFeePerGas = block.baseFeePerGas.mul(2).add(maxPriorityFeePerGas);
|
||||
}
|
||||
return { maxFeePerGas, maxPriorityFeePerGas, gasPrice };
|
||||
});
|
||||
}
|
||||
// Alias for "on"
|
||||
addListener(eventName, listener) {
|
||||
return this.on(eventName, listener);
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"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"}
|
||||
2
packages/abstract-provider/lib/_version.d.ts
vendored
2
packages/abstract-provider/lib/_version.d.ts
vendored
@@ -1,2 +1,2 @@
|
||||
export declare const version = "abstract-provider/5.1.0";
|
||||
export declare const version = "abstract-provider/5.4.0";
|
||||
//# sourceMappingURL=_version.d.ts.map
|
||||
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.version = void 0;
|
||||
exports.version = "abstract-provider/5.1.0";
|
||||
exports.version = "abstract-provider/5.4.0";
|
||||
//# sourceMappingURL=_version.js.map
|
||||
13
packages/abstract-provider/lib/index.d.ts
vendored
13
packages/abstract-provider/lib/index.d.ts
vendored
@@ -15,6 +15,8 @@ export declare type TransactionRequest = {
|
||||
chainId?: number;
|
||||
type?: number;
|
||||
accessList?: AccessListish;
|
||||
maxPriorityFeePerGas?: BigNumberish;
|
||||
maxFeePerGas?: BigNumberish;
|
||||
};
|
||||
export interface TransactionResponse extends Transaction {
|
||||
hash: string;
|
||||
@@ -38,6 +40,7 @@ interface _Block {
|
||||
gasUsed: BigNumber;
|
||||
miner: string;
|
||||
extraData: string;
|
||||
baseFeePerGas?: null | BigNumber;
|
||||
}
|
||||
export interface Block extends _Block {
|
||||
transactions: Array<string>;
|
||||
@@ -70,12 +73,19 @@ export interface TransactionReceipt {
|
||||
blockNumber: number;
|
||||
confirmations: number;
|
||||
cumulativeGasUsed: BigNumber;
|
||||
effectiveGasPrice: BigNumber;
|
||||
byzantium: boolean;
|
||||
type: number;
|
||||
status?: number;
|
||||
}
|
||||
export interface FeeData {
|
||||
maxFeePerGas: null | BigNumber;
|
||||
maxPriorityFeePerGas: null | BigNumber;
|
||||
gasPrice: null | BigNumber;
|
||||
}
|
||||
export interface EventFilter {
|
||||
address?: string;
|
||||
topics?: Array<string | Array<string>>;
|
||||
topics?: Array<string | Array<string> | null>;
|
||||
}
|
||||
export interface Filter extends EventFilter {
|
||||
fromBlock?: BlockTag;
|
||||
@@ -110,6 +120,7 @@ export declare abstract class Provider implements OnceBlockable {
|
||||
abstract getNetwork(): Promise<Network>;
|
||||
abstract getBlockNumber(): Promise<number>;
|
||||
abstract getGasPrice(): Promise<BigNumber>;
|
||||
getFeeData(): Promise<FeeData>;
|
||||
abstract getBalance(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<BigNumber>;
|
||||
abstract getTransactionCount(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<number>;
|
||||
abstract getCode(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<string>;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -14,8 +14,45 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Provider = exports.TransactionOrderForkEvent = exports.TransactionForkEvent = exports.BlockForkEvent = exports.ForkEvent = void 0;
|
||||
var bignumber_1 = require("@ethersproject/bignumber");
|
||||
var bytes_1 = require("@ethersproject/bytes");
|
||||
var properties_1 = require("@ethersproject/properties");
|
||||
var logger_1 = require("@ethersproject/logger");
|
||||
@@ -103,6 +140,34 @@ var Provider = /** @class */ (function () {
|
||||
logger.checkAbstract(_newTarget, Provider);
|
||||
properties_1.defineReadOnly(this, "_isProvider", true);
|
||||
}
|
||||
Provider.prototype.getFeeData = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var _a, block, gasPrice, maxFeePerGas, maxPriorityFeePerGas;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0: return [4 /*yield*/, properties_1.resolveProperties({
|
||||
block: this.getBlock("latest"),
|
||||
gasPrice: this.getGasPrice().catch(function (error) {
|
||||
// @TODO: Why is this now failing on Calaveras?
|
||||
//console.log(error);
|
||||
return null;
|
||||
})
|
||||
})];
|
||||
case 1:
|
||||
_a = _b.sent(), block = _a.block, gasPrice = _a.gasPrice;
|
||||
maxFeePerGas = null, maxPriorityFeePerGas = null;
|
||||
if (block && block.baseFeePerGas) {
|
||||
// We may want to compute this more accurately in the future,
|
||||
// using the formula "check if the base fee is correct".
|
||||
// See: https://eips.ethereum.org/EIPS/eip-1559
|
||||
maxPriorityFeePerGas = bignumber_1.BigNumber.from("1000000000");
|
||||
maxFeePerGas = block.baseFeePerGas.mul(2).add(maxPriorityFeePerGas);
|
||||
}
|
||||
return [2 /*return*/, { maxFeePerGas: maxFeePerGas, maxPriorityFeePerGas: maxPriorityFeePerGas, gasPrice: gasPrice }];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
// Alias for "on"
|
||||
Provider.prototype.addListener = function (eventName, listener) {
|
||||
return this.on(eventName, listener);
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"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"}
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"author": "Richard Moore <me@ricmoo.com>",
|
||||
"dependencies": {
|
||||
"@ethersproject/bignumber": "^5.1.0",
|
||||
"@ethersproject/bytes": "^5.1.0",
|
||||
"@ethersproject/logger": "^5.1.0",
|
||||
"@ethersproject/networks": "^5.1.0",
|
||||
"@ethersproject/properties": "^5.1.0",
|
||||
"@ethersproject/transactions": "^5.1.0",
|
||||
"@ethersproject/web": "^5.1.0"
|
||||
"@ethersproject/bignumber": "^5.4.0",
|
||||
"@ethersproject/bytes": "^5.4.0",
|
||||
"@ethersproject/logger": "^5.4.0",
|
||||
"@ethersproject/networks": "^5.4.0",
|
||||
"@ethersproject/properties": "^5.4.0",
|
||||
"@ethersproject/transactions": "^5.4.0",
|
||||
"@ethersproject/web": "^5.4.0"
|
||||
},
|
||||
"description": "An Abstract Class for describing an Ethereum Provider for ethers.",
|
||||
"ethereum": "donations.ethers.eth",
|
||||
@@ -41,7 +41,7 @@
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"tarballHash": "0x9a2ee9005c813b52689b7d87a01f6ce29010ef3f899c5fc500e6ae3ea0f03ea2",
|
||||
"tarballHash": "0x0d152f2cef24f5a71be21511b20e285fa705aacdf06f626542595ff64aad5394",
|
||||
"types": "./lib/index.d.ts",
|
||||
"version": "5.1.0"
|
||||
"version": "5.4.0"
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const version = "abstract-provider/5.1.0";
|
||||
export const version = "abstract-provider/5.4.0";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
|
||||
import { BytesLike, isHexString } from "@ethersproject/bytes";
|
||||
import { Network } from "@ethersproject/networks";
|
||||
import { Deferrable, Description, defineReadOnly } from "@ethersproject/properties";
|
||||
import { Deferrable, Description, defineReadOnly, resolveProperties } from "@ethersproject/properties";
|
||||
import { AccessListish, Transaction } from "@ethersproject/transactions";
|
||||
import { OnceBlockable } from "@ethersproject/web";
|
||||
|
||||
@@ -29,6 +29,9 @@ export type TransactionRequest = {
|
||||
|
||||
type?: number;
|
||||
accessList?: AccessListish;
|
||||
|
||||
maxPriorityFeePerGas?: BigNumberish;
|
||||
maxFeePerGas?: BigNumberish;
|
||||
}
|
||||
|
||||
export interface TransactionResponse extends Transaction {
|
||||
@@ -67,6 +70,8 @@ interface _Block {
|
||||
|
||||
miner: string;
|
||||
extraData: string;
|
||||
|
||||
baseFeePerGas?: null | BigNumber;
|
||||
}
|
||||
|
||||
export interface Block extends _Block {
|
||||
@@ -108,13 +113,21 @@ export interface TransactionReceipt {
|
||||
blockNumber: number,
|
||||
confirmations: number,
|
||||
cumulativeGasUsed: BigNumber,
|
||||
effectiveGasPrice: BigNumber,
|
||||
byzantium: boolean,
|
||||
type: number;
|
||||
status?: number
|
||||
};
|
||||
|
||||
export interface FeeData {
|
||||
maxFeePerGas: null | BigNumber;
|
||||
maxPriorityFeePerGas: null | BigNumber;
|
||||
gasPrice: null | BigNumber;
|
||||
}
|
||||
|
||||
export interface EventFilter {
|
||||
address?: string;
|
||||
topics?: Array<string | Array<string>>;
|
||||
topics?: Array<string | Array<string> | null>;
|
||||
}
|
||||
|
||||
export interface Filter extends EventFilter {
|
||||
@@ -206,7 +219,6 @@ export type Listener = (...args: Array<any>) => void;
|
||||
|
||||
///////////////////////////////
|
||||
// Exported Abstracts
|
||||
|
||||
export abstract class Provider implements OnceBlockable {
|
||||
|
||||
// Network
|
||||
@@ -215,6 +227,28 @@ export abstract class Provider implements OnceBlockable {
|
||||
// Latest State
|
||||
abstract getBlockNumber(): Promise<number>;
|
||||
abstract getGasPrice(): Promise<BigNumber>;
|
||||
async getFeeData(): Promise<FeeData> {
|
||||
const { block, gasPrice } = await resolveProperties({
|
||||
block: this.getBlock("latest"),
|
||||
gasPrice: this.getGasPrice().catch((error) => {
|
||||
// @TODO: Why is this now failing on Calaveras?
|
||||
//console.log(error);
|
||||
return null;
|
||||
})
|
||||
});
|
||||
|
||||
let maxFeePerGas = null, maxPriorityFeePerGas = null;
|
||||
|
||||
if (block && block.baseFeePerGas) {
|
||||
// We may want to compute this more accurately in the future,
|
||||
// using the formula "check if the base fee is correct".
|
||||
// See: https://eips.ethereum.org/EIPS/eip-1559
|
||||
maxPriorityFeePerGas = BigNumber.from("1000000000");
|
||||
maxFeePerGas = block.baseFeePerGas.mul(2).add(maxPriorityFeePerGas);
|
||||
}
|
||||
|
||||
return { maxFeePerGas, maxPriorityFeePerGas, gasPrice };
|
||||
}
|
||||
|
||||
// Account
|
||||
abstract getBalance(addressOrName: string | Promise<string>, blockTag?: BlockTag | Promise<BlockTag>): Promise<BigNumber>;
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export declare const version = "abstract-signer/5.1.0";
|
||||
export declare const version = "abstract-signer/5.4.0";
|
||||
//# sourceMappingURL=_version.d.ts.map
|
||||
@@ -1,2 +1,2 @@
|
||||
export const version = "abstract-signer/5.1.0";
|
||||
export const version = "abstract-signer/5.4.0";
|
||||
//# sourceMappingURL=_version.js.map
|
||||
3
packages/abstract-signer/lib.esm/index.d.ts
vendored
3
packages/abstract-signer/lib.esm/index.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider";
|
||||
import { BlockTag, FeeData, Provider, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider";
|
||||
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
|
||||
import { Bytes, BytesLike } from "@ethersproject/bytes";
|
||||
import { Deferrable } from "@ethersproject/properties";
|
||||
@@ -35,6 +35,7 @@ export declare abstract class Signer {
|
||||
sendTransaction(transaction: Deferrable<TransactionRequest>): Promise<TransactionResponse>;
|
||||
getChainId(): Promise<number>;
|
||||
getGasPrice(): Promise<BigNumber>;
|
||||
getFeeData(): Promise<FeeData>;
|
||||
resolveName(name: string): Promise<string>;
|
||||
checkTransaction(transaction: Deferrable<TransactionRequest>): Deferrable<TransactionRequest>;
|
||||
populateTransaction(transaction: Deferrable<TransactionRequest>): Promise<TransactionRequest>;
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC/G,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAkD,MAAM,2BAA2B,CAAC;AAmBvG,MAAM,WAAW,eAAe;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC/B;AAWD,MAAM,WAAW,eAAe;IAC5B,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACtI;AAED,8BAAsB,MAAM;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAM7B,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAMtC,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAM9D,QAAQ,CAAC,eAAe,CAAC,WAAW,EAAE,UAAU,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAItF,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM;IAE5C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;;IActB,UAAU,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IAKnD,mBAAmB,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAMzD,WAAW,CAAC,WAAW,EAAE,UAAU,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;IAO5E,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,kBAAkB,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAO7F,eAAe,CAAC,WAAW,EAAE,UAAU,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASpF,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAM7B,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC;IAKjC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBhD,gBAAgB,CAAC,WAAW,EAAE,UAAU,CAAC,kBAAkB,CAAC,GAAG,UAAU,CAAC,kBAAkB,CAAC;IA+BvF,mBAAmB,CAAC,WAAW,EAAE,UAAU,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAmDnG,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAMxC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,MAAM;CAG/C;AAED,qBAAa,UAAW,SAAQ,MAAO,YAAW,eAAe;IAC7D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ;IAOhD,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAMvD,WAAW,CAAC,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrD,eAAe,CAAC,WAAW,EAAE,UAAU,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7E,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlI,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU;CAG1C"}
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"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"}
|
||||
@@ -13,7 +13,7 @@ import { Logger } from "@ethersproject/logger";
|
||||
import { version } from "./_version";
|
||||
const logger = new Logger(version);
|
||||
const allowedTransactionKeys = [
|
||||
"accessList", "chainId", "data", "from", "gasLimit", "gasPrice", "nonce", "to", "type", "value"
|
||||
"accessList", "chainId", "data", "from", "gasLimit", "gasPrice", "maxFeePerGas", "maxPriorityFeePerGas", "nonce", "to", "type", "value"
|
||||
];
|
||||
const forwardErrors = [
|
||||
Logger.errors.INSUFFICIENT_FUNDS,
|
||||
@@ -81,6 +81,12 @@ export class Signer {
|
||||
return yield this.provider.getGasPrice();
|
||||
});
|
||||
}
|
||||
getFeeData() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
this._checkProvider("getFeeData");
|
||||
return yield this.provider.getFeeData();
|
||||
});
|
||||
}
|
||||
resolveName(name) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
this._checkProvider("resolveName");
|
||||
@@ -124,6 +130,9 @@ export class Signer {
|
||||
// this Signer. Should be used by sendTransaction but NOT by signTransaction.
|
||||
// By default called from: (overriding these prevents it)
|
||||
// - sendTransaction
|
||||
//
|
||||
// Notes:
|
||||
// - We allow gasPrice for EIP-1559 as long as it matches maxFeePerGas
|
||||
populateTransaction(transaction) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const tx = yield resolveProperties(this.checkTransaction(transaction));
|
||||
@@ -139,8 +148,84 @@ export class Signer {
|
||||
return address;
|
||||
}));
|
||||
}
|
||||
if (tx.gasPrice == null) {
|
||||
tx.gasPrice = this.getGasPrice();
|
||||
// Do not allow mixing pre-eip-1559 and eip-1559 proerties
|
||||
const hasEip1559 = (tx.maxFeePerGas != null || tx.maxPriorityFeePerGas != null);
|
||||
if (tx.gasPrice != null && (tx.type === 2 || hasEip1559)) {
|
||||
logger.throwArgumentError("eip-1559 transaction do not support gasPrice", "transaction", transaction);
|
||||
}
|
||||
else if ((tx.type === 0 || tx.type === 1) && hasEip1559) {
|
||||
logger.throwArgumentError("pre-eip-1559 transaction do not support maxFeePerGas/maxPriorityFeePerGas", "transaction", transaction);
|
||||
}
|
||||
if ((tx.type === 2 || tx.type == null) && (tx.maxFeePerGas != null && tx.maxPriorityFeePerGas != null)) {
|
||||
// Fully-formed EIP-1559 transaction (skip getFeeData)
|
||||
tx.type = 2;
|
||||
}
|
||||
else if (tx.type === 0 || tx.type === 1) {
|
||||
// Explicit Legacy or EIP-2930 transaction
|
||||
// Populate missing gasPrice
|
||||
if (tx.gasPrice == null) {
|
||||
tx.gasPrice = this.getGasPrice();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We need to get fee data to determine things
|
||||
const feeData = yield this.getFeeData();
|
||||
if (tx.type == null) {
|
||||
// We need to auto-detect the intended type of this transaction...
|
||||
if (feeData.maxFeePerGas != null && feeData.maxPriorityFeePerGas != null) {
|
||||
// The network supports EIP-1559!
|
||||
// Upgrade transaction from null to eip-1559
|
||||
tx.type = 2;
|
||||
if (tx.gasPrice != null) {
|
||||
// Using legacy gasPrice property on an eip-1559 network,
|
||||
// so use gasPrice as both fee properties
|
||||
const gasPrice = tx.gasPrice;
|
||||
delete tx.gasPrice;
|
||||
tx.maxFeePerGas = gasPrice;
|
||||
tx.maxPriorityFeePerGas = gasPrice;
|
||||
}
|
||||
else {
|
||||
// Populate missing fee data
|
||||
if (tx.maxFeePerGas == null) {
|
||||
tx.maxFeePerGas = feeData.maxFeePerGas;
|
||||
}
|
||||
if (tx.maxPriorityFeePerGas == null) {
|
||||
tx.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (feeData.gasPrice != null) {
|
||||
// Network doesn't support EIP-1559...
|
||||
// ...but they are trying to use EIP-1559 properties
|
||||
if (hasEip1559) {
|
||||
logger.throwError("network does not support EIP-1559", Logger.errors.UNSUPPORTED_OPERATION, {
|
||||
operation: "populateTransaction"
|
||||
});
|
||||
}
|
||||
// Populate missing fee data
|
||||
if (tx.gasPrice == null) {
|
||||
tx.gasPrice = feeData.gasPrice;
|
||||
}
|
||||
// Explicitly set untyped transaction to legacy
|
||||
tx.type = 0;
|
||||
}
|
||||
else {
|
||||
// getFeeData has failed us.
|
||||
logger.throwError("failed to get consistent fee data", Logger.errors.UNSUPPORTED_OPERATION, {
|
||||
operation: "signer.getFeeData"
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (tx.type === 2) {
|
||||
// Explicitly using EIP-1559
|
||||
// Populate missing fee data
|
||||
if (tx.maxFeePerGas == null) {
|
||||
tx.maxFeePerGas = feeData.maxFeePerGas;
|
||||
}
|
||||
if (tx.maxPriorityFeePerGas == null) {
|
||||
tx.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tx.nonce == null) {
|
||||
tx.nonce = this.getTransactionCount("pending");
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
packages/abstract-signer/lib/_version.d.ts
vendored
2
packages/abstract-signer/lib/_version.d.ts
vendored
@@ -1,2 +1,2 @@
|
||||
export declare const version = "abstract-signer/5.1.0";
|
||||
export declare const version = "abstract-signer/5.4.0";
|
||||
//# sourceMappingURL=_version.d.ts.map
|
||||
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.version = void 0;
|
||||
exports.version = "abstract-signer/5.1.0";
|
||||
exports.version = "abstract-signer/5.4.0";
|
||||
//# sourceMappingURL=_version.js.map
|
||||
3
packages/abstract-signer/lib/index.d.ts
vendored
3
packages/abstract-signer/lib/index.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import { BlockTag, Provider, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider";
|
||||
import { BlockTag, FeeData, Provider, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider";
|
||||
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
|
||||
import { Bytes, BytesLike } from "@ethersproject/bytes";
|
||||
import { Deferrable } from "@ethersproject/properties";
|
||||
@@ -35,6 +35,7 @@ export declare abstract class Signer {
|
||||
sendTransaction(transaction: Deferrable<TransactionRequest>): Promise<TransactionResponse>;
|
||||
getChainId(): Promise<number>;
|
||||
getGasPrice(): Promise<BigNumber>;
|
||||
getFeeData(): Promise<FeeData>;
|
||||
resolveName(name: string): Promise<string>;
|
||||
checkTransaction(transaction: Deferrable<TransactionRequest>): Deferrable<TransactionRequest>;
|
||||
populateTransaction(transaction: Deferrable<TransactionRequest>): Promise<TransactionRequest>;
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"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"}
|
||||
@@ -57,7 +57,7 @@ var logger_1 = require("@ethersproject/logger");
|
||||
var _version_1 = require("./_version");
|
||||
var logger = new logger_1.Logger(_version_1.version);
|
||||
var allowedTransactionKeys = [
|
||||
"accessList", "chainId", "data", "from", "gasLimit", "gasPrice", "nonce", "to", "type", "value"
|
||||
"accessList", "chainId", "data", "from", "gasLimit", "gasPrice", "maxFeePerGas", "maxPriorityFeePerGas", "nonce", "to", "type", "value"
|
||||
];
|
||||
var forwardErrors = [
|
||||
logger_1.Logger.errors.INSUFFICIENT_FUNDS,
|
||||
@@ -171,6 +171,18 @@ var Signer = /** @class */ (function () {
|
||||
});
|
||||
});
|
||||
};
|
||||
Signer.prototype.getFeeData = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
this._checkProvider("getFeeData");
|
||||
return [4 /*yield*/, this.provider.getFeeData()];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
Signer.prototype.resolveName = function (name) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
@@ -220,9 +232,12 @@ var Signer = /** @class */ (function () {
|
||||
// this Signer. Should be used by sendTransaction but NOT by signTransaction.
|
||||
// By default called from: (overriding these prevents it)
|
||||
// - sendTransaction
|
||||
//
|
||||
// Notes:
|
||||
// - We allow gasPrice for EIP-1559 as long as it matches maxFeePerGas
|
||||
Signer.prototype.populateTransaction = function (transaction) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var tx;
|
||||
var tx, hasEip1559, feeData, gasPrice;
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
@@ -249,9 +264,84 @@ var Signer = /** @class */ (function () {
|
||||
});
|
||||
}); });
|
||||
}
|
||||
hasEip1559 = (tx.maxFeePerGas != null || tx.maxPriorityFeePerGas != null);
|
||||
if (tx.gasPrice != null && (tx.type === 2 || hasEip1559)) {
|
||||
logger.throwArgumentError("eip-1559 transaction do not support gasPrice", "transaction", transaction);
|
||||
}
|
||||
else if ((tx.type === 0 || tx.type === 1) && hasEip1559) {
|
||||
logger.throwArgumentError("pre-eip-1559 transaction do not support maxFeePerGas/maxPriorityFeePerGas", "transaction", transaction);
|
||||
}
|
||||
if (!((tx.type === 2 || tx.type == null) && (tx.maxFeePerGas != null && tx.maxPriorityFeePerGas != null))) return [3 /*break*/, 2];
|
||||
// Fully-formed EIP-1559 transaction (skip getFeeData)
|
||||
tx.type = 2;
|
||||
return [3 /*break*/, 5];
|
||||
case 2:
|
||||
if (!(tx.type === 0 || tx.type === 1)) return [3 /*break*/, 3];
|
||||
// Explicit Legacy or EIP-2930 transaction
|
||||
// Populate missing gasPrice
|
||||
if (tx.gasPrice == null) {
|
||||
tx.gasPrice = this.getGasPrice();
|
||||
}
|
||||
return [3 /*break*/, 5];
|
||||
case 3: return [4 /*yield*/, this.getFeeData()];
|
||||
case 4:
|
||||
feeData = _a.sent();
|
||||
if (tx.type == null) {
|
||||
// We need to auto-detect the intended type of this transaction...
|
||||
if (feeData.maxFeePerGas != null && feeData.maxPriorityFeePerGas != null) {
|
||||
// The network supports EIP-1559!
|
||||
// Upgrade transaction from null to eip-1559
|
||||
tx.type = 2;
|
||||
if (tx.gasPrice != null) {
|
||||
gasPrice = tx.gasPrice;
|
||||
delete tx.gasPrice;
|
||||
tx.maxFeePerGas = gasPrice;
|
||||
tx.maxPriorityFeePerGas = gasPrice;
|
||||
}
|
||||
else {
|
||||
// Populate missing fee data
|
||||
if (tx.maxFeePerGas == null) {
|
||||
tx.maxFeePerGas = feeData.maxFeePerGas;
|
||||
}
|
||||
if (tx.maxPriorityFeePerGas == null) {
|
||||
tx.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (feeData.gasPrice != null) {
|
||||
// Network doesn't support EIP-1559...
|
||||
// ...but they are trying to use EIP-1559 properties
|
||||
if (hasEip1559) {
|
||||
logger.throwError("network does not support EIP-1559", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
|
||||
operation: "populateTransaction"
|
||||
});
|
||||
}
|
||||
// Populate missing fee data
|
||||
if (tx.gasPrice == null) {
|
||||
tx.gasPrice = feeData.gasPrice;
|
||||
}
|
||||
// Explicitly set untyped transaction to legacy
|
||||
tx.type = 0;
|
||||
}
|
||||
else {
|
||||
// getFeeData has failed us.
|
||||
logger.throwError("failed to get consistent fee data", logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
|
||||
operation: "signer.getFeeData"
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (tx.type === 2) {
|
||||
// Explicitly using EIP-1559
|
||||
// Populate missing fee data
|
||||
if (tx.maxFeePerGas == null) {
|
||||
tx.maxFeePerGas = feeData.maxFeePerGas;
|
||||
}
|
||||
if (tx.maxPriorityFeePerGas == null) {
|
||||
tx.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas;
|
||||
}
|
||||
}
|
||||
_a.label = 5;
|
||||
case 5:
|
||||
if (tx.nonce == null) {
|
||||
tx.nonce = this.getTransactionCount("pending");
|
||||
}
|
||||
@@ -281,7 +371,7 @@ var Signer = /** @class */ (function () {
|
||||
});
|
||||
}
|
||||
return [4 /*yield*/, properties_1.resolveProperties(tx)];
|
||||
case 2: return [2 /*return*/, _a.sent()];
|
||||
case 6: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"author": "Richard Moore <me@ricmoo.com>",
|
||||
"dependencies": {
|
||||
"@ethersproject/abstract-provider": "^5.1.0",
|
||||
"@ethersproject/bignumber": "^5.1.0",
|
||||
"@ethersproject/bytes": "^5.1.0",
|
||||
"@ethersproject/logger": "^5.1.0",
|
||||
"@ethersproject/properties": "^5.1.0"
|
||||
"@ethersproject/abstract-provider": "^5.4.0",
|
||||
"@ethersproject/bignumber": "^5.4.0",
|
||||
"@ethersproject/bytes": "^5.4.0",
|
||||
"@ethersproject/logger": "^5.4.0",
|
||||
"@ethersproject/properties": "^5.4.0"
|
||||
},
|
||||
"description": "An Abstract Class for desribing an Ethereum Signer for ethers.",
|
||||
"ethereum": "donations.ethers.eth",
|
||||
@@ -39,7 +39,7 @@
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"tarballHash": "0x56d53f21cca4bb8b1b1f7c25edf66e7633dbe56c90164546110f4702c6d0650e",
|
||||
"tarballHash": "0x8c090123662370f27356110b775c8ae479d2fbe3e6794b33bdcc9a4ab70ebaed",
|
||||
"types": "./lib/index.d.ts",
|
||||
"version": "5.1.0"
|
||||
"version": "5.4.0"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user