Added documentation.

This commit is contained in:
Richard Moore 2020-04-16 22:25:05 -04:00
parent 5b51549437
commit 723249d36c
No known key found for this signature in database
GPG Key ID: 665176BE8E9DC651
23 changed files with 237 additions and 43 deletions

@ -11,6 +11,13 @@ Building
--------
```
/home/ricmoo/ethers.js> npm run build-docs
/home/ricmoo/ethers.js> npm run build-docs
```
License
-------
All documentation for ethers.js and Flatworm is released under the
[Creative Commons Attribution 4.0 International License](https://choosealicense.com/licenses/cc-by-4.0/)
license.

@ -130,14 +130,14 @@ _heading: Write Methods Analysis @<contract-write-check>
There are secveral options to analyze properties and results of a
write method without actually executing it.
_property: contract.estimate.METHOD_NAME(...args [ , overrides ]) => Promise<[[bignumber]]> @<contract-estimateGas>
_property: contract.estimateGas.METHOD_NAME(...args [ , overrides ]) => Promise<[[bignumber]]> @<contract-estimateGas>
Returns the estimate units of gas that would be required to
execute the //METHOD_NAME// with //args// and //overrides//.
_property: contract.populateTransaction.METHOD_NAME(...args [ , overrides ]) => Promise<[UnsignedTx](types-unsignedtransaction)> @<contract-populateTransaction>
Returns an [[types-unsignedtransaction]] which represents the transaction
that would need to be signed and submitted to the network to execute
//METHOD_NAME// with //args/ and //overrides//.
//METHOD_NAME// with //args// and //overrides//.
_property: contract.staticCall.METHOD_NAME(...args [ , overrides ]) => Promise<any> @<contract-staticCall>
Rather than executing the state-change of a transaction, it is possible

@ -14,7 +14,7 @@ add the additional properties defined in //abi// to a **Contract**
connected to //address// using the //providerOrSigner//.
_subsection: Properties ^^//(inheritted from [[contract]])//^^
_subsection: Properties @NOTE<(inheritted from [[contract]])>
_property: erc20.address => string<[[address]]>
This is the address (or ENS name) the contract was constructed with.
@ -40,7 +40,7 @@ _property: erc20.signer => [[signer]]
If a signer was provided to the constructor, this is that signer.
_subsection: Methods ^^//(inheritted from [[contract]])//^^
_subsection: Methods @NOTE<(inheritted from [[contract]])>
_property: erc20.attach(addressOrName) => [[contract]]
Returns a new instance of the **Contract** attached to a new
@ -63,7 +63,7 @@ _property: erc20.deployed() => Promise<Contract>
_property: Contract.isIndexed(value) => boolean
_subsection: Events ^^//(inheritted from Contract)//^^ @<erc20-events>
_subsection: Events @NOTE<(inheritted from [[contract]])> @<erc20-events>
_property: erc20.queryFilter(event [ , fromBlockOrBlockHash [ , toBlock ]) => Promise<Array<Event>> @<erc20-queryfilter>
Return Events that match the //event//.
@ -90,7 +90,7 @@ Unsubscribe all listeners for //event//. If no event is provided,
all events are unsubscribed.
_subsection: Meta-Class Methods ^^//(added at Runtime)//^^
_subsection: Meta-Class Methods @NOTE<(added at Runtime)>
Since the Contract is a Meta-Class, the methods available here depend
on the ABI which was passed into the **Contract**.
@ -137,7 +137,7 @@ blockchain also means there are certain consistency modes that cannot be
known until an actual transaction is attempted.
_subsection: Meta-Class Filters ^^//(added at Runtime)//^^
_subsection: Meta-Class Filters @NOTE<(added at Runtime)>
Since the Contract is a Meta-Class, the methods available here depend
on the ABI which was passed into the **Contract**.

@ -0,0 +1,65 @@
_section: Experimental
The **Experimental** package is used for features that are not ready
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.
_subsection: BrainWallet @<experimental-brainwallet> @INHERIT<[[wallet]]>
Ethers removed support for BrainWallets in v4, since they are unsafe and
many can be easily guessed, allowing attackers to steal the funds. This
class is offered to ensure older systems which used brain wallets can
still recover their funds and assets.
_property: BrainWallet.generate(username, password [ , progressCallback ]) => [[experimental-brainwallet]]
Generates a brain wallet, with a slightly improved experience, in which
the generated wallet has a mnemonic.
_property: BrainWallet.generateLegacy(username, password [ , progressCallback ]) => [[experimental-brainwallet]]
Generate a brain wallet which is compatibile with the ethers v3 and earlier.
_subsection: EIP1193Bridge @<experimental-eip1193bridge> @INHERIT<[[link-npm-events]]>
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.
_subsection: NonceManager @<experimental-noncemanager> @INHERIT<[[signer]]>
The **NonceManager** is designed to manage the nonce for a Signer,
automatically increasing it as it sends transactions.
Currently the NonceManager does not handle re-broadcast. If you attempt
to send a lot of transactions to the network on a node that does not
control that account, the transaction pool may drop your transactions.
In the future, it'd be nice if the **NonceManager** remembered transactions
and watched for them on the network, rebroadcasting transactions that
appear to have been dropped.
Another future feature will be some sort of failure mode. For example, often
a transaction is dependent on another transaction being mined first.
_property: new NonceManager(signer)
Create a new NonceManager.
_property: nonceManager.signer => [[signer]]
The signer whose nonce is being managed.
_property: nonceManager.provider => [[provider]]
The provider associated with the signer.
_property: nonceManager.setTransactionCount(count) => void
Set the current transaction count (nonce) for the signer.
This may be useful it interacting with the signer outside of using
this class.
_property: nonceManager.increaseTransactionCount( [ count = 1 ]) => void
Bump the current transaction count (nonce) by //count//.
This may be useful it interacting with the signer outside of using
this class.

@ -1,6 +1,7 @@
_section: Application Programming Interface @NAV<API>
Here...
An Application Programming Interface (API) is the formal
specification of the library.
_toc:
contract
@ -8,3 +9,4 @@ _toc:
providers
utils
other
experimental

@ -56,9 +56,9 @@ _definition: **Supported Networks**
- Kovan (proof-of-authority testnet)
_subsection: CloudfrontProvider @INHERIT<[[provider-urljsonrpc]]>
_subsection: CloudflareProvider @INHERIT<[[provider-urljsonrpc]]>
The CloudfrontProvider is backed by the [Cloudflare Ethereum Gateway](link-cloudflare).
The CloudflareProvider is backed by the [Cloudflare Ethereum Gateway](link-cloudflare).
_definition: **Supported Networks**

@ -7,8 +7,8 @@ and [Parity](link-parity)) as well as many third-party web
services (e.g. [INFURA](link-infura))
_property: new ethers.providers.JsonRpcProvider([ url [ , aNetworkish ] ])
Connect to a JSON-RPC API located at //url// using the /aNetworkish// network.
If //url// is not specified, the default (i.e. ``http://localhost:8545``) is used
Connect to a JSON-RPC API located at //url// using the //aNetworkish// network.
If //url// is not specified, the default (i.e. ``http:/\/localhost:8545``) is used
and if no network is specified, it will be determined automatically by
querying the node.

@ -5,17 +5,17 @@ Explain what a provider is...
_subsection: Accounts Methods
_property: provider.getBalance(address [ , blockTag = "latest" ]) => Promise<[[bignumber]]> @<provider-getbalance> @SRC<providers/base-provider>
_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.
_property: provider.getCode(address [ , blockTag = "latest" ]) => Promise<string<[[datahexstring]]>> @<providers-getcode> @SRC<providers/base-provider>
_property: provider.getCode(address [ , blockTag = latest ]) => Promise<string<[[datahexstring]]>> @<providers-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``.
_property: provider.getStorageAt(addr, pos [ , blockTag = "latest" ]) => Promise<string<[[datahexstring]]>> @<providers-getstorageat> @SRC<providers/base-provider>
_property: provider.getStorageAt(addr, pos [ , blockTag = latest ]) => Promise<string<[[datahexstring]]>> @<providers-getstorageat> @SRC<providers/base-provider>
Returns the ``Bytes32`` value of the position //pos// at address //addr//, as of the //blockTag//.
_property: provider.getTransactionCount(address [ , blockTag = "latest" ]) => Promise<number> @<providers-gettransactioncount> @SRC<providers/base-provider>
_property: provider.getTransactionCount(address [ , blockTag = latest ]) => Promise<number> @<providers-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.
@ -78,7 +78,7 @@ Returns a //best guess// of the [[gas-price]] to use in a transaction.
_subsection: Transactions Methods
_property: provider.call(transaction [ , blockTag = "latest" ]) => Promise<string<[[hexstring]]>> @<providers-call> @SRC<providers/base-provider>
_property: provider.call(transaction [ , blockTag = latest ]) => Promise<string<[[datahexstring]]>> @<providers-call> @SRC<providers/base-provider>
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 gettings on Contracts.
@ -96,7 +96,7 @@ Submits //transaction// to the network to be mined. The //transaction// **must**
and be valid (i.e. the nonce is correct and the account has sufficient balance to pay
for the transaction).
_property: provider.waitForTransaction(transactionHash) => Promise<[[provider-receipt]]> @<providers-waitfortransaction> @SRC<providers/base-provider>
_property: provider.waitForTransaction(hash [ , confirms = 1 [ , timeout ] ]) => Promise<[TxReceipt](provider-receipt)> @<providers-waitfortransaction> @SRC<providers/base-provider>
Returns a Promise which will not resolve until //transactionHash// is mined.

@ -236,7 +236,7 @@ _property: receipt.from => string<[[address]]>
The address this transaction is from.
_property: receipt.contractAddress => string<[[address]]>
If this transaction has a ``null` to address, it is an **init transaction**
If this transaction has a ``null`` to address, it is an **init transaction**
used to deploy a contract, in which case this is the address created by that
contract.

@ -146,6 +146,13 @@ Create an instance from an encrypted JSON wallet. If //progress//
is provided it will be called during decryption with a value between 0 and
1 indicating the progress towards completion.
_property: ethers.Wallet.fromEncryptedJsonSync(json, password) => [[wallet]] @<wallet-fromencryptedjsonsync> @SRC<wallet>
Create an instance from an encrypted JSON wallet.
This operation will operate synchronously which will lock up the user
interface, possibly for a non-trivial duration. Most applications should
use the asynchronous ``fromEncryptedJson`` instead.
_property: ethers.Wallet.fromMnemonic(mnemonic [ , path, [ wordlist ] ]) => [[wallet]]
Create an instance from a mnemonic phrase.

@ -1,5 +1,19 @@
_section: Application Binary Interface @NAV<ABI>
An **Application Binary Interface** (ABI) is a collection of
[Fragments](abi-fragment) which specify how to interact with
various components of a Contract.
An [[abi-interface]] helps organize Fragments by type as well
as provides the functionality required to encode, decode and
work with each component.
Most developers will not require this low-level access to encoding
and decoding the binary data on the network and will most likely
use a [[contract]] which provides a more convenient interface. Some
framework, tool developers or developers using advanced techniques
may find these classes and utilities useful.
_toc:
interface
fragments

@ -187,10 +187,10 @@ _subsection: Specifying Fragments @<abi-fragmentid>
When specifying a fragment to any of the functions in an **Interface**,
any of the following may be used:
- The name of the event or function, if it is unique and non-ambiguous
- The **name** of the event or function, if it is unique and non-ambiguous
within the ABI (e.g. ``transfer``)
- The signature of the event or function. The signature is normalized,
- The **signature** of the event or function. The signature is normalized,
so, for example, ``uint`` and ``uint256`` are equivalent (e.g. ``transfer(address, uint)``)
- The sighash or topichash of the function. The sighash is often referred
- The **sighash** or **topichash** of the function. The sighash is often referred
to the function selector in Solidity (e.g. ``0xa9059cbb``)
- A [[abi-fragment]]
- A [[abi-fragment]]

@ -12,5 +12,5 @@ function _inspect(result) {
let a = BigNumber.from(42);
let b = BigNumber.from("91");
a.mul(b);
//!
a.mul(b);
//!

@ -71,10 +71,10 @@ _property: bignumber.mul(otherValue) => [[bignumber]] @SRC<bignumber>
Returns a BigNumber with the value of //bignumber// **&times;** //otherValue//.
_property: bignumber.div(divisor) => [[bignumber]] @SRC<bignumber>
Returns a BigNumber with the value of //bignumber// **&#247;** //divisor//.
Returns a BigNumber with the value of //bignumber// **&div;** //divisor//.
_property: bignumber.mod(divisor) => [[bignumber]] @SRC<bignumber>
Returns a BigNumber with the value of the **remainder** of //bignumber// &#247; //divisor//.
Returns a BigNumber with the value of the **remainder** of //bignumber// &div; //divisor//.
_property: bignumber.pow(exponent) => [[bignumber]] @SRC<bignumber>
Returns a BigNumber with the value of //bignumber// to the power of //exponent//.
@ -82,7 +82,7 @@ Returns a BigNumber with the value of //bignumber// to the power of //exponent//
_property: bignumber.abs() => [[bignumber]] @SRC<bignumber>
Returns a BigNumber with the absolute value of //bignumber//.
_property: bignumber.maskn(bitcount) => [[bignumber]] @SRC<bignumber>
_property: bignumber.mask(bitcount) => [[bignumber]] @SRC<bignumber>
Returns a BigNumber with the value of //bignumber// with bits beyond
the //bitcount// least significant bits set to zero.
@ -176,8 +176,8 @@ _code: bignumber-ieee754.js
To remedy this, all numbers (which can be large) are stored
and manipulated as [Big Numbers](bignumber).
The functions [parseEther( etherString )](http://linkto) and
[formatEther( wei )](http://linkto) can be used to convert
The functions [parseEther( etherString )](utils-parseether) and
[formatEther( wei )](utils-formatether) can be used to convert
between string representations, which are displayed to or entered
by the user and Big Number representations which can have
mathematical operations handled safely.
@ -222,7 +222,7 @@ over other libraries which include separate Big Number libraries for
various purposes.
_heading: Why not allow us to set a global Big Number library?
_heading: Allow us to set a global Big Number library?
Another comment that comes up frequently is tha desire to specify a
global user-defined Big Number library, which all functions would

@ -93,10 +93,10 @@ larger than 256 bits and the number of decimals must be no larger than 80.
For example:
- **fixed128x18** is signed, 128 bits wide and has 18 decimals; this is useful for most purposes
- **fixed32x0** is signed, 32 bits wide and has 0 decimals; this would be the same as a ``int32_t` in C
- **ufixed32x0** is unsigned, 32 bits wide and has 0 decimals; this would be the same as a ``uint32_t` in C
- **fixed** is shorthand for ``fixed128x18`
- **ufixed** is shorthand for ``ufixed128x18`
- **fixed32x0** is signed, 32 bits wide and has 0 decimals; this would be the same as a ``int32_t`` in C
- **ufixed32x0** is unsigned, 32 bits wide and has 0 decimals; this would be the same as a ``uint32_t`` in C
- **fixed** is shorthand for ``fixed128x18``
- **ufixed** is shorthand for ``ufixed128x18``
_heading: Creating Instances

@ -1,6 +1,6 @@
_section: Property Utilities
_property: ethers.utils.checkPropertoes() => void
_property: ethers.utils.checkProperties() => void
_property: ethers.utils.deepCopy(anObject) => any
_property: ethers.utils.defineReadOnly(anObject, name, value) => void

@ -14,7 +14,7 @@ _property: signingKey.compressedPublicKey => string<[[datahexstring]]<33>>
The compressed public key for this Signing Key. It will always be
33 bytes (66 nibbles) and begine with either ``0x02`` or ``0x03``.
_property: signingKey.signDisgest(digest) => [[signature]]
_property: signingKey.signDigest(digest) => [[signature]]
Sign the //digest// and return the signature.
_property: signingKey.computeSharedSecret(otherKey) => string<[[datahexstring]]<32>>
@ -39,7 +39,7 @@ will then be used to compute the address; this allows systems which use
the v to encode additional data (such as [EIP-155](link-eip-155))
to be used since the v parameter is still completely non-ambiguous.
_property: ethers.utils.recocverPublicKey(digest, signature) => string<[[datahexstring]]<65>> @<utils-recoverpublickey>
_property: ethers.utils.recoverPublicKey(digest, signature) => string<[[datahexstring]]<65>> @<utils-recoverpublickey>
_property: ethers.utils.computePublicKey(key [, compressed = false ]) => string<[[datahexstring]]> @<utils-computepublickey>
Computes the public key of //key//, optionally compressing it. The //key//

@ -1,4 +1,4 @@
_section: Concepts
_section: Ethereum Basics
This is a very breif overview of some aspects of //Ethereum//
and blockchains which developers can make use of or should
@ -7,3 +7,4 @@ be aware of.
_toc:
events
gas
security

@ -0,0 +1,68 @@
_section: Security
_subsection: Key Derivation Functions @<security-pbkdf>
This is not specific to Ethereum, but is a useful technique
to understand and has some implications on User Experience.
Many people are concerned that encrypting and decrypting an
Ethereum wallet is quite slow and can take quite some time.
It is important to understand this is intentional and provides
much stronger security.
The algorithm usually used for this process is [scrypt](link-wiki-scrypt),
which is a memory and CPU intensive algorithm which computes
a key (fixed-length psudo-random series of bytes) for a given
password.
_heading: Why does it take so long?
The goal is to use as much CPU and memory as possible during
this algorithm, so that a single computer can only compute a
very small number of results for some fixed amount of time. To
scale up an attack, the attacker requires additional compuers,
increasing the cost to [brute-force attack](link-wiki-bruteforce)
to guess the password.
For example, if a user knows their correct password, this process
may take 10 seconds for them to unlock their own wallet and proceed.
But since an attacker does not know the password, they must guess; and
each guess also requires 10 seconds. So, if they wish to try guessing 1
million passwords, their computer would be completely tied up for 10
million seconds, or around 115 days.
Without using an algorithm like this, a user would be able
to log in instantly, however, 1 million passwords would only
take a few seconds to attempt. Even secure passwords would
likely be broken within a short period of time. There is no way
the algorithm can be faster for a legitimate user without also
being faster for an attacker.
_heading: Mitigating the User Experience
Rather than reducing the security (see below), a better practice is to make
the user feel better about waiting. The Ethers encryption and decryption
API allows the developer to incorporate a progress bar, by passing in a
progress callback which will be periodically called with a number between
0 and 1 indication percent completion.
In general a progress bar makes the experience feel faster, as well as
more comfortable since there is a clear indication how much (relative) time
is remaining. Additionally, using language like //"decrpyting..."// in
a progress bar makes a user feel like there time is not being //needlessly//
wasted.
_heading: Work-Arounds (not recommended)
There are ways to reduce the time required to decrypt an Ethereum JSON
Wallet, but please keep in mind that doing so **discards nearly all security**
on that wallet.
The scrypt algorithm is designed to be tuned. The main purpose of this is
to increase the difficulty as time goes on and computers get faster, but
it can also be tuned down in situations where the security is less important.
_code: lightkdf.js

@ -0,0 +1,23 @@
// <hide>
const { Wallet } = require("./packages/ethers");
// </hide>
// Our wallet object
const wallet = Wallet.createRandom();
// The password to encrypt with
const password = "password123";
// WARNING: Doing this substantially reduces the security
// of the wallet. This is highly NOT recommended.
// We override the default scrypt.N value, which is used
// to indicate the difficulty to crack this wallet.
const json = wallet.encrypt(password, {
scrypt: {
// The number must be a power of 2 (default: 131072)
N: 64
}
});

@ -121,6 +121,7 @@ module.exports = {
logo: "logo.svg",
link: "https://docs-beta.ethers.io",
copyright: "The content of this site is licensed under the [Creative Commons Attribution 4.0 International License](https://choosealicense.com/licenses/cc-by-4.0/).",
markdown: {
"banner": "-----\n\nDocumentation: [html](https://docs-beta.ethers.io/)\n\n-----\n\n"
@ -128,6 +129,8 @@ module.exports = {
getSourceUrl: getSourceUrl,
codeRoot: "../",
externalLinks: {
"link-alchemy": "https:/\/alchemyapi.io",
"link-cloudflare": "https:/\/developers.cloudflare.com/distributed-web/ethereum-gateway/",
@ -141,6 +144,7 @@ module.exports = {
"link-metamask": "https:/\/metamask.io/",
"link-parity": "https:/\/www.parity.io",
"link-rtd": "https:/\/github.com/readthedocs/sphinx_rtd_theme",
"link-semver": { name: "semver", url: "https:/\/semver.org" },
"link-solidity": { name: "Solidity" , url: "https:/\/solidity.readthedocs.io/en/v0.6.2/" },
"link-sphinx": "https:/\/www.sphinx-doc.org/",
@ -170,11 +174,13 @@ module.exports = {
"link-eip-191": { name: "EIP-191", url: "https:/\/eips.ethereum.org/EIPS/eip-191" },
"link-eip-609": "https:/\/eips.ethereum.org/EIPS/eip-609",
"link-eip-1014": "https:/\/eips.ethereum.org/EIPS/eip-1014",
"link-eip-1193": { name: "EIP-1193", url: "https:/\/eips.ethereum.org/EIPS/eip-1193" },
"link-eip-2098": "https:/\/eips.ethereum.org/EIPS/eip-2098",
"link-bip-39": "https://en.bitcoin.it/wiki/BIP_0039",
"link-bip-32": "https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki",
"link-npm-elliptic": { name: "elliptic", url: "https:/\/www.npmjs.com/package/elliptic" },
"link-npm-events": { name: "EventEmitter", url: "https:/\/nodejs.org/dist/latest-v13.x/docs/api/events.html#events_class_eventemitter" },
"link-npm-bnjs": { name: "BN.js", url: "https:/\/www.npmjs.com/package/bn.js" },
"link-npm-query-bignumber": "https:/\/www.npmjs.com/search?q=bignumber",
@ -189,6 +195,7 @@ module.exports = {
"link-wiki-basicauth": { name: "Basic Authentication", url: "https:/\/en.wikipedia.org/wiki/Basic_access_authentication" },
"link-wiki-backoff": { name: "Exponential Backoff", url: "https:/\/en.wikipedia.org/wiki/Exponential_backoff" },
"link-wiki-bloomfilter": { name: "Bloom Filter", url: "https:/\/en.wikipedia.org/wiki/Bloom_filter" },
"link-wiki-bruteforce": "https:/\/en.wikipedia.org/wiki/Brute-force_attack",
"link-wiki-cryptographichash": "https:/\/en.wikipedia.org/wiki/Cryptographic_hash_function",
"link-wiki-homoglyph": "https:/\/en.wikipedia.org/wiki/IDN_homograph_attack",
"link-wiki-hmac": "https:/\/en.wikipedia.org/wiki/HMAC",

@ -1,5 +1,5 @@
// CommonJS
const { ethers } = require("ethers");
// ES6 or TypeScript
const { ethers } = require("ethers");
// ES6 or TypeScript
import { ethers } from "ethers";

@ -46,7 +46,7 @@ _toc:
contributing
documentation
license
_subsection: Legacy Documentation