Updated docs.
This commit is contained in:
parent
59239d2f61
commit
a78ca7eb8d
@ -4,9 +4,9 @@ An Application Programming Interface (API) is the formal
|
|||||||
specification of the library.
|
specification of the library.
|
||||||
|
|
||||||
_toc:
|
_toc:
|
||||||
contract
|
|
||||||
signer
|
|
||||||
providers
|
providers
|
||||||
|
signer
|
||||||
|
contract
|
||||||
utils
|
utils
|
||||||
other
|
other
|
||||||
experimental
|
experimental
|
||||||
|
@ -181,6 +181,7 @@ module.exports = {
|
|||||||
"link-infura": { name: "INFURA", url: "https:/\/infura.io" },
|
"link-infura": { name: "INFURA", url: "https:/\/infura.io" },
|
||||||
"link-ledger": "https:/\/www.ledger.com",
|
"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-parity": { name: "Parity", url: "https:/\/www.parity.io" },
|
||||||
"link-rtd": "https:/\/github.com/readthedocs/sphinx_rtd_theme",
|
"link-rtd": "https:/\/github.com/readthedocs/sphinx_rtd_theme",
|
||||||
"link-semver": { name: "semver", url: "https:/\/semver.org" },
|
"link-semver": { name: "semver", url: "https:/\/semver.org" },
|
||||||
@ -197,6 +198,11 @@ module.exports = {
|
|||||||
"link-legacy-docs3": "https:/\/docs.ethers.io/v3/",
|
"link-legacy-docs3": "https:/\/docs.ethers.io/v3/",
|
||||||
"link-legacy-docs4": "https:/\/docs.ethers.io/v4/",
|
"link-legacy-docs4": "https:/\/docs.ethers.io/v4/",
|
||||||
|
|
||||||
|
"link-github-ci": "https:/\/github.com/ethers-io/ethers.js/actions/runs/158006903",
|
||||||
|
"link-github-issues": "https:/\/github.com/ethers-io/ethers.js/issues",
|
||||||
|
|
||||||
|
"link-issue-407": "https:/\/github.com/ethers-io/ethers.js/issues/407",
|
||||||
|
|
||||||
"link-infura-secret": "https:/\/infura.io/docs/gettingStarted/authentication",
|
"link-infura-secret": "https:/\/infura.io/docs/gettingStarted/authentication",
|
||||||
|
|
||||||
"link-web3": "https:/\/github.com/ethereum/web3.js",
|
"link-web3": "https:/\/github.com/ethereum/web3.js",
|
||||||
@ -237,6 +243,7 @@ module.exports = {
|
|||||||
"link-js-bigint": "https:/\/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt",
|
"link-js-bigint": "https:/\/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt",
|
||||||
"link-js-normalize": { name: "String.normalize", url: "https:/\/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize" },
|
"link-js-normalize": { name: "String.normalize", url: "https:/\/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize" },
|
||||||
"link-js-maxsafe": "https:/\/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER#Description",
|
"link-js-maxsafe": "https:/\/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER#Description",
|
||||||
|
"link-js-proxy": "https:/\/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy",
|
||||||
"link-js-typedarray": "https:/\/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray",
|
"link-js-typedarray": "https:/\/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray",
|
||||||
|
|
||||||
"link-ricmoo-humanreadableabi": "https:/\/blog.ricmoo.com/human-readable-contract-abis-in-ethers-js-141902f4d917",
|
"link-ricmoo-humanreadableabi": "https:/\/blog.ricmoo.com/human-readable-contract-abis-in-ethers-js-141902f4d917",
|
||||||
|
@ -1,5 +1,16 @@
|
|||||||
_section: Migration: From Ethers v4 @<migration-v4>
|
_section: Migration: From Ethers v4 @<migration-v4>
|
||||||
|
|
||||||
|
This document only covers the features present in v4 which have changed
|
||||||
|
in some important way in v5.
|
||||||
|
|
||||||
|
It does not cover all the new additional featuers that have been added and
|
||||||
|
mainly aims to help those updating their older scripts and applications to
|
||||||
|
retain functional parity.
|
||||||
|
|
||||||
|
If you encounter any missing changes, please let me know and I'll update this
|
||||||
|
guide.
|
||||||
|
|
||||||
|
|
||||||
_subsection: BigNumber
|
_subsection: BigNumber
|
||||||
|
|
||||||
_heading: Namespace
|
_heading: Namespace
|
||||||
@ -18,6 +29,7 @@ ethers.BigNumberish
|
|||||||
|
|
||||||
|
|
||||||
_heading: Creating Instances
|
_heading: Creating Instances
|
||||||
|
|
||||||
The ``bigNumberify`` method was always preferred over the constructor
|
The ``bigNumberify`` method was always preferred over the constructor
|
||||||
since it could short-circuit an object instantiation for [[BigNumber]
|
since it could short-circuit an object instantiation for [[BigNumber]
|
||||||
objects (since they are immutable). This has been moved to a static
|
objects (since they are immutable). This has been moved to a static
|
||||||
@ -37,9 +49,99 @@ ethers.BigNumber.from(someValue)
|
|||||||
|
|
||||||
_subsection: Contracts
|
_subsection: Contracts
|
||||||
|
|
||||||
_code: @lang<script>
|
_heading: ENS Name Resolution
|
||||||
|
|
||||||
// @TODO
|
The name of the resolved address has changed. If the address passed into the
|
||||||
|
constructor was an ENS name, the address will be resovled before any calls
|
||||||
|
are made to the contract.
|
||||||
|
|
||||||
|
The name of the property where the resolved address has changed from ``addressPromise``
|
||||||
|
to ``resolvedAddress``.
|
||||||
|
|
||||||
|
_code: Resolved ENS Names @lang<script>
|
||||||
|
|
||||||
|
// v4
|
||||||
|
contract.addressPromise
|
||||||
|
|
||||||
|
// v5
|
||||||
|
contract.resolvedAddress
|
||||||
|
|
||||||
|
|
||||||
|
_heading: Gas Estimation
|
||||||
|
|
||||||
|
The only difference in gas estimation is that the bucket has changed
|
||||||
|
its name from ``estimate`` to ``estimateGas``.
|
||||||
|
|
||||||
|
_code: Gas Estimation @lang<script>
|
||||||
|
|
||||||
|
// v4
|
||||||
|
contract.estimate.transfer(toAddress, amount)
|
||||||
|
|
||||||
|
// v5
|
||||||
|
contract.estimateGas.transfer(toAddress, amount)
|
||||||
|
|
||||||
|
_heading: Functions
|
||||||
|
|
||||||
|
In a contract in ethers, there is a ``functions`` bucket, which exposes
|
||||||
|
all the methods of a contract.
|
||||||
|
|
||||||
|
All these functions are available on the root contract itself as well
|
||||||
|
and historically there was no difference between ``contact.foo`` and
|
||||||
|
``contract.functions.foo``. The original reason for the ``functions`` bucket
|
||||||
|
was to help when there were method names that collided with other buckets,
|
||||||
|
which is rare.
|
||||||
|
|
||||||
|
In v5, the ``functions`` bucket is now intended to help with frameworks and
|
||||||
|
for the new error recovery API, so most users should use the methods on the
|
||||||
|
root contract.
|
||||||
|
|
||||||
|
The main difference will occur when a contract method only returns a single
|
||||||
|
item. The root method will dereference this automatically while the ``functions``
|
||||||
|
bucket will preserve it as an [[Result]].
|
||||||
|
|
||||||
|
If a method returns multiple items, there is no difference.
|
||||||
|
|
||||||
|
This helps when creating a framework, since the result will always be known to
|
||||||
|
have the same number of components as the [[Fragment]] outputs, without having
|
||||||
|
to handle the special case of a single return value.
|
||||||
|
|
||||||
|
_code: Functions Bucket @lang<script>
|
||||||
|
|
||||||
|
const abi = [
|
||||||
|
|
||||||
|
// Returns a single value
|
||||||
|
"function single() view returns (uint8)",
|
||||||
|
|
||||||
|
// Returns two values
|
||||||
|
"function double() view returns (uint8, uint8)",
|
||||||
|
];
|
||||||
|
|
||||||
|
// v4
|
||||||
|
await contract.single()
|
||||||
|
// 123
|
||||||
|
await contract.functions.single()
|
||||||
|
// 123
|
||||||
|
|
||||||
|
|
||||||
|
// v5 (notice the change in the .function variant)
|
||||||
|
await contract.single()
|
||||||
|
// 123
|
||||||
|
await contract.functions.single()
|
||||||
|
// [ 123 ]
|
||||||
|
|
||||||
|
|
||||||
|
// v4
|
||||||
|
await contract.double()
|
||||||
|
// [ 123, 5 ]
|
||||||
|
await contract.functions.double()
|
||||||
|
// [ 123, 5 ]
|
||||||
|
|
||||||
|
|
||||||
|
// v5 (no difference from v4)
|
||||||
|
await contract.double()
|
||||||
|
// [ 123, 5 ]
|
||||||
|
await contract.functions.double()
|
||||||
|
// [ 123, 5 ]
|
||||||
|
|
||||||
|
|
||||||
_subsection: Errors
|
_subsection: Errors
|
||||||
@ -84,6 +186,7 @@ logger.info(...)
|
|||||||
|
|
||||||
|
|
||||||
_subsection: Interface
|
_subsection: Interface
|
||||||
|
|
||||||
The [[Interface]] object has undergone the most dramatic changes.
|
The [[Interface]] object has undergone the most dramatic changes.
|
||||||
|
|
||||||
It is no longer a meta-class and now has methods that simplify handling
|
It is no longer a meta-class and now has methods that simplify handling
|
||||||
@ -178,14 +281,6 @@ const eventSig = eventFragment.format()
|
|||||||
const topic = interface.getTopic(eventFragment)
|
const topic = interface.getTopic(eventFragment)
|
||||||
|
|
||||||
|
|
||||||
_subsection: Utilities
|
|
||||||
|
|
||||||
_heading: Renaming
|
|
||||||
|
|
||||||
_code: @lang<script>
|
|
||||||
|
|
||||||
// @TODO
|
|
||||||
|
|
||||||
_subsection: Wallet
|
_subsection: Wallet
|
||||||
|
|
||||||
_heading: Mnemonic Phrases
|
_heading: Mnemonic Phrases
|
||||||
|
@ -29,15 +29,16 @@ _code: @lang<script>
|
|||||||
const web3 = new Web3(Web3.givenProvider);
|
const web3 = new Web3(Web3.givenProvider);
|
||||||
|
|
||||||
// ethers
|
// ethers
|
||||||
import { ethers } from "./dist/ethers.esm.js";
|
|
||||||
const provider = new ethers.providers.Web3Provider(window.ethereum);
|
const provider = new ethers.providers.Web3Provider(window.ethereum);
|
||||||
|
|
||||||
|
|
||||||
_subsection: Signers
|
_subsection: Signers
|
||||||
|
|
||||||
In ethers, a **signer** is an abstraction of an Ethereum Account. It can be used to sign messages and transactions and send signed transactions to the Ethereum Network.
|
In ethers, a **signer** is an abstraction of an Ethereum Account. It can be used to sign messages and transactions and send signed transactions to the Ethereum Network.
|
||||||
|
|
||||||
In web3, an account can be used to sign messages and transactions.
|
In web3, an account can be used to sign messages and transactions.
|
||||||
|
|
||||||
|
|
||||||
_heading: Creating signer
|
_heading: Creating signer
|
||||||
|
|
||||||
_code: @lang<script>
|
_code: @lang<script>
|
||||||
@ -45,20 +46,26 @@ _code: @lang<script>
|
|||||||
// web3
|
// web3
|
||||||
const account = web3.eth.accounts.create();
|
const account = web3.eth.accounts.create();
|
||||||
|
|
||||||
// ethers
|
// ethers (create random new account)
|
||||||
const signer = ethers.Wallet.createRandom();
|
const signer = ethers.Wallet.createRandom();
|
||||||
// getting signer from JSON RPC providers
|
|
||||||
|
// ethers (connect to JSON-RPC accounts)
|
||||||
const signer = provider.getSigner();
|
const signer = provider.getSigner();
|
||||||
|
|
||||||
|
|
||||||
_heading: Signing a message
|
_heading: Signing a message
|
||||||
|
|
||||||
_code: @lang<script>
|
_code: @lang<script>
|
||||||
|
|
||||||
// web3
|
// web3 (using a private key)
|
||||||
let signature = web3.eth.accounts.sign('Some data', privateKey);
|
signature = web3.eth.accounts.sign('Some data', privateKey)
|
||||||
|
|
||||||
|
// web3 (using a JSON-RPC account)
|
||||||
|
// @TODO
|
||||||
|
|
||||||
// ethers
|
// ethers
|
||||||
let signature = await signer.signMessage('Some data');
|
signature = await signer.signMessage('Some data')
|
||||||
|
|
||||||
|
|
||||||
_subsection: Contracts
|
_subsection: Contracts
|
||||||
|
|
||||||
@ -123,23 +130,32 @@ const receipt = await tx.wait();
|
|||||||
|
|
||||||
_heading: Overloaded Functions
|
_heading: Overloaded Functions
|
||||||
|
|
||||||
Overloaded functions are functions that have the same name but different parameter types. In ethers, the syntax to call an overloaded contract function is different from the non-overloaded function. This section shows the differences between web3 and ethers when calling overloaded functions. See [issue #407](https://github.com/ethers-io/ethers.js/issues/407) for more details.
|
Overloaded functions are functions that have the same name but different parameter
|
||||||
|
types.
|
||||||
|
|
||||||
|
In ethers, the syntax to call an overloaded contract function is different
|
||||||
|
from the non-overloaded function. This section shows the differences between web3
|
||||||
|
and ethers when calling overloaded functions.
|
||||||
|
|
||||||
|
See [issue #407](link-issue-407) for more details.
|
||||||
|
|
||||||
_code: @lang<script>
|
_code: @lang<script>
|
||||||
|
|
||||||
// web3
|
// web3
|
||||||
const message = await contract.methods.getMessage('nice').call();
|
message = await contract.methods.getMessage('nice').call();
|
||||||
console.log('message', message);
|
|
||||||
|
|
||||||
|
|
||||||
// ethers
|
// ethers
|
||||||
const abi = ['function getMessage(string memory prefix) public view returns (string memory)',
|
const abi = [
|
||||||
'function getMessage() public view returns (string memory)'];
|
"function getMessage(string) public view returns (string)",
|
||||||
|
"function getMessage() public view returns (string)"
|
||||||
|
]
|
||||||
const contract = new ethers.Contract(address, abi, signer);
|
const contract = new ethers.Contract(address, abi, signer);
|
||||||
|
|
||||||
// this is how ethers identifies which function to call for overloaded functions
|
// for ambiguous functions (two functions with the same
|
||||||
const message = await contract['getMessage(string)']('nice');
|
// name), the signature must also be specified
|
||||||
console.log('message', message);
|
message = await contract['getMessage(string)']('nice');
|
||||||
|
|
||||||
|
|
||||||
_subsection: Numbers
|
_subsection: Numbers
|
||||||
|
|
||||||
@ -150,10 +166,17 @@ Convert to BigNumber:
|
|||||||
_code: @lang<script>
|
_code: @lang<script>
|
||||||
|
|
||||||
// web3
|
// web3
|
||||||
const bn = web3.utils.toBN('123456');
|
web3.utils.toBN('123456');
|
||||||
|
|
||||||
|
// ethers (from a number; must be within safe range)
|
||||||
|
ethers.BigNumber.from(123456)
|
||||||
|
|
||||||
|
// ethers (from base-10 string)
|
||||||
|
ethers.BigNumber.from("123456")
|
||||||
|
|
||||||
|
// ethers (from hex string)
|
||||||
|
ethers.BigNumber.from("0x1e240")
|
||||||
|
|
||||||
// ethers
|
|
||||||
const bn = ethers.BigNumber.from(123456);
|
|
||||||
|
|
||||||
_subsection: Utilities
|
_subsection: Utilities
|
||||||
|
|
||||||
@ -167,6 +190,9 @@ _code: @lang<script>
|
|||||||
web3.utils.sha3('hello world');
|
web3.utils.sha3('hello world');
|
||||||
web3.utils.keccak256('hello world');
|
web3.utils.keccak256('hello world');
|
||||||
|
|
||||||
// ethers
|
// ethers (hash of a string)
|
||||||
ethers.utils.id('hello world')
|
ethers.utils.id('hello world')
|
||||||
|
|
||||||
|
// ethers (hash of binary data)
|
||||||
|
ethers.utils.keccak256('0x4242')
|
||||||
|
|
||||||
|
@ -1,3 +1,385 @@
|
|||||||
_section: Testing
|
_section: Testing
|
||||||
|
|
||||||
Here goes info about testing
|
Testing is a critcial part of any library which wishes to remain secure, safe
|
||||||
|
and reliable.
|
||||||
|
|
||||||
|
Ethers currently has **over 23k tests** among its test suites, which are all
|
||||||
|
made available for other projects to use as simple exported GZIP-JSON files.
|
||||||
|
|
||||||
|
The tests are run on every check-in and the results can been seen on the
|
||||||
|
[GitHub CI Action](link-github-ci).
|
||||||
|
|
||||||
|
We also strive to constantly add new test cases, especially when issues
|
||||||
|
arise to ensure the issue is present prior to the fix, corrected after the
|
||||||
|
fix and included to prevent future changes from causing a regression.
|
||||||
|
|
||||||
|
A large number of the test cases were created procedurally by using
|
||||||
|
known correct implementations from various sources (such as Geth) and
|
||||||
|
written in different languages and verifyied with multiple libraries.
|
||||||
|
|
||||||
|
For example, the ABI test suites were generated by procedurally generating
|
||||||
|
a list of types, for each type choosing a random (valid) value, which then
|
||||||
|
was converted into a Solidity source file, compiled using ``solc`` and
|
||||||
|
deployed to a running Parity node and executed, with its outputs being
|
||||||
|
captured. Similar to the how many of the hashing, event and selector test
|
||||||
|
cases were created.
|
||||||
|
|
||||||
|
|
||||||
|
_subsection: Supported Platforms @<testing-supported>
|
||||||
|
|
||||||
|
While web technologies move quite fast, especially in the Web3 universe, we try
|
||||||
|
to keep ethers as accessible as possible.
|
||||||
|
|
||||||
|
Currently ethers should work on almost any ES3 or better environment and tests
|
||||||
|
are run against:
|
||||||
|
|
||||||
|
- node.js 8.x
|
||||||
|
- node.js 10.x
|
||||||
|
- node.js 12.x
|
||||||
|
- node.js 13.x
|
||||||
|
- Web Browsers (using UMD)
|
||||||
|
- Web Browsers (using ES modules)
|
||||||
|
|
||||||
|
If there is an environment you feel has been overlooked or have suggestions, please feel
|
||||||
|
free to reach out by opening an [issue on Github](link-github-issues).
|
||||||
|
|
||||||
|
We would like to add a test build for Expo and React as those developers often seem
|
||||||
|
to encounter pain points when using ethers, so if you have experience or ideas on this,
|
||||||
|
[bug us](link-github-issues).
|
||||||
|
|
||||||
|
The next Major version (probably summer 2021) will likely drop support for node 8.x
|
||||||
|
and will require ES2015 for [Proxy](link-js-proxy).
|
||||||
|
|
||||||
|
Certain features in JavaScript are also avoided, such as look-behind tokens in regular
|
||||||
|
expressions, since these have caused conflicts (at import time) with certain JavaScript
|
||||||
|
environmants such as [Otto](link-otto).
|
||||||
|
|
||||||
|
Basically, the moral of the story is "be inclusive and don't drop people needlessly".
|
||||||
|
|
||||||
|
|
||||||
|
_subsection: Test Suites @<testing-suites>
|
||||||
|
|
||||||
|
The test suites are avaialble a gzipped JSON files in the
|
||||||
|
``@ethersproject/testcases``, which makes it easy to install and import
|
||||||
|
(both GZIP and JSON are quite easy to consume from most langauges). Each
|
||||||
|
test suite also has its schema available in this package.
|
||||||
|
|
||||||
|
_table: Test Suites @style<full>
|
||||||
|
|
||||||
|
$Account: Private Keys and addresses in checksum and ICAP formats
|
||||||
|
$ContractEvents: Compiled Solidity, ABI interfaces, input types/values with the
|
||||||
|
output types/values for emitted events; all tests were
|
||||||
|
executed against real Ethereum nodes
|
||||||
|
$ContractAbi: Compiled Solidity, ABI interfaces, input types/values with the
|
||||||
|
output types/values, encoded and decoded binrary data and normalized
|
||||||
|
values for function calls executed against real Ethereum nodes.
|
||||||
|
$ContractAbi2: Identical to ``contract-interface``, except with emphasis on
|
||||||
|
the ABIv2 coder which supports nested dynami types and strutured
|
||||||
|
data
|
||||||
|
$ContractSignatures: Contract signatures and matching selectors
|
||||||
|
$Hashes: Data and respective hashes against a variety of hash functions
|
||||||
|
$HDNode: HDNodes (BIP-32) with mnemonics, entropy, seed and computed nodes
|
||||||
|
with pathes and addresses
|
||||||
|
$Namehash: ENS names along with computed [namehashes](link-namehash
|
||||||
|
$Nameprep: IDNA and Nameprep representations including official vectors
|
||||||
|
$RLP: Recursive-Length Prefix (RLP) data and encodings
|
||||||
|
$SoliditiyHashes: Hashes based on the Solidity non-standard packed form
|
||||||
|
$Transactions: Signed and unsigned transactions with their serialized formats
|
||||||
|
including both with and without EIP-155 replay protection
|
||||||
|
$Units: Values converted between various units
|
||||||
|
$Wallet: Keystore JSON format wallets, passwords and decrypted values
|
||||||
|
$Wordlist: Fully decompressed BIP-39 offcial wordlists
|
||||||
|
|
||||||
|
| **Filename** | **Test Cases** <|
|
||||||
|
| accounts.json.gz | $Account <|
|
||||||
|
| contract-events.json.gz | $ContractEvents <|
|
||||||
|
| contract-interface.json.gz | $ContractAbi <|
|
||||||
|
| contract-interface-abi2.json.gz | $ContractAbi2 <|
|
||||||
|
| contract-signatures.json.gz | $ContractSignatures <|
|
||||||
|
| hashes.json.gz | $Hashes <|
|
||||||
|
| hdnode.json.gz | $HDNode <|
|
||||||
|
| namehash.json.gz | $Namehash <|
|
||||||
|
| nameprep.json.gz | $Nameprep <|
|
||||||
|
| rlp-coder.json.gz | $RLP <|
|
||||||
|
| solidity-hashes.json.gz | $SoliditiyHashes <|
|
||||||
|
| transactions.json.gz | $Transactions <|
|
||||||
|
| units.json.gz | $Units <|
|
||||||
|
| wallets.json.gz | $Wallet <|
|
||||||
|
| wordlists.json.gz | $Wordlist <|
|
||||||
|
|
||||||
|
|
||||||
|
_subsection: Test Suite API @<testing-api>
|
||||||
|
|
||||||
|
There are also convenience functions for those developing directly in TypeScript.
|
||||||
|
|
||||||
|
_property: testcases.loadTests(tag) => Array<TestCase>
|
||||||
|
Load all the given testcases for the //tag//.
|
||||||
|
|
||||||
|
A tag is the string in the above list of test case names not including
|
||||||
|
any extenstion (e.g. ``"solidity-hashes"``)
|
||||||
|
|
||||||
|
_property: testcases.TestCase.TEST_NAME
|
||||||
|
Most testcases have its schema available as a TypeScript type to make testing
|
||||||
|
each property easier.
|
||||||
|
|
||||||
|
_heading: Deterministic Random Numbers (DRNG)
|
||||||
|
|
||||||
|
When creating test cases, often we want want random data from the perspective
|
||||||
|
we do not case what values are used, however we want the values to be consistent
|
||||||
|
accross runs. Otherwise it becomes difficult to reproduce an issue.
|
||||||
|
|
||||||
|
In each of the following the seed is used to control the random value returned. Be
|
||||||
|
sure to tweak the seed properly, for eaxmple on each iteration change the value and
|
||||||
|
in recursive functions, concatentate to the seed.
|
||||||
|
|
||||||
|
_property: testcases.randomBytes(seed, lower [, upper ]) => Uint8Array
|
||||||
|
Return at least //lower// random bytes, up to //upper// (exclusive) if specified,
|
||||||
|
given //seed//. If //upper// is omitted, exactly ///lower// bytes are returned.
|
||||||
|
|
||||||
|
_property: testcases.randomHexString(seed, lower [, upper ]) => string<[[DataHexString]]>
|
||||||
|
Identical to randomBytes, except returns the value as a [[DataHexString]] instead of a
|
||||||
|
Uint8Array.
|
||||||
|
|
||||||
|
_property: testcases.randomNumber(seed, lower, upper) => number
|
||||||
|
Returns a random number of at least //lower// and less than //upper//
|
||||||
|
given //seed//.
|
||||||
|
|
||||||
|
|
||||||
|
_subsection: Schemas @<testing-schemas>
|
||||||
|
|
||||||
|
This section is still a work in progress, but will outline some of the more nuanced
|
||||||
|
aspects of the test cases and their values.
|
||||||
|
|
||||||
|
There will likely be an overhaul of the test cases in the next major version, to
|
||||||
|
make code coverage testing more straight forward and to collapse some of the redundancy.
|
||||||
|
|
||||||
|
For example, there is no longer a need to separate the ABI and ABIv2 test case and the
|
||||||
|
accounts and transactions suites can be merged into one large collection.
|
||||||
|
|
||||||
|
|
||||||
|
_heading: Accounts
|
||||||
|
|
||||||
|
Basic account information using a private key and computing various addrss forms.
|
||||||
|
|
||||||
|
Tests were verfified against [EthereumJS](https:/\/github.com/ethereumjs) and custom
|
||||||
|
scripts created to directly interact with Geth and cpp implementations.
|
||||||
|
|
||||||
|
//See: ``accounts.json.gz``//
|
||||||
|
|
||||||
|
_table: Properties
|
||||||
|
|
||||||
|
| **Property** | **Meaning** |
|
||||||
|
| name | The testcase name |
|
||||||
|
| privateKey | The private key |
|
||||||
|
| address | The address (lowercase) |
|
||||||
|
| checksumAddress | The address with checksum-adjusted case |
|
||||||
|
| icapAddress | The ICAP address |
|
||||||
|
|
||||||
|
_code: Example @lang<script>
|
||||||
|
{
|
||||||
|
"name": "random-1023",
|
||||||
|
"address": "0x53bff74b9af2e3853f758a8d2bd61cd115d27782",
|
||||||
|
"privateKey": "0x8ab0e165c2ea461b01cdd49aec882d179dccdbdb5c85c3f9c94c448aa65c5ace",
|
||||||
|
"checksumAddress": "0x53bFf74b9Af2E3853f758A8D2Bd61CD115d27782",
|
||||||
|
"icapAddress": "XE709S6NUSJR6SXQERCMYENAYYOZ2Y91M6A"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_heading: Contract Interface
|
||||||
|
|
||||||
|
Procedurally generated test cases to test ABI coding.
|
||||||
|
|
||||||
|
_code: Example @lang<script>
|
||||||
|
{
|
||||||
|
"name": "random-1999",
|
||||||
|
"source": "contract Test {\n function test() constant returns (address, bool, bytes14[1]) {\n address a = address(0x061C7F399Ee738c97C7b7cD840892B281bf772B5);\n bool b = bool(true);\n bytes14[1] memory c;\n c[0] = bytes14(0x327621c4abe12d4f21804ed40455);\n return (a, b, c);\n }\n}\n",
|
||||||
|
"types": "[\"address\",\"bool\",\"bytes14[1]\"]",
|
||||||
|
"interface": "[{\"constant\":true,\"inputs\":[],\"name\":\"test\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"bool\"},{\"name\":\"\",\"type\":\"bytes14[1]\"}],\"type\":\"function\"}]\n",
|
||||||
|
"bytecode": "0x6060604052610175806100126000396000f360606040526000357c010000000000000000000000000000000000000000000000000000000090048063f8a8fd6d1461003957610037565b005b610046600480505061009d565b604051808473ffffffffffffffffffffffffffffffffffffffff1681526020018315158152602001826001602002808383829060006004602084601f0104600f02600301f150905001935050505060405180910390f35b600060006020604051908101604052806001905b60008152602001906001900390816100b157905050600060006020604051908101604052806001905b60008152602001906001900390816100da5790505073061c7f399ee738c97c7b7cd840892b281bf772b59250600191506d327621c4abe12d4f21804ed404557201000000000000000000000000000000000000028160006001811015610002579090602002019071ffffffffffffffffffffffffffffffffffff191690818152602001505082828295509550955061016d565b50505090919256",
|
||||||
|
"result": "0x000000000000000000000000061c7f399ee738c97c7b7cd840892b281bf772b50000000000000000000000000000000000000000000000000000000000000001327621c4abe12d4f21804ed40455000000000000000000000000000000000000",
|
||||||
|
"values": "[{\"type\":\"string\",\"value\":\"0x061C7F399Ee738c97C7b7cD840892B281bf772B5\"},{\"type\":\"boolean\",\"value\":true},[{\"type\":\"buffer\",\"value\":\"0x327621c4abe12d4f21804ed40455\"}]]",
|
||||||
|
"normalizedValues": "[{\"type\":\"string\",\"value\":\"0x061C7F399Ee738c97C7b7cD840892B281bf772B5\"},{\"type\":\"boolean\",\"value\":true},[{\"type\":\"buffer\",\"value\":\"0x327621c4abe12d4f21804ed40455\"}]]",
|
||||||
|
"runtimeBytecode": "0x60606040526000357c010000000000000000000000000000000000000000000000000000000090048063f8a8fd6d1461003957610037565b005b610046600480505061009d565b604051808473ffffffffffffffffffffffffffffffffffffffff1681526020018315158152602001826001602002808383829060006004602084601f0104600f02600301f150905001935050505060405180910390f35b600060006020604051908101604052806001905b60008152602001906001900390816100b157905050600060006020604051908101604052806001905b60008152602001906001900390816100da5790505073061c7f399ee738c97c7b7cd840892b281bf772b59250600191506d327621c4abe12d4f21804ed404557201000000000000000000000000000000000000028160006001811015610002579090602002019071ffffffffffffffffffffffffffffffffffff191690818152602001505082828295509550955061016d565b50505090919256"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_heading: Contract Signatures
|
||||||
|
|
||||||
|
Computed ABI signatures and the selector hash.
|
||||||
|
|
||||||
|
_code: Example @lang<script>
|
||||||
|
{
|
||||||
|
"name": "random-1999",
|
||||||
|
"sigHash": "0xf51e9244",
|
||||||
|
"abi": "[{\"constant\":false,\"inputs\":[{\"name\":\"r0\",\"type\":\"string[2]\"},{\"name\":\"r1\",\"type\":\"uint128\"},{\"components\":[{\"name\":\"a\",\"type\":\"bytes\"},{\"name\":\"b\",\"type\":\"bytes\"},{\"name\":\"c\",\"type\":\"bytes\"}],\"name\":\"r2\",\"type\":\"tuple\"},{\"name\":\"r3\",\"type\":\"bytes\"}],\"name\":\"testSig\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"test\",\"outputs\":[{\"name\":\"r0\",\"type\":\"string[2]\"},{\"name\":\"r1\",\"type\":\"uint128\"},{\"components\":[{\"name\":\"a\",\"type\":\"bytes\"},{\"name\":\"b\",\"type\":\"bytes\"},{\"name\":\"c\",\"type\":\"bytes\"}],\"name\":\"r2\",\"type\":\"tuple\"},{\"name\":\"r3\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}]",
|
||||||
|
"signature": "testSig(string[2],uint128,(bytes,bytes,bytes),bytes)"
|
||||||
|
}
|
||||||
|
|
||||||
|
_heading: Hashes
|
||||||
|
|
||||||
|
_code: Examples @lang<script>
|
||||||
|
{
|
||||||
|
"data": "0x3718a88ceb214c1480c32a9d",
|
||||||
|
"keccak256": "0x82d7d2dc3d384ddb289f41917b8280675bb1283f4fe2b601ac7c8f0a2c2824fa",
|
||||||
|
"sha512": "0xe93462bb1de62ba3e6a980c3cb0b61728d3f771cea9680b0fa947b6f8fb2198a2690a3a837495c753b57f936401258dfe333a819e85f958b7d786fb9ab2b066c",
|
||||||
|
"sha256": "0xe761d897e667aa72141dd729264c393c4ddda5c62312bbd21b0f4d954eba1a8d"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_heading: Hierarchal Deterministic Node (BIP-32)
|
||||||
|
|
||||||
|
Tests for [BIP-32](link-bip-32) HD Wallets.
|
||||||
|
|
||||||
|
_code: Example @lang<script>
|
||||||
|
{
|
||||||
|
"name": "trezor-23",
|
||||||
|
"entropy": "0xf585c11aec520db57dd353c69554b21a89b20fb0650966fa0a9d6f74fd989d8f",
|
||||||
|
"mnemonic": "void come effort suffer camp survey warrior heavy shoot primary clutch crush open amazing screen patrol group space point ten exist slush involve unfold",
|
||||||
|
"locale": "en",
|
||||||
|
"password": "TREZOR",
|
||||||
|
"hdnodes": [
|
||||||
|
{
|
||||||
|
"path": "m",
|
||||||
|
"address": "0xfd8eb95169ce57eab52fb69bc6922e9b6454d9aa",
|
||||||
|
"privateKey": "0x679bf92c04cf16307053cbed33784f3c4266b362bf5f3d7ee13bed6f2719743c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0xada964e9f10c4fc9787f9e17f00c63fe188722b0",
|
||||||
|
"privateKey": "0xdcbcb48a2b11eef0aab93a8f88d83f60a3aaabb34f9ffdbe939b8f059b30f2b7",
|
||||||
|
"path": "m/8'/8'/2/3/4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"privateKey": "0x10fd3776145dbeccb3d6925e4fdc0d58b452fce40cb8760b12f8b4223fafdfa6",
|
||||||
|
"address": "0xf3f6b1ef343d5f5f231a2287e801a46add43eb06",
|
||||||
|
"path": "m/1'/3'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0xb7b0fdb6e0f79f0529e95400903321e8a601b411",
|
||||||
|
"privateKey": "0x093a8ff506c95a2b79d397aed59703f6212ff3084731c2f03089b069ae76e69d",
|
||||||
|
"path": "m/8'/4'/7'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "m/7'/5'/11",
|
||||||
|
"privateKey": "0x6bd79da4dfa7dd0abf566a011bdb7cba0d28bba9ca249ba25880d5dabf861b42",
|
||||||
|
"address": "0x1b3ad5fa50ae32875748107f4b2160829cc10536"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "m/9'/6'/2'/7'/3'",
|
||||||
|
"address": "0x42eb4bed59f3291d02387cf0fb23098c55d82611",
|
||||||
|
"privateKey": "0xfc173acba7bc8bb2c434965d9e99f5a221f81add421bae96a891d08d60be11dd"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"seed": "0x01f5bced59dec48e362f2c45b5de68b9fd6c92c6634f44d6d40aab69056506f0e35524a518034ddc1192e1dacd32c1ed3eaa3c3b131c88ed8e7e54c49a5d0998"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_heading: ENS Namehash
|
||||||
|
|
||||||
|
Test cases for the [ENS Namehash Algorithm](link-namehash).
|
||||||
|
|
||||||
|
_code: Examples
|
||||||
|
{
|
||||||
|
"expected": "0x33868cc5c3fd3a9cd3adbc1e868ea133d2218f60dc2660c3bc48d8b1f4961384",
|
||||||
|
"name": "ViTalIk.WALlet.Eth",
|
||||||
|
"test": "mixed case"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_heading: RLP Coder
|
||||||
|
|
||||||
|
_code: Examples @lang<script>
|
||||||
|
{
|
||||||
|
"name": "arrayWithNullString3",
|
||||||
|
"encoded": "0xc3808080",
|
||||||
|
"decoded": [ "0x", "0x", "0x" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_heading: Solidity Hashes
|
||||||
|
|
||||||
|
Tests for the non-standard packed form of the Solidity hash functions.
|
||||||
|
|
||||||
|
These tests were created by procedurally generating random signatures and
|
||||||
|
values that match those signatures, constructing the equivalent Soldity,
|
||||||
|
compiling it and deploying it to a Parity node then evaluating the response.
|
||||||
|
|
||||||
|
_code: Example @lang<script>
|
||||||
|
{
|
||||||
|
"name": "random-1999",
|
||||||
|
"keccak256": "0x7d98f1144a0cd689f720aa2f11f0a73bd52a2da1117175bc4bacd93c130966a1",
|
||||||
|
"ripemd160": "0x59384617f8a06efd57ab106c9e0c20c3e64137ac000000000000000000000000",
|
||||||
|
"sha256": "0xf9aeea729ff39f8d372d8552bca81eb2a3c5d433dc8f98140040a03b7d81ac92",
|
||||||
|
"values": [
|
||||||
|
"0xcdffcb5242e6",
|
||||||
|
"0xc1e101b60ebe4688",
|
||||||
|
"0x5819f0ef5537796e43bdcd48309f717d6f7ccffa",
|
||||||
|
"0xec3f3f9f",
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
"types": [
|
||||||
|
"int184",
|
||||||
|
"int176",
|
||||||
|
"address",
|
||||||
|
"int64",
|
||||||
|
"bool",
|
||||||
|
"bool"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_heading: Transactions
|
||||||
|
|
||||||
|
Serialized signed and unsigned transactions with both EIP-155 enabled and
|
||||||
|
disabled.
|
||||||
|
|
||||||
|
_code: Examples @lang<script>
|
||||||
|
{
|
||||||
|
"name": "random-998",
|
||||||
|
"privateKey": "0xd16c8076a15f7fb583f05dc12686fe526bc59d298f1eb7b9a237b458133d1dec",
|
||||||
|
"signedTransactionChainId5": "0xf8708391d450848517cfba8736fcf36da03ee4949577303fd4e0acbe72c6c116acab5bf63f0b1e9c8365fdc7827dc82ea059891894eb180cb7c6c45a52f62d2103420d3ad0bc3ba518d0a25ed910842522a0155c0ea2aee2ea82e75843aab297420bad907d46809d046b13d692928f4d78aa",
|
||||||
|
"gasLimit": "0x36fcf36da03ee4",
|
||||||
|
"to": "0x9577303fd4e0acbe72c6c116acab5bf63f0b1e9c",
|
||||||
|
"data": "0x7dc8",
|
||||||
|
"accountAddress": "0x6d4a6aff30ca5ca4b8422eea0ebcb669c7d79859",
|
||||||
|
"unsignedTransaction": "0xed8391d450848517cfba8736fcf36da03ee4949577303fd4e0acbe72c6c116acab5bf63f0b1e9c8365fdc7827dc8",
|
||||||
|
"nonce": "0x91d450",
|
||||||
|
"gasPrice": "0x8517cfba",
|
||||||
|
"signedTransaction": "0xf8708391d450848517cfba8736fcf36da03ee4949577303fd4e0acbe72c6c116acab5bf63f0b1e9c8365fdc7827dc81ba05030832331e6be48c95e1569a1ca9505c495486f72d6009b3a30fadfa05d9686a05cd3116b416d2362da1e9b0ca7fb1856c4e591cc22e63b395bd881ce2d3735e6",
|
||||||
|
"unsignedTransactionChainId5": "0xf08391d450848517cfba8736fcf36da03ee4949577303fd4e0acbe72c6c116acab5bf63f0b1e9c8365fdc7827dc8058080",
|
||||||
|
"value": "0x65fdc7"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_heading: Units
|
||||||
|
|
||||||
|
Unit conversion.
|
||||||
|
|
||||||
|
_code: Example @lang<script>
|
||||||
|
{
|
||||||
|
"name": "one-two-three-3",
|
||||||
|
"gwei_format": "-1234567890123456.789012345",
|
||||||
|
"ether_format": "-1234567.890123456789012345",
|
||||||
|
"gwei": "-1234567890123456.789012345",
|
||||||
|
"ether": "-1234567.890123456789012345",
|
||||||
|
"finney": "-1234567890.123456789012345",
|
||||||
|
"wei": "-1234567890123456789012345",
|
||||||
|
"finney_format": "-1234567890.123456789012345"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_heading: Wallets
|
||||||
|
|
||||||
|
Tests for the JSON keystore format.
|
||||||
|
|
||||||
|
_code: Example @lang<script>
|
||||||
|
{
|
||||||
|
"mnemonic": null,
|
||||||
|
"name": "secretstorage_password",
|
||||||
|
"type": "secret-storage",
|
||||||
|
"password": "foo",
|
||||||
|
"privateKey": "0xf03e581353c794928373fb0893bc731aefc4c4e234e643f3a46998b03cd4d7c5",
|
||||||
|
"hasAddress": true,
|
||||||
|
"json": "{\"address\":\"88a5c2d9919e46f883eb62f7b8dd9d0cc45bc290\",\"Crypto\":{\"cipher\":\"aes-128-ctr\",\"ciphertext\":\"10adcc8bcaf49474c6710460e0dc974331f71ee4c7baa7314b4a23d25fd6c406\",\"cipherparams\":{\"iv\":\"1dcdf13e49cea706994ed38804f6d171\"},\"kdf\":\"scrypt\",\"kdfparams\":{\"dklen\":32,\"n\":262144,\"p\":1,\"r\":8,\"salt\":\"bbfa53547e3e3bfcc9786a2cbef8504a5031d82734ecef02153e29daeed658fd\"},\"mac\":\"1cf53b5ae8d75f8c037b453e7c3c61b010225d916768a6b145adf5cf9cb3a703\"},\"id\":\"fb1280c0-d646-4e40-9550-7026b1be504a\",\"version\":3}\n",
|
||||||
|
"address": "0x88a5c2d9919e46f883eb62f7b8dd9d0cc45bc290"
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user