<divclass="link title"><ahref="/v5/">Documentation</a></div><divclass="base show link depth-1"><ahref="/v5/getting-started/">Getting Started</a></div><divclass="base show link depth-1"><ahref="/v5/concepts/">Ethereum Basics</a></div><divclass="hide link depth-2"><ahref="/v5/concepts/events/">Events</a></div><divclass="hide link depth-2"><ahref="/v5/concepts/gas/">Gas</a></div><divclass="hide link depth-2"><ahref="/v5/concepts/security/">Security</a></div><divclass="hide link depth-2"><ahref="/v5/concepts/best-practices/">Best Practices</a></div><divclass="base show link depth-1"><ahref="/v5/api-keys/">Provider API Keys</a></div><divclass="base show link depth-1"><ahref="/v5/api/">Application Programming Interface</a></div><divclass="hide link depth-2"><ahref="/v5/api/providers/">Providers</a></div><divclass="hide link depth-3"><ahref="/v5/api/providers/provider/">Provider</a></div><divclass="hide link depth-3"><ahref="/v5/api/providers/jsonrpc-provider/">JsonRpcProvider</a></div><divclass="hide link depth-3"><ahref="/v5/api/providers/api-providers/">API Providers</a></div><divclass="hide link depth-3"><ahref="/v5/api/providers/other/">Other Providers</a></div><divclass="hide link depth-3"><ahref="/v5/api/providers/types/">Types</a></div><divclass="hide link depth-2"><ahref="/v5/api/signer/">Signers</a></div><divclass="hide link depth-2"><ahref="/v5/api/contract/">Contract Interaction</a></div><divclass="hide link depth-3"><ahref="/v5/api/contract/contract/">Contract</a></div><divclass="hide link depth-3"><ahref="/v5/api/contract/contract-factory/">ContractFactory</a></div><divclass="hide link depth-3"><ahref="/v5/api/contract/example/">Example: ERC-20 Contract</a></div><divclass="hide link depth-2"><ahref="/v5/api/utils/">Utilities</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/abi/">Application Binary Interface</a></div><divclass="hide link depth-4"><ahref="/v5/api/utils/abi/coder/">AbiCoder</a></div><divclass="hide link depth-4"><ahref="/v5/api/utils/abi/formats/">ABI Formats</a></div><divclass="hide link depth-4"><ahref="/v5/api/utils/abi/fragments/">Fragments</a></div><divclass="hide link depth-4"><ahref="/v5/api/utils/abi/interface/">Interface</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/address/">Addresses</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/bignumber/">BigNumber</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/bytes/">Byte Manipulation</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/constants/">Constants</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/display-logic/">Display Logic and Input</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/encoding/">Encoding Utilities</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/fixednumber/">FixedNumber</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/hashing/">Hashing Algorithms</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/hdnode/">HD Wallet</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/logger/">Logging</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/properties/">Property Utilities</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/signing-key/">Signing Key</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/strings/">Strings</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/transactions/">Transactions</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/web/">Web Utilities</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/wordlists/">Wordlists</a></div><divclass="hide link depth-2"><ahref="/v5/api/other/">Other Libraries</a></div><divclass="hide link depth-3"><ahref="/v5/api/other/assembly/">Assembly</a></div><divclass="hide link depth-4"><ahref="/v5/api/other/assembly/dialect/">Ethers ASM Dialect</a></div><divclass="hide link depth-4"><ahref="/v5/api/other/assembly/api/">Utilities</a></div><divclass="hide link depth-4"><ahref="/v5/api/other/assembly/ast/
<aname="contributing"></a><aname="contributing"></a><h1class="show-anchors"><div>Contributing and Hacking<divclass="anchors"><aclass="self"href="/v5/contributing/#contributing"></a></div></div></h1><p>The ethers.js library is something that I've written out of necessity, and has grown somewhat organically over time.</p>
<p>Many things are the way they are for good (at the time, at least) reasons, but I always welcome criticism, and am completely willing to have my mind changed on things.</p>
<p><ul><li>Backwards-compatibility-breaking changes will not be accepted; they may be considered for the next major version </li><li>Security is important; adding dependencies require fairly convincing arguments as to why </li><li>The library aims to be lean, so keep an eye on the dist/ethers.min.js file size before and after your changes </li><li>Keep the PR simple and readable; only modify files in the <codeclass="inline">docs.wrm/</code> and <codeclass="inline">packages/*/src.ts/</code> folders, as this allows the changes to be easily verified </li><li>Add test cases for both expected and unexpected input </li><li>Any new features need to be supported by me (future issues, documentation, testing, migration), so anything that is overly complicated or specific may not be accepted </li></ul></p>
<p>In general, <b>please start an issue <i>before</i> beginning a pull request</b>, so we can have a public discussion and figure out the best way to address the problem/feature. <b>:)</b></p>
<aname="contributing--building"></a><aname="contributing--contributing--building"></a><h2class="show-anchors"><div>Building<divclass="anchors"><aclass="self"href="/v5/contributing/#contributing--building"></a></div></div></h2><p>The build process for ethers is unfortunatly not super trivial, but I have attempted to make it as straight-forward as possible.</p>
<p>It is a mono-repo which attempts to be compatibile with a large number of environments, build tools and platforms, which is why there are a some weird things it must do.</p>
<p>There are several custom scripts in the <codeclass="inline">misc/admin</code> folder to help manage the monorepo. Developers working on contributing to ethers should not generally need to worry about those, since they are wrapped up behind <codeclass="inline">npm run SCRIPT</code> operations.</p>
<divclass="code-title"><div>Installing</div></div><divclass="code"># Clone the repository
# - Hoists all sub-package dependencies in the package.json (preinstall)
# - Installs all the (hoisted) dependencies and devDependencies (install)
# - Build the rat-nests (in .package_node_modules) (postinstall)
# - Create a dependency graph for the TypeScript (postinstall)
# - Link the rat-nets into each project (postinstall)
/home/ricmoo/ethers.js> npm install</div><aname="contributing--updating"></a><aname="contributing--contributing--building--contributing--updating"></a><h3class="show-anchors"><div>Making Changes<divclass="anchors"><aclass="self"href="/v5/contributing/#contributing--updating"></a></div></div></h3><p>Once your environment is set up, you should be able to simply start the <codeclass="inline">auto-build</code> feature, and make changes to the TypeScript source.</p>
/home/ricmoo/ethers.js> npm run build</div><aname="contributing--contributing--building--creating-browser-ready-files"></a><h3class="show-anchors"><div>Creating Browser-Ready Files<divclass="anchors"><aclass="self"href="/v5/contributing/#contributing--contributing--building--creating-browser-ready-files"></a></div></div></h3><p>To create files for use directly in a browser, the distribution files (located in <codeclass="inline">packages/ethers/dist</code>) need to be built which requires several intermediate builds, scripts and for various rollup scripts to execute.</p>
<divclass="code-title"><div>Building Distribution Files</div></div><divclass="code"># If you need to rebuild all the libs (esm + cjs) and dist files
# Note: this requires node 10 or newer
/home/ricmoo/ethers.js> npm run build-all</div><aname="contributing--contributing--building--testing"></a><h3class="show-anchors"><div>Testing<divclass="anchors"><aclass="self"href="/v5/contributing/#contributing--contributing--building--testing"></a></div></div></h3>
<divclass="code-title"><div>Testing</div></div><divclass="code"># Rebuilds all files (npm run build-all) and bundles testcases up for testing
/home/ricmoo/ethers.js> npm run test-node</div><aname="contributing--contributing--building--distribution"></a><h3class="show-anchors"><div>Distribution<divclass="anchors"><aclass="self"href="/v5/contributing/#contributing--contributing--building--distribution"></a></div></div></h3><p>Most developers should not ever require this step, but for people forking ethers and creating alternates (for example if you have a non-EVM compatible chain but are trying to reuse this package).</p>
<p>This script will rebuild the entire ethers project, compare it against npm, re-write package versions, update internal hashes, re-write various TypeScript files (to get around some ES+TS limitations for Tree Shaking and linking), re-write map files, bundle stripped versions of dependencies and basically just a whole bunch of stuff.</p>
<p>If you use this and get stuck, <ahref="mailto:me@ricmoo.com">message me</a>.</p>
<divclass="code-title"><div>Preparing the Distribution</div></div><divclass="code"># Prepare all the distribution files
# - Remove all generated files (i.e. npm run clean)
# - Re-install all dependencies, hoisting, etc. (npm install)
# - Spell check all strings in every TypeScript files
# - Build everything from scratch with this clean install
# - Compare local with npm, bumping the version if changed
# - Build everything again (with the updated versions)
# - Update the CHANGELOG.md with the git history since the last change
/home/ricmoo/ethers.js> npm run update-version</div><divclass="definition container-box note"><divclass="term">Do NOT check in dist files in a PR</div><divclass="body"><p>For Pull Requests, please ONLY commit files in the <codeclass="inline">docs.wrm/</code> and <codeclass="inline">packages/*/src.ts/</code> folders. I will prepare the distribution builds myself and keeping the PR relevant makes it easier to verify the changes.</p>
</div></div><aname="contributing--contributing--building--publishing"></a><h3class="show-anchors"><div>Publishing<divclass="anchors"><aclass="self"href="/v5/contributing/#contributing--contributing--building--publishing"></a></div></div></h3><p>Again, this should not be necessary for most developers. This step requires using the <codeclass="inline">misc/admin/cmds/config-set</code> script for a number of values, including private keys, NPM session keys, AWS access keys, GitHub API tokens, etc.</p>
<p>The config file is encrypted with about 30 seconds of scrypt password-based key derivation function, so brute-forcing the file is quite expensive.</p>
<p>The config file also contains a plain-text mnemonic. This is a money-pot. Place a tempting amount of ether or Bitcoin on this account and set up an e-mail alert for this account.</p>
<p>If any attacker happens across your encrypted config, they will have instant access to the plain-text mnemonic, so they have the option to immediately steal the ether (i.e. the responsible-disclosure bond).</p>
<p>If you ever see this ether taken, your encrypted file is compromised! Rotate all your AWS keys, NPM session keys, etc. immedately.</p>
<p>@TODO: document all the keys that need to be set for each step</p>
<divclass="code-title"><div>Preparing the Distribution</div></div><divclass="code"># Publish
# - Update any changed packages to NPM
# - Create a release on GitHub with the latest CHANGELOG.md description
# - Upload the bundled files the the CDN
# - Flush the CDN edge caches
/home/ricmoo/ethers.js> npm run publish-all</div><aname="contributing--documentation"></a><aname="contributing--contributing--documentation"></a><h2class="show-anchors"><div>Documentation<divclass="anchors"><aclass="self"href="/v5/contributing/#contributing--documentation"></a></div></div></h2><p>The documents are generated using <ahref="/v5/documentation/">Flatworm</a> documentation generation tool, which was written for the purpose of writing the documentation for ethers.</p>
<p><ul><li>Try to keep lines no longer than <i>around</i> 80 characters </li><li>Avoid inline links in the source; use the <codeclass="inline">externalLinks</code> field in the config.js </li><li>Prefix external links with <codeclass="inline">link-</code></li><li>Changing an anchor name must be well justified, as it will break all existing links to that section; flatworm will support symlinks in the future </li><li>In general, I aim for consistency; look to similar situations throughout the documentation </li></ul></p>
<aname="contributing--contributing--documentation--building"></a><h3class="show-anchors"><div>Building<divclass="anchors"><aclass="self"href="/v5/contributing/#contributing--contributing--documentation--building"></a></div></div></h3><p>To build the documentation, you should first follow the <ahref="/v5/contributing/#contributing--building">above steps</a> to build the ethers library.</p>
<p>Building the docs will generate several types of output:</p>
<p><ul><li>A full set of HTML pages, linking across each other </li><li>A single one-page HTML page with all pages linking to local anchors </li><li>A full set of README.md pages organized to be browsable and linkable in GitHub </li><li>A metadata dump for tool ingestion (still needs more work) </li><li>(@TODO; only half done) The documentation as a LaTeX and generated PDF </li></ul></p>
<divclass="code-title"><div>Building the Documentations</div></div><divclass="code">/home/ricmoo/ethers.js> npm run build-docs</div><aname="contributing--contributing--documentation--evaluation"></a><h3class="show-anchors"><div>Evaluation<divclass="anchors"><aclass="self"href="/v5/contributing/#contributing--contributing--documentation--evaluation"></a></div></div></h3><p>When building the documentation, all code samples are run through a JavaScript VM to ensure there are no typos in the example code, as well the exact output of results are injected into the output, so there is no need to keep the results and code in-sync.</p>
<p>However, this can be a bit of a headache when making many small changes, so to build the documentation faster, you can skip the evaluation step, which will inject the code directly.</p>
<divclass="code-title"><div>Build docs skipping evaluation</div></div><divclass="code">/home/ricmoo/ethers.js> npm run build-docs -- --skip-eval</div><aname="contributing--contributing--documentation--previewing-changes"></a><h3class="show-anchors"><div>Previewing Changes<divclass="anchors"><aclass="self"href="/v5/contributing/#contributing--contributing--documentation--previewing-changes"></a></div></div></h3><p>To preview the changes locally, you can use any standard web server and run from the <codeclass="inline">/docs/</code> folder, or use the built-in web server.</p>
<p>The same caveats as normal web development apply, such flushing browser caches after changing (and re-building) the docs.</p>
<divclass="code-title"><div>Running a webserver</div></div><divclass="code">/home/ricmoo/ethers.js> npm run serve-docs</div>
<divclass="copyright">The content of this site is licensed under the <ahref="https://choosealicense.com/licenses/cc-by-4.0/">Creative Commons License</a>. Generated on February 8, 2021, 3:25pm.</div>