Compare commits
372 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a71f518255 | ||
|
|
a27ef82577 | ||
|
|
30b716bf2c | ||
|
|
e85e32b8f7 | ||
|
|
56fabe987b | ||
|
|
cf7d9da290 | ||
|
|
13dd42c6c3 | ||
|
|
d06aa26d74 | ||
|
|
ed7e6a500e | ||
|
|
a3012977b1 | ||
|
|
8b62aeff9c | ||
|
|
95708b9a4a | ||
|
|
1e6a3c23c4 | ||
|
|
8e31b4dcf4 | ||
|
|
d5815cc4f1 | ||
|
|
01aea705ce | ||
|
|
2c3dae0874 | ||
|
|
c6eebf9928 | ||
|
|
32b7373456 | ||
|
|
fc1e006575 | ||
|
|
d9f45b3b9d | ||
|
|
8a7b5efad0 | ||
|
|
24bd3281f7 | ||
|
|
3f631e9681 | ||
|
|
8770cc46fd | ||
|
|
04c0515f0b | ||
|
|
4467d9fa00 | ||
|
|
1a5af9b8e2 | ||
|
|
bd152f7ea0 | ||
|
|
24c3caae14 | ||
|
|
bebd6698c6 | ||
|
|
a72e404259 | ||
|
|
7b299dd9c9 | ||
|
|
9bf17fa07c | ||
|
|
66d6aaf4b4 | ||
|
|
f599d6f23d | ||
|
|
7a15201786 | ||
|
|
7bc9c6b953 | ||
|
|
0855d6e9f5 | ||
|
|
948f77050d | ||
|
|
9e57e71dc0 | ||
|
|
dab6ede226 | ||
|
|
1f6c0ab281 | ||
|
|
056d7c8bfc | ||
|
|
47c41143cb | ||
|
|
ef1b28e958 | ||
|
|
e192903050 | ||
|
|
9d9b14b952 | ||
|
|
bc400c7b87 | ||
|
|
120dcd024a | ||
|
|
04f7a9f3b7 | ||
|
|
e70f3fe26f | ||
|
|
ef529dc5e6 | ||
|
|
9f0967f21f | ||
|
|
774c310389 | ||
|
|
21fae9f0ba | ||
|
|
ce85a7e976 | ||
|
|
7c4a9083c2 | ||
|
|
7becc93ed0 | ||
|
|
540a670f94 | ||
|
|
ab628c285e | ||
|
|
9bff2cb3d9 | ||
|
|
96de58122a | ||
|
|
b1c7f5c21a | ||
|
|
905e98aa39 | ||
|
|
dca0d14d38 | ||
|
|
5998fea53d | ||
|
|
dfaa8ee7e6 | ||
|
|
fa4a29028d | ||
|
|
f46aa75ef1 | ||
|
|
d160bac273 | ||
|
|
be518c32ec | ||
|
|
26cdbab59b | ||
|
|
b8cda5dffd | ||
|
|
f67a9a8569 | ||
|
|
bae215eb7f | ||
|
|
54e6e57fce | ||
|
|
38e825cee6 | ||
|
|
16007d4d1e | ||
|
|
cf47ec5fd5 | ||
|
|
ae23bb76a9 | ||
|
|
33a029e457 | ||
|
|
c2a6a012bf | ||
|
|
6807a76b8d | ||
|
|
5f26fd55c9 | ||
|
|
c562150d26 | ||
|
|
4e8f004e9e | ||
|
|
9aac785395 | ||
|
|
1651389571 | ||
|
|
2d98b4fca1 | ||
|
|
f26074b92b | ||
|
|
eb91d708ac | ||
|
|
83891f9258 | ||
|
|
7b134bd5c9 | ||
|
|
e175448380 | ||
|
|
1d419b5829 | ||
|
|
95b2c72b12 | ||
|
|
7b0d02d30e | ||
|
|
0c72e0f1fd | ||
|
|
315ecfd19e | ||
|
|
c61f3bc2a0 | ||
|
|
1be096130c | ||
|
|
9eed04a6d5 | ||
|
|
82d6dcbdde | ||
|
|
4935f93015 | ||
|
|
3df0e06c64 | ||
|
|
18d8d1f34d | ||
|
|
7b80ba20fe | ||
|
|
f635af2684 | ||
|
|
813fcef4ad | ||
|
|
32c9a09762 | ||
|
|
03545aa78b | ||
|
|
03152ea014 | ||
|
|
0578a88efa | ||
|
|
3f5bc6ddc1 | ||
|
|
ab13887cda | ||
|
|
28f383300c | ||
|
|
4ba63acc10 | ||
|
|
3d6a7ec020 | ||
|
|
2f57c6a4ab | ||
|
|
d3d2953e8d | ||
|
|
0403314023 | ||
|
|
eb432aa1f4 | ||
|
|
617714d196 | ||
|
|
42784b8d38 | ||
|
|
50d712d6af | ||
|
|
c7e9715758 | ||
|
|
0844de4eb4 | ||
|
|
caa1983665 | ||
|
|
b8391b0e61 | ||
|
|
1e1c93effa | ||
|
|
b145898976 | ||
|
|
1bd91615ee | ||
|
|
d3079745c5 | ||
|
|
ecce86125d | ||
|
|
5899c8aec0 | ||
|
|
3de1b81501 | ||
|
|
ab319f2f4c | ||
|
|
5b94ce2966 | ||
|
|
91c577b611 | ||
|
|
2f363da5ff | ||
|
|
73a46efea3 | ||
|
|
8f3d71dc5f | ||
|
|
a5c6a468f4 | ||
|
|
8947fd405e | ||
|
|
cb43a99405 | ||
|
|
b7e61bd67e | ||
|
|
0a8be37b08 | ||
|
|
6582ede1ce | ||
|
|
f3c6d819f3 | ||
|
|
bee76a49b2 | ||
|
|
68095a48ae | ||
|
|
0e5419ec79 | ||
|
|
a48552a4fb | ||
|
|
ab806cad15 | ||
|
|
d5b41ce210 | ||
|
|
fb6d141723 | ||
|
|
7a404fb8ed | ||
|
|
f8adf82e16 | ||
|
|
8395cc146f | ||
|
|
8fc5914c5a | ||
|
|
cc250b2060 | ||
|
|
375627f6b1 | ||
|
|
d67f8fb778 | ||
|
|
45f367512d | ||
|
|
ad87b718a9 | ||
|
|
48c9e0bf39 | ||
|
|
d1d636b503 | ||
|
|
4166b2753d | ||
|
|
32a6b2a362 | ||
|
|
f2a32d0d5b | ||
|
|
5762a1f83d | ||
|
|
8320d534d7 | ||
|
|
c41b89a0c1 | ||
|
|
b6a061e7bf | ||
|
|
a662490e82 | ||
|
|
bdb54ac52b | ||
|
|
32a90b66f0 | ||
|
|
95b87f61a6 | ||
|
|
017b1feba2 | ||
|
|
accb85268c | ||
|
|
f0b3bc32d5 | ||
|
|
78e4273a32 | ||
|
|
dd09bf0735 | ||
|
|
4b163e9e73 | ||
|
|
aacb95cd6b | ||
|
|
e6315a6b3c | ||
|
|
3ac91a414c | ||
|
|
2dd5c1a6d2 | ||
|
|
2653449f3c | ||
|
|
cddb03880a | ||
|
|
e80f8dd4e6 | ||
|
|
1b4bc7a6a6 | ||
|
|
4e9394554b | ||
|
|
1d27d95670 | ||
|
|
2e431a5002 | ||
|
|
da4e107268 | ||
|
|
7175e2e99c | ||
|
|
68229ac0af | ||
|
|
7274cd06cf | ||
|
|
be3854e648 | ||
|
|
63f8b28223 | ||
|
|
593b4886ff | ||
|
|
6d1904c379 | ||
|
|
0aafca71db | ||
|
|
0d40156fcb | ||
|
|
576e9b54ab | ||
|
|
bc5cc2e7e3 | ||
|
|
660e69db71 | ||
|
|
551cfa0062 | ||
|
|
0f0d0c00d3 | ||
|
|
a1f8d188a7 | ||
|
|
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 | ||
|
|
ce8f1e4015 | ||
|
|
58488e78f9 | ||
|
|
29116593ba | ||
|
|
51f0e1a52f | ||
|
|
c086962302 | ||
|
|
c0daf437f7 | ||
|
|
8eaeba35f5 | ||
|
|
4a44865a8c | ||
|
|
725fe0aa32 | ||
|
|
08adc18a68 | ||
|
|
1fcf4b6ce6 | ||
|
|
7c8ae9cfcb | ||
|
|
0cd5fccfad | ||
|
|
53ee187443 | ||
|
|
4577444c44 | ||
|
|
1cb3199e5c | ||
|
|
25c3024a89 | ||
|
|
ae0d5eb7c2 | ||
|
|
b8df000c8f | ||
|
|
eb1ec2f231 | ||
|
|
b65508995c | ||
|
|
2a7dbf0571 | ||
|
|
0dc6f4a45b | ||
|
|
2534b1b3b2 | ||
|
|
a11602d066 | ||
|
|
bec066bcb5 | ||
|
|
ef5a2b4baa | ||
|
|
9e273220b6 | ||
|
|
d55ab6d4e6 | ||
|
|
1a7c4e89ef | ||
|
|
c84a5e62f5 | ||
|
|
6978cca17d | ||
|
|
0e3016bfae | ||
|
|
d50b2d7e65 | ||
|
|
941e4210c6 | ||
|
|
3b1d3fcee6 | ||
|
|
81fd628292 | ||
|
|
f9dd0996ca | ||
|
|
87ceaed4be | ||
|
|
0e1721b130 | ||
|
|
c47d2eba4d | ||
|
|
1db4ce12d4 | ||
|
|
6c43e20e7a | ||
|
|
b2ecffb0c8 | ||
|
|
a953f71752 | ||
|
|
c5a53d6911 | ||
|
|
bcda16df1d | ||
|
|
d937668dc1 | ||
|
|
8279120e0a | ||
|
|
243beffa4f | ||
|
|
3a76d69a16 | ||
|
|
5b41675f33 | ||
|
|
80cde06bcc | ||
|
|
7d0b33dc42 | ||
|
|
173f4d44bf | ||
|
|
73e94349de | ||
|
|
796954f880 | ||
|
|
f0a88f551f | ||
|
|
f4b97c00ed | ||
|
|
38eccc8b9d | ||
|
|
a3b5f7132c | ||
|
|
a1e7db4abe | ||
|
|
689459c1fd | ||
|
|
755fc72094 | ||
|
|
620b7b91a1 | ||
|
|
fb9eea6c7e | ||
|
|
d83c583412 | ||
|
|
3f97b94d15 | ||
|
|
0ae9ac6f98 | ||
|
|
2333b6cfd2 | ||
|
|
73b31b371f | ||
|
|
fd0cf2cc54 | ||
|
|
27a981c84b |
67
.github/ISSUE_TEMPLATE/beta-issue.yml
vendored
Normal file
67
.github/ISSUE_TEMPLATE/beta-issue.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
name: Beta (v6) Bug
|
||||
description: Open an issue for a bug in the v6 beta
|
||||
title: "Title Here"
|
||||
labels: ["v6-beta"]
|
||||
assignees:
|
||||
- ricmoo
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
This form is **only** for issues in the **v6 beta**, which you can access using either the `v6-beta` tag in the repository or install using `ethers@beta` with `npm`.
|
||||
|
||||
The v6 branch will be very lively, undergoing a lot of changes, including backwards compatible changes between beta versions.
|
||||
|
||||
Before opening an issue, please make sure you have **fully updated to the latest version** by removing the `node_modules/` and `package-lock.json` and then running a fresh `npm install`. Otherwise you may end up with incompatible versions which may conflict with each other.
|
||||
|
||||
Thanks for trying out the v6 beta! Cheers!
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Ethers Beta Version
|
||||
description: What version of ethers are you using? Before opening an issue, please make sure you are using the latest beta.
|
||||
placeholder: x.y.z-beta.N
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: about-the-bug
|
||||
attributes:
|
||||
label: Describe the Problem
|
||||
description: Please describe what you expected to happen vs what did happen?
|
||||
placeholder: What happened?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: code-snippet
|
||||
attributes:
|
||||
label: Code Snippet
|
||||
description: If possible, please include a **short and concise** code snippets that can reproduce this issue. Ideally code that can be pasted into the [Ethers Playground](https://playground.ethers.org).
|
||||
placeholder: e.g. provider.getBlockNumber()
|
||||
render: shell
|
||||
- type: textarea
|
||||
id: errors
|
||||
attributes:
|
||||
label: Errors
|
||||
description: If there is an error, please include the **entire error** (redacting any sensitive information).
|
||||
placeholder: "e.g. Error: invalid name (code='INVALID_ARGUMENT, ...)"
|
||||
render: shell
|
||||
- type: dropdown
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment
|
||||
description: What environment, platforms or frameworks are you using? Select all that apply.
|
||||
multiple: true
|
||||
options:
|
||||
- node.js
|
||||
- Browser (Chrome, Safari, etc)
|
||||
- React Native/Expo/JavaScriptCore
|
||||
- Hardhat
|
||||
- Geth
|
||||
- Parity
|
||||
- Ganache
|
||||
- Other (please specify)
|
||||
- type: input
|
||||
id: other-envrionment
|
||||
attributes:
|
||||
label: Environment (Other)
|
||||
placeholder: anything else?
|
||||
81
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
81
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
name: Bug Report
|
||||
description: Open an issue for a bug in Ethers
|
||||
title: "Bug Report Title"
|
||||
labels: ["investigate"]
|
||||
assignees:
|
||||
- ricmoo
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**READ THIS FIRST** and follow all instructions, please. `:)`
|
||||
|
||||
Thank you for taking the time to report an issue. This form is for reporting **bugs within ethers**.
|
||||
|
||||
If you are **new to ethers** or *uncertain* whether this is a bug in ethers, a bug in another framework or a bug in your own code, please [start a discussion](https://github.com/ethers-io/ethers.js/discussions) first.
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Ethers Version
|
||||
description: What version of ethers are you using? Before opening an issue, please make sure you are up to date.
|
||||
placeholder: x.y.z
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: search-terms
|
||||
attributes:
|
||||
label: Search Terms
|
||||
description: Have you searched for answers [in the documentation](https://docs.ethers.io), through [the issues](https://github.com/ethers-io/ethers.js/issues) and [on the discusions](https://github.com/ethers-io/ethers.js/discussions)? Please include the search terms you have tried. This helps us add more keywords where needed.
|
||||
placeholder: e.g. abi, network, utf8
|
||||
- type: textarea
|
||||
id: about-the-bug
|
||||
attributes:
|
||||
label: Describe the Problem
|
||||
description: Please describe what you expected to happen vs what did happen?
|
||||
placeholder: What happened?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: code-snippet
|
||||
attributes:
|
||||
label: Code Snippet
|
||||
description: If possible, please include a **short and concise** code snippets that can reproduce this issue. Ideally code that can be pasted into the [Ethers Playground](https://playground.ethers.org).
|
||||
placeholder: e.g. provider.getBlockNumber()
|
||||
render: shell
|
||||
- type: textarea
|
||||
id: contract-abi
|
||||
attributes:
|
||||
label: Contract ABI
|
||||
description: If this involves a contract, please include any **concise and relevant** ABI fragments.
|
||||
placeholder: e.g. [ 'function balanceOf(address owner) view returns (uint)' ]
|
||||
render: shell
|
||||
- type: textarea
|
||||
id: errors
|
||||
attributes:
|
||||
label: Errors
|
||||
description: If there is an error, please include the **entire error** (redacting any sensitive information).
|
||||
placeholder: "e.g. Error: invalid name (code='INVALID_ARGUMENT, ...)"
|
||||
render: shell
|
||||
- type: dropdown
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment
|
||||
description: What environment, platforms or frameworks are you using? Select all that apply.
|
||||
multiple: true
|
||||
options:
|
||||
- Ethereum (mainnet/ropsten/rinkeby/goerli)
|
||||
- Altcoin - Please specify (e.g. Polygon)
|
||||
- node.js (v12 or newer)
|
||||
- node.js (older than v12)
|
||||
- Browser (Chrome, Safari, etc)
|
||||
- React Native/Expo/JavaScriptCore
|
||||
- Hardhat
|
||||
- Geth
|
||||
- Parity
|
||||
- Ganache
|
||||
- Other (please specify)
|
||||
- type: input
|
||||
id: other-envrionment
|
||||
attributes:
|
||||
label: Environment (Other)
|
||||
placeholder: anything else?
|
||||
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
|
||||
23
.github/ISSUE_TEMPLATE/documentation.yml
vendored
Normal file
23
.github/ISSUE_TEMPLATE/documentation.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: Documentation
|
||||
description: Documentation update, change or suggestion
|
||||
title: "Documentation Title"
|
||||
labels: ["documentation"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please include anything about the [documentation](https://docs.ethers.io) you would like to see improved.
|
||||
|
||||
- Missing information or details?
|
||||
- Spelling or Grammar mistakes?
|
||||
- Wrong Information?
|
||||
- Dead or wrong links?
|
||||
- Something needs code examples?
|
||||
- General feedback or anything else?
|
||||
- type: textarea
|
||||
id: suggestion
|
||||
attributes:
|
||||
label: Suggestion
|
||||
placeholder: e.g. please add an example for ropsten
|
||||
validations:
|
||||
required: true
|
||||
26
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
26
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Feature Request
|
||||
description: Suggest a new feature or addition to Ethers
|
||||
title: "Feature Request Title"
|
||||
labels: [ "enhancement" ]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
The best place to start a new feature request is by starting an [Idea discussion](https://github.com/ethers-io/ethers.js/discussions), to mull over the feature, discuss current options and think through the impact on the overall library.
|
||||
|
||||
Keep in mind that features increase the library size, and may require additional dependencies. Ethers strives to remain lean and the number of dependencies low, so many features may make more sense as ancillary packages.
|
||||
- type: textarea
|
||||
id: about-the-feature
|
||||
attributes:
|
||||
label: Describe the Feature
|
||||
description: Please describe the feature, the problem it is solving, your solution and alternatives you've considered.
|
||||
placeholder: e.g. I want Ethers to be more/less magical.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: code-example
|
||||
attributes:
|
||||
label: Code Example
|
||||
description: Optionally, provide an example of how the feature would be used in code.
|
||||
placeholder: e.g. provider.doMagic()
|
||||
render: shell
|
||||
56
.github/workflows/nodejs.yml
vendored
56
.github/workflows/nodejs.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [ 8.x, 10.x, 12.x, 13.x ]
|
||||
node-version: [ 12.x, 14.x, 16.x ]
|
||||
|
||||
steps:
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
@@ -69,33 +69,33 @@ jobs:
|
||||
- name: Run tests
|
||||
run: npm run test-browser-${{ matrix.module }}
|
||||
|
||||
test-react-native:
|
||||
|
||||
runs-on: macos-latest
|
||||
|
||||
# Temporary for testing CI
|
||||
continue-on-error: true
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- name: Use Node.js 12.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12.x
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install dependencies (and link per package)
|
||||
run: npm ci
|
||||
|
||||
- name: Build CommonJS and ESM (from TypeScript)
|
||||
run: npm run build-all
|
||||
|
||||
- name: Run tests
|
||||
run: npm run test-react
|
||||
# test-react-native:
|
||||
#
|
||||
# runs-on: macos-latest
|
||||
#
|
||||
# # Temporary for testing CI
|
||||
# continue-on-error: true
|
||||
#
|
||||
# strategy:
|
||||
# fail-fast: false
|
||||
#
|
||||
# steps:
|
||||
# - name: Use Node.js 12.x
|
||||
# uses: actions/setup-node@v1
|
||||
# with:
|
||||
# node-version: 12.x
|
||||
#
|
||||
# - name: Checkout repository
|
||||
# uses: actions/checkout@v2
|
||||
#
|
||||
# - name: Install dependencies (and link per package)
|
||||
# run: npm ci
|
||||
#
|
||||
# - name: Build CommonJS and ESM (from TypeScript)
|
||||
# run: npm run build-all
|
||||
#
|
||||
# - name: Run tests
|
||||
# run: npm run test-react
|
||||
|
||||
|
||||
coverage:
|
||||
|
||||
302
CHANGELOG.md
302
CHANGELOG.md
@@ -3,6 +3,308 @@ Changelog
|
||||
|
||||
This change log is managed by `admin/cmds/update-versions` but may be manually updated.
|
||||
|
||||
|
||||
ethers/v5.6.8 (2022-05-24 11:50)
|
||||
--------------------------------
|
||||
|
||||
- Update BN.js for hexstring bug fix. ([#3017](https://github.com/ethers-io/ethers.js/issues/3017); [30b716b](https://github.com/ethers-io/ethers.js/commit/30b716bf2cfd67ca38f76e344a26c0c2d5b75935), [a27ef82](https://github.com/ethers-io/ethers.js/commit/a27ef825772f72071439c51e51180b6fcc64f03c))
|
||||
|
||||
ethers/v5.6.7 (2022-05-20 19:11)
|
||||
--------------------------------
|
||||
|
||||
- Add Skynet support. ([#2853](https://github.com/ethers-io/ethers.js/issues/2853), [#2866](https://github.com/ethers-io/ethers.js/issues/2866); [13dd42c](https://github.com/ethers-io/ethers.js/commit/13dd42c6c38d6977645555cdf7ab60354b0e2725))
|
||||
- Fix WebWorker support in rollup files. ([#2976](https://github.com/ethers-io/ethers.js/issues/2976); [d06aa26](https://github.com/ethers-io/ethers.js/commit/d06aa26d74eecd06149f908ce25dbaf867754c0e))
|
||||
- Remove superfluous logging. ([#2995](https://github.com/ethers-io/ethers.js/issues/2995); [ed7e6a5](https://github.com/ethers-io/ethers.js/commit/ed7e6a500e6087efcace8a5ff98997fbce2c6d6d))
|
||||
- Add matic and optimism support to default provider. ([a301297](https://github.com/ethers-io/ethers.js/commit/a3012977b1b10110ea15625754e8fc117e1ea147))
|
||||
- Use case-insensitive schemes for getDefaultProvider. ([#2320](https://github.com/ethers-io/ethers.js/issues/2320); [8b62aef](https://github.com/ethers-io/ethers.js/commit/8b62aeff9cce44cbd16ff41f8fc01ebb101f8265))
|
||||
- Pad position in JSON-RPC getStorageAt calls. ([#2982](https://github.com/ethers-io/ethers.js/issues/2982); [d5815cc](https://github.com/ethers-io/ethers.js/commit/d5815cc4f1c13e5265c748d8afc4c085a97b1945))
|
||||
|
||||
ethers/v5.6.6 (2022-05-12 17:29)
|
||||
--------------------------------
|
||||
|
||||
- Ensure gas estimate errors are not call exceptions in disguise. ([#2954](https://github.com/ethers-io/ethers.js/issues/2954); [2c3dae0](https://github.com/ethers-io/ethers.js/commit/2c3dae08745530b8c3ea3ab6c8f03e8fa8ac1e5c))
|
||||
- Added optimism to EtherscanProvider. ([#2968](https://github.com/ethers-io/ethers.js/issues/2968); [c6eebf9](https://github.com/ethers-io/ethers.js/commit/c6eebf9928597cab305b663fa409d30e3122e7d0))
|
||||
- Remove pedantic check for new keyword which broke some platforms for inheritance. ([#2860](https://github.com/ethers-io/ethers.js/issues/2860), [#2861](https://github.com/ethers-io/ethers.js/issues/2861); [32b7373](https://github.com/ethers-io/ethers.js/commit/32b7373456972e0fbd47e7edaf056ed130adf1da))
|
||||
|
||||
ethers/v5.6.5 (2022-05-01 02:10)
|
||||
--------------------------------
|
||||
|
||||
- Added testnets for AnkrProvider. ([#2949](https://github.com/ethers-io/ethers.js/issues/2949), [#2950](https://github.com/ethers-io/ethers.js/issues/2950); [d9f45b3](https://github.com/ethers-io/ethers.js/commit/d9f45b3b9db92c72f9c606bab8315d0eb02fec70))
|
||||
- Better error coalescing for OpenEthereum nodes. ([#2846](https://github.com/ethers-io/ethers.js/issues/2846); [bebd669](https://github.com/ethers-io/ethers.js/commit/bebd6698c6c3193f0bdb96b54c5daa5ee5d0692c))
|
||||
- Enforce 32-byte private key length (2926). ([7b299dd](https://github.com/ethers-io/ethers.js/commit/7b299dd9c97571b12916e3ae529540f3f2e5a367))
|
||||
- Fixed decimal strings as value-type properties for JsonRpcSigner. ([#2948](https://github.com/ethers-io/ethers.js/issues/2948); [9bf17fa](https://github.com/ethers-io/ethers.js/commit/9bf17fa07c6149a02ef217f2b89f1bfd990b1a6c))
|
||||
|
||||
ethers/v5.6.4 (2022-04-13 16:56)
|
||||
--------------------------------
|
||||
|
||||
- Support new OpenEthereum NONCE_EXPIRED string. ([#2845](https://github.com/ethers-io/ethers.js/issues/2845), [#2846](https://github.com/ethers-io/ethers.js/issues/2846); [0855d6e](https://github.com/ethers-io/ethers.js/commit/0855d6e9f593515b639c10a3f65bad712c68221c))
|
||||
|
||||
ethers/v5.6.3 (2022-04-13 00:23)
|
||||
--------------------------------
|
||||
|
||||
- Mimic Hardhard error strings in CALL_EXCEPTION for popular matchers. ([#2849](https://github.com/ethers-io/ethers.js/issues/2849), [#2862](https://github.com/ethers-io/ethers.js/issues/2862); [dab6ede](https://github.com/ethers-io/ethers.js/commit/dab6ede226e572706655e2865d4c953e37741a5c))
|
||||
- Fix pocket API key not being passed in for default provider. ([#2890](https://github.com/ethers-io/ethers.js/issues/2890); [056d7c8](https://github.com/ethers-io/ethers.js/commit/056d7c8bfc5896759c383d7cfae8ed0ec5c5eefb))
|
||||
|
||||
ethers/v5.6.2 (2022-03-25 17:56)
|
||||
--------------------------------
|
||||
|
||||
- Fixed left-padding in arrayify. ([#2833](https://github.com/ethers-io/ethers.js/issues/2833); [e192903](https://github.com/ethers-io/ethers.js/commit/e19290305080ebdfa2cb2ab2719cb53fee5a6cc7))
|
||||
- More robust JSON-RPC error handling for reverted executions. ([#2603](https://github.com/ethers-io/ethers.js/issues/2603); [9d9b14b](https://github.com/ethers-io/ethers.js/commit/9d9b14b95299b793c1a0f4cb8f42e4e0252fed1c))
|
||||
- Added IPNS support for ENS contenthash. ([e70f3fe](https://github.com/ethers-io/ethers.js/commit/e70f3fe26f3b0dfd44fdbc163e2cc6c8eb9433f8))
|
||||
- Added initial AnkrProvider ([96de581](https://github.com/ethers-io/ethers.js/commit/96de58122af57be761e431e9268958eeaa352480))
|
||||
|
||||
ethers/v5.6.1 (2022-03-16 01:25)
|
||||
--------------------------------
|
||||
|
||||
- Fix issue with CCIP Read using wrong sender. ([#2478](https://github.com/ethers-io/ethers.js/issues/2478); [5998fea](https://github.com/ethers-io/ethers.js/commit/5998fea53d5ea26358c2f10939dfdf0bc679936d), [905e98a](https://github.com/ethers-io/ethers.js/commit/905e98aa392e2a52d6b0339b21bfce5237fd8662))
|
||||
|
||||
ethers/v5.6.0 (2022-03-09 14:57)
|
||||
--------------------------------
|
||||
|
||||
- Tweaked test case to re-order transaction after event listeners added. ([fa4a290](https://github.com/ethers-io/ethers.js/commit/fa4a29028d97d598b43b2f5ff98077e8cadf56a4))
|
||||
- Ignore errors when resolving ENS resolver properties. ([d160bac](https://github.com/ethers-io/ethers.js/commit/d160bac273775f928a9441b0275dbdb6032368fa))
|
||||
- Enable CCIP Read for ENS resolvers. ([#2478](https://github.com/ethers-io/ethers.js/issues/2478); [be518c3](https://github.com/ethers-io/ethers.js/commit/be518c32ec7db9dd4769b57cdf130eb333aebb72))
|
||||
- Fix missing events on certain network conditions. ([#1798](https://github.com/ethers-io/ethers.js/issues/1798), [#1814](https://github.com/ethers-io/ethers.js/issues/1814), [#1830](https://github.com/ethers-io/ethers.js/issues/1830), [#2274](https://github.com/ethers-io/ethers.js/issues/2274), [#2652](https://github.com/ethers-io/ethers.js/issues/2652); [f67a9a8](https://github.com/ethers-io/ethers.js/commit/f67a9a8569cdfd0ef9ce5fbf09866aab6e4814d4), [f46aa75](https://github.com/ethers-io/ethers.js/commit/f46aa75ef1f3428e640cd046db3f080d264b32f3))
|
||||
- Added defaultProvider option to omit specific Providers. ([bae215e](https://github.com/ethers-io/ethers.js/commit/bae215eb7fb3efea8473a544579abac1bebb7ef0))
|
||||
- Add support for pending blocks. ([#2225](https://github.com/ethers-io/ethers.js/issues/2225); [54e6e57](https://github.com/ethers-io/ethers.js/commit/54e6e57fcece4c1718a577ecbeb1af97998e8bdc))
|
||||
- Help URLs for errors. ([#2489](https://github.com/ethers-io/ethers.js/issues/2489); [38e825c](https://github.com/ethers-io/ethers.js/commit/38e825cee624ff935ec6b70023cf288126a6bb85), [c562150](https://github.com/ethers-io/ethers.js/commit/c562150d2678710f50e5ee3ffa88d0e62d6f696f))
|
||||
- Added CCIP support to provider.call. ([#2478](https://github.com/ethers-io/ethers.js/issues/2478); [ae23bb7](https://github.com/ethers-io/ethers.js/commit/ae23bb76a937924bf57baf679e6efd8cdf59bc47))
|
||||
- Adjust default maxPriorityFeePerGas to 1.5 gwei. ([33a029e](https://github.com/ethers-io/ethers.js/commit/33a029e457320a226c68a01f4cfa2d110125a8b8))
|
||||
- Fix contracts when name resolution fails without any checks. ([#2737](https://github.com/ethers-io/ethers.js/issues/2737); [c2a6a01](https://github.com/ethers-io/ethers.js/commit/c2a6a012bf1d8fcd5805e45754cebdfe211c6933))
|
||||
- Preserve explicit chainId in JsonRpcProvider during transaction serialization. ([#2691](https://github.com/ethers-io/ethers.js/issues/2691); [6807a76](https://github.com/ethers-io/ethers.js/commit/6807a76b8ddfdd121f98b21e269de3b195a7673e))
|
||||
- Fixed eth_chainId response for Eip1193Bridge. ([#2711](https://github.com/ethers-io/ethers.js/issues/2711); [5f26fd5](https://github.com/ethers-io/ethers.js/commit/5f26fd55c9d010c00f830a4c83a480a54773858d))
|
||||
- Remove spurious console.log from Interface. ([#2714](https://github.com/ethers-io/ethers.js/issues/2714); [4e8f004](https://github.com/ethers-io/ethers.js/commit/4e8f004e9e42892840663311cafe042c0b24c61e))
|
||||
- Allow raw WebSocket to be passed into WebSocketProvider. ([#2562](https://github.com/ethers-io/ethers.js/issues/2562), [#2644](https://github.com/ethers-io/ethers.js/issues/2644); [9aac785](https://github.com/ethers-io/ethers.js/commit/9aac785395e9b47655477a3ba7baf05df3274de9))
|
||||
- Added Cloudflare Worker support. ([#1886](https://github.com/ethers-io/ethers.js/issues/1886); [2d98b4f](https://github.com/ethers-io/ethers.js/commit/2d98b4fca1eb2544fec728f7c1c7b0d450e0dbee), [1651389](https://github.com/ethers-io/ethers.js/commit/1651389571b5dd16c1c056dcd94729b48a4bdd85))
|
||||
- Add support for EIP-2098 compact signatures. ([#2246](https://github.com/ethers-io/ethers.js/issues/2246); [f26074b](https://github.com/ethers-io/ethers.js/commit/f26074b92b0fc8efd3d85c68e84cc6ff8897e4a8))
|
||||
- Add EIP-2544 Wildcard support. ([#2477](https://github.com/ethers-io/ethers.js/issues/2477), [#2582](https://github.com/ethers-io/ethers.js/issues/2582), [#2583](https://github.com/ethers-io/ethers.js/issues/2583); [83891f9](https://github.com/ethers-io/ethers.js/commit/83891f9258492f9801aa579ac50764b6491b6180))
|
||||
|
||||
ethers/v5.5.4 (2022-01-24 16:45)
|
||||
--------------------------------
|
||||
|
||||
- Support invalid but popular IPFS URI format. ([#2271](https://github.com/ethers-io/ethers.js/issues/2271), [#2527](https://github.com/ethers-io/ethers.js/issues/2527), [#2590](https://github.com/ethers-io/ethers.js/issues/2590); [03545aa](https://github.com/ethers-io/ethers.js/commit/03545aa78b0e7bd177e22432e4842b0580a11d7d))
|
||||
|
||||
ethers/v5.5.3 (2022-01-06 03:52)
|
||||
--------------------------------
|
||||
|
||||
- Fixed case-folding in schemes for ENS avatars. ([#2500](https://github.com/ethers-io/ethers.js/issues/2500); [3f5bc6d](https://github.com/ethers-io/ethers.js/commit/3f5bc6ddc1013f0a5974f2ee6f542d6c91480c13))
|
||||
- Added Kintsugi network. ([#2434](https://github.com/ethers-io/ethers.js/issues/2434); [ab13887](https://github.com/ethers-io/ethers.js/commit/ab13887cda3939703dc1f7e27d139ef6001b7dd2))
|
||||
- Fix browser random in WebWorkers. ([#2405](https://github.com/ethers-io/ethers.js/issues/2405); [4ba63ac](https://github.com/ethers-io/ethers.js/commit/4ba63acc107fdd0a6d6ef3e27349e65edb007447))
|
||||
- Add support for IPFS metadata imageUrl in getAvatar. ([#2426](https://github.com/ethers-io/ethers.js/issues/2426); [3d6a7ec](https://github.com/ethers-io/ethers.js/commit/3d6a7ec020eacd993b4b0fd3274574de3ddcc257))
|
||||
- Do not swallow ENS not supported errors. ([#2387](https://github.com/ethers-io/ethers.js/issues/2387); [2f57c6a](https://github.com/ethers-io/ethers.js/commit/2f57c6a4ab44083b2c03f5e57b2702ab7078d286))
|
||||
|
||||
ethers/v5.5.2 (2021-11-30 19:16)
|
||||
--------------------------------
|
||||
|
||||
- Fixed test case for getAvatar; url has moved ([617714d](https://github.com/ethers-io/ethers.js/commit/617714d19632c7b4789f042ef8357f858421fbae))
|
||||
- Added basic redirect support. ([42784b8](https://github.com/ethers-io/ethers.js/commit/42784b8d38a96170d19ea8adcbc42ebf7415804c))
|
||||
- Added arbitrum and optimism to networks and providers. ([#2335](https://github.com/ethers-io/ethers.js/issues/2335); [0844de4](https://github.com/ethers-io/ethers.js/commit/0844de4eb45eb4170fafb6f2a239b53b6be22f1c))
|
||||
- Added support for data URLs for avatar metadata. ([b8391b0](https://github.com/ethers-io/ethers.js/commit/b8391b0e61bf3627702668920c4fd6506f9bdc60))
|
||||
- Fixed getAvatar for unconfigured ENS names. ([1e1c93e](https://github.com/ethers-io/ethers.js/commit/1e1c93effa083765be52f3dee10400a9b3eeb003))
|
||||
|
||||
ethers/v5.5.1 (2021-10-20 03:59)
|
||||
--------------------------------
|
||||
|
||||
- Fixed abstract Provider signature issue. ([#2190](https://github.com/ethers-io/ethers.js/issues/2190); [1bd9161](https://github.com/ethers-io/ethers.js/commit/1bd91615eedcb34a24fca04aa93a9aac394968ed))
|
||||
|
||||
ethers/v5.5.0 (2021-10-19 00:01)
|
||||
--------------------------------
|
||||
|
||||
- Added ENS avatar support to provider. ([#2185](https://github.com/ethers-io/ethers.js/issues/2185); [ecce861](https://github.com/ethers-io/ethers.js/commit/ecce86125d87ef5258406bde2fff5bc8c9ff3141))
|
||||
- Fixed splitSignature logic for verifying EIP-2930 and EIP-1559 v. ([#2084](https://github.com/ethers-io/ethers.js/issues/2084); [3de1b81](https://github.com/ethers-io/ethers.js/commit/3de1b815014b10d223a42e524fe9c25f9087293b))
|
||||
- Include events on ContractFactory deployment transactions. ([#1334](https://github.com/ethers-io/ethers.js/issues/1334); [ab319f2](https://github.com/ethers-io/ethers.js/commit/ab319f2f4c365d4cd1b1e17e577ecd18a7a89276))
|
||||
- admin: fixed alias script. ([#1494](https://github.com/ethers-io/ethers.js/issues/1494); [8f3d71d](https://github.com/ethers-io/ethers.js/commit/8f3d71dc5fd0e91407737a4b82c58c31269ed2be))
|
||||
- Better errors when non-string address or ENS name is passed into Contracts or provider methods. ([#1051](https://github.com/ethers-io/ethers.js/issues/1051); [a5c6a46](https://github.com/ethers-io/ethers.js/commit/a5c6a468f4a7ad29fb5277e08c6b8b208383a575))
|
||||
- Use personal_sign instead of eth_sign for message signing with JsonRpcSigner; added _legacySignMessage for legacy support. ([#1542](https://github.com/ethers-io/ethers.js/issues/1542), [#1840](https://github.com/ethers-io/ethers.js/issues/1840); [8947fd4](https://github.com/ethers-io/ethers.js/commit/8947fd405e3aea07f6db958d89a3ad39abe3a25a))
|
||||
- Removed extra wordlists from the dist files. ([#2058](https://github.com/ethers-io/ethers.js/issues/2058), [#2077](https://github.com/ethers-io/ethers.js/issues/2077); [cb43a99](https://github.com/ethers-io/ethers.js/commit/cb43a99405cdc5bdcc875efc1821e00e55447791))
|
||||
- Fix issue when Solidity method collises with JavaScript prototype. ([#1432](https://github.com/ethers-io/ethers.js/issues/1432), [#2054](https://github.com/ethers-io/ethers.js/issues/2054), [#2120](https://github.com/ethers-io/ethers.js/issues/2120); [0a8be37](https://github.com/ethers-io/ethers.js/commit/0a8be37b087470d9354f387d7c439cb0166eaf4d))
|
||||
- Add support for Cloudflare Workers. ([#1886](https://github.com/ethers-io/ethers.js/issues/1886); [6582ede](https://github.com/ethers-io/ethers.js/commit/6582ede1ce46be0b3abafb120e052b95a2d172b3))
|
||||
- Added more information to some invalid argument errors. ([#1130](https://github.com/ethers-io/ethers.js/issues/1130); [f3c6d81](https://github.com/ethers-io/ethers.js/commit/f3c6d819f34b6d93f53d98b9f337ade5aa37a594))
|
||||
- Fix compile-time error in new TypeScript version. ([bee76a4](https://github.com/ethers-io/ethers.js/commit/bee76a49b2e5f95ea2eab49aabf5e44cb4ca794b))
|
||||
- Adding customData support to transactions to assist L2 chains. ([#1761](https://github.com/ethers-io/ethers.js/issues/1761); [68095a4](https://github.com/ethers-io/ethers.js/commit/68095a48ae19ed06cbcf2f415f1fcbda90d4b2ae))
|
||||
- Added some explicit null results to previously implicit null results for ENS. ([#1850](https://github.com/ethers-io/ethers.js/issues/1850); [0e5419e](https://github.com/ethers-io/ethers.js/commit/0e5419ec79cb18d82bab8c47bfa3ab4a21cfd293))
|
||||
- Added BigNumber _difficulty to Block results. ([#2001](https://github.com/ethers-io/ethers.js/issues/2001), [#2036](https://github.com/ethers-io/ethers.js/issues/2036); [a48552a](https://github.com/ethers-io/ethers.js/commit/a48552a4fb85a08178d07437a3934db98b7d0736))
|
||||
- Removed redundant call to normalizing blockTag (#1838). ([d5b41ce](https://github.com/ethers-io/ethers.js/commit/d5b41ce210c0f22dd795749810f6ce798f71a00f))
|
||||
- Fixed isBytes check for invalid length or elements. ([#1964](https://github.com/ethers-io/ethers.js/issues/1964); [7a404fb](https://github.com/ethers-io/ethers.js/commit/7a404fb8ed95a99baab8f3b384f438b697fa5d76))
|
||||
- Fixed randomBytes not rejecting NaN as a length. ([#1977](https://github.com/ethers-io/ethers.js/issues/1977); [f8adf82](https://github.com/ethers-io/ethers.js/commit/f8adf82e16aaad1a7c1750e7f2e3a9f8073b73e1))
|
||||
- Allow any Networkish for getDefaultProvider. ([#2031](https://github.com/ethers-io/ethers.js/issues/2031); [cc250b2](https://github.com/ethers-io/ethers.js/commit/cc250b2060451e0ee6b1cf3edb6b005f9eee9c61))
|
||||
- Stop allowing commas in fixed numbers; left over from legacy comma support. ([#2083](https://github.com/ethers-io/ethers.js/issues/2083); [45f3675](https://github.com/ethers-io/ethers.js/commit/45f367512d1d5dccfd06fad9cc8688e4d0cccdb8))
|
||||
- Export FallbackProviderConfig. ([#2121](https://github.com/ethers-io/ethers.js/issues/2121); [48c9e0b](https://github.com/ethers-io/ethers.js/commit/48c9e0bf39eec9b5b30ab7cd5685effdccaa1b1a))
|
||||
|
||||
ethers/v5.4.7 (2021-09-16 13:17)
|
||||
--------------------------------
|
||||
|
||||
- Fix parseUints with excess zeros and fix ReDoS issue. ([#2016](https://github.com/ethers-io/ethers.js/issues/2016), [#1975](https://github.com/ethers-io/ethers.js/issues/1975), [#1976](https://github.com/ethers-io/ethers.js/issues/1976); [32a6b2a](https://github.com/ethers-io/ethers.js/commit/32a6b2a362815eb85ce3f3abad5adf92f2b80e10))
|
||||
|
||||
ethers/v5.4.6 (2021-08-27 15:34)
|
||||
--------------------------------
|
||||
|
||||
- Temporarily remove the block miner for clique-based networks from CI testing. ([#1967](https://github.com/ethers-io/ethers.js/issues/1967); [8320d53](https://github.com/ethers-io/ethers.js/commit/8320d534d78173dfa8ecb4def634a00483a6aa9c))
|
||||
- More readable errors involving Uint8Arrays. ([b6a061e](https://github.com/ethers-io/ethers.js/commit/b6a061e7bfd14c1f2df1418df37f704275908e8b))
|
||||
- Added Deferred Error support to Description objects to extent Interface parse methods. ([#1894](https://github.com/ethers-io/ethers.js/issues/1894); [a662490](https://github.com/ethers-io/ethers.js/commit/a662490e82a9b71b5f6dee0a8242e6fa78409d79))
|
||||
- Fix address coder to prepare non-hexdatastring addresses as hexdatastring. ([#1906](https://github.com/ethers-io/ethers.js/issues/1906); [017b1fe](https://github.com/ethers-io/ethers.js/commit/017b1feba2c9dea88f078b299d211cbd58d43b49))
|
||||
- Removed temporary code for better errors needed until Alchemy added EIP-1559 support. ([#1893](https://github.com/ethers-io/ethers.js/issues/1893); [accb852](https://github.com/ethers-io/ethers.js/commit/accb85268c92fa894e769ec1dca322e117d33e5f))
|
||||
|
||||
ethers/v5.4.5 (2021-08-18 03:05)
|
||||
--------------------------------
|
||||
|
||||
- Fxied getBlockWithTransactions results (#1858). ([78e4273](https://github.com/ethers-io/ethers.js/commit/78e4273a327d12da9a1ec008d3f2146d97385921))
|
||||
|
||||
ethers/v5.4.4 (2021-08-04 01:37)
|
||||
--------------------------------
|
||||
|
||||
- Fixed Etherscan API key in default provider. ([#1807](https://github.com/ethers-io/ethers.js/issues/1807); [1d27d95](https://github.com/ethers-io/ethers.js/commit/1d27d95670ee3a51879393fed44297128c4a42a3))
|
||||
- Adjust default masPriorityFeePerGas to account for MEV-heavy blocks. ([#1817](https://github.com/ethers-io/ethers.js/issues/1817); [7175e2e](https://github.com/ethers-io/ethers.js/commit/7175e2e99c2747e8d2314feb407bf0a0f9371ece))
|
||||
|
||||
ethers/v5.4.3 (2021-07-29 23:26)
|
||||
--------------------------------
|
||||
|
||||
- Fixed JsonRpcProvider for pre-EIP-2930 chains. ([#1766](https://github.com/ethers-io/ethers.js/issues/1766); [7274cd0](https://github.com/ethers-io/ethers.js/commit/7274cd06cf3f6f31c6df3fd6636706d8536b7ee2))
|
||||
- Forward some missing EIP-1559 fields to call and estimateGas. ([#1766](https://github.com/ethers-io/ethers.js/issues/1766); [be3854e](https://github.com/ethers-io/ethers.js/commit/be3854e648fdef0478db8a64c26be6d9e90cf453))
|
||||
- Fixed possible UnhandledPromiseException for bad ENS names. ([63f8b28](https://github.com/ethers-io/ethers.js/commit/63f8b2822318d1e0fcc41f4662feb6e5ae338f3d))
|
||||
- Prevent overriding value for non-payble constructors. ([#1785](https://github.com/ethers-io/ethers.js/issues/1785); [593b488](https://github.com/ethers-io/ethers.js/commit/593b4886ff607d00d656b8131b843933eb48838e))
|
||||
|
||||
ethers/v5.4.2 (2021-07-23 17:22)
|
||||
--------------------------------
|
||||
|
||||
- Fix test case for new transactions responses. ([0aafca7](https://github.com/ethers-io/ethers.js/commit/0aafca71dbc019beb398e1b5a0f24936a4fd215a))
|
||||
- Added matic support to INFURA and Alchemy. ([#1546](https://github.com/ethers-io/ethers.js/issues/1546); [576e9b5](https://github.com/ethers-io/ethers.js/commit/576e9b54abc3ff048113f93f765aa3177bf3b819))
|
||||
- Added string change to coalesce errors on some clients. ([bc5cc2e](https://github.com/ethers-io/ethers.js/commit/bc5cc2e7e34f6cc69c43c1665be9c18854fb26b8))
|
||||
- Added wait to transactions returned by getBlockWithTransactions. ([#971](https://github.com/ethers-io/ethers.js/issues/971); [660e69d](https://github.com/ethers-io/ethers.js/commit/660e69db71d42084b1fe791d864d13f0111f84fb))
|
||||
- Fixed floor, ceiling and round for FixedNumber for non-default Formats. ([#1749](https://github.com/ethers-io/ethers.js/issues/1749); [551cfa0](https://github.com/ethers-io/ethers.js/commit/551cfa0062ec1645c9310335e0e6cbd250bb3788))
|
||||
- Fixed null confirmations in Wallet transaction. ([#1706](https://github.com/ethers-io/ethers.js/issues/1706); [0f0d0c0](https://github.com/ethers-io/ethers.js/commit/0f0d0c00d3fc14e5454169d42a9286b1d8b0abef))
|
||||
- Fixed Etherscan string change and enabled all tests. ([a1f8d18](https://github.com/ethers-io/ethers.js/commit/a1f8d188a7bc0b0d11426b7ef0d018cc1b7b399d))
|
||||
|
||||
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)
|
||||
--------------------------------
|
||||
|
||||
- Fixed JsonRpcProvider event-loop caching when using any network. ([#1484](https://github.com/ethers-io/ethers.js/issues/1484); [58488e7](https://github.com/ethers-io/ethers.js/commit/58488e78f9ef79715693e19b42663335aad88c03))
|
||||
- Updated experimental Eip1193Bridge to support final EIP-1193 API. ([2911659](https://github.com/ethers-io/ethers.js/commit/29116593ba6c9c0fa491b13787cca8b233d4218c))
|
||||
- Fail early for ABI decoding that will obviously run out of data. ([#1486](https://github.com/ethers-io/ethers.js/issues/1486); [51f0e1a](https://github.com/ethers-io/ethers.js/commit/51f0e1a52fb885e6f146f7b3b70ed487fd1c8f5a))
|
||||
- Fixed BigNumber toBigInt return type. ([#1485](https://github.com/ethers-io/ethers.js/issues/1485); [c086962](https://github.com/ethers-io/ethers.js/commit/c0869623024bbf3671938dad03b131ff2ac54345))
|
||||
|
||||
ethers/v5.1.2 (2021-04-18 19:31)
|
||||
--------------------------------
|
||||
|
||||
- Increase provider tests gas price for sending a transaction. ([8eaeba3](https://github.com/ethers-io/ethers.js/commit/8eaeba35f550c3d9aa1ae62eb8d8e0c912818f7f))
|
||||
- Fixed run-checking non-filter Contract events. ([#1458](https://github.com/ethers-io/ethers.js/issues/1458); [4a44865](https://github.com/ethers-io/ethers.js/commit/4a44865a8c22adb9c55d5c37a81ee46ebc68228c))
|
||||
|
||||
ethers/v5.1.1 (2021-04-18 02:47)
|
||||
--------------------------------
|
||||
|
||||
- Increased sendTransaction timeout to 15 minutes and pull Pocket from tx tests. ([08adc18](https://github.com/ethers-io/ethers.js/commit/08adc18a68bdc730633bdaaf2329014a84c12b2b))
|
||||
- Export Eip1193Bridge in experimental package. ([1fcf4b6](https://github.com/ethers-io/ethers.js/commit/1fcf4b6ce6922d2bcb245375c967da3072f113ed))
|
||||
- Prevent non-typed transactions from unsafely ignoring specified access lists. ([#1364](https://github.com/ethers-io/ethers.js/issues/1364); [4577444](https://github.com/ethers-io/ethers.js/commit/4577444c448f41114263077c5b54fbe6af749fd4))
|
||||
- Update tests for current EIP-2930 support across backends. ([#1364](https://github.com/ethers-io/ethers.js/issues/1364); [1cb3199](https://github.com/ethers-io/ethers.js/commit/1cb3199e5cb01f5a55eb00ab6c7904606d7ea1dd))
|
||||
- Removed underscore from the JsonRpcBatchProvider name. ([#62](https://github.com/ethers-io/ethers.js/issues/62), [#656](https://github.com/ethers-io/ethers.js/issues/656), [#892](https://github.com/ethers-io/ethers.js/issues/892); [ae0d5eb](https://github.com/ethers-io/ethers.js/commit/ae0d5eb7c2e37a003d893671db59c2d5719aea0f))
|
||||
- Added better error detection when pre-EIP-155 transactions are disabled. ([b8df000](https://github.com/ethers-io/ethers.js/commit/b8df000c8f0ccd252b6049ac5a32a986d5a8e08d))
|
||||
- Fix Android React Native environment shims which crash on normalizing Korean test. ([#1298](https://github.com/ethers-io/ethers.js/issues/1298); [eb1ec2f](https://github.com/ethers-io/ethers.js/commit/eb1ec2f2318e2851073ea1634e5003cdb53f1c1b))
|
||||
- Fixed EIP-2930 transactions for EtherscanProvider. ([#1364](https://github.com/ethers-io/ethers.js/issues/1364); [b655089](https://github.com/ethers-io/ethers.js/commit/b65508995ce7d02f109a970ebeb625819beb915a))
|
||||
- Re-enable AlchemyProvider Berlin tests. ([bec066b](https://github.com/ethers-io/ethers.js/commit/bec066bcb5ab8b95a7e7ce4848d7b76d7f248ccc))
|
||||
- Added experimental _JsonRpcBatchProvider. ([#62](https://github.com/ethers-io/ethers.js/issues/62), [#656](https://github.com/ethers-io/ethers.js/issues/656), [#892](https://github.com/ethers-io/ethers.js/issues/892); [d55ab6d](https://github.com/ethers-io/ethers.js/commit/d55ab6d4e6025c484cc7e64486d927bd54a0772b))
|
||||
- Cache JsonRpcProvider requests for certain methods per event loop. ([#1371](https://github.com/ethers-io/ethers.js/issues/1371); [1a7c4e8](https://github.com/ethers-io/ethers.js/commit/1a7c4e89efecc2b8afc8bea4c1f8f75fdaac08c5))
|
||||
|
||||
ethers/v5.1.0 (2021-03-30 14:44)
|
||||
--------------------------------
|
||||
|
||||
- Added BigNumber.toBigInt method. ([#1415](https://github.com/ethers-io/ethers.js/issues/1415); [81fd628](https://github.com/ethers-io/ethers.js/commit/81fd628292b7dde90fe5115074fa68476a872dbf))
|
||||
- Abstracted Contract with BaseContract without meta-class properties for easier extensions. ([#1384](https://github.com/ethers-io/ethers.js/issues/1384); [87ceaed](https://github.com/ethers-io/ethers.js/commit/87ceaed4be21283619da74678cf371c228c918b7))
|
||||
- Fixed Contract properties that collide with null member properties. ([#1393](https://github.com/ethers-io/ethers.js/issues/1393); [0e1721b](https://github.com/ethers-io/ethers.js/commit/0e1721b13084dacf63089e47116f7d5331be4f36))
|
||||
- Added EIP-2930 support. ([#1364](https://github.com/ethers-io/ethers.js/issues/1364); [c47d2eb](https://github.com/ethers-io/ethers.js/commit/c47d2eba4dc741eb5cb754c3ef5064b8ea7ac7cc))
|
||||
- Added abstraction for EIP-2718 support. ([1db4ce1](https://github.com/ethers-io/ethers.js/commit/1db4ce12d49e235a7155de24ee153f409e7e7370))
|
||||
|
||||
ethers/v5.0.32 (2021-03-07 18:17)
|
||||
---------------------------------
|
||||
|
||||
- Bumped TypeScript to 4.2.2. ([#1288](https://github.com/ethers-io/ethers.js/issues/1288); [b2ecffb](https://github.com/ethers-io/ethers.js/commit/b2ecffb0c8d44c8ee65199e7866dc744abae4e6e))
|
||||
- Fixed shims from not displaying debug information. ([a953f71](https://github.com/ethers-io/ethers.js/commit/a953f717523a844a3a45810a5acc6630383884d3))
|
||||
- Force TypedData numbers to be in decimal. ([#1193](https://github.com/ethers-io/ethers.js/issues/1193); [c5a53d6](https://github.com/ethers-io/ethers.js/commit/c5a53d6911d7c41dd03a290b550e80f2919e9379))
|
||||
|
||||
ethers/v5.0.31 (2021-02-12 19:04)
|
||||
---------------------------------
|
||||
|
||||
- Prevent unhandled rejections when passing nullish into Contract constructor. ([#1234](https://github.com/ethers-io/ethers.js/issues/1234); [d937668](https://github.com/ethers-io/ethers.js/commit/d937668dc1d39cc293f64bbd30b99b29614d1607))
|
||||
- Better error messaging when provider backends give bogus responses. ([#1243](https://github.com/ethers-io/ethers.js/issues/1243); [8279120](https://github.com/ethers-io/ethers.js/commit/8279120e0ad1cbb7aeabd32c08e168a4228abbec))
|
||||
- Prevent unconfigured ENS names from making an init tx. ([#1290](https://github.com/ethers-io/ethers.js/issues/1290); [243beff](https://github.com/ethers-io/ethers.js/commit/243beffa4f83c910f5f1c5e0554531e5dcf3ab93))
|
||||
|
||||
ethers/v5.0.30 (2021-02-08 15:22)
|
||||
---------------------------------
|
||||
|
||||
- When in Status trigger personal_sign instead of eth_sign. ([#1285](https://github.com/ethers-io/ethers.js/issues/1285); [73e9434](https://github.com/ethers-io/ethers.js/commit/73e94349de94d2969ccb21c834119525ddfcb961))
|
||||
- Bump elliptic version for CVE-2020-28498. ([#1284](https://github.com/ethers-io/ethers.js/issues/1284); [796954f](https://github.com/ethers-io/ethers.js/commit/796954f8807b0c464c7baa8f7ff299e22685e192))
|
||||
|
||||
ethers/v5.0.29 (2021-02-03 14:36)
|
||||
---------------------------------
|
||||
|
||||
- Fixed typos in JSON ABI formatting. ([#1275](https://github.com/ethers-io/ethers.js/issues/1275); [73b31b3](https://github.com/ethers-io/ethers.js/commit/73b31b371fa47bacc4f5f6bed01d0d1e5d66fa2c))
|
||||
|
||||
ethers/v5.0.28 (2021-02-02 17:12)
|
||||
---------------------------------
|
||||
|
||||
- Added load balancer support to PocketProvider. ([#1052](https://github.com/ethers-io/ethers.js/issues/1052); [27a981c](https://github.com/ethers-io/ethers.js/commit/27a981c84b578feb762fdb37dd5325d9c335bd59))
|
||||
|
||||
ethers/v5.0.27 (2021-02-01 15:55)
|
||||
---------------------------------
|
||||
|
||||
|
||||
49
README.md
49
README.md
@@ -12,7 +12,7 @@ A complete Ethereum wallet implementation and utilities in JavaScript (and TypeS
|
||||
- Import and export **JSON wallets** (Geth, Parity and crowdsale)
|
||||
- Import and export BIP 39 **mnemonic phrases** (12 word backup phrases) and **HD Wallets** (English as well as Czech, French, Italian, Japanese, Korean, Simplified Chinese, Spanish, Traditional Chinese)
|
||||
- Meta-classes create JavaScript objects from any contract ABI, including **ABIv2** and **Human-Readable ABI**
|
||||
- Connect to Ethereum nodes over [JSON-RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC), [INFURA](https://infura.io), [Etherscan](https://etherscan.io), [Alchemy](https://alchemyapi.io) or [MetaMask](https://metamask.io)
|
||||
- Connect to Ethereum nodes over [JSON-RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC), [INFURA](https://infura.io), [Etherscan](https://etherscan.io), [Alchemy](https://alchemyapi.io), [Ankr](https://ankr.com) or [MetaMask](https://metamask.io)
|
||||
- **ENS names** are first-class citizens; they can be used anywhere an Ethereum addresses can be used
|
||||
- **Tiny** (~104kb compressed; 322kb uncompressed)
|
||||
- **Modular** packages; include only what you need
|
||||
@@ -26,10 +26,12 @@ A complete Ethereum wallet implementation and utilities in JavaScript (and TypeS
|
||||
Keep Updated
|
||||
------------
|
||||
|
||||
For the latest news and advisories, please follow the [@ethersproject](https://twitter.com/ethersproject)
|
||||
on Twitter (low-traffic, non-marketing, important information only) as well as watch this GitHub project.
|
||||
For the latest news and advisories, please follow the
|
||||
[@ethersproject](https://twitter.com/ethersproject) on Twitter (low-traffic,
|
||||
non-marketing, important information only) as well as watch this GitHub project.
|
||||
|
||||
For the latest changes, see the [CHANGELOG](https://github.com/ethers-io/ethers.js/blob/master/CHANGELOG.md).
|
||||
For the latest changes, see the
|
||||
[CHANGELOG](https://github.com/ethers-io/ethers.js/blob/master/CHANGELOG.md).
|
||||
|
||||
|
||||
Installing
|
||||
@@ -44,7 +46,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.6.umd.min.js" type="text/javascript">
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -52,7 +54,7 @@ Installing
|
||||
|
||||
```
|
||||
<script type="module">
|
||||
import { ethers } from "https://cdn.ethers.io/lib/ethers-5.0.umd.min.js";
|
||||
import { ethers } from "https://cdn.ethers.io/lib/ethers-5.6.esm.min.js";
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -66,7 +68,34 @@ Browse the [documentation](https://docs.ethers.io/v5/) online:
|
||||
- [Full API Documentation](https://docs.ethers.io/v5/api/)
|
||||
- [Various Ethereum Articles](https://blog.ricmoo.com/)
|
||||
|
||||
Or browse the entire documentation as a [single page](https://docs.ethers.io/v5/single-page/) to make searching easier.
|
||||
|
||||
Providers
|
||||
---------
|
||||
|
||||
Ethers works closely with an ever-growing list of third-party providers
|
||||
to ensure getting started is quick and easy, by providing default keys
|
||||
to each service.
|
||||
|
||||
These built-in keys mean you can use `ethers.getDefaultProvider()` and
|
||||
start developing right away.
|
||||
|
||||
However, the API keys provided to ethers are also shared and are
|
||||
intentionally throttled to encourage developers to eventually get
|
||||
their own keys, which unlock many other features, such as faster
|
||||
responses, more capacity, analytics and other features like archival
|
||||
data.
|
||||
|
||||
When you are ready to sign up and start using for your own keys, please
|
||||
check out the [Provider API Keys](https://docs.ethers.io/v5/api-keys/) in
|
||||
the documentation.
|
||||
|
||||
A special thanks to these services for providing community resources:
|
||||
|
||||
- [Ankr](https://www.ankr.com/)
|
||||
- [Etherscan](https://etherscan.io/)
|
||||
- [INFURA](https://infura.io/)
|
||||
- [Alchemy](https://dashboard.alchemyapi.io/signup?referral=55a35117-028e-4b7c-9e47-e275ad0acc6d)
|
||||
- [Pocket](https://pokt.network/pocket-gateway-ethereum-mainnet/)
|
||||
|
||||
|
||||
Ancillary Packages
|
||||
@@ -80,9 +109,9 @@ everyone else with packages they do not need.
|
||||
|
||||
We will keep a list of useful packages here.
|
||||
|
||||
- `@ethersproject/experimental` ([documentation](https://docs.ethers.io))
|
||||
- `@ethersproject/cli` ([documentation](https://docs.ethers.io))
|
||||
- `@ethersproject/hardware-wallets` ([documentation](https://docs.ethers.io))
|
||||
- `@ethersproject/experimental` ([documentation](https://docs.ethers.io/v5/api/experimental/))
|
||||
- `@ethersproject/cli` ([documentation](https://docs.ethers.io/v5/cli/))
|
||||
- `@ethersproject/hardware-wallets` ([documentation](https://docs.ethers.io/v5/api/other/hardware/))
|
||||
|
||||
|
||||
License
|
||||
|
||||
@@ -25,7 +25,7 @@ free tier, which (depending on the service) includes many advantages:
|
||||
- useful **metric tracking** for performance tuning and to analyze your customer behaviour
|
||||
- more **advanced APIs**, such as archive data or advanced log queries
|
||||
|
||||
_subsection: Etherscan @<api-keys--etherscan>
|
||||
_subsection: Etherscan @NOTE<(see the [[EtherscanProvider]])> @<api-keys--etherscan>
|
||||
|
||||
Etherscan is an Ethereum block explorer, which is possibly the most useful
|
||||
developer tool for building and debugging Ethereum applications.
|
||||
@@ -40,13 +40,17 @@ operations required to interact with the Ethereum Blockchain.
|
||||
- higher rate limit (since you are not using the [shared rate limit](link-etherscan-ratelimit))
|
||||
- customer usage metrics
|
||||
|
||||
_subsection: INFURA @<api-keys--infura>
|
||||
_definition: **Networks:**
|
||||
``homestead``, ``ropsten``, ``rinkeby``, ``goerli`` and ``kovan``.
|
||||
|
||||
|
||||
_subsection: INFURA @NOTE<(see the [[InfuraProvider]])> @<api-keys--infura>
|
||||
|
||||
The INFURA service has been around for quite some time and is very robust
|
||||
and reliable and highly recommended.
|
||||
|
||||
They offer a standard JSON-RPC interface and a WebSocket interface, which makes
|
||||
interaction with standard tools versatile, simple and straight forward.
|
||||
interaction with standard tools versatile, simple and straightforward.
|
||||
|
||||
[Sign up for a free Project ID on INFURA](link-infura-signup)
|
||||
|
||||
@@ -56,7 +60,13 @@ interaction with standard tools versatile, simple and straight forward.
|
||||
- customer usage metrics
|
||||
- access to archive data (requires paid upgrade)
|
||||
|
||||
_subsection: Alchemy @<api-keys--alchemy>
|
||||
_definition: **Networks:**
|
||||
``homestead``, ``ropsten``, ``rinkeby``, ``goerli``, ``kovan``, ``matic``,
|
||||
``maticmum``, ``optimism``, ``optimism-kovan``, ``arbitrum`` and
|
||||
``arbitrum-rinkeby``.
|
||||
|
||||
|
||||
_subsection: Alchemy @NOTE<(see the [[AlchemyProvider]])> @<api-keys--alchemy>
|
||||
|
||||
The Alchemy service has been around a few years and is also very robust
|
||||
and reliable.
|
||||
@@ -74,9 +84,17 @@ with debugging.
|
||||
- access to advanced token balance and metadata APIs
|
||||
- access to advanced debugging trace and revert reason APIs
|
||||
|
||||
_subsection: Pocket Gateway@<api-keys--pocket-gateway>
|
||||
_definition: **Networks:**
|
||||
``homestead``, ``ropsten``, ``rinkeby``, ``goerli``, ``kovan``, ``matic``,
|
||||
``maticmum``, ``optimism``, ``optimism-kovan``, ``arbitrum`` and
|
||||
``arbitrum-rinkeby``.
|
||||
|
||||
|
||||
_subsection: Pocket Gateway @NOTE<(see the [[PocketProvider]])> @<api-keys--pocket-gateway>
|
||||
|
||||
They offer a standard JSON-RPC interface using either a load-balanced
|
||||
network or non-load-balanced fleet.
|
||||
|
||||
[Sign up for a free API key on Pocket](link-pocket-signup)
|
||||
|
||||
**Benefits:**
|
||||
@@ -86,6 +104,26 @@ _subsection: Pocket Gateway@<api-keys--pocket-gateway>
|
||||
- Stake as opposed to paying a monthly fee
|
||||
- Highly redundant global set of nodes incentivized by cryptoeconomic incentives
|
||||
|
||||
_definition: **Networks:**
|
||||
``homestead``
|
||||
|
||||
|
||||
_subsection: Ankr @NOTE<(see the [[AnkrProvider]])> @<api-keys--ankr>
|
||||
|
||||
They offer a standard JSON-RPC interface and have fairly high capacity without
|
||||
the need for an API key early on in the development cycle.
|
||||
|
||||
[See their free tier features on Ankr](link-ankr-public)
|
||||
|
||||
**Benefits:**
|
||||
|
||||
- higher rate limit
|
||||
- customer usage metrics
|
||||
- access to archive data (requires paid upgrade)
|
||||
|
||||
_definition: **Networks:**
|
||||
``homestead``, ``matic`` and ``arbitrum``
|
||||
|
||||
|
||||
_subsection: Creating a Default Provider @<api-keys--getDefaultProvider>
|
||||
|
||||
@@ -100,6 +138,8 @@ using the default API key for that service.
|
||||
It is **highly recommended** that you provide an API for each service, to
|
||||
maximize your applications performance.
|
||||
|
||||
If the API key ``"-"`` is used, the corresponding Provider will be omitted.
|
||||
|
||||
_code: Passing API Keys into getDefaultProvider @lang<script>
|
||||
|
||||
// Use the mainnet
|
||||
@@ -122,5 +162,6 @@ const provider = ethers.getDefaultProvider(network, {
|
||||
// pocket: {
|
||||
// applicationId: ,
|
||||
// applicationSecretKey:
|
||||
// }
|
||||
// },
|
||||
ankr: YOUR_ANKR_API_KEY
|
||||
});
|
||||
|
||||
34
docs.wrm/api/contract/MyToken.sol
Normal file
34
docs.wrm/api/contract/MyToken.sol
Normal file
@@ -0,0 +1,34 @@
|
||||
// Do not use this; it is only for an example in the docs
|
||||
|
||||
contract MyToken {
|
||||
event Transfer(address indexed from, address indexed to, uint amount);
|
||||
|
||||
mapping (address => uint256) _balances;
|
||||
|
||||
constructor(uint256 totalSupply) {
|
||||
emit Transfer(address(0), msg.sender, totalSupply);
|
||||
_balances[msg.sender] = totalSupply;
|
||||
}
|
||||
|
||||
// Read-Only Functions
|
||||
function balanceOf(address owner) public view returns (uint256) {
|
||||
return _balances[owner];
|
||||
}
|
||||
|
||||
function decimals() public pure returns (uint8) {
|
||||
return 18;
|
||||
}
|
||||
|
||||
function symbol() public pure returns (string memory) {
|
||||
return "MyToken";
|
||||
}
|
||||
|
||||
// Authenticated Functions
|
||||
function transfer(address to, uint amount) public returns (bool) {
|
||||
require(_balances[msg.sender] >= amount, "insufficient token balance");
|
||||
_balances[msg.sender] -= amount;
|
||||
_balances[to] += amount;
|
||||
emit Transfer(msg.sender, to, amount);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ Consumes the output of the Solidity compiler, extracting the ABI
|
||||
and bytecode from it, allowing for the various formats the solc
|
||||
compiler has emitted over its life.
|
||||
|
||||
_property: contractFactory.connect(signer) => [[Contract]] @<ContractFactory-connect>
|
||||
_property: contractFactory.connect(signer) => [[ContractFactory]] @<ContractFactory-connect>
|
||||
|
||||
Returns a **new instance** of the ContractFactory with the same //interface//
|
||||
and //bytecode//, but with a different //signer//.
|
||||
@@ -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:
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
_section: Contract @<Contract> @SRC<contracts:class.Contract>
|
||||
|
||||
Explain contract here...
|
||||
A **Contract** is an abstraction of code that has been deployed
|
||||
to the blockchain.
|
||||
|
||||
A Contract may be sent transactions, which will trigger its code
|
||||
to be run with the input of the transaction data.
|
||||
|
||||
_subsection: Creating Instances @<Contract--creating>
|
||||
|
||||
_property: new ethers.Contract(address, abi, signerOrProvider) @src<contracts:constructor.Contract>
|
||||
_property: new ethers.Contract(address, abi, signerOrProvider) @src<contracts:class.Contract>
|
||||
|
||||
_property: contract.attach(addressOrName) => [[Contract]] @<Contract-attach> @SRC<contracts:Contract.attach>
|
||||
_property: contract.attach(addressOrName) => [[Contract]] @<Contract-attach> @SRC<contracts:BaseContract.attach>
|
||||
Returns a new instance of the **Contract** attached to a new
|
||||
address. This is useful if there are multiple similar or identical
|
||||
copies of a Contract on the network and you wish to interact with
|
||||
each of them.
|
||||
|
||||
_property: contract.connect(providerOrSigner) => [[Contract]] @<Contract-connect> @SRC<contracts:Contract.connect>
|
||||
_property: contract.connect(providerOrSigner) => [[Contract]] @<Contract-connect> @SRC<contracts:BaseContract.connect>
|
||||
Returns a new instance of the Contract, but connected to
|
||||
//providerOrSigner//.
|
||||
|
||||
@@ -61,11 +65,11 @@ _subsection: Events @<Contract--events>
|
||||
_property: contract.queryFilter(event [ , fromBlockOrBlockHash [ , toBlock ]) => Promise<Array<Event>> @<Contract-queryFilter> @SRC<contracts>
|
||||
Return Events that match the //event//.
|
||||
|
||||
_property: contract.listenerCount([ event ]) => number @<Contract-listenerCount> @SRC<contracts:Contract.listenerCount>
|
||||
_property: contract.listenerCount([ event ]) => number @<Contract-listenerCount> @SRC<contracts:BaseContract.listenerCount>
|
||||
Return the number of listeners that are subscribed to //event//. If
|
||||
no event is provided, returns the total count of all events.
|
||||
|
||||
_property: contract.listeners(event) => Array<Listener> @<Contract-listeners> @SRC<contracts:Contract.listeners>
|
||||
_property: contract.listeners(event) => Array<Listener> @<Contract-listeners> @SRC<contracts:BaseContract.listeners>
|
||||
Return a list of listeners that are subscribed to //event//.
|
||||
|
||||
_property: contract.off(event, listener) => this @<Contract-off> @SRC<contracts>
|
||||
@@ -78,7 +82,7 @@ _property: contract.once(event, listener) => this @<Contract-once> @SRC<contrac
|
||||
Subscribe once to //event// calling //listener// when the event
|
||||
occurs.
|
||||
|
||||
_property: contract.removeAllListeners([ event ]) => this @<Contract-removeAllListeners> @SRC<contracts:Contract.removeAllListeners>
|
||||
_property: contract.removeAllListeners([ event ]) => this @<Contract-removeAllListeners> @SRC<contracts:BaseContract.removeAllListeners>
|
||||
Unsubscribe all listeners for //event//. If no event is provided,
|
||||
all events are unsubscribed.
|
||||
|
||||
@@ -94,17 +98,21 @@ at run-time during the **Contract** constructor.
|
||||
|
||||
_heading: Read-Only Methods (constant) @<Contract--readonly>
|
||||
|
||||
A constant method is read-only and evaluates a small amount of EVM
|
||||
code against the current blockchain state and can be computed by
|
||||
asking a single node, which can return a result. It is therefore
|
||||
free and does not require any ether, but **cannot make changes** to
|
||||
the blockchain state..
|
||||
A constant method (denoted by ``pure`` or ``view`` in Solidity)
|
||||
is read-only and evaluates a small amount of EVM code against the
|
||||
current blockchain state and can be computed by asking a single
|
||||
node, which can return a result. It is therefore free and does
|
||||
not require any ether, but **cannot make changes** to the
|
||||
blockchain state..
|
||||
|
||||
_property: contract.METHOD_NAME(...args [, overrides ]) => Promise<any> @<Contract-functionsCall>
|
||||
The type of the result depends on the ABI.
|
||||
The type of the result depends on the ABI. If the method returns a single
|
||||
value, it will be returned directly, otherwise a [[Result]] object will
|
||||
be returned with each parameter available positionally and if the parameter
|
||||
is named, it will also be available by its name.
|
||||
|
||||
For values that have a simple meaning in JavaScript, the types are fairly
|
||||
straight forward; strings and booleans are returned as JavaScript strings
|
||||
straightforward; strings and booleans are returned as JavaScript strings
|
||||
and booleans.
|
||||
|
||||
For numbers, if the **type** is in the JavaScript safe range (i.e. less
|
||||
@@ -113,6 +121,32 @@ number is used. Otherwise a [[BigNumber]] is returned.
|
||||
|
||||
For bytes (both fixed length and dynamic), a [[DataHexString]] is returned.
|
||||
|
||||
If the call reverts (or runs out of gas), a [CALL_EXCEPTION](errors--call-exception)
|
||||
will be thrown which will include:
|
||||
|
||||
- ``error.address`` - the contract address
|
||||
- ``error.args`` - the arguments passed into the method
|
||||
- ``error.transaction`` - the transaction
|
||||
|
||||
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
|
||||
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``);
|
||||
//most developers will not require this//
|
||||
- ``overrides.gasLimit`` - the amount of gas (theoretically) to allow a node
|
||||
to use during the execution of the code; since there is no transaction, there
|
||||
is not going to be any fee charged, but the EVM still processes gas metering
|
||||
so calls like ``gasleft`` (or ``GAS``) report meaningful values
|
||||
- ``overrides.blockTag`` - a block tag to simulate the execution at, which
|
||||
can be used for hypothetical historic analysis; note that many backends
|
||||
do not support this, or may require paid plans to access as the node database
|
||||
storage and processing requirements are much higher
|
||||
|
||||
_property: contract.functions.METHOD_NAME(...args [, overrides ]) => Promise<[[Result]]>
|
||||
|
||||
The result will always be a [[Result]], even if there is only a single
|
||||
@@ -130,6 +164,8 @@ allowing an alternate UTF-8 error strategy to be used.
|
||||
|
||||
Most developers should not require this.
|
||||
|
||||
The //overrides// are identical to the read-only operations above.
|
||||
|
||||
_heading: Write Methods (non-constant) @<Contract--write>
|
||||
|
||||
A non-constant method requires a transaction to be signed and requires
|
||||
@@ -147,6 +183,32 @@ Returns a [[providers-TransactionResponse]] for the transaction after
|
||||
it is sent to the network. This requires the **Contract** has a
|
||||
signer.
|
||||
|
||||
The //overrides// object for write methods may include any of:
|
||||
|
||||
- ``overrides.gasPrice`` - the price to pay per gas
|
||||
- ``overrides.gasLimit`` - the limit on the amount of gas to allow the transaction
|
||||
to consume; any unused gas is returned at the gasPrice
|
||||
- ``overrides.value`` - the amount of ether (in wei) to forward with the call
|
||||
- ``overrides.nonce`` - the nonce to use for the [[Signer]]
|
||||
|
||||
If the ``wait()`` method on the returned [[providers-TransactionResponse]]
|
||||
is called, there will be additional properties on the receipt:
|
||||
|
||||
- ``receipt.events`` - an array of the logs, with additional properties
|
||||
(if the ABI included a description for the events)
|
||||
- ``receipt.events[n].args`` - the parsed arguments
|
||||
- ``receipt.events[n].decode`` - a method that can be used to parse the
|
||||
log topics and data (this was used to compute ``args``)
|
||||
- ``receipt.events[n].event`` - the name of the event
|
||||
- ``receipt.events[n].eventSignature`` - the full signature of the event
|
||||
- ``receipt.removeListener()`` - a method to remove the listener that trigger
|
||||
this event
|
||||
- ``receipt.getBlock()`` - a method to return the [Block](providers-Block) this event occurred in
|
||||
- ``receipt.getTransaction()`` - a method to return the
|
||||
[Transaction](providers-TransactionResponse) this event occurred in
|
||||
- ``receipt.getTransactionReceipt()`` - a method to return the
|
||||
[Transaction Receipt](providers-TransactionReceipt) this event occurred in
|
||||
|
||||
|
||||
_heading: Write Methods Analysis @<Contract--check>
|
||||
|
||||
@@ -157,11 +219,17 @@ _property: contract.estimateGas.METHOD_NAME(...args [ , overrides ]) => Promise<
|
||||
Returns the estimate units of gas that would be required to
|
||||
execute the //METHOD_NAME// with //args// and //overrides//.
|
||||
|
||||
The //overrides// are identical to the overrides above for read-only
|
||||
or write methods, depending on the type of call of //METHOD_NAME//.
|
||||
|
||||
_property: contract.populateTransaction.METHOD_NAME(...args [ , overrides ]) => Promise<[UnsignedTx](UnsignedTransaction)> @<contract-populateTransaction>
|
||||
Returns an [[UnsignedTransaction]] which represents the transaction
|
||||
that would need to be signed and submitted to the network to execute
|
||||
//METHOD_NAME// with //args// and //overrides//.
|
||||
|
||||
The //overrides// are identical to the overrides above for read-only
|
||||
or write methods, depending on the type of call of //METHOD_NAME//.
|
||||
|
||||
_property: contract.callStatic.METHOD_NAME(...args [ , overrides ]) => Promise<any> @<contract-callStatic>
|
||||
Rather than executing the state-change of a transaction, it is possible
|
||||
to ask a node to //pretend// that a call is not state-changing and
|
||||
@@ -172,6 +240,8 @@ can be used to determine if a transaction will fail or succeed.
|
||||
|
||||
This otherwise functions the same as a [Read-Only Method](Contract--readonly).
|
||||
|
||||
The //overrides// are identical to the read-only operations above.
|
||||
|
||||
_heading: Event Filters @<Contract--filters>
|
||||
An event filter is made up of topics, which are values logged in a
|
||||
[[link-wiki-bloomfilter]], allowing efficient searching for entries
|
||||
|
||||
@@ -1,10 +1,75 @@
|
||||
_section: Example: ERC-20 Contract
|
||||
|
||||
The concept of Meta-Classes is somewhat confusing, so we will go
|
||||
over a short example.
|
||||
|
||||
A meta-class is a class which is defined at run-time. A Contract
|
||||
is specified by an //Application Binary Interface// (ABI), which describes
|
||||
the methods and events it has. This description is passed to the
|
||||
[[Contract]] object at run-time, and it creates a new Class, adding
|
||||
all the methods defined in the ABI at run-time.
|
||||
|
||||
_subsection: Deploying a Contract
|
||||
|
||||
Most often, any contract you will need to interact with will already
|
||||
be deployed to the blockchain, but for this example will will first
|
||||
deploy the contract.
|
||||
|
||||
_property: new ethers.ContractFactory(abi, bytecode, signer)
|
||||
Create a new [[ContractFactory]] which can deploy a contract to the
|
||||
blockchain.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const signer = localSigner;
|
||||
//_hide: const parseUnits = utils.parseUnits;
|
||||
|
||||
const bytecode = "0x608060405234801561001057600080fd5b506040516103bc3803806103bc83398101604081905261002f9161007c565b60405181815233906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a333600090815260208190526040902055610094565b60006020828403121561008d578081fd5b5051919050565b610319806100a36000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063313ce5671461005157806370a082311461006557806395d89b411461009c578063a9059cbb146100c5575b600080fd5b604051601281526020015b60405180910390f35b61008e610073366004610201565b6001600160a01b031660009081526020819052604090205490565b60405190815260200161005c565b604080518082018252600781526626bcaa37b5b2b760c91b6020820152905161005c919061024b565b6100d86100d3366004610222565b6100e8565b604051901515815260200161005c565b3360009081526020819052604081205482111561014b5760405162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e7420746f6b656e2062616c616e6365000000000000604482015260640160405180910390fd5b336000908152602081905260408120805484929061016a9084906102b6565b90915550506001600160a01b0383166000908152602081905260408120805484929061019790849061029e565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350600192915050565b80356001600160a01b03811681146101fc57600080fd5b919050565b600060208284031215610212578081fd5b61021b826101e5565b9392505050565b60008060408385031215610234578081fd5b61023d836101e5565b946020939093013593505050565b6000602080835283518082850152825b818110156102775785810183015185820160400152820161025b565b818111156102885783604083870101525b50601f01601f1916929092016040019392505050565b600082198211156102b1576102b16102cd565b500190565b6000828210156102c8576102c86102cd565b500390565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220d80384ce584e101c5b92e4ee9b7871262285070dbcd2d71f99601f0f4fcecd2364736f6c63430008040033";
|
||||
|
||||
// A Human-Readable ABI; we only need to specify relevant fragments,
|
||||
// in the case of deployment this means the constructor
|
||||
const abi = [
|
||||
"constructor(uint totalSupply)"
|
||||
];
|
||||
|
||||
const factory = new ethers.ContractFactory(abi, bytecode, signer)
|
||||
|
||||
// Deploy, setting total supply to 100 tokens (assigned to the deployer)
|
||||
const contract = await factory.deploy(parseUnits("100"));
|
||||
|
||||
// The contract is not currentl live on the network yet, however
|
||||
// its address is ready for us
|
||||
//_result:
|
||||
contract.address
|
||||
//_log:
|
||||
//_hide: _page.address = contract.address;
|
||||
|
||||
// Wait until the contract has been deployed before interacting
|
||||
// with it; returns the receipt for the deployemnt transaction
|
||||
//_result:
|
||||
await contract.deployTransaction.wait();
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Connecting to a Contract
|
||||
|
||||
_code: A simple ERC-20 contract @lang<javascript>
|
||||
_heading: ERC20Contract @INHERIT<[[Contract]]>
|
||||
|
||||
// A Human-Readable ABI; any supported ABI format could be used
|
||||
_property: new ethers.Contract(address, abi, providerOrSigner)
|
||||
Creating a new instance of a Contract connects to an existing
|
||||
contract by specifying its //address// on the blockchain,
|
||||
its //abi// (used to populate the class' methods) a //providerOrSigner//.
|
||||
|
||||
If a [[Provider]] is given, the contract has only read-only access, while
|
||||
a [[Signer]] offers access to state manipulating methods.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const provider = localProvider;
|
||||
//_hide: const signer = localSigner;
|
||||
|
||||
// A Human-Readable ABI; for interacting with the contract, we
|
||||
// must include any fragment we wish to use
|
||||
const abi = [
|
||||
// Read-Only Functions
|
||||
"function balanceOf(address owner) view returns (uint256)",
|
||||
@@ -12,20 +77,15 @@ const abi = [
|
||||
"function symbol() view returns (string)",
|
||||
|
||||
// Authenticated Functions
|
||||
"function transfer(address to, uint amount) returns (boolean)",
|
||||
"function transfer(address to, uint amount) returns (bool)",
|
||||
|
||||
// Events
|
||||
"event Transfer(address indexed from, address indexed to, uint amount)"
|
||||
];
|
||||
|
||||
// This can be an address or an ENS name
|
||||
const address = "dai.tokens.ethers.eth";
|
||||
|
||||
// An example Provider
|
||||
const provider = ethers.getDefaultProvider();
|
||||
|
||||
// An example Signer
|
||||
const signer = ethers.Wallet.createRandom().connect(provider);
|
||||
//_hide: const address = _page.address;
|
||||
//_verbatim: `const address = ${ JSON.stringify(address) };`
|
||||
|
||||
// Read-Only; By connecting to a Provider, allows:
|
||||
// - Any constant function
|
||||
@@ -34,20 +94,13 @@ const signer = ethers.Wallet.createRandom().connect(provider);
|
||||
// - Estimating Gas for non-constant (as an anonymous sender)
|
||||
// - Static Calling non-constant methods (as anonymous sender)
|
||||
const erc20 = new ethers.Contract(address, abi, provider);
|
||||
//_hide: _page.erc20 = erc20;
|
||||
|
||||
// Read-Write; By connecting to a Signer, allows:
|
||||
// - Everything from Read-Only (except as Signer, not anonymous)
|
||||
// - Sending transactions for non-constant functions
|
||||
const erc20_rw = new ethers.Contract(address, abi, signer)
|
||||
|
||||
|
||||
_heading: ERC20Contract @INHERIT<[[Contract]]>
|
||||
|
||||
_property: new ethers.Contract(address, abi, providerOrSigner)
|
||||
See the above code example for creating an Instance which will
|
||||
(in addition to the Contact methods and properties) automatically
|
||||
add the additional properties defined in //abi// to a **Contract**
|
||||
connected to //address// using the //providerOrSigner//.
|
||||
const erc20_rw = new ethers.Contract(address, abi, signer);
|
||||
//_hide: _page.erc20_rw = erc20_rw;
|
||||
|
||||
|
||||
_subsection: Properties @NOTE<(inheritted from [[Contract]])>
|
||||
@@ -101,6 +154,8 @@ _property: Contract.isIndexed(value) => boolean
|
||||
|
||||
_subsection: Events @NOTE<(inheritted from [[Contract]])> @<erc20-events>
|
||||
|
||||
See [Meta-Class Filters](erc20-meta-events) for examples using events.
|
||||
|
||||
_property: erc20.queryFilter(event [ , fromBlockOrBlockHash [ , toBlock ]) => Promise<Array<Event>> @<erc20-queryfilter>
|
||||
Return Events that match the //event//.
|
||||
|
||||
@@ -126,7 +181,7 @@ Unsubscribe all listeners for //event//. If no event is provided,
|
||||
all events are unsubscribed.
|
||||
|
||||
|
||||
_subsection: Meta-Class Methods @NOTE<(added at Runtime)>
|
||||
_subsection: Meta-Class Methods @NOTE<(added at Runtime)> @<erc20-meta-methods>
|
||||
|
||||
Since the Contract is a Meta-Class, the methods available here depend
|
||||
on the ABI which was passed into the **Contract**.
|
||||
@@ -136,12 +191,35 @@ Returns the number of decimal places used by this ERC-20 token. This can be
|
||||
used with [parseUnits](utils-parseUnits) when taking input from the user or
|
||||
[formatUnits](utils-formatunits] when displaying the token amounts in the UI.
|
||||
|
||||
_property: erc20.getBalance(owner [, overrides ]) => Promise<[[BigNumber]]>
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const erc20 = _page.erc20;
|
||||
//_result:
|
||||
await erc20.decimals();
|
||||
//_log:
|
||||
|
||||
_property: erc20.balanceOf(owner [, overrides ]) => Promise<[[BigNumber]]>
|
||||
Returns the balance of //owner// for this ERC-20 token.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const signer = localSigner;
|
||||
//_hide: const erc20 = _page.erc20;
|
||||
|
||||
//_result:
|
||||
await erc20.balanceOf(signer.getAddress())
|
||||
//_log:
|
||||
|
||||
_property: erc20.symbol([ overrides ]) => Promise<string>
|
||||
Returns the symbol of the token.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const erc20 = _page.erc20;
|
||||
//_result:
|
||||
await erc20.symbol();
|
||||
//_log:
|
||||
|
||||
_property: erc20_rw.transfer(target, amount [, overrides ]) => Promise<[[providers-TransactionResponse]]>
|
||||
Transfers //amount// tokens to //target// from the current signer.
|
||||
The return value (a boolean) is inaccessible during a write operation
|
||||
@@ -149,20 +227,86 @@ using a transaction. Other techniques (such as events) are required
|
||||
if this value is required. On-chain contracts calling the ``transfer``
|
||||
function have access to this result, which is why it is possible.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const signer = localSigner;
|
||||
//_hide: const erc20_rw = _page.erc20_rw;
|
||||
//_hide: const parseUnits = utils.parseUnits;
|
||||
//_hide: const formatUnits = utils.formatUnits;
|
||||
|
||||
// Before...
|
||||
//_result:
|
||||
formatUnits(await erc20_rw.balanceOf(signer.getAddress()));
|
||||
//_log:
|
||||
|
||||
// Transfer 1.23 tokens to the ENS name "ricmoo.eth"
|
||||
//_result:
|
||||
tx = await erc20_rw.transfer("ricmoo.eth", parseUnits("1.23"));
|
||||
//_log:
|
||||
|
||||
// Wait for the transaction to be mined...
|
||||
//_result:
|
||||
await tx.wait();
|
||||
//_log:
|
||||
|
||||
// After!
|
||||
//_result:
|
||||
formatUnits(await erc20_rw.balanceOf(signer.getAddress()));
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
formatUnits(await erc20_rw.balanceOf("ricmoo.eth"));
|
||||
//_log:
|
||||
|
||||
_property: erc20.callStatic.transfer(target, amount [, overrides ]) => Promise<boolean>
|
||||
Performs a dry-run of transferring //amount// tokens to //target// from
|
||||
the current signer, without actually signing or sending a transaction.
|
||||
|
||||
This can be used to preflight check that a transaction will be successful.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const erc20_rw = _page.erc20_rw;
|
||||
//_hide: const randomWallet = ethers.Wallet.createRandom().connect(erc20_rw.provider);
|
||||
//_hide: const parseUnits = utils.parseUnits;
|
||||
|
||||
// The signer has enough tokens to send, so true is returned
|
||||
//_result:
|
||||
await erc20_rw.callStatic.transfer("ricmoo.eth", parseUnits("1.23"));
|
||||
//_log:
|
||||
|
||||
// A random address does not have enough tokens to
|
||||
// send, in which case the contract throws an error
|
||||
erc20_random = erc20_rw.connect(randomWallet);
|
||||
//_throws:
|
||||
await erc20_random.callStatic.transfer("ricmoo.eth", parseUnits("1.23"));
|
||||
//_log:
|
||||
|
||||
_property: erc20.estimateGas.transfer(target, amount [, overrides ]) => Promise<[[BigNumber]]>
|
||||
Returns an estimate for how many units of gas would be required
|
||||
to transfer //amount// tokens to //target//.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const erc20_rw = _page.erc20_rw;
|
||||
//_hide: const parseUnits = utils.parseUnits;
|
||||
|
||||
//_result:
|
||||
await erc20_rw.estimateGas.transfer("ricmoo.eth", parseUnits("1.23"));
|
||||
//_log:
|
||||
|
||||
_property: erc20.populateTransaction.transfer(target, amount [, overrides ]) => Promise<[UnsignedTx](UnsignedTransaction)>
|
||||
Returns an [[UnsignedTransaction]] which could be signed and submitted
|
||||
to the network to transaction //amount// tokens to //target//.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const erc20_rw = _page.erc20_rw;
|
||||
//_hide: const parseUnits = utils.parseUnits;
|
||||
|
||||
//_result:
|
||||
await erc20_rw.populateTransaction.transfer("ricmoo.eth", parseUnits("1.23"));
|
||||
//_log:
|
||||
|
||||
_note: Note on Estimating and Static Calling
|
||||
|
||||
@@ -173,7 +317,7 @@ blockchain also means there are certain consistency modes that cannot be
|
||||
known until an actual transaction is attempted.
|
||||
|
||||
|
||||
_subsection: Meta-Class Filters @NOTE<(added at Runtime)>
|
||||
_subsection: Meta-Class Filters @NOTE<(added at Runtime)> @<erc20-meta-events>
|
||||
|
||||
Since the Contract is a Meta-Class, the methods available here depend
|
||||
on the ABI which was passed into the **Contract**.
|
||||
@@ -184,3 +328,75 @@ to [subscribe/unsubscribe to events](erc20-events).
|
||||
|
||||
If //fromAddress// is null or not provided, then any from address matches.
|
||||
If //toAddress// is null or not provided, then any to address matches.
|
||||
|
||||
_code: query filter *from* events @lang<javascript>
|
||||
|
||||
//_hide: const signer = localSigner;
|
||||
//_hide: const erc20 = _page.erc20;
|
||||
|
||||
//_result:
|
||||
filterFrom = erc20.filters.Transfer(signer.address);
|
||||
//_log:
|
||||
|
||||
// Search for transfers *from* me in the last 10 blocks
|
||||
//_result:
|
||||
logsFrom = await erc20.queryFilter(filterFrom, -10, "latest");
|
||||
//_log:
|
||||
|
||||
// Note that the args providees the details of the event, each
|
||||
// parameters is available positionally, and since our ABI
|
||||
// included parameter names also by name
|
||||
//_result:
|
||||
logsFrom[0].args
|
||||
//_log:
|
||||
|
||||
//_hide: _page.filterFrom = filterFrom;
|
||||
|
||||
|
||||
_code: query filter with *to* events @lang<javascript>
|
||||
|
||||
//_hide: const signer = localSigner;
|
||||
//_hide: const erc20 = _page.erc20;
|
||||
|
||||
//_result:
|
||||
filterTo = erc20.filters.Transfer(null, signer.address);
|
||||
//_log:
|
||||
|
||||
// Search for transfers *to* me in the last 10 blocks
|
||||
// Note: the contract transferred totalSupply tokens to us
|
||||
// when it was deployed in its constructor
|
||||
//_result:
|
||||
logsTo = await erc20.queryFilter(filterTo, -10, "latest");
|
||||
//_log:
|
||||
|
||||
// Note that the args providees the details of the event, each
|
||||
// parameters is available positionally, and since our ABI
|
||||
// included parameter names also by name
|
||||
//_result:
|
||||
logsTo[0].args
|
||||
//_log:
|
||||
|
||||
//_hide: _page.filterTo = filterTo;
|
||||
|
||||
_code: listen for events @lang<javascript>
|
||||
|
||||
//_hide: const erc20 = _page.erc20;
|
||||
//_hide: const filterFrom = _page.filterFrom;
|
||||
//_hide: const filterTo = _page.filterTo;
|
||||
|
||||
// Listen to incoming events from signer:
|
||||
erc20.on(filterFrom, (from, to, amount, event) => {
|
||||
// The `from` will always be the signer address
|
||||
});
|
||||
|
||||
// Listen to incoming events to signer:
|
||||
erc20.on(filterTo, (from, to, amount, event) => {
|
||||
// The `to` will always be the signer address
|
||||
});
|
||||
|
||||
// Listen to all Transfer events:
|
||||
erc20.on("Transfer", (from, to, amount, event) => {
|
||||
// ...
|
||||
});
|
||||
|
||||
//_hide: erc20.removeAllListeners();
|
||||
|
||||
@@ -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]]>
|
||||
|
||||
@@ -58,8 +78,16 @@ Set the current transaction count (nonce) for the signer.
|
||||
This may be useful in interacting with the signer outside of using
|
||||
this class.
|
||||
|
||||
_property: nonceManager.increaseTransactionCount( [ count = 1 ]) => void
|
||||
_property: nonceManager.incrementTransactionCount( [ count = 1 ]) => void
|
||||
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";
|
||||
|
||||
@@ -11,7 +11,7 @@ To mitigate these issues, it is recommended you use a
|
||||
[Default Provider](providers-getDefaultProvider).
|
||||
|
||||
|
||||
_subsection: EtherscanProvider @<EtherscanProvider> @inherit<[[Provider]]> @src<providers:class.EtherscanProvider>
|
||||
_subsection: EtherscanProvider @<EtherscanProvider> @inherit<[[BaseProvider]]> @src<providers:class.EtherscanProvider>
|
||||
|
||||
The **EtherscanProvider** is backed by a combination of the various
|
||||
[Etherscan APIs](link-etherscan-api).
|
||||
@@ -39,18 +39,16 @@ It is highly recommended for production, you register with
|
||||
|
||||
_definition: **Supported Networks**
|
||||
|
||||
- Homestead (Mainnet)
|
||||
- Ropsten (proof-of-work testnet)
|
||||
- Rinkeby (proof-of-authority testnet)
|
||||
- Görli (clique testnet)
|
||||
- Kovan (proof-of-authority testnet)
|
||||
- ``homestead`` - Homestead (Mainnet)
|
||||
- ``ropsten`` - Ropsten (proof-of-work testnet)
|
||||
- ``rinkeby`` - Rinkeby (proof-of-authority testnet)
|
||||
- ``goerli`` - Görli (clique testnet)
|
||||
- ``kovan`` - Kovan (proof-of-authority testnet)
|
||||
|
||||
_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);
|
||||
|
||||
@@ -111,19 +106,23 @@ It is highly recommended for production, you register with
|
||||
|
||||
_definition: **Supported Networks**
|
||||
|
||||
- Homestead (Mainnet)
|
||||
- Ropsten (proof-of-work testnet)
|
||||
- Rinkeby (proof-of-authority testnet)
|
||||
- Görli (clique testnet)
|
||||
- Kovan (proof-of-authority testnet)
|
||||
- ``homestead`` - Homestead (Mainnet)
|
||||
- ``ropsten`` - Ropsten (proof-of-work testnet)
|
||||
- ``rinkeby`` - Rinkeby (proof-of-authority testnet)
|
||||
- ``goerli`` - Görli (clique testnet)
|
||||
- ``kovan`` - Kovan (proof-of-authority testnet)
|
||||
- ``matic`` - Polygon
|
||||
- ``maticmum`` - Polygon Mumbai Testnet
|
||||
- ``optimism`` - Optimism (L2; optimistic roll-up)
|
||||
- ``optimism-kovan`` - Optimism Testnet (L2; optimistic roll-up testnet)
|
||||
- ``arbitrum`` - Arbitrum (L2; optimistic roll-up)
|
||||
- ``arbitrum-rinkeby`` - Arbitrum Testnet (L2; optimistic roll-up testnet)
|
||||
|
||||
_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 +143,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>
|
||||
@@ -170,18 +167,22 @@ It is highly recommended for production, you register with
|
||||
|
||||
_definition: **Supported Networks**
|
||||
|
||||
- Homestead (Mainnet)
|
||||
- Ropsten (proof-of-work testnet)
|
||||
- Rinkeby (proof-of-authority testnet)
|
||||
- Görli (clique testnet)
|
||||
- Kovan (proof-of-authority testnet)
|
||||
- ``homestead`` - Homestead (Mainnet)
|
||||
- ``ropsten`` - Ropsten (proof-of-work testnet)
|
||||
- ``rinkeby`` - Rinkeby (proof-of-authority testnet)
|
||||
- ``goerli`` - Görli (clique testnet)
|
||||
- ``kovan`` - Kovan (proof-of-authority testnet)
|
||||
- ``matic`` - Polygon
|
||||
- ``maticmum`` - Polygon Mumbai Testnet
|
||||
- ``optimism`` - Optimism (L2; optimistic roll-up)
|
||||
- ``optimism-kovan`` - Optimism Testnet (L2; optimistic roll-up testnet)
|
||||
- ``arbitrum`` - Arbitrum (L2; optimistic roll-up)
|
||||
- ``arbitrum-rinkeby`` - Arbitrum Testnet (L2; optimistic roll-up testnet)
|
||||
|
||||
_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 +197,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>
|
||||
@@ -210,13 +209,106 @@ Create a new **CloudflareProvider** connected to mainnet (i.e. "homestead").
|
||||
|
||||
_definition: **Supported Networks**
|
||||
|
||||
- Homestead (Mainnet)
|
||||
- ``homestead`` - Homestead (Mainnet)
|
||||
|
||||
_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();
|
||||
|
||||
|
||||
_subsection: PocketProvider @<PocketProvider> @inherit<[[UrlJsonRpcProvider]]> @src<providers:class.PocketProvider>
|
||||
|
||||
The **PocketProvider** is backed by [Pocket](link-pocket).
|
||||
|
||||
_property: new ethers.providers.PocketProvider([ network = "homestead", [ apiKey ] ])
|
||||
Create a new **PocketProvider** connected to //network// with
|
||||
the optional //apiKey//.
|
||||
|
||||
The //network// may be specified as a **string** for a common
|
||||
network name, a **number** for a common chain ID or a
|
||||
[Network Object](providers-Network).
|
||||
|
||||
_note: Note: Default API keys
|
||||
If no //apiKey// is provided, a shared API key will be used,
|
||||
which may result in reduced performance and throttled requests.
|
||||
|
||||
It is highly recommended for production, you register with
|
||||
[Pocket](link-pocket) for your own API key.
|
||||
|
||||
_definition: **Supported Networks**
|
||||
|
||||
- ``homestead`` - Homestead (Mainnet)
|
||||
- ``ropsten`` - Ropsten (proof-of-work testnet)
|
||||
- ``rinkeby`` - Rinkeby (proof-of-authority testnet)
|
||||
- ``goerli`` - Görli (clique testnet)
|
||||
|
||||
_code: Pocket Examples @lang<javascript>
|
||||
|
||||
//_hide: const PocketProvider = ethers.providers.PocketProvider;
|
||||
//_hide: const applicationId = "...";
|
||||
//_hide: const applicationSecretKey = "...";
|
||||
//_hide: const loadBalancer = true;
|
||||
|
||||
// Connect to mainnet (homestead)
|
||||
provider = new PocketProvider();
|
||||
|
||||
// Connect to the ropsten testnet
|
||||
// (see EtherscanProvider above for other network examples)
|
||||
provider = new PocketProvider("ropsten");
|
||||
|
||||
// Connect to mainnet with an Application ID (these are equivalent)
|
||||
provider = new PocketProvider(null, applicationId);
|
||||
provider = new PocketProvider("homestead", applicationId);
|
||||
|
||||
// Connect to mainnet with an application ID, application secret
|
||||
// and specify whether to use the load balances
|
||||
provider = new PocketProvider("homestead", {
|
||||
applicationId: applicationId,
|
||||
applicationSecretKey: applicationSecretKey,
|
||||
loadBalancer: loadBalancer // true or false
|
||||
});
|
||||
|
||||
|
||||
_subsection: AnkrProvider @<AnkrProvider> @inherit<[[UrlJsonRpcProvider]]> @src<providers:class.AnkrProvider>
|
||||
|
||||
The **AnkrProvider** is backed by [Ankr](link-ankr).
|
||||
|
||||
_property: new ethers.providers.AnkrProvider([ network = "homestead", [ apiKey ] ])
|
||||
Create a new **AnkrProvider** connected to //network// with
|
||||
the optional //apiKey//.
|
||||
|
||||
The //network// may be specified as a **string** for a common
|
||||
network name, a **number** for a common chain ID or a
|
||||
[Network Object](providers-Network).
|
||||
|
||||
_note: Note: Default API keys
|
||||
If no //apiKey// is provided, a shared API key will be used,
|
||||
which may result in reduced performance and throttled requests.
|
||||
|
||||
It is highly recommended for production, you register with
|
||||
[Ankr](link-ankr) for your own API key.
|
||||
|
||||
_definition: **Supported Networks**
|
||||
|
||||
- ``homestead`` - Homestead (Mainnet)
|
||||
- ``matic`` - Polygon
|
||||
- ``arbitrum`` - Arbitrum (L2; optimistic roll-up)
|
||||
|
||||
_code: Ankr Examples @lang<javascript>
|
||||
|
||||
//_hide: const AnkrProvider = ethers.providers.AnkrProvider;
|
||||
//_hide: const apiKey = "...";
|
||||
|
||||
// Connect to mainnet (homestead)
|
||||
provider = new AnkrProvider();
|
||||
|
||||
// Connect to polygont
|
||||
// (see EtherscanProvider above for other network examples)
|
||||
provider = new AnkrProvider("matic");
|
||||
|
||||
// Connect to mainnet with an API Key (these are equivalent)
|
||||
provider = new AnkrProvider(null, apiKey);
|
||||
provider = new AnkrProvider("homestead", apiKey);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -92,10 +116,11 @@ _code: Example: Override the ENS registry @lang<script>
|
||||
|
||||
const network = {
|
||||
name: "dev",
|
||||
chianId: 1337,
|
||||
chainId: 1337,
|
||||
ensAddress: customEnsAddress
|
||||
};
|
||||
|
||||
|
||||
_subsection: Provider Documentation
|
||||
|
||||
_toc:
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
_section: JsonRpcProvider @<JsonRpcProvider> @INHERIT<[[Provider]]> @SRC<providers:class.JsonRpcProvider>
|
||||
_section: JsonRpcProvider @<JsonRpcProvider> @INHERIT<[[BaseProvider]]> @SRC<providers:class.JsonRpcProvider>
|
||||
|
||||
The [JSON-RPC API](link-jsonrpc) is a popular method for interacting
|
||||
with Ethereum and is available in all major Ethereum node implementations
|
||||
(e.g. [[link-geth]] and [[link-parity]]) as well as many
|
||||
third-party web services (e.g. [[link-infura]])
|
||||
|
||||
_property: new ethers.providers.JsonRpcProvider([ url [ , aNetworkish ] ]) @SRC<providers:constructor.JsonRpcProvider>
|
||||
Connect to a JSON-RPC API located at //url// using the //aNetworkish// network.
|
||||
If //url// is not specified, the default (i.e. ``http:/\/localhost:8545``) is used
|
||||
and if no network is specified, it will be determined automatically by
|
||||
querying the node.
|
||||
_property: new ethers.providers.JsonRpcProvider([ urlOrConnectionInfo [ , networkish ] ]) @SRC<providers:constructor.JsonRpcProvider>
|
||||
Connect to a JSON-RPC HTTP API using the URL or [[ConnectionInfo]] //urlOrConnectionInfo//
|
||||
connected to the //networkish// network.
|
||||
|
||||
If //urlOrConnectionInfo// is not specified, the default (i.e. ``http:/\/localhost:8545``)
|
||||
is used and if no network is specified, it will be determined automatically by querying the
|
||||
node using ``eth_chainId`` and falling back on ``eth_networkId``.
|
||||
|
||||
_note: Note: Connecting to a Local Node
|
||||
Each node implementation is slightly different and may require specific
|
||||
@@ -17,6 +19,9 @@ command-line flags, configuration or settings in their UI to enable
|
||||
JSON-RPC, unlock accounts or expose specific APIs. Please consult
|
||||
their documentation.
|
||||
|
||||
_property: jsonRpcProvider.connection => [[ConnectionInfo]]
|
||||
The fully formed [[ConnectionInfo]] the Provider is connected to.
|
||||
|
||||
_property: jsonRpcProvider.getSigner([ addressOrIndex ]) => [[JsonRpcSigner]] @<JsonRpcProvider-getSigner> @SRC<providers/json-rpc-provider>
|
||||
Returns a [[JsonRpcSigner]] which is managed by this Ethereum node, at
|
||||
//addressOrIndex//. If no //addressOrIndex// is provided, the first
|
||||
@@ -24,7 +29,7 @@ account (account #0) is used.
|
||||
|
||||
_property: jsonRpcProvider.getUncheckedSigner([ addressOrIndex ]) => [[UncheckedJsonRpcSigner]] @<JsonRpcProvider-getUncheckedSigner> @SRC<providers/json-rpc-provider>
|
||||
|
||||
_property: jsonRpcProvider.listAccounts() => Array<string> @<JsonRpcProvider-listAccounts> @SRC<providers/json-rpc-provider>
|
||||
_property: jsonRpcProvider.listAccounts() => Promise<Array<string>> @<JsonRpcProvider-listAccounts> @SRC<providers/json-rpc-provider>
|
||||
Returns a list of all account addresses managed by this provider.
|
||||
|
||||
_property: jsonRpcProvider.send(method, params) => Promise<any> @<JsonRpcProvider-send> @SRC<providers/json-rpc-provider>
|
||||
@@ -73,6 +78,25 @@ object, with most of the properties set to null, but allows access to the
|
||||
transaction hash quickly, if that is all that is required.
|
||||
|
||||
|
||||
_subsection: StaticJsonRpcProvider @<StaticJsonRpcProvider> @INHERIT<[[JsonRpcProvider]]> @SRC<providers:class.StaticJsonRpcProvider>
|
||||
|
||||
An ethers Provider will execute frequent ``getNetwork`` calls to ensure
|
||||
the network calls and network being communicated with are consistent.
|
||||
|
||||
In the case of a client like MetaMask, this is desired as the network
|
||||
may be changed by the user at any time, in such cases the cost of
|
||||
checking the chainId is local and therefore cheap.
|
||||
|
||||
However, there are also many times where it is known the network cannot
|
||||
change, such as when connecting to an INFURA endpoint, in which case,
|
||||
the **StaticJsonRpcProvider** can be used which will indefinitely cache
|
||||
the chain ID, which can reduce network traffic and reduce round-trip
|
||||
queries for the chain ID.
|
||||
|
||||
This [[Provider]] should **only** be used when it is known the network
|
||||
cannot change.
|
||||
|
||||
|
||||
_subsection: Node-Specific Methods @<JsonRpcProvider--other>
|
||||
|
||||
Many methods are less common or specific to certain Ethereum Node implementations
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
_section: Other Providers
|
||||
|
||||
Others...
|
||||
|
||||
_subsection: FallbackProvider @<FallbackProvider> @INHERIT<[[Provider]]> @SRC<providers/fallback-provider:class.FallbackProvider>
|
||||
_subsection: FallbackProvider @<FallbackProvider> @INHERIT<[[BaseProvider]]> @SRC<providers/fallback-provider:class.FallbackProvider>
|
||||
|
||||
The **FallbackProvider** is the most advanced [[Provider]] available in
|
||||
ethers.
|
||||
@@ -11,7 +9,7 @@ It uses a quorum and connects to multiple [Providers](Provider) as backends,
|
||||
each configured with a //priority// and a //weight// .
|
||||
|
||||
When a request is made, the request is dispatched to multiple backends, randomly
|
||||
chosen (higher priority backends are always selected first) and the results from
|
||||
chosen (lower-value priority backends are always selected first) and the results from
|
||||
each are compared against the others. Only once the quorum has been reached will that
|
||||
result be accepted and returned to the caller.
|
||||
|
||||
@@ -40,9 +38,9 @@ _property: fallbackProviderConfig.provider => [[Provider]]
|
||||
The provider for this configuration.
|
||||
|
||||
_property: fallbackProviderConfig.priority => number
|
||||
The priority used for the provider. Higher priorities are favoured over lower
|
||||
priorities. If multiple providers share the same priority, they are chosen
|
||||
at random.
|
||||
The priority used for the provider. Lower-value priorities are favoured over
|
||||
higher-value priorities. If multiple providers share the same priority, they
|
||||
are chosen at random.
|
||||
|
||||
_property: fallbackProviderConfig.stallTimeout => number
|
||||
The timeout (in ms) after which another [[Provider]] will be attempted. This
|
||||
@@ -70,6 +68,18 @@ _property: ipcProvider.path => string
|
||||
The path this [[Provider]] is connected to.
|
||||
|
||||
|
||||
_subsection: JsonRpcBatchProvider @<JsonRpcBatchProvider> @INHERIT<[[JsonRpcProvider]]> @SRC<providers:class.JsonRpcBatchProvider>
|
||||
|
||||
The **JsonRpcBatchProvider** operated identically to any other Provider,
|
||||
except the calls are implicly batched during an event-loop and sent using
|
||||
the JSON-RPC batch protocol to the backend.
|
||||
|
||||
This results in fewer connections and fewer requests, which may result
|
||||
in lower costs or faster responses, depending on your use case.
|
||||
|
||||
Keep in mind some backends may not support batched requests.
|
||||
|
||||
|
||||
_subsection: UrlJsonRpcProvider @<UrlJsonRpcProvider> @INHERIT<[[JsonRpcProvider]]> @SRC<providers:class.UrlJsonRpcProvider>
|
||||
|
||||
This class is intended to be sub-classed and not used directly. It
|
||||
@@ -101,7 +111,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
|
||||
@@ -156,7 +166,7 @@ WebSockets are much more intensive on your server resources, as they must manage
|
||||
and maintain the state for each client. For this reason, many services may also
|
||||
charge additional fees for using their WebSocket endpoints.
|
||||
|
||||
_property: new ethers.provider.WebSocketProvider([ url [ , network ] ])
|
||||
_property: new ethers.providers.WebSocketProvider([ url [ , network ] ])
|
||||
Returns a new [[WebSocketProvider]] connected to //url// as the //network//.
|
||||
|
||||
If //url// is unspecified, the default ``"ws:/\/localhost:8546"`` will be used.
|
||||
|
||||
@@ -1,42 +1,61 @@
|
||||
_section: Provider @<Provider>
|
||||
|
||||
Explain what a provider is...
|
||||
A **Provider** in ethers is a read-only abstraction to
|
||||
access the blockchain data.
|
||||
|
||||
_note: Coming from Web3.js?
|
||||
If you are coming from Web3.js, this is one of the biggest
|
||||
differences you will encounter using ethers.
|
||||
|
||||
The ethers library creates a strong division between the
|
||||
operation a **Provider** can perform and those of a [[Signer]],
|
||||
which Web3.js lumps together.
|
||||
|
||||
This separation of concerns and a stricted subset of Provider
|
||||
operations allows for a larger variety of backends, a more
|
||||
consistent API and ensures other libraries to operate without
|
||||
being able to rely on any underlying assumption.
|
||||
|
||||
_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>
|
||||
@@ -45,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>
|
||||
|
||||
@@ -73,26 +96,118 @@ reading and debugging much simpler.
|
||||
The provider offers some basic operations to help resolve and
|
||||
work with ENS names.
|
||||
|
||||
_property: provider.getAvatar(name) => Promise<string>
|
||||
Returns the URL for the avatar associated to the ENS name, or null
|
||||
if no avatar was configured.
|
||||
|
||||
_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");
|
||||
//!
|
||||
//_result:
|
||||
await provider.resolveName("ricmoo.eth");
|
||||
//_log:
|
||||
|
||||
// Lookup an address of an ENS name...
|
||||
provider.resolveName("ricmoo.firefly.eth");
|
||||
//!
|
||||
|
||||
_subsection: EnsResolver @<EnsResolver>
|
||||
|
||||
_property: resolver.name => string
|
||||
The name of this resolver.
|
||||
|
||||
_property: resolver.address => string<[[address]]>
|
||||
The address of the Resolver.
|
||||
|
||||
_property: resolver.getAddress([ cointType = 60 ]) => Promise<string>
|
||||
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.getAvatar() => Promise<AvatarInfo>
|
||||
Returns an object the provides the URL of the avatar and the
|
||||
linkage representing each stage in the avatar resolution.
|
||||
|
||||
If there is no avatar found (or the owner of any NFT does not
|
||||
match the name owner), null is returned.
|
||||
|
||||
The AvatarInfo has the properties:
|
||||
|
||||
- ``info.linkage`` - An array of info on each step resolving the avatar
|
||||
- ``info.url`` - The URL of the avatar
|
||||
|
||||
_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>
|
||||
|
||||
@@ -109,36 +224,65 @@ _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: Network Status Examples @lang<javascript>
|
||||
_code: @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)...
|
||||
// The gas price (in wei)...
|
||||
gasPrice = await provider.getGasPrice()
|
||||
//! async gasPrice
|
||||
//_log: gasPrice
|
||||
|
||||
// ...often this gas price is easier to understand or
|
||||
// display to the user in gwei (giga-wei, or 1e9 wei)
|
||||
// display to the user in gwei
|
||||
//_result:
|
||||
utils.formatUnits(gasPrice, "gwei")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
_property: provider.getFeeData() => Promise<[[providers-FeeData]]> @<Provider-getFeeData> @SRC<abstract-provider>
|
||||
Returns the current recommended [[providers-FeeData]] to use in a transaction.
|
||||
|
||||
For an EIP-1559 transaction, the ``maxFeePerGas`` and ``maxPriorityFeePerGas``
|
||||
should be used.
|
||||
|
||||
For legacy transactions and networks which do not support EIP-1559, the ``gasPrice``
|
||||
should be used.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
// The gas price (in wei)...
|
||||
feeData = await provider.getFeeData()
|
||||
//_log: feeData
|
||||
|
||||
// ...often these values are easier to understand or
|
||||
// display to the user in gwei
|
||||
//_result:
|
||||
utils.formatUnits(feeData.maxFeePerGas, "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.
|
||||
|
||||
This can be used for testing or attaching scripts to wait until the node is
|
||||
up and running smoothly.
|
||||
|
||||
|
||||
_subsection: Transactions Methods @<Provider--transaction-methods>
|
||||
@@ -148,6 +292,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 resolver 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.
|
||||
@@ -156,44 +312,116 @@ 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.
|
||||
|
||||
If a transaction has not been mined, this method will search the transaction
|
||||
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.
|
||||
|
||||
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();
|
||||
//_hide: const tx = await localSigner.populateTransaction({ to: "ricmoo.eth", value: ethers.utils.parseEther("3.14159") });
|
||||
//_hide: const signedTx = await localSigner.signTransaction(tx);
|
||||
|
||||
//_verbatim: `const signedTx = ${ JSON.stringify(signedTx) };`
|
||||
//_result:
|
||||
await provider.sendTransaction(signedTx);
|
||||
//_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.
|
||||
|
||||
If //confirms// is 0, this method is non-blocking and if the
|
||||
transaction has not been mined returns null. Otherwise,
|
||||
this method will block until the transaction has //confirms//
|
||||
blocks mined on top of the block in which is was mined.
|
||||
|
||||
_subsection: Event Emitter Methods @<Provider--event-methods>
|
||||
|
||||
Explain events here...
|
||||
The EventEmitter API allows applications to use an
|
||||
[[link-wiki-observer-pattern]] to register callbacks for when
|
||||
various events occur.
|
||||
|
||||
This closely follows the Event Emitter provided by other JavaScript
|
||||
libraries with the exception that event names support some more
|
||||
[complex objects](Provider--events), not only strings. The objects
|
||||
are normalized internally.
|
||||
|
||||
_property: provider.on(eventName, listener) => this @<Provider-on> @SRC<providers/base-provider>
|
||||
Add a //listener// to be triggered for each //eventName//.
|
||||
Add a //listener// to be triggered for each //eventName// [event](Provider--events).
|
||||
|
||||
_property: provider.once(eventName, listener) => this @<Provider-once> @SRC<providers/base-provider>
|
||||
Add a //listener// to be triggered for only the next //eventName//,
|
||||
at which time it will be removed.
|
||||
Add a //listener// to be triggered for only the next
|
||||
//eventName// [event](Provider--events), at which time it will be removed.
|
||||
|
||||
_property: provider.emit(eventName, ...args) => boolean @<Provider-emit> @SRC<providers/base-provider>
|
||||
Notify all listeners of //eventName//, passing //args// to each listener. This
|
||||
is generally only used internally.
|
||||
Notify all listeners of the //eventName// [event](Provider--events),
|
||||
passing //args// to each listener. This is generally only used internally.
|
||||
|
||||
_property: provider.off(eventName [ , listener ]) => this @<Provider-off> @SRC<providers/base-provider>
|
||||
Remove a //listener// for //eventName//. If no //listener// is provided,
|
||||
all listeners for //eventName// are removed.
|
||||
Remove a //listener// for the //eventName// [event](Provider--events).
|
||||
If no //listener// is provided, all listeners for //eventName// are removed.
|
||||
|
||||
_property: provider.removeAllListeners([ eventName ]) => this @<Provider-removeAllListeners> @SRC<providers/base-provider>
|
||||
Remove all the listeners for //eventName//. If no //eventName// is provided,
|
||||
**all** events are removed.
|
||||
Remove all the listeners for the //eventName// [events](Provider--events).
|
||||
If no //eventName// is provided, **all** events are removed.
|
||||
|
||||
_property: provider.listenerCount([ eventName ]) => number @<Provider-listenerCount> @SRC<providers/base-provider>
|
||||
Returns the number of listeners for //eventName//. If no //eventName// is
|
||||
provided, the total number of listeners is returned.
|
||||
Returns the number of listeners for the //eventName// [events](Provider--events).
|
||||
If no //eventName// is provided, the total number of listeners is returned.
|
||||
|
||||
_property: provider.listeners(eventName) => Array<Listener> @<Provider-listeners> @SRC<providers/base-provider>
|
||||
Returns the list of Listeners for //eventName//.
|
||||
Returns the list of Listeners for the //eventName// [events](Provider--events).
|
||||
|
||||
|
||||
_heading: Events @<Provider--events>
|
||||
@@ -207,7 +435,7 @@ properties ``address`` (the source contract) and ``topics`` (a topic-set to matc
|
||||
|
||||
If ``address`` is unspecified, the filter matches any contract address.
|
||||
|
||||
See events for more information on how to specify topic-sets.
|
||||
See [EventFilters](providers-EventFilter) for more information on filtering events.
|
||||
|
||||
_definition: **Topic-Set Filter**
|
||||
|
||||
@@ -216,6 +444,8 @@ The value of a **Topic-Set Filter** is a array of Topic-Sets.
|
||||
This event is identical to a //Log Filter// with the address omitted (i.e. from
|
||||
any contract).
|
||||
|
||||
See [EventFilters](providers-EventFilter) for more information on filtering events.
|
||||
|
||||
_definition: **Transaction Filter**
|
||||
|
||||
The value of a **Transaction Filter** is any transaction hash.
|
||||
@@ -260,11 +490,10 @@ $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;
|
||||
//_hide: const hexZeroPad = ethers.utils.hexZeroPad;
|
||||
|
||||
provider.on("block", (blockNumber) => {
|
||||
// Emitted on every block change
|
||||
@@ -296,8 +525,8 @@ topicSets = [
|
||||
utils.id("Transfer(address,address,uint256)"),
|
||||
null,
|
||||
[
|
||||
myAddress,
|
||||
myOtherAddress
|
||||
hexZeroPad(myAddress, 32),
|
||||
hexZeroPad(myOtherAddress, 32)
|
||||
]
|
||||
]
|
||||
provider.on(topicSets, (log, event) => {
|
||||
@@ -314,13 +543,24 @@ 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>
|
||||
|
||||
_property: Provider.isProvider(object) => boolean @<Provider-isProvider> @SRC<abstract-provider>
|
||||
Returns true if and only if //object// is a Provider.
|
||||
|
||||
|
||||
_subsection: BaseProvider @<BaseProvider> @INHERIT<[[Provider]]> @SRC<providers:class.BaseProvider>
|
||||
|
||||
Most Providers available in ethers are sub-classes of BaseProvider, which
|
||||
simplifies sub-classes, as it handles much of the event operations, such as
|
||||
polling and formatting.
|
||||
|
||||
_property: provider.polling => boolean
|
||||
Indicates if the Provider is currently polling. If there are no events to
|
||||
poll for or polling has been explicitly disabled, this will be false.
|
||||
|
||||
_property: provider.pollingInterval => number
|
||||
The frequency at which the provider polls.
|
||||
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
_section: Types
|
||||
|
||||
_subsection: BlockTag @<providers-BlockTag>
|
||||
A **BlockTag** specifies a specific location in the Blockchain.
|
||||
A **BlockTag** specifies a specific block location in the Blockchain.
|
||||
|
||||
- **``"latest"``** -- The most recently mined block
|
||||
- **``"earliest"``** -- Block #0
|
||||
- **``"pending"``** -- The block currently being prepared for mining; not all
|
||||
- **``"latest"``** - The most recently mined block
|
||||
- **``"earliest"``** - Block #0
|
||||
- **``"pending"``** - The block currently being prepared for mining; not all
|
||||
operations and backends support this BlockTag
|
||||
- **//number//** -- The block at this height
|
||||
- **//a negative number//** -- The block this many blocks ago
|
||||
|
||||
_heading: EventType @<providers-EventType>
|
||||
|
||||
And **EventType** can be any of the following.
|
||||
|
||||
- **//string//** -- TODO...
|
||||
- **//Array<string<[[DataHexString]]<32>> | Array<string<[[DataHexString]]<32>>>>//** -- TODO...
|
||||
- **//[[providers-EventFilter]]//** -- TODO...
|
||||
|
||||
- **//number//** - The block at this height
|
||||
- **//a negative number//** - The block this many blocks ago
|
||||
- **//hex string//** - The block at this height (as a hexidecimal value)
|
||||
|
||||
_subsection: Networkish @<providers-Networkish>
|
||||
A **Networkish** may be any of the following:
|
||||
@@ -42,6 +34,23 @@ _property: network.ensAddress => string<[[address]]>
|
||||
The address at which the ENS registry is deployed on this network.
|
||||
|
||||
|
||||
_subsection: FeeData @<providers-FeeData>
|
||||
|
||||
A **FeeData** object encapsulates the necessary fee data required
|
||||
to send a transaction, based on the best available recommendations.
|
||||
|
||||
_property: feeData.gasPrice => [[BigNumber]]
|
||||
The gasPrice to use for legacy transactions or networks which do not
|
||||
support EIP-1559.
|
||||
|
||||
_property: feeData.maxFeePerGas => [[BigNumber]]
|
||||
The ``maxFeePerGas`` to use for a transaction. This is based on the
|
||||
most recent block's ``baseFee``.
|
||||
|
||||
_property: feeData.maxPriorityFeePerGas => [[BigNumber]]
|
||||
The ``maxPriorityFeePerGas`` to use for a transaction. This accounts
|
||||
for the uncle risk and for the majority of current MEV risk.
|
||||
|
||||
_subsection: Block @<providers-Block>
|
||||
|
||||
_property: block.hash => string<[[DataHexString]]<32>>
|
||||
@@ -64,6 +73,21 @@ This property is generally of little interest to developers.
|
||||
_property: block.difficulty => number
|
||||
The difficulty target required to be met by the miner of the block.
|
||||
|
||||
Recently the difficulty frequently exceeds the size that a JavaScript
|
||||
number can safely store (53-bits), so in that case this property may
|
||||
be null. It is recommended to use the `_difficulty` property below,
|
||||
which will always return a value, but as a [[BigNumber]].
|
||||
|
||||
This property is generally of little interest to developers.
|
||||
|
||||
_property: block._difficulty => [[BigNumber]]
|
||||
The difficulty target required to be met by the miner of the block,
|
||||
as a [[BigNumber]].
|
||||
|
||||
Recently the difficulty frequently exceeds the size that a JavaScript
|
||||
number can safely store (53-bits), so this property was added to
|
||||
safely encode the value for applications that require it.
|
||||
|
||||
This property is generally of little interest to developers.
|
||||
|
||||
_property: block.gasLimit => [[BigNumber]]
|
||||
@@ -111,10 +135,15 @@ _heading: EventFilter @<providers-EventFilter>
|
||||
_property: filter.address => string<[[address]]>
|
||||
The address to filter by, or ``null`` to match any address.
|
||||
|
||||
_property: filter.topics => Array<string<[[DataHexString]]<32>> | Array<string<[[DataHexString]]<32>>>>
|
||||
The topics to filter by, or ``null`` to match any topics. Each entry represents an
|
||||
**AND** condition that must match, or may be ``null`` to match anything. If a given
|
||||
entry is an Array, then that entry is treated as an **OR** for any value in the entry.
|
||||
_property: filter.topics => Array<string<[Data](DataHexString)<32>> | Array<string<[Data](DataHexString)<32>>>>
|
||||
The topics to filter by or ``null`` to match any topics.
|
||||
|
||||
Each entry represents an **AND** condition that must match, or may
|
||||
be ``null`` to match anything. If a given entry is an Array, then
|
||||
that entry is treated as an **OR** for any value in the entry.
|
||||
|
||||
See [Filters](events--filters) for more details and examples
|
||||
on specifying complex filters.
|
||||
|
||||
_heading: Filter @<providers-Filter> @INHERIT<[[providers-EventFilter]]>
|
||||
|
||||
@@ -186,18 +215,47 @@ _property: transactionRequest.nonce => number | Promise<number>
|
||||
The nonce for this transaction. This should be set to the number of
|
||||
transactions ever sent **from** this address.
|
||||
|
||||
_property: transactionRequest.gasLimit => [[BigNumber]] | Promise<[[BigNumber]]>
|
||||
The maximum amount of gas this transaction is permitted to use.
|
||||
|
||||
_property: transactionRequest.gasPrice => [[BigNumber]] | Promise<[[BigNumber]]>
|
||||
The price (in wei) per unit of gas this transaction will pay.
|
||||
|
||||
_property: transactionRequest.data => [[DataHexString]] | Promise<[[DataHexString]]>
|
||||
The transaction data.
|
||||
|
||||
_property: transactionRequest.value => [[BigNumber]] | Promise<[[BigNumber]]>
|
||||
The amount (in wei) this transaction is sending.
|
||||
|
||||
_property: transactionRequest.gasLimit => [[BigNumber]] | Promise<[[BigNumber]]>
|
||||
The maximum amount of gas this transaction is permitted to use.
|
||||
|
||||
If left unspecified, ethers will use ``estimateGas`` to determine the value
|
||||
to use. For transactions with unpredicatable gas estimates, this may be required
|
||||
to specify explicitly.
|
||||
|
||||
_property: transactionRequest.gasPrice => [[BigNumber]] | Promise<[[BigNumber]]>
|
||||
The price (in wei) per unit of gas this transaction will pay.
|
||||
|
||||
This may not be specified for transactions with ``type`` set to ``1`` or ``2``, or
|
||||
if ``maxFeePerGas`` or ``maxPriorityFeePerGas`` is given.
|
||||
|
||||
_property: transactionRequest.maxFeePerGas => [[BigNumber]] | Promise<[[BigNumber]]>
|
||||
The maximum price (in wei) per unit of gas this transaction will pay for the
|
||||
combined [[link-eip-1559]] block's base fee and this transaction's priority fee.
|
||||
|
||||
Most developers should leave this unspecified and use the default value that
|
||||
ethers determines from the network.
|
||||
|
||||
This may not be specified for transactions with ``type`` set to ``0`` or if ``gasPrice``
|
||||
is specified..
|
||||
|
||||
_property: transactionRequest.maxPriorityFeePerGas => [[BigNumber]] | Promise<[[BigNumber]]>
|
||||
The price (in wei) per unit of gas this transaction will allow in addition to
|
||||
the [[link-eip-1559]] block's base fee to bribe miners into giving this transaction
|
||||
priority. This is **included in** the ``maxFeePerGas``, so this will **not affect**
|
||||
the total maximum cost set with ``maxFeePerGas``.
|
||||
|
||||
Most developers should leave this unspecified and use the default value that
|
||||
ethers determines from the network.
|
||||
|
||||
This may not be specified for transactions with ``type`` set to ``0`` or if ``gasPrice``
|
||||
is specified.
|
||||
|
||||
_property: transactionRequest.chainId => number | Promise<number>
|
||||
The chain ID this transaction is authorized on, as specified by
|
||||
[EIP-155](link-eip-155).
|
||||
@@ -205,7 +263,19 @@ The chain ID this transaction is authorized on, as specified by
|
||||
If the chain ID is 0 will disable EIP-155 and the transaction will be valid
|
||||
on any network. This can be **dangerous** and care should be taken, since it
|
||||
allows transactions to be replayed on networks that were possibly not
|
||||
intended.
|
||||
intended. Intentionally-replayable transactions are also disabled by default
|
||||
on recent versions of Geth and require configuration to enable.
|
||||
|
||||
_property: transactionRequest.type => null | number
|
||||
|
||||
The [[link-eip-2718]] type of this transaction envelope, or ``null``
|
||||
for to use the network default. To force using a lagacy transaction
|
||||
without an envelope, use type ``0``.
|
||||
|
||||
_property: transactionRequest.accessList => [[providers-AccessListish]]
|
||||
|
||||
The [[providers-AccessList]] to include; only available for [[link-eip-2930]]
|
||||
and [[link-eip-1559]] transactions.
|
||||
|
||||
_heading: TransactionResponse @<providers-TransactionResponse> @INHERIT<[[Transaction]]>
|
||||
|
||||
@@ -229,11 +299,45 @@ The number of blocks that have been mined (including the initial block) since th
|
||||
transaction was mined.
|
||||
|
||||
_property: transaction.raw => string<[[DataHexString]]>
|
||||
The serialized transaction.
|
||||
The serialized transaction. This may be null as some backends do not
|
||||
populate it. If this is required, it can be computed from a **TransactionResponse**
|
||||
object using [this cookbook recipe](cookbook--compute-raw-transaction).
|
||||
|
||||
_property: transaction.wait([ confirmations = 1 ]) => Promise<[[providers-TransactionReceipt]]>
|
||||
Wait for //confirmations//. If 0, and the transaction has not been mined,
|
||||
``null`` is returned.
|
||||
_property: transaction.wait([ confirms = 1 ]) => Promise<[[providers-TransactionReceipt]]>
|
||||
Resolves to the [[providers-TransactionReceipt]] once the transaction
|
||||
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
|
||||
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 => number
|
||||
The [[link-eip-2718]] type of this transaction. If the transaction
|
||||
is a legacy transaction without an envelope, it will have the type ``0``.
|
||||
|
||||
_property: transactionRequest.accessList => [[providers-AccessList]]
|
||||
The [[providers-AccessList]] included, or null for transaction types which
|
||||
do not support access lists.
|
||||
|
||||
_heading: TransactionReceipt @<providers-TransactionReceipt>
|
||||
|
||||
@@ -257,6 +361,10 @@ _property: receipt.transactionIndex => number
|
||||
The index of this transaction in the list of transactions included in
|
||||
the block this transaction was mined in.
|
||||
|
||||
_property: receipt.type => number
|
||||
The [[link-eip-2718]] type of this transaction. If the transaction
|
||||
is a legacy transaction without an envelope, it will have the type ``0``.
|
||||
|
||||
_property: receipt.root => string
|
||||
The intermediate state root of a receipt.
|
||||
|
||||
@@ -271,6 +379,16 @@ must be considered.
|
||||
_property: receipt.gasUsed => [[BigNumber]]
|
||||
The amount of gas actually used by this transaction.
|
||||
|
||||
_property: receipt.effectiveGasPrice => [[BigNumber]]
|
||||
The effective gas price the transaction was charged at.
|
||||
|
||||
Prior to EIP-1559 or on chains that do not support it, this value will
|
||||
simply be equal to the transaction ``gasPrice``.
|
||||
|
||||
On EIP-1559 chains, this is equal to the block ``baseFee`` for the block
|
||||
that the transaction was included in, plus the transaction
|
||||
``maxPriorityFeePerGas`` clamped to the transaction ``maxFeePerGas``.
|
||||
|
||||
_property: receipt.logsBloom => string<[[DataHexString]]>
|
||||
A [bloom-filter](link-wiki-bloomfilter), which
|
||||
includes all the addresses and topics included in any log in this
|
||||
@@ -304,7 +422,106 @@ _property: receipt.byzantium => boolean
|
||||
This is true if the block is in a [post-Byzantium Hard Fork](link-eip-609)
|
||||
block.
|
||||
|
||||
_property: receipt.status => boolean
|
||||
_property: receipt.status => number
|
||||
The status of a transaction is 1 is successful or 0 if it was
|
||||
reverted. Only transactions included in blocks [post-Byzantium Hard Fork](link-eip-609)
|
||||
have this property.
|
||||
|
||||
_subsection: Access Lists
|
||||
|
||||
An Access List is optional an includes a list of addresses and storage
|
||||
slots for that address which should be //warmed// or pre-fetched for
|
||||
use within the execution of this transaction. A //warmed// value has an
|
||||
additional upfront cost to access, but is discounted throughout the code
|
||||
execution for reading and writing.
|
||||
|
||||
_heading: AccessListish @<providers-AccessListish>
|
||||
|
||||
A looser description of an [[providers-AccessList]], which will be
|
||||
converted internally using [accessListify](utils-accessListify).
|
||||
|
||||
|
||||
It may be any of:
|
||||
|
||||
- any [[providers-AccessList]]
|
||||
- an Array of 2-element Arrays, where the first element is the address
|
||||
and second array is an array of storage keys
|
||||
- an object, whose keys represent the addresses and each value is an
|
||||
array of storage keys
|
||||
|
||||
When using the object form (the last option), the addresses and storage
|
||||
slots will be sorted. If an explicit order for the access list is
|
||||
required, one of the other forms must be used. Most developers
|
||||
**do not** require explicit order.
|
||||
|
||||
_code: equivalent to the AccessList example below @lang<javascript>
|
||||
|
||||
// Option 1:
|
||||
// AccessList
|
||||
// see below
|
||||
|
||||
// Option 2:
|
||||
// Array< [ Address, Array<Bytes32> ] >
|
||||
//_hide: ;
|
||||
accessList = [
|
||||
[
|
||||
"0x0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
|
||||
[
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000004",
|
||||
"0x0bcad17ecf260d6506c6b97768bdc2acfb6694445d27ffd3f9c1cfbee4a9bd6d"
|
||||
]
|
||||
],
|
||||
[
|
||||
"0x5FfC014343cd971B7eb70732021E26C35B744cc4",
|
||||
[
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// Option 3:
|
||||
// Record<Address, Array<Bytes32>>
|
||||
accessList = {
|
||||
"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e": [
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000004",
|
||||
"0x0bcad17ecf260d6506c6b97768bdc2acfb6694445d27ffd3f9c1cfbee4a9bd6d"
|
||||
],
|
||||
"0x5FfC014343cd971B7eb70732021E26C35B744cc4": [
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
_heading: AccessList @<providers-AccessList>
|
||||
|
||||
An [[link-eip-2930]] transaction allows an optional **AccessList**
|
||||
which causes a transaction to //warm// (i.e. pre-cache) another
|
||||
addresses state and the specified storage keys.
|
||||
|
||||
This incurs an increased intrinsic cost for the transaction, but provides
|
||||
discounts for storage and state access throughout the execution of the
|
||||
transaction.
|
||||
|
||||
_code: example access list
|
||||
|
||||
// Array of objects with the form:
|
||||
// {
|
||||
// address: Address,
|
||||
// storageKey: Array< DataHexString< 32 > >
|
||||
// }
|
||||
|
||||
accessList = [
|
||||
{
|
||||
address: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
|
||||
storageKeys: [
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000004",
|
||||
"0x0bcad17ecf260d6506c6b97768bdc2acfb6694445d27ffd3f9c1cfbee4a9bd6d"
|
||||
]
|
||||
},
|
||||
{
|
||||
address: "0x5FfC014343cd971B7eb70732021E26C35B744cc4",
|
||||
storageKeys: [
|
||||
"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>
|
||||
@@ -224,7 +228,7 @@ does not have a secure entropy source, an error is thrown.
|
||||
Wallets created using this method will have a mnemonic.
|
||||
|
||||
_property: ethers.Wallet.fromEncryptedJson(json, password [ , progress ]) => Promise<[[Wallet]]> @<Wallet-fromEncryptedJson> @SRC<wallet>
|
||||
Create an instance from an encrypted JSON wallet.
|
||||
Create an instance by decrypting an encrypted JSON wallet.
|
||||
|
||||
If //progress// is provided it will be called during decryption
|
||||
with a value between 0 and 1 indicating the progress towards
|
||||
@@ -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>
|
||||
|
||||
@@ -42,7 +42,78 @@ _property: abiCoder.encode(types, values) => string<[[DataHexString]]> @<AbiCode
|
||||
Encode the array //values// according to the array of //types//, each of which may be a
|
||||
string or a [[ParamType]].
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const abiCoder = utils.defaultAbiCoder;
|
||||
|
||||
// Encoding simple types
|
||||
//_result:
|
||||
abiCoder.encode([ "uint", "string" ], [ 1234, "Hello World" ]);
|
||||
//_log:
|
||||
//_hide: _page.example1 = _;
|
||||
|
||||
// Encoding with arrays types
|
||||
//_result:
|
||||
abiCoder.encode([ "uint[]", "string" ], [ [ 1234, 5678 ] , "Hello World" ]);
|
||||
//_log:
|
||||
//_hide: _page.example2 = _;
|
||||
|
||||
// Encoding complex structs (using positional properties)
|
||||
//_result:
|
||||
abiCoder.encode(
|
||||
[ "uint", "tuple(uint256, string)" ],
|
||||
[
|
||||
1234,
|
||||
[ 5678, "Hello World" ]
|
||||
]
|
||||
);
|
||||
//_log:
|
||||
//_hide: _page.example3 = _;
|
||||
|
||||
// Encoding complex structs (using keyword properties)
|
||||
//_result:
|
||||
abiCoder.encode(
|
||||
[ "uint a", "tuple(uint256 b, string c) d" ],
|
||||
[
|
||||
1234,
|
||||
{ b: 5678, c: "Hello World" }
|
||||
]
|
||||
);
|
||||
//_log:
|
||||
|
||||
_property: abiCoder.decode(types, data) => [[Result]] @<AbiCoder-decode> @SRC<abi/abi-coder>
|
||||
|
||||
Decode the //data// according to the array of //types//, each of which may be a
|
||||
string or [[ParamType]].
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const abiCoder = utils.defaultAbiCoder;
|
||||
|
||||
// Decoding simple types
|
||||
//_hide: data = _page.example1;
|
||||
//_verbatim: `data = ${ JSON.stringify(data) };`
|
||||
//_result:
|
||||
abiCoder.decode([ "uint", "string" ], data);
|
||||
//_log:
|
||||
|
||||
// Decoding with arrays types
|
||||
//_hide: data = _page.example2;
|
||||
//_verbatim: `data = ${ JSON.stringify(data) };`
|
||||
//_result:
|
||||
abiCoder.decode([ "uint[]", "string" ], data);
|
||||
//_log:
|
||||
|
||||
// Decoding complex structs; unnamed parameters allows ONLY
|
||||
// positional access to values
|
||||
//_hide: data = _page.example3;
|
||||
//_verbatim: `data = ${ JSON.stringify(data) };`
|
||||
//_result:
|
||||
abiCoder.decode([ "uint", "tuple(uint256, string)" ], data);
|
||||
//_log:
|
||||
|
||||
// Decoding complex structs; named parameters allows positional
|
||||
// or keyword access to values
|
||||
//_result:
|
||||
abiCoder.decode([ "uint a", "tuple(uint256 b, string c) d" ], data);
|
||||
//_log:
|
||||
|
||||
@@ -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-readable (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 Human-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,25 +219,145 @@ 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.encodeErrorResult(fragment [ , values ]) => string<[[DataHexString]]> @SRC<abi/interface>
|
||||
Returns the encoded error result, which would normally be the response from
|
||||
a reverted 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 during a revert)
|
||||
//_result:
|
||||
iface.encodeErrorResult("AccountLocked", [
|
||||
"0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
||||
parseEther("1.0")
|
||||
]);
|
||||
//_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>
|
||||
|
||||
_property: interface.decodeErrorResult(fragment, data) => [[Result]] @SRC<abi/interface>
|
||||
Returns the decoded values from the result of a call during a revert for
|
||||
//fragment// (see [[Interface--specifying-fragments]]) for the given //data//.
|
||||
|
||||
Most developers won't need this, as the ``decodeFunctionResult`` will automatically
|
||||
decode errors if the //data// represents a revert.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const iface = _page.iface;
|
||||
|
||||
// Decoding result data (e.g. from an eth_call)
|
||||
errorData = "0xf7c3865a0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba720000000000000000000000000000000000000000000000000de0b6b3a7640000";
|
||||
|
||||
//_result:
|
||||
iface.decodeErrorResult("AccountLocked", errorData)
|
||||
//_log:
|
||||
|
||||
_property: interface.decodeEventLog(fragment, data [ , topics ]) => [[Result]] @SRC<abi/interface>
|
||||
Returns the decoded event values from an event log for
|
||||
//fragment// (see [[Interface--specifying-fragments]]) for the given //data//
|
||||
@@ -100,6 +365,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,25 +392,119 @@ 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
|
||||
automatically search the ABI for a matching Event or Function and decode
|
||||
the components as a fully specified description.
|
||||
|
||||
_property: interface.parseError(data) => [[ErrorDescription]] @SRC<abi/interface>
|
||||
Search for the error that matches the error selector in //data// and parse out
|
||||
the details.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const iface = _page.iface;
|
||||
|
||||
const data = "0xf7c3865a0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba720000000000000000000000000000000000000000000000000de0b6b3a7640000";
|
||||
|
||||
//_result:
|
||||
iface.parseError(data);
|
||||
//_hide: _.errorFragment = createClass("ErrorFragment");
|
||||
//_log:
|
||||
|
||||
_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>
|
||||
|
||||
@@ -142,6 +521,24 @@ any named value for this key is renamed to ``_length``. If there is a
|
||||
name collision, only the first is available by its key.
|
||||
|
||||
|
||||
_heading: ErrorDescription @<ErrorDescription>
|
||||
|
||||
_property: errorDescription.args => [[Result]]
|
||||
The values of the input parameters of the error.
|
||||
|
||||
_property: errorDescription.errorFragment => [[ErrorFragment]]
|
||||
The [[ErrorFragment]] which matches the selector in the data.
|
||||
|
||||
_property: errorDescription.name => string
|
||||
The error name. (e.g. ``AccountLocked``)
|
||||
|
||||
_property: errorDescription.signature => string
|
||||
The error signature. (e.g. ``AccountLocked(address,uint256)``)
|
||||
|
||||
_property: errorDescription.sighash => string
|
||||
The selector of the error.
|
||||
|
||||
|
||||
_heading: LogDescription @<LogDescription>
|
||||
|
||||
_property: logDescription.args => [[Result]]
|
||||
|
||||
@@ -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
|
||||
@@ -45,17 +44,76 @@ _property: ethers.utils.getAddress(address) => string<[[address]]> @<utils-getA
|
||||
Returns //address// as a Checksum Address.
|
||||
|
||||
If //address// is an invalid 40-nibble [[HexString]] or if it contains mixed case and
|
||||
the checksum is invalid, an InvalidArgument Error is thrown.
|
||||
the checksum is invalid, an [INVALID_ARGUMENT](errors--invalid-argument) Error is thrown.
|
||||
|
||||
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 [utils.getAddress](utils-getAddress).
|
||||
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>
|
||||
@@ -159,6 +168,10 @@ Returns true if and only if the value of //BigNumber// is zero.
|
||||
|
||||
_heading: Conversion
|
||||
|
||||
_property: BigNumber.toBigInt() => bigint @SRC<bignumber>
|
||||
Returns the value of //BigNumber// as a [JavaScript BigInt](link-js-bigint) value,
|
||||
on platforms which support them.
|
||||
|
||||
_property: BigNumber.toNumber() => number @SRC<bignumber>
|
||||
Returns the value of //BigNumber// as a JavaScript value.
|
||||
|
||||
@@ -186,8 +199,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 +228,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:
|
||||
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
_section: Byte Manipulation
|
||||
|
||||
Tra la la...
|
||||
While there are many high-level APIs for interacting with
|
||||
Ethereum, such as [Contracts](Contract) and [Providers](Provider),
|
||||
a lot of the low level access requires byte manipulation
|
||||
operations.
|
||||
|
||||
Many of these operations are used internally, but can also be
|
||||
used to help normalize binary data representations from the
|
||||
output of various functions and methods.
|
||||
|
||||
_subsection: Types
|
||||
|
||||
@@ -31,8 +38,10 @@ _heading: Signature @<Signature>
|
||||
|
||||
- **r** and **s** --- The x co-ordinate of **r** and the **s** value of the signature
|
||||
- **v** --- The parity of the y co-ordinate of **r**
|
||||
- **_vs** --- The [compact representation](link-eip-2098) of the **s** and **v**
|
||||
- **yParityAndS** --- The [compact representation](link-eip-2098) of the **s** and **v**
|
||||
- **_vs** --- Deprecated property; renamed to yParityAndS
|
||||
- **recoveryParam** --- The normalized (i.e. 0 or 1) value of **v**
|
||||
- **compact** - The full siggnature using [compact representation](link-eip-2098)
|
||||
|
||||
_heading: Raw Signature @<signature-raw> @inherit<string\<[[DataHexString]]\<65\>\>>
|
||||
|
||||
@@ -79,28 +88,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
|
||||
@@ -163,15 +178,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:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
_section: Constants @<constants>
|
||||
|
||||
The **ethers.contants** Object contains commonly used values.
|
||||
The **ethers.constants** Object contains commonly used values.
|
||||
|
||||
|
||||
_subsection: Bytes
|
||||
|
||||
@@ -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,28 +301,32 @@ 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>
|
||||
|
||||
When using the Solidity ``abi.packEncoded(...)`` function, a non-standard
|
||||
When using the Solidity ``abi.encodePacked(...)`` function, a non-standard
|
||||
//tightly packed// version of encoding is used. These functions implement
|
||||
the tightly packing algorithm.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
_section: HD Wallet @<hdnodes>
|
||||
|
||||
TODO: Explain [BIP32](link-bip-32) [BIP-39](link-bip-39) and whatnot here...
|
||||
The Hierarchal Deterministic (HD) Wallet was a standard
|
||||
created for Bitcoin, but lends itself well to a wide variety of
|
||||
Blockchains which rely on secp256k1 private keys.
|
||||
|
||||
For a more detailed technical understanding:
|
||||
|
||||
- [BIP-32](link-bip-32) - the hierarchal deterministic description
|
||||
- [BIP-39](link-bip-39) - the method used to derive the BIP-32 seed
|
||||
from human-readable sequences of words (i.e. a mnemonic)
|
||||
- [BIP-44](link-bip-44) - a standard defined to make BIP-32 easy
|
||||
to adapt to any future compatible blockchain
|
||||
|
||||
_subsection: Types
|
||||
|
||||
|
||||
@@ -48,39 +48,38 @@ Throw an Error with //message// and an optional //code// and
|
||||
additional //params// set.
|
||||
|
||||
_property: logger.throwArgumentError(message, name, value) => never @SRC<logger>
|
||||
Throw an [INVALID_ARGUMENT](errors-InvalidArgument) Error with //name// and //value//.
|
||||
|
||||
Throw an [INVALID_ARGUMENT](errors--invalid-argument) Error with //name// and //value//.
|
||||
|
||||
_heading: Usage Validation
|
||||
|
||||
There can be used to ensure various properties and actions are safe.
|
||||
|
||||
_property: logger.checkAbstract(target, kind) => void @SRC<logger>
|
||||
Checks that //target// is not //kind// and performs the same operations
|
||||
as ``checkNew``. This is useful for ensuring abstract classes are not
|
||||
being instantiated.
|
||||
_property: logger.checkAbstract(target, kind) => void @<Logger-checkAbstract> @SRC<logger>
|
||||
If //target// is //kind//, throws a [UNSUPPORTED_OPERATION](errors--unsupported-operation) error
|
||||
otherwise performs the same operations as [checkNew](Logger-checkNew).
|
||||
|
||||
_property: logger.checkArgumentCount(count, expectedCount [ , message) => void @SRC<logger>
|
||||
If //count// is not equal to //expectedCount//, throws a [MISSING_ARGUMENT](errors-MissingArgument)
|
||||
or [UNEXPECTED_ARGUMENT](errors-UnexpectedArgument) error.
|
||||
This is useful for ensuring abstract classes are not being instantiated.
|
||||
|
||||
_property: logger.checkNew(target, kind) => void @SRC<logger>
|
||||
_property: logger.checkArgumentCount(count, expectedCount [ , message) => void @<Logger-checkArgumentCount> @SRC<logger>
|
||||
If //count// is not equal to //expectedCount//, throws a [MISSING_ARGUMENT](errors--missing-argument)
|
||||
or [UNEXPECTED_ARGUMENT](errors--unexpected-argument) error.
|
||||
|
||||
_property: logger.checkNew(target, kind) => void @<Logger-checkNew> @SRC<logger>
|
||||
If //target// is not a valid ``this`` or ``target`` value, throw a
|
||||
[MISSING_NEW](errors-MissingNew) error. This is useful to ensure
|
||||
[MISSING_NEW](errors--missing-new) error. This is useful to ensure
|
||||
callers of a Class are using ``new``.
|
||||
|
||||
_property: logger.checkNormalize(message) => void @SRC<logger>
|
||||
_property: logger.checkNormalize(message) => void @<Logger-checkNoralize> @SRC<logger>
|
||||
Check that the environment has a correctly functioning [[link-js-normalize]]. If not, a
|
||||
[UNSUPPORTED_OPERATION](errors-UnsupportedOperation) error is thrown.
|
||||
[UNSUPPORTED_OPERATION](errors--unsupported-operation) error is thrown.
|
||||
|
||||
_property: logger.checkSafeUint53(value [, message ]) => void @SRC<logger>
|
||||
_property: logger.checkSafeUint53(value [, message ]) => void @<Logger-checkSafeUint53> @SRC<logger>
|
||||
If //value// is not safe as a [JavaScript number](link-wiki-ieee754), throws a
|
||||
[NUMERIC_FAULT](errors-NumericFault) error.
|
||||
|
||||
[NUMERIC_FAULT](errors--numeric-fault) error.
|
||||
|
||||
_heading: Censorship @<Logger--censorship>
|
||||
|
||||
_property: Logger.setCensorship(censor [ , permanent = false ]) => void @SRC<logger>
|
||||
_property: Logger.setCensorship(censor [ , permanent = false ]) => void @<Logger-setCensorship> @SRC<logger>
|
||||
Set error censorship, optionally preventing errors from being uncensored.
|
||||
|
||||
In production applications, this prevents any error from leaking information
|
||||
@@ -88,7 +87,7 @@ by masking the message and values of errors.
|
||||
|
||||
This can impact debugging, making it substantially more difficult.
|
||||
|
||||
_property: Logger.setLogLevel(logLevel) => void @SRC<logger>
|
||||
_property: Logger.setLogLevel(logLevel) => void @<Logger-setLogLevel> @SRC<logger>
|
||||
Set the log level, to suppress logging output below a [particular log level](Logger-levels).
|
||||
|
||||
|
||||
@@ -98,76 +97,113 @@ Every error in Ethers has a ``code`` value, which is a string that will
|
||||
match one of the following error codes.
|
||||
|
||||
|
||||
_heading: Generic Error Codes
|
||||
_heading: Generic Error Codes @<errors-generic>
|
||||
|
||||
_property: Logger.errors.NOT_IMPLEMENTED
|
||||
The operation is not implemented.
|
||||
_property: Logger.errors.NOT_IMPLEMENTED @<errors--not-implemented>
|
||||
The operation is not implemented. This may occur when calling a method
|
||||
on a sub-class that has not fully implemented its abstract superclass.
|
||||
|
||||
_property: Logger.errors.SERVER_ERROR
|
||||
_property: Logger.errors.SERVER_ERROR @<errors--server-error>
|
||||
There was an error communicating with a server.
|
||||
|
||||
_property: Logger.errors.TIMEOUT @<errors-Timeout>
|
||||
This may occur for a number of reasons, for example:
|
||||
|
||||
- a [CORS](link-cors) issue; this is quite often the problem and also the
|
||||
hardest to diagnose and fix, so it is very beneficial to familiarize
|
||||
yourself with CORS; some backends allow you configure your CORS, such as
|
||||
the geth command-line or conifguration files or the INFURA and Alchemy
|
||||
dashboards by specifing allowed Origins, methods, etc.
|
||||
- an SSL issue; for example, if you are trying to connect to a local node via
|
||||
HTTP but are serving the content from a secure HTTPS website
|
||||
- a link issue; a firewall is preventing the traffic from reaching the server
|
||||
- a server issue; the server is down, or is returning 500 error codes
|
||||
- a backend DDoS mitigation proxy; for example, Etherscan operates behind a
|
||||
Cloudflare proxy, which will block traffic if the request is sent via
|
||||
specific User Agents or the client fingerprint is detected as a bot in some
|
||||
cases
|
||||
|
||||
_property: Logger.errors.TIMEOUT @<errors--timeout>
|
||||
A timeout occurred.
|
||||
|
||||
_property: Logger.errors.UNKNOWN_ERROR @<errors-UnknownError>
|
||||
_property: Logger.errors.UNKNOWN_ERROR @<errors--unknown-error>
|
||||
A generic unknown error.
|
||||
|
||||
_property: Logger.errors.UNSUPPORTED_OPERATION @<errors-UnsupportedOperation>
|
||||
_property: Logger.errors.UNSUPPORTED_OPERATION @<errors--unsupported-operation>
|
||||
The operation is not supported.
|
||||
|
||||
This can happen for a variety reasons, for example:
|
||||
|
||||
_heading: Safety Error Codes
|
||||
- Some backends do not support certain operations; such as passing a blockTag
|
||||
to an [[EtherscanProvider]] for [call](Provider-call)
|
||||
- A [[Contract]] object connected to [[Provider]] (instead of a [[Signer]]) cannot
|
||||
[sign](Signer-signTransaction) or [send](Signer-sendTransaction) transactions
|
||||
- a [[Contract]] connected to a [[Signer]] without a [[Provider]] is write-only
|
||||
and cannot estimate gas or execute static calls
|
||||
|
||||
_property: Logger.errors.BUFFER_OVERRUN
|
||||
|
||||
_heading: Safety Error Codes @<errors-safety>
|
||||
|
||||
_property: Logger.errors.BUFFER_OVERRUN @<errors--buffer-overrun>
|
||||
The amount of data needed is more than the amount of data required,
|
||||
which would cause the data buffer to read past its end.
|
||||
|
||||
_property: Logger.errors.NUMERIC_FAULT @<errors-NumericFault>
|
||||
This can occur if a contract erroneously returns invalid ABI-encoded
|
||||
data or RLP data is malformed.
|
||||
|
||||
_property: Logger.errors.NUMERIC_FAULT @<errors--numeric-fault>
|
||||
There was an invalid operation done on numeric values.
|
||||
|
||||
Common cases of this occur when there is [[link-wiki-overflow]],
|
||||
[[link-wiki-underflow]] in fixed numeric types or division by zero.
|
||||
|
||||
|
||||
_heading: Usage Error Codes
|
||||
_heading: Usage Error Codes @<errors-usage>
|
||||
|
||||
_property: Logger.errors.INVALID_ARGUMENT @<errors-InvalidArgument>
|
||||
_property: Logger.errors.INVALID_ARGUMENT @<errors--invalid-argument>
|
||||
The type or value of an argument is invalid. This will generally also
|
||||
include the ``name`` and ``value`` of the argument. Any function which
|
||||
accepts sensitive data (such as a private key) will include the string
|
||||
``[\[REDACTED]\]`` instead of the value passed in.
|
||||
``"[\[REDACTED]\]"`` instead of the value passed in.
|
||||
|
||||
_property: Logger.errors.MISSING_ARGUMENT @<errors-MissingArgument>
|
||||
_property: Logger.errors.MISSING_ARGUMENT @<errors--missing-argument>
|
||||
An expected parameter was not specified.
|
||||
|
||||
_property: Logger.errors.MISSING_NEW @<errors-MissingNew>
|
||||
An object is a Class, but is now being called with ``new``.
|
||||
_property: Logger.errors.MISSING_NEW @<errors--missing-new>
|
||||
An object is a Class, but is not being called with ``new``.
|
||||
|
||||
_property: Logger.errors.UNEXPECTED_ARGUMENT @<errors-UnexpectedArgument>
|
||||
_property: Logger.errors.UNEXPECTED_ARGUMENT @<errors--unexpected-argument>
|
||||
Too many parameters we passed into a function.
|
||||
|
||||
|
||||
_heading: Ethereum Error Codes
|
||||
_heading: Ethereum Error Codes @<errors-ethereum>
|
||||
|
||||
_property: Logger.errors.CALL_EXCEPTION
|
||||
_property: Logger.errors.CALL_EXCEPTION @<errors--call-exception>
|
||||
An attempt to call a blockchain contract (getter) resulted in a
|
||||
revert or other error.
|
||||
revert or other error, such as insufficient gas (out-of-gas) or an
|
||||
invalid opcode. This can also occur during gas estimation or if
|
||||
waiting for a [[providers-TransactionReceipt]] which failed during execution.
|
||||
|
||||
_property: Logger.errors.INSUFFICIENT_FUNDS
|
||||
Consult the contract to determine the cause, such as a failed condition
|
||||
in a ``require`` statement. The ``reason`` property may provide more
|
||||
context for the cause of this error.
|
||||
|
||||
_property: Logger.errors.INSUFFICIENT_FUNDS @<errors--insufficient-funds>
|
||||
The account is attempting to make a transaction which costs more than is
|
||||
available.
|
||||
|
||||
A sending account must have enough ether to pay for the value, the gas limit
|
||||
(at the gas price) as well as the intrinsic cost of data. The intrinsic cost
|
||||
of data is 4 gas for each zero byte and 68 gas for each non-zero byte.
|
||||
of data is 4 gas for each zero byte and 68 gas for each non-zero byte, as well
|
||||
as 35000 gas if a transaction contains no ``to`` property and is therefore
|
||||
expected to create a new account.
|
||||
|
||||
_property: Logger.errors.NETWORK_ERROR
|
||||
_property: Logger.errors.NETWORK_ERROR @<errors--network>
|
||||
An Ethereum network validation error, such as an invalid chain ID.
|
||||
|
||||
_property: Logger.errors.NONCE_EXPIRED
|
||||
_property: Logger.errors.NONCE_EXPIRED @<errors--nonce-expired>
|
||||
The nonce being specified has already been used in a mined transaction.
|
||||
|
||||
_property: Logger.errors.REPLACEMENT_UNDERPRICED
|
||||
_property: Logger.errors.REPLACEMENT_UNDERPRICED @<errors--replacement-underpriced>
|
||||
When replacing a transaction, by using a nonce which has already been sent to
|
||||
the network, but which has not been mined yet the new transaction must specify
|
||||
a higher gas price.
|
||||
@@ -175,9 +211,28 @@ a higher gas price.
|
||||
This error occurs when the gas price is insufficient to //bribe// the transaction
|
||||
pool to prefer the new transaction over the old one. Generally, the new gas price
|
||||
should be about 50% + 1 wei more, so if a gas price of 10 gwei was used, the
|
||||
replacement should be 15.000000001 gwei.
|
||||
replacement should be 15.000000001 gwei. This is not enforced by the protocol, as
|
||||
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.UNPREDICTABLE_GAS_LIMIT
|
||||
_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.
|
||||
|
||||
|
||||
@@ -1,9 +1,40 @@
|
||||
_section: Property Utilities
|
||||
|
||||
_property: ethers.utils.checkProperties() => void
|
||||
This is a collection of utility functions used for handling
|
||||
properties in a platform-safe way.
|
||||
|
||||
The next major version of ethers will no longer be compatible
|
||||
with ES3, so many of these will be removed in favor of the
|
||||
built-in options available in ES2015 and above.
|
||||
|
||||
_property: ethers.utils.checkProperties(object, check) => void
|
||||
|
||||
Checks that //object// only contains properties included
|
||||
in //check//, and throws [INVALID_ARGUMENT](errors--invalid-argument) if not.
|
||||
|
||||
_property: ethers.utils.deepCopy(anObject) => any
|
||||
|
||||
Creates a recursive copy of //anObject//. Frozen (i.e. and other known
|
||||
immutable) objects are copied by reference.
|
||||
|
||||
_property: ethers.utils.defineReadOnly(anObject, name, value) => void
|
||||
|
||||
Uses the ``Object.defineProperty`` method to set a read-only property
|
||||
on an object.
|
||||
|
||||
_property: ethers.utils.getStatic(aConstructor, key) => any
|
||||
|
||||
Recursively check for a static method //key// on an inheritance chain
|
||||
from //aConstructor// to all ancestors.
|
||||
|
||||
This is used to mimic behaviour in other languages where ``this`` in
|
||||
a static method will also search ancestors.
|
||||
|
||||
_property: ethers.utils.resolveProperties(anObject) => Promise<any> @<utils-resolveproperties> @SRC<properties>
|
||||
|
||||
Retruns a Promise which resolves all child values on //anObject//.
|
||||
|
||||
_property: ethers.utils.shallowCopy(anObject) => any
|
||||
|
||||
Returns a shallow copy of //anObject//. This is the same as
|
||||
using ``Object.assign({ }, anObject)``.
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
_section: Strings @<strings>
|
||||
|
||||
Tra la la
|
||||
A **String** is a representation of a human-readable input of output,
|
||||
which are often taken for granted.
|
||||
|
||||
When dealing with blockchains, properly handling human-readable and
|
||||
human-provided data is important to prevent loss of funds, assets,
|
||||
incorrect permissions, etc.
|
||||
|
||||
_subsection: Bytes32String @<Bytes32String>
|
||||
|
||||
|
||||
@@ -18,6 +18,12 @@ The gas limit for this transaction.
|
||||
_property: unsignedTransaction.gasPrice => [[BigNumberish]]
|
||||
The gas price for this transaction.
|
||||
|
||||
_property: unsignedTransaction.maxFeePerGas => [[BigNumberish]]
|
||||
The maximum fee per unit of gas for this transaction.
|
||||
|
||||
_property: unsignedTransaction.maxPriorityFeePerGas => [[BigNumberish]]
|
||||
The maximum priority fee per unit of gas for this transaction.
|
||||
|
||||
_property: unsignedTransaction.data => [[BytesLike]]
|
||||
The data for this transaction.
|
||||
|
||||
@@ -38,7 +44,7 @@ The transaction hash, which can be used as an identifier for
|
||||
//transaction//. This is the keccak256 of the serialized RLP encoded
|
||||
representation of //transaction//.
|
||||
|
||||
_property: unsignedTransaction.to => string<[Address](address)>
|
||||
_property: transaction.to => string<[Address](address)>
|
||||
The address //transaction// is to.
|
||||
|
||||
_property: transaction.from => string<[Address](address)>
|
||||
@@ -57,9 +63,21 @@ refunded at the end of the transaction, and if there is insufficient gas
|
||||
to complete execution, the effects of the transaction are reverted, but
|
||||
the gas is **fully consumed** and an out-of-gas error occurs.
|
||||
|
||||
_property: transaction.gasPrice => [[BigNumber]]
|
||||
_property: transaction.gasPrice => null | [[BigNumber]]
|
||||
The price (in wei) per unit of gas for //transaction//.
|
||||
|
||||
For [[link-eip-1559]] transactions, this will be null.
|
||||
|
||||
_property: transaction.maxFeePerGas => [[BigNumber]]
|
||||
The maximum price (in wei) per unit of gas for //transaction//.
|
||||
|
||||
For transactions that are not [[link-eip-1559]] transactions, this will be null.
|
||||
|
||||
_property: transaction.maxPriorityFeePerGas => [[BigNumber]]
|
||||
The priority fee price (in wei) per unit of gas for //transaction//.
|
||||
|
||||
For transactions that are not [[link-eip-1559]] transactions, this will be null.
|
||||
|
||||
_property: transaction.data => [[BytesLike]]
|
||||
The data for //transaction//. In a contract this is the call data.
|
||||
|
||||
@@ -97,6 +115,15 @@ used to encode the chain ID into the serialized transaction.
|
||||
|
||||
_subsection: Functions @<transactions--functions>
|
||||
|
||||
_property: ethers.utils.accessListify(anAcceslistish) => [[providers-AccessList]] @<utils-accessListify> @SRC<transactions:accessListify>
|
||||
Normalizes the [[providers-AccessListish]] //anAccessListish// into
|
||||
an [[providers-AccessList]].
|
||||
|
||||
This is useful for other utility functions which wish to remain
|
||||
flexible as to the input parameter for access lists, such as
|
||||
when creating a [[Signer]] which needs to manipulate a possibly
|
||||
typed transaction envelope.
|
||||
|
||||
_property: ethers.utils.parseTransaction(aBytesLike) => [[Transaction]] @<utils-parseTransaction> @SRC<transactions:parse>
|
||||
Parses the transaction properties from a serialized transaction.
|
||||
|
||||
|
||||
@@ -33,6 +33,12 @@ How long to wait before rejecting with a //timeout// error.
|
||||
_property: connection.headers => { [ key: string]: string }
|
||||
Additional headers to include in the connection.
|
||||
|
||||
_property: connection.skipFetchSetup => boolean
|
||||
Normally a connection will specify the default values for a connection
|
||||
such as CORS-behavior and caching policy, to ensure compatibility across
|
||||
platforms. On some services, such as Cloudflare Workers, specifying any
|
||||
value (inclluding the default values) will cause failure. Setting this
|
||||
to true will prevent any values being passed to the underlying API.
|
||||
|
||||
_heading: PollOptions @<PollOptions>
|
||||
|
||||
|
||||
@@ -1,34 +1,40 @@
|
||||
_section: Events
|
||||
|
||||
Explain how topics and such work
|
||||
|
||||
_subsection: Solidity Topics
|
||||
|
||||
How to compute the topic...
|
||||
_section: Events @<events>
|
||||
|
||||
_subsection: Logs and Filtering
|
||||
|
||||
Example hog logs are used.
|
||||
Logs and filtering are used quite often in blockchain applications,
|
||||
since they allow for efficient queries of indexed data and provide
|
||||
lower-cost data storage when the data is not required to be
|
||||
accessed on-chain.
|
||||
|
||||
Link to provider.getLogs and contract.on
|
||||
These can be used in conjunction with the [Provider Events API](Provider--event-methods)
|
||||
and with the [Contract Events API](Contract--events).
|
||||
|
||||
_heading: Filters
|
||||
The Contract Events API also provides [higher-level methods](Contract--filters)
|
||||
to compute and query this data, which should be preferred over the lower-level filter.
|
||||
|
||||
Filter are used as a way to query ... efficient, explain bloom filters lightly
|
||||
_heading: Filters @<events--filters>
|
||||
|
||||
A filter may have up to 4 topic-sets, where each topic-set refers
|
||||
to a condition that must match the log topic in that position (i.e. each
|
||||
condition is ``AND``-ed together).
|
||||
When a Contract creates a log, it can include up to 4 pieces of
|
||||
data to be indexed by. The indexed data is hashed and included in
|
||||
a [[link-wiki-bloomfilter]], which is a data structure that allows
|
||||
for efficient filtering.
|
||||
|
||||
If a topic-set is ``null``, a log topic in that position is not filtered
|
||||
So, a filter may correspondingly have up to 4 topic-sets, where each
|
||||
topic-set refers to a condition that must match the indexed log topic
|
||||
in that position (i.e. each condition is ``AND``-ed together).
|
||||
|
||||
If a topic-set is ``null``, a log topic in that position is **not filtered**
|
||||
at all and **any value** matches.
|
||||
|
||||
If a topic-set is a single topic, a log topic in that position must match
|
||||
If a topic-set is a single topic, a log topic in that position **must** match
|
||||
**that topic**.
|
||||
|
||||
If a topic-set is an array of topics, a log topic in that position must
|
||||
match any **one** of the topics (i.e. the topic in this position are ``OR``-ed).
|
||||
match **any one** of the topics (i.e. the topic in this position are ``OR``-ed).
|
||||
|
||||
This may sound complicated at first, but is more easily understood with
|
||||
some examples.
|
||||
|
||||
_table: Example Log Matching @style<full>
|
||||
|
||||
@@ -51,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.
|
||||
@@ -87,33 +91,33 @@ const hexZeroPad = ethers.utils.hexZeroPad;
|
||||
filter = {
|
||||
address: tokenAddress,
|
||||
topics: [
|
||||
id("Transfer(address,address,uint256)"),
|
||||
utils.id("Transfer(address,address,uint256)"),
|
||||
hexZeroPad(myAddress, 32)
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// List all token transfers *to* myAddress:
|
||||
filter = {
|
||||
address: tokenAddress,
|
||||
topics: [
|
||||
id("Transfer(address,address,uint256)"),
|
||||
utils.id("Transfer(address,address,uint256)"),
|
||||
null,
|
||||
hexZeroPad(myAddress, 32)
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// List all token transfers *to* myAddress or myOtherAddress:
|
||||
filter = {
|
||||
address: tokenAddress,
|
||||
topics: [
|
||||
id("Transfer(address,address,uint256)"),
|
||||
utils.id("Transfer(address,address,uint256)"),
|
||||
null,
|
||||
[
|
||||
hexZeroPad(myAddress, 32),
|
||||
hexZeroPad(myOtherAddress, 32),
|
||||
]
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
_null:
|
||||
|
||||
@@ -122,35 +126,87 @@ 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>
|
||||
|
||||
This is a quick (and non-comprehensive) overview of how events are computed
|
||||
in Solidity.
|
||||
|
||||
This is likely out of the scope for most developers, but may be interesting
|
||||
to those who want to learn a bit more about the underlying technology.
|
||||
|
||||
Solidity provides two types of events, anonymous and non-anonymous. The
|
||||
default is non-anonymous, and most developers will not need to worry about
|
||||
anonymous events.
|
||||
|
||||
For non-anonymous events, up to 3 topics may be indexed (instead of 4), since
|
||||
the first topic is reserved to specify the event signature. This allows
|
||||
non-anonymous events to always be filtered by their event signature.
|
||||
|
||||
This topic hash is always in the first slot of the indexed data, and is
|
||||
computed by normalizing the Event signature and taking the keccak256 hash
|
||||
of it.
|
||||
|
||||
For anonymous events, up to 4 topics may be indexed, and there is no
|
||||
signature topic hash, so the events cannot be filtered by the event
|
||||
signature.
|
||||
|
||||
Each additional indexed property is processed depending on whether its
|
||||
length is fixed or dynamic.
|
||||
|
||||
For fixed length types (e.g. ``uint``, ``bytes5``), all of which are
|
||||
internally exactly 32 bytes (shorter types are padded with zeros;
|
||||
numeric values are padded on the left, data values padded on the right),
|
||||
these are included directly by their actual value, 32 bytes of data.
|
||||
|
||||
For dynamic types (e.g. ``string``, ``uint256[]``) , the value is hashed
|
||||
using keccak256 and this hash is used.
|
||||
|
||||
Because dynamic types are hashed, there are important consequences in
|
||||
parsing events that should be kept in mind. Mainly that the original
|
||||
value is lost in the event. So, it is possible to tell is a topic is
|
||||
equal to a given string, but if they do not match, there is no way
|
||||
to determine what the value was.
|
||||
|
||||
If a developer requires that a string value is required to be both
|
||||
able to be filtered and also able to be read, the value must be included
|
||||
in the signature twice, once indexed and once non-indexed (e.g.
|
||||
``someEvent(string indexed searchBy, string clearText)``).
|
||||
|
||||
For a more detailed description, please refer to the
|
||||
[Solidity Event Documentation](link-solidity-events).
|
||||
|
||||
_heading: Other Things? TODO
|
||||
|
||||
|
||||
@@ -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 running 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 developers inspect the memory contents of JavaScript
|
||||
programs. In these cases, any //private key// or //mnemonic//
|
||||
sitting 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.
|
||||
|
||||
Advanced timing attacks are very difficult to mitigate in any
|
||||
garbage-collection-based language. Most libraries where this
|
||||
matters will hopefully mitigate 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
|
||||
@@ -51,7 +128,7 @@ progress callback which will be periodically called with a number between
|
||||
In general a progress bar makes the experience feel faster, as well as
|
||||
more comfortable since there is a clear indication how much (relative) time
|
||||
is remaining. Additionally, using language like //"decrypting..."// in
|
||||
a progress bar makes a user feel like there time is not being //needlessly//
|
||||
a progress bar makes a user feel like their time is not being //needlessly//
|
||||
wasted.
|
||||
|
||||
_heading: Work-Arounds (not recommended)
|
||||
|
||||
@@ -43,6 +43,8 @@ function getDefinitions(source) {
|
||||
if (depth === 3) {
|
||||
add("var", node.name.escapedText, node.name.end);
|
||||
}
|
||||
} else if (ts.isGetAccessorDeclaration(node)) {
|
||||
add("getter", (lastClass + "." + node.name.text), node.name.end);
|
||||
}
|
||||
ts.forEachChild(node, (node) => { return visit(node, depth + 1); });
|
||||
}
|
||||
@@ -115,10 +117,14 @@ const getSourceUrl = (function(path, include, exclude) {
|
||||
}
|
||||
})("../packages/", new RegExp("packages/.*/src.ts/.*\.ts$"), new RegExp("/node_modules/|src.ts/.*browser.*"));
|
||||
|
||||
let localSigner = null;
|
||||
|
||||
function codeContextify(context) {
|
||||
const { inspect } = require("util");
|
||||
const ethers = context.require("./packages/ethers");
|
||||
|
||||
if (localSigner == null) { localSigner = ethers.Wallet.createRandom(); }
|
||||
|
||||
context.ethers = ethers;
|
||||
context.BigNumber = ethers.BigNumber;
|
||||
context.constants = ethers.constants;
|
||||
@@ -131,21 +137,44 @@ function codeContextify(context) {
|
||||
|
||||
// We use a local dev node for some signing examples, but want to
|
||||
// resolve ENS names against mainnet; super hacky but makes the
|
||||
// docs nicer
|
||||
// docs nicer (funded in _startup)
|
||||
context.localProvider = new ethers.providers.JsonRpcProvider();
|
||||
context.localSigner = context.localProvider.getSigner();
|
||||
context.localSigner = localSigner.connect(context.localProvider);
|
||||
context.localProvider.resolveName = context.provider.resolveName.bind(context.provider);
|
||||
|
||||
context.BigNumber.prototype[inspect.custom] = function(depth, options) {
|
||||
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,
|
||||
@@ -154,14 +183,31 @@ function codeContextify(context) {
|
||||
sorted: true,
|
||||
});
|
||||
}
|
||||
|
||||
context._startup = async function() {
|
||||
console.log("Startup");
|
||||
const signer = context.localProvider.getSigner();
|
||||
const tx = await signer.sendTransaction({
|
||||
to: localSigner.address,
|
||||
value: ethers.utils.parseEther("10.0")
|
||||
});
|
||||
await tx.wait();
|
||||
}
|
||||
|
||||
context._shutdown = function() {
|
||||
console.log("Shutdown");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
title: "ethers",
|
||||
subtitle: "v5.0",
|
||||
subtitle: "v5.4",
|
||||
description: "Documentation for ethers, a complete, tiny and simple Ethereum library.",
|
||||
logo: "logo.svg",
|
||||
|
||||
socialImage: "social.jpg",
|
||||
|
||||
prefix: "/v5",
|
||||
|
||||
link: "https:/\/docs.ethers.io",
|
||||
@@ -178,7 +224,9 @@ module.exports = {
|
||||
codeRoot: "../",
|
||||
|
||||
externalLinks: {
|
||||
"link-mail": "mailto:me@ricmoo.com",
|
||||
"link-alchemy": { name: "Alchemy", url: "https:/\/alchemyapi.io" },
|
||||
"link-ankr": { name: "Ankr", url: "https:/\/www.ankr.com" },
|
||||
"link-cloudflare": { name: "Cloudflare", url: "https:/\/developers.cloudflare.com/distributed-web/ethereum-gateway/" },
|
||||
"link-ens": { name: "ENS", url: "https:/\/ens.domains/" },
|
||||
"link-ethereum": { name: "Ethereum", url: "https:/\/ethereumorg" },
|
||||
@@ -190,17 +238,21 @@ module.exports = {
|
||||
"link-infura": { name: "INFURA", url: "https:/\/infura.io" },
|
||||
"link-javascriptcore": { name: "JavaScriptCore", url: "https:/\/developer.apple.com/documentation/javascriptcore?language=objc" },
|
||||
"link-ledger": "https:/\/www.ledger.com",
|
||||
"link-metamask": { name: "Metamask", url: "https:/\/metamask.io/" },
|
||||
"link-metamask": { name: "MetaMask", url: "https:/\/metamask.io/" },
|
||||
"link-otto": "https:/\/github.com/robertkrimen/otto",
|
||||
"link-parity": { name: "Parity", url: "https:/\/www.parity.io" },
|
||||
"link-pocket": { name: "Pocket Network", url: "https:/\/pokt.network" },
|
||||
"link-react-native": { name: "React Native", url: "https:/\/reactnative.dev" },
|
||||
"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/en/v0.6.2/" },
|
||||
"link-solidity": { name: "Solidity" , url: "https:/\/solidity.readthedocs.io/" },
|
||||
"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",
|
||||
"link-ankr-public": "https:/\/www.ankr.com/protocol/public/",
|
||||
"link-ankr-premium": "https:/\/www.ankr.com/protocol/plan/",
|
||||
"link-etherscan-signup": "https:/\/etherscan.io/apis",
|
||||
"link-etherscan-ratelimit": "https:/\/info.etherscan.com/api-return-errors/",
|
||||
"link-infura-signup": "https:/\/infura.io/register",
|
||||
@@ -239,19 +291,26 @@ 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",
|
||||
|
||||
"link-eip-155": { name: "EIP-155", url: "https:/\/eips.ethereum.org/EIPS/eip-155" },
|
||||
"link-eip-191": { name: "EIP-191", url: "https:/\/eips.ethereum.org/EIPS/eip-191" },
|
||||
"link-eip-609": { name: "EIP-609", url: "https:/\/eips.ethereum.org/EIPS/eip-609" },
|
||||
"link-eip-634": { name: "EIP-634", url: "https:/\/eips.ethereum.org/EIPS/eip-634" },
|
||||
"link-eip-712": { name: "EIP-712", url: "https:/\/eips.ethereum.org/EIPS/eip-712" },
|
||||
"link-eip-1014": { name: "EIP-1014", url: "https:/\/eips.ethereum.org/EIPS/eip-1014" },
|
||||
"link-eip-1193": { name: "EIP-1193", url: "https:/\/eips.ethereum.org/EIPS/eip-1193" },
|
||||
"link-eip-1559": { name: "EIP-1559", url: "https:/\/eips.ethereum.org/EIPS/eip-1559" },
|
||||
"link-eip-1577": { name: "EIP-1577", url: "https:/\/eips.ethereum.org/EIPS/eip-1577" },
|
||||
"link-eip-2098": { name: "EIP-2098", url: "https:/\/eips.ethereum.org/EIPS/eip-2098" },
|
||||
"link-eip-2304": { name: "EIP-2304", url: "https:/\/eips.ethereum.org/EIPS/eip-2304" },
|
||||
"link-eip-2718": { name: "EIP-2718", url: "https:/\/eips.ethereum.org/EIPS/eip-2718" },
|
||||
"link-eip-2930": { name: "EIP-2930", url: "https:/\/eips.ethereum.org/EIPS/eip-2930" },
|
||||
"link-bip-39": { name: "BIP-39", url: "https:/\/en.bitcoin.it/wiki/BIP_0039" },
|
||||
"link-bip-32": { name: "BIP-32", url: "https:/\/github.com/bitcoin/bips/blob/master/bip-0032.mediawiki" },
|
||||
"link-bip-44": { name: "BIP-44", url: "https:/\/en.bitcoin.it/wiki/BIP_0044" },
|
||||
|
||||
"link-npm-elliptic": { name: "elliptic", url: "https:/\/www.npmjs.com/package/elliptic" },
|
||||
"link-npm-ethersproject-shims": { name: "Shims", url: "https:/\/www.npmjs.com/package/@ethersproject/shims" },
|
||||
@@ -267,18 +326,25 @@ module.exports = {
|
||||
"link-js-proxy": "https:/\/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy",
|
||||
"link-js-typedarray": "https:/\/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray",
|
||||
|
||||
"link-cors": { name: "CORS", url: "https:/\/developer.mozilla.org/en-US/docs/Web/HTTP/CORS" },
|
||||
|
||||
"link-ricmoo-humanreadableabi": "https:/\/blog.ricmoo.com/human-readable-contract-abis-in-ethers-js-141902f4d917",
|
||||
|
||||
"link-other-ethereum-dev-docs": "https:/\/ethereum.org/en/developers/docs/",
|
||||
|
||||
"link-wiki-basicauth": { name: "Basic Authentication", url: "https:/\/en.wikipedia.org/wiki/Basic_access_authentication" },
|
||||
"link-wiki-backoff": { name: "Exponential Backoff", url: "https:/\/en.wikipedia.org/wiki/Exponential_backoff" },
|
||||
"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: "Observer 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",
|
||||
@@ -286,9 +352,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",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ Many things are the way they are for good (at the time, at least) reasons,
|
||||
but I always welcome criticism, and am completely willing to have my mind
|
||||
changed on things.
|
||||
|
||||
So, pull requests are always welcome, but please keep a few points in mind:
|
||||
Pull requests are always welcome, but please keep a few points in mind:
|
||||
|
||||
- Backwards-compatibility-breaking changes will not be accepted; they may be
|
||||
considered for the next major version
|
||||
@@ -15,6 +15,9 @@ So, pull requests are always welcome, but please keep a few points in mind:
|
||||
arguments as to why
|
||||
- The library aims to be lean, so keep an eye on the dist/ethers.min.js
|
||||
file size before and after your changes
|
||||
- Keep the PR simple and readable; only modify files in the ``docs.wrm/``
|
||||
and ``packages/*/src.ts/`` folders, as this allows the changes to be easily
|
||||
verified
|
||||
- Add test cases for both expected and unexpected input
|
||||
- Any new features need to be supported by me (future issues, documentation,
|
||||
testing, migration), so anything that is overly complicated or specific
|
||||
@@ -27,60 +30,135 @@ have a public discussion and figure out the best way to address the problem/feat
|
||||
|
||||
_subsection: Building @<contributing--building>
|
||||
|
||||
If you wish to modify the source code, there are a few steps involved in
|
||||
setting up your environment.
|
||||
The build process for ethers is unfortunatly not super trivial, but
|
||||
I have attempted to make it as straightforward as possible.
|
||||
|
||||
Since the library uses a monorepo, you must install an initial required
|
||||
set of libraries, which can then be used to install the remaining libraries
|
||||
used within each package, as well as link all the packages within the repo
|
||||
with each other.
|
||||
It is a mono-repo which attempts to be compatibile with a large
|
||||
number of environments, build tools and platforms, which is why
|
||||
there are a some weird things it must do.
|
||||
|
||||
_code: Preparing for builds @lang<shell>
|
||||
There are several custom scripts in the ``misc/admin`` folder
|
||||
to help manage the monorepo. Developers working on contributing
|
||||
to ethers should not generally need to worry about those, since
|
||||
they are wrapped up behind ``npm run SCRIPT`` operations.
|
||||
|
||||
_code: Installing @lang<shell>
|
||||
|
||||
# Clone the repository
|
||||
/home/ricmoo> git clone git@github.com:ethers-io/ethers.js.git
|
||||
/home/ricmoo> git clone https://github.com/ethers-io/ethers.js.git
|
||||
|
||||
/home/ricmoo> cd ethers.js
|
||||
|
||||
# Install the base dependencies
|
||||
# Install all dependencies:
|
||||
# - Hoists all sub-package dependencies in the package.json (preinstall)
|
||||
# - Installs all the (hoisted) dependencies and devDependencies (install)
|
||||
# - Build the rat-nests (in .package_node_modules) (postinstall)
|
||||
# - Create a dependency graph for the TypeScript (postinstall)
|
||||
# - Link the rat-nets into each project (postinstall)
|
||||
/home/ricmoo/ethers.js> npm install
|
||||
|
||||
# Install each module's dependencies and link the libraries
|
||||
# internally, so they reference each other
|
||||
/home/ricmoo/ethers.js> npm run bootstrap
|
||||
_heading: Making Changes @<contributing--updating>
|
||||
|
||||
|
||||
_subsection: Making your changes @<contributing--updating>
|
||||
|
||||
TODO: Add more information here.
|
||||
Once your environment is set up, you should be able to simply
|
||||
start the ``auto-build`` feature, and make changes to the
|
||||
TypeScript source.
|
||||
|
||||
_code: Watching and Building @lang<shell>
|
||||
|
||||
# Begin watching the files and re-building whenever they change
|
||||
/home/ricmoo/ethers.js> npm run auto-build
|
||||
|
||||
# Or if you do not want to watch and just build
|
||||
/home/ricmoo/ethers.js> npm run build
|
||||
|
||||
# Sometimes the issue only affects the ESM modules
|
||||
/home/ricmoo/ethers.js> npm run auto-build-esm
|
||||
_heading: Creating Browser-Ready Files
|
||||
|
||||
To create files for use directly in a browser, the distribution
|
||||
files (located in ``packages/ethers/dist``) need to be built
|
||||
which requires several intermediate builds, scripts and for
|
||||
various rollup scripts to execute.
|
||||
|
||||
# Or if you only need to run a single build
|
||||
/home/ricmoo/ethers.js> npm run _build-cjs
|
||||
/home/ricmoo/ethers.js> npm run _build-esm
|
||||
_code: Building Distribution Files @lang<shell>
|
||||
|
||||
# If you need to rebuild all the libs (esm + cjs) and dist files
|
||||
# Note: this requires node 10 or newer
|
||||
/home/ricmoo/ethers.js> npm run build-all
|
||||
|
||||
_heading: Testing
|
||||
|
||||
_code: Testing @lang<shell>
|
||||
|
||||
# Rebuilds all files and bundles testcases up for testing
|
||||
# Rebuilds all files (npm run build-all) and bundles testcases up for testing
|
||||
/home/ricmoo/ethers.js> npm test
|
||||
|
||||
# Often you don't need the full CI experience
|
||||
/home/ricmoo/ethers.js> npm run _test-node
|
||||
/home/ricmoo/ethers.js> npm run test-node
|
||||
|
||||
_heading: Distribution
|
||||
|
||||
Most developers should not ever require this step, but for people
|
||||
forking ethers and creating alternates (for example if you have
|
||||
a non-EVM compatible chain but are trying to reuse this package).
|
||||
|
||||
This script will rebuild the entire ethers project, compare it
|
||||
against npm, re-write package versions, update internal hashes,
|
||||
re-write various TypeScript files (to get around some ES+TS
|
||||
limitations for Tree Shaking and linking), re-write map files,
|
||||
bundle stripped versions of dependencies and basically just a
|
||||
whole bunch of stuff.
|
||||
|
||||
If you use this and get stuck, [message me](link-mail).
|
||||
|
||||
_code: Preparing the Distribution @lang<shell>
|
||||
|
||||
# Prepare all the distribution files
|
||||
# - Remove all generated files (i.e. npm run clean)
|
||||
# - Re-install all dependencies, hoisting, etc. (npm install)
|
||||
# - Spell check all strings in every TypeScript files
|
||||
# - Build everything from scratch with this clean install
|
||||
# - Compare local with npm, bumping the version if changed
|
||||
# - Build everything again (with the updated versions)
|
||||
# - Update the CHANGELOG.md with the git history since the last change
|
||||
/home/ricmoo/ethers.js> npm run update-version
|
||||
|
||||
_note: Do NOT check in dist files in a PR
|
||||
|
||||
For Pull Requests, please ONLY commit files in the ``docs.wrm/`` and
|
||||
``packages/*/src.ts/`` folders. I will prepare the distribution builds
|
||||
myself and keeping the PR relevant makes it easier to verify the changes.
|
||||
|
||||
_heading: Publishing
|
||||
|
||||
Again, this should not be necessary for most developers. This step
|
||||
requires using the ``misc/admin/cmds/config-set`` script for a number
|
||||
of values, including private keys, NPM session keys, AWS access keys,
|
||||
GitHub API tokens, etc.
|
||||
|
||||
The config file is encrypted with about 30 seconds of scrypt password-based
|
||||
key derivation function, so brute-forcing the file is quite expensive.
|
||||
|
||||
The config file also contains a plain-text mnemonic. This is a money-pot.
|
||||
Place a tempting amount of ether or Bitcoin on this account and set up an
|
||||
e-mail alert for this account.
|
||||
|
||||
If any attacker happens across your encrypted config, they will have instant
|
||||
access to the plain-text mnemonic, so they have the option to immediately
|
||||
steal the ether (i.e. the responsible-disclosure bond).
|
||||
|
||||
If you ever see this ether taken, your encrypted file is compromised! Rotate
|
||||
all your AWS keys, NPM session keys, etc. immedately.
|
||||
|
||||
@TODO: document all the keys that need to be set for each step
|
||||
|
||||
_code: Preparing the Distribution @lang<shell>
|
||||
|
||||
# Publish
|
||||
# - Update any changed packages to NPM
|
||||
# - Create a release on GitHub with the latest CHANGELOG.md description
|
||||
# - Upload the bundled files the the CDN
|
||||
# - Flush the CDN edge caches
|
||||
/home/ricmoo/ethers.js> npm run publish-all
|
||||
|
||||
|
||||
_subsection: Documentation @<contributing--documentation>
|
||||
|
||||
@@ -95,7 +173,7 @@ Style Guide (this section will have much more coming):
|
||||
- Prefix external links with ``link-``
|
||||
- Changing an anchor name must be well justified, as it will break all existing links
|
||||
to that section; flatworm will support symlinks in the future
|
||||
- In general, I aim for xonsistency; look to similar situations throughout the documentation
|
||||
- In general, I aim for consistency; look to similar situations throughout the documentation
|
||||
|
||||
|
||||
_heading: Building
|
||||
|
||||
@@ -6,4 +6,5 @@ snippets of code that are in general useful.
|
||||
_toc:
|
||||
|
||||
react-native
|
||||
transactions
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ _subsection: Installing @<cookbook-reactnative-shims>
|
||||
To use ethers in React Native, you must either provide shims for the needed
|
||||
missing functionality, or use the ethers.js shim.
|
||||
|
||||
It is **HIGHLY RECOMMENDED** you check out the [security section](cookbook-reactnative-security>
|
||||
It is **HIGHLY RECOMMENDED** you check out the [security section](cookbook-reactnative-security)
|
||||
below for instructions on installing packages which can affect the security
|
||||
of your application.
|
||||
|
||||
|
||||
24
docs.wrm/cookbook/transactions.wrm
Normal file
24
docs.wrm/cookbook/transactions.wrm
Normal file
@@ -0,0 +1,24 @@
|
||||
_section: Transactions @<cookbook--transactions>
|
||||
|
||||
_subsection: Compute the raw transaction @<cookbook--compute-raw-transaction>
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
function getRawTransaction(tx) {
|
||||
function addKey(accum, key) {
|
||||
if (tx[key]) { accum[key] = tx[key]; }
|
||||
return accum;
|
||||
}
|
||||
|
||||
// Extract the relevant parts of the transaction and signature
|
||||
const txFields = "accessList chainId data gasPrice gasLimit maxFeePerGas maxPriorityFeePerGas nonce to type value".split(" ");
|
||||
const sigFields = "v r s".split(" ");
|
||||
|
||||
// Seriailze the signed transaction
|
||||
const raw = utils.serializeTransaction(txFields.reduce(addKey, { }), sigFields.reduce(addKey, { }));
|
||||
|
||||
// Double check things went well
|
||||
if (utils.keccak256(raw) !== tx.hash) { throw new Error("serializing failed!"); }
|
||||
|
||||
return raw;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
BIN
docs.wrm/favicon.ico
Normal file
BIN
docs.wrm/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -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>
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ $Contract: A Contract is an abstraction which represents a connection to a
|
||||
| **Contract** | $Contract |
|
||||
|
||||
|
||||
_subsection: Connecting to Ethereum: Metamask @<getting-started--connecting>
|
||||
_subsection: Connecting to Ethereum: MetaMask @<getting-started--connecting>
|
||||
|
||||
The quickest and easiest way to experiment and begin developing on
|
||||
Ethereum is to use [[link-metamask]], which is a browser extension
|
||||
@@ -82,13 +82,16 @@ that provides:
|
||||
- A connection to the Ethereum network (a [[Provider]])
|
||||
- Holds your private key and can sign things (a [[Signer]])
|
||||
|
||||
_code: Connecting to Metamask @lang<script>
|
||||
_code: Connecting to MetaMask @lang<script>
|
||||
|
||||
// A Web3Provider wraps a standard Web3 provider, which is
|
||||
// what Metamask injects as window.ethereum into each page
|
||||
// what MetaMask injects as window.ethereum into each page
|
||||
const provider = new ethers.providers.Web3Provider(window.ethereum)
|
||||
|
||||
// The Metamask plugin also allows signing transactions to
|
||||
// MetaMask requires requesting permission to connect users accounts
|
||||
await provider.send("eth_requestAccounts", []);
|
||||
|
||||
// The MetaMask plugin also allows signing transactions to
|
||||
// send ether and pay to change state within the blockchain.
|
||||
// For this, you need the account signer...
|
||||
const signer = provider.getSigner()
|
||||
@@ -101,7 +104,7 @@ with Ethereum and is available in all major Ethereum node implementations
|
||||
third-party web services (e.g. [[link-infura]]). It typically provides:
|
||||
|
||||
- A connection to the Ethereum network (a [[Provider]])
|
||||
- Holds your private key and can sign thing (a [[Signer]])
|
||||
- Holds your private key and can sign things (a [[Signer]])
|
||||
|
||||
_code: Connecting to an RPC client @lang<script>
|
||||
|
||||
@@ -123,22 +126,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>
|
||||
@@ -165,7 +172,7 @@ If you are familiar with Databases, this is similar to an //Object Relational Ma
|
||||
|
||||
In order to communicate with the Contract on-chain, this class
|
||||
needs to know what methods are available and how to encode and
|
||||
decode the data, which is what the //Application Binary Interface// (API)
|
||||
decode the data, which is what the //Application Binary Interface// (ABI)
|
||||
provides.
|
||||
|
||||
This class is a //meta-class//, which means its methods are constructed
|
||||
@@ -204,38 +211,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 +260,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 +274,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 +282,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
|
||||
|
||||
// Filter for all token transfers to me
|
||||
filterFrom = daiContract.filters.Transfer(myAddress, null);
|
||||
// <hide>
|
||||
filterFrom
|
||||
// </hide>
|
||||
//!
|
||||
//_log: myAddress
|
||||
|
||||
// Filter for all token transfers from me
|
||||
filterTo = daiContract.filters.Transfer(null, myAddress);
|
||||
// <hide>
|
||||
filterTo
|
||||
// </hide>
|
||||
//!
|
||||
filterFrom = daiContract.filters.Transfer(myAddress, null);
|
||||
//_log: filterFrom
|
||||
|
||||
// List all transfers sent from me a specific block range
|
||||
daiContract.queryFilter(filterFrom, 9843470, 9843480)
|
||||
//!
|
||||
// Filter for all token transfers to me
|
||||
filterTo = daiContract.filters.Transfer(null, myAddress);
|
||||
//_log: filterTo
|
||||
|
||||
// List all transfers sent from me in a specific block range
|
||||
//_result:
|
||||
await daiContract.queryFilter(filterFrom, 9843470, 9843480)
|
||||
//_log:
|
||||
|
||||
//
|
||||
// The following have had the results omitted due to the
|
||||
@@ -335,26 +315,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 +343,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
|
||||
|
||||
@@ -45,6 +45,7 @@ _toc:
|
||||
migration
|
||||
testing
|
||||
contributing
|
||||
other-resources
|
||||
documentation
|
||||
license
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -69,7 +69,7 @@ signature = await signer.signMessage('Some data')
|
||||
|
||||
_subsection: Contracts
|
||||
|
||||
A contract object is an abstraction of a smart contract on the Ethereum Network. It allows for easy interaction with the smart contact.
|
||||
A contract object is an abstraction of a smart contract on the Ethereum Network. It allows for easy interaction with the smart contract.
|
||||
|
||||
_heading: Deploying a Contract
|
||||
|
||||
|
||||
17
docs.wrm/other-resources.wrm
Normal file
17
docs.wrm/other-resources.wrm
Normal file
@@ -0,0 +1,17 @@
|
||||
_section: Other Resources
|
||||
|
||||
There is a lot of documentation on the internet to help you get started,
|
||||
learn more or cover advanced topics. Here are a few resources to check out.
|
||||
|
||||
_subsection: Ethereum Overview
|
||||
|
||||
- Official [Ethereum Developer Documentations](link-other-ethereum-dev-docs)
|
||||
- The [Solidity Documentation](link-solidity), the defactor language for smart
|
||||
contracts as well as a resource for some of the core concepts of Ethereum
|
||||
|
||||
_subsection: Tutorials
|
||||
|
||||
I do not manage or maintain these tutorials, but have happened across them.
|
||||
If a link is dead or outdated, please [let me know](link-mail) and I'll update it.
|
||||
|
||||
- [Alchemy - How to Mint an NFT](https://docs.alchemy.com/alchemy/tutorials/how-to-create-an-nft/how-to-mint-an-nft-with-ethers)
|
||||
BIN
docs.wrm/social.jpg
Normal file
BIN
docs.wrm/social.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
@@ -151,7 +151,7 @@ This section is still a work in progress, but will outline some of the more nuan
|
||||
aspects of the test cases and their values.
|
||||
|
||||
There will likely be an overhaul of the test cases in the next major version, to
|
||||
make code coverage testing more straight forward and to collapse some of the redundancy.
|
||||
make code coverage testing more straightforward and to collapse some of the redundancy.
|
||||
|
||||
For example, there is no longer a need to separate the ABI and ABIv2 test case and the
|
||||
accounts and transactions suites can be merged into one large collection.
|
||||
|
||||
15
docs.wrm/troubleshooting/building.wrm
Normal file
15
docs.wrm/troubleshooting/building.wrm
Normal file
@@ -0,0 +1,15 @@
|
||||
_section: Building @<troubleshooting-building>
|
||||
|
||||
@TODO
|
||||
|
||||
_subsection: Packages
|
||||
|
||||
Sometimes packages get out of sync.
|
||||
|
||||
_code:
|
||||
|
||||
/home/ethers> rm package-lock.json node_modules/
|
||||
|
||||
/home/ethers> rm yarn.lock
|
||||
|
||||
/home/ethers> npm install
|
||||
249
docs.wrm/troubleshooting/errors.wrm
Normal file
249
docs.wrm/troubleshooting/errors.wrm
Normal file
@@ -0,0 +1,249 @@
|
||||
_section: Error Codes @<error-codes>
|
||||
|
||||
All errors in ethers are created by the [[Logger]] class, which includes
|
||||
a number of additional properties and extra data, which can assist in
|
||||
debugging and when submitting issues.
|
||||
|
||||
When submitting an issue, please include as much of any error as possible,
|
||||
but also make sure you understand the error and have tried suggested solutions
|
||||
both in this trouble-shooting document and any other issues you find when
|
||||
searching the GitHub issues.
|
||||
|
||||
|
||||
_subsection: CALL_EXCEPTION @<help-CALL_EXCEPTION>
|
||||
|
||||
This error occurs when a call or transaction is used to interact with
|
||||
the blockchain reverts (via ``revert``, ``require``, et cetera).
|
||||
|
||||
Due to the overall flexibility of Ethereum and Turing Completeness,
|
||||
there is a large variety of reasons this can occur and troubleshooting
|
||||
requires attention.
|
||||
|
||||
|
||||
_heading: Common Causes
|
||||
|
||||
- The code does not exist on-chain. This may happen if you failed to wait
|
||||
until the contract was deployed, the address is incorrect or if you
|
||||
are connected to a different network than the contract has been deployed.
|
||||
Check the code exists using ``provider.getCode(address)``.
|
||||
- The wrong code is being accessed, for example if an artifact file was
|
||||
not correctly updated so an older instance of the contract is being called
|
||||
- The contract is failing during a ``require`` statement. For example, if
|
||||
a contract method requires an //admin account// to be used, but the
|
||||
contract is connected to another [[Signer]].
|
||||
- The wrong ABI is being used to interact with a contract.
|
||||
|
||||
_heading: Debugging
|
||||
|
||||
- Always double check the address and network you are connected to and use
|
||||
``provider.getCode(address)`` to verify the deployed code matches your
|
||||
most recent version.
|
||||
- Try accessing other, simpler contract methods to verify the account is correct.
|
||||
|
||||
|
||||
_subsection: INSUFFICIENT_FUNDS @<help-INSUFFICIENT_FUNDS>
|
||||
|
||||
This usually occurs when a transaction is attempted, but the sending account
|
||||
does not have enough ether to cover the cost of the transaction.
|
||||
|
||||
A transaction has an intrinsic cost which must be met, which accounts for
|
||||
the value being sent, the base fee of the transaction, additional fees per byte
|
||||
of calldata and whether the transaction will create a new account (i.e. the ``to``
|
||||
is empty).
|
||||
|
||||
This error can also happen if ``provider.estimateGas`` is used with a non-zero
|
||||
fee (i.e. ``gasPrice``, ``maxFeePerGas`` or ``maxPriorityFeePerGas``). If any
|
||||
fee properties are specified, the ``from`` account must have sufficient ether
|
||||
to execute the transaction.
|
||||
|
||||
|
||||
_subsection: MISSING_NEW @<help-MISSING_NEW>
|
||||
|
||||
Classes in ethers must be instantiated with the ``new`` operator. This
|
||||
error indicates that a Class is attempting to be used as a function.
|
||||
|
||||
_code: Examples @lang<javascript>
|
||||
|
||||
//_hide: privateKey = "0x0123456789012345678901234567890123456789012345678901234567890123";
|
||||
//_hide: Wallet = ethers.Wallet;
|
||||
|
||||
// Bad:
|
||||
//_throws:
|
||||
ethers.Wallet(privateKey)
|
||||
//_log:
|
||||
|
||||
// Good:
|
||||
//_result:
|
||||
new ethers.Wallet(privateKey)
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: NONCE_EXPIRED @<help-NONCE_EXPIRED>
|
||||
|
||||
This error occurs when a transaction is being sent with a ``nonce`` that
|
||||
is lower than next required ``nonce``.
|
||||
|
||||
Each Ethereum transaction requires a ``nonce`` property equal to the index
|
||||
of that transaction for that account for all time. So, if an account has
|
||||
send four transactions over its lifetime, that means the nonces 0 though 3
|
||||
(inclusive) have been used. The next transaction must use a nonce of 4.
|
||||
Attempting to re-use a nonce less than 4 will result in this error.
|
||||
|
||||
|
||||
_subsection: NUMERIC_FAULT @<help-NUMERIC_FAULT>
|
||||
|
||||
A [numeric fault](errors--numeric-fault) is a consequence of
|
||||
performing an illegal operation with numeric values, such as
|
||||
dividing by zero.
|
||||
|
||||
The error will indicate the ``operation``, which further indicates
|
||||
the reason for the error.
|
||||
|
||||
|
||||
_heading: Overflow @<help-NUMERIC_FAULT-overflow>
|
||||
|
||||
JavaScript uses [IEEE 754 double-precision binary floating point](link-wiki-ieee754)
|
||||
numbers to represent numeric values. As a result, there are //holes//
|
||||
in the integer set after 9,007,199,254,740,991; which is
|
||||
problematic for //Ethereum// because that is only around 0.009
|
||||
ether (in wei), which means any value over that will begin to
|
||||
experience rounding errors.
|
||||
|
||||
As a result, any attempt to use a number which is outside the safe
|
||||
range, which would result in incorrect values, an error is thrown.
|
||||
|
||||
In general, numbers should be kept as strings, [[BigNumber]] instances or
|
||||
using ES2020 bigints, which all can safely be used without loss of precission.
|
||||
|
||||
_code: Examples @lang<javascript>
|
||||
|
||||
// One ether is outside the safe range
|
||||
//_throws:
|
||||
BigNumber.from(1000000000000000000)
|
||||
//_log:
|
||||
|
||||
// Providing the value as a string is safe
|
||||
//_result:
|
||||
BigNumber.from("1000000000000000000")
|
||||
//_log:
|
||||
|
||||
// As is using a bigint (notice the `n` suffix)
|
||||
//_result:
|
||||
BigNumber.from(1000000000000000000n)
|
||||
//_log:
|
||||
|
||||
// But most often, the `parseEther` function solves this
|
||||
//_result:
|
||||
utils.parseEther("1.0")
|
||||
//_log:
|
||||
|
||||
|
||||
_heading: Numeric Underflow @<help-NUMERIC_FAULT-underflow>
|
||||
|
||||
Numeric underflow sbould not be confused with overflow.
|
||||
|
||||
Numeric underflow occurs when the precission of a value cannot be
|
||||
safely represented in the current data type.
|
||||
|
||||
**Common Causes**
|
||||
|
||||
- Using values with fractional componets (e.g. ``BigNumber.from(1.2)``).
|
||||
If you require fractions, you must use the [[FixedNumber]] class.
|
||||
- Parsing string values that have more decimals than the unit supports
|
||||
(e.g. ``parseUints("1.33", 1)``).
|
||||
|
||||
_code: Examples @lang<javascript>
|
||||
|
||||
// BigNumbers cannot be created with a fractional component
|
||||
//_throws:
|
||||
BigNumber.from(1.2)
|
||||
//_log:
|
||||
|
||||
// Parsing a value with more decimals than the type
|
||||
//_throws:
|
||||
utils.parseUnits("1.34", 1);
|
||||
//_log:
|
||||
|
||||
|
||||
_heading: Division by zero @<help-NUMERIC_FAULT-division-by-zero>
|
||||
|
||||
This error occurs when dividing by zero or attempting to take the modulo zero.
|
||||
|
||||
|
||||
_heading: Unbound Result @<help-NUMERIC_FAULT-unbound-result>
|
||||
|
||||
The ethers [[BigNumber]] does not support bitwise operators
|
||||
on negative numbers which can result in the need for an infinite
|
||||
number of set bits.
|
||||
|
||||
Other implementations may use negative values to indicate this,
|
||||
but this is considered out of scope for ethers.
|
||||
|
||||
|
||||
_heading: Unsupported Operation @<help-NUMERIC_FAULT-unsupported>
|
||||
|
||||
The ethers [[BigNumber]] does not support negative powers or bitwise
|
||||
shift operation using negative values.
|
||||
|
||||
_code: Examples @lang<javascript>
|
||||
|
||||
two = BigNumber.from(2);
|
||||
|
||||
//_throws:
|
||||
two.pow(-2)
|
||||
//_log:
|
||||
|
||||
// Cannot use negative values to alter shift direction
|
||||
//_throws:
|
||||
two.shr(-1)
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: REPLACEMENT_UNDERPRICED @<help-REPLACEMENT_UNDERPRICED>
|
||||
|
||||
To prevent nodes from being overloaded with junk transactions, a transaction
|
||||
is only accepted into the memory pool if it has a reasonable chance of being
|
||||
actually mined, which means that the account has sufficient balance, the nonce
|
||||
is correct and the fee seems reasonable.
|
||||
|
||||
Once a transaction is in the memory pool though, to prevent an account from
|
||||
flooding the network with many different transactions with the same nonce (each
|
||||
of which satisfies the above criteria), to replace an existing transaction
|
||||
an additional committment of a fee must be made by increasing the promised fee.
|
||||
|
||||
When replacing a legacy non-EIP1559 transaction, the ``gasPrice`` must be
|
||||
increased. When replacing a modern, EIP-1559 transaction, the ``maxPriorityFeePerGas``
|
||||
should be increased.
|
||||
|
||||
|
||||
_subsection: TRANSACTION_REPLACED @<help-TRANSACTION_REPLACED>
|
||||
|
||||
This error is thrown when waiting for a transaction which has been
|
||||
replaced by another, by the sender submitting a second transaction
|
||||
with the same nonce, while the transaction was pending in the
|
||||
transaction pool.
|
||||
|
||||
You can learn more about this feature in the ``.wait`` method of
|
||||
[TransactionResponse](providers-TransactionResponse).
|
||||
|
||||
|
||||
_subsection: UNPREDICTABLE_GAS_LIMIT @<help-UNPREDICTABLE_GAS_LIMIT>
|
||||
|
||||
During gas estimation it is possible that a transaction would actually
|
||||
fail (and hence has no reasonable estimate of gas requirements) or that
|
||||
the transaction is complex in a way that does not permit a node to
|
||||
estiamte the gas requirements, in which case this error is thrown.
|
||||
|
||||
In almost all cases, this will unfortunately require you specify an
|
||||
explicit ``gasLimit`` for your transaction, which will disable ether's
|
||||
automatic population of the ``gasLimit`` field, which will cause this
|
||||
error to go away.
|
||||
|
||||
To dial in an appropriate gas limit, try a value that is much higher
|
||||
than you expect, and then make a few transactions to discover reasonable
|
||||
values and then you can reduce this value down to that ballpark.
|
||||
|
||||
Keep in mind this error can also occur if the transaction would
|
||||
legitimately fail, in which case the root cause must be addressed, such
|
||||
as ensuring the correct [[Signer]] is being used, the appropriate allowance
|
||||
for an ERC-20 token has been approved, etc.
|
||||
62
docs.wrm/troubleshooting/help.wrm
Normal file
62
docs.wrm/troubleshooting/help.wrm
Normal file
@@ -0,0 +1,62 @@
|
||||
_section: Getting Help @<troubleshooting-issues>
|
||||
|
||||
@TODO
|
||||
|
||||
_subsection: Starting a discussion
|
||||
|
||||
Before opening an issue
|
||||
|
||||
|
||||
_subsection: Opening an Issue
|
||||
|
||||
Keep in mind that opening an issue should be a last resort, as it
|
||||
requires time and energy by the library developers to look at that
|
||||
could otherwise be spent on improving the library, documentation
|
||||
and tools.
|
||||
|
||||
Before opening an issue, please make sure you have searched any
|
||||
public information, such as:
|
||||
|
||||
- Documentation
|
||||
- GitHub Discussions
|
||||
- GitHub Issues (including closed issues)
|
||||
|
||||
There are several types of issues tracked by ethers. Using the correct
|
||||
one helps you receive feedback quicker and helps us keep the right
|
||||
person
|
||||
|
||||
_heading: Feature Requests
|
||||
|
||||
|
||||
|
||||
_heading: Bugs
|
||||
|
||||
This type of issue is for anything you you believe to be a bug in ethers.
|
||||
|
||||
Keep in mind that ethers is used extensively by thousands of people every
|
||||
day, so while chances are possible you found a bug, please make sure to
|
||||
do your due diligence to rule out user error.
|
||||
|
||||
If you are new to ethers, or are doing a fairly common operation, it is
|
||||
quite likely what you are experiencing is a misunderstanding of how to
|
||||
use a function, method or class. You should consider opening a discussion first.
|
||||
|
||||
|
||||
Please make sure you include as much information as is useful:
|
||||
|
||||
- Are you using a third-party library, like Hardhat or Truffle?
|
||||
- What platform are you on, a web browser, React Native, node, etc.?
|
||||
- What network are you on, such as Ethereum mainnet, Optimism, etc.?
|
||||
- What backend are you using, such as Geth, INFURA, Provider Engine, etc.?
|
||||
|
||||
|
||||
_heading: Docuementation
|
||||
|
||||
If you have found a typo in the documentation, a feature which isn't
|
||||
documented (or documented well) or just find something described in
|
||||
the documentation confusing, please feel free to create an issue and
|
||||
we will try to improve it.
|
||||
|
||||
_heading: Other
|
||||
|
||||
This should never be used.
|
||||
11
docs.wrm/troubleshooting/index.wrm
Normal file
11
docs.wrm/troubleshooting/index.wrm
Normal file
@@ -0,0 +1,11 @@
|
||||
_section: TroubleShooting
|
||||
|
||||
|
||||
|
||||
_toc:
|
||||
building
|
||||
errors
|
||||
network
|
||||
help
|
||||
|
||||
_subsection: About Trbouble-Shooting
|
||||
9
docs.wrm/troubleshooting/network.wrm
Normal file
9
docs.wrm/troubleshooting/network.wrm
Normal file
@@ -0,0 +1,9 @@
|
||||
_section: Troubleshooting Network @<troubleshooting-network>
|
||||
|
||||
@TODO
|
||||
|
||||
_subsection: Links
|
||||
|
||||
_subsection: Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
_subsection: Mobile Development (Device Firewalls)
|
||||
1
docs/api-keys/redirects.txt
Normal file
1
docs/api-keys/redirects.txt
Normal file
@@ -0,0 +1 @@
|
||||
index.html => /v5/api-keys
|
||||
9
docs/errors/redirects.txt
Normal file
9
docs/errors/redirects.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
server-error => /v5/api/utils/logger/#errors--server-error
|
||||
unsupported-operation => /v5/api/utils/logger/#errors--unsupported-operation
|
||||
numeric-fault => /v5/api/utils/logger/#errors--numeric-fault
|
||||
call-exception => /v5/api/utils/logger/#errors--numeric-fault
|
||||
insufficient-funds => /v5/api/utils/logger/#errors--insufficient-funds
|
||||
nonce-expired => /v5/api/utils/logger/#errors--nonce-expired
|
||||
replacement-underpriced => /v5/api/utils/logger/#errors--replacement-underpriced
|
||||
unpredicatable-gas-limit => /v5/api/utils/logger/#errors--unpredicatable-gas-limit
|
||||
|
||||
BIN
docs/favicon.ico
Normal file
BIN
docs/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -26,8 +26,8 @@ Developer Documentation
|
||||
* [Signing Messages](getting-started)
|
||||
* [Ethereum Basics](concepts)
|
||||
* [Events](concepts/events)
|
||||
* [Solidity Topics](concepts/events)
|
||||
* [Logs and Filtering](concepts/events)
|
||||
* [Solidity Topics](concepts/events)
|
||||
* [Gas](concepts/gas)
|
||||
* [Gas Price](concepts/gas)
|
||||
* [Gas Limit](concepts/gas)
|
||||
@@ -47,6 +47,7 @@ Developer Documentation
|
||||
* [Accounts Methods](api/providers/provider)
|
||||
* [Blocks Methods](api/providers/provider)
|
||||
* [Ethereum Naming Service (ENS) Methods](api/providers/provider)
|
||||
* [EnsResolver](api/providers/provider)
|
||||
* [Logs Methods](api/providers/provider)
|
||||
* [Network Status Methods](api/providers/provider)
|
||||
* [Transactions Methods](api/providers/provider)
|
||||
@@ -253,8 +254,10 @@ Developer Documentation
|
||||
* [Schemas](testing)
|
||||
* [Contributing and Hacking](contributing)
|
||||
* [Building](contributing)
|
||||
* [Making your changes](contributing)
|
||||
* [Documentation](contributing)
|
||||
* [Other Resources](other-resources)
|
||||
* [Ethereum Overview](other-resources)
|
||||
* [Tutorials](other-resources)
|
||||
* [Flatworm Docs](documentation)
|
||||
* [Fragments](documentation)
|
||||
* [Markdown](documentation)
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -12,6 +12,7 @@ Application Programming Interface
|
||||
* [Accounts Methods](providers/provider)
|
||||
* [Blocks Methods](providers/provider)
|
||||
* [Ethereum Naming Service (ENS) Methods](providers/provider)
|
||||
* [EnsResolver](providers/provider)
|
||||
* [Logs Methods](providers/provider)
|
||||
* [Network Status Methods](providers/provider)
|
||||
* [Transactions Methods](providers/provider)
|
||||
|
||||
@@ -12,14 +12,17 @@ Creating Instances
|
||||
|
||||
#### **new ***ethers* . **ContractFactory**( interface , bytecode [ , signer ] )
|
||||
|
||||
Creates a new instance of a **ContractFactory** for the contract described by the *interface* and *bytecode* initcode.
|
||||
|
||||
|
||||
#### *ContractFactory* . **fromSolidity**( compilerOutput [ , signer ] ) => *[ContractFactory](/v5/api/contract/contract-factory/)*
|
||||
|
||||
Consumes the output of the Solidity compiler, extracting the ABI and bytecode from it, allowing for the various formats the solc compiler has emitted over its life.
|
||||
|
||||
|
||||
#### *contractFactory* . **connect**( signer ) => *[Contract](/v5/api/contract/contract/)*
|
||||
|
||||
Returns a **new instance** of the ContractFactory with the same *interface* and *bytecode*, but with a different *signer*.
|
||||
|
||||
|
||||
Properties
|
||||
@@ -27,14 +30,17 @@ Properties
|
||||
|
||||
#### *contractFactory* . **interface** => *[Interface](/v5/api/utils/abi/interface/)*
|
||||
|
||||
The [Contract](/v5/api/contract/contract/) interface.
|
||||
|
||||
|
||||
#### *contractFactory* . **bytecode** => *string< [DataHexString](/v5/api/utils/bytes/#DataHexString) >*
|
||||
|
||||
The bytecode (i.e. initcode) that this **ContractFactory** will use to deploy the Contract.
|
||||
|
||||
|
||||
#### *contractFactory* . **signer** => *[Signer](/v5/api/signer/#Signer)*
|
||||
|
||||
The [Signer](/v5/api/signer/#Signer) (if any) this ContractFactory will use to deploy instances of the Contract to the Blockchain.
|
||||
|
||||
|
||||
Methods
|
||||
@@ -45,49 +51,87 @@ Methods
|
||||
Return an instance of a [Contract](/v5/api/contract/contract/) attached to *address*. This is the same as using the [Contract constructor](/v5/api/contract/contract/#Contract--creating) with *address* and this the *interface* and *signerOrProvider* passed in when creating the ContractFactory.
|
||||
|
||||
|
||||
#### *contractFactory* . **getDeployTransaction**( ...args ) => *[UnsignedTransaction](/v5/api/utils/transactions/#UnsignedTransaction)*
|
||||
#### *contractFactory* . **getDeployTransaction**( ...args [ , overrides ] ) => *[UnsignedTransaction](/v5/api/utils/transactions/#UnsignedTransaction)*
|
||||
|
||||
Returns the unsigned transaction which would deploy this Contract with *args* passed to the Contract's constructor.
|
||||
|
||||
If the optional *overrides* is specified, they can be used to override the endowment `value`, transaction `nonce`, `gasLimit` or `gasPrice`.
|
||||
|
||||
#### *contractFactory* . **deploy**( ...args ) => *Promise< [Contract](/v5/api/contract/contract/) >*
|
||||
|
||||
#### *contractFactory* . **deploy**( ...args [ , overrides ] ) => *Promise< [Contract](/v5/api/contract/contract/) >*
|
||||
|
||||
Uses the signer to deploy the Contract with *args* passed into the constructor and returns a Contract which is attached to the address where this contract **will** be deployed once the transaction is mined.
|
||||
|
||||
The transaction can be found at `contract.deployTransaction`, and no interactions should be made until the transaction is mined.
|
||||
|
||||
If the optional *overrides* is specified, they can be used to override the endowment `value`, transaction `nonce`, `gasLimit` or `gasPrice`.
|
||||
|
||||
```
|
||||
// <hide>
|
||||
const signer = ethers.LocalSigner();
|
||||
const ContractFactory = ethers.ContractFactory;
|
||||
// </hide>
|
||||
|
||||
```javascript
|
||||
// If your contract constructor requires parameters, the ABI
|
||||
// must include the constructor
|
||||
const abi = [
|
||||
"constructor(address owner, uint256 initialValue)"
|
||||
"constructor(address owner, uint256 initialValue)",
|
||||
"function value() view returns (uint)"
|
||||
];
|
||||
|
||||
const factory = new ContractFactory(abi, bytecode, signer)
|
||||
// The factory we use for deploying contracts
|
||||
factory = new ContractFactory(abi, bytecode, signer)
|
||||
|
||||
const contract = await factory.deploy("ricmoo.eth", 42);
|
||||
// Deploy an instance of the contract
|
||||
contract = await factory.deploy("ricmoo.eth", 42);
|
||||
|
||||
// The address is available immediately, but the contract
|
||||
// is NOT deployed yet
|
||||
contract.address
|
||||
//!
|
||||
// '0x26E9685C018Bf3A401DFA632827e7e6C7D96b1C0'
|
||||
|
||||
// The transaction that the signer sent to deploy
|
||||
contract.deployTransaction
|
||||
//!
|
||||
// {
|
||||
// blockHash: null,
|
||||
// blockNumber: null,
|
||||
// chainId: 1337,
|
||||
// confirmations: 0,
|
||||
// creates: '0x26E9685C018Bf3A401DFA632827e7e6C7D96b1C0',
|
||||
// data: '0x608060405234801561001057600080fd5b5060405161012e38038061012e8339818101604052604081101561003357600080fd5b81019080805190602001909291908051906020019092919050505081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060008190555050506088806100a66000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80633fa4f24514602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000805490509056fea2646970667358221220926465385af0e8706644e1ff3db7161af699dc063beaadd55405f2ccd6478d7564736f6c63430007040033000000000000000000000000ab7c8803962c0f2f5bbbe3fa8bf41cd82aa1923c000000000000000000000000000000000000000000000000000000000000002a',
|
||||
// from: '0xf3e6942b256A60B596B24F633caE8aDB4983fCA6',
|
||||
// gasLimit: { BigNumber: "126462" },
|
||||
// gasPrice: { BigNumber: "1" },
|
||||
// hash: '0x4037630fdadbbe0aac0bf90eba61118e35ee5fc28329e2134bb2bad0bfc12684',
|
||||
// nonce: 1,
|
||||
// r: '0xc3bb79ea4600864cd110fe74d31d38bb3702c327fd5aef9feddf66903cc87a4f',
|
||||
// s: '0x35cc2ffe352c02b5fcfbbcd2e348001af670f64438d7a9b2c34756ec293a0784',
|
||||
// to: null,
|
||||
// transactionIndex: null,
|
||||
// v: 2709,
|
||||
// value: { BigNumber: "0" },
|
||||
// wait: [Function]
|
||||
// }
|
||||
|
||||
// Wait until the transaction is mined
|
||||
// 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()
|
||||
//!
|
||||
// { Promise: {
|
||||
// blockHash: '0x1715de2bdfec15a7f64fb79a8254699274be6776df244d24a04945a3218543e6',
|
||||
// blockNumber: 2,
|
||||
// byzantium: true,
|
||||
// confirmations: 1,
|
||||
// contractAddress: '0x26E9685C018Bf3A401DFA632827e7e6C7D96b1C0',
|
||||
// cumulativeGasUsed: { BigNumber: "126462" },
|
||||
// from: '0xf3e6942b256A60B596B24F633caE8aDB4983fCA6',
|
||||
// gasUsed: { BigNumber: "126462" },
|
||||
// logs: [],
|
||||
// logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
|
||||
// status: 1,
|
||||
// to: null,
|
||||
// transactionHash: '0x4037630fdadbbe0aac0bf90eba61118e35ee5fc28329e2134bb2bad0bfc12684',
|
||||
// transactionIndex: 0
|
||||
// } }
|
||||
|
||||
// Now the contract is safe to interact with
|
||||
contract.value()
|
||||
//!
|
||||
// { Promise: { BigNumber: "42" } }
|
||||
```
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -117,7 +117,7 @@ Meta-Class
|
||||
|
||||
#### *contract* . **METHOD_NAME**( ...args [ , overrides ] ) => *Promise< any >*
|
||||
|
||||
The type of the result depends on the ABI.
|
||||
The type of the result depends on the ABI. If the method returns a single value, it will be returned directly, otherwise a [Result](/v5/api/utils/abi/interface/#Result) object will be returned with each parameter available positionally and if the parameter is named, it will also be available by its name.
|
||||
|
||||
For values that have a simple meaning in JavaScript, the types are fairly straight forward; strings and booleans are returned as JavaScript strings and booleans.
|
||||
|
||||
@@ -125,6 +125,16 @@ For numbers, if the **type** is in the JavaScript safe range (i.e. less than 53
|
||||
|
||||
For bytes (both fixed length and dynamic), a [DataHexString](/v5/api/utils/bytes/#DataHexString) is returned.
|
||||
|
||||
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
|
||||
- `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`); *most developers will not require this*
|
||||
- `overrides.gasLimit` - the amount of gas (theoretically) to allow a node to use during the execution of the code; since there is no transaction, there is not going to be any fee charged, but the EVM still processes gas metering so calls like `gasleft` (or `GAS`) report meaningful values
|
||||
- `overrides.blockTag` - a block tag to simulate the execution at, which can be used for hypothetical historic analysis; note that many backends do not support this, or may require paid plans to access as the node database storage and processing requirements are much higher
|
||||
|
||||
|
||||
|
||||
|
||||
#### *contract* . *functions* . **METHOD_NAME**( ...args [ , overrides ] ) => *Promise< [Result](/v5/api/utils/abi/interface/#Result) >*
|
||||
|
||||
@@ -136,6 +146,8 @@ Another use for this method is for error recovery. For example, if a function re
|
||||
|
||||
Most developers should not require this.
|
||||
|
||||
The *overrides* are identical to the read-only operations above.
|
||||
|
||||
|
||||
### Write Methods (non-constant)
|
||||
|
||||
@@ -143,6 +155,29 @@ Most developers should not require this.
|
||||
|
||||
Returns a [TransactionResponse](/v5/api/providers/types/#providers-TransactionResponse) for the transaction after it is sent to the network. This requires the **Contract** has a signer.
|
||||
|
||||
The *overrides* object for write methods may include any of:
|
||||
|
||||
- `overrides.gasPrice` - the price to pay per gas
|
||||
- `overrides.gasLimit` - the limit on the amount of gas to allow the transaction to consume; any unused gas is returned at the gasPrice
|
||||
- `overrides.value` - the amount of ether (in wei) to forward with the call
|
||||
- `overrides.nonce` - the nonce to use for the [Signer](/v5/api/signer/#Signer)
|
||||
|
||||
|
||||
|
||||
If the `wait()` method on the returned [TransactionResponse](/v5/api/providers/types/#providers-TransactionResponse) is called, there will be additional properties on the receipt:
|
||||
|
||||
- `receipt.events` - an array of the logs, with additional properties (if the ABI included a description for the events)
|
||||
- `receipt.events[n].args` - the parsed arguments
|
||||
- `receipt.events[n].decode` - a method that can be used to parse the log topics and data (this was used to compute `args`)
|
||||
- `receipt.events[n].event` - the name of the event
|
||||
- `receipt.events[n].eventSignature` - the full signature of the event
|
||||
- `receipt.removeListener()` - a method to remove the listener that trigger this event
|
||||
- `receipt.getBlock()` - a method to return the [Block](/v5/api/providers/types/#providers-Block) this event occurred in
|
||||
- `receipt.getTransaction()` - a method to return the [Transaction](/v5/api/providers/types/#providers-TransactionResponse) this event occurred in
|
||||
- `receipt.getTransactionReceipt()` - a method to return the [Transaction Receipt](/v5/api/providers/types/#providers-TransactionReceipt) this event occurred in
|
||||
|
||||
|
||||
|
||||
|
||||
### Write Methods Analysis
|
||||
|
||||
@@ -150,11 +185,15 @@ Returns a [TransactionResponse](/v5/api/providers/types/#providers-TransactionRe
|
||||
|
||||
Returns the estimate units of gas that would be required to execute the *METHOD_NAME* with *args* and *overrides*.
|
||||
|
||||
The *overrides* are identical to the overrides above for read-only or write methods, depending on the type of call of *METHOD_NAME*.
|
||||
|
||||
|
||||
#### *contract* . *populateTransaction* . **METHOD_NAME**( ...args [ , overrides ] ) => *Promise< [UnsignedTx](/v5/api/utils/transactions/#UnsignedTransaction) >*
|
||||
|
||||
Returns an [UnsignedTransaction](/v5/api/utils/transactions/#UnsignedTransaction) which represents the transaction that would need to be signed and submitted to the network to execute *METHOD_NAME* with *args* and *overrides*.
|
||||
|
||||
The *overrides* are identical to the overrides above for read-only or write methods, depending on the type of call of *METHOD_NAME*.
|
||||
|
||||
|
||||
#### *contract* . *callStatic* . **METHOD_NAME**( ...args [ , overrides ] ) => *Promise< any >*
|
||||
|
||||
@@ -164,6 +203,8 @@ This does not actually change any state, but is free. This in some cases can be
|
||||
|
||||
This otherwise functions the same as a [Read-Only Method](/v5/api/contract/contract/#Contract--readonly).
|
||||
|
||||
The *overrides* are identical to the read-only operations above.
|
||||
|
||||
|
||||
### Event Filters
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -48,7 +48,7 @@ Set the current transaction count (nonce) for the signer.
|
||||
This may be useful in interacting with the signer outside of using this class.
|
||||
|
||||
|
||||
#### *nonceManager* . **increaseTransactionCount**( [ count = 1 ] ) => *void*
|
||||
#### *nonceManager* . **incrementTransactionCount**( [ count = 1 ] ) => *void*
|
||||
|
||||
Bump the current transaction count (nonce) by *count*.
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -54,6 +54,7 @@ Provider Documentation
|
||||
* [Accounts Methods](provider)
|
||||
* [Blocks Methods](provider)
|
||||
* [Ethereum Naming Service (ENS) Methods](provider)
|
||||
* [EnsResolver](provider)
|
||||
* [Logs Methods](provider)
|
||||
* [Network Status Methods](provider)
|
||||
* [Transactions Methods](provider)
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -7,9 +7,11 @@ Documentation: [html](https://docs.ethers.io/)
|
||||
JsonRpcProvider
|
||||
===============
|
||||
|
||||
#### **new ***ethers* . *providers* . **JsonRpcProvider**( [ url [ , aNetworkish ] ] )
|
||||
#### **new ***ethers* . *providers* . **JsonRpcProvider**( [ urlOrConnectionInfo [ , networkish ] ] )
|
||||
|
||||
Connect to a JSON-RPC API located at *url* using the *aNetworkish* network. If *url* is not specified, the default (i.e. `http://localhost:8545`) is used and if no network is specified, it will be determined automatically by querying the node.
|
||||
Connect to a JSON-RPC HTTP API using the URL or [ConnectionInfo](/v5/api/utils/web/#ConnectionInfo) *urlOrConnectionInfo* connected to the *networkish* network.
|
||||
|
||||
If *urlOrConnectionInfo* is not specified, the default (i.e. `http://localhost:8545`) is used and if no network is specified, it will be determined automatically by querying the node using `eth_chaindId` and falling back on `eth_networkId`.
|
||||
|
||||
|
||||
#### Note: Connecting to a Local Node
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -36,7 +36,7 @@ The provider for this configuration.
|
||||
|
||||
#### *fallbackProviderConfig* . **priority** => *number*
|
||||
|
||||
The priority used for the provider. Higher priorities are favoured over lower priorities. If multiple providers share the same priority, they are chosen at random.
|
||||
The priority used for the provider. Lower-value priorities are favoured over higher-value priorities. If multiple providers share the same priority, they are chosen at random.
|
||||
|
||||
|
||||
#### *fallbackProviderConfig* . **stallTimeout** => *number*
|
||||
@@ -123,7 +123,7 @@ This is identical to `sendAsync`. Historically, this used a synchronous web requ
|
||||
WebSocketProvider
|
||||
-----------------
|
||||
|
||||
#### **new ***ethers* . *provider* . **WebSocketProvider**( [ url [ , network ] ] )
|
||||
#### **new ***ethers* . *providers* . **WebSocketProvider**( [ url [ , network ] ] )
|
||||
|
||||
Returns a new [WebSocketProvider](/v5/api/providers/other/#WebSocketProvider) connected to *url* as the *network*.
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -7,6 +7,15 @@ Documentation: [html](https://docs.ethers.io/)
|
||||
Provider
|
||||
========
|
||||
|
||||
#### Coming from Web3.js?
|
||||
|
||||
If you are coming from Web3.js, this is one of the biggest differences you will encounter using ethers.
|
||||
|
||||
The ethers library creates a strong division between the operation a **Provider** can perform and those of a [Signer](/v5/api/signer/#Signer), which Web3.js lumps together.
|
||||
|
||||
This separation of concerns and a stricted subset of Provider operations allows for a larger variety of backends, a more consistent API and ensures other libraries to operate without being able to rely on any underlying assumption.
|
||||
|
||||
|
||||
Accounts Methods
|
||||
----------------
|
||||
|
||||
@@ -33,7 +42,7 @@ Returns the number of transactions *address* has ever **sent**, as of *blockTag*
|
||||
```javascript
|
||||
// Get the balance for an account...
|
||||
provider.getBalance("ricmoo.firefly.eth");
|
||||
// { Promise: { BigNumber: "284831012276355695" } }
|
||||
// { Promise: { BigNumber: "25334210474552466902" } }
|
||||
|
||||
// Get the code for a contract...
|
||||
provider.getCode("registrar.firefly.eth");
|
||||
@@ -45,7 +54,7 @@ provider.getStorageAt("registrar.firefly.eth", 0)
|
||||
|
||||
// Get transaction count of an account...
|
||||
provider.getTransactionCount("ricmoo.firefly.eth");
|
||||
// { Promise: 689 }
|
||||
// { Promise: 712 }
|
||||
```
|
||||
|
||||
Blocks Methods
|
||||
@@ -96,7 +105,7 @@ provider.getBlockWithTransactions(100004)
|
||||
// blockHash: '0xf93283571ae16dcecbe1816adc126954a739350cd1523a1559eabeae155fbb63',
|
||||
// blockNumber: 100004,
|
||||
// chainId: 0,
|
||||
// confirmations: 11212224,
|
||||
// confirmations: 11717911,
|
||||
// creates: null,
|
||||
// data: '0x',
|
||||
// from: '0xcf00A85f3826941e7A25BFcF9Aac575d40410852',
|
||||
@@ -118,6 +127,11 @@ provider.getBlockWithTransactions(100004)
|
||||
Ethereum Naming Service (ENS) Methods
|
||||
-------------------------------------
|
||||
|
||||
#### *provider* . **getResolver**( name ) => *Promise< [EnsResolver](/v5/api/providers/provider/#EnsResolver) >*
|
||||
|
||||
Returns an EnsResolver instance which can be used to further inquire about specific entries for an ENS name.
|
||||
|
||||
|
||||
#### *provider* . **lookupAddress**( address ) => *Promise< string >*
|
||||
|
||||
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.
|
||||
@@ -138,6 +152,34 @@ provider.resolveName("ricmoo.firefly.eth");
|
||||
// { Promise: '0x8ba1f109551bD432803012645Ac136ddd64DBA72' }
|
||||
```
|
||||
|
||||
EnsResolver
|
||||
-----------
|
||||
|
||||
#### *resolver* . **name** => *string*
|
||||
|
||||
The name of this resolver.
|
||||
|
||||
|
||||
#### *resolver* . **address** => *string< [Address](/v5/api/utils/address/#address) >*
|
||||
|
||||
The address of the Resolver.
|
||||
|
||||
|
||||
#### *resolver* . **getAddress**( [ cointType = 60 ] ) => *Promise< string >*
|
||||
|
||||
Returns a Promise which resolves to the [EIP-2304](https://eips.ethereum.org/EIPS/eip-2304) multicoin address stored for the *coinType*. By default an Ethereum [Address](/v5/api/utils/address/#address) (`coinType = 60`) will be returned.
|
||||
|
||||
|
||||
#### *resolver* . **getContentHash**( ) => *Promise< string >*
|
||||
|
||||
Returns a Promise which resolves to any stored [EIP-1577](https://eips.ethereum.org/EIPS/eip-1577) content hash.
|
||||
|
||||
|
||||
#### *resolver* . **getText**( key ) => *Promise< string >*
|
||||
|
||||
Returns a Promise which resolves to any stored [EIP-634](https://eips.ethereum.org/EIPS/eip-634) text entry for *key*.
|
||||
|
||||
|
||||
Logs Methods
|
||||
------------
|
||||
|
||||
@@ -166,6 +208,13 @@ Returns the block number (or height) of the most recently mined block.
|
||||
Returns a *best guess* of the [Gas Price](/v5/concepts/gas/#gas-price) to use in a transaction.
|
||||
|
||||
|
||||
#### *provider* . **ready** => *Promise< [Network](/v5/api/providers/types/#providers-Network) >*
|
||||
|
||||
Returns a Promise which will stall until the network has heen established, 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.
|
||||
|
||||
|
||||
```javascript
|
||||
// The network information
|
||||
provider.getNetwork()
|
||||
@@ -177,16 +226,16 @@ provider.getNetwork()
|
||||
|
||||
// The current block number
|
||||
provider.getBlockNumber()
|
||||
// { Promise: 11312227 }
|
||||
// { Promise: 11817914 }
|
||||
|
||||
// Get the current suggested gas price (in wei)...
|
||||
gasPrice = await provider.getGasPrice()
|
||||
// { BigNumber: "46200000000" }
|
||||
// { BigNumber: "207000000000" }
|
||||
|
||||
// ...often this gas price is easier to understand or
|
||||
// display to the user in gwei (giga-wei, or 1e9 wei)
|
||||
utils.formatUnits(gasPrice, "gwei")
|
||||
// '46.2'
|
||||
// '207.0'
|
||||
```
|
||||
|
||||
Transactions Methods
|
||||
@@ -204,6 +253,20 @@ Returns an estimate of the amount of gas that would be required to submit *trans
|
||||
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.
|
||||
|
||||
|
||||
#### *provider* . **getTransaction**( hash ) => *Promise< [TransactionResponse](/v5/api/providers/types/#providers-TransactionResponse) >*
|
||||
|
||||
Returns the transaction with *hash* or null if the transaction is unknown.
|
||||
|
||||
If a transaction has not been mined, this method will search the transaction 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.
|
||||
|
||||
|
||||
#### *provider* . **getTransactionReceipt**( hash ) => *Promise< [TransactionReceipt](/v5/api/providers/types/#providers-TransactionReceipt) >*
|
||||
|
||||
Returns the transaction receipt for *hash* or null if the transaction has not been mined.
|
||||
|
||||
To stall until the transaction has been mined, consider the `waitForTransaction` method below.
|
||||
|
||||
|
||||
#### *provider* . **sendTransaction**( transaction ) => *Promise< [TransactionResponse](/v5/api/providers/types/#providers-TransactionResponse) >*
|
||||
|
||||
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).
|
||||
@@ -213,43 +276,45 @@ Submits *transaction* to the network to be mined. The *transaction* **must** be
|
||||
|
||||
Returns a Promise which will not resolve until *transactionHash* is mined.
|
||||
|
||||
If *confirms* is 0, this method is non-blocking and if the transaction has not been mined returns null. Otherwise, this method will block until the transaction has *confirms* blocks mined on top of the block in which is was mined.
|
||||
|
||||
|
||||
Event Emitter Methods
|
||||
---------------------
|
||||
|
||||
#### *provider* . **on**( eventName , listener ) => *this*
|
||||
|
||||
Add a *listener* to be triggered for each *eventName*.
|
||||
Add a *listener* to be triggered for each *eventName* [event](/v5/api/providers/provider/#Provider--events).
|
||||
|
||||
|
||||
#### *provider* . **once**( eventName , listener ) => *this*
|
||||
|
||||
Add a *listener* to be triggered for only the next *eventName*, at which time it will be removed.
|
||||
Add a *listener* to be triggered for only the next *eventName* [event](/v5/api/providers/provider/#Provider--events), at which time it will be removed.
|
||||
|
||||
|
||||
#### *provider* . **emit**( eventName , ...args ) => *boolean*
|
||||
|
||||
Notify all listeners of *eventName*, passing *args* to each listener. This is generally only used internally.
|
||||
Notify all listeners of the *eventName* [event](/v5/api/providers/provider/#Provider--events), passing *args* to each listener. This is generally only used internally.
|
||||
|
||||
|
||||
#### *provider* . **off**( eventName [ , listener ] ) => *this*
|
||||
|
||||
Remove a *listener* for *eventName*. If no *listener* is provided, all listeners for *eventName* are removed.
|
||||
Remove a *listener* for the *eventName* [event](/v5/api/providers/provider/#Provider--events). If no *listener* is provided, all listeners for *eventName* are removed.
|
||||
|
||||
|
||||
#### *provider* . **removeAllListeners**( [ eventName ] ) => *this*
|
||||
|
||||
Remove all the listeners for *eventName*. If no *eventName* is provided, **all** events are removed.
|
||||
Remove all the listeners for the *eventName* [events](/v5/api/providers/provider/#Provider--events). If no *eventName* is provided, **all** events are removed.
|
||||
|
||||
|
||||
#### *provider* . **listenerCount**( [ eventName ] ) => *number*
|
||||
|
||||
Returns the number of listeners for *eventName*. If no *eventName* is provided, the total number of listeners is returned.
|
||||
Returns the number of listeners for the *eventName* [events](/v5/api/providers/provider/#Provider--events). If no *eventName* is provided, the total number of listeners is returned.
|
||||
|
||||
|
||||
#### *provider* . **listeners**( eventName ) => *Array< Listener >*
|
||||
|
||||
Returns the list of Listeners for *eventName*.
|
||||
Returns the list of Listeners for the *eventName* [events](/v5/api/providers/provider/#Provider--events).
|
||||
|
||||
|
||||
### Events
|
||||
@@ -260,7 +325,7 @@ A filter is an object, representing a contract log Filter, which has the optiona
|
||||
|
||||
If `address` is unspecified, the filter matches any contract address.
|
||||
|
||||
See events for more information on how to specify topic-sets.
|
||||
See [EventFilters](/v5/api/providers/types/#providers-EventFilter) for more information on filtering events.
|
||||
|
||||
|
||||
#### **Topic-Set Filter**
|
||||
@@ -269,6 +334,8 @@ The value of a **Topic-Set Filter** is a array of Topic-Sets.
|
||||
|
||||
This event is identical to a *Log Filter* with the address omitted (i.e. from any contract).
|
||||
|
||||
See [EventFilters](/v5/api/providers/types/#providers-EventFilter) for more information on filtering events.
|
||||
|
||||
|
||||
#### **Transaction Filter**
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -10,8 +10,6 @@ Types
|
||||
BlockTag
|
||||
--------
|
||||
|
||||
### EventType
|
||||
|
||||
Networkish
|
||||
----------
|
||||
|
||||
@@ -118,9 +116,13 @@ Events and Logs
|
||||
The address to filter by, or `null` to match any address.
|
||||
|
||||
|
||||
#### *filter* . **topics** => *Array< string< [DataHexString](/v5/api/utils/bytes/#DataHexString)< 32 > > | Array< string< [DataHexString](/v5/api/utils/bytes/#DataHexString)< 32 > > > >*
|
||||
#### *filter* . **topics** => *Array< string< [Data](/v5/api/utils/bytes/#DataHexString)< 32 > > | Array< string< [Data](/v5/api/utils/bytes/#DataHexString)< 32 > > > >*
|
||||
|
||||
The topics to filter by, or `null` to match any topics. Each entry represents an **AND** condition that must match, or may be `null` to match anything. If a given entry is an Array, then that entry is treated as an **OR** for any value in the entry.
|
||||
The topics to filter by or `null` to match any topics.
|
||||
|
||||
Each entry represents an **AND** condition that must match, or may be `null` to match anything. If a given entry is an Array, then that entry is treated as an **OR** for any value in the entry.
|
||||
|
||||
See [Filters](/v5/concepts/events/#events--filters) for more details and examples on specifying complex filters.
|
||||
|
||||
|
||||
### Filter
|
||||
@@ -268,9 +270,17 @@ The number of blocks that have been mined (including the initial block) since th
|
||||
The serialized transaction.
|
||||
|
||||
|
||||
#### *transaction* . **wait**( [ confirmations = 1 ] ) => *Promise< [TransactionReceipt](/v5/api/providers/types/#providers-TransactionReceipt) >*
|
||||
#### *transaction* . **wait**( [ confirms = 1 ] ) => *Promise< [TransactionReceipt](/v5/api/providers/types/#providers-TransactionReceipt) >*
|
||||
|
||||
Resolves to the [TransactionReceipt](/v5/api/providers/types/#providers-TransactionReceipt) once the transaction 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](/v5/api/utils/logger/#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`
|
||||
|
||||
|
||||
Wait for *confirmations*. If 0, and the transaction has not been mined, `null` is returned.
|
||||
|
||||
|
||||
### TransactionReceipt
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -273,7 +273,7 @@ walletMnemonic.publicKey
|
||||
walletMnemonic.mnemonic
|
||||
// {
|
||||
// locale: 'en',
|
||||
// path: 'm/44\'/60\'/0\'/0/0',
|
||||
// path: "m/44'/60'/0'/0/0",
|
||||
// phrase: 'announce room limb pattern dry unit scale effort smooth jazz weasel alcohol'
|
||||
// }
|
||||
|
||||
@@ -335,7 +335,7 @@ contract = new ethers.Contract("dai.tokens.ethers.eth", abi, signer)
|
||||
|
||||
// Get the number of tokens for this account
|
||||
tokens = await contract.balanceOf(signer.getAddress())
|
||||
// { BigNumber: "15923148775162018481031" }
|
||||
// { BigNumber: "198172622063578627973" }
|
||||
|
||||
//
|
||||
// Pre-flight (check for revert) on DAI from the signer
|
||||
@@ -352,7 +352,7 @@ contract.callStatic.transfer("donations.ethers.eth", tokens)
|
||||
|
||||
// This will fail since it is greater than the token balance
|
||||
contract.callStatic.transfer("donations.ethers.eth", tokens.add(1))
|
||||
// Error: call revert exception (method="transfer(address,uint256)", errorSignature="Error(string)", errorArgs=["Dai/insufficient-balance"], reason="Dai/insufficient-balance", code=CALL_EXCEPTION, version=abi/5.0.9)
|
||||
// Error: call revert exception (method="transfer(address,uint256)", errorSignature="Error(string)", errorArgs=["Dai/insufficient-balance"], reason="Dai/insufficient-balance", code=CALL_EXCEPTION, version=abi/5.0.12)
|
||||
```
|
||||
|
||||
ExternallyOwnedAccount
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -21,14 +21,14 @@ Converting and Verifying
|
||||
|
||||
Returns *address* as a Checksum Address.
|
||||
|
||||
If *address* is an invalid 40-nibble [HexString](/v5/api/utils/bytes/#HexString) or if it contains mixed case and the checksum is invalid, an InvalidArgument Error is thrown.
|
||||
If *address* is an invalid 40-nibble [HexString](/v5/api/utils/bytes/#HexString) or if it contains mixed case and the checksum is invalid, an [INVALID_ARGUMENT](/v5/api/utils/logger/#errors--invalid-argument) Error is thrown.
|
||||
|
||||
The value of *address* may be any supported address format.
|
||||
|
||||
|
||||
#### *ethers* . *utils* . **getIcapAddress**( address ) => *string< [IcapAddress](/v5/api/utils/address/#address-icap) >*
|
||||
|
||||
Returns *address* as an [ICAP address](https://github.com/ethereum/wiki/wiki/Inter-exchange-Client-Address-Protocol-%28ICAP%29). Supports the same restrictions as [utils.getAddress](/v5/api/utils/address/#utils-getAddress).
|
||||
Returns *address* as an [ICAP address](https://github.com/ethereum/wiki/wiki/Inter-exchange-Client-Address-Protocol-%28ICAP%29). Supports the same restrictions as [getAddress](/v5/api/utils/address/#utils-getAddress).
|
||||
|
||||
|
||||
#### *ethers* . *utils* . **isAddress**( address ) => *boolean*
|
||||
|
||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user