Compare commits
142 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
7a12216cfb |
121
CHANGELOG.md
121
CHANGELOG.md
@@ -3,6 +3,127 @@ Changelog
|
||||
|
||||
This change log is managed by `admin/cmds/update-versions` but may be manually updated.
|
||||
|
||||
|
||||
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)
|
||||
--------------------------------
|
||||
|
||||
|
||||
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:
|
||||
|
||||
@@ -98,11 +98,12 @@ 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. If the method returns a single
|
||||
@@ -132,7 +133,7 @@ The //overrides// object for a read-only method may include any of:
|
||||
- ``overrides.from`` - the ``msg.sender`` (or ``CALLER``) to use during the
|
||||
execution of the code
|
||||
- ``overrides.value`` - the ``msg.value`` (or ``CALLVALUE``) to use during the
|
||||
exectuiont of the code
|
||||
execution of the code
|
||||
- ``overrides.gasPrice`` - the price to pay per gas (theoretically); since there
|
||||
is no transaction, there is not going to be any fee charged, but the EVM still
|
||||
requires a value to report to ``tx.gasprice`` (or ``GASPRICE``);
|
||||
|
||||
@@ -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 the 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.
|
||||
|
||||
_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]]>
|
||||
|
||||
@@ -63,3 +83,11 @@ Bump the current transaction count (nonce) by //count//.
|
||||
|
||||
This may be useful in interacting with the signer outside of using
|
||||
this class.
|
||||
|
||||
_code: Importing @lang<script>
|
||||
|
||||
// Node
|
||||
const { NonceManager } = require("@ethersproject/experimental");
|
||||
|
||||
// ESM/TypeScript
|
||||
import { NonceManager } from "@ethersproject/experimental";
|
||||
|
||||
@@ -47,10 +47,8 @@ _definition: **Supported Networks**
|
||||
|
||||
_code: Etherscan Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const EtherscanProvider = ethers.providers.EtherscanProvider;
|
||||
const apiKey = "...";
|
||||
// </hide>
|
||||
//_hide: const EtherscanProvider = ethers.providers.EtherscanProvider;
|
||||
//_hide: const apiKey = "...";
|
||||
|
||||
// Connect to mainnet (homestead)
|
||||
provider = new EtherscanProvider();
|
||||
@@ -59,12 +57,9 @@ provider = new EtherscanProvider();
|
||||
provider = new EtherscanProvider("rinkeby");
|
||||
provider = new EtherscanProvider(4);
|
||||
|
||||
const network = ethers.providers.getNetwork("rinkeby");
|
||||
// <hide>
|
||||
delete network._defaultProvider;
|
||||
network
|
||||
// </hide>
|
||||
//!
|
||||
network = ethers.providers.getNetwork("rinkeby");
|
||||
//_hide: delete network._defaultProvider;
|
||||
//_log: network
|
||||
|
||||
provider = new EtherscanProvider(network);
|
||||
|
||||
@@ -119,11 +114,9 @@ _definition: **Supported Networks**
|
||||
|
||||
_code: INFURA Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const InfuraProvider = ethers.providers.InfuraProvider;
|
||||
const projectId = "...";
|
||||
const projectSecret = "...";
|
||||
// </hide>
|
||||
//_hide: const InfuraProvider = ethers.providers.InfuraProvider;
|
||||
//_hide: const projectId = "...";
|
||||
//_hide: const projectSecret = "...";
|
||||
|
||||
// Connect to mainnet (homestead)
|
||||
provider = new InfuraProvider();
|
||||
@@ -144,9 +137,7 @@ provider = new InfuraProvider("homestead", {
|
||||
|
||||
// Connect to the INFURA WebSocket endpoints with a WebSocketProvider
|
||||
provider = InfuraProvider.getWebSocketProvider()
|
||||
// <hide>
|
||||
provider.destroy();
|
||||
// </hide>
|
||||
//_hide: await provider.destroy();
|
||||
|
||||
|
||||
_subsection: AlchemyProvider @<AlchemyProvider> @inherit<[[UrlJsonRpcProvider]]> @src<providers:class.AlchemyProvider>
|
||||
@@ -178,10 +169,8 @@ _definition: **Supported Networks**
|
||||
|
||||
_code: Alchemy Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const AlchemyProvider = ethers.providers.AlchemyProvider;
|
||||
const apiKey = "...";
|
||||
// </hide>
|
||||
//_hide: const AlchemyProvider = ethers.providers.AlchemyProvider;
|
||||
//_hide: const apiKey = "...";
|
||||
|
||||
// Connect to mainnet (homestead)
|
||||
provider = new AlchemyProvider();
|
||||
@@ -196,9 +185,7 @@ provider = new AlchemyProvider("homestead", apiKey);
|
||||
|
||||
// Connect to the Alchemy WebSocket endpoints with a WebSocketProvider
|
||||
provider = AlchemyProvider.getWebSocketProvider()
|
||||
// <hide>
|
||||
provider.destroy();
|
||||
// </hide>
|
||||
//_hide: provider.destroy();
|
||||
|
||||
|
||||
_subsection: CloudflareProvider @<CloudflareProvider> @inherit<[[UrlJsonRpcProvider]]> @src<providers:class.CloudflareProvider>
|
||||
@@ -214,9 +201,7 @@ _definition: **Supported Networks**
|
||||
|
||||
_code: Cloudflare Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const CloudflareProvider = ethers.providers.CloudflareProvider;
|
||||
// </hide>
|
||||
//_hide: const CloudflareProvider = ethers.providers.CloudflareProvider;
|
||||
|
||||
// Connect to mainnet (homestead)
|
||||
provider = new CloudflareProvider();
|
||||
|
||||
@@ -77,9 +77,33 @@ _subsection: Networks
|
||||
There are several official common Ethereum networks as well as custom
|
||||
networks and other compatible projects.
|
||||
|
||||
Any API that accept a [[providers-Networkish]] can be passed a common name (such as
|
||||
``"mainnet"`` or ``"ropsten"``) to use that network definition or may specify
|
||||
custom parameters.
|
||||
Any API that accept a [[providers-Networkish]] can be passed a common
|
||||
name (such as ``"mainnet"`` or ``"ropsten"``) or chain ID to use that
|
||||
network definition or may specify custom parameters.
|
||||
|
||||
_property: ethers.providers.getNetwork(aNetworkish) => [[providers-Network]]
|
||||
|
||||
Returns the full [[providers-Network]] for the given standard
|
||||
//aNetworkish// [[providers-Networkish]].
|
||||
|
||||
This is useful for functions and classes which wish to accept [[providers-Networkish]]
|
||||
as an input parameter.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const getNetwork = ethers.providers.getNetwork;
|
||||
|
||||
// By Chain Name
|
||||
//_result:
|
||||
getNetwork("homestead");
|
||||
//_hide: delete _._defaultProvider;
|
||||
//_log:
|
||||
|
||||
// By Chain ID
|
||||
//_result:
|
||||
getNetwork(1);
|
||||
//_hide: delete _._defaultProvider;
|
||||
//_log:
|
||||
|
||||
_heading: Custom ENS Contract
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -26,7 +26,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>
|
||||
@@ -75,6 +75,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
|
||||
|
||||
@@ -99,7 +99,7 @@ application to ethers by wrapping an existing Web3-compatible (such as a
|
||||
[Web3WsProvider](link-web3-ws)) and exposing it as an ethers.js [[Provider]]
|
||||
which can then be used with the rest of the library.
|
||||
|
||||
This may also be used to wrap a standard [EIP-1193 Provider](link-eip-1193].
|
||||
This may also be used to wrap a standard [EIP-1193 Provider](link-eip-1193).
|
||||
|
||||
_property: new ethers.providers.Web3Provider(externalProvider [, network ])
|
||||
Create a new **Web3Provider**, which wraps an [EIP-1193 Provider](link-eip-1193) or
|
||||
|
||||
@@ -21,35 +21,41 @@ _subsection: Accounts Methods @<Provider--account-methods>
|
||||
_property: provider.getBalance(address [ , blockTag = latest ]) => Promise<[[BigNumber]]> @<Provider-getBalance> @SRC<providers/base-provider>
|
||||
Returns the balance of //address// as of the //blockTag// block height.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getBalance("ricmoo.eth");
|
||||
//_log:
|
||||
|
||||
_property: provider.getCode(address [ , blockTag = latest ]) => Promise<string<[[DataHexString]]>> @<Provider-getCode> @SRC<providers/base-provider>
|
||||
Returns the contract code of //address// as of the //blockTag// block height. If there is
|
||||
no contract currently deployed, the result is ``0x``.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getCode("registrar.firefly.eth");
|
||||
//_log:
|
||||
|
||||
_property: provider.getStorageAt(addr, pos [ , blockTag = latest ]) => Promise<string<[[DataHexString]]>> @<Provider-getStorageAt> @SRC<providers/base-provider>
|
||||
Returns the ``Bytes32`` value of the position //pos// at address //addr//, as of the //blockTag//.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getStorageAt("registrar.firefly.eth", 0)
|
||||
//_log:
|
||||
|
||||
_property: provider.getTransactionCount(address [ , blockTag = latest ]) => Promise<number> @<Provider-getTransactionCount> @SRC<providers/base-provider>
|
||||
Returns the number of transactions //address// has ever **sent**, as of //blockTag//.
|
||||
This value is required to be the nonce for the next transaction from //address//
|
||||
sent to the network.
|
||||
|
||||
_code: Account Examples @lang<javascript>
|
||||
_code: @lang<javascript>
|
||||
|
||||
// Get the balance for an account...
|
||||
provider.getBalance("ricmoo.firefly.eth");
|
||||
//!
|
||||
|
||||
// Get the code for a contract...
|
||||
provider.getCode("registrar.firefly.eth");
|
||||
//!
|
||||
|
||||
// Get the storage value at position 0...
|
||||
provider.getStorageAt("registrar.firefly.eth", 0)
|
||||
//!
|
||||
|
||||
// Get transaction count of an account...
|
||||
provider.getTransactionCount("ricmoo.firefly.eth");
|
||||
//!
|
||||
//_result:
|
||||
await provider.getTransactionCount("ricmoo.eth");
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Blocks Methods @<Provider--block-methods>
|
||||
@@ -58,17 +64,21 @@ _property: provider.getBlock(block) => Promise<[[providers-Block]]> @<Provider-
|
||||
Get the //block// from the network, where the ``result.transactions`` is a list
|
||||
of transaction hashes.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getBlock(100004)
|
||||
//_log:
|
||||
|
||||
_property: provider.getBlockWithTransactions(block) => Promise<[[providers-BlockWithTransactions]]> @<Provider-getBlockWithTransactions> @SRC<providers/base-provider>
|
||||
Get the //block// from the network, where the ``result.transactions`` is
|
||||
an Array of [[providers-TransactionResponse]] objects.
|
||||
|
||||
_code: Block Examples @lang<javascript>
|
||||
_code: @lang<javascript>
|
||||
|
||||
provider.getBlock(100004)
|
||||
//!
|
||||
|
||||
provider.getBlockWithTransactions(100004)
|
||||
//!
|
||||
//_result:
|
||||
await provider.getBlockWithTransactions(100004)
|
||||
//_log:
|
||||
|
||||
_subsection: Ethereum Naming Service (ENS) Methods @<Provider--ens-methods>
|
||||
|
||||
@@ -90,25 +100,39 @@ _property: provider.getResolver(name) => Promise<[[EnsResolver]]>
|
||||
Returns an EnsResolver instance which can be used to further inquire
|
||||
about specific entries for an ENS name.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: provider = ethers.getDefaultProvider();
|
||||
|
||||
// See below (Resolver) for examples of using this object
|
||||
const resolver = await provider.getResolver("ricmoo.eth");
|
||||
|
||||
//_hide: _page.resolver = resolver;
|
||||
|
||||
_property: provider.lookupAddress(address) => Promise<string> @<Provider-lookupAddress> @SRC<providers/base-provider>
|
||||
Performs a reverse lookup of the //address// in ENS using the
|
||||
//Reverse Registrar//. If the name does not exist, or the
|
||||
forward lookup does not match, ``null`` is returned.
|
||||
|
||||
An ENS name requries additional configuration to setup a reverse
|
||||
record, they are not automatically set up.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.lookupAddress("0x5555763613a12D8F3e73be831DFf8598089d3dCa");
|
||||
//_log:
|
||||
|
||||
_property: provider.resolveName(name) => Promise<string<[Address](address)>> @<Provider-ResolveName> @SRC<providers/base-provider>
|
||||
Looks up the address of //name//. If the name is not owned, or
|
||||
does not have a //Resolver// configured, or the //Resolver// does
|
||||
not have an address configured, ``null`` is returned.
|
||||
|
||||
_code: ENS Examples @lang<javascript>
|
||||
_code: @lang<javascript>
|
||||
|
||||
// Reverse lookup of an ENS by address...
|
||||
provider.lookupAddress("0x6fC21092DA55B392b045eD78F4732bff3C580e2c");
|
||||
//!
|
||||
|
||||
// Lookup an address of an ENS name...
|
||||
provider.resolveName("ricmoo.firefly.eth");
|
||||
//!
|
||||
//_result:
|
||||
await provider.resolveName("ricmoo.eth");
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: EnsResolver @<EnsResolver>
|
||||
@@ -124,12 +148,51 @@ Returns a Promise which resolves to the [[link-eip-2304]] multicoin address
|
||||
stored for the //coinType//. By default an Ethereum [[address]]
|
||||
(``coinType = 60``) will be returned.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const resolver = _page.resolver;
|
||||
|
||||
// By default, looks up the Ethereum address
|
||||
// (this will match provider.resolveName)
|
||||
//_result:
|
||||
await resolver.getAddress();
|
||||
//_log:
|
||||
|
||||
// Specify the coinType for other coin addresses (0 = Bitcoin)
|
||||
//_result:
|
||||
await resolver.getAddress(0);
|
||||
//_log:
|
||||
|
||||
_property: resolver.getContentHash() => Promise<string>
|
||||
Returns a Promise which resolves to any stored [[link-eip-1577]] content hash.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const resolver = _page.resolver;
|
||||
|
||||
//_result:
|
||||
await resolver.getContentHash();
|
||||
//_log:
|
||||
|
||||
_property: resolver.getText(key) => Promise<string>
|
||||
Returns a Promise which resolves to any stored [[link-eip-634]] text entry for //key//.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const resolver = _page.resolver;
|
||||
|
||||
//_result:
|
||||
await resolver.getText("email");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
await resolver.getText("url");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
await resolver.getText("com.twitter");
|
||||
//_log:
|
||||
|
||||
_subsection: Logs Methods @<Provider--log-methods>
|
||||
|
||||
_property: provider.getLogs(filter) => Promise<Array<[[providers-Log]]>> @<Provider-getLogs> @SRC<providers/base-provider>
|
||||
@@ -145,12 +208,59 @@ _subsection: Network Status Methods @<Provider--network-methods>
|
||||
_property: provider.getNetwork() => Promise<[[providers-Network]]> @<Provider-getNetwork> @SRC<providers/base-provider:method.BaseProvider.getNetwork>
|
||||
Returns the [[providers-Network]] this Provider is connected to.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getNetwork()
|
||||
//_hide: _ = utils.shallowCopy(_);
|
||||
//_hide: delete _._defaultProvider;
|
||||
//_log:
|
||||
|
||||
_property: provider.getBlockNumber() => Promise<number> @<Provider-getBlockNumber> @SRC<providers/base-provider>
|
||||
Returns the block number (or height) of the most recently mined block.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getBlockNumber()
|
||||
//_log:
|
||||
|
||||
_property: provider.getGasPrice() => Promise<[[BigNumber]]> @<Provider-getGasPrice> @SRC<providers/base-provider>
|
||||
Returns a //best guess// of the [[gas-price]] to use in a transaction.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
// The gas price (in wei)...
|
||||
gasPrice = await provider.getGasPrice()
|
||||
//_log: gasPrice
|
||||
|
||||
// ...often this gas price is easier to understand or
|
||||
// display to the user in gwei
|
||||
//_result:
|
||||
utils.formatUnits(gasPrice, "gwei")
|
||||
//_log:
|
||||
|
||||
_property: provider.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.
|
||||
@@ -158,31 +268,6 @@ ignoring errors due to the target node not being active yet.
|
||||
This can be used for testing or attaching scripts to wait until the node is
|
||||
up and running smoothly.
|
||||
|
||||
_code: Network Status Examples @lang<javascript>
|
||||
|
||||
// The network information
|
||||
provider.getNetwork()
|
||||
// <hide>
|
||||
//!
|
||||
network = utils.shallowCopy(_)
|
||||
delete network._defaultProvider
|
||||
network
|
||||
// </hide>
|
||||
//!
|
||||
|
||||
// The current block number
|
||||
provider.getBlockNumber()
|
||||
//!
|
||||
|
||||
// Get the current suggested gas price (in wei)...
|
||||
gasPrice = await provider.getGasPrice()
|
||||
//! async gasPrice
|
||||
|
||||
// ...often this gas price is easier to understand or
|
||||
// display to the user in gwei (giga-wei, or 1e9 wei)
|
||||
utils.formatUnits(gasPrice, "gwei")
|
||||
//!
|
||||
|
||||
|
||||
_subsection: Transactions Methods @<Provider--transaction-methods>
|
||||
|
||||
@@ -191,6 +276,18 @@ Returns the result of executing the //transaction//, using //call//. A call
|
||||
does not require any ether, but cannot change any state. This is useful
|
||||
for calling getters on Contracts.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.call({
|
||||
// ENS public resovler address
|
||||
to: "0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41",
|
||||
|
||||
// `function addr(namehash("ricmoo.eth")) view returns (address)`
|
||||
data: "0x3b3b57debf074faa138b72c65adbdcfb329847e4f2c04bde7f7dd7fcad5a52d2f395a558"
|
||||
});
|
||||
//_log:
|
||||
|
||||
_property: provider.estimateGas(transaction) => Promise<[[BigNumber]]> @<Provider-estimateGas> @SRC<providers/base-provider>
|
||||
Returns an estimate of the amount of gas that would be required to submit //transaction//
|
||||
to the network.
|
||||
@@ -199,6 +296,23 @@ An estimate may not be accurate since there could be another transaction
|
||||
on the network that was not accounted for, but after being mined affected
|
||||
relevant state.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const parseEther = ethers.utils.parseEther;
|
||||
|
||||
//_result:
|
||||
await provider.estimateGas({
|
||||
// Wrapped ETH address
|
||||
to: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
||||
|
||||
// `function deposit() payable`
|
||||
data: "0xd0e30db0",
|
||||
|
||||
// 1 ether
|
||||
value: parseEther("1.0")
|
||||
});
|
||||
//_log:
|
||||
|
||||
_property: provider.getTransaction(hash) => Promise<[[providers-TransactionResponse]]> @<Provider-getTransaction> @src<providers/base-provider>
|
||||
Returns the transaction with //hash// or null if the transaction is unknown.
|
||||
|
||||
@@ -207,6 +321,12 @@ pool. Various backends may have more restrictive transaction pool access (e.g.
|
||||
if the gas price is too low or the transaction was only recently sent and not
|
||||
yet indexed) in which case this method may also return null.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_result:
|
||||
await provider.getTransaction("0x5b73e239c55d790e3c9c3bbb84092652db01bb8dbf49ccc9e4a318470419d9a0");
|
||||
//_log:
|
||||
|
||||
_property: provider.getTransactionReceipt(hash) => Promise<[[providers-TransactionReceipt]]> @<Provider-getTransactionReceipt> @src<providers/base-provider>
|
||||
Returns the transaction receipt for //hash// or null if the transaction
|
||||
has not been mined.
|
||||
@@ -214,11 +334,34 @@ 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.
|
||||
|
||||
@@ -331,11 +474,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
|
||||
@@ -367,8 +509,8 @@ topicSets = [
|
||||
utils.id("Transfer(address,address,uint256)"),
|
||||
null,
|
||||
[
|
||||
myAddress,
|
||||
myOtherAddress
|
||||
hexZeroPad(myAddress, 32),
|
||||
hexZeroPad(myOtherAddress, 32)
|
||||
]
|
||||
]
|
||||
provider.on(topicSets, (log, event) => {
|
||||
@@ -385,10 +527,7 @@ provider.on("error", (tx) => {
|
||||
// Emitted when any error occurs
|
||||
});
|
||||
|
||||
// <hide>
|
||||
// Make sure our documentation builds without waiting forever
|
||||
provider.removeAllListeners()
|
||||
// </hide>
|
||||
//_hide: provider.removeAllListeners() /* Make sure the docs build without waiting forever */
|
||||
|
||||
_subsection: Inspection Methods @<Provider--inspection-methods>
|
||||
|
||||
|
||||
@@ -34,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>>
|
||||
@@ -183,18 +200,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).
|
||||
@@ -208,12 +254,13 @@ 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 legacy transactions that do not have an envelope.
|
||||
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 in an [[link-eip-2930]] transaction, which will
|
||||
include a ``type`` of ``1``.
|
||||
The [[providers-AccessList]] to include; only available for [[link-eip-2930]]
|
||||
and [[link-eip-1559]] transactions.
|
||||
|
||||
_heading: TransactionResponse @<providers-TransactionResponse> @INHERIT<[[Transaction]]>
|
||||
|
||||
@@ -237,7 +284,9 @@ 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
|
||||
rpopulate it. If this is required, it can be computed from a **TransactionResponse**
|
||||
object using [this cookbook recipe](cookbook--compute-raw-transaction).
|
||||
|
||||
_property: transaction.wait([ confirms = 1 ]) => Promise<[[providers-TransactionReceipt]]>
|
||||
Resolves to the [[providers-TransactionReceipt]] once the transaction
|
||||
@@ -245,22 +294,35 @@ has been included in the chain for //confirms// blocks. If //confirms//
|
||||
is 0, and the transaction has not been mined, ``null`` is returned.
|
||||
|
||||
If the transaction execution failed (i.e. the receipt status is ``0``),
|
||||
a [CALL_EXCEPTION](errors--call-exception) Error will be rejected with
|
||||
a [CALL_EXCEPTION](errors--call-exception) error will be rejected with
|
||||
the following properties:
|
||||
|
||||
- ``error.transaction`` - the original transaction
|
||||
- ``error.transactionHash`` - the hash of the transaction
|
||||
- ``error.receipt`` - the actual receipt, with the status of ``0``
|
||||
|
||||
_property: transactionRequest.type => null | number
|
||||
If the transaction is replaced by another transaction, a
|
||||
[TRANSACTION_REPLACED](errors--transaction-replaced) error will be rejected
|
||||
with the following properties:
|
||||
|
||||
The [[link-eip-2718]] type of this transaction envelope, or ``null``
|
||||
for legacy transactions that do not have an envelope.
|
||||
- ``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 in an [[link-eip-2930]] transaction, which will
|
||||
also have its ``type`` equal to ``1``.
|
||||
The [[providers-AccessList]] included, or null for transaction types which
|
||||
do not support access lists.
|
||||
|
||||
_heading: TransactionReceipt @<providers-TransactionReceipt>
|
||||
|
||||
@@ -284,6 +346,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.
|
||||
|
||||
@@ -371,7 +437,8 @@ _code: equivalent to the AccessList example below @lang<javascript>
|
||||
|
||||
// Option 2:
|
||||
// Array< [ Address, Array<Bytes32> ] >
|
||||
[
|
||||
//_hide: ;
|
||||
accessList = [
|
||||
[
|
||||
"0x0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
|
||||
[
|
||||
@@ -385,17 +452,11 @@ _code: equivalent to the AccessList example below @lang<javascript>
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
]
|
||||
]
|
||||
]
|
||||
// <hide>
|
||||
;
|
||||
// </hide>
|
||||
];
|
||||
|
||||
// Option 3:
|
||||
// Record<Address, Array<Bytes32>>
|
||||
// <hide>
|
||||
(
|
||||
// </hide>
|
||||
{
|
||||
accessList = {
|
||||
"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e": [
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000004",
|
||||
"0x0bcad17ecf260d6506c6b97768bdc2acfb6694445d27ffd3f9c1cfbee4a9bd6d"
|
||||
@@ -403,10 +464,7 @@ _code: equivalent to the AccessList example below @lang<javascript>
|
||||
"0x5FfC014343cd971B7eb70732021E26C35B744cc4": [
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
]
|
||||
}
|
||||
// <hide>
|
||||
)
|
||||
// </hide>
|
||||
};
|
||||
|
||||
|
||||
_heading: AccessList @<providers-AccessList>
|
||||
@@ -427,7 +485,7 @@ _code: example access list
|
||||
// storageKey: Array< DataHexString< 32 > >
|
||||
// }
|
||||
|
||||
[
|
||||
accessList = [
|
||||
{
|
||||
address: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
|
||||
storageKeys: [
|
||||
@@ -441,4 +499,4 @@ _code: example access list
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
]
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
@@ -39,7 +39,7 @@ asynchronous source, such as hardware wallets.
|
||||
Sub-classes **must** implement this.
|
||||
|
||||
_property: Signer.isSigner(object) => boolean @<Signer-isSigner> @SRC<abstract-signer>
|
||||
Returns true if an only if //object// is a **Signer**.
|
||||
Returns true if and only if //object// is a **Signer**.
|
||||
|
||||
_heading: Blockchain Methods @<Signer--blockchain-methods>
|
||||
|
||||
@@ -74,6 +74,12 @@ _property: signer.signMessage(message) => Promise<string<[RawSignature](signatur
|
||||
This returns a Promise which resolves to the [[signature-raw]]
|
||||
of //message//.
|
||||
|
||||
A signed message is prefixd with ``"\\x19Ethereum Signed Message:\\n"`` and
|
||||
the length of the message, using the [hashMessage](utils-hashMessage)
|
||||
method, so that it is [EIP-191](link-eip-191) compliant. If recovering
|
||||
the address in Solidity, this prefix will be required to create a matching
|
||||
hash.
|
||||
|
||||
Sub-classes **must** implement this, however they may throw if signing a
|
||||
message is not supported, such as in a Contract-based Wallet or
|
||||
Meta-Transaction-based Wallet.
|
||||
@@ -126,9 +132,7 @@ it has been used in the field a bit.
|
||||
|
||||
_code: Typed Data Example @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
signer = new Wallet("0x1234567890123456789012345678901234567890123456789012345678901234");
|
||||
// </hide>
|
||||
//_hide: signer = new Wallet("0x1234567890123456789012345678901234567890123456789012345678901234");
|
||||
|
||||
// All properties on a domain are optional
|
||||
const domain = {
|
||||
@@ -164,9 +168,9 @@ const value = {
|
||||
contents: 'Hello, Bob!'
|
||||
};
|
||||
|
||||
|
||||
const signature = await signer._signTypedData(domain, types, value);
|
||||
//! async signature
|
||||
//_result:
|
||||
signature = await signer._signTypedData(domain, types, value);
|
||||
//_log:
|
||||
|
||||
|
||||
_heading: Sub-Classes @<Signer--subclassing>
|
||||
@@ -281,35 +285,43 @@ walletMnemonic = Wallet.fromMnemonic(mnemonic)
|
||||
// ...or from a private key
|
||||
walletPrivateKey = new Wallet(walletMnemonic.privateKey)
|
||||
|
||||
//_result:
|
||||
walletMnemonic.address === walletPrivateKey.address
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// The address as a Promise per the Signer API
|
||||
walletMnemonic.getAddress()
|
||||
//!
|
||||
//_result:
|
||||
await walletMnemonic.getAddress()
|
||||
//_log:
|
||||
|
||||
// A Wallet address is also available synchronously
|
||||
//_result:
|
||||
walletMnemonic.address
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// The internal cryptographic components
|
||||
//_result:
|
||||
walletMnemonic.privateKey
|
||||
//!
|
||||
//_log:
|
||||
//_result:
|
||||
walletMnemonic.publicKey
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// The wallet mnemonic
|
||||
//_result:
|
||||
walletMnemonic.mnemonic
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Note: A wallet created with a private key does not
|
||||
// have a mnemonic (the derivation prevents it)
|
||||
//_result:
|
||||
walletPrivateKey.mnemonic
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Signing a message
|
||||
walletMnemonic.signMessage("Hello World")
|
||||
//!
|
||||
//_result:
|
||||
await walletMnemonic.signMessage("Hello World")
|
||||
//_log:
|
||||
|
||||
tx = {
|
||||
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
||||
@@ -317,24 +329,29 @@ tx = {
|
||||
}
|
||||
|
||||
// Signing a transaction
|
||||
walletMnemonic.signTransaction(tx)
|
||||
//!
|
||||
//_result:
|
||||
await walletMnemonic.signTransaction(tx)
|
||||
//_log:
|
||||
|
||||
// The connect method returns a new instance of the
|
||||
// Wallet connected to a provider
|
||||
//_result:
|
||||
wallet = walletMnemonic.connect(provider)
|
||||
//_null:
|
||||
|
||||
// Querying the network
|
||||
wallet.getBalance();
|
||||
//!
|
||||
wallet.getTransactionCount();
|
||||
//!
|
||||
//_result:
|
||||
await wallet.getBalance();
|
||||
//_log:
|
||||
//_result:
|
||||
await wallet.getTransactionCount();
|
||||
//_log:
|
||||
|
||||
// Sending ether
|
||||
wallet.sendTransaction(tx)
|
||||
// <hide>
|
||||
//! error
|
||||
// </hide>
|
||||
//_hide: wallet = localSigner; /* prevent insufficient funds error from blowing up the docs */
|
||||
//_result:
|
||||
await wallet.sendTransaction(tx)
|
||||
//_log:
|
||||
|
||||
|
||||
|
||||
@@ -367,12 +384,10 @@ abi = [
|
||||
]
|
||||
contract = new ethers.Contract("dai.tokens.ethers.eth", abi, signer)
|
||||
|
||||
// <hide>
|
||||
//!
|
||||
// </hide>
|
||||
// Get the number of tokens for this account
|
||||
//_result:
|
||||
tokens = await contract.balanceOf(signer.getAddress())
|
||||
//! async tokens
|
||||
//_log:
|
||||
|
||||
//
|
||||
// Pre-flight (check for revert) on DAI from the signer
|
||||
@@ -384,12 +399,14 @@ tokens = await contract.balanceOf(signer.getAddress())
|
||||
//
|
||||
|
||||
// This will pass since the token balance is available
|
||||
contract.callStatic.transfer("donations.ethers.eth", tokens)
|
||||
//!
|
||||
//_result:
|
||||
await contract.callStatic.transfer("donations.ethers.eth", tokens)
|
||||
//_log:
|
||||
|
||||
// This will fail since it is greater than the token balance
|
||||
contract.callStatic.transfer("donations.ethers.eth", tokens.add(1))
|
||||
//! error
|
||||
//_throws:
|
||||
await contract.callStatic.transfer("donations.ethers.eth", tokens.add(1))
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: ExternallyOwnedAccount @<ExternallyOwnedAccount>
|
||||
|
||||
@@ -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-readalbe (since
|
||||
the parser is a machine) and human-readable (at least **developer-readable**),
|
||||
as well as simple for humans to type and inline into code, which improves
|
||||
code readability. The Human-Readable ABI is also considerably smaller, which
|
||||
helps reduce code size.
|
||||
|
||||
A Huamn-Readable ABI is simple an array of strings, where each string is
|
||||
the Solidity signature.
|
||||
|
||||
Signatures may be minimally specified (i.e. names of inputs and outputs
|
||||
may be omitted) or fully specified (i.e. with all property names) and
|
||||
whitespace is ignored.
|
||||
|
||||
Several modifiers available in Solidity are dropped internally, as they
|
||||
are not required for the ABI and used old by Solidity's semantic checking
|
||||
system, such as input parameter data location like ``"calldata"``
|
||||
and ``"memory"``. As such, they can be safely dropped in the ABI as well.
|
||||
|
||||
_code: Human-Readable ABI Example @lang<javascript>
|
||||
|
||||
const humanReadableAbi = [
|
||||
|
||||
// Simple types
|
||||
"constructor(string symbol, string name)",
|
||||
"function transferFrom(address from, address to, uint value)",
|
||||
"function balanceOf(address owner) view returns (uint balance)",
|
||||
"event Transfer(address indexed from, address indexed to, address value)",
|
||||
"error InsufficientBalance(account owner, uint balance)",
|
||||
|
||||
// Some examples with the struct type, we use the tuple keyword:
|
||||
// (note: the tuple keyword is optional, simply using additional
|
||||
// parentheses accomplishes the same thing)
|
||||
// struct Person {
|
||||
// string name;
|
||||
// uint16 age;
|
||||
// }
|
||||
"function addPerson(tuple(string name, uint16 age) person)",
|
||||
"function addPeople(tuple(string name, uint16 age)[] person)",
|
||||
"function getPerson(uint id) view returns (tuple(string name, uint16 age))",
|
||||
|
||||
"event PersonAdded(uint indexed id, tuple(string name, uint16 age) person)"
|
||||
];
|
||||
|
||||
//_hide: _page.humanReadableAbi = humanReadableAbi;
|
||||
|
||||
|
||||
_subsection: Solidity JSON ABI @<abi-formats--solidity>
|
||||
|
||||
See [Solidity compiler](link-solc-output).
|
||||
The **Solidity JSON ABI** is a standard format that many tools export,
|
||||
including the Solidity compiler. For the full specification, see
|
||||
the [Solidity compiler documentation](link-solc-output).
|
||||
|
||||
Various versions include slightly different keys and values. For example,
|
||||
early compilers included only a boolean ``"constant"`` to indicate mutability,
|
||||
while newer versions include a string ``"mutabilityState"``, which encompasses
|
||||
several older properties.
|
||||
|
||||
When creating an instance of a [Fragment](Fragment) using a JSON ABI, it will
|
||||
automatically infer all legacy properties for new-age ABIs and for legacy
|
||||
ABIs will infer the new-age properties. All properties will be populated, so
|
||||
it will match the equivalent created using a Human-Readable ABI fragment.
|
||||
|
||||
_code: The same ABI as JSON ABI @lang<javascript>
|
||||
|
||||
const jsonAbi = `[
|
||||
{
|
||||
"type": "constructor",
|
||||
"payable": false,
|
||||
"inputs": [
|
||||
{ "type": "string", "name": "symbol" },
|
||||
{ "type": "string", "name": "name" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "transferFrom",
|
||||
"constant": false,
|
||||
"payable": false,
|
||||
"inputs": [
|
||||
{ "type": "address", "name": "from" },
|
||||
{ "type": "address", "name": "to" },
|
||||
{ "type": "uint256", "name": "value" }
|
||||
],
|
||||
"outputs": [ ]
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "balanceOf",
|
||||
"constant":true,
|
||||
"stateMutability": "view",
|
||||
"payable":false, "inputs": [
|
||||
{ "type": "address", "name": "owner"}
|
||||
],
|
||||
"outputs": [
|
||||
{ "type": "uint256"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "event",
|
||||
"anonymous": false,
|
||||
"name": "Transfer",
|
||||
"inputs": [
|
||||
{ "type": "address", "name": "from", "indexed":true},
|
||||
{ "type": "address", "name": "to", "indexed":true},
|
||||
{ "type": "address", "name": "value"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "error",
|
||||
"name": "InsufficientBalance",
|
||||
"inputs": [
|
||||
{ "type": "account", "name": "owner"},
|
||||
{ "type": "uint256", "name": "balance"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "addPerson",
|
||||
"constant": false,
|
||||
"payable": false,
|
||||
"inputs": [
|
||||
{
|
||||
"type": "tuple",
|
||||
"name": "person",
|
||||
"components": [
|
||||
{ "type": "string", "name": "name" },
|
||||
{ "type": "uint16", "name": "age" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "addPeople",
|
||||
"constant": false,
|
||||
"payable": false,
|
||||
"inputs": [
|
||||
{
|
||||
"type": "tuple[]",
|
||||
"name": "person",
|
||||
"components": [
|
||||
{ "type": "string", "name": "name" },
|
||||
{ "type": "uint16", "name": "age" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "getPerson",
|
||||
"constant": true,
|
||||
"stateMutability": "view",
|
||||
"payable": false,
|
||||
"inputs": [
|
||||
{ "type": "uint256", "name": "id" }
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "tuple",
|
||||
"components": [
|
||||
{ "type": "string", "name": "name" },
|
||||
{ "type": "uint16", "name": "age" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "event",
|
||||
"anonymous": false,
|
||||
"name": "PersonAdded",
|
||||
"inputs": [
|
||||
{ "type": "uint256", "name": "id", "indexed": true },
|
||||
{
|
||||
"type": "tuple",
|
||||
"name": "person",
|
||||
"components": [
|
||||
{ "type": "string", "name": "name", "indexed": false },
|
||||
{ "type": "uint16", "name": "age", "indexed": false }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]`;
|
||||
|
||||
//_hide: _page.jsonAbi = jsonAbi;
|
||||
|
||||
_subsection: Solidity Object ABI @<abi-formats--object>
|
||||
|
||||
The output from parsing (using JSON.parse) a Solidity JSON ABI
|
||||
is also fully compatible with the [[Interface]] class and each
|
||||
method, event and error from that object are compatible with
|
||||
the [[Fragment]] class.
|
||||
|
||||
Some developers may prefer this as it allows access to the ABI
|
||||
properties as normal JavaScript objects, and closely matches the
|
||||
JSON ABI that those familiar with the Solidity ABI will recognize.
|
||||
|
||||
_subsection: Converting Between Formats
|
||||
|
||||
The [[Fragment]] object makes it simple to reformat a single
|
||||
method, event or error, however most developers will be interested
|
||||
in converting an entire ABI.
|
||||
|
||||
For production code it is recommended to inline the Human-Readable
|
||||
ABI as it makes it easy to see at a glance which methods, events
|
||||
and errors are available. It is also highly recommend to strip out
|
||||
unused parts of the ABI (such as admin methods) to further reduce
|
||||
code size.
|
||||
|
||||
_code: Converting to Full Human-Readable ABI @lang<javascript>
|
||||
|
||||
//_hide: const Interface = ethers.utils.Interface;
|
||||
//_hide: const FormatTypes = ethers.utils.FormatTypes;
|
||||
//_hide: jsonAbi = _page.jsonAbi;
|
||||
|
||||
// Using the "full" format will ensure the Result objects
|
||||
// have named properties, which improves code readability
|
||||
const iface = new Interface(jsonAbi);
|
||||
//_result:
|
||||
iface.format(FormatTypes.full);
|
||||
//_log:
|
||||
|
||||
_code: Converting to Minimal Human-Readable ABI @lang<javascript>
|
||||
|
||||
//_hide: const Interface = ethers.utils.Interface;
|
||||
//_hide: const FormatTypes = ethers.utils.FormatTypes;
|
||||
//_hide: jsonAbi = _page.jsonAbi;
|
||||
|
||||
// Using the "minimal" format will save a small amount of
|
||||
// space, but is generally not worth it as named properties
|
||||
// on Results will not be available
|
||||
const iface = new Interface(jsonAbi);
|
||||
//_result:
|
||||
iface.format(FormatTypes.minimal);
|
||||
//_log:
|
||||
|
||||
_code: Converting to JSON ABI @lang<javascript>
|
||||
|
||||
//_hide: const Interface = ethers.utils.Interface;
|
||||
//_hide: const FormatTypes = ethers.utils.FormatTypes;
|
||||
//_hide: humanReadableAbi = _page.humanReadableAbi;
|
||||
|
||||
// Sometimes you may need to export a Human-Readable ABI to
|
||||
// JSON for tools that do not have Human-Readable support
|
||||
|
||||
// For compactness, the JSON is kept with minimal white-space
|
||||
const iface = new Interface(humanReadableAbi);
|
||||
//_result:
|
||||
jsonAbi = iface.format(FormatTypes.json);
|
||||
//_log:
|
||||
|
||||
// However it is easy to use JSON.parse and JSON.stringify
|
||||
// with formatting parameters to assist with readability
|
||||
//_result:
|
||||
JSON.stringify(JSON.parse(jsonAbi), null, 2);
|
||||
//_log:
|
||||
|
||||
@@ -5,7 +5,6 @@ Explain an ABI.
|
||||
_subsection: Formats
|
||||
|
||||
_heading: JSON String ABI (Solidity Output JSON)
|
||||
|
||||
The **JSON ABI Format** is the format that is
|
||||
[output from the Solidity compiler](link-solc-output).
|
||||
|
||||
@@ -15,50 +14,74 @@ of Objects, where each Object has various properties describing the [[Fragment]]
|
||||
The deserialized JSON string (which is a normal JavaScript Object) may
|
||||
also be passed into any function which accepts a JSON String ABI.
|
||||
|
||||
_heading: Humanb-Readable ABI
|
||||
_heading: Humanb-Readable ABI @<human-readable-abi>
|
||||
The Human-Readable ABI was introduced by ethers in [this article](link-ricmoo-humanreadableabi)
|
||||
and has since gained wider adoption.
|
||||
|
||||
The Human-Readable ABI was @TODO
|
||||
The ABI is described by using an array of strings, where each string is the
|
||||
Solidity signature of the **constructor**, **function**, **event** or **error**.
|
||||
|
||||
[article](link-ricmoo-humanreadableabi)
|
||||
When parsing a fragment, all inferred properties will be injected (e.g. a //payable//
|
||||
method will have its ``constant`` proeprty set to false).
|
||||
|
||||
Tuples can be specified by using the ``tuple(...)`` syntax or with bare (additional)
|
||||
parenthesis, ``(...)``.
|
||||
|
||||
_code: Example Human-Readable ABI
|
||||
|
||||
const ABI = [
|
||||
// Constructor
|
||||
"constructor(address ens)",
|
||||
|
||||
// Constant functions (pure or view)
|
||||
"function balanceOf(address owner) view returns (uint)",
|
||||
|
||||
// State-mutating functions (payable or non-payable)
|
||||
"function mint(uint amount) payable",
|
||||
"function transfer(address to, uint amount) returns (bool)",
|
||||
|
||||
// Events
|
||||
"event Transfer(address indexed from, address indexed to, uint amount)",
|
||||
|
||||
// Errors
|
||||
"error InsufficientFunds(address from, uint balance)",
|
||||
]
|
||||
|
||||
|
||||
_heading: Output Formats @<fragments--output-formats> @SRC<abi/fragments:FormatTypes>
|
||||
|
||||
Each [[Fragment]] and [[ParamType]] may be output using its ``format``
|
||||
method.
|
||||
|
||||
_property: ethers.utils.FragmentTypes.full => string
|
||||
|
||||
_property: ethers.utils.FormatTypes.full => string
|
||||
This is a full human-readable string, including all parameter names, any
|
||||
optional modifiers (e.g. ``indexed``, ``public``, etc) and white-space
|
||||
to aid in human readability.
|
||||
|
||||
_property: ethers.utils.FragmentTypes.minimal => string
|
||||
|
||||
_property: ethers.utils.FormatTypes.minimal => string
|
||||
This is similar to ``full``, except with no unnecessary whitespace or parameter
|
||||
names. This is useful for storing a minimal string which can still fully
|
||||
reconstruct the original Fragment using [Fragment . from](Fragment-from).
|
||||
|
||||
_property: ethers.utils.FragmentTypes.json => string
|
||||
|
||||
_property: ethers.utils.FormatTypes.json => string
|
||||
This returns a JavaScript Object which is safe to call ``JSON.stringify``
|
||||
on to create a JSON string.
|
||||
|
||||
_property: ethers.utils.FragmentTypes.sighash => string
|
||||
|
||||
_property: ethers.utils.FormatTypes.sighash => string
|
||||
This is a minimal output format, which is used by Solidity when computing a
|
||||
signature hash or an event topic hash.
|
||||
|
||||
_warning: Note
|
||||
|
||||
The ``sighash`` format is **insufficient** to re-create the original [[Fragment]],
|
||||
since it discards modifiers such as indexed, anonymous, stateMutability, etc.
|
||||
|
||||
It is only useful for computing the selector for a Fragment, and cannot
|
||||
be used to format an Interface.
|
||||
|
||||
|
||||
_subsection: Fragment @<Fragment> @SRC<abi/fragments:class.Fragment>
|
||||
|
||||
An ABI is a collection of **Fragments**, where each fragment specifies:
|
||||
|
||||
- An [Error](ErrorFragment)
|
||||
- An [Event](EventFragment)
|
||||
- A [Function](FunctionFragment)
|
||||
- A [Constructor](ConstructorFragment)
|
||||
@@ -66,12 +89,10 @@ An ABI is a collection of **Fragments**, where each fragment specifies:
|
||||
_heading: Properties
|
||||
|
||||
_property: fragment.name => string
|
||||
|
||||
This is the name of the Event or Function. This will be null for
|
||||
a [[ConstructorFragment]].
|
||||
|
||||
_property: fragment.type => string
|
||||
|
||||
This is a string which indicates the type of the [[Fragment]]. This
|
||||
will be one of:
|
||||
|
||||
@@ -80,19 +101,20 @@ will be one of:
|
||||
- ``function``
|
||||
|
||||
_property: fragment.inputs => Array<[[ParamType]]>
|
||||
|
||||
This is an array of each [[ParamType]] for the input parameters to
|
||||
the Constructor, Event of Function.
|
||||
|
||||
_heading: Methods
|
||||
|
||||
_property: ethers.utils.Fragment.from(objectOrString) => [[Fragment]] @<Fragment-from> @SRC<abi/fragments:Fragment.from>
|
||||
_property: fragment.format([ format = sighash]) => string @<Fragment-format> @SRC<abi/fragments:Fragment.format>
|
||||
Creates a string representation of the Fragment using the available
|
||||
[output formats](fragments--output-formats).
|
||||
|
||||
Returns a
|
||||
_property: ethers.utils.Fragment.from(objectOrString) => [[Fragment]] @<Fragment-from> @SRC<abi/fragments:Fragment.from>
|
||||
Creates a new **Fragment** sub-class from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.Fragment.isFragment(object) => boolean @<Fragment-isFragment> @SRC<abi/fragments:Fragment.isFragment>
|
||||
|
||||
Tra lal al
|
||||
Returns true if //object// is a **Fragment**.
|
||||
|
||||
|
||||
_subsection: ConstructorFragment @<ConstructorFragment> @INHERIT<[[Fragment]]> @SRC<abi/fragments:class.ConstructorFragment>
|
||||
@@ -100,17 +122,14 @@ _subsection: ConstructorFragment @<ConstructorFragment> @INHERIT<[[Fragment]]> @
|
||||
_heading: Properties
|
||||
|
||||
_property: fragment.gas => [[BigNumber]]
|
||||
|
||||
This is the gas limit that should be used during deployment. It may be
|
||||
null.
|
||||
|
||||
_property: fragment.payable => boolean
|
||||
|
||||
This is whether the constructor may receive ether during deployment as
|
||||
an endowment (i.e. msg.value != 0).
|
||||
|
||||
_property: fragment.stateMutability => string
|
||||
|
||||
This is the state mutability of the constructor. It can be any of:
|
||||
|
||||
- ``nonpayable``
|
||||
@@ -119,12 +138,21 @@ This is the state mutability of the constructor. It can be any of:
|
||||
_heading: Methods
|
||||
|
||||
_property: ethers.utils.ConstructorFragment.from(objectOrString) => [[ConstructorFragment]] @<ConstructorFragment-from> @SRC<abi/fragments:ConstructorFragment.from>
|
||||
|
||||
Tra la la...
|
||||
Creates a new **ConstructorFragment** from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.ConstructorFragment.isConstructorFragment(object) => boolean @<ConstructorFragment-isConstructorFragment> @SRC<abi/fragments:ConstructorFragment.isConstructorFragment>
|
||||
Returns true if //object// is a **ConstructorFragment**.
|
||||
|
||||
Tra lal al
|
||||
|
||||
_subsection: ErrorFragment @<ErrorFragment> @INHERIT<[[Fragment]]> @SRC<abi/fragments:class.ErrorFragment>
|
||||
|
||||
_heading: Methods
|
||||
|
||||
_property: ethers.utils.ErrorFragment.from(objectOrString) => [[ErrorFragment]] @<ErrorFragment-from> @SRC<abi/fragments:ErrorFragment.from>
|
||||
Creates a new **ErrorFragment** from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.ErrorFragment.isErrorFragment(object) => boolean @<ErrorFragment-isErrorFragment> @SRC<abi/fragments:ErrorFragment.isErrorFragment>
|
||||
Returns true if //object// is an **ErrorFragment**.
|
||||
|
||||
|
||||
_subsection: EventFragment @<EventFragment> @INHERIT<[[Fragment]]> @SRC<abi/fragments:class.EventFragment>
|
||||
@@ -132,19 +160,16 @@ _subsection: EventFragment @<EventFragment> @INHERIT<[[Fragment]]> @SRC<abi/frag
|
||||
_heading: Properties
|
||||
|
||||
_property: fragment.anonymous => boolean
|
||||
|
||||
This is whether the event is anonymous. An anonymous Event does not inject its
|
||||
topic hash as topic0 when creating a log.
|
||||
|
||||
_heading: Methods
|
||||
|
||||
_property: ethers.utils.EventFragment.from(objectOrString) => [[EventFragment]] @<EventFragment-from> @SRC<abi/fragments:EventFragment.from>
|
||||
|
||||
Tra la la...
|
||||
Creates a new **EventFragment** from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.EventFragment.isEventFragment(object) => boolean @<EventFragment-isEventFragment> @SRC<abi/fragments:EventFragment.isEventFragment>
|
||||
|
||||
Tra lal al
|
||||
Returns true if //object// is an **EventFragment**.
|
||||
|
||||
|
||||
_subsection: FunctionFragment @<FunctionFragment> @INHERIT<[[ConstructorFragment]]> @SRC<abi/fragments:class.FunctionFragment>
|
||||
@@ -152,12 +177,10 @@ _subsection: FunctionFragment @<FunctionFragment> @INHERIT<[[ConstructorFragment
|
||||
_heading: Properties
|
||||
|
||||
_property: fragment.constant => boolean
|
||||
|
||||
This is whether the function is constant (i.e. does not change state). This
|
||||
is true if the state mutability is ``pure`` or ``view``.
|
||||
|
||||
_property: fragment.stateMutability => string
|
||||
|
||||
This is the state mutability of the constructor. It can be any of:
|
||||
|
||||
- ``nonpayable``
|
||||
@@ -166,22 +189,18 @@ This is the state mutability of the constructor. It can be any of:
|
||||
- ``view``
|
||||
|
||||
_property: fragment.outputs => Array<[[ParamType]]>
|
||||
|
||||
A list of the Function output parameters.
|
||||
|
||||
_heading: Method
|
||||
_heading: Methods
|
||||
|
||||
_property: ethers.utils.FunctionFragment.from(objectOrString) => [[FunctionFragment]] @<FunctionFragment-from> @SRC<abi/fragments:ConstructorFragment.from>
|
||||
|
||||
Tra la la...
|
||||
Creates a new **FunctionFragment** from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.FunctionFragment.isFunctionFragment(object) => boolean @<FunctionFragment-isFunctionFragment> @SRC<abi/fragments:FunctionFragment.isFunctionFragment>
|
||||
|
||||
Tra lal al
|
||||
Returns true if //object// is a **FunctionFragment**.
|
||||
|
||||
|
||||
_subsection: ParamType @<ParamType> @SRC<abi/fragments:class.ParamType>
|
||||
|
||||
The following examples will represent the Solidity parameter:
|
||||
|
||||
``string foobar``
|
||||
@@ -189,53 +208,42 @@ The following examples will represent the Solidity parameter:
|
||||
_heading: Properties
|
||||
|
||||
_property: paramType.name => string @<ParamType-name>
|
||||
|
||||
The local parameter name. This may be null for unnamed parameters. For example,
|
||||
the parameter definition ``string foobar`` would be ``foobar``.
|
||||
|
||||
_property: paramType.type => string @<ParamType-type>
|
||||
|
||||
The full type of the parameter, including tuple and array symbols. This may be null
|
||||
for unnamed parameters. For the above example, this would be ``foobar``.
|
||||
|
||||
_property: paramType.baseType => string @<ParamType-baseType>
|
||||
|
||||
The base type of the parameter. For primitive types (e.g. ``address``, ``uint256``, etc)
|
||||
this is equal to [type](ParamType-type). For arrays, it will be the string ``array`` and for
|
||||
a tuple, it will be the string ``tuple``.
|
||||
|
||||
_property: paramType.indexed => boolean @<ParamType-indexed>
|
||||
|
||||
Whether the parameter has been marked as indexed. This **only** applies
|
||||
to parameters which are part of an [[EventFragment]].
|
||||
|
||||
_property: paramType.arrayChildren => [[ParamType]] @<ParamType-arrayChildren>
|
||||
|
||||
The type of children of the array. This is null for any parameter
|
||||
which is not an array.
|
||||
|
||||
_property: paramType.arrayLength => number @<ParamType-arrayLength>
|
||||
|
||||
The length of the array, or ``-1`` for dynamic-length arrays. This is
|
||||
null for parameters which are not arrays.
|
||||
|
||||
_property: paramType.components => Array<[[ParamType]]> @<ParamType-components>
|
||||
|
||||
The components of a tuple. This is null for non-tuple parameters.
|
||||
|
||||
|
||||
_heading: Methods
|
||||
|
||||
Tra la la...
|
||||
|
||||
_property: paramType.format([ outputType = sighash ])
|
||||
|
||||
Tra la la...
|
||||
Creates a string representation of the Fragment using the available
|
||||
[output formats](fragments--output-formats).
|
||||
|
||||
_property: ethers.utils.ParamType.from(objectOrString) => [[ParamType]] @<ParamType-from> @SRC<abi/fragments:ParamType.from>
|
||||
|
||||
Tra la la...
|
||||
Creates a new **ParamType** from any compatible //objectOrString//.
|
||||
|
||||
_property: ethers.utils.ParamType.isParamType(object) => boolean @<ParamType-isParamType> @SRC<abi/fragments:ParamType.isParamType>
|
||||
|
||||
Tra la la...
|
||||
Returns true if //object// is a **ParamType**.
|
||||
|
||||
@@ -26,11 +26,47 @@ which is a format the Ethers created to simplify manually typing the ABI
|
||||
into the source and so that a Contract ABI can also be referenced easily
|
||||
within the same source file.
|
||||
|
||||
_code: Creating an Interface instance @lang<javascript>
|
||||
|
||||
//_hide: const Interface = ethers.utils.Interface;
|
||||
|
||||
// This interface is used for the below examples
|
||||
|
||||
const iface = new Interface([
|
||||
// Constructor
|
||||
"constructor(string symbol, string name)",
|
||||
|
||||
// State mutating method
|
||||
"function transferFrom(address from, address to, uint amount)",
|
||||
|
||||
// State mutating method, which is payable
|
||||
"function mint(uint amount) payable",
|
||||
|
||||
// Constant method (i.e. "view" or "pure")
|
||||
"function balanceOf(address owner) view returns (uint)",
|
||||
|
||||
// An Event
|
||||
"event Transfer(address indexed from, address indexed to, uint256 amount)",
|
||||
|
||||
// A Custom Solidity Error
|
||||
"error AccountLocked(address owner, uint256 balance)",
|
||||
|
||||
// Examples with structured types
|
||||
"function addUser(tuple(string name, address addr) user) returns (uint id)",
|
||||
"function addUsers(tuple(string name, address addr)[] user) returns (uint[] id)",
|
||||
"function getUser(uint id) view returns (tuple(string name, address addr) user)"
|
||||
]);
|
||||
|
||||
//_hide: _page.iface = iface;
|
||||
|
||||
_subsection: Properties @<Interface--properties>
|
||||
|
||||
_property: interface.fragments => Array<[[Fragment]]>
|
||||
All the [Fragments](Fragment) in the interface.
|
||||
|
||||
_property: interface.errors => Array<[[ErrorFragment]]>
|
||||
All the [Error Fragments](ErrorFragment) in the interface.
|
||||
|
||||
_property: interface.events => Array<[[EventFragment]]>
|
||||
All the [Event Fragments](EventFragment) in the interface.
|
||||
|
||||
@@ -48,24 +84,133 @@ Return the formatted **Interface**. If the format type is ``json`` a
|
||||
single string is returned, otherwise an Array of the human-readable
|
||||
strings is returned.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const iface = _page.iface;
|
||||
|
||||
const FormatTypes = ethers.utils.FormatTypes;
|
||||
|
||||
//_result:
|
||||
iface.format(FormatTypes.json)
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
iface.format(FormatTypes.full)
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
iface.format(FormatTypes.minimal)
|
||||
//_log:
|
||||
|
||||
_subsection: Fragment Access @<Interface--fragments>
|
||||
|
||||
_property: interface.getFunction(fragment) => [[FunctionFragment]] @SRC<abi/interface>
|
||||
Returns the [[FunctionFragment]] for //fragment// (see [[Interface--specifying-fragments]]).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const iface = _page.iface;
|
||||
|
||||
// By method signature, which is normalized so whitespace
|
||||
// and superfluous attributes are ignored
|
||||
iface.getFunction("transferFrom(address, address, uint256)");
|
||||
|
||||
// By name; this ONLY works if the method is non-ambiguous
|
||||
iface.getFunction("transferFrom");
|
||||
|
||||
// By method selector
|
||||
iface.getFunction("0x23b872dd");
|
||||
|
||||
// Throws if the method does not exist
|
||||
//_throws:
|
||||
iface.getFunction("doesNotExist()");
|
||||
//_log:
|
||||
|
||||
_property: interface.getError(fragment) => [[ErrorFragment]] @SRC<abi/interface>
|
||||
Returns the [[ErrorFragment]] for //fragment// (see [[Interface--specifying-fragments]]).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const iface = _page.iface;
|
||||
|
||||
// By error signature, which is normalized so whitespace
|
||||
// and superfluous attributes are ignored
|
||||
iface.getError("AccountLocked(address, uint256)");
|
||||
|
||||
// By name; this ONLY works if the error is non-ambiguous
|
||||
iface.getError("AccountLocked");
|
||||
|
||||
// By error selector
|
||||
iface.getError("0xf7c3865a");
|
||||
|
||||
// Throws if the error does not exist
|
||||
//_throws:
|
||||
iface.getError("DoesNotExist()");
|
||||
//_log:
|
||||
|
||||
_property: interface.getEvent(fragment) => [[EventFragment]] @SRC<abi/interface>
|
||||
Returns the [[EventFragment]] for //fragment// (see [[Interface--specifying-fragments]]).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const iface = _page.iface;
|
||||
|
||||
// By event signature, which is normalized so whitespace
|
||||
// and superfluous attributes are ignored
|
||||
iface.getEvent("Transfer(address, address, uint256)");
|
||||
|
||||
// By name; this ONLY works if the event is non-ambiguous
|
||||
iface.getEvent("Transfer");
|
||||
|
||||
// By event topic hash
|
||||
iface.getEvent("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef");
|
||||
|
||||
// Throws if the event does not exist
|
||||
//_throws:
|
||||
iface.getEvent("DoesNotExist()");
|
||||
//_log:
|
||||
|
||||
_subsection: Signature and Topic Hashes @<Interface--selectors>
|
||||
|
||||
_property: interface.getSighash(fragment) => string<[[DataHexString]]<4>> @SRC<abi/interface:method.Interface.getSighash>
|
||||
Return the sighash (or Function Selector) for //fragment// (see [[Interface--specifying-fragments]]).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const iface = _page.iface;
|
||||
|
||||
//_result:
|
||||
iface.getSighash("balanceOf");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
iface.getSighash("balanceOf(address)");
|
||||
//_log:
|
||||
|
||||
const fragment = iface.getFunction("balanceOf")
|
||||
//_result:
|
||||
iface.getSighash(fragment);
|
||||
//_log:
|
||||
|
||||
_property: interface.getEventTopic(fragment) => string<[[DataHexString]]<32>> @SRC<abi/interface:method.Interface.getEventTopic>
|
||||
Return the topic hash for //fragment// (see [[Interface--specifying-fragments]]).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const iface = _page.iface;
|
||||
|
||||
//_result:
|
||||
iface.getEventTopic("Transfer");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
iface.getEventTopic("Transfer(address, address, uint)");
|
||||
//_log:
|
||||
|
||||
const fragment = iface.getEvent("Transfer")
|
||||
//_result:
|
||||
iface.getEventTopic(fragment);
|
||||
//_log:
|
||||
|
||||
_subsection: Encoding Data @<Interface--encoding>
|
||||
|
||||
@@ -74,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
|
||||
@@ -49,13 +48,72 @@ the checksum is invalid, an [INVALID_ARGUMENT](errors--invalid-argument) Error i
|
||||
|
||||
The value of //address// may be any supported address format.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const getAddress = ethers.utils.getAddress;
|
||||
|
||||
// Injects the checksum (via upper-casing specific letters)
|
||||
//_result:
|
||||
getAddress("0x8ba1f109551bd432803012645ac136ddd64dba72");
|
||||
//_log:
|
||||
|
||||
// Converts and injects the checksum
|
||||
//_result:
|
||||
getAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36");
|
||||
//_log:
|
||||
|
||||
// Throws if a checksummed address is provided, but a
|
||||
// letter is the wrong case
|
||||
// ------------v (should be lower-case)
|
||||
//_throws:
|
||||
getAddress("0x8Ba1f109551bD432803012645Ac136ddd64DBA72")
|
||||
//_log:
|
||||
|
||||
// Throws if the ICAP/IBAN checksum fails
|
||||
//_throws:
|
||||
getIcapAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK37");
|
||||
//_log:
|
||||
|
||||
// Throws if the address is invalid, in general
|
||||
//_throws:
|
||||
getIcapAddress("I like turtles!");
|
||||
//_log:
|
||||
|
||||
|
||||
_property: ethers.utils.getIcapAddress(address) => string<[IcapAddress](address-icap)> @<utils-getIcapAddress> @SRC<address>
|
||||
Returns //address// as an [ICAP address](link-icap).
|
||||
Supports the same restrictions as [getAddress](utils-getAddress).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const getIcapAddress = ethers.utils.getIcapAddress;
|
||||
|
||||
//_result:
|
||||
getIcapAddress("0x8ba1f109551bd432803012645ac136ddd64dba72");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
getIcapAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36");
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.isAddress(address) => boolean @<utils-isAddress> @SRC<address>
|
||||
Returns true if //address// is valid (in any supported format).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const isAddress = ethers.utils.isAddress;
|
||||
|
||||
//_result:
|
||||
isAddress("0x8ba1f109551bd432803012645ac136ddd64dba72");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
isAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
isAddress("I like turtles.");
|
||||
//_log:
|
||||
|
||||
_subsection: Derivation @<utils--address-derivation>
|
||||
|
||||
@@ -64,10 +122,49 @@ Returns the address for //publicOrPrivateKey//. A public key may be
|
||||
compressed or uncompressed, and a private key will be converted
|
||||
automatically to a public key for the derivation.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const computeAddress = ethers.utils.computeAddress;
|
||||
|
||||
// Private Key
|
||||
//_result:
|
||||
computeAddress("0xb976778317b23a1385ec2d483eda6904d9319135b89f1d8eee9f6d2593e2665d");
|
||||
//_log:
|
||||
|
||||
// Public Key (compressed)
|
||||
//_result:
|
||||
computeAddress("0x0376698beebe8ee5c74d8cc50ab84ac301ee8f10af6f28d0ffd6adf4d6d3b9b762");
|
||||
//_log:
|
||||
|
||||
// Public Key (uncompressed)
|
||||
//_result:
|
||||
computeAddress("0x0476698beebe8ee5c74d8cc50ab84ac301ee8f10af6f28d0ffd6adf4d6d3b9b762d46ca56d3dad2ce13213a6f42278dabbb53259f2d92681ea6a0b98197a719be3");
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.recoverAddress(digest, signature) => string<[[address]]> @<utils-recoverAddress> @SRC<transactions>
|
||||
Use [[link-wiki-ecrecover]] to determine the address that signed //digest// to
|
||||
which generated //signature//.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const recoverAddress = ethers.utils.recoverAddress;
|
||||
|
||||
const digest = "0x7c5ea36004851c764c44143b1dcb59679b11c9a68e5f41497f6cf3d480715331";
|
||||
|
||||
// Using an expanded Signature
|
||||
//_result:
|
||||
recoverAddress(digest, {
|
||||
r: "0x528459e4aec8934dc2ee94c4f3265cf6ce00d47cf42bb106afda3642c72e25eb",
|
||||
s: "0x42544137118256121502784e5a6425e6183ca964421ecd577db6c66ba9bccdcf",
|
||||
v: 27
|
||||
});
|
||||
//_log:
|
||||
|
||||
// Using a flat Signature
|
||||
const signature = "0x528459e4aec8934dc2ee94c4f3265cf6ce00d47cf42bb106afda3642c72e25eb42544137118256121502784e5a6425e6183ca964421ecd577db6c66ba9bccdcf1b";
|
||||
//_result:
|
||||
recoverAddress(digest, signature);
|
||||
//_log:
|
||||
|
||||
_subsection: Contracts Addresses @<utils--contract-addresses>
|
||||
|
||||
@@ -75,9 +172,33 @@ _property: ethers.utils.getContractAddress(transaction) => string<[[address]]>
|
||||
Returns the contract address that would result if //transaction// was
|
||||
used to deploy a contract.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const getContractAddress = ethers.utils.getContractAddress;
|
||||
|
||||
const from = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
|
||||
const nonce = 5;
|
||||
|
||||
//_result:
|
||||
getContractAddress({ from, nonce });
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.getCreate2Address(from, salt, initCodeHash) => string<[[address]]> @<utils-getCreate2Address> @SRC<address>
|
||||
Returns the contract address that would result from the given
|
||||
[CREATE2](link-eip-1014) call.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const getCreate2Address = ethers.utils.getCreate2Address;
|
||||
//_hide: const keccak256 = ethers.utils.keccak256;
|
||||
|
||||
const from = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
|
||||
const salt = "0x7c5ea36004851c764c44143b1dcb59679b11c9a68e5f41497f6cf3d480715331";
|
||||
const initCode = "0x6394198df16000526103ff60206004601c335afa6040516060f3";
|
||||
const initCodeHash = keccak256(initCode);
|
||||
|
||||
//_result:
|
||||
getCreate2Address(from, salt, initCodeHash);
|
||||
//_log:
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
_section: BigNumber @<BigNumber>
|
||||
|
||||
Many operations in Ethereum operation on numbers which are
|
||||
Many operations in Ethereum operate on numbers which are
|
||||
[outside the range of safe values](BigNumber--notes-safenumbers) to use
|
||||
in JavaScript.
|
||||
|
||||
@@ -49,43 +49,52 @@ _heading: Examples: @<>
|
||||
_code: @lang<javascript>
|
||||
|
||||
// From a decimal string...
|
||||
//_result:
|
||||
BigNumber.from("42")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From a HexString...
|
||||
//_result:
|
||||
BigNumber.from("0x2a")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From a negative HexString...
|
||||
//_result:
|
||||
BigNumber.from("-0x2a")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From an Array (or Uint8Array)...
|
||||
//_result:
|
||||
BigNumber.from([ 42 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From an existing BigNumber...
|
||||
let one1 = constants.One;
|
||||
let one2 = BigNumber.from(one1)
|
||||
|
||||
//_result:
|
||||
one2
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// ...which returns the same instance
|
||||
//_result:
|
||||
one1 === one2
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From a (safe) number...
|
||||
//_result:
|
||||
BigNumber.from(42)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// From a ES2015 BigInt... (only on platforms with BigInt support)
|
||||
//_result:
|
||||
BigNumber.from(42n)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Numbers outside the safe range fail:
|
||||
//_throws:
|
||||
BigNumber.from(Number.MAX_SAFE_INTEGER);
|
||||
//! error
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Methods @<BigNumber--methods>
|
||||
@@ -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 [JavScript 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:
|
||||
|
||||
|
||||
@@ -86,28 +86,34 @@ zeros.
|
||||
_code: Examples @lang<javascript>
|
||||
|
||||
// Convert a hexstring to a Uint8Array
|
||||
//_result:
|
||||
arrayify("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Convert an Array to a hexstring
|
||||
//_result:
|
||||
hexlify([1, 2, 3, 4])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Convert an Object to a hexstring
|
||||
//_result:
|
||||
hexlify({ length: 2, "0": 1, "1": 2 })
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Convert an Array to a hexstring
|
||||
//_result:
|
||||
hexlify([ 1 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Convert a number to a stripped hex value
|
||||
//_result:
|
||||
hexValue(1)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Convert an Array to a stripped hex value
|
||||
//_result:
|
||||
hexValue([ 1, 2 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Array Manipulation
|
||||
@@ -170,15 +176,18 @@ Return a copy of //array// shuffled using [[link-wiki-shuffle]].
|
||||
|
||||
_code: Examples @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.randomBytes(8)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
const data = [ 1, 2, 3, 4, 5, 6, 7 ];
|
||||
|
||||
// Returns a new Array
|
||||
//_result:
|
||||
utils.shuffled(data);
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// The Original is unscathed...
|
||||
//_result:
|
||||
data
|
||||
//!
|
||||
//_log:
|
||||
|
||||
@@ -53,6 +53,13 @@ _heading: Formatting @<display-logic--formatting>
|
||||
_property: ethers.utils.commify(value) => string @<utils-commify> @SRC<units>
|
||||
Returns a string with value grouped by 3 digits, separated by ``,``.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const commify = ethers.utils.commify;
|
||||
|
||||
//_result:
|
||||
commify("-1000.3000");
|
||||
//_log:
|
||||
|
||||
_heading: Conversion @<unit-conversion>
|
||||
|
||||
@@ -60,13 +67,88 @@ _property: ethers.utils.formatUnits(value [ , unit = "ether" ] ) => string @<ut
|
||||
Returns a string representation of //value// formatted with //unit//
|
||||
digits (if it is a number) or to the unit specified (if a string).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const formatUnits = ethers.utils.formatUnits;
|
||||
//_hide: const BigNumber = ethers.BigNumber;
|
||||
|
||||
const oneGwei = BigNumber.from("1000000000");
|
||||
const oneEther = BigNumber.from("1000000000000000000");
|
||||
|
||||
//_result:
|
||||
formatUnits(oneGwei, 0);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
formatUnits(oneGwei, "gwei");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
formatUnits(oneGwei, 9);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
formatUnits(oneEther);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
formatUnits(oneEther, 18);
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.formatEther(value) => string @<utils-formatEther> @SRC<units>
|
||||
The equivalent to calling ``formatUnits(value, "ether")``.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const formatEther = ethers.utils.formatEther;
|
||||
//_hide: const BigNumber = ethers.BigNumber;
|
||||
|
||||
const value = BigNumber.from("1000000000000000000");
|
||||
|
||||
//_result:
|
||||
formatEther(value);
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.parseUnits(value [ , unit = "ether" ] ) => [BigNumber](BigNumber) @<utils-parseUnits> @SRC<units>
|
||||
Returns a [BigNumber](BigNumber) representation of //value//, parsed with
|
||||
//unit// digits (if it is a number) or from the unit specified (if
|
||||
a string).
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const parseUnits = ethers.utils.parseUnits;
|
||||
|
||||
//_result:
|
||||
parseUnits("1.0");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
parseUnits("1.0", "ether");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
parseUnits("1.0", 18);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
parseUnits("121.0", "gwei");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
parseUnits("121.0", 9);
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.parseEther(value) => [BigNumber](BigNumber) @<utils-parseEther> @SRC<units>
|
||||
The equivalent to calling ``parseUnits(value, "ether")``.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const parseEther = ethers.utils.parseEther;
|
||||
|
||||
//_result:
|
||||
parseEther("1.0");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
parseEther("-0.5");
|
||||
//_log:
|
||||
|
||||
@@ -2,23 +2,63 @@ _section: Encoding Utilities @<encoding>
|
||||
|
||||
_subsection: Base58 @<Bse58> @SRC<basex:Base58>
|
||||
|
||||
_property: ethers.utils.base58.decode(textData) => Uin8Array
|
||||
_property: ethers.utils.base58.decode(textData) => Uint8Array
|
||||
Return a typed Uint8Array representation of //textData// decoded using
|
||||
base-58 encoding.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const base58 = ethers.utils.base58;
|
||||
|
||||
//_result:
|
||||
base58.decode("TzMhH");
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.base58.encode(aBytesLike) => string
|
||||
Return //aBytesLike// encoded as a string using the base-58 encoding.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const base58 = ethers.utils.base58;
|
||||
|
||||
//_result:
|
||||
base58.encode("0x12345678");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
base58.encode([ 0x12, 0x34, 0x56, 0x78 ]);
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Base64 @<Base64>
|
||||
|
||||
_property: ethers.utils.base64.decode(textData) => Uin8Array @SRC<base64>
|
||||
_property: ethers.utils.base64.decode(textData) => Uint8Array @SRC<base64>
|
||||
Return a typed Uint8Array representation of //textData// decoded using
|
||||
base-64 encoding.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const base64 = ethers.utils.base64;
|
||||
|
||||
//_result:
|
||||
base64.decode("EjQ=");
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.base64.encode(aBytesLike) => string @SRC<base64>
|
||||
Return //aBytesLike// encoded as a string using the base-64 encoding.
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const base64 = ethers.utils.base64;
|
||||
|
||||
//_result:
|
||||
base64.encode("0x1234");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
base64.encode([ 0x12, 0x34 ]);
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Recursive-Length Prefix @<rlp--methods>
|
||||
|
||||
@@ -26,15 +66,53 @@ The [[link-rlp]] encoding is used throughout Ethereum to serialize nested
|
||||
structures of Arrays and data.
|
||||
|
||||
_property: ethers.utils.RLP.encode(dataObject) => string<[[DataHexString]]> @<utils-rlpEncode> @SRC<rlp>
|
||||
Encode a structured Data Object into its RLP-encoded representation.
|
||||
Encode a structured [Data Object](rlp--dataobject) into its RLP-encoded representation.
|
||||
|
||||
Each Data component may be a valid [[BytesLike]].
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const RLP = ethers.utils.RLP;
|
||||
|
||||
//_result:
|
||||
RLP.encode("0x12345678");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.encode([ "0x12345678" ]);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.encode([ new Uint8Array([ 0x12, 0x34, 0x56, 0x78 ]) ]);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.encode([ [ "0x42", [ "0x43" ] ], "0x12345678", [ ] ]);
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.encode([ ]);
|
||||
//_log:
|
||||
|
||||
_property: ethers.utils.RLP.decode(aBytesLike) => [DataObject](rlp--dataobject) @<utils.rlpDecode> @SRC<rlp>
|
||||
Decode an RLP-encoded //aBytesLike// into its structured Data Object.
|
||||
Decode an RLP-encoded //aBytesLike// into its structured [Data Object](rlp--dataobject).
|
||||
|
||||
All Data components will be returned as a [[DataHexString]].
|
||||
|
||||
_code: @lang<javascript>
|
||||
|
||||
//_hide: const RLP = ethers.utils.RLP;
|
||||
|
||||
//_result:
|
||||
RLP.decode("0x8412345678");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.decode("0xcac342c1438412345678c0");
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
RLP.decode("0xc0");
|
||||
//_log:
|
||||
|
||||
_heading: Data Object @<rlp--dataobject>
|
||||
|
||||
A **Data Object** is a recursive structure which is used to serialize many
|
||||
|
||||
@@ -27,14 +27,17 @@ Returns the [SHA2-512](link-wiki-sha2) digest of //aBytesLike//.
|
||||
|
||||
_code: KECCAK256 @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.keccak256([ 0x12, 0x34 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.keccak256("0x")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.keccak256("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// The value MUST be data, such as:
|
||||
// - an Array of numbers
|
||||
@@ -42,16 +45,19 @@ utils.keccak256("0x1234")
|
||||
// - a Uint8Array
|
||||
|
||||
// Do NOT use UTF-8 strings that are not a DataHexstring
|
||||
//_throws:
|
||||
utils.keccak256("hello world")
|
||||
//! error
|
||||
//_log:
|
||||
|
||||
// If needed, convert strings to bytes first:
|
||||
//_result:
|
||||
utils.keccak256(utils.toUtf8Bytes("hello world"))
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Or equivalently use the identity function:
|
||||
//_result:
|
||||
utils.id("hello world")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Keep in mind that the string "0x1234" represents TWO
|
||||
// bytes (i.e. [ 0x12, 0x34 ]. If you wish to compute the
|
||||
@@ -61,48 +67,56 @@ utils.id("hello world")
|
||||
// Consider the following examples:
|
||||
|
||||
// Hash of TWO (2) bytes:
|
||||
//_result:
|
||||
utils.keccak256("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Hash of TWO (2) bytes: (same result)
|
||||
//_result:
|
||||
utils.keccak256([ 0x12, 0x34 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
const bytes = utils.toUtf8Bytes("0x1234")
|
||||
// <hide>
|
||||
bytes
|
||||
// </hide>
|
||||
//!
|
||||
//_result:
|
||||
bytes = utils.toUtf8Bytes("0x1234")
|
||||
//_log:
|
||||
|
||||
// Hash of SIX (6) characters (different than above)
|
||||
//_result:
|
||||
utils.keccak256(bytes)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Hash of SIX (6) characters (same result)
|
||||
//_result:
|
||||
utils.id("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
_code: RIPEMD160 @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.ripemd160("0x")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.ripemd160("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
_code: SHA-2 @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.sha256("0x")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.sha256("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.sha512("0x")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.sha512("0x1234")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: HMAC @<utils--hmac>
|
||||
@@ -123,8 +137,9 @@ _code: HMAC @lang<javascript>
|
||||
|
||||
const key = "0x0102"
|
||||
const data = "0x1234"
|
||||
//_result:
|
||||
utils.computeHmac("sha256", key, data)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Hashing Helpers @<utils--hashing-helpers>
|
||||
@@ -137,12 +152,14 @@ and the length of //message//.
|
||||
_code: Hashing Messages @lang<javascript>
|
||||
|
||||
// Hashing a string message
|
||||
//_result:
|
||||
utils.hashMessage("Hello World")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Hashing binary data (also "Hello World", but as bytes)
|
||||
//_result:
|
||||
utils.hashMessage( [ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// NOTE: It is important to understand how strings and binary
|
||||
// data is handled differently. A string is ALWAYS processed
|
||||
@@ -151,18 +168,21 @@ utils.hashMessage( [ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 ])
|
||||
|
||||
// Hashing a hex string is the same as hashing a STRING
|
||||
// Note: this is the hash of the 4 characters [ '0', 'x', '4', '2' ]
|
||||
//_result:
|
||||
utils.hashMessage("0x42")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Hashing the binary data
|
||||
// Note: this is the hash of the 1 byte [ 0x42 ]
|
||||
//_result:
|
||||
utils.hashMessage([ 0x42 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// Hashing the binary data
|
||||
// Note: similarly, this is the hash of the 1 byte [ 0x42 ]
|
||||
//_result:
|
||||
utils.hashMessage(utils.arrayify("0x42"))
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_property: ethers.utils.namehash(name) => string<[[DataHexString]]<32>> @<utils-namehash> @SRC<hash>
|
||||
@@ -170,17 +190,21 @@ Returns the [ENS Namehash](link-namehash) of //name//.
|
||||
|
||||
_code: Namehash @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.namehash("")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.namehash("eth")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.namehash("ricmoo.firefly.eth")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.namehash("ricmoo.xyz")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
_heading: Typed Data Encoder @<TypedDataEncoder> @SRC<hash:class.TypedDataEncoder>
|
||||
|
||||
@@ -244,19 +268,17 @@ been recursively replacedwith the value of calling //resolveName// with that val
|
||||
|
||||
_code: Typed Data Example @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
TypedDataEncoder = ethers.utils._TypedDataEncoder
|
||||
// </hide>
|
||||
//_hide: TypedDataEncoder = ethers.utils._TypedDataEncoder
|
||||
|
||||
const domain = {
|
||||
domain = {
|
||||
name: 'Ether Mail',
|
||||
version: '1',
|
||||
chainId: 1,
|
||||
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
|
||||
}
|
||||
};
|
||||
|
||||
// The named list of all type definitions
|
||||
const types = {
|
||||
types = {
|
||||
Person: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'wallet', type: 'address' }
|
||||
@@ -266,10 +288,10 @@ const types = {
|
||||
{ name: 'to', type: 'Person' },
|
||||
{ name: 'contents', type: 'string' }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// The data to sign
|
||||
const value = {
|
||||
value = {
|
||||
from: {
|
||||
name: 'Cow',
|
||||
wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826'
|
||||
@@ -279,23 +301,27 @@ const value = {
|
||||
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'
|
||||
},
|
||||
contents: 'Hello, Bob!'
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//_result:
|
||||
TypedDataEncoder.encode(domain, types, value)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
TypedDataEncoder.getPayload(domain, types, value)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
TypedDataEncoder.getPrimaryType(types)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
TypedDataEncoder.hash(domain, types, value)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
TypedDataEncoder.hashDomain(domain)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Solidity Hashing Algorithms @<utils--solidity-hashing>
|
||||
@@ -318,17 +344,21 @@ according to their respective type in //types//.
|
||||
|
||||
_code: Solidity Hashing @lang<javascript>
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "int16", "uint48" ], [ -1, 12 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "string", "uint8" ], [ "Hello", 3 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.solidityKeccak256([ "int16", "uint48" ], [ -1, 12 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.soliditySha256([ "int16", "uint48" ], [ -1, 12 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// As a short example of the non-distinguished nature of
|
||||
// Solidity tight-packing (which is why it is inappropriate
|
||||
@@ -336,14 +366,18 @@ utils.soliditySha256([ "int16", "uint48" ], [ -1, 12 ])
|
||||
// the following examples are all equal, despite representing
|
||||
// very different values and layouts.
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "string", "string" ], [ "hello", "world01" ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "string", "string" ], [ "helloworld", "01" ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "string", "string", "uint16" ], [ "hell", "oworld", 0x3031 ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
//_result:
|
||||
utils.solidityPack([ "uint96" ], [ "32309054545061485574011236401" ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
@@ -216,6 +216,22 @@ it deals with unmined transactions, and can be configured by each node, however
|
||||
to ensure a transaction is propagated to a miner it is best practice to follow
|
||||
the defaults most nodes have enabled.
|
||||
|
||||
_property: Logger.errors.TRANSACTION_REPLACED @<errors--transaction-replaced>
|
||||
When a transaction has been replaced by the user, by broadcasting a new transaction
|
||||
with the same nonce as an existing in-flight (unmined) transaction in the mempool,
|
||||
this error will occur while waiting if the transaction being waited for has become
|
||||
invalidated by that other transaction.
|
||||
|
||||
This can happen for several reasons, but most commonly because the user has increased
|
||||
the gas price (which changes the transaction hash) to "speed up" a transaction or if
|
||||
a user has "cancelled" the transaction in their client. In either case this is
|
||||
usually accomplished by bribing the miners with a higher gas priced transaction.
|
||||
|
||||
This error will have the additional properties, ``cancelled``, ``hash``, ``reason``,
|
||||
``receipt`` and ``replacement``.
|
||||
|
||||
See the [[providers-TransactionResponse]] for the ``wait`` method for more details.
|
||||
|
||||
_property: Logger.errors.UNPREDICTABLE_GAS_LIMIT @<errors--unpredicatable-gas-limit>
|
||||
When estimating the required amount of gas for a transaction, a node is queried for
|
||||
its best guess.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -57,13 +57,11 @@ $TopicABaCD: **[** (topic[0] = A) **OR** (topic[0] = B) **]** **AND**
|
||||
|
||||
_code: ERC-20 Transfer Filter Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const tokenAddress = ethers.constants.AddressZero;
|
||||
const myAddress = ethers.constants.AddressZero;
|
||||
const myOtherAddress = ethers.constants.AddressZero;
|
||||
const id = ethers.utils.id;
|
||||
const hexZeroPad = ethers.utils.hexZeroPad;
|
||||
// </hide>
|
||||
//_hide: const tokenAddress = ethers.constants.AddressZero;
|
||||
//_hide: const myAddress = ethers.constants.AddressZero;
|
||||
//_hide: const myOtherAddress = ethers.constants.AddressZero;
|
||||
//_hide: const id = ethers.utils.id;
|
||||
//_hide: const hexZeroPad = ethers.utils.hexZeroPad;
|
||||
|
||||
// Short example of manually creating filters for an ERC-20
|
||||
// Transfer event.
|
||||
@@ -96,7 +94,7 @@ filter = {
|
||||
id("Transfer(address,address,uint256)"),
|
||||
hexZeroPad(myAddress, 32)
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// List all token transfers *to* myAddress:
|
||||
filter = {
|
||||
@@ -106,7 +104,7 @@ filter = {
|
||||
null,
|
||||
hexZeroPad(myAddress, 32)
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// List all token transfers *to* myAddress or myOtherAddress:
|
||||
filter = {
|
||||
@@ -119,7 +117,7 @@ filter = {
|
||||
hexZeroPad(myOtherAddress, 32),
|
||||
]
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
_null:
|
||||
|
||||
@@ -128,35 +126,37 @@ To simplify life, ..., explain here, the contract API
|
||||
|
||||
_code: ERC-20 Contract Filter Examples @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const tokenAddress = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; // DAI
|
||||
const myAddress = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
|
||||
const otherAddress = "0xEA517D5a070e6705Cc5467858681Ed953d285Eb9";
|
||||
const provider = ethers.getDefaultProvider();
|
||||
const Contract = ethers.Contract;
|
||||
// </hide>
|
||||
//_hide: const tokenAddress = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; /* DAI */
|
||||
//_hide: const myAddress = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
|
||||
//_hide: const otherAddress = "0xEA517D5a070e6705Cc5467858681Ed953d285Eb9";
|
||||
//_hide: const provider = ethers.getDefaultProvider();
|
||||
//_hide: const Contract = ethers.Contract;
|
||||
|
||||
const abi = [
|
||||
abi = [
|
||||
"event Transfer(address indexed src, address indexed dst, uint val)"
|
||||
];
|
||||
|
||||
const contract = new Contract(tokenAddress, abi, provider);
|
||||
contract = new Contract(tokenAddress, abi, provider);
|
||||
|
||||
// List all token transfers *from* myAddress
|
||||
//_result:
|
||||
contract.filters.Transfer(myAddress)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// List all token transfers *to* myAddress:
|
||||
//_result:
|
||||
contract.filters.Transfer(null, myAddress)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// List all token transfers *from* myAddress *to* otherAddress:
|
||||
//_result:
|
||||
contract.filters.Transfer(myAddress, otherAddress)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// List all token transfers *to* myAddress OR otherAddress:
|
||||
//_result:
|
||||
contract.filters.Transfer(null, [ myAddress, otherAddress ])
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_subsection: Solidity Topics @<events-solidity>
|
||||
|
||||
@@ -1,5 +1,82 @@
|
||||
_section: Security @<security>
|
||||
|
||||
While security should be a concern for all developers, in the
|
||||
blockchain space developers must be additionally conscious of
|
||||
many areas which can be exploited.
|
||||
|
||||
Once a problem has an economic incentives to exploit it, there
|
||||
is a much larger risk and with blockchain apps it can become
|
||||
quite valuable to attack.
|
||||
|
||||
In addition to many of the other security issues app developers
|
||||
may have to worry about, there are a few additional vectors
|
||||
that JavaScript developers should be aware of.
|
||||
|
||||
_subsection: Side-Channel Attacks
|
||||
|
||||
A [Side-Channel Attack](link-wiki-side-channel-attack) occurs
|
||||
when something orthogonal to the implementation of the algorithm
|
||||
used can be exploited to learn more about secure or private
|
||||
information.
|
||||
|
||||
_heading: Released Data (Strings, Uint8Arrays, Buffers)
|
||||
|
||||
In JavaScript, memory may not be securely allocated, or more
|
||||
importantly securely released.
|
||||
|
||||
[Historically](https://github.com/nodejs/node/issues/4660),
|
||||
``new Buffer(16)`` would re-use old memory that had been
|
||||
released. This would mean that code runnint later, may have
|
||||
access to data that was discarded.
|
||||
|
||||
As an example of the dangers, imagine if you had used a Buffer
|
||||
to store a private key, signed data and then returned from the
|
||||
function, allowing the Buffer to be de-allocated. A future
|
||||
function may be able to request a new Buffer, which would still
|
||||
have that left-over private key, which it could then use to
|
||||
steal the funds from that account.
|
||||
|
||||
There are also many debugging tools and systems designed to
|
||||
assist develoeprs inspect the memory contents of JavaScript
|
||||
programs. In these cases, any //private key// or //mnemonic//
|
||||
siiting in memory may be visible to other users on the system,
|
||||
or malicious scripts.
|
||||
|
||||
_heading: Timing Attack
|
||||
|
||||
Timing attacks allow a malicious user or script to determine
|
||||
private data through analysing how long an operation requires
|
||||
to execute.
|
||||
|
||||
In JavaScript, //Garbage Collection// occurs periodically when the
|
||||
system determines it is required. Each JavaScript implementation
|
||||
is different, with a variety of strategies and and abilities.
|
||||
|
||||
Most Garbage Collection requires "stopping the world", or pausing
|
||||
all code being executed while it runs. This adds a large delay
|
||||
to any code that was currently running.
|
||||
|
||||
This can be exploited by attackers to "condition cause a delay".
|
||||
They will set up a scenario where the system is on the edge of
|
||||
needing to garbage collect, and call your code with two paths,
|
||||
a simple path and complex path. The simple path won't stir things
|
||||
up enough to cause a garbage collection, while the complex one
|
||||
will. By timing how long the code took to execute, they now know
|
||||
whether garbage collection occured and therefore whether the simple
|
||||
or complex path was taken.
|
||||
|
||||
Advancced timing attacks are very difficult to mitigate in any
|
||||
garbage-collection-based language. Most libraries where this
|
||||
matters will hopefully mitigated this for you as much as possible,
|
||||
but it is still good to be aware of.
|
||||
|
||||
_heading: General Concerns
|
||||
|
||||
- [Cross-Site Scripting](link-wiki-xss)
|
||||
- [Cross-Site Request Forgery](link-wiki-csrf)
|
||||
- [Phishing](link-wiki-phishing)
|
||||
|
||||
|
||||
_subsection: Key Derivation Functions @<security--pbkdf>
|
||||
|
||||
This is not specific to Ethereum, but is a useful technique
|
||||
|
||||
@@ -117,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;
|
||||
@@ -133,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,
|
||||
@@ -156,12 +183,26 @@ 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.2",
|
||||
subtitle: "v5.4",
|
||||
description: "Documentation for ethers, a complete, tiny and simple Ethereum library.",
|
||||
logo: "logo.svg",
|
||||
|
||||
@@ -196,7 +237,7 @@ 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" },
|
||||
@@ -258,6 +299,7 @@ module.exports = {
|
||||
"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" },
|
||||
@@ -292,12 +334,14 @@ module.exports = {
|
||||
"link-wiki-bloomfilter": { name: "Bloom Filter", url: "https:/\/en.wikipedia.org/wiki/Bloom_filter" },
|
||||
"link-wiki-bruteforce": "https:/\/en.wikipedia.org/wiki/Brute-force_attack",
|
||||
"link-wiki-cryptographichash": "https:/\/en.wikipedia.org/wiki/Cryptographic_hash_function",
|
||||
"link-wiki-csrf": "https:/\/en.wikipedia.org/wiki/Cross-site_request_forgery",
|
||||
"link-wiki-ecrecover": { name: "ECDSA Public Key Recovery", url: "https:/\/en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Public_key_recovery" },
|
||||
"link-wiki-homoglyph": "https:/\/en.wikipedia.org/wiki/IDN_homograph_attack",
|
||||
"link-wiki-hmac": "https:/\/en.wikipedia.org/wiki/HMAC",
|
||||
"link-wiki-iban": "https:/\/en.wikipedia.org/wiki/International_Bank_Account_Number",
|
||||
"link-wiki-ieee754": "https:/\/en.wikipedia.org/wiki/Double-precision_floating-point_format",
|
||||
"link-wiki-observer-pattern": { name: "Obeserver Pattern", url: "https:/\/en.wikipedia.org/wiki/Observer_pattern" },
|
||||
"link-wiki-phishing": "https:/\/en.wikipedia.org/wiki/Phishing",
|
||||
"link-wiki-ripemd": "https:/\/en.m.wikipedia.org/wiki/RIPEMD",
|
||||
"link-wiki-sha2": "https:/\/en.wikipedia.org/wiki/SHA-2",
|
||||
"link-wiki-twoscomplement": "https:/\/en.wikipedia.org/wiki/Two%27s_complement",
|
||||
@@ -305,9 +349,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",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -6,4 +6,5 @@ snippets of code that are in general useful.
|
||||
_toc:
|
||||
|
||||
react-native
|
||||
transactions
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -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,13 @@ 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
|
||||
// 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()
|
||||
@@ -123,22 +123,26 @@ logs, look up deployed code and so on.
|
||||
_code: Basic Queries @lang<javascript>
|
||||
|
||||
// Look up the current block number
|
||||
provider.getBlockNumber()
|
||||
//!
|
||||
//_result:
|
||||
await provider.getBlockNumber()
|
||||
//_log:
|
||||
|
||||
// Get the balance of an account (by address or ENS name, if supported by network)
|
||||
//_result:
|
||||
balance = await provider.getBalance("ethers.eth")
|
||||
//! async balance
|
||||
//_log:
|
||||
|
||||
// Often you need to format the output to something more user-friendly,
|
||||
// such as in ether (instead of wei)
|
||||
//_result:
|
||||
ethers.utils.formatEther(balance)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
// If a user enters a string in an input field, you may need
|
||||
// to convert it from ether (as a string) to wei (as a BigNumber)
|
||||
//_result:
|
||||
ethers.utils.parseEther("1.0")
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_heading: Writing to the Blockchain @<getting-started--sending>
|
||||
@@ -204,38 +208,33 @@ const daiAbi = [
|
||||
// The Contract object
|
||||
const daiContract = new ethers.Contract(daiAddress, daiAbi, provider);
|
||||
|
||||
//_hide: _page.daiAbi = daiAbi;
|
||||
//_hide: _page.daiContract = daiContract;
|
||||
|
||||
_heading: Read-Only Methods @<getting-started--reading>
|
||||
|
||||
_code: Querying the DAI Contract @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const daiAbi = [
|
||||
// Some simple details about the token
|
||||
"function name() view returns (string)",
|
||||
"function symbol() view returns (string)",
|
||||
|
||||
// Get the account balance
|
||||
"function balanceOf(address) view returns (uint)",
|
||||
];
|
||||
const daiContract = new ethers.Contract("dai.tokens.ethers.eth", daiAbi, provider);
|
||||
// </hide>
|
||||
//_hide: const daiContract = _page.daiContract;
|
||||
|
||||
// Get the ERC-20 token name
|
||||
daiContract.name()
|
||||
//!
|
||||
//_result:
|
||||
await daiContract.name()
|
||||
//_log:
|
||||
|
||||
// Get the ERC-20 token symbol (for tickers and UIs)
|
||||
daiContract.symbol()
|
||||
//!
|
||||
//_result:
|
||||
await daiContract.symbol()
|
||||
//_log:
|
||||
|
||||
// Get the balance of an address
|
||||
balance = await daiContract.balanceOf("ricmoo.firefly.eth")
|
||||
//! async balance
|
||||
//_log: balance
|
||||
|
||||
// Format the DAI for displaying to the user
|
||||
//_result:
|
||||
ethers.utils.formatUnits(balance, 18)
|
||||
//!
|
||||
//_log:
|
||||
|
||||
|
||||
_heading: State Changing Methods @<getting-started--writing>
|
||||
@@ -258,13 +257,8 @@ _heading: Listening to Events @<getting-started--events>
|
||||
|
||||
_code: Listening to Events @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const daiAbi = [
|
||||
"event Transfer(address indexed, address indexed, uint256)"
|
||||
];
|
||||
const daiContract = new ethers.Contract("dai.tokens.ethers.eth", daiAbi, provider);
|
||||
const formatEther = ethers.utils.formatEther;
|
||||
// </hide>
|
||||
//_hide: const daiContract = _page.daiContract;
|
||||
//_hide: const formatEther = ethers.utils.formatEther;
|
||||
|
||||
// Receive an event when ANY transfer occurs
|
||||
daiContract.on("Transfer", (from, to, amount, event) => {
|
||||
@@ -277,10 +271,7 @@ daiContract.on("Transfer", (from, to, amount, event) => {
|
||||
// A filter for when a specific address receives tokens
|
||||
myAddress = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
|
||||
filter = daiContract.filters.Transfer(null, myAddress)
|
||||
// <hide>
|
||||
filter
|
||||
// </hide>
|
||||
//!
|
||||
//_log: filter
|
||||
|
||||
// Receive an event when that filter occurs
|
||||
daiContract.on(filter, (from, to, amount, event) => {
|
||||
@@ -288,46 +279,32 @@ daiContract.on(filter, (from, to, amount, event) => {
|
||||
console.log(`I got ${ formatEther(amount) } from ${ from }.`);
|
||||
});
|
||||
|
||||
// <hide>
|
||||
// Don't want to block the docs from compiling...
|
||||
daiContract.removeAllListeners();
|
||||
// </hide>
|
||||
//_hide: daiContract.removeAllListeners(); /* Don't want to block the docs from compiling... */
|
||||
|
||||
|
||||
_heading: Query Historic Events @<getting-started--history>
|
||||
|
||||
_code: Filtering Historic Events @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const signer = new ethers.VoidSigner("0x8ba1f109551bD432803012645Ac136ddd64DBA72");
|
||||
const daiAbi = [
|
||||
"event Transfer(address indexed, address indexed, uint256)"
|
||||
];
|
||||
const daiContract = new ethers.Contract("dai.tokens.ethers.eth", daiAbi, provider);
|
||||
//!
|
||||
// </hide>
|
||||
//_hide: const signer = new ethers.VoidSigner("0x8ba1f109551bD432803012645Ac136ddd64DBA72");
|
||||
//_hide: const daiContract = _page.daiContract;
|
||||
|
||||
// Get the address of the Signer
|
||||
myAddress = await signer.getAddress()
|
||||
//! async myAddress
|
||||
//_log: myAddress
|
||||
|
||||
// Filter for all token transfers from me
|
||||
filterFrom = daiContract.filters.Transfer(myAddress, null);
|
||||
// <hide>
|
||||
filterFrom
|
||||
// </hide>
|
||||
//!
|
||||
//_log: filterFrom
|
||||
|
||||
// Filter for all token transfers to me
|
||||
filterTo = daiContract.filters.Transfer(null, myAddress);
|
||||
// <hide>
|
||||
filterTo
|
||||
// </hide>
|
||||
//!
|
||||
//_log: filterTo
|
||||
|
||||
// List all transfers sent from me a specific block range
|
||||
daiContract.queryFilter(filterFrom, 9843470, 9843480)
|
||||
//!
|
||||
//_result:
|
||||
await daiContract.queryFilter(filterFrom, 9843470, 9843480)
|
||||
//_log:
|
||||
|
||||
//
|
||||
// The following have had the results omitted due to the
|
||||
@@ -335,26 +312,22 @@ daiContract.queryFilter(filterFrom, 9843470, 9843480)
|
||||
//
|
||||
|
||||
// List all transfers sent in the last 10,000 blocks
|
||||
daiContract.queryFilter(filterFrom, -10000)
|
||||
await daiContract.queryFilter(filterFrom, -10000)
|
||||
|
||||
// List all transfers ever sent to me
|
||||
daiContract.queryFilter(filterTo)
|
||||
|
||||
await daiContract.queryFilter(filterTo)
|
||||
|
||||
_subsection: Signing Messages @<getting-started--signing>
|
||||
|
||||
_code: Signing Messages @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const signer = ethers.Wallet.createRandom();
|
||||
//!
|
||||
// </hide>
|
||||
//_hide: const signer = ethers.Wallet.createRandom();
|
||||
|
||||
// To sign a simple string, which are used for
|
||||
// logging into a service, such as CryptoKitties,
|
||||
// pass the string in.
|
||||
signature = await signer.signMessage("Hello World");
|
||||
//! async signature
|
||||
//_log: signature
|
||||
|
||||
//
|
||||
// A common case is also signing a hash, which is 32
|
||||
@@ -367,8 +340,8 @@ message = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
|
||||
|
||||
// This array representation is 32 bytes long
|
||||
messageBytes = ethers.utils.arrayify(message);
|
||||
//!
|
||||
//_log: messageBytes
|
||||
|
||||
// To sign a hash, you most often want to sign the bytes
|
||||
signature = await signer.signMessage(messageBytes)
|
||||
//! async signature
|
||||
//_log: signature
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -14,4 +14,4 @@ _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.
|
||||
|
||||
- No links yet; send me some
|
||||
- [Alchemy - How to Mint an NFT](https://docs.alchemy.com/alchemy/tutorials/how-to-create-an-nft/how-to-mint-an-nft-with-ethers)
|
||||
|
||||
@@ -5,23 +5,23 @@ const path_1 = require("./path");
|
||||
const utils_1 = require("./utils");
|
||||
function setupConfig(outDir, moduleType, targetType) {
|
||||
// Configure the tsconfit.package.json...
|
||||
const path = path_1.resolve("tsconfig.package.json");
|
||||
const content = utils_1.loadJson(path);
|
||||
const path = (0, path_1.resolve)("tsconfig.package.json");
|
||||
const content = (0, utils_1.loadJson)(path);
|
||||
content.compilerOptions.module = moduleType;
|
||||
content.compilerOptions.target = targetType;
|
||||
utils_1.saveJson(path, content, true);
|
||||
(0, utils_1.saveJson)(path, content, true);
|
||||
// Configure the browser field for every pacakge, copying the
|
||||
// browser.umd filed for UMD and browser.esm for ESM
|
||||
path_1.dirnames.forEach((dirname) => {
|
||||
const filename = path_1.getPackageJsonPath(dirname);
|
||||
const info = utils_1.loadJson(filename);
|
||||
const filename = (0, path_1.getPackageJsonPath)(dirname);
|
||||
const info = (0, utils_1.loadJson)(filename);
|
||||
if (info._ethers_nobuild) {
|
||||
return;
|
||||
}
|
||||
let path = path_1.resolve("packages", dirname, "tsconfig.json");
|
||||
let content = utils_1.loadJson(path);
|
||||
let path = (0, path_1.resolve)("packages", dirname, "tsconfig.json");
|
||||
let content = (0, utils_1.loadJson)(path);
|
||||
content.compilerOptions.outDir = outDir;
|
||||
utils_1.saveJson(path, content, true);
|
||||
(0, utils_1.saveJson)(path, content, true);
|
||||
});
|
||||
}
|
||||
function setupBuild(buildModule) {
|
||||
|
||||
@@ -39,7 +39,7 @@ const npm = __importStar(require("./npm"));
|
||||
const path_1 = require("./path");
|
||||
const run_1 = require("./run");
|
||||
const utils_1 = require("./utils");
|
||||
const changelogPath = path_1.resolve("CHANGELOG.md");
|
||||
const changelogPath = (0, path_1.resolve)("CHANGELOG.md");
|
||||
function generate() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const lines = fs_1.default.readFileSync(changelogPath).toString().trim().split("\n");
|
||||
@@ -59,11 +59,11 @@ function generate() {
|
||||
const published = yield npm.getPackage("ethers");
|
||||
if (versions.indexOf(version) >= 0) {
|
||||
const line = `Version ${version} already in CHANGELOG. Please edit before committing.`;
|
||||
console.log(log_1.colorify.red(utils_1.repeat("=", line.length)));
|
||||
console.log(log_1.colorify.red((0, utils_1.repeat)("=", line.length)));
|
||||
console.log(log_1.colorify.red(line));
|
||||
console.log(log_1.colorify.red(utils_1.repeat("=", line.length)));
|
||||
console.log(log_1.colorify.red((0, utils_1.repeat)("=", line.length)));
|
||||
}
|
||||
const gitResult = yield run_1.run("git", ["log", (published.gitHead + "..")]);
|
||||
const gitResult = yield (0, run_1.run)("git", ["log", (published.gitHead + "..")]);
|
||||
if (!gitResult.ok) {
|
||||
console.log(gitResult);
|
||||
throw new Error("Error running git log");
|
||||
@@ -78,7 +78,7 @@ function generate() {
|
||||
});
|
||||
}
|
||||
else if (line.toLowerCase().substring(0, 5) === "date:") {
|
||||
changes[changes.length - 1].date = utils_1.getDateTime(new Date(line.substring(5).trim()));
|
||||
changes[changes.length - 1].date = (0, utils_1.getDateTime)(new Date(line.substring(5).trim()));
|
||||
}
|
||||
else if (line.substring(0, 1) === " ") {
|
||||
line = line.trim();
|
||||
@@ -92,9 +92,9 @@ function generate() {
|
||||
for (let i = 0; i < firstLine; i++) {
|
||||
output.push(lines[i]);
|
||||
}
|
||||
const newTitle = `ethers/v${version} (${utils_1.getDateTime(new Date())})`;
|
||||
const newTitle = `ethers/v${version} (${(0, utils_1.getDateTime)(new Date())})`;
|
||||
output.push(newTitle);
|
||||
output.push(utils_1.repeat("-", newTitle.length));
|
||||
output.push((0, utils_1.repeat)("-", newTitle.length));
|
||||
output.push("");
|
||||
changes.forEach((change) => {
|
||||
let body = change.body.trim();
|
||||
|
||||
@@ -65,7 +65,7 @@ const path_1 = require("../path");
|
||||
accum[name] = version;
|
||||
return accum;
|
||||
}, {});
|
||||
const packageJsonPath = path_1.getPackageJsonPath(dirname);
|
||||
const packageJsonPath = (0, path_1.getPackageJsonPath)(dirname);
|
||||
local.updateJson(packageJsonPath, {
|
||||
dependencies: deps,
|
||||
version: newVersion
|
||||
|
||||
@@ -40,8 +40,8 @@ const npm = __importStar(require("../npm"));
|
||||
const utils_1 = require("../utils");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const common = utils_1.loadJson(path_1.resolve("package.json")).common;
|
||||
const progress = log_1.getProgressBar(log_1.colorify.bold("Bumping package.json versions"));
|
||||
const common = (0, utils_1.loadJson)((0, path_1.resolve)("package.json")).common;
|
||||
const progress = (0, log_1.getProgressBar)(log_1.colorify.bold("Bumping package.json versions"));
|
||||
const latestVersions = {};
|
||||
let updated = false;
|
||||
const output = [];
|
||||
@@ -49,7 +49,7 @@ const utils_1 = require("../utils");
|
||||
for (let i = 0; i < path_1.dirnames.length; i++) {
|
||||
progress(i / path_1.dirnames.length);
|
||||
const dirname = path_1.dirnames[i];
|
||||
const packageJsonPath = path_1.getPackageJsonPath(dirname);
|
||||
const packageJsonPath = (0, path_1.getPackageJsonPath)(dirname);
|
||||
// Set the common elements to the package.json
|
||||
local.updateJson(packageJsonPath, common, true);
|
||||
const pLocal = local.getPackage(dirname);
|
||||
@@ -68,7 +68,7 @@ const utils_1 = require("../utils");
|
||||
output.push([
|
||||
" ",
|
||||
log_1.colorify.blue(pLocal.name),
|
||||
utils_1.repeat(" ", 47 - pLocal.name.length - pNpm.version.length),
|
||||
(0, utils_1.repeat)(" ", 47 - pLocal.name.length - pNpm.version.length),
|
||||
pNpm.version,
|
||||
log_1.colorify.bold(" => "),
|
||||
log_1.colorify.green(version)
|
||||
@@ -80,13 +80,13 @@ const utils_1 = require("../utils");
|
||||
// Write out the _version.ts
|
||||
if (!pLocal._ethers_nobuild) {
|
||||
const code = "export const version = " + JSON.stringify(dirname + "/" + version) + ";\n";
|
||||
fs_1.default.writeFileSync(path_1.resolve(path_1.getPackagePath(dirname), "src.ts/_version.ts"), code);
|
||||
fs_1.default.writeFileSync((0, path_1.resolve)((0, path_1.getPackagePath)(dirname), "src.ts/_version.ts"), code);
|
||||
}
|
||||
}
|
||||
progress(1);
|
||||
if (updated) {
|
||||
const filename = path_1.resolve("packages/ethers/package.json");
|
||||
const info = utils_1.loadJson(filename);
|
||||
const filename = (0, path_1.resolve)("packages/ethers/package.json");
|
||||
const info = (0, utils_1.loadJson)(filename);
|
||||
Object.keys(info.dependencies).forEach((name) => {
|
||||
const version = latestVersions[name];
|
||||
if (name == null) {
|
||||
@@ -94,7 +94,7 @@ const utils_1 = require("../utils");
|
||||
}
|
||||
info.dependencies[name] = version;
|
||||
});
|
||||
utils_1.saveJson(filename, info);
|
||||
(0, utils_1.saveJson)(filename, info);
|
||||
}
|
||||
output.forEach((line) => { console.log(line); });
|
||||
});
|
||||
|
||||
@@ -38,10 +38,10 @@ const config = {
|
||||
console.log(log_1.colorify.bold(`Bundling Testcase Data...`));
|
||||
const data = { "_": JSON.stringify({ name: "browser-fs", config: config }) };
|
||||
config.dirs.forEach((dirname) => {
|
||||
let fulldirname = path_2.resolve("packages/testcases", dirname);
|
||||
let fulldirname = (0, path_2.resolve)("packages/testcases", dirname);
|
||||
fs_1.default.readdirSync(fulldirname).forEach((filename) => {
|
||||
const key = path_1.join(dirname, filename);
|
||||
const content = fs_1.default.readFileSync(path_1.join(fulldirname, filename));
|
||||
const key = (0, path_1.join)(dirname, filename);
|
||||
const content = fs_1.default.readFileSync((0, path_1.join)(fulldirname, filename));
|
||||
if (filename.split(".").pop() === "gz") {
|
||||
const contentData = zlib_1.default.gunzipSync(content);
|
||||
data[key] = String(contentData.length) + "," + zlib_1.default.deflateRawSync(contentData).toString("base64");
|
||||
@@ -52,15 +52,15 @@ const config = {
|
||||
//console.log(` - Added ${ key } (${ data[key].length } bytes)`);
|
||||
});
|
||||
});
|
||||
utils_1.mkdir(path_2.resolve("packages/testcases/lib"));
|
||||
utils_1.mkdir(path_2.resolve("packages/testcases/lib._esm"));
|
||||
utils_1.mkdir(path_2.resolve("packages/testcases/lib.esm"));
|
||||
(0, utils_1.mkdir)((0, path_2.resolve)("packages/testcases/lib"));
|
||||
(0, utils_1.mkdir)((0, path_2.resolve)("packages/testcases/lib._esm"));
|
||||
(0, utils_1.mkdir)((0, path_2.resolve)("packages/testcases/lib.esm"));
|
||||
// We write it out to all needed places
|
||||
fs_1.default.writeFileSync(path_2.resolve("packages/testcases/lib/browser-data.json"), JSON.stringify(data));
|
||||
fs_1.default.writeFileSync(path_2.resolve("packages/testcases/lib._esm/browser-data.json"), JSON.stringify(data));
|
||||
fs_1.default.writeFileSync(path_2.resolve("packages/testcases/lib.esm/browser-data.json"), JSON.stringify(data));
|
||||
fs_1.default.writeFileSync((0, path_2.resolve)("packages/testcases/lib/browser-data.json"), JSON.stringify(data));
|
||||
fs_1.default.writeFileSync((0, path_2.resolve)("packages/testcases/lib._esm/browser-data.json"), JSON.stringify(data));
|
||||
fs_1.default.writeFileSync((0, path_2.resolve)("packages/testcases/lib.esm/browser-data.json"), JSON.stringify(data));
|
||||
// Write it to the TypeScript source last, in case it is running it will
|
||||
// be regenerated overwriting the above files, but with identical content
|
||||
fs_1.default.writeFileSync(path_2.resolve("packages/testcases/src.ts/browser-data.json"), JSON.stringify(data));
|
||||
fs_1.default.writeFileSync((0, path_2.resolve)("packages/testcases/src.ts/browser-data.json"), JSON.stringify(data));
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -15,6 +15,6 @@ const github_1 = require("../github");
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const user = yield config_1.config.get("github-user");
|
||||
const password = yield config_1.config.get("github-readonly");
|
||||
yield github_1.syncIssues(user, password);
|
||||
yield (0, github_1.syncIssues)(user, password);
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -24,8 +24,8 @@ const log_1 = require("../log");
|
||||
function alias(name) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(` Aliasing: ${name}`);
|
||||
const baseDir = path_2.resolve("packages", name);
|
||||
const info = utils_1.loadJson(path_2.resolve(baseDir, "package.json"));
|
||||
const baseDir = (0, path_2.resolve)("packages", name);
|
||||
const info = (0, utils_1.loadJson)((0, path_2.resolve)(baseDir, "package.json"));
|
||||
const replacements = info["_ethers.alias"] || {};
|
||||
const skip = Object.keys(replacements).reduce((accum, key) => {
|
||||
const replace = replacements[key];
|
||||
@@ -37,10 +37,10 @@ function alias(name) {
|
||||
}, ({}));
|
||||
const transforms = [];
|
||||
const recurse = function (input, output) {
|
||||
fs_1.default.readdirSync(path_1.join(baseDir, input)).forEach((filename) => {
|
||||
const stat = fs_1.default.statSync(path_1.join(baseDir, input, filename));
|
||||
fs_1.default.readdirSync((0, path_1.join)(baseDir, input)).forEach((filename) => {
|
||||
const stat = fs_1.default.statSync((0, path_1.join)(baseDir, input, filename));
|
||||
if (stat.isDirectory()) {
|
||||
recurse(path_1.join(input, filename), path_1.join(output, filename));
|
||||
recurse((0, path_1.join)(input, filename), (0, path_1.join)(output, filename));
|
||||
return;
|
||||
}
|
||||
if (skip[filename]) {
|
||||
@@ -61,7 +61,7 @@ function alias(name) {
|
||||
if (replace) {
|
||||
inputFilename = replace;
|
||||
transform = function (content) {
|
||||
content = content.replace(/(\/\/# sourceMappingURL=)(.*)$/g, (all, prefix, mapFilename) => {
|
||||
content = content.replace(/^(\/\/# sourceMappingURL=)(.*)$/mg, (all, prefix, mapFilename) => {
|
||||
return prefix + filename + ".map";
|
||||
});
|
||||
return content;
|
||||
@@ -118,19 +118,19 @@ function alias(name) {
|
||||
};
|
||||
}
|
||||
}
|
||||
transforms.push({ input: path_1.join(input, inputFilename), output: path_1.join(output, filename), transform });
|
||||
transforms.push({ input: (0, path_1.join)(input, inputFilename), output: (0, path_1.join)(output, filename), transform });
|
||||
});
|
||||
};
|
||||
recurse("lib._esm", "lib.esm");
|
||||
transforms.forEach(({ input, output, transform }) => {
|
||||
const sourceFile = path_1.join(baseDir, input);
|
||||
const sourceFile = (0, path_1.join)(baseDir, input);
|
||||
let content = fs_1.default.readFileSync(sourceFile).toString();
|
||||
if (transform) {
|
||||
content = transform(content);
|
||||
}
|
||||
const targetFile = path_1.join(baseDir, output);
|
||||
const targetDir = path_1.dirname(targetFile);
|
||||
utils_1.mkdir(targetDir);
|
||||
const targetFile = (0, path_1.join)(baseDir, output);
|
||||
const targetDir = (0, path_1.dirname)(targetFile);
|
||||
(0, utils_1.mkdir)(targetDir);
|
||||
fs_1.default.writeFileSync(targetFile, content);
|
||||
});
|
||||
});
|
||||
@@ -138,9 +138,9 @@ function alias(name) {
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(log_1.colorify.bold(`Aliasing Node ESM to Browser ESM...`));
|
||||
const dirnames = depgraph_1.getOrdered(true);
|
||||
const dirnames = (0, depgraph_1.getOrdered)(true);
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
//if (dirnames[i] !== "base64") { continue; }
|
||||
//if (dirnames[i] !== "signing-key") { continue; }
|
||||
yield alias(dirnames[i]);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -14,11 +14,11 @@ const local_1 = require("../local");
|
||||
const log_1 = require("../log");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const dependencies = local_1.getDependencies(null, (name) => {
|
||||
return !path_1.isEthers(name);
|
||||
const dependencies = (0, local_1.getDependencies)(null, (name) => {
|
||||
return !(0, path_1.isEthers)(name);
|
||||
});
|
||||
console.log(log_1.colorify.bold(`Hoisting ${Object.keys(dependencies).length} dependencies into root package...`));
|
||||
local_1.updateJson(path_1.dirs.rootPackageJsonPath, { dependencies });
|
||||
(0, local_1.updateJson)(path_1.dirs.rootPackageJsonPath, { dependencies });
|
||||
});
|
||||
})().catch((error) => {
|
||||
console.log(`Error running ${process.argv[0]}: ${error.message}`);
|
||||
|
||||
@@ -33,28 +33,28 @@ function link(existing, path) {
|
||||
}
|
||||
}
|
||||
// Link
|
||||
const dir = path_1.dirname(path);
|
||||
utils_1.mkdir(dir);
|
||||
const dir = (0, path_1.dirname)(path);
|
||||
(0, utils_1.mkdir)(dir);
|
||||
fs_1.default.symlinkSync(existing, path, "junction");
|
||||
}
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(log_1.colorify.bold(`Linking ${path_2.packages.length} package node_modules rat nests...`));
|
||||
const nodeModulesBase = path_1.resolve(path_2.dirs.root, ".package_node_modules");
|
||||
const nodeModulesBase = (0, path_1.resolve)(path_2.dirs.root, ".package_node_modules");
|
||||
// Make a symlink in the ROOT/node_mpdules to each package in this repo
|
||||
path_2.packages.forEach((name) => {
|
||||
// e.g. /node_modules/@ethersproject/abi => /packages/abi
|
||||
link(path_2.getPackagePath(name), path_1.resolve(path_2.dirs.root, "node_modules", name));
|
||||
link((0, path_2.getPackagePath)(name), (0, path_1.resolve)(path_2.dirs.root, "node_modules", name));
|
||||
// e.g. /packages/abi/node_modules => /.package_node_modules/abi/
|
||||
const nodeModules = path_1.resolve(nodeModulesBase, path_2.getDirname(name));
|
||||
utils_1.mkdir(nodeModules);
|
||||
link(nodeModules, path_1.resolve(path_2.getPackagePath(name), "node_modules"));
|
||||
const nodeModules = (0, path_1.resolve)(nodeModulesBase, (0, path_2.getDirname)(name));
|
||||
(0, utils_1.mkdir)(nodeModules);
|
||||
link(nodeModules, (0, path_1.resolve)((0, path_2.getPackagePath)(name), "node_modules"));
|
||||
});
|
||||
path_2.packages.forEach((name) => {
|
||||
const nodeModules = path_1.resolve(nodeModulesBase, path_2.getDirname(name));
|
||||
const deps = local_1.getDependencies(name);
|
||||
const nodeModules = (0, path_1.resolve)(nodeModulesBase, (0, path_2.getDirname)(name));
|
||||
const deps = (0, local_1.getDependencies)(name);
|
||||
Object.keys(deps).forEach((name) => {
|
||||
link(path_1.resolve(path_2.dirs.root, "node_modules", name), path_1.resolve(nodeModules, name));
|
||||
link((0, path_1.resolve)(path_2.dirs.root, "node_modules", name), (0, path_1.resolve)(nodeModules, name));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ const utils_1 = require("../utils");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const versions = path_1.dirnames.reduce((accum, dirname) => {
|
||||
const pkg = local_1.getPackage(dirname);
|
||||
const pkg = (0, local_1.getPackage)(dirname);
|
||||
accum[pkg.name] = pkg.version;
|
||||
return accum;
|
||||
}, ({}));
|
||||
@@ -25,8 +25,8 @@ const utils_1 = require("../utils");
|
||||
return;
|
||||
}
|
||||
console.log(dirname);
|
||||
const path = path_1.resolve("packages", dirname, "package.json");
|
||||
const json = utils_1.loadJson(path);
|
||||
const path = (0, path_1.resolve)("packages", dirname, "package.json");
|
||||
const json = (0, utils_1.loadJson)(path);
|
||||
for (const name in (json.dependencies || {})) {
|
||||
const version = json.dependencies[name];
|
||||
const target = (versions[name] ? ("^" + versions[name]) : version);
|
||||
@@ -35,7 +35,7 @@ const utils_1 = require("../utils");
|
||||
}
|
||||
json.dependencies[name] = target;
|
||||
}
|
||||
utils_1.saveJson(path, json, true);
|
||||
(0, utils_1.saveJson)(path, json, true);
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
0
misc/admin/lib/cmds/peg-version.d.ts
vendored
Normal file
0
misc/admin/lib/cmds/peg-version.d.ts
vendored
Normal file
16
misc/admin/lib/cmds/peg-version.js
Normal file
16
misc/admin/lib/cmds/peg-version.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
import { dirnames, getPackage } from "../local";
|
||||
import { colorify } from "../log";
|
||||
|
||||
const dirname = process.argv[2];
|
||||
if (dirname == null) {
|
||||
console.log("Usage: peg-version DIRNAME");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
(async function(dirname) {
|
||||
const { name, version } = getPackage(dirname);
|
||||
console.log(colorify.bold(`Pegging ${ name } to ${ version }...`));
|
||||
|
||||
})(dirname);
|
||||
*/
|
||||
@@ -89,10 +89,10 @@ function invalidate(cloudfront, distributionId) {
|
||||
exports.invalidate = invalidate;
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const dirnames = depgraph_1.getOrdered();
|
||||
const dirnames = (0, depgraph_1.getOrdered)();
|
||||
// @TODO: Fail if there are any untracked files or unchecked in files
|
||||
const publish = {};
|
||||
const progressUpdate = log_1.getProgressBar(log_1.colorify.bold("Finding updated packages..."));
|
||||
const progressUpdate = (0, log_1.getProgressBar)(log_1.colorify.bold("Finding updated packages..."));
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
progressUpdate(i / dirnames.length);
|
||||
let dirname = dirnames[i];
|
||||
@@ -103,8 +103,8 @@ exports.invalidate = invalidate;
|
||||
continue;
|
||||
}
|
||||
// Get the latest commit this package was modified at
|
||||
const path = path_1.resolve("packages", dirname);
|
||||
const gitHead = yield git_1.getGitTag(path);
|
||||
const path = (0, path_1.resolve)("packages", dirname);
|
||||
const gitHead = yield (0, git_1.getGitTag)(path);
|
||||
if (gitHead == null) {
|
||||
throw new Error("hmmm...");
|
||||
}
|
||||
@@ -119,7 +119,7 @@ exports.invalidate = invalidate;
|
||||
console.log(log_1.colorify.bold(`Found ${Object.keys(publish).length} updated pacakges...`));
|
||||
Object.keys(publish).forEach((dirname) => {
|
||||
const info = publish[dirname];
|
||||
console.log(` ${log_1.colorify.blue(info.name)} ${utils_1.repeat(" ", 50 - info.name.length - info.oldVersion.length)} ${info.oldVersion} ${log_1.colorify.bold("=>")} ${log_1.colorify.green(info.newVersion)}`);
|
||||
console.log(` ${log_1.colorify.blue(info.name)} ${(0, utils_1.repeat)(" ", 50 - info.name.length - info.oldVersion.length)} ${info.oldVersion} ${log_1.colorify.bold("=>")} ${log_1.colorify.green(info.newVersion)}`);
|
||||
});
|
||||
const publishNames = Object.keys(publish);
|
||||
publishNames.sort((a, b) => (dirnames.indexOf(a) - dirnames.indexOf(b)));
|
||||
@@ -149,17 +149,17 @@ exports.invalidate = invalidate;
|
||||
console.log(log_1.colorify.bold("Publishing:"));
|
||||
for (let i = 0; i < publishNames.length; i++) {
|
||||
const dirname = publishNames[i];
|
||||
const path = path_1.resolve("packages", dirname);
|
||||
const pathJson = path_1.resolve("packages", dirname, "package.json");
|
||||
const path = (0, path_1.resolve)("packages", dirname);
|
||||
const pathJson = (0, path_1.resolve)("packages", dirname, "package.json");
|
||||
const { gitHead, name, newVersion } = publish[dirname];
|
||||
console.log(` ${log_1.colorify.blue(name)} @ ${log_1.colorify.green(newVersion)}`);
|
||||
local.updateJson(pathJson, { gitHead: gitHead }, true);
|
||||
const info = utils_1.loadJson(pathJson);
|
||||
const info = (0, utils_1.loadJson)(pathJson);
|
||||
yield npm.publish(path, info, options);
|
||||
local.updateJson(pathJson, { gitHead: undefined }, true);
|
||||
}
|
||||
if (publishNames.indexOf("ethers") >= 0 || forcePublish) {
|
||||
const change = changelog_1.getLatestChange();
|
||||
const change = (0, changelog_1.getLatestChange)();
|
||||
const patchVersion = change.version.substring(1);
|
||||
const minorVersion = patchVersion.split(".").slice(0, 2).join(".");
|
||||
const awsAccessId = yield config_1.config.get("aws-upload-scripts-accesskey");
|
||||
@@ -169,8 +169,8 @@ exports.invalidate = invalidate;
|
||||
// The password above already succeeded
|
||||
const username = yield config_1.config.get("github-user");
|
||||
const password = yield config_1.config.get("github-release");
|
||||
const hash = createHash("sha384").update(fs_1.default.readFileSync(path_1.resolve("packages/ethers/dist/ethers.umd.min.js"))).digest("base64");
|
||||
const gitCommit = yield git_1.getGitTag(path_1.resolve("CHANGELOG.md"));
|
||||
const hash = createHash("sha384").update(fs_1.default.readFileSync((0, path_1.resolve)("packages/ethers/dist/ethers.umd.min.js"))).digest("base64");
|
||||
const gitCommit = yield (0, git_1.getGitTag)((0, path_1.resolve)("CHANGELOG.md"));
|
||||
let content = change.content.trim();
|
||||
content += '\n\n----\n\n';
|
||||
content += '**Embedding UMD with [SRI](https:/\/developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity):**\n';
|
||||
@@ -183,7 +183,7 @@ exports.invalidate = invalidate;
|
||||
content += '```';
|
||||
// Publish the release
|
||||
const beta = false;
|
||||
const link = yield github_1.createRelease(username, password, change.version, change.title, content, beta, gitCommit);
|
||||
const link = yield (0, github_1.createRelease)(username, password, change.version, change.title, content, beta, gitCommit);
|
||||
console.log(`${log_1.colorify.bold("Published release:")} ${link}`);
|
||||
}
|
||||
// Upload libs to the CDN (as ethers-v5.1 and ethers-5.1.x)
|
||||
@@ -244,7 +244,7 @@ exports.invalidate = invalidate;
|
||||
const { bucketName, originRoot, filename, key, suffix } = fileInfos[i];
|
||||
yield putObject(s3, {
|
||||
ACL: "public-read",
|
||||
Body: fs_1.default.readFileSync(path_1.resolve(filename)),
|
||||
Body: fs_1.default.readFileSync((0, path_1.resolve)(filename)),
|
||||
Bucket: bucketName,
|
||||
ContentType: "application/javascript; charset=utf-8",
|
||||
Key: (originRoot + key)
|
||||
|
||||
@@ -42,8 +42,8 @@ function start(root, options) {
|
||||
if (options.port == null) {
|
||||
options.port = 8000;
|
||||
}
|
||||
root = path_1.resolve(root);
|
||||
const server = http_1.createServer((req, resp) => {
|
||||
root = (0, path_1.resolve)(root);
|
||||
const server = (0, http_1.createServer)((req, resp) => {
|
||||
const url = req.url.split("?")[0];
|
||||
// Follow redirects in options
|
||||
if (options.redirects && options.redirects[url]) {
|
||||
@@ -51,7 +51,7 @@ function start(root, options) {
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
let filename = path_1.resolve(root, "." + url);
|
||||
let filename = (0, path_1.resolve)(root, "." + url);
|
||||
// Make sure we aren't crawling out of our sandbox
|
||||
if (url[0] !== "/" || filename.substring(0, filename.length) !== filename) {
|
||||
resp.writeHead(403);
|
||||
@@ -94,7 +94,7 @@ function start(root, options) {
|
||||
return server;
|
||||
}
|
||||
exports.start = start;
|
||||
start(path_2.resolve("docs"), {
|
||||
start((0, path_2.resolve)("docs"), {
|
||||
redirects: {
|
||||
"/": "/v5/"
|
||||
}
|
||||
|
||||
@@ -19,19 +19,19 @@ const utils_1 = require("../utils");
|
||||
console.log(log_1.colorify.bold("Setting Option:"), arg);
|
||||
switch (arg) {
|
||||
case "esm":
|
||||
build_1.setupBuild(true);
|
||||
(0, build_1.setupBuild)(true);
|
||||
break;
|
||||
case "cjs":
|
||||
build_1.setupBuild(false);
|
||||
(0, build_1.setupBuild)(false);
|
||||
break;
|
||||
// This will remove the browser field entirely, so make sure
|
||||
// to set esm of cjs first as they will restore the browser
|
||||
// field
|
||||
case "browser-lang-all": {
|
||||
const filename = path_1.getPackageJsonPath("wordlists");
|
||||
const info = utils_1.loadJson(filename);
|
||||
const filename = (0, path_1.getPackageJsonPath)("wordlists");
|
||||
const info = (0, utils_1.loadJson)(filename);
|
||||
delete info.browser;
|
||||
utils_1.saveJson(filename, info, true);
|
||||
(0, utils_1.saveJson)(filename, info, true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -18,7 +18,7 @@ if (process.argv.length !== 3) {
|
||||
const key = process.argv[2];
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const value = yield log_1.getPassword("Value: ");
|
||||
const value = yield (0, log_1.getPassword)("Value: ");
|
||||
yield config_1.config.set(key, value);
|
||||
});
|
||||
})().catch((error) => {
|
||||
|
||||
@@ -16,7 +16,7 @@ const fs_1 = __importDefault(require("fs"));
|
||||
const path_1 = require("../path");
|
||||
const utils_1 = require("../utils");
|
||||
function copy(src, dst, transform) {
|
||||
let data = fs_1.default.readFileSync(path_1.resolve(src));
|
||||
let data = fs_1.default.readFileSync((0, path_1.resolve)(src));
|
||||
if (transform) {
|
||||
data = Buffer.from(transform(data.toString()));
|
||||
}
|
||||
@@ -24,14 +24,14 @@ function copy(src, dst, transform) {
|
||||
}
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield utils_1.mkdir(path_1.resolve("output/karma"));
|
||||
copy(path_1.resolve("packages/ethers/dist/ethers.esm.js"), path_1.resolve("output/karma/ethers.esm.js"));
|
||||
copy(path_1.resolve("packages/tests/dist/tests.esm.js"), path_1.resolve("output/karma/tests.esm.js"), (data) => {
|
||||
yield (0, utils_1.mkdir)((0, path_1.resolve)("output/karma"));
|
||||
copy((0, path_1.resolve)("packages/ethers/dist/ethers.esm.js"), (0, path_1.resolve)("output/karma/ethers.esm.js"));
|
||||
copy((0, path_1.resolve)("packages/tests/dist/tests.esm.js"), (0, path_1.resolve)("output/karma/tests.esm.js"), (data) => {
|
||||
return data.replace(/^(import [^;]* from ')(ethers)(';)/, (all, prefix, id, suffix) => {
|
||||
return prefix + "./ethers.esm.js" + suffix;
|
||||
});
|
||||
});
|
||||
copy(path_1.resolve("packages/ethers/dist/ethers.umd.js"), path_1.resolve("output/karma/ethers.umd.js"));
|
||||
copy(path_1.resolve("packages/tests/dist/tests.umd.js"), path_1.resolve("output/karma/tests.umd.js"));
|
||||
copy((0, path_1.resolve)("packages/ethers/dist/ethers.umd.js"), (0, path_1.resolve)("output/karma/ethers.umd.js"));
|
||||
copy((0, path_1.resolve)("packages/tests/dist/tests.umd.js"), (0, path_1.resolve)("output/karma/tests.umd.js"));
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -22,7 +22,7 @@ const Words = fs_1.default.readFileSync("/usr/share/dict/words").toString().spli
|
||||
}, {});
|
||||
`
|
||||
// Words missing from the dictionary
|
||||
accessing addresses aligned autofill called cancelled changed censored
|
||||
accessing addresses aligned autofill avatar called cancelled changed censored
|
||||
clamping compiled computed configured consumed creating decoded decoding
|
||||
decreased decrypt decrypted decrypting deployed deploying deprecated detected
|
||||
discontinued earliest email emitted enabled encoded encoder encoding encrypt
|
||||
@@ -58,9 +58,9 @@ ABIEncoder testcase numberish Wordlist
|
||||
abi addr api app arg arrayify asm backend basex bigint bignumber bn byte
|
||||
bytecode callback calldata charset checksum ciphertext cli codepoint
|
||||
commify config
|
||||
contenthash ctr ctrl debug dd dklen eexist encseed eof eq ethaddr
|
||||
contenthash ctr ctrl debug dd dklen eexist encseed eof eq erc ethaddr
|
||||
ethseed ethers eval exec filename func gz gzip hid http https hw iv
|
||||
info init ipc json kdf kdfparams labelhash lang lib mm multihash nfc
|
||||
info init ipc json kdf kdfparams labelhash lang lib metadata mm multihash nfc
|
||||
nfkc nfd nfkd nodehash notok nowait nullish oob opcode pbkdf pc plugin
|
||||
pragma pre prf recid repl rpc sighash topichash solc stdin stdout subclasses
|
||||
subnode timeout todo txt typeof ufixed utc utf util url urlencoded uuid vm
|
||||
@@ -72,13 +72,14 @@ abiv
|
||||
// Query parameters
|
||||
apikey asc endblock startblock
|
||||
|
||||
alchemyapi Cloudflare Etherscan INFURA IPFS MetaMask Nodesmith
|
||||
alchemyapi arbitrum Cloudflare Etherscan INFURA IPFS MetaMask Nodesmith
|
||||
Trezor ledgerhq axic bitcoinjs browserify easyseed ethereumjs
|
||||
goerli homestead kotti kovan mainnet morden mordor rinkeby
|
||||
ropsten testnet lb
|
||||
goerli homestead kotti kovan mainnet morden mordor rinkeby kintsugi
|
||||
ropsten testnet lb maticmum
|
||||
|
||||
// Demo words
|
||||
args foo eth foo foobar ll localhost passwd ricmoo tx xxx yna
|
||||
brantly
|
||||
|
||||
// nameprep tags
|
||||
ALCat BiDi LCat nameprep
|
||||
@@ -129,7 +130,7 @@ function getStrings(source) {
|
||||
const Include = new RegExp("packages/.*/src.ts/.*\.ts$");
|
||||
const Exclude = new RegExp("/node_modules/|src.ts/.*browser.*");
|
||||
function getAllStrings(path) {
|
||||
const Root = path_1.resolve(__dirname, path);
|
||||
const Root = (0, path_1.resolve)(__dirname, path);
|
||||
const readdir = function (path) {
|
||||
if (path.match(Exclude)) {
|
||||
return [];
|
||||
@@ -137,7 +138,7 @@ function getAllStrings(path) {
|
||||
const stat = fs_1.default.statSync(path);
|
||||
if (stat.isDirectory()) {
|
||||
return fs_1.default.readdirSync(path).reduce((result, filename) => {
|
||||
readdir(path_1.resolve(path, filename)).forEach((file) => {
|
||||
readdir((0, path_1.resolve)(path, filename)).forEach((file) => {
|
||||
result.push(file);
|
||||
});
|
||||
return result;
|
||||
@@ -174,7 +175,7 @@ function starts(text, prefix) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(log_1.colorify.bold("Spell checking source code strings..."));
|
||||
let count = 0;
|
||||
getAllStrings(path_1.resolve(__dirname, "../../../../packages")).forEach((file) => {
|
||||
getAllStrings((0, path_1.resolve)(__dirname, "../../../../packages")).forEach((file) => {
|
||||
if (starts(file.filename, "/testcases/src.ts/generation-scripts")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ const path_1 = require("../path");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(log_1.colorify.bold("Updating CHANGELOG.md..."));
|
||||
fs_1.default.writeFileSync(path_1.resolve("CHANGELOG.md"), yield changelog_1.generate());
|
||||
fs_1.default.writeFileSync((0, path_1.resolve)("CHANGELOG.md"), yield (0, changelog_1.generate)());
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -14,8 +14,8 @@ const path_1 = require("../path");
|
||||
const local_1 = require("../local");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const ordered = depgraph_1.getOrdered(true);
|
||||
local_1.updateJson(path_1.resolve("tsconfig.project.json"), {
|
||||
const ordered = (0, depgraph_1.getOrdered)(true);
|
||||
(0, local_1.updateJson)((0, path_1.resolve)("tsconfig.project.json"), {
|
||||
references: ordered.map((name) => ({ path: ("./packages/" + name) }))
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const log_1 = require("../log");
|
||||
const path_1 = require("../path");
|
||||
const sourceEthers = fs_1.default.readFileSync(path_1.resolve("packages/ethers/src.ts/ethers.ts")).toString();
|
||||
const sourceEthers = fs_1.default.readFileSync((0, path_1.resolve)("packages/ethers/src.ts/ethers.ts")).toString();
|
||||
const targets = sourceEthers.match(/export\s*{\s*((.|\s)*)}/)[1].trim();
|
||||
////////////////////
|
||||
// Begin template
|
||||
@@ -35,4 +35,4 @@ export {
|
||||
// End template
|
||||
////////////////////
|
||||
console.log(log_1.colorify.bold(`Flattening exports...`));
|
||||
fs_1.default.writeFileSync(path_1.resolve("packages/ethers/src.ts/index.ts"), output);
|
||||
fs_1.default.writeFileSync((0, path_1.resolve)("packages/ethers/src.ts/index.ts"), output);
|
||||
|
||||
@@ -14,14 +14,14 @@ const log_1 = require("../log");
|
||||
const path_1 = require("../path");
|
||||
(function () {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const progress = log_1.getProgressBar(log_1.colorify.bold("Updating package.json hashes"));
|
||||
const progress = (0, log_1.getProgressBar)(log_1.colorify.bold("Updating package.json hashes"));
|
||||
// Updating all tarball hashes now that versions have been updated
|
||||
for (let i = 0; i < path_1.dirnames.length; i++) {
|
||||
progress(i / path_1.dirnames.length);
|
||||
const dirname = path_1.dirnames[i];
|
||||
//const gitHead = await getGitTag(resolve("packages", dirname));
|
||||
const tarballHash = local_1.computeTarballHash(dirname);
|
||||
local_1.updateJson(path_1.getPackageJsonPath(dirname), { tarballHash }, true);
|
||||
const tarballHash = (0, local_1.computeTarballHash)(dirname);
|
||||
(0, local_1.updateJson)((0, path_1.getPackageJsonPath)(dirname), { tarballHash }, true);
|
||||
}
|
||||
progress(1);
|
||||
});
|
||||
|
||||
@@ -116,7 +116,7 @@ function _getFiles(result, root) {
|
||||
if (filename === '.DS_Store') {
|
||||
return;
|
||||
}
|
||||
const fullFilename = path_1.join(root, filename);
|
||||
const fullFilename = (0, path_1.join)(root, filename);
|
||||
const stat = fs_1.default.statSync(fullFilename);
|
||||
if (stat.isDirectory()) {
|
||||
_getFiles(result, fullFilename);
|
||||
@@ -150,7 +150,7 @@ function getFiles(basedir) {
|
||||
secretAccessKey: awsSecretKey
|
||||
});
|
||||
const added = [], removed = [], changed = [], upload = [];
|
||||
const basedir = path_2.resolve("docs");
|
||||
const basedir = (0, path_2.resolve)("docs");
|
||||
const local = yield getFiles(basedir);
|
||||
const remote = yield getKeys(s3, bucket);
|
||||
Object.keys(local).forEach((filename) => {
|
||||
@@ -177,7 +177,7 @@ function getFiles(basedir) {
|
||||
console.log('Changed: ', changed.length);
|
||||
for (let i = 0; i < upload.length; i++) {
|
||||
const filename = upload[i];
|
||||
const content = fs_1.default.readFileSync(path_1.join(basedir, filename));
|
||||
const content = fs_1.default.readFileSync((0, path_1.join)(basedir, filename));
|
||||
console.log(`Uploading: ${filename} (${content.length} bytes)`);
|
||||
yield putObject(s3, bucket, filename, content);
|
||||
}
|
||||
|
||||
@@ -22,15 +22,15 @@ const scrypt_js_1 = __importDefault(require("scrypt-js"));
|
||||
const log_1 = require("./log");
|
||||
function getRandomBytes(length) {
|
||||
const result = new Uint8Array(length);
|
||||
result.set(crypto_1.randomBytes(length));
|
||||
result.set((0, crypto_1.randomBytes)(length));
|
||||
return result;
|
||||
}
|
||||
function computeHmac(key, data) {
|
||||
return "0x" + crypto_1.createHmac("sha512", key).update(data).digest("hex");
|
||||
return "0x" + (0, crypto_1.createHmac)("sha512", key).update(data).digest("hex");
|
||||
}
|
||||
function getScrypt(message, password, salt) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const progress = log_1.getProgressBar(message);
|
||||
const progress = (0, log_1.getProgressBar)(message);
|
||||
return yield scrypt_js_1.default.scrypt(Buffer.from(password), Buffer.from(salt), (1 << 17), 8, 1, 64, progress);
|
||||
});
|
||||
}
|
||||
@@ -58,7 +58,7 @@ class Config {
|
||||
}
|
||||
this.canary = data.canary || "";
|
||||
this.salt = data.salt;
|
||||
const password = yield log_1.getPassword(log_1.colorify.bold("Password (config-store): "));
|
||||
const password = yield (0, log_1.getPassword)(log_1.colorify.bold("Password (config-store): "));
|
||||
this.dkey = yield getScrypt(log_1.colorify.bold("Unlocking config"), password, this.salt);
|
||||
if (data.ciphertext) {
|
||||
const ciphertext = Buffer.from(data.ciphertext, "base64");
|
||||
@@ -113,7 +113,7 @@ class Config {
|
||||
this.salt = this.dkey = null;
|
||||
}
|
||||
}
|
||||
const _config = new Config(path_1.resolve(os_1.default.homedir(), ".ethers-dist"));
|
||||
const _config = new Config((0, path_1.resolve)(os_1.default.homedir(), ".ethers-dist"));
|
||||
exports.config = {
|
||||
get: function (key) {
|
||||
return _config.get(key);
|
||||
|
||||
@@ -47,7 +47,7 @@ function getOrdered(skipNobuild) {
|
||||
};
|
||||
for (let i = 0; i < path_1.dirnames.length; i++) {
|
||||
let dirname = path_1.dirnames[i];
|
||||
let info = local_1.getPackage(dirname);
|
||||
let info = (0, local_1.getPackage)(dirname);
|
||||
if (skipNobuild && info._ethers_nobuild) {
|
||||
continue;
|
||||
}
|
||||
@@ -91,8 +91,8 @@ exports.getOrdered = getOrdered;
|
||||
function sort(dirnames) {
|
||||
let ordered = getOrdered();
|
||||
dirnames.sort((a, b) => {
|
||||
let ai = ordered.indexOf(local_1.getPackage(a).name);
|
||||
let bi = ordered.indexOf(local_1.getPackage(b).name);
|
||||
let ai = ordered.indexOf((0, local_1.getPackage)(a).name);
|
||||
let bi = ordered.indexOf((0, local_1.getPackage)(b).name);
|
||||
if (ai === -1 || bi === -1) {
|
||||
throw new Error("unknown dirname - " + [a, b].join(", "));
|
||||
}
|
||||
|
||||
@@ -73,9 +73,9 @@ function _getUrl(href, options) {
|
||||
options = {};
|
||||
}
|
||||
// @TODO: Once we drop support for node 8, we can pass the href
|
||||
// firectly into request and skip adding the components
|
||||
// directly into request and skip adding the components
|
||||
// to this request object
|
||||
const url = url_1.parse(href);
|
||||
const url = (0, url_1.parse)(href);
|
||||
const request = {
|
||||
protocol: nonnull(url.protocol),
|
||||
hostname: nonnull(url.hostname),
|
||||
|
||||
@@ -14,7 +14,7 @@ const run_1 = require("./run");
|
||||
// Returns the most recent git commit hash for a given filename
|
||||
function getGitTag(filename) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const result = yield run_1.run("git", ["log", "-n", "1", "--", filename]);
|
||||
const result = yield (0, run_1.run)("git", ["log", "-n", "1", "--", filename]);
|
||||
if (!result.ok) {
|
||||
throw new Error(`git log error`);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ function _fetchGitHub(user, password, getUrlFunc, url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const result = [];
|
||||
while (true) {
|
||||
const filename = path_1.resolve("github-cache", Buffer.from(js_sha3_1.keccak_256.create().update(Buffer.from(url)).digest()).toString("hex").substring(0, 12));
|
||||
const filename = (0, path_1.resolve)("github-cache", Buffer.from(js_sha3_1.keccak_256.create().update(Buffer.from(url)).digest()).toString("hex").substring(0, 12));
|
||||
const headers = {
|
||||
"User-Agent": "ethers-io",
|
||||
};
|
||||
@@ -41,7 +41,7 @@ function _fetchGitHub(user, password, getUrlFunc, url) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
const response = yield geturl_1.getUrl(url, { headers, user, password });
|
||||
const response = yield (0, geturl_1.getUrl)(url, { headers, user, password });
|
||||
console.log(response.statusCode);
|
||||
// Cached response is good; use it!
|
||||
if (response.statusCode !== 304) {
|
||||
@@ -129,7 +129,7 @@ function syncIssues(user, password) {
|
||||
exports.syncIssues = syncIssues;
|
||||
function createRelease(user, password, tagName, title, body, prerelease, commit) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const result = yield geturl_1.getUrl("https:/\/api.github.com/repos/ethers-io/ethers.js/releases", {
|
||||
const result = yield (0, geturl_1.getUrl)("https:/\/api.github.com/repos/ethers-io/ethers.js/releases", {
|
||||
body: Buffer.from(JSON.stringify({
|
||||
tag_name: tagName,
|
||||
target_commitish: (commit || "master"),
|
||||
|
||||
@@ -9,7 +9,7 @@ const path_1 = require("./path");
|
||||
const run_1 = require("./run");
|
||||
const utils_1 = require("./utils");
|
||||
function getPackage(name) {
|
||||
const value = utils_1.loadJson(path_1.getPackageJsonPath(name));
|
||||
const value = (0, utils_1.loadJson)((0, path_1.getPackageJsonPath)(name));
|
||||
return {
|
||||
name: value.name,
|
||||
version: value.version,
|
||||
@@ -23,7 +23,7 @@ function getPackage(name) {
|
||||
}
|
||||
exports.getPackage = getPackage;
|
||||
function updateJson(path, replace, sort) {
|
||||
const values = utils_1.loadJson(path);
|
||||
const values = (0, utils_1.loadJson)(path);
|
||||
Object.keys(replace).forEach((key) => {
|
||||
const value = replace[key];
|
||||
if (value === undefined) {
|
||||
@@ -33,12 +33,12 @@ function updateJson(path, replace, sort) {
|
||||
values[key] = replace[key];
|
||||
}
|
||||
});
|
||||
utils_1.saveJson(path, values, !!sort);
|
||||
(0, utils_1.saveJson)(path, values, !!sort);
|
||||
}
|
||||
exports.updateJson = updateJson;
|
||||
function getDependencies(name, filter) {
|
||||
if (name) {
|
||||
return utils_1.sortRecords(getPackage(name).dependencies);
|
||||
return (0, utils_1.sortRecords)(getPackage(name).dependencies);
|
||||
}
|
||||
// Find all versions for each package dependency
|
||||
const deps = path_1.dirnames.reduce((accum, dirname) => {
|
||||
@@ -55,7 +55,7 @@ function getDependencies(name, filter) {
|
||||
return accum;
|
||||
}, {});
|
||||
// Make sure each package dependency only has 1 version
|
||||
return utils_1.sortRecords(Object.keys(deps).reduce((accum, name) => {
|
||||
return (0, utils_1.sortRecords)(Object.keys(deps).reduce((accum, name) => {
|
||||
const versions = Object.keys(deps[name]);
|
||||
if (versions.length > 1) {
|
||||
throw new Error(`cannot depend on multiple versions for ${JSON.stringify(name)}: ${versions.map(v => JSON.stringify(v)).join(", ")}`);
|
||||
@@ -66,7 +66,7 @@ function getDependencies(name, filter) {
|
||||
}
|
||||
exports.getDependencies = getDependencies;
|
||||
function getPackList(name) {
|
||||
const result = run_1.run("npm", ["pack", "--json", path_1.getPackagePath(name), "--dry-run"]);
|
||||
const result = (0, run_1.run)("npm", ["pack", "--json", (0, path_1.getPackagePath)(name), "--dry-run"]);
|
||||
if (!result.ok) {
|
||||
const error = new Error(`failed to run npm pack: ${name}`);
|
||||
error.result = result;
|
||||
@@ -118,9 +118,9 @@ function computeTarballHash(name) {
|
||||
const files = getPackList(name);
|
||||
files.sort();
|
||||
// Compute the hash for each file
|
||||
const packageRoot = path_1.getPackagePath(name);
|
||||
const packageRoot = (0, path_1.getPackagePath)(name);
|
||||
const hashes = files.reduce((accum, filename) => {
|
||||
let content = fs_1.default.readFileSync(path_1.resolve(packageRoot, filename));
|
||||
let content = fs_1.default.readFileSync((0, path_1.resolve)(packageRoot, filename));
|
||||
// The package.json includes the hash, so we need to nix it to get a consistent hash
|
||||
if (filename === "package.json") {
|
||||
const info = JSON.parse(content.toString());
|
||||
@@ -128,10 +128,10 @@ function computeTarballHash(name) {
|
||||
delete info.tarballHash;
|
||||
content = Buffer.from(JSON.stringify(info, null, 2));
|
||||
}
|
||||
accum[filename] = utils_1.sha256(content);
|
||||
accum[filename] = (0, utils_1.sha256)(content);
|
||||
return accum;
|
||||
}, {});
|
||||
return utils_1.sha256(Buffer.from("{" + files.map((filename) => {
|
||||
return (0, utils_1.sha256)(Buffer.from("{" + files.map((filename) => {
|
||||
return `${JSON.stringify(filename)}:"${hashes[filename]}"`;
|
||||
}).join(",") + "}"));
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ function _getPrompt(prompt, options, callback) {
|
||||
(process.stdout).clearLine();
|
||||
(process.stdout).cursorTo(0);
|
||||
if (options.mask) {
|
||||
process.stdout.write(prompt + utils_1.repeat(options.mask, message.length));
|
||||
process.stdout.write(prompt + (0, utils_1.repeat)(options.mask, message.length));
|
||||
}
|
||||
else {
|
||||
process.stdout.write(prompt + message);
|
||||
|
||||
@@ -22,10 +22,10 @@ const cache = {};
|
||||
function getPackageInfo(name) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Convert dirname to package if needed
|
||||
name = local_1.getPackage(name).name;
|
||||
name = (0, local_1.getPackage)(name).name;
|
||||
if (!cache[name]) {
|
||||
try {
|
||||
const result = yield geturl_1.getUrl("http:/" + "/registry.npmjs.org/" + name);
|
||||
const result = yield (0, geturl_1.getUrl)("https:/\/registry.npmjs.org/" + name);
|
||||
cache[name] = JSON.parse(Buffer.from(result.body).toString("utf8"));
|
||||
}
|
||||
catch (error) {
|
||||
@@ -66,12 +66,12 @@ exports.getPackage = getPackage;
|
||||
function publish(path, manifest, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
yield libnpmpublish_1.publish(path, manifest, options);
|
||||
yield (0, libnpmpublish_1.publish)(path, manifest, options);
|
||||
}
|
||||
catch (error) {
|
||||
// We need an OTP
|
||||
if (error.code === "EOTP") {
|
||||
const otp = yield log_1.getPrompt(log_1.colorify.bold("Enter OTP: "));
|
||||
const otp = yield (0, log_1.getPrompt)(log_1.colorify.bold("Enter OTP: "));
|
||||
options.otp = otp.replace(" ", "");
|
||||
// Retry with the new OTP
|
||||
return yield publish(path, manifest, options);
|
||||
|
||||
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isEthers = exports.getPackageJsonPath = exports.getDirname = exports.getPackagePath = exports.packages = exports.dirnames = exports.dirs = exports.resolve = exports.root = void 0;
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const path_1 = require("path");
|
||||
exports.root = path_1.resolve(__dirname, "../../../");
|
||||
exports.root = (0, path_1.resolve)(__dirname, "../../../");
|
||||
function resolve(...args) {
|
||||
args.unshift(exports.root);
|
||||
return path_1.resolve.apply(null, args);
|
||||
@@ -23,8 +23,8 @@ exports.dirnames = Object.freeze(fs_1.default.readdirSync(exports.dirs.packages)
|
||||
return (dirname[0] !== ".");
|
||||
}));
|
||||
const packageLookup = exports.dirnames.reduce((accum, dirname) => {
|
||||
const packagePath = path_1.resolve(exports.dirs.packages, dirname);
|
||||
const packageJsonPath = path_1.resolve(packagePath, "package.json");
|
||||
const packagePath = (0, path_1.resolve)(exports.dirs.packages, dirname);
|
||||
const packageJsonPath = (0, path_1.resolve)(packagePath, "package.json");
|
||||
const info = JSON.parse(fs_1.default.readFileSync(packageJsonPath).toString());
|
||||
const packageName = info.name;
|
||||
const version = info.version;
|
||||
|
||||
@@ -10,7 +10,7 @@ function run(progname, args, currentWorkingDirectory) {
|
||||
if (currentWorkingDirectory) {
|
||||
options.cwd = currentWorkingDirectory;
|
||||
}
|
||||
const child = child_process_1.spawnSync(progname, args, options);
|
||||
const child = (0, child_process_1.spawnSync)(progname, args, options);
|
||||
const result = {
|
||||
_stderr: child.stderr,
|
||||
stderr: (child.stderr.toString() || null),
|
||||
|
||||
@@ -28,7 +28,7 @@ function repeat(char, length) {
|
||||
}
|
||||
exports.repeat = repeat;
|
||||
function sha256(content) {
|
||||
const hasher = crypto_1.createHash("sha256");
|
||||
const hasher = (0, crypto_1.createHash)("sha256");
|
||||
hasher.update(content);
|
||||
return "0x" + hasher.digest("hex");
|
||||
}
|
||||
@@ -43,7 +43,7 @@ function sortRecords(record) {
|
||||
}
|
||||
exports.sortRecords = sortRecords;
|
||||
function atomicWrite(path, value) {
|
||||
const tmp = path_1.resolve(__dirname, "../../../.atomic-tmp");
|
||||
const tmp = (0, path_1.resolve)(__dirname, "../../../.atomic-tmp");
|
||||
fs_1.default.writeFileSync(tmp, value);
|
||||
fs_1.default.renameSync(tmp, path);
|
||||
}
|
||||
@@ -96,7 +96,7 @@ function mkdir(path) {
|
||||
break;
|
||||
}
|
||||
dirs.push(path);
|
||||
path = path_1.dirname(path);
|
||||
path = (0, path_1.dirname)(path);
|
||||
}
|
||||
while (dirs.length) {
|
||||
fs_1.default.mkdirSync(dirs.pop());
|
||||
|
||||
@@ -52,7 +52,7 @@ async function alias(name: string): Promise<void> {
|
||||
if (replace) {
|
||||
inputFilename = replace;
|
||||
transform = function(content: string) {
|
||||
content = content.replace(/(\/\/# sourceMappingURL=)(.*)$/g, (all, prefix, mapFilename) => {
|
||||
content = content.replace(/^(\/\/# sourceMappingURL=)(.*)$/mg, (all, prefix, mapFilename) => {
|
||||
return prefix + filename + ".map";
|
||||
});
|
||||
return content;
|
||||
@@ -132,7 +132,7 @@ async function alias(name: string): Promise<void> {
|
||||
console.log(colorify.bold(`Aliasing Node ESM to Browser ESM...`));
|
||||
const dirnames = getOrdered(true);
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
//if (dirnames[i] !== "base64") { continue; }
|
||||
//if (dirnames[i] !== "signing-key") { continue; }
|
||||
await alias(dirnames[i]);
|
||||
}
|
||||
})();
|
||||
|
||||
16
misc/admin/src.ts/cmds/peg-version.ts
Normal file
16
misc/admin/src.ts/cmds/peg-version.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
import { dirnames, getPackage } from "../local";
|
||||
import { colorify } from "../log";
|
||||
|
||||
const dirname = process.argv[2];
|
||||
if (dirname == null) {
|
||||
console.log("Usage: peg-version DIRNAME");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
(async function(dirname) {
|
||||
const { name, version } = getPackage(dirname);
|
||||
console.log(colorify.bold(`Pegging ${ name } to ${ version }...`));
|
||||
|
||||
})(dirname);
|
||||
*/
|
||||
@@ -13,7 +13,7 @@ const Words = fs.readFileSync("/usr/share/dict/words").toString().split("\n").re
|
||||
|
||||
`
|
||||
// Words missing from the dictionary
|
||||
accessing addresses aligned autofill called cancelled changed censored
|
||||
accessing addresses aligned autofill avatar called cancelled changed censored
|
||||
clamping compiled computed configured consumed creating decoded decoding
|
||||
decreased decrypt decrypted decrypting deployed deploying deprecated detected
|
||||
discontinued earliest email emitted enabled encoded encoder encoding encrypt
|
||||
@@ -49,9 +49,9 @@ ABIEncoder testcase numberish Wordlist
|
||||
abi addr api app arg arrayify asm backend basex bigint bignumber bn byte
|
||||
bytecode callback calldata charset checksum ciphertext cli codepoint
|
||||
commify config
|
||||
contenthash ctr ctrl debug dd dklen eexist encseed eof eq ethaddr
|
||||
contenthash ctr ctrl debug dd dklen eexist encseed eof eq erc ethaddr
|
||||
ethseed ethers eval exec filename func gz gzip hid http https hw iv
|
||||
info init ipc json kdf kdfparams labelhash lang lib mm multihash nfc
|
||||
info init ipc json kdf kdfparams labelhash lang lib metadata mm multihash nfc
|
||||
nfkc nfd nfkd nodehash notok nowait nullish oob opcode pbkdf pc plugin
|
||||
pragma pre prf recid repl rpc sighash topichash solc stdin stdout subclasses
|
||||
subnode timeout todo txt typeof ufixed utc utf util url urlencoded uuid vm
|
||||
@@ -63,13 +63,14 @@ abiv
|
||||
// Query parameters
|
||||
apikey asc endblock startblock
|
||||
|
||||
alchemyapi Cloudflare Etherscan INFURA IPFS MetaMask Nodesmith
|
||||
alchemyapi arbitrum Cloudflare Etherscan INFURA IPFS MetaMask Nodesmith
|
||||
Trezor ledgerhq axic bitcoinjs browserify easyseed ethereumjs
|
||||
goerli homestead kotti kovan mainnet morden mordor rinkeby
|
||||
ropsten testnet lb
|
||||
goerli homestead kotti kovan mainnet morden mordor rinkeby kintsugi
|
||||
ropsten testnet lb maticmum
|
||||
|
||||
// Demo words
|
||||
args foo eth foo foobar ll localhost passwd ricmoo tx xxx yna
|
||||
brantly
|
||||
|
||||
// nameprep tags
|
||||
ALCat BiDi LCat nameprep
|
||||
|
||||
@@ -79,7 +79,7 @@ async function _getUrl(href: string, options?: Options): Promise<GetUrlResponse>
|
||||
if (options == null) { options = { }; }
|
||||
|
||||
// @TODO: Once we drop support for node 8, we can pass the href
|
||||
// firectly into request and skip adding the components
|
||||
// directly into request and skip adding the components
|
||||
// to this request object
|
||||
const url = parse(href);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ async function getPackageInfo(name: string): Promise<any> {
|
||||
|
||||
if (!cache[name]) {
|
||||
try {
|
||||
const result = await getUrl("http:/" + "/registry.npmjs.org/" + name);
|
||||
const result = await getUrl("https:/\/registry.npmjs.org/" + name);
|
||||
cache[name] = JSON.parse(Buffer.from(result.body).toString("utf8"));
|
||||
} catch (error) {
|
||||
if (error.status === 404) { return null; }
|
||||
|
||||
2185
package-lock.json
generated
2185
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -65,22 +65,22 @@
|
||||
"@types/node": "^12.7.4",
|
||||
"@types/semver": "^7.3.4",
|
||||
"aes-js": "3.0.0",
|
||||
"aws-sdk": "2.137.0",
|
||||
"aws-sdk": "2.1039.0",
|
||||
"diff": "4.0.1",
|
||||
"flatworm": "0.0.2-beta.5",
|
||||
"flatworm": "0.0.2-beta.7",
|
||||
"jison": "0.4.18",
|
||||
"karma": "6.3.2",
|
||||
"karma-chrome-launcher": "3.1.0",
|
||||
"karma-mocha": "2.0.1",
|
||||
"libnpmpublish": "3.0.1",
|
||||
"mocha": "^7.1.1",
|
||||
"mocha": "^9.1.3",
|
||||
"nyc": "15.1.0",
|
||||
"rollup": "2.33.2",
|
||||
"rollup-plugin-node-polyfills": "0.2.1",
|
||||
"rollup-plugin-sourcemaps": "0.6.3",
|
||||
"scrypt-js": "3.0.1",
|
||||
"semver": "^5.6.0",
|
||||
"typescript": "4.2.2",
|
||||
"typescript": "4.4.4",
|
||||
"uglify-es": "3.3.9"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -95,7 +95,7 @@
|
||||
"bn.js": "^4.11.9",
|
||||
"elliptic": "6.5.4",
|
||||
"hash.js": "1.1.7",
|
||||
"js-sha3": "0.5.7",
|
||||
"js-sha3": "0.8.0",
|
||||
"scrypt-js": "3.0.1",
|
||||
"solc": "0.7.1",
|
||||
"tiny-inflate": "1.0.3",
|
||||
|
||||
2
packages/abi/lib.esm/_version.d.ts
vendored
2
packages/abi/lib.esm/_version.d.ts
vendored
@@ -1,2 +1,2 @@
|
||||
export declare const version = "abi/5.3.0";
|
||||
export declare const version = "abi/5.5.0";
|
||||
//# sourceMappingURL=_version.d.ts.map
|
||||
@@ -1,2 +1,2 @@
|
||||
export const version = "abi/5.3.0";
|
||||
export const version = "abi/5.5.0";
|
||||
//# sourceMappingURL=_version.js.map
|
||||
@@ -11,7 +11,7 @@ export class AddressCoder extends Coder {
|
||||
}
|
||||
encode(writer, value) {
|
||||
try {
|
||||
getAddress(value);
|
||||
value = getAddress(value);
|
||||
}
|
||||
catch (error) {
|
||||
this._throwError(error.message, value);
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../src.ts/coders/address.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,KAAK,EAAkB,MAAM,kBAAkB,CAAC;AAEzD,MAAM,OAAO,YAAa,SAAQ,KAAK;IAEnC,YAAY,SAAiB;QACzB,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IAED,YAAY;QACR,OAAO,4CAA4C,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,MAAc,EAAE,KAAa;QAChC,IAAI;YACA,UAAU,CAAC,KAAK,CAAC,CAAC;SACrB;QAAC,OAAO,KAAK,EAAE;YACZ,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC1C;QACD,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,CAAC,MAAc;QACjB,OAAO,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACxE,CAAC;CACJ"}
|
||||
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../src.ts/coders/address.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,KAAK,EAAkB,MAAM,kBAAkB,CAAC;AAEzD,MAAM,OAAO,YAAa,SAAQ,KAAK;IAEnC,YAAY,SAAiB;QACzB,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IAED,YAAY;QACR,OAAO,4CAA4C,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,MAAc,EAAE,KAAa;QAChC,IAAI;YACA,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;SAC5B;QAAC,OAAO,KAAK,EAAE;YACZ,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC1C;QACD,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,CAAC,MAAc;QACjB,OAAO,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACxE,CAAC;CACJ"}
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src.ts/coders/array.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGjE,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG;IAAE,CAAE,IAAI,EAAE,MAAM,GAAI,GAAG,CAAA;CAAE,GAAG,MAAM,CAuEzH;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,CAiFnE;AAGD,qBAAa,UAAW,SAAQ,KAAK;IACjC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAS3D,YAAY,IAAI,KAAK,CAAC,GAAG,CAAC;IAW1B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM;IAoBjD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG;CAsB9B"}
|
||||
{"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src.ts/coders/array.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGjE,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG;IAAE,CAAE,IAAI,EAAE,MAAM,GAAI,GAAG,CAAA;CAAE,GAAG,MAAM,CAuEzH;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,CAmFnE;AAGD,qBAAa,UAAW,SAAQ,KAAK;IACjC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAS3D,YAAY,IAAI,KAAK,CAAC,GAAG,CAAC;IAW1B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM;IAoBjD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG;CAsB9B"}
|
||||
@@ -131,6 +131,7 @@ export function unpack(reader, coders) {
|
||||
const value = values[index];
|
||||
if (value instanceof Error) {
|
||||
Object.defineProperty(values, name, {
|
||||
enumerable: true,
|
||||
get: () => { throw value; }
|
||||
});
|
||||
}
|
||||
@@ -142,6 +143,7 @@ export function unpack(reader, coders) {
|
||||
const value = values[i];
|
||||
if (value instanceof Error) {
|
||||
Object.defineProperty(values, i, {
|
||||
enumerable: true,
|
||||
get: () => { throw value; }
|
||||
});
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
1
packages/abi/lib.esm/fragments.d.ts
vendored
1
packages/abi/lib.esm/fragments.d.ts
vendored
@@ -3,6 +3,7 @@ export interface JsonFragmentType {
|
||||
readonly name?: string;
|
||||
readonly indexed?: boolean;
|
||||
readonly type?: string;
|
||||
readonly internalType?: any;
|
||||
readonly components?: ReadonlyArray<JsonFragmentType>;
|
||||
}
|
||||
export interface JsonFragment {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"fragments.d.ts","sourceRoot":"","sources":["../src.ts/fragments.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"fragments.d.ts","sourceRoot":"","sources":["../src.ts/fragments.ts"],"names":[],"mappings":"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"}
|
||||
@@ -201,7 +201,7 @@ export const FormatTypes = Object.freeze({
|
||||
sighash: "sighash",
|
||||
// Human-Readable with Minimal spacing and without names (compact human-readable)
|
||||
minimal: "minimal",
|
||||
// Human-Readble with nice spacing, including all names
|
||||
// Human-Readable with nice spacing, including all names
|
||||
full: "full",
|
||||
// JSON-format a la Solidity
|
||||
json: "json"
|
||||
@@ -239,7 +239,7 @@ export class ParamType {
|
||||
// Format the parameter fragment
|
||||
// - sighash: "(uint256,address)"
|
||||
// - minimal: "tuple(uint256,address) indexed"
|
||||
// - full: "tuple(uint256 foo, addres bar) indexed baz"
|
||||
// - full: "tuple(uint256 foo, address bar) indexed baz"
|
||||
format(format) {
|
||||
if (!format) {
|
||||
format = FormatTypes.sighash;
|
||||
@@ -814,7 +814,8 @@ function verifyType(type) {
|
||||
// @TODO: more verification
|
||||
return type;
|
||||
}
|
||||
const regexIdentifier = new RegExp("^[A-Za-z_][A-Za-z0-9_]*$");
|
||||
// See: https://github.com/ethereum/solidity/blob/1f8f1a3db93a548d0555e3e14cfc55a10e25b60e/docs/grammar/SolidityLexer.g4#L234
|
||||
const regexIdentifier = new RegExp("^[a-zA-Z$_][a-zA-Z0-9$_]*$");
|
||||
function verifyIdentifier(value) {
|
||||
if (!value || !value.match(regexIdentifier)) {
|
||||
logger.throwArgumentError(`invalid identifier "${value}"`, "value", value);
|
||||
|
||||
File diff suppressed because one or more lines are too long
12
packages/abi/lib.esm/interface.d.ts
vendored
12
packages/abi/lib.esm/interface.d.ts
vendored
@@ -20,6 +20,13 @@ export declare class TransactionDescription extends Description<TransactionDescr
|
||||
readonly sighash: string;
|
||||
readonly value: BigNumber;
|
||||
}
|
||||
export declare class ErrorDescription extends Description<ErrorDescription> {
|
||||
readonly errorFragment: ErrorFragment;
|
||||
readonly name: string;
|
||||
readonly args: Result;
|
||||
readonly signature: string;
|
||||
readonly sighash: string;
|
||||
}
|
||||
export declare class Indexed extends Description<Indexed> {
|
||||
readonly hash: string;
|
||||
readonly _isIndexed: boolean;
|
||||
@@ -51,11 +58,13 @@ export declare class Interface {
|
||||
getFunction(nameOrSignatureOrSighash: string): FunctionFragment;
|
||||
getEvent(nameOrSignatureOrTopic: string): EventFragment;
|
||||
getError(nameOrSignatureOrSighash: string): ErrorFragment;
|
||||
getSighash(functionFragment: FunctionFragment | string): string;
|
||||
getSighash(fragment: ErrorFragment | FunctionFragment | string): string;
|
||||
getEventTopic(eventFragment: EventFragment | string): string;
|
||||
_decodeParams(params: ReadonlyArray<ParamType>, data: BytesLike): Result;
|
||||
_encodeParams(params: ReadonlyArray<ParamType>, values: ReadonlyArray<any>): string;
|
||||
encodeDeploy(values?: ReadonlyArray<any>): string;
|
||||
decodeErrorResult(fragment: ErrorFragment | string, data: BytesLike): Result;
|
||||
encodeErrorResult(fragment: ErrorFragment | string, values?: ReadonlyArray<any>): string;
|
||||
decodeFunctionData(functionFragment: FunctionFragment | string, data: BytesLike): Result;
|
||||
encodeFunctionData(functionFragment: FunctionFragment | string, values?: ReadonlyArray<any>): string;
|
||||
decodeFunctionResult(functionFragment: FunctionFragment | string, data: BytesLike): Result;
|
||||
@@ -74,6 +83,7 @@ export declare class Interface {
|
||||
topics: Array<string>;
|
||||
data: string;
|
||||
}): LogDescription;
|
||||
parseError(data: BytesLike): ErrorDescription;
|
||||
static isInterface(value: any): value is Interface;
|
||||
}
|
||||
//# sourceMappingURL=interface.d.ts.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../src.ts/interface.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../src.ts/interface.ts"],"names":[],"mappings":"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"}
|
||||
@@ -16,6 +16,8 @@ export class LogDescription extends Description {
|
||||
}
|
||||
export class TransactionDescription extends Description {
|
||||
}
|
||||
export class ErrorDescription extends Description {
|
||||
}
|
||||
export class Indexed extends Description {
|
||||
static isIndexed(value) {
|
||||
return !!(value && value._isIndexed);
|
||||
@@ -56,7 +58,7 @@ export class Interface {
|
||||
defineReadOnly(this, "fragments", abi.map((fragment) => {
|
||||
return Fragment.from(fragment);
|
||||
}).filter((fragment) => (fragment != null)));
|
||||
defineReadOnly(this, "_abiCoder", getStatic((new.target), "getAbiCoder")());
|
||||
defineReadOnly(this, "_abiCoder", getStatic(new.target, "getAbiCoder")());
|
||||
defineReadOnly(this, "functions", {});
|
||||
defineReadOnly(this, "errors", {});
|
||||
defineReadOnly(this, "events", {});
|
||||
@@ -153,7 +155,7 @@ export class Interface {
|
||||
}
|
||||
return this.functions[matching[0]];
|
||||
}
|
||||
// Normlize the signature and lookup the function
|
||||
// Normalize the signature and lookup the function
|
||||
const result = this.functions[FunctionFragment.fromString(nameOrSignatureOrSighash).format()];
|
||||
if (!result) {
|
||||
logger.throwArgumentError("no matching function", "signature", nameOrSignatureOrSighash);
|
||||
@@ -183,7 +185,7 @@ export class Interface {
|
||||
}
|
||||
return this.events[matching[0]];
|
||||
}
|
||||
// Normlize the signature and lookup the function
|
||||
// Normalize the signature and lookup the function
|
||||
const result = this.events[EventFragment.fromString(nameOrSignatureOrTopic).format()];
|
||||
if (!result) {
|
||||
logger.throwArgumentError("no matching event", "signature", nameOrSignatureOrTopic);
|
||||
@@ -214,7 +216,7 @@ export class Interface {
|
||||
}
|
||||
return this.errors[matching[0]];
|
||||
}
|
||||
// Normlize the signature and lookup the function
|
||||
// Normalize the signature and lookup the function
|
||||
const result = this.errors[FunctionFragment.fromString(nameOrSignatureOrSighash).format()];
|
||||
if (!result) {
|
||||
logger.throwArgumentError("no matching error", "signature", nameOrSignatureOrSighash);
|
||||
@@ -222,11 +224,21 @@ export class Interface {
|
||||
return result;
|
||||
}
|
||||
// Get the sighash (the bytes4 selector) used by Solidity to identify a function
|
||||
getSighash(functionFragment) {
|
||||
if (typeof (functionFragment) === "string") {
|
||||
functionFragment = this.getFunction(functionFragment);
|
||||
getSighash(fragment) {
|
||||
if (typeof (fragment) === "string") {
|
||||
try {
|
||||
fragment = this.getFunction(fragment);
|
||||
}
|
||||
catch (error) {
|
||||
try {
|
||||
fragment = this.getError(fragment);
|
||||
}
|
||||
catch (_) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
return getStatic(this.constructor, "getSighash")(functionFragment);
|
||||
return getStatic(this.constructor, "getSighash")(fragment);
|
||||
}
|
||||
// Get the topic (the bytes32 hash) used by Solidity to identify an event
|
||||
getEventTopic(eventFragment) {
|
||||
@@ -244,6 +256,25 @@ export class Interface {
|
||||
encodeDeploy(values) {
|
||||
return this._encodeParams(this.deploy.inputs, values || []);
|
||||
}
|
||||
decodeErrorResult(fragment, data) {
|
||||
if (typeof (fragment) === "string") {
|
||||
fragment = this.getError(fragment);
|
||||
}
|
||||
const bytes = arrayify(data);
|
||||
if (hexlify(bytes.slice(0, 4)) !== this.getSighash(fragment)) {
|
||||
logger.throwArgumentError(`data signature does not match error ${fragment.name}.`, "data", hexlify(bytes));
|
||||
}
|
||||
return this._decodeParams(fragment.inputs, bytes.slice(4));
|
||||
}
|
||||
encodeErrorResult(fragment, values) {
|
||||
if (typeof (fragment) === "string") {
|
||||
fragment = this.getError(fragment);
|
||||
}
|
||||
return hexlify(concat([
|
||||
this.getSighash(fragment),
|
||||
this._encodeParams(fragment.inputs, values || [])
|
||||
]));
|
||||
}
|
||||
// Decode the data for a function call (e.g. tx.data)
|
||||
decodeFunctionData(functionFragment, data) {
|
||||
if (typeof (functionFragment) === "string") {
|
||||
@@ -397,7 +428,7 @@ export class Interface {
|
||||
topics.push(keccak256(value));
|
||||
}
|
||||
else if (param.baseType === "tuple" || param.baseType === "array") {
|
||||
// @TOOD
|
||||
// @TODO
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
else {
|
||||
@@ -480,6 +511,7 @@ export class Interface {
|
||||
// Make error named values throw on access
|
||||
if (value instanceof Error) {
|
||||
Object.defineProperty(result, param.name, {
|
||||
enumerable: true,
|
||||
get: () => { throw wrapAccessError(`property ${JSON.stringify(param.name)}`, value); }
|
||||
});
|
||||
}
|
||||
@@ -493,6 +525,7 @@ export class Interface {
|
||||
const value = result[i];
|
||||
if (value instanceof Error) {
|
||||
Object.defineProperty(result, i, {
|
||||
enumerable: true,
|
||||
get: () => { throw wrapAccessError(`index ${i}`, value); }
|
||||
});
|
||||
}
|
||||
@@ -526,7 +559,7 @@ export class Interface {
|
||||
}
|
||||
// @TODO: If anonymous, and the only method, and the input count matches, should we parse?
|
||||
// Probably not, because just because it is the only event in the ABI does
|
||||
// not mean we have the full ABI; maybe jsut a fragment?
|
||||
// not mean we have the full ABI; maybe just a fragment?
|
||||
return new LogDescription({
|
||||
eventFragment: fragment,
|
||||
name: fragment.name,
|
||||
@@ -535,6 +568,20 @@ export class Interface {
|
||||
args: this.decodeEventLog(fragment, log.data, log.topics)
|
||||
});
|
||||
}
|
||||
parseError(data) {
|
||||
const hexData = hexlify(data);
|
||||
let fragment = this.getError(hexData.substring(0, 10).toLowerCase());
|
||||
if (!fragment) {
|
||||
return null;
|
||||
}
|
||||
return new ErrorDescription({
|
||||
args: this._abiCoder.decode(fragment.inputs, "0x" + hexData.substring(10)),
|
||||
errorFragment: fragment,
|
||||
name: fragment.name,
|
||||
signature: fragment.format(),
|
||||
sighash: this.getSighash(fragment),
|
||||
});
|
||||
}
|
||||
/*
|
||||
static from(value: Array<Fragment | string | JsonAbi> | string | Interface) {
|
||||
if (Interface.isInterface(value)) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
packages/abi/lib/_version.d.ts
vendored
2
packages/abi/lib/_version.d.ts
vendored
@@ -1,2 +1,2 @@
|
||||
export declare const version = "abi/5.3.0";
|
||||
export declare const version = "abi/5.5.0";
|
||||
//# sourceMappingURL=_version.d.ts.map
|
||||
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.version = void 0;
|
||||
exports.version = "abi/5.3.0";
|
||||
exports.version = "abi/5.5.0";
|
||||
//# sourceMappingURL=_version.js.map
|
||||
@@ -24,7 +24,7 @@ var AbiCoder = /** @class */ (function () {
|
||||
function AbiCoder(coerceFunc) {
|
||||
var _newTarget = this.constructor;
|
||||
logger.checkNew(_newTarget, AbiCoder);
|
||||
properties_1.defineReadOnly(this, "coerceFunc", coerceFunc || null);
|
||||
(0, properties_1.defineReadOnly)(this, "coerceFunc", coerceFunc || null);
|
||||
}
|
||||
AbiCoder.prototype._getCoder = function (param) {
|
||||
var _this = this;
|
||||
@@ -97,7 +97,7 @@ var AbiCoder = /** @class */ (function () {
|
||||
var _this = this;
|
||||
var coders = types.map(function (type) { return _this._getCoder(fragments_1.ParamType.from(type)); });
|
||||
var coder = new tuple_1.TupleCoder(coders, "_");
|
||||
return coder.decode(this._getReader(bytes_1.arrayify(data), loose));
|
||||
return coder.decode(this._getReader((0, bytes_1.arrayify)(data), loose));
|
||||
};
|
||||
return AbiCoder;
|
||||
}());
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"abi-coder.js","sourceRoot":"","sources":["../src.ts/abi-coder.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"abi-coder.js","sourceRoot":"","sources":["../src.ts/abi-coder.ts"],"names":[],"mappings":"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"}
|
||||
@@ -45,14 +45,14 @@ var Coder = /** @class */ (function () {
|
||||
exports.Coder = Coder;
|
||||
var Writer = /** @class */ (function () {
|
||||
function Writer(wordSize) {
|
||||
properties_1.defineReadOnly(this, "wordSize", wordSize || 32);
|
||||
(0, properties_1.defineReadOnly)(this, "wordSize", wordSize || 32);
|
||||
this._data = [];
|
||||
this._dataLength = 0;
|
||||
this._padding = new Uint8Array(wordSize);
|
||||
}
|
||||
Object.defineProperty(Writer.prototype, "data", {
|
||||
get: function () {
|
||||
return bytes_1.hexConcat(this._data);
|
||||
return (0, bytes_1.hexConcat)(this._data);
|
||||
},
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
@@ -68,19 +68,19 @@ var Writer = /** @class */ (function () {
|
||||
return data.length;
|
||||
};
|
||||
Writer.prototype.appendWriter = function (writer) {
|
||||
return this._writeData(bytes_1.concat(writer._data));
|
||||
return this._writeData((0, bytes_1.concat)(writer._data));
|
||||
};
|
||||
// Arrayish items; padded on the right to wordSize
|
||||
Writer.prototype.writeBytes = function (value) {
|
||||
var bytes = bytes_1.arrayify(value);
|
||||
var bytes = (0, bytes_1.arrayify)(value);
|
||||
var paddingOffset = bytes.length % this.wordSize;
|
||||
if (paddingOffset) {
|
||||
bytes = bytes_1.concat([bytes, this._padding.slice(paddingOffset)]);
|
||||
bytes = (0, bytes_1.concat)([bytes, this._padding.slice(paddingOffset)]);
|
||||
}
|
||||
return this._writeData(bytes);
|
||||
};
|
||||
Writer.prototype._getValue = function (value) {
|
||||
var bytes = bytes_1.arrayify(bignumber_1.BigNumber.from(value));
|
||||
var bytes = (0, bytes_1.arrayify)(bignumber_1.BigNumber.from(value));
|
||||
if (bytes.length > this.wordSize) {
|
||||
logger.throwError("value out-of-bounds", logger_1.Logger.errors.BUFFER_OVERRUN, {
|
||||
length: this.wordSize,
|
||||
@@ -88,7 +88,7 @@ var Writer = /** @class */ (function () {
|
||||
});
|
||||
}
|
||||
if (bytes.length % this.wordSize) {
|
||||
bytes = bytes_1.concat([this._padding.slice(bytes.length % this.wordSize), bytes]);
|
||||
bytes = (0, bytes_1.concat)([this._padding.slice(bytes.length % this.wordSize), bytes]);
|
||||
}
|
||||
return bytes;
|
||||
};
|
||||
@@ -110,14 +110,14 @@ var Writer = /** @class */ (function () {
|
||||
exports.Writer = Writer;
|
||||
var Reader = /** @class */ (function () {
|
||||
function Reader(data, wordSize, coerceFunc, allowLoose) {
|
||||
properties_1.defineReadOnly(this, "_data", bytes_1.arrayify(data));
|
||||
properties_1.defineReadOnly(this, "wordSize", wordSize || 32);
|
||||
properties_1.defineReadOnly(this, "_coerceFunc", coerceFunc);
|
||||
properties_1.defineReadOnly(this, "allowLoose", allowLoose);
|
||||
(0, properties_1.defineReadOnly)(this, "_data", (0, bytes_1.arrayify)(data));
|
||||
(0, properties_1.defineReadOnly)(this, "wordSize", wordSize || 32);
|
||||
(0, properties_1.defineReadOnly)(this, "_coerceFunc", coerceFunc);
|
||||
(0, properties_1.defineReadOnly)(this, "allowLoose", allowLoose);
|
||||
this._offset = 0;
|
||||
}
|
||||
Object.defineProperty(Reader.prototype, "data", {
|
||||
get: function () { return bytes_1.hexlify(this._data); },
|
||||
get: function () { return (0, bytes_1.hexlify)(this._data); },
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -29,7 +29,7 @@ var AddressCoder = /** @class */ (function (_super) {
|
||||
};
|
||||
AddressCoder.prototype.encode = function (writer, value) {
|
||||
try {
|
||||
address_1.getAddress(value);
|
||||
value = (0, address_1.getAddress)(value);
|
||||
}
|
||||
catch (error) {
|
||||
this._throwError(error.message, value);
|
||||
@@ -37,7 +37,7 @@ var AddressCoder = /** @class */ (function (_super) {
|
||||
return writer.writeValue(value);
|
||||
};
|
||||
AddressCoder.prototype.decode = function (reader) {
|
||||
return address_1.getAddress(bytes_1.hexZeroPad(reader.readValue().toHexString(), 20));
|
||||
return (0, address_1.getAddress)((0, bytes_1.hexZeroPad)(reader.readValue().toHexString(), 20));
|
||||
};
|
||||
return AddressCoder;
|
||||
}(abstract_coder_1.Coder));
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../src.ts/coders/address.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;AAEb,kDAAoD;AACpD,8CAAkD;AAElD,mDAAyD;AAEzD;IAAkC,gCAAK;IAEnC,sBAAY,SAAiB;eACzB,kBAAM,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC;IACjD,CAAC;IAED,mCAAY,GAAZ;QACI,OAAO,4CAA4C,CAAC;IACxD,CAAC;IAED,6BAAM,GAAN,UAAO,MAAc,EAAE,KAAa;QAChC,IAAI;YACA,oBAAU,CAAC,KAAK,CAAC,CAAC;SACrB;QAAC,OAAO,KAAK,EAAE;YACZ,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC1C;QACD,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,6BAAM,GAAN,UAAO,MAAc;QACjB,OAAO,oBAAU,CAAC,kBAAU,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACxE,CAAC;IACL,mBAAC;AAAD,CAAC,AAtBD,CAAkC,sBAAK,GAsBtC;AAtBY,oCAAY"}
|
||||
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../src.ts/coders/address.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;AAEb,kDAAoD;AACpD,8CAAkD;AAElD,mDAAyD;AAEzD;IAAkC,gCAAK;IAEnC,sBAAY,SAAiB;eACzB,kBAAM,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC;IACjD,CAAC;IAED,mCAAY,GAAZ;QACI,OAAO,4CAA4C,CAAC;IACxD,CAAC;IAED,6BAAM,GAAN,UAAO,MAAc,EAAE,KAAa;QAChC,IAAI;YACA,KAAK,GAAG,IAAA,oBAAU,EAAC,KAAK,CAAC,CAAA;SAC5B;QAAC,OAAO,KAAK,EAAE;YACZ,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC1C;QACD,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,6BAAM,GAAN,UAAO,MAAc;QACjB,OAAO,IAAA,oBAAU,EAAC,IAAA,kBAAU,EAAC,MAAM,CAAC,SAAS,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACxE,CAAC;IACL,mBAAC;AAAD,CAAC,AAtBD,CAAkC,sBAAK,GAsBtC;AAtBY,oCAAY"}
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src.ts/coders/array.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGjE,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG;IAAE,CAAE,IAAI,EAAE,MAAM,GAAI,GAAG,CAAA;CAAE,GAAG,MAAM,CAuEzH;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,CAiFnE;AAGD,qBAAa,UAAW,SAAQ,KAAK;IACjC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAS3D,YAAY,IAAI,KAAK,CAAC,GAAG,CAAC;IAW1B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM;IAoBjD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG;CAsB9B"}
|
||||
{"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src.ts/coders/array.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGjE,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG;IAAE,CAAE,IAAI,EAAE,MAAM,GAAI,GAAG,CAAA;CAAE,GAAG,MAAM,CAuEzH;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,CAmFnE;AAGD,qBAAa,UAAW,SAAQ,KAAK;IACjC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAS3D,YAAY,IAAI,KAAK,CAAC,GAAG,CAAC;IAW1B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM;IAoBjD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG;CAsB9B"}
|
||||
@@ -149,6 +149,7 @@ function unpack(reader, coders) {
|
||||
var value = values[index];
|
||||
if (value instanceof Error) {
|
||||
Object.defineProperty(values, name, {
|
||||
enumerable: true,
|
||||
get: function () { throw value; }
|
||||
});
|
||||
}
|
||||
@@ -160,6 +161,7 @@ function unpack(reader, coders) {
|
||||
var value = values[i];
|
||||
if (value instanceof Error) {
|
||||
Object.defineProperty(values, i, {
|
||||
enumerable: true,
|
||||
get: function () { throw value; }
|
||||
});
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user