diff --git a/.npmrc b/.npmrc index 9cf9495031..43c97e719a 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1 @@ -package-lock=false \ No newline at end of file +package-lock=false diff --git a/.travis.yml b/.travis.yml index d621fccd39..dce1622fdb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ install: - scripts/install.sh script: + - npx tsc --version - npm run test - npm run lint - node scripts/check-dependencies.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d3fbd5b235..0d3ba2b7cb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ To install this project you have to run: ## Building the projects Plugins require buidler-core to be built or tested. Our recommendation is to run `npm run watch` from the root folder. -This will keep everything compiled, and these problems will be avoided. +This will keep everything compiled, and these problems will be avoided. ## Testing @@ -30,32 +30,32 @@ You can run a package's tests by executing `npm run test` inside its folder. Or ## Code formatting We use [Prettier](https://prettier.io/) to format all the code without any special configuration. Whatever Prettier does -is considered The Right Thing. It's completely fine to commit non-prettied code and then reformat it in a later commit. +is considered The Right Thing. It's completely fine to commit non-prettied code and then reformat it in a later commit. We also have [tslint](https://palantir.github.io/tslint/) installed in all the projects. It checks that you have run Prettier and forbids some dangerous patterns. -The linter is always run in the CI, so make sure it passes before pushing code. You can use `npm run lint` and +The linter is always run in the CI, so make sure it passes before pushing code. You can use `npm run lint` and `npm run lint:fix` inside the packages' folders. ## Dependencies -We keep our dependencies versions in sync between the different projects. +We keep our dependencies versions in sync between the different projects. Running `node scripts/check-dependencies.js` from the root folder checks that every project specifies the same versions -of each dependency. It will print an error if the versions get out of sync. +of each dependency. It will print an error if the versions get out of sync. ## Performance and dependencies loading -Buidler and its plugins are optimized for keeping startup time low. +Buidler and its plugins are optimized for keeping startup time low. This is done by selectively requiring dependencies when needed using `import` or `require` following this criteria: -1. If something is only imported for its type, and NOT its value, use a top-level `import ... from "mod"` +1. If something is only imported for its type, and NOT its value, use a top-level `import ... from "mod"` 1. If a module is in the least below, use a top-level `import ... from "mod""`. -3. Otherwise, use `await import` or `require` locally in the functions that use it. - 3.1. If the function is sync, use node's `require` - 3.2. If the function is an async, use `await import` +1. Otherwise, use `await import` or `require` locally in the functions that use it. + 3.1. If the function is sync, use node's `require` + 3.2. If the function is an async, use `await import` Note that these rules don't apply to tests. You can always use top-level imports there. @@ -63,13 +63,40 @@ Note that these rules don't apply to tests. You can always use top-level imports This is a list of the modules that always get loaded during startup: -* `fs` -* `path` -* `util` -* `find-up` -* `fs-extra` -* `chalk` -* `semver` -* `deepmerge` -* `source-map-support/register` - +- `fs` +- `path` +- `util` +- `find-up` +- `fs-extra` +- `chalk` +- `semver` +- `deepmerge` +- `source-map-support/register` + +## Common errors + +### Monkey-patching dependencies multiple times + +You should avoid monkey-patching whenever possible. But if it's necessary to do so, you should pay extra care when doing +it in Buidler or your tests may fail in very hard to debug ways. + +When tests are run, Buidler gets initialized multiple times. That may lead to monkey-patching the same multiple times. +To avoid this, keep references to the original implementations. In order to do this, you need to get it just once: + +```js +let originalImpl; // May be a global + +// ... + +if (originalImpl === undefined) { + originalImpl = lib.func; +} + +lib.func = function(...args) { + // Do something; + return originalImpl.apply(this, args); +}; +``` + +This isn't normally a problem if you are monkey-patching an object's methods. But it is when monkey-patching a class +or its prototype. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..05250b7e76 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +SEE LICENSE IN EACH PACKAGE'S LICENSE FILE diff --git a/config/typescript/@types/ethereumjs-abi/index.d.ts b/config/typescript/@types/ethereumjs-abi/index.d.ts new file mode 100644 index 0000000000..50bf5b2824 --- /dev/null +++ b/config/typescript/@types/ethereumjs-abi/index.d.ts @@ -0,0 +1 @@ +declare module "ethereumjs-abi"; diff --git a/config/typescript/@types/ethereumjs-block/index.d.ts b/config/typescript/@types/ethereumjs-block/index.d.ts new file mode 100644 index 0000000000..4147bedd4a --- /dev/null +++ b/config/typescript/@types/ethereumjs-block/index.d.ts @@ -0,0 +1 @@ +declare module "ethereumjs-block"; diff --git a/config/typescript/@types/ganache-core/index.d.ts b/config/typescript/@types/ganache-core/index.d.ts new file mode 100644 index 0000000000..12b85af281 --- /dev/null +++ b/config/typescript/@types/ganache-core/index.d.ts @@ -0,0 +1 @@ +declare module "ganache-core"; diff --git a/config/typescript/@types/merkle-patricia-tree/index.d.ts b/config/typescript/@types/merkle-patricia-tree/index.d.ts new file mode 100644 index 0000000000..9979d565bb --- /dev/null +++ b/config/typescript/@types/merkle-patricia-tree/index.d.ts @@ -0,0 +1 @@ +declare module "merkle-patricia-tree/secure"; diff --git a/docs/.gitignore b/docs/.gitignore index 4322b9c148..e2b65fbf25 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -2,3 +2,5 @@ /api /.vuepress/dist .DS_Store +/errors/README.md +wget-readmes.sh diff --git a/docs/.vuepress/components/Plugins.vue b/docs/.vuepress/components/Plugins.vue index 81e59131bf..815fc7d982 100644 --- a/docs/.vuepress/components/Plugins.vue +++ b/docs/.vuepress/components/Plugins.vue @@ -8,7 +8,7 @@
{{ plugin.name }} - {{ plugin.version }} +

{{ plugin.description }}

@@ -21,75 +21,9 @@ @@ -92,15 +105,19 @@ $navbar-vertical-padding = 0.7rem $navbar-horizontal-padding = 1.5rem .navbar - padding $navbar-vertical-padding $navbar-horizontal-padding + .header + padding $navbar-vertical-padding $navbar-horizontal-padding + line-height $navbarHeight - 1.4rem position relative a, span, img display inline-block .logo + margin-top $navbar-vertical-padding height $navbarHeight - 1.4rem min-width $navbarHeight - 1.4rem margin-right 0.8rem + margin-left $navbar-horizontal-padding vertical-align top .site-name font-size 1.3rem @@ -125,7 +142,8 @@ $navbar-horizontal-padding = 1.5rem @media (max-width: $MQMobile) .navbar - padding-left 4rem + .logo + margin-left 4rem .can-hide display none .links diff --git a/docs/.vuepress/theme/SidebarLink.vue b/docs/.vuepress/theme/SidebarLink.vue index 8288bf9658..70767fd2fe 100644 --- a/docs/.vuepress/theme/SidebarLink.vue +++ b/docs/.vuepress/theme/SidebarLink.vue @@ -16,9 +16,10 @@ export default { ? selfActive || item.children.some(c => isActive($route, item.basePath + '#' + c.slug)) : selfActive const link = renderLink(h, item.path, item.title || item.path, active) - const configDepth = $page.frontmatter.sidebarDepth != null - ? $page.frontmatter.sidebarDepth - : $site.themeConfig.sidebarDepth + const configDepth = item.depth !== undefined ? item.depth : + $page.frontmatter.sidebarDepth != null + ? $page.frontmatter.sidebarDepth + : $site.themeConfig.sidebarDepth const maxDepth = configDepth == null ? 1 : configDepth const displayAllHeaders = !!$site.themeConfig.displayAllHeaders if (item.type === 'auto') { diff --git a/docs/.vuepress/theme/styles/config.styl b/docs/.vuepress/theme/styles/config.styl index af4fb49eec..a1e02923e2 100644 --- a/docs/.vuepress/theme/styles/config.styl +++ b/docs/.vuepress/theme/styles/config.styl @@ -8,7 +8,9 @@ $codeBgColor = #282c34 $arrowBgColor = #ccc // layout +$bannerHeight = 0rem $navbarHeight = 3.6rem +$navbarAndBannerHeight = $bannerHeight + $navbarHeight $sidebarWidth = 20rem $contentWidth = 740px diff --git a/docs/.vuepress/theme/styles/mobile.styl b/docs/.vuepress/theme/styles/mobile.styl index b35e59c588..0c9fab9188 100644 --- a/docs/.vuepress/theme/styles/mobile.styl +++ b/docs/.vuepress/theme/styles/mobile.styl @@ -14,7 +14,7 @@ $mobileSidebarWidth = $sidebarWidth * 0.82 @media (max-width: $MQMobile) .sidebar top 0 - padding-top $navbarHeight + padding-top $navbarAndBannerHeight transform translateX(-100%) transition transform .2s ease .page diff --git a/docs/.vuepress/theme/styles/theme.styl b/docs/.vuepress/theme/styles/theme.styl index 85dc5b3760..3ea47c179c 100644 --- a/docs/.vuepress/theme/styles/theme.styl +++ b/docs/.vuepress/theme/styles/theme.styl @@ -26,7 +26,7 @@ body top 0 left 0 right 0 - height $navbarHeight + height $navbarAndBannerHeight background-color #fff box-sizing border-box border-bottom 1px solid $borderColor @@ -47,7 +47,7 @@ body position fixed z-index 10 margin 0 - top $navbarHeight + top $navbarAndBannerHeight left 0 bottom 0 box-sizing border-box @@ -57,7 +57,7 @@ body .content:not(.custom) @extend $wrapper > *:first-child - margin-top $navbarHeight + margin-top $navbarAndBannerHeight a:hover text-decoration underline p.demo @@ -106,8 +106,8 @@ h1, h2, h3, h4, h5, h6 font-weight 600 line-height 1.25 .content:not(.custom) > & - margin-top (0.5rem - $navbarHeight) - padding-top ($navbarHeight + 1rem) + margin-top (0.5rem - $navbarAndBannerHeight) + padding-top ($navbarAndBannerHeight + 1rem) margin-bottom 0 &:first-child margin-top -1.5rem @@ -164,7 +164,7 @@ th, td padding .6em 1em .custom-layout - padding-top $navbarHeight + padding-top $navbarAndBannerHeight .theme-container &.sidebar-open diff --git a/docs/.vuepress/theme/util.js b/docs/.vuepress/theme/util.js index ef95bea552..df05a0073e 100644 --- a/docs/.vuepress/theme/util.js +++ b/docs/.vuepress/theme/util.js @@ -121,6 +121,7 @@ export function resolveSidebarItems (page, route, site, localePath) { } const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar + if (!sidebarConfig) { return [] } else { @@ -196,7 +197,8 @@ function resolveItem (item, pages, base, isNested) { return resolvePage(pages, item, base) } else if (Array.isArray(item)) { return Object.assign(resolvePage(pages, item[0], base), { - title: item[1] + title: item[1], + depth: item[2] }) } else { if (isNested) { @@ -210,7 +212,8 @@ function resolveItem (item, pages, base, isNested) { type: 'group', title: item.title, children: children.map(child => resolveItem(child, pages, base, true)), - collapsable: item.collapsable !== false + collapsable: item.collapsable !== false, + depth: item.depth } } } diff --git a/docs/README.md b/docs/README.md index 4449e34b16..3a85dc3196 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,7 +3,7 @@ home: true heroImage: ./mascots.svg actionText: Get Started search: false -footer: MIT Licensed | Copyright © 2018-2019 Nomic Labs +footer: Copyright © 2018-2019 Nomic Labs LLC ---
@@ -12,9 +12,11 @@ footer: MIT Licensed | Copyright © 2018-2019 Nomic Labs ```js + import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; + pragma solidity ^0.5.1; - contract DeathStar { + contract DeathStar is ERC721 { address private owner; @@ -28,8 +30,6 @@ footer: MIT Licensed | Copyright © 2018-2019 Nomic Labs } } - - ```
@@ -42,22 +42,22 @@ footer: MIT Licensed | Copyright © 2018-2019 Nomic Labs // For unit tests usePlugin("@nomiclabs/buidler-truffle5"); usePlugin("@nomiclabs/buidler-ganache"); - - // Automatically generate testable contracts where - // internal methods are exposed as external. - usePlugin("@nomiclabs/buidler-autoexternal"); + usePlugin("buidler-gas-reporter"); // Linting usePlugin("@nomiclabs/buidler-solhint"); // For scripts usePlugin("@nomiclabs/buidler-ethers"); - usePlugin("@nomiclabs/buidler-faucets"); - + // Faster compilation usePlugin("@nomiclabs/buidler-docker-solc"); - module.exports = {}; + module.exports = { + buidlerevm: { + throwOnTransactionFailures: true + } + }; ```
@@ -65,48 +65,48 @@ footer: MIT Licensed | Copyright © 2018-2019 Nomic Labs
-

3. Write your tasks

+

3. Write your tests

- ```js +```js +contract('ERC721', function () { + describe('safeTransferFrom to a contract that does not implement the required function', function () { + it('reverts', async function () { + const invalidReceiver = this.token; - task("shoot", "Shoots the laser. Handle with care.") - .addParam("target", "The target planet") - .setAction(async (target) => { - const DeathStar = artifacts.require("DeathStar"); - await DeathStar.at(..).shoot(target); - - console.log("Target destroyed.") + await this.token.safeTransferFrom( + owner, + invalidReceiver.address, + tokenId, + { from: owner } + ) }); - - - module.exports = {}; - - - ``` + }); +}); +```
-

4. Interact with your contract easily

- - ```sh - $ npx buidler help shoot - Buidler version 1.0.0-beta.13 +

4. Debug your code with Buidler EVM

- Usage: buidler [GLOBAL OPTIONS] shoot --target - - OPTIONS: + ``` +$ npx buidler test - --target The target planet +Contract: DeathStar + safeTransferFrom to a contract that does not implement the required function: - shoot: Shoots the laser. Handle with care. +Error: Transaction reverted: function selector was not recognized and there's no fallback function + at DeathStar. (contracts/DeathStar.sol:9) + at DeathStar._checkOnERC721Received (contracts/token/ERC721/ERC721.sol:334) + at DeathStar._safeTransferFrom (contracts/token/ERC721/ERC721.sol:196) + at DeathStar.safeTransferFrom (contracts/token/ERC721/ERC721.sol:179) + at DeathStar.safeTransferFrom (contracts/token/ERC721/ERC721.sol:162) + at TruffleContract.safeTransferFrom (node_modules/@nomiclabs/truffle-contract/lib/execute.js:157:24) + at Context. (test/DeathStar-test.js:321:26) - For global options help run: buidler help - $ npx buidler shoot --target alderaan - Target destroyed. ```
diff --git a/docs/_redirects b/docs/_redirects new file mode 100644 index 0000000000..a61c75234b --- /dev/null +++ b/docs/_redirects @@ -0,0 +1,3 @@ +# Manual redirects + +/links/stack-traces / 302 diff --git a/docs/advanced/buidler-runtime-environment.md b/docs/advanced/buidler-runtime-environment.md new file mode 100644 index 0000000000..a7e8cd5b4a --- /dev/null +++ b/docs/advanced/buidler-runtime-environment.md @@ -0,0 +1,70 @@ +# Buidler Runtime Environment (BRE) + +## Overview + +The Buidler Runtime Environment, or BRE for short, is an object containing all the functionality that Buidler exposes when running a task, test or script. In reality, Buidler _is_ the BRE. + +When you require Buidler (`const buidler = require("@nomiclabs/buidler")`) you're getting an instance of the BRE. + +During initialization, the Buidler configuration file essentially constructs a list of things to be added to the BRE. This includes tasks, configs and plugins. Then when tasks, tests or scripts run, the BRE is always present and available to access anything that is contained in it. + +The BRE has a role of centralizing coordination across all Buidler components. This architecture allows for plugins to inject functionality that becomes available everywhere the BRE is accessible. + +## Using the BRE + +By default, the BRE gives you programmatic access to the task runner and the config system, and exports an [EIP1193-compatible](https://eips.ethereum.org/EIPS/eip-1193) Ethereum provider. You can find more information about [it in its API docs](/api/classes/environment.html). + +Plugins can extend the BRE. For example, [buidler-web3](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3) adds a Web3.js instance to it, making it available to tasks, tests and scripts. + +### As global variables + +Before running a task, test or script, Buidler injects the BRE into the global scope, turning all of its fields into global variables. When the task execution is completed, these global variables are removed, restoring their original value, if they had one. + +### Explicitly + +Not everyone likes magic global variables, and Buidler doesn't force you to use them. Everything can be done explicitly in tasks, tests and scripts. + +When writing tests or scripts, you can use `require("@nomiclabs/buidler")` to import the BRE. You can read more about this in [Accessing the BRE from outside a task](#accessing-the-bre-from-outside-a-task). + +You can import the config DSL explicitly when defining your tasks, and receive the BRE explicitly as an argument to your actions. You can read more about this in [Creating your own tasks](#creating-your-own-tasks). + +## Extending the BRE + +The BRE only provides the core functionality that users and plugin developers need to start building on top of Buidler. Using it to interface directly with Ethereum in your project can be somewhat harder than expected. + +Everything gets easier when you use higher-level libraries, like [Web3.js](https://web3js.readthedocs.io/en/latest/) or [@truffle/contract](https://www.npmjs.com/package/@truffle/contract), but these libraries need some initialization to work, and that could get repetitive. + +Buidler lets you hook into the BRE construction, and extend it with new functionality. This way, you only have to initialize everything once, and your new features or libraries will be available everywhere the BRE is used. + +You can do this by adding a BRE extender into a queue. This extender is just a synchronous function that receives the BRE, and adds fields to it with your new functionality. These new fields will also get [injected into the global scope during runtime](#exporting-globally). + +For example, adding an instance of Web3.js to the BRE can be done in this way: + +```js +extendEnvironment(env => { + const Web3 = require("web3"); + env.Web3 = Web3; + + // env.network.provider is an EIP1193-compatible provider. + env.web3 = new Web3(new Web3HTTPProviderAdapter(env.network.provider)); +}); +``` + +## Accessing the BRE from outside a task + +The BRE can be used from any JavaScript or TypeScript file. To do so, you only have to import it with `require("@nomiclabs/buidler")`. You can do this to keep more control over your development workflow, create your own tools, or to use Buidler with other dev tools from the node.js ecosystem. + +Running test directly with [Mocha](https://www.npmjs.com/package/mocha) instead of `npx buidler test` can be done by explicitly importing the BRE in them like this: + +```js +const env = require("@nomiclabs/buidler"); +const assert = require("assert"); + +describe("Buidler Runtime Environment", function() { + it("should have a config field", function() { + assert.notEqual(env.config, undefined); + }); +}); +``` + +This way, tests written for Buidler are just normal Mocha tests. This enables you to run them from your favorite editor without the need of any Buidler-specific plugin. For example, you can [run them from Visual Studio Code using Mocha Test Explorer](../guides/vscode-tests.md). diff --git a/docs/advanced/building-plugins.md b/docs/advanced/building-plugins.md new file mode 100644 index 0000000000..95df127f6f --- /dev/null +++ b/docs/advanced/building-plugins.md @@ -0,0 +1,60 @@ +# Building plugins + +This section is an overview of how to create a plugin. For a complete example of a +plugin go to the [TypeScript plugin boilerplate project](https://github.com/nomiclabs/buidler-ts-plugin-boilerplate/). + +## Plugin functionality + +Plugins are bits of reusable configuration. Anything that you can do in a plugin, can also be done in your config file. You can test your ideas in a config file, and move them into a plugin when ready. + +The main things that plugins can do are extending the Buidler Runtime Environment, extending the Buidler config, defining new tasks, and overriding existing ones. + +### Extending the BRE + +To learn how to successfully extend the [BRE](./buidler-runtime-environment.md) in TypeScript, and to give your users type information about your extension, take a look at [`src/index.ts`](https://github.com/nomiclabs/buidler-ts-plugin-boilerplate/blob/master/src/index.ts) in the boilerplate repo and read the [Extending the BRE](./buidler-runtime-environment.md#extending-the-bre) documentation. + +Make sure to keep the type extension in your main file, as that convention is used across different plugins. + +### Extending the Buidler config + +An example on how to add fields to the Buidler config can be found in [`src/index.ts`](https://github.com/nomiclabs/buidler-ts-plugin-boilerplate/blob/master/src/index.ts). + +Note that all config extension's have to be optional. + +### Throwing errors from your plugins + +To show better stack traces to your users, please only throw [`BuidlerPluginError`](/api/classes/buidlerpluginerror.html#constructors) errors, which can be found in `@nomiclabs/buidler/plugins`. + +### Optimizing your plugin for better startup time + +Keeping startup time short is vital to give a good user experience. To do so, Buidler and its plugins delay any slow import or initialization until the very last moment. To do so, you can use `lazyObject`, and `lazyFunction` from `@nomiclabs/buidler/plugins`. + +An example on how to use them is present in [`src/index.ts`](https://github.com/nomiclabs/buidler-ts-plugin-boilerplate/blob/master/src/index.ts). + +## Notes on dependencies + +Knowing when to use a `dependency` or a `peerDependency` can be tricky. We recommend [these](https://yarnpkg.com/blog/2018/04/18/dependencies-done-right/) [articles](https://lexi-lambda.github.io/blog/2016/08/24/understanding-the-npm-dependency-model/) to learn about their distinctions. + +If you are still in doubt, these can be helpful: + +- **Rule of thumb #1:** Buidler MUST be a peer dependency. + +- **Rule of thumb #2:** If your plugin P depends on another plugin P2, P2 should be a peer dependency of P, and P2's peer dependencies should be peer dependencies of P. + +- **Rule of thumb #3:** If you have a non-Buidler dependency that your users may `require()`, it should be a peer dependency. + +- **Rule of thumb #4:** Every `peerDependency` should also be a `devDependency`. + +Also, if you depend on a Buidler plugin written in TypeScript, you should add it's type extensions' `.d.ts` file to the `files` array of `tsconfig.json`. + +## Hooking into the user's workflow + +To integrate into your users' existing workflow, we recommend plugin authors to override built-in tasks whenever it makes sense. + +Examples of suggested overrides are: + +- Preprocessing smart contracts should override one of the `compile` internal tasks. +- Linter integrations should override the `check` task. +- Plugins generating intermediate files should override the `clean` task. + +For a list of all the built-in tasks and internal tasks please take a look at [`task-names.ts`](https://github.com/nomiclabs/buidler/blob/master/packages/buidler-core/src/builtin-tasks/task-names.ts) diff --git a/docs/buidler-evm/README.md b/docs/buidler-evm/README.md new file mode 100644 index 0000000000..ef2a42d39a --- /dev/null +++ b/docs/buidler-evm/README.md @@ -0,0 +1,80 @@ +# Buidler EVM + +Buidler comes built-in with Buidler EVM, a development network to deploy +and run your contracts on, facilitating testing and debugging. Buidler EVM is +based on [`ethereumjs-vm`](https://github.com/ethereumjs/ethereumjs-vm), +just like Remix and Ganache, so you don't have to worry about consensus bugs. + +By default, an instance of Buidler EVM will be automatically created when +your run a task, script or test your smart contracts. You don't need to +do anything to enable it. + +## Solidity stack traces + +Buidler EVM has first-class Solidity support. It always knows which +smart contracts are being run, what they do exactly and why they fail. + +If a transaction or call fails, Buidler EVM will throw an exception. +This exception will have a combined JavaScript and Solidity stack +trace: stack traces that start in JavaScript/TypeScript up to your +call to the contract, and continue with the full Solidity call stack. + +This is an example of a Buidler EVM exception: + +``` +Error: Transaction reverted: function selector was not recognized and there's no fallback function + at ERC721Mock. (contracts/mocks/ERC721Mock.sol:9) + at ERC721Mock._checkOnERC721Received (contracts/token/ERC721/ERC721.sol:334) + at ERC721Mock._safeTransferFrom (contracts/token/ERC721/ERC721.sol:196) + at ERC721Mock.safeTransferFrom (contracts/token/ERC721/ERC721.sol:179) + at ERC721Mock.safeTransferFrom (contracts/token/ERC721/ERC721.sol:162) + at TruffleContract.safeTransferFrom (node_modules/@nomiclabs/truffle-contract/lib/execute.js:157:24) + at Context. (test/token/ERC721/ERC721.behavior.js:321:26) +``` + +The last two lines correspond to the JavaScript test code that executed a +failing transaction. The rest is the Solidity stack trace. +This way you know exactly why your tests aren't passing. + +## Automatic error messages + +Buidler EVM always knows why your transaction or call failed, and uses this +information to make debugging your contracts easier. + +When a transaction fails without a reason, Buidler EVM will create a clear +error message in the following cases: + +- Calling a non-payable function with ETH + +- Sending ETH to a contract without a payable fallback function + +- Calling a non-existent function when there's no fallback function + +- Calling a function with incorrect parameters + +- Calling an external function that doesn't return the right amount of data + +- Calling an external function on a non-contract account + +- Failing to execute an external call because of its parameters (e.g. trying to send too much ETH) + +- Calling a library without `DELEGATECALL` + +- Incorrectly calling a precompiled contract + +## Limitations + +### Supported Solidity versions + +Buidler EVM can run any smart contract, but it only understands Solidity 0.5.1 and newer. + +If you are compiling with an older version of Solidity, or using another language, you can use Buidler EVM, but +Solidity stack traces won't be generated. + +### Solidity optimizer support + +Buidler EVM can work with smart contracts compiled with optimizations, +but this may lead to your stack traces' line numbers being a little off. + +We recommend compiling without optimizations when testing and debugging +your contracts. diff --git a/docs/build-error-list.ts b/docs/build-error-list.ts new file mode 100644 index 0000000000..c9ef2f99d7 --- /dev/null +++ b/docs/build-error-list.ts @@ -0,0 +1,32 @@ +import { + ERROR_RANGES, + ErrorDescriptor, + ERRORS, + getErrorCode +} from "../packages/buidler-core/src/internal/core/errors-list"; + +let content = `# Buidler errors + +This section contains a list of all the possible errors you may encounter when +using Buidler and an explanation of each of them.`; + +for (const [rangeName, range] of Object.entries(ERROR_RANGES)) { + content += ` + +## ${range.title} + +`; + + for (const errorDescriptor of Object.values( + ERRORS[rangeName] + )) { + content += `### ${getErrorCode(errorDescriptor)}: ${errorDescriptor.title} + +${errorDescriptor.description} + + +`; + } +} + +console.log(content); diff --git a/docs/build-error-redirects.ts b/docs/build-error-redirects.ts new file mode 100644 index 0000000000..db83bcb081 --- /dev/null +++ b/docs/build-error-redirects.ts @@ -0,0 +1,25 @@ +import { + ERROR_RANGES, + ErrorDescriptor, + ERRORS, + getErrorCode +} from "../packages/buidler-core/src/internal/core/errors-list"; + +let content = `# Buidler errors redirects +`; + +for (const rangeName of Object.keys(ERROR_RANGES)) { + for (const errorDescriptor of Object.values( + ERRORS[rangeName] + )) { + content += ` +# ${getErrorCode(errorDescriptor)} +/${getErrorCode(errorDescriptor)} /errors/#${getErrorCode(errorDescriptor)} 302 +/${getErrorCode(errorDescriptor).toLowerCase()} /errors/#${getErrorCode( + errorDescriptor + )} 302 +`; + } +} + +console.log(content); diff --git a/docs/build-plugins-doc.ts b/docs/build-plugins-doc.ts new file mode 100644 index 0000000000..e9ffd2e297 --- /dev/null +++ b/docs/build-plugins-doc.ts @@ -0,0 +1,21 @@ +const plugins = require("./.vuepress/plugins.js"); +import { writeFileSync } from "fs"; + +let bashDownload = ` +set -x +set -e +`; + +plugins.forEach(plugin => { + const readmeUrl = plugin.url.replace( + /.+github.com(.+)\/tree(.+)$/, + "https://raw.githubusercontent.com$1$2" + "/README.md" + ); + const readmePath = + "plugins/" + plugin.name.replace("/", "-").replace(/^@/, "") + ".md"; + + bashDownload += `wget ${readmeUrl} -O ${readmePath} +`; +}); + +writeFileSync("wget-readmes.sh", bashDownload); diff --git a/docs/build-site.sh b/docs/build-site.sh index 29999e22df..c54a3a37e1 100644 --- a/docs/build-site.sh +++ b/docs/build-site.sh @@ -1,13 +1,20 @@ #!/usr/bin/env bash +set -x +set -e + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" cd ../ -npm install -npx lerna bootstrap +bash scripts/install.sh cd "$DIR" npm install npm run apidocs bash fix-api-docs.sh +npx ts-node build-plugins-doc.ts +bash wget-readmes.sh + +bash error-list.sh npm run build +bash error-list.sh diff --git a/docs/config/README.md b/docs/config/README.md new file mode 100644 index 0000000000..8c38930c41 --- /dev/null +++ b/docs/config/README.md @@ -0,0 +1,140 @@ +# Configuration + +When Buidler is run, it searches for the closest `buidler.config.js` file starting +from the Current Working Directory. This file normally lives in the root of your project. An empty `buidler.config.js` is enough for Buidler to work. + +The entirety of your Buidler setup (i.e. your config, plugins and custom tasks) is contained in this file. + +## Available config options + +To set up your config, you have to export an object from `buidler.config.js`. + +This object can have the following entries: `defaultNetwork`, `networks`, `solc`, and `paths`. A complete configuration would look like this: + +```js +module.exports = { + defaultNetwork: "networkName", + networks: {...}, + solc: {...}, + paths:{...} +} +``` + +## Networks configuration + +The `networks` config field is an optional object where network names map to their configuration. + +There are two kinds of networks in Buidler: [JSON-RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) based networks, +and the built-in Buidler EVM network. + +You can customize which network is used by default when running Buidler by setting the config's `defaultNetwork` field. If you omit this config, its default value is `"buidlerevm"`. + +### Buidler EVM network + +Buidler comes built-in with a especial network called `buidlerevm`. When using this network, +an instance of [Buidler EVM](../buidler-evm) will be automatically created when your run a task, script or test your smart contracts + +Buidler EVM has first-class support of Solidity. It always knows which +smart contracts are being run and knows exactly what they do and why +they fail. Learn more about it [here](../buidler-evm). + +You can set the following fields on the `buidlerevm` config: + +- `chainId`: The chan id number used by Buidler EVM's blockchain. Default value: `31337`. + +- `from`: The address to use as default sender. If not present the first account of the Buidler EVM is used. + +- `gas`: Its value should be `"auto"` or a number. If a number is used, it will be the gas limit used by default in every transaction. If `"auto"` is used, the gas limit will be automatically estimated. Default value: `9500000`. + +- `gasPrice`: Its value should be `"auto"` or a number. This parameter behaves like `gas`. Default value: `8000000000`. + +- `gasMultiplier`: A number used to multiply the results of gas estimation to give it some slack due to the uncertainty of the estimation process. Default: `1`. + +- `accounts`: An array of the initial accounts that Buidler EVM will create. Each of them must be an object with `privateKey` and `balance` fields. Both of them `0x`-prefixed strings. By default, it has 20 accounts with 10000 ETH each. + +- `blockGasLimit`: The block gas limit to use in Buidler EVM's blockchain. Default value: `9500000` + +- `hardfork`: This setting changes how Buidler EVM works, to mimic Ethereum's mainnet at a given hardfork. It must be one of `"byzantium"`, `"constantinople"`, `"petersburg"`, and `"istanbul"`. Default value: `"petersburg"` + +- `throwOnTransactionFailures`: A boolean that controls if Buidler EVM throws on transaction failures. +If this value is `true`, Buidler EVM will throw [combined JavaScript and Soldity stack traces](../buidler-evm/README.md#solidity-stack-traces) +on transaction failures. If it is `false`, it will return the failing transaction hash. In both cases +the transactions are added into the blockchain. Default value: `true` + +- `throwOnCallFailures`: A boolean that controls if Buidler EVM throws on call failures. +If this value is `true`, Buidler EVM will throw [combined JavaScript and Soldity stack traces](../buidler-evm/README.md#solidity-stack-traces) +when a call fails. If it is `false`, it will return the call's `return data`, which can contain +a revert reason. Default value: `true` + +### JSON-RPC based networks + +These are networks that connect to an external node. Nodes can be running in your computer, like Ganache, or remotely, +like Infura. + +This kind of networks are configured with objects with the following fields: + +- `url`: The url of the node. This argument is required for custom networks. + +- `chainId`: An optional number, used to validate the network Buidler connects to. If not present, this validation is omitted. + +- `from`: The address to use as default sender. If not present the first account of the node is used. + +- `gas`: Its value should be `"auto"` or a number. If a number is used, it will be the gas limit used by default in every transaction. If `"auto"` is used, the gas limit will be automatically estimated. Default value: `"auto"`. + +- `gasPrice`: Its value should be `"auto"` or a number. This parameter behaves like `gas`. Default value: `"auto"`. + +- `gasMultiplier`: A number used to multiply the results of gas estimation to give it some slack due to the uncertainty of the estimation process. Default: `1`. + +- `accounts`: This field controls which accounts Buidler uses. It can use the node's accounts (by setting it to `"remote"`), a list of local accounts (by setting it to an array of hex-encoded private keys), or use an [HD Wallet](#hd-wallet-config). Default value: `"remote"`. + + +### HD Wallet config + +To use an HD Wallet with Buidler you should set your network's `accounts` field to an object with the following fields: + +- `mnemonic`: A required string with the mnemonic of the wallet. + +- `path`: The HD parent of all the derived keys. Default value: `"m/44'/60'/0'/0"`. + +- `initialIndex`: The initial index to derive. Default value: `0`. + +- `count`: The number of accounts to derive. Default value: `10`. + + +### Default networks object + +```js +{ + localhost: { + url: "http://127.0.0.1:8545"; + }, + buidlerevm: { + // See its defaults + } +} +``` + +## Solc configuration + +The `solc` config field is an optional object which can contain the following keys: + +- `version`: The solc version to use. We recommend always setting this field. Default value: `"0.5.11"`. + +- `optimizer`: An object with `enabled` and `runs` keys. Default value: `{ enabled: false, runs: 200 }`. + +- `evmVersion`: A string controlling the target evm version. One of `"homestead"`, `"tangerineWhistle"`, `"spuriousDragon"`, `"byzantium"`, `"constantinople"`, `"petersburg"`, `"istanbul""`. Default value: managed by Solidity. Please, consult its documentation. + +## Path configuration + +You can customize the different paths that Buidler uses by providing an object with the following keys: + +- `root`: The root of the Buidler project. This path is resolved from the `buidler.config.js`'s directory. Default value: The directory containing the config file. +- `sources`: The directory where your contract are stored. This path is resolved from the project's root. Default value: './contracts'. +- `tests`: The directory where your tests are located. This path is resolved from the project's root. Default value: './test'. + +- `cache`: The directory used by Buidler to cache its internal stuff. This path is resolved from the project's root. Default value: './cache'. +- `artifacts`: The directory where the compilation artifacts are stored. This path is resolved from the project's root. Default value: './artifacts'. + +## Quickly integrating other tools from Buidler's config + +Buidler's config file will always run before any task, so you can use it to integrate with other tools, like importing `@babel/register`. diff --git a/docs/documentation/README.md b/docs/documentation/README.md deleted file mode 100644 index 4f7023e2a5..0000000000 --- a/docs/documentation/README.md +++ /dev/null @@ -1,369 +0,0 @@ ---- -prev: false -next: false -sidebar: auto ---- - -# Documentation - -**You don't need to read this to use Buidler, you can get started quickly by reading the [Getting Started](/guides/#getting-started) guide.** - -## Overview - -Buidler is designed around the concepts of _tasks_, and the _Buidler Runtime Environment_: a set of functionality to create tasks. This document describes both concepts in detail. - -If you want to write your own tasks, create plugins, or want to understand Buidler internals, keep reading. - -### Tasks - -Buidler helps smart contract developers automate their workflow by letting them run and create tasks. Tasks can call other tasks, allowing complex workflows to be defined. Users and plugins can override existing tasks, making those workflows customizable and extendable. - -A task is a JavaScript async function with some associated metadata. This metadata is used by Buidler to automate some things for you. Arguments parsing, validation, and help messages are taken care of. - -### Buidler Runtime Environment (BRE) - -The Buidler Runtime Environment, or BRE for short, is an object containing all the functionality that Buidler exposes when running a task, test or script. In reality, Buidler _is_ the BRE. - -When you require Buidler (`const buidler = require("@nomiclabs/buidler")`) you're getting an instance of the BRE. - -During initialization, the Buidler configuration file essentially constructs a list of things to be added to the BRE. This includes tasks, configs and plugins. Then when tasks, tests or scripts run, the BRE is always present and available to access anything that is contained in it. - -The BRE has a role of centralizing coordination across all Buidler components. This architecture allows for plugins to inject functionality that becomes available everywhere the BRE is accessible. - -Check out the [Using the Buidler Runtime Environment (BRE)](#using-the-buidler-runtime-environment-bre) section for more information on how to use it. - -## Creating your own tasks - -You can create your own tasks in your `buidler.config.js` file. The Config DSL will be available in the global environment, with functions for defining tasks. You can also import the DSL with `require("@nomiclabs/buidler/config")` if you prefer to keep things explicit, and take advantage of your editor's autocomplete. - -Creating a task is done by calling the [`task` function](/api/#task). It will return a [`TaskDefinition`](/api/interfaces/taskdefinition.html) object, which can be used to define the task's parameters. There are multiple ways of calling `task`, take a look at [its API documentation](/api/#task). - -The simplest task you can define is - -```js -task("hello", "Prints 'Hello, World!'", async function action( - taskArguments, - env, - runSuper -) { - console.log("Hello, World!"); -}); -``` - -`task`'s first argument is the task name. The second one is its description, which is used for printing help messages in the CLI. The third one, `action`, is an async function that receives the following arguments: - -- `taskArguments` is an object with the parsed CLI arguments of the task. In this case, it's an empty object. -- `env` is the [Buidler Runtime Environment]. -- `runSuper` is only relevant if you are overriding an existing task, which we'll learn about next. Its purpose is to let you run the original task's action. - -Defining the action's arguments is optional. The Buidler Runtime Environment and `runSuper` will also be available in the global scope. We can rewrite our "hello" task this way: - -```js -task("hello", "Prints 'Hello, World!'", async () => - console.log("Hello, World!") -); -``` - -#### Tasks' actions requirements - -The only requirement for writing a task is that the `Promise` returned by its action must not resolve before every async process it started is finished. - -This is an example of a task whose action doesn't meet this requirement. - -```js -task("BAD", "This task is broken", async () => { - setTimeout(() => { - throw new Error( - "This tasks' action returned a promise that resolved before I was thrown" - ); - }, 1000); -}); -``` - -This other task uses a `Promise` to wait for the timeout to fire. - -```js -task("delayed-hello", "Prints 'Hello, World!' after a second", async () => { - return new Promise((resolve, reject) => { - setTimeout(() => { - console.log("Hello, World!"); - resolve(); - }, 1000); - }); -}); -``` - -Manually creating a `Promise` can look challenging, but you don't have to do that if you stick to `async`/`await` and `Promise`-based APIs. For example, you can use the npm package [`delay`](https://www.npmjs.com/package/delay) for a promisified version of `setTimeout`. - -#### Defining parameters - -Buidler tasks can receive `--named` parameters with a value, `--flags`, positional and variadic parameters. Variadic parameters act like JavaScript's rest parameters. The Config DSL `task` function returns an object with methods to define all of them. Once defined, Buidler takes control of parsing parameters, validating them, and printing help messages. - -Adding a positional parameter to the `hello` task can look like this: - -```js -task("hello", "Prints a greeting'") - .addOptionalParam("greeting", "The greeting to print", "Hello, World!") - .setAction(async ({ greeting }) => console.log(greeting)); -``` - -And would be run with `npx buidler hello --greeting Hola`. - -You can read the full documentation of these methods and their possible parameters in the [TaskDefinition API doc](/api/interfaces/taskdefinition.html#methods). - -##### Positional parameters restrictions - -Positional and variadic parameters don't have to be named, and have the usual restrictions of a programming language: - -- No parameter can follow a variadic one -- Required/mandatory parameters can't follow an optional one. - -Failing to follow these restrictions will result in an exception being thrown when loading Buidler. - -##### Type validations - -Buidler takes care of validating and parsing the values provided for each parameter. You can declare the type of a parameter, and Buidler will get the CLI strings and convert it into your desired type. If this conversion fails, it will print an error message explaining why. - -A number of types are available in the Config DSL through a `types` object. This object is injected into the global scope before processing your `buidler.config.js`, but you can also import it explicitly with `const { types } = require("@nomiclabs/buidler/config")` and take advantage of your editor's autocomplete. - -An example of a task defining a type for one of its parameters is - -```js -task("hello", "Prints 'Hello' multiple times") - .addOptionalParam( - "times", - "The number of times to print 'Hello'", - 1, - types.int - ) - .setAction(async ({ times }) => { - for (let i = 0; i < times; i++) { - console.log("Hello"); - } - }); -``` - -Calling it with `npx buidler hello --times notanumber` will result in an error. - -### Overriding tasks - -Defining a task with the same name than an existing one will override it. This is useful to change or extend the behavior of built-in and plugin-provided tasks. - -Task overriding works very similarly to overriding methods when extending a class. You can set your own action, which can call the previous one. The only restriction when overriding tasks, is that you can't add or remove parameters. - -Task override hierarchy order is important since actions can only call the immediately previous definition, using the `runSuper` function. - -Overriding built-in tasks is a great way to customize and extend Buidler. To know which tasks to override, take a look at [src/builtin-tasks](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-core/src/builtin-tasks). - -#### The `runSuper` function - -`runSuper` is a function available to override task's actions. It can be received as the third argument of the task or used directly from the global object. - -This function works like [JavaScript's `super` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super), it calls the task's previously defined action. - -If the task isn't overriding a previous task definition calling `runSuper` will result in an error. To check if calling it won't fail, you can use the `boolean` field `runSuper.isDefined`. - -The `runSuper` function receives a single optional argument: an object with the task arguments. If this argument isn't provided, the same task arguments received by the action calling it will be used. - -### Internal tasks - -Creating tasks with lots of logic makes it hard to extend or customize them. Making multiple small and focused tasks that call each other is better to allow for extension. If you design your tasks in this way, users that want to change only a small aspect of them can override one of your internal tasks. - -For example, the `compile` task is implemented as a pipeline of six tasks. It just calls internal tasks like `compile:get-source-paths`, `compile:get-dependency-graph`, and `compile:build-artifacts`. We recommend prefixing intermediate tasks with their main task and a colon. - -To avoid help messages getting cluttered with lots of intermediate tasks, you can define those using the `internalTask` config DSL function. The `internalTask` function works almost exactly like `task`. The only difference is that tasks defined with it won't be included in help messages. - -## Using the Buidler Runtime Environment (BRE) - -By default, the BRE gives you programmatic access to the task runner and the config system, and exports an [EIP1193-compatible](https://eips.ethereum.org/EIPS/eip-1193) Ethereum provider. You can find more information about [it in its API docs](/api/classes/environment.html). - -Plugins can extend the BRE. For example, [buidler-web3](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3) adds a `web3` instance to it, making it available to tasks, tests and scripts. - -### Exporting globally - -Before running a task, test or script, Buidler injects the BRE into the global scope, turning all of its fields into global variables. When the task execution is completed, these global variables are removed, restoring their original value, if they had one. - -### Explicit usage - -Not everyone likes magic global variables, and Buidler doesn't force you to use them. Everything can be done explicitly in tasks, tests and scripts. - -You can import the config DSL explicitly when defining your tasks, and receive the BRE explicitly as an argument to your actions. You can read more about this in [Creating your own tasks](#creating-your-own-tasks). - -When writing tests or scripts, you can use `require("@nomiclabs/buidler")` to import the BRE. You can read more about this in [Accessing the BRE from outside a task](/documentation/#accessing-from-outside-a-task). - -### Extending - -The BRE only provides the core functionality that users and plugin developers need to start building on top of Buidler. Using it to interface directly with Ethereum in your project can be somewhat harder than expected. - -Everything gets easier when you use higher-level libraries, like [web3.js](https://web3js.readthedocs.io/en/latest/) or [truffle-contract](https://github.com/trufflesuite/truffle-contract), but these libraries need some initialization to work, and that could get repetitive. - -Buidler lets you hook into the BRE construction, and extend it with new functionality. This way, you only have to initialize everything once, and your new features or libraries will be available everywhere the BRE is used. - -You can do this by adding a BRE extender into a queue. This extender is just a synchronous function that receives the BRE, and adds fields to it with your new functionality. These new fields will also get [injected into the global scope during runtime](#exporting-globally). - -For example, adding an instance of Web3.js to the BRE can be done in this way: - -```js -extendEnvironment(env => { - env.Web3 = require("web3"); - - // env.network.provider is the EIP1193-compatible provider. - env.web3 = new env.Web3(new Web3HTTPProviderAdapter(env.network.provider)); -}); -``` - -### Accessing from outside a task - -The BRE can be used from any JavaScript or TypeScript file. To do so, you only have to import it with `require("@nomiclabs/buidler")`. You can do this to keep more control over your development workflow, create your own tools, or to use Buidler with other dev tools from the node.js ecosystem. - -Running test directly with [mocha](https://www.npmjs.com/package/mocha) instead of `npx buidler test` can be done by explicitly importing the BRE in them like this: - -```js -const env = require("@nomiclabs/buidler"); -const assert = require("assert"); - -describe("Buidler Runtime Environment", function() { - it("should have a config field", function() { - assert.notEqual(env.config, undefined); - }); -}); -``` - -This way, tests written for Buidler are just normal mocha tests. This enables you to run them from your favorite editor without the need of any Buidler-specific plugin. For example, you can run them from Visual Studio Code using [Mocha sidebar](https://marketplace.visualstudio.com/items?itemName=maty.vscode-mocha-sidebar). - -## Configuration - -Buidler is exporting a JavaScript object from a `buidler.config.js` file, which, by default, lives in the root of your project. - -The entirety of your Builder setup is contained in this file. Feel free to add any ad-hoc configs you may find useful for your project, just make sure to assign them to `module.exports` so they'll be accessible later on through the config object in the [Builder Runtime Environment](/documentation/#buidler-runtime-environment-bre). - -An empty `builder.config.js` is enough for builder to work. - -### Available config options - -The exported config object can have the following entries: `defaultNetwork`, `networks`, `solc`, and `paths`. A complete configuration would look like this: - -```js -module.exports = { - defaultNetwork: "networkName", - networks: {...}, - solc: {...}, - paths:{...} -} -``` - -#### Networks configuration - -The `networks` config field is an optional object where network names map to objects with the following fields: - -- `url`: The url of the node. This argument is required for custom networks. -- `timeout`: The amount of milliseconds before an RPC call timeouts. Default value: `20000`. -- `chainId`: An optional number, used to validate the network Buidler connects to. If not present, this validation is omitted. -- `from`: The address to use as default sender. If not present the first account of the node is used. -- `gas`: Its value should be `"auto"` or a number. If a number is used, it will be the gas limit used by default in every transaction. If `"auto"` is used, the gas limit will be automatically estimated. Default value: `"auto"`. -- `gasPrice`: Its value should be `"auto"` or a number. This parameter behaves like `gas`. Default value: `"auto"`. -- `gasMultiplier`: A number used to multiply the results of gas estimation to give it some slack due to the uncertainty of the estimation process. Default: `1`. -- `accounts`: This field controls which accounts Buidler uses. It can use the node's accounts (by setting it to `"remote"`), a list of local accounts (by setting it to an array of hex-encoded private keys), or use an HD Wallet (see below). Default value: `"remote"`. - -You can customize which network is used by default when running Buidler by setting the config's `defaultNetwork` field. If you omit this config, its default value will be `"develop"`. - -##### HD Wallet config - -To use an HD Wallet with Buidler you should set your network's `accounts` field to an object with the following fields: - -- `mnemonic`: A required string with the mnemonic of the wallet. -- `path`: The HD parent of all the derived keys. Default value: `"m/44'/60'/0'/0"`. -- `initialIndex`: The initial index to derive. Default value: `0`. -- `count`: The number of accounts to derive. Default value: `10`. - -##### Default networks object - -```js -develop: { - url: "http://127.0.0.1:8545"; -} -``` - -##### Solc configuration - -The `solc` config field is an optional object which can contain the following keys: - -- `version`: The solc version to use. We recommend always setting this field. Default value: `"0.5.8"`. -- `optimizer`: An object with `enabled` and `runs` keys. Default value: `{ enabled: false, runs: 200 }`. -- `evmVersion`: A string controlling the target evm version. One of `"homestead"`, `"tangerineWhistle"`, `"spuriousDragon"`, `"byzantium"`, `"constantinople"`, and `"petersburg"`. Default value: managed by Solidity. Please, consult its documentation. - -##### Path configuration - -You can customize the different paths that buidler uses by providing an object with the following keys: - -- `root`: The root of the Buidler project. This path is resolved from the `buidler.config.js`'s directory. Default value: '.'. -- `sources`: The directory where your contract are stored. This path is resolved from the project's root. Default value: './contracts'. -- `tests`: The directory where your tests are located. This path is resolved from the project's root. Default value: './test'. - -- `cache`: The directory used by Buidler to cache its internal stuff. This path is resolved from the project's root. Default value: './cache'. -- `artifacts`: The directory where the compilation artifacts are stored. This path is resolved from the project's root. Default value: './artifacts'. - -### Quickly integrating other tools - -Buidler's config file will always run before any task, so you can use it to integrate with other tools, like importing `@babel/register`. - -## Plugin development best practices - -This is based on the [TypeScript plugin boilerplate project](https://github.com/nomiclabs/buidler-ts-plugin-boilerplate/). We highly recommend to develop plugins in TypeScript. - -### Plugin functionality - -Plugins are bits of reusable configuration. Anything that you can do in a plugin, can also be done in your config file. You can test your ideas in a config file, and move them into a plugin when ready. - -The main things that plugins can do are extending the Buidler Runtime Environment, extending the Buidler config, defining new tasks, and overriding existing ones. - -#### Extending the BRE - -To learn how to successfully extend the [BRE](/documentation/#buidler-runtime-environment-bre) in TypeScript, and to give your users type information about your extension, take a look at [`src/index.ts`](https://github.com/nomiclabs/buidler-ts-plugin-boilerplate/blob/master/src/index.ts) in the boilerplate repo and read the [Extending the BRE](/documentation/#extending) documentation. - -Make sure to keep the type extension in your main file, as that convention is used across different plugins. - -#### Extending the Buidler config - -An example on how to add fields to the Buidler config can be found in [`src/index.ts`](https://github.com/nomiclabs/buidler-ts-plugin-boilerplate/blob/master/src/index.ts). - -Note that all config extension's have to be optional. - -#### Throwing errors from your plugins - -To show better stack traces to your users, please only throw [`BuidlerPluginError`](/api/classes/buidlerpluginerror.html#constructors) errors, which can be found in `@nomiclabs/buidler/plugins`. - -#### Optimizing your plugin for better startup time - -Keeping startup time short is vital to give a good user experience. To do so, Buidler and its plugins delay any slow import or initialization until the very last moment. To do so, you can use `lazyObject`, and `lazyFunction` from `@nomiclabs/buidler/plugins`. - -An example on how to use them is present in [`src/index.ts`](https://github.com/nomiclabs/buidler-ts-plugin-boilerplate/blob/master/src/index.ts). - -### Notes on dependencies - -Knowing when to use a `dependency` or a `peerDependency` can be tricky. We recommend [these](https://yarnpkg.com/blog/2018/04/18/dependencies-done-right/) [articles](https://lexi-lambda.github.io/blog/2016/08/24/understanding-the-npm-dependency-model/) to learn about their distinctions. - -If you are still in doubt, these can be helpful: - -- Rule of thumb #1: Buidler MUST be a peer dependency. -- Rule of thumb #2: If your plugin P depends on another plugin P2, P2 should be a peer dependency of P, and P2's peer dependencies should be peer dependencies of P. -- Rule of thumb #3: If you have a non-Buidler dependency that your users may `require()`, it should be a peer dependency. -- Rule of thumb #4: Every `peerDependency` should also be a `devDependency`. - -Also, if you depend on a Buidler plugin written in TypeScript, you should add it's main `.d.ts` to the `include` array of `tsconfig.json`. - -### Hooking into the user's workflow - -To integrate into your users' existing workflow, we recommend plugin authors to override built-in tasks whenever it makes sense. - -Examples of suggested overrides are: - -- Preprocessing smart contracts should override one of the `compile` internal tasks. -- Linter integrations should override the `check` task. -- Plugins generating intermediate files should override the `clean` task. - -For a list of all the built-in tasks and internal tasks please take a look at [`task-names.ts`](https://github.com/nomiclabs/buidler/blob/master/packages/buidler-core/src/builtin-tasks/task-names.ts) - - -[tasks]: #tasks -[Buidler Runtime Environment]: #buidler-runtime-environment-bre \ No newline at end of file diff --git a/docs/error-list.sh b/docs/error-list.sh new file mode 100644 index 0000000000..3c6826119b --- /dev/null +++ b/docs/error-list.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -x +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +cd "$DIR" + +mkdir -p errors +npx ts-node build-error-list.ts > errors/README.md +mkdir -p .vuepress/dist + +npx ts-node build-error-redirects.ts > .vuepress/dist/_redirects +cat _redirects >> .vuepress/dist/_redirects diff --git a/docs/getting-started/README.md b/docs/getting-started/README.md new file mode 100644 index 0000000000..79b2bffbb4 --- /dev/null +++ b/docs/getting-started/README.md @@ -0,0 +1,236 @@ +## Overview + +Buidler is a task runner that facilitates building Ethereum smart contracts. It helps developer manage and automate the recurring tasks that are inherent to the process of building smart contracts, as well as easily introducing more functionality around this workflow. This means compiling and testing at the very core. + +Buidler is designed around the concepts of **tasks** and **plugins**. Every time you're running Buidler from the CLI you're running a task. E.g. `npx buidler compile` is running the `compile` task. + +The bulk of Buidler's functionality comes from plugins, which as a developer you're free to choose the ones you want to use. Buidler is unopinionated in terms of what tools you end up using, but it does come with some built-in defaults. All of which can be overriden. + +Tasks can call other tasks, allowing complex workflows to be defined. Users and plugins can override existing tasks, making those workflows customizable and extendable. + +## Installation + +### Local installation (recommended) + +The recommended way of using Buidler is through a local installation in your project. This way your environment will be reproducible and you will avoid future version conflicts. To use it in this way you will need to prepend `npx` to run it (i.e. `npx buidler`). To install locally initialize your `npm` project using `npm init` and follow the instructions. Once ready run: + + npm install --save-dev @nomiclabs/buidler + +### Global installation + +Be careful about inconsistent behavior across different projects that use different Buidler versions. + + npm install --global @nomiclabs/buidler + +If you choose to install Buidler globally, you have to do the same for its plugins and their dependencies. + +## Quick Start + +This guide will explore the basics of creating a Buidler project. + +A barebones installation with no plugins allows you to compile your Solidity code, install plugins and create your own tasks. + +To create your Buidler project run `npx buidler` in your project folder: + +``` +$ npx buidler +888 d8b 888 888 +888 Y8P 888 888 +888 888 888 +88888b. 888 888 888 .d88888 888 .d88b. 888d888 +888 "88b 888 888 888 d88" 888 888 d8P Y8b 888P" +888 888 888 888 888 888 888 888 88888888 888 +888 d88P Y88b 888 888 Y88b 888 888 Y8b. 888 +88888P" "Y88888 888 "Y88888 888 "Y8888 888 + +👷 Welcome to Buidler v1.0.0 👷‍‍ + +? What do you want to do? … +❯ Create a sample project + Create an empty buidler.config.js + Quit +``` + +Let’s create the sample project and go through the steps to try out the sample task and compile, test and deploy the sample contract. + +The sample project uses the `buidler-truffle5`, which makes Buidler compatible with +tests built for Truffle. You can learn more about it [in this guide](../guides/truffle-testing.md). +For now, all you need to know is that you may need to install some dependencies with + +```bash +npm install --save-dev @nomiclabs/buidler-truffle5 @nomiclabs/buidler-web3 web3 +``` + +### Running tasks + +To first get a quick sense of what's available and what's going on, run `npx buidler` in your project folder: + +``` +$ npx buidler +Buidler version 1.0.0 + +Usage: buidler [GLOBAL OPTIONS] [TASK OPTIONS] + +GLOBAL OPTIONS: + + --config A Buidler config file. + --emoji Use emoji in messages. + --help Shows this message. + --network The network to connect to. (default: "buidlerevm") + --show-stack-traces Show stack traces. + --version Shows buidler's version. + + +AVAILABLE TASKS: + + accounts Prints a list of the available accounts + clean Clears the cache and deletes all artifacts + compile Compiles the entire project, building all artifacts + console Opens a buidler console + flatten Flattens and prints all contracts and their dependencies + help Prints this message + run Runs a user-defined script after compiling the project + test Runs mocha tests + +To get help for a specific task run: buidler help [task] +``` + +This is the list of built-in tasks, and the sample `accounts` task. Further ahead, when you start using plugins to add more functionality, tasks defined by those will also show up here. This is your starting point to find out what tasks are available to run. + +If you take a look at `buidler.config.js`, you will find the definition of the task `accounts`: + +```js{5-11} +usePlugin("@nomiclabs/buidler-truffle5"); + +// This is a sample Buidler task. To learn how to create your own go to +// https://buidler.dev/guides/create-task.html +task("accounts", "Prints the list of accounts", async () => { + const accounts = await web3.eth.getAccounts(); + + for (const account of accounts) { + console.log(account); + } +}); + +module.exports = {}; +``` + +To run it, try `npx buidler accounts`: + +``` +$ npx buidler accounts +0xc783df8a850f42e7F7e57013759C285caa701eB6 +0xeAD9C93b79Ae7C1591b1FB5323BD777E86e150d4 +0xE5904695748fe4A84b40b3fc79De2277660BD1D3 +0x92561F28Ec438Ee9831D00D1D59fbDC981b762b2 +0x2fFd013AaA7B5a7DA93336C2251075202b33FB2B +0x9FC9C2DfBA3b6cF204C37a5F690619772b926e39 +0xFbC51a9582D031f2ceaaD3959256596C5D3a5468 +0x84Fae3d3Cba24A97817b2a18c2421d462dbBCe9f +0xfa3BdC8709226Da0dA13A4d904c8b66f16c3c8BA +0x6c365935CA8710200C7595F0a72EB6023A7706Cd +0xD7de703D9BBC4602242D0f3149E5fFCD30Eb3ADF +0x532792B73C0C6E7565912E7039C59986f7E1dD1f +0xEa960515F8b4C237730F028cBAcF0a28E7F45dE0 +0x3d91185a02774C70287F6c74Dd26d13DFB58ff16 +0x5585738127d12542a8fd6C71c19d2E4CECDaB08a +0x0e0b5a3F244686Cf9E7811754379B9114D42f78B +0x704cF59B16Fd50Efd575342B46Ce9C5e07076A4a +0x0a057a7172d0466AEF80976D7E8c80647DfD35e3 +0x68dfc526037E9030c8F813D014919CC89E7d4d74 +0x26C43a1D431A4e5eE86cD55Ed7Ef9Edf3641e901 +``` + +### Compiling your contracts + +Next, if you take a look at `contracts/`, you should be able to find `Greeter.sol:` + +```js +pragma solidity ^0.5.1; + +contract Greeter { + + string greeting; + + constructor(string memory _greeting) public { + greeting = _greeting; + } + + function greet() public view returns (string memory) { + return greeting; + } + +} +``` + +To compile it, simply run: + +```bash +npx buidler compile +``` + +### Testing your contracts + +The sample project comes with these tests that use [`@truffle/contract`](https://www.npmjs.com/package/@truffle/contract) and +[Web3.js](https://github.com/ethereum/web3.js). You can use other libraries if you want, check the integrations described in our guides. + +```js +const Greeter = artifacts.require("Greeter"); + +// Traditional Truffle test +contract("Greeter", accounts => { + it("Should return the new greeting once it's changed", async function() { + const greeter = await Greeter.new("Hello, world!"); + assert.equal(await greeter.greet(), "Hello, world!"); + + await greeter.setGreeting("Hola, mundo!"); + + assert.equal(await greeter.greet(), "Hola, mundo!"); + }); +}); +``` + +You can run your tests with `npx buidler test` + +``` +$ npx buidler test +Compiling... +Compiled 1 contract successfully + + + Contract: Greeter + ✓ Should return the new greeting once it's changed (323ms) + + 1 passing (323ms) +``` + +### Deploying your contracts + +Next, to deploy the contract we will use a Buidler script. +Create a file `deploy.js` in `scripts/` with the following code: + +```js +async function main() { + const Greeter = artifacts.require("Greeter"); + + const greeter = await Greeter.new("Hello, Buidler!"); + console.log("Greeter deployed to:", greeter.address); +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); +``` +And run it with `npx buidler run scripts/deploy.js`: +``` +$ npx buidler run scripts/deploy.js +All contracts have already been compiled, skipping compilation. +Greeter deployed to: 0x080f632fB4211CFc19d1E795F3f3109f221D44C9 +``` + +Congrats! You have created a project, ran a Buidler task, compiled a smart contract, installed a Truffle integration plugin, wrote and ran a test using the Truffle plugin, and deployed a contract. + +For any questions or feedback you may have, you can find us in the [Buidler Support Telegram group](http://t.me/BuidlerSupport). diff --git a/docs/guides/README.md b/docs/guides/README.md deleted file mode 100644 index c3342cce6e..0000000000 --- a/docs/guides/README.md +++ /dev/null @@ -1,205 +0,0 @@ ---- -prev: false ---- - -# Getting started - -In this guide, we’ll explore how to start using Buidler in your Ethereum project. - -**What makes Buidler special? What can you achieve with it?** - -Buidler allows you to streamline your development workflow by making it easy to incorporate other tools into your process, as well as granting you all the flexibility you need to adapt the tools to your exact needs. What dependencies and tools you use is up to you. Buidler will only help you orchestrate them. - -Out of the box, you can compile your Solidity code, install plugins and create your own tasks. - -Let’s install it to try it out: - -```bash -npm install @nomiclabs/buidler -``` - -To create a Buidler project just run `npx buidler` in your project folder: - -![](https://cdn-images-1.medium.com/max/1600/1*Ri6bdhh0eIJTJT31dy6DhQ.png) - -Let’s create the sample project and go through the steps to try out the sample task, compile, test and deploy the sample contract. - -To first get a quick sense of what's available and what's going on, run `npx buidler` in your project folder: -``` -$ npx buidler -Buidler version 1.0.0-beta.13 - -Usage: buidler [GLOBAL OPTIONS] [TASK OPTIONS] - -GLOBAL OPTIONS: - - --config A Buidler config file. - --emoji Use emoji in messages. - --help Shows this message. - --network The network to connect to. (default: "develop") - --show-stack-traces Show stack traces. - --version Shows buidler's version. - - -AVAILABLE TASKS: - - accounts Prints a list of the available accounts - clean Clears the cache and deletes all artifacts - compile Compiles the entire project, building all artifacts - console Opens a buidler console - flatten Flattens and prints all contracts and their dependencies - help Prints this message - run Runs a user-defined script after compiling the project - test Runs mocha tests - -To get help for a specific task run: buidler help [task] -``` - -This is the list of built-in tasks, and the sample `accounts` task. Further ahead, when you start using plugins to add more functionality, tasks defined by those will also show up here. This is your starting point to find out what tasks are available to run. - -If you take a look at `buidler.config.js`, you will find the definition of the task `accounts`: - -```js -task("accounts", "Prints a list of the available accounts", async () => { - const accounts = await ethereum.send("eth_accounts"); - - console.log("Accounts:", accounts); -}); - -module.exports = {}; -``` - -_NOTE: in the Buidler 1.0.0 beta release we’ve disabled the automatic ganache instance feature to keep working on its stability, so you’ll need to run it manually. This feature will be back by the time we ship the stable release. Please run `ganache-cli` in a separate terminal to keep going._ - -To run it, try `npx buidler accounts`: - -``` -$ npx buidler accounts -Accounts: [ '0x9d6bd5939d6e2629f2bdffac5417ba22e31ea6a5', - '0xdb981036cf05c2219121c778578300cc6b91bd34', - '0xdc66201940a7ced201b1e4ed9fa72047fa029dc1', - '0x6a0ead959f30e51e86bb2285ab5e36a68ac22d98', - '0x9bc40d79da06d28d57982eb9e40cd0ba095cdae8', - '0xcff265234958dfe27e7e1bbfcbd253ac4882bcae', - '0x13447a4658db5f9bdab4f82656958b7688c4435f', - '0x7dce2d4229cb4ccbcd050ffe7bc405d936314a73', - '0x2f52b335f53f16a5d9727da8d2231923fa04f0c5', - '0x23024feafd6587ef4576496484fee2796ba66e3c' ] -``` - -You will learn how to create your own tasks in the [next guide](/guides/create-task.md). - -Next, if you take a look at `contracts/`, you should be able to find `Greeter.sol:` - -```js -pragma solidity ^0.5.1; - -contract Greeter { - - string greeting; - - constructor(string memory _greeting) public { - greeting = _greeting; - } - - function greet() public view returns (string memory) { - return greeting; - } - -} -``` - -To compile it, simply run: - -```bash -npx buidler compile -``` - -Now, you’ll likely want to run some tests. Let’s install `buidler-truffle5` and test out the Truffle integration: - -```bash -npm install @nomiclabs/buidler-truffle5 @nomiclabs/buidler-web3 web3 -``` - -Add `usePlugin("@nomiclabs/buidler-truffle5")` to the top of your `buidler.config.js`, so that it looks like this: -```js -usePlugin("@nomiclabs/buidler-truffle5") - -task("accounts", "Prints a list of the available accounts", async () => { - const accounts = await ethereum.send("eth_accounts"); - - console.log("Accounts:", accounts); -}); - -module.exports = {}; -``` - -Change `test/sample-test.js` to: - -```js -const assert = require("assert"); - -describe("Ethereum provider", function() { - it("Should return the accounts", async function() { - const accounts = await ethereum.send("eth_accounts"); - assert(accounts.length !== 0, "No account was returned"); - }); -}); - -contract("Greeter", function() { - it("Should give the correct greeting", async function() { - const Greeter = artifacts.require("Greeter"); - const greeter = await Greeter.new("Hello, Buidler!"); - - assert.equal(await greeter.greet(), "Hello, Buidler!"); - }); -}); -``` - -And run `npx buidler test` - -``` -$ npx buidler test -Compiling... -Compiled 1 contract successfully - - - Ethereum provider - ✓ Should return the accounts - - Greeter - ✓ Should give the correct greeting (376ms) - - - 2 passing (383ms) -``` - -Next, to deploy the contract we will use the Truffle plugin again. Create a file `deploy.js` in `scripts/`: - -```js -async function main() { - const Greeter = artifacts.require("Greeter"); - - const greeter = await Greeter.new("Hello, Buidler!"); - console.log("Greeter deployed to:", greeter.address); -} - -main() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); -``` -And run it with `npx buidler run scripts/deploy.js`: -``` -$ npx buidler run scripts/deploy.js -All contracts have already been compiled, skipping compilation. -Greeter deployed to: 0x080f632fB4211CFc19d1E795F3f3109f221D44C9 -``` - -Congrats! You have created a project, ran a Buidler task, compiled a smart contract, installed a Truffle integration plugin, wrote and ran a test using the Truffle plugin, and deployed a contract. - -These cover the basics to start using Buidler. Move on to the next section to learn more. - -For any questions or feedback you may have, you can find us in the [Buidler Support Telegram group](http://t.me/BuidlerSupport). diff --git a/docs/guides/buidler-console.md b/docs/guides/buidler-console.md new file mode 100644 index 0000000000..46fbdbbd9b --- /dev/null +++ b/docs/guides/buidler-console.md @@ -0,0 +1,70 @@ +# Using the Buidler console + +Budiler comes built-in with an interactive JavaScript console. You can use it by running `npx buidler console`: +``` +$ npx buidler console +All contracts have already been compiled, skipping compilation. +> +``` + +The `compile` task will be called before opening the console prompt, but you can skip this with the `--no-compile` parameter. + +The execution environment for the console is the same as for tasks. This means the configuration has been processed, and the [Buidler Runtime Environment] initialized and injected into the global scope. For example, that you'll have access in the global scope to the `config` object: +``` +> config +{ defaultNetwork: 'buidlerevm', + solc: + { version: '0.5.8', optimizer: { enabled: false, runs: 200 } }, + + ... + +} +> +``` + +And the initialized `ethers` object if you're using the `buidler-ethers` plugin: +``` +> ethers +{ provider: + EthersProviderWrapper { + + ... + + }, + getContract: [AsyncFunction: getContract], + signers: [AsyncFunction: signers] } +> +``` + +And the `artifacts` object if you're using the `buidler-truffle5` plugin, and so on. + +Anything that has been injected into the [Buidler Runtime Environment] will be magically available in the global scope, or if you're the more explicit kind of developer, you can also require the BRE explicitly and get autocomplete: + +``` +> const buidler = require("@nomiclabs/buidler") +undefined +> buidler. +buidler.__defineGetter__ buidler.__defineSetter__ buidler.__lookupGetter__ buidler.__lookupSetter__ buidler.__proto__ +buidler.hasOwnProperty buidler.isPrototypeOf buidler.propertyIsEnumerable buidler.toLocaleString buidler.toString +buidler.valueOf + +buidler._runTaskDefinition buidler.constructor buidler.injectToGlobal + +buidler._extenders buidler.buidlerArguments buidler.config buidler.ethereum buidler.ethers +buidler.network buidler.run buidler.tasks + +> +``` + +You will also notice that the console has the handy history feature you expect out of most interactive terminals, including across different sessions. Try it by pressing the up arrow key. + +### Asynchronous operations and top-level await + +Interacting with the Ethereum network and your smart contracts are asynchronous operations, hence most APIs and libraries +use JavaScript's `Promise` for returning values. + +To make things easier, Buidler's console supports `await` top-level await (i.e. `console.log(await web3.eth.getBalance()`). To use this feature, you need to be using Node 10 or higher. + +For any help or feedback you may have, you can find us in the [Buidler Support Telegram group](http://t.me/BuidlerSupport). + +[Buidler Runtime Environment]: ../advanced/buidler-runtime-environment.md diff --git a/docs/guides/compile-contracts.md b/docs/guides/compile-contracts.md new file mode 100644 index 0000000000..a232a06b1b --- /dev/null +++ b/docs/guides/compile-contracts.md @@ -0,0 +1,89 @@ +# Compiling your contracts + +To compile your contracts in your Buidler project, use the `compile` built-in task: +``` +$ npx buidler compile +Compiling... +Compiled 1 contract successfully +``` + +The compiled artifacts will be saved in the `artifacts/` directory by default, or whatever your configured artifacts path is. Look at the [paths configuration section](../config) to learn how to change it. This directory will be created if it doesn't exist. + +After the initial compilation, if the contract code hasn't changed then Buidler will skip compilation when running the `compile` task: +``` +$ npx buidler compile +All contracts have already been compiled, skipping compilation. +``` + +To force a compilation you can use the `--force` argument, or run `npx buidler clean` to clear the caches and delete the artifacts. + +## Artifacts + +Compiling with Buidler generates one JSON artifact per contract. These are based on Truffle's artifact format, and are compatible with most tools. + +Each artifact consists of a json with the following properties: + +- `contractName`: A string with the contract's name. + +- `abi`: A [JSON description](https://solidity.readthedocs.io/en/latest/abi-spec.html#abi-json) of the contract's ABI. + +- `bytecode`: A `"0x"`-prefixed hex string of the unlinked deployment bytecode. If the contract is not deployable then, this has the `"0x"` string. + +- `deployedBytecode`: A `"0x"`-prefixed hex string of the unlinked runtime/deployed bytecode. If the contract is not deployable then, this has the `"0x"` string. + +- `linkReferences`: The bytecode's link references object [as returned by solc](https://solidity.readthedocs.io/en/latest/using-the-compiler.html). If the contract doesn't need to be linked, this value contains an empty object. + +- `deployedLinkReferences`: The deployed bytecode's link references object [as returned by solc](https://solidity.readthedocs.io/en/latest/using-the-compiler.html). If the contract doesn't need to be linked, this value contains an empty object. + +## Configuring the compiler + +If you need to customize the `solc` compiler options, then you can do so through the `solc` config field in your `buidler.config.js`, which is an optional object that can contain the following properties: + +- `version`: the solc version to use. We recommend always setting this field. Default value: `"0.5.11"`. + +- `optimizer`: an object with `enabled` and `runs` keys. Default value: `{ enabled: false, runs: 200 }`. + +- `evmVersion`: a string controlling the target evm version. One of `homestead`, `tangerineWhistle`, `spuriousDragon`, `byzantium`, `constantinople`, `petersburg`, and `instanbul`. Default value: managed by `solc`. + +## Solidity 4 and Solidity 5 contracts in the same project + +Buidler can handle scenarios where you need to compile Solidity 4 and Solidity 5 contracts in the same project. An example of this is when there are deployed contracts that have been written in Solidity 4 but your new contracts that depend on the old ones are written in Solidity 5, or different contract dependencies use different Solidity versions and you need both of these to play along to run your tests. + +We have a plugin to make this easier on our roadmap, but until that's released you will need to create an extra config file to compile the Solidity 4 contracts, and two separate directories for the code. + +Create the directories `4` and `5` inside `contracts/` so that it looks like this: +``` +contracts/ + 4/ + 5/ +``` + +Create a `buidler.config.4.js` with the following contents: +```js +module.exports = { + solc: { + version: "0.4.25" + }, + paths: { + sources: "./contracts/4", + } +}; +``` + +Set your `buidler.config.js` to the following contents: +```js +// assuming you're running Truffle 5 tests. +// There's also buidler-truffle4 if your tests are written for the Truffle 4 API. +// You can use either of them with both versions of Solidity. +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports = { + paths: { + sources: "./contracts/5", + } +}; +``` + +Then run at least once `npx buidler compile --config buidler.config.4.js`, and use `npx buidler test` as you normally would to run your tests. + +For any help or feedback you may have, you can find us in the [Buidler Support Telegram group](http://t.me/BuidlerSupport). diff --git a/docs/guides/create-plugin.md b/docs/guides/create-plugin.md index 0bc033a544..dd90a97fc9 100644 --- a/docs/guides/create-plugin.md +++ b/docs/guides/create-plugin.md @@ -1,8 +1,3 @@ ---- -prev: "create-task" -next: "truffle-migration" ---- - # Creating a plugin In this guide, we will explore the creation of plugins for Buidler, which are the key component for integrating other tools and extending the built-in functionality. @@ -21,7 +16,7 @@ For example, adding the following to `buidler.config.js`: ```js extendEnvironment(env => { - env.hi = "hello, buidler"; + env.hi = "Hello, Buidler!"; }); ``` @@ -29,7 +24,7 @@ Will make `hi` available everywhere where the environment is accessible. ```js extendEnvironment(env => { - env.hi = "hello, buidler"; + env.hi = "Hello, Buidler!"; }); task("envtest", (args, env) => { @@ -43,7 +38,7 @@ Will yield: ``` $ npx buidler envtest -hello, buidler +Hello, Buidler! ``` This is literally all it takes to put together a plugin for Buidler. Injecting an ethers.js instance into the environment would look like this: @@ -82,11 +77,10 @@ Now, this is just injecting from the config file, which by itself can be useful You can use the [plugin boilerplate repository](https://github.com/nomiclabs/buidler-ts-plugin-boilerplate) as a starting point to create an npm package for your plugin. We highly recommend using TypeScript for your plugins, especially if you’re looking to inject objects into the [Buidler Runtime Environment]. This way, types can be exported and text editors can autocomplete for your users. -For a fully functional ethers plugin written in TypeScript take a look at [nomiclabs/buidler-ethers](https://github.com/nomiclabs/buidler-ethers) on Github. +For a fully functional ethers.js plugin written in TypeScript take a look at [nomiclabs/buidler-ethers](https://github.com/nomiclabs/buidler-ethers) on Github. -Take a look at the [plugin best practices documentation](/docs/guides/create-plugin.md) and if you end up publishing a plugin, send us a pull request to add it to our [plugins section](/plugins). +Take a look at the [plugin best practices documentation](../advanced/building-plugins.md) and if you end up publishing a plugin, send us a pull request to add it to our [plugins section](../plugins/README.md). For any questions or feedback you may have, you can find us in the [Buidler Support Telegram group](http://t.me/BuidlerSupport). - -[Buidler Runtime Environment]: /documentation/#buidler-runtime-environment-bre \ No newline at end of file +[Buidler runtime environment]: ../advanced/buidler-runtime-environment.md diff --git a/docs/guides/create-task.md b/docs/guides/create-task.md index ee44790900..d86fa1ae2e 100644 --- a/docs/guides/create-task.md +++ b/docs/guides/create-task.md @@ -1,17 +1,16 @@ - - # Creating a task -In this guide, we will explore the creation of tasks in Buidler, which are the core component used for automation. For a general overview of using Buidler refer to the [Getting started guide](/guides/#getting-started). +This guide will explore the creation of tasks in Buidler, which are the core component used for automation. -## **What exactly are tasks in Buidler?** +A task is a JavaScript async function with some associated metadata. This metadata is used by Buidler to automate some things for you. Arguments parsing, validation, and help messages are taken care of. Everything you can do in Buidler is defined as a task. The default actions that come out of the box are built-in tasks and they are implemented using the same APIs that are available to you as a user. To see the currently available tasks in your project, run `npx buidler`: + ``` $ npx buidler -Buidler version 1.0.0-beta.13 +Buidler version 1.0.0 Usage: buidler [GLOBAL OPTIONS] [TASK OPTIONS] @@ -20,7 +19,7 @@ GLOBAL OPTIONS: --config A Buidler config file. --emoji Use emoji in messages. --help Shows this message. - --network The network to connect to. (default: "develop") + --network The network to connect to. (default: "buidlerevm") --show-stack-traces Show stack traces. --version Shows buidler's version. @@ -42,21 +41,21 @@ For some ideas, you could create a task to reset the state of a development envi Let’s go through the process of creating one to interact with a smart contract. -Tasks in Buidler are asynchronous JavaScript functions that get access to the [Buidler Runtime Environment](/documentation/#buidler-runtime-environment-bre), through which you get access to the configuration, parameters, programmatic access to other tasks and any objects plugins may have injected. +Tasks in Buidler are asynchronous JavaScript functions that get access to the [Buidler Runtime Environment](../advanced/buidler-runtime-environment.md), through which you get access to the configuration, parameters, programmatic access to other tasks and any objects plugins may have injected. -For our example we will use Web3.js to interact with our contracts, so we will install the [web3 plugin](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3), which injects a Web3 instance into the Buidler environment: +For our example we will use Web3.js to interact with our contracts, so we will install the [Web3.js plugin](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3), which injects a Web3.js instance into the Buidler environment: ```bash -npm install @nomiclabs/buidler-web3 web3 +npm install --save-dev @nomiclabs/buidler-web3 web3 ``` -_Take a look at the [list of Buidler plugins](/plugins) to see other available libraries._ +_Take a look at the [list of Buidler plugins](../plugins/README.md) to see other available libraries._ Task creation code can go in `buidler.config.js`, or whatever your configuration file is called. It’s a good place to create simple tasks. If your task is more complex, it's also perfectly valid to split the code into several files and `require` from the configuration file. -_If you’re writing a Buidler plugin that adds a task, they can also be created from a separate npm package. Learn more about creating tasks through plugins in our [How to create a plugin guide](/guides/create-plugin.md)._ +_If you’re writing a Buidler plugin that adds a task, they can also be created from a separate npm package. Learn more about creating tasks through plugins in our [How to create a plugin guide](./create-plugin.md)._ -**The configuration file is always executed on startup before anything else happens.** It's good to keep this in mind. We will load the Web3.js plugin and add our task creation code to it. +**The configuration file is always executed on startup before anything else happens.** It's good to keep this in mind. We will load the Web3.js plugin and add our task creation code to it. For this tutorial, we're going to create a task to get an account’s balance from the terminal. You can do this with the Buidler’s config DSL, which is available in the global scope of `buidler.config.js`: @@ -73,7 +72,7 @@ After saving the file, you should already be able to see the task in Buidler: ``` $ npx buidler -Buidler version 1.0.0-beta.13 +Buidler version 1.0.0 Usage: buidler [GLOBAL OPTIONS] [TASK OPTIONS] @@ -82,7 +81,7 @@ GLOBAL OPTIONS: --config A Buidler config file. --emoji Use emoji in messages. --help Shows this message. - --network The network to connect to. (default: "develop") + --network The network to connect to. (default: "buidlerevm") --show-stack-traces Show stack traces. --version Shows buidler's version. @@ -117,7 +116,7 @@ When you add a parameter to a task, Buidler will handle its help messages for yo ``` $ npx buidler help balance -Buidler version 1.0.0-beta.13 +Buidler version 1.0.0 Usage: buidler [GLOBAL OPTIONS] balance --account @@ -130,19 +129,19 @@ balance: Prints an account's balance For global options help run: buidler help ``` -Let’s now get the account’s balance. The [Buidler Runtime Environment](/documentation/#buidler-runtime-environment-bre) will be available in the global scope. By using Buidler’s [web3 plugin](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3) we get access to a web3 instance: +Let’s now get the account’s balance. The [Buidler Runtime Environment](../advanced/buidler-runtime-environment.md) will be available in the global scope. By using Buidler’s [Web3.js plugin](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3) we get access to a Web3.js instance: ```js usePlugin("@nomiclabs/buidler-web3"); task("balance", "Prints an account's balance") - .addParam("account", "The account's address") - .setAction(async taskArgs => { - const account = web3.utils.toChecksumAddress(taskArgs.account); - const balance = await web3.eth.getBalance(account); + .addParam("account", "The account's address") + .setAction(async taskArgs => { + const account = web3.utils.toChecksumAddress(taskArgs.account); + const balance = await web3.eth.getBalance(account); - console.log(web3.utils.fromWei(balance, "ether"), "ETH"); - }); + console.log(web3.utils.fromWei(balance, "ether"), "ETH"); + }); module.exports = {}; ``` @@ -155,6 +154,156 @@ $ npx buidler balance --account 0x080f632fb4211cfc19d1e795f3f3109f221d44c9 ``` And there you have it. Your first fully functional Buidler task, allowing you to interact with the Ethereum blockchain in an easy way. -For more detailed information about creating tasks, refer to the [tasks documentation page](/documentation/#tasks). + +## Advanced usage + +You can create your own tasks in your `buidler.config.js` file. The Config DSL will be available in the global environment, with functions for defining tasks. You can also import the DSL with `require("@nomiclabs/buidler/config")` if you prefer to keep things explicit, and take advantage of your editor's autocomplete. + +Creating a task is done by calling the [`task` function](/api/#task). It will return a [`TaskDefinition`](/api/interfaces/taskdefinition.html) object, which can be used to define the task's parameters. There are multiple ways of calling `task`, take a look at [its API documentation](/api/#task). + +The simplest task you can define is + +```js +task("hello", "Prints 'Hello, World!'", async function(taskArguments, env, runSuper) { + console.log("Hello, World!"); +}); +``` + +`task`'s first argument is the task name. The second one is its description, which is used for printing help messages in the CLI. The third one is an async function that receives the following arguments: + +- `taskArguments` is an object with the parsed CLI arguments of the task. In this case, it's an empty object. + +- `env` is the [Buidler Runtime Environment](../advanced/buidler-runtime-environment.md). + +- `runSuper` is only relevant if you are overriding an existing task, which we'll learn about next. Its purpose is to let you run the original task's action. + +Defining the action's arguments is optional. The Buidler Runtime Environment and `runSuper` will also be available in the global scope. We can rewrite our "hello" task this way: + +```js +task("hello", "Prints 'Hello, World!'", async () => { + console.log("Hello, World!"); +}); +``` + +### Tasks' actions requirements + +The only requirement for writing a task is that the `Promise` returned by its action must not resolve before every async process it started is finished. + +This is an example of a task whose action doesn't meet this requirement. + +```js +task("BAD", "This task is broken", async () => { + setTimeout(() => { + throw new Error( + "This tasks' action returned a promise that resolved before I was thrown" + ); + }, 1000); +}); +``` + +This other task uses a `Promise` to wait for the timeout to fire. + +```js +task("delayed-hello", "Prints 'Hello, World!' after a second", async () => { + return new Promise((resolve, reject) => { + setTimeout(() => { + console.log("Hello, World!"); + resolve(); + }, 1000); + }); +}); +``` + +Manually creating a `Promise` can look challenging, but you don't have to do that if you stick to `async`/`await` and `Promise`-based APIs. For example, you can use the npm package [`delay`](https://www.npmjs.com/package/delay) for a promisified version of `setTimeout`. + +### Defining parameters + +Buidler tasks can receive `--named` parameters with a value, `--flags`, positional and variadic parameters. Variadic parameters act like JavaScript's rest parameters. The Config DSL `task` function returns an object with methods to define all of them. Once defined, Buidler takes control of parsing parameters, validating them, and printing help messages. + +Adding an optional parameter to the `hello` task can look like this: + +```js +task("hello", "Prints a greeting'") + .addOptionalParam("greeting", "The greeting to print", "Hello, World!") + .setAction(async ({ greeting }) => console.log(greeting)); +``` + +And would be run with `npx buidler hello --greeting Hola`. + +You can read the full documentation of these methods and their possible parameters in the [TaskDefinition API doc](/api/interfaces/taskdefinition.html#methods). + +#### Positional parameters restrictions + +Positional and variadic parameters don't have to be named, and have the usual restrictions of a programming language: + +- No positional parameter can follow a variadic one +- Required/mandatory parameters can't follow an optional one. + +Failing to follow these restrictions will result in an exception being thrown when loading Buidler. + +#### Type validations + +Buidler takes care of validating and parsing the values provided for each parameter. You can declare the type of a parameter, and Buidler will get the CLI strings and convert them into your desired type. If this conversion fails, it will print an error message explaining why. + +A number of types are available in the Config DSL through a `types` object. This object is injected into the global scope before processing your `buidler.config.js`, but you can also import it explicitly with `const { types } = require("@nomiclabs/buidler/config")` and take advantage of your editor's autocomplete. + +An example of a task defining a type for one of its parameters is + +```js +task("hello", "Prints 'Hello' multiple times") + .addOptionalParam("times", "The number of times to print 'Hello'", 1, types.int) + .setAction(async ({ times }) => { + for (let i = 0; i < times; i++) { + console.log("Hello"); + } + }); +``` + +Calling it with `npx buidler hello --times notanumber` will result in an error. + +### Overriding tasks + +Defining a task with the same name than an existing one will override it. This is useful to change or extend the behavior of built-in and plugin-provided tasks. + +Task overriding works very similarly to overriding methods when extending a class. You can set your own action, which can call the previous one. The only restriction when overriding tasks, is that you can't add or remove parameters. + +Task override order is important since actions can only call the immediately previous definition, using the `runSuper` function. + +Overriding built-in tasks is a great way to customize and extend Buidler. To know which tasks to override, take a look at [src/builtin-tasks](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-core/src/builtin-tasks). + +#### The `runSuper` function + +`runSuper` is a function available to override task's actions. It can be received as the third argument of the task or used directly from the global object. + +This function works like [JavaScript's `super` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super), it calls the task's previously defined action. + +If the task isn't overriding a previous task definition calling `runSuper` will result in an error. To check if calling it won't fail, you can use the `boolean` field `runSuper.isDefined`. + +The `runSuper` function receives a single optional argument: an object with the task arguments. If this argument isn't provided, the same task arguments received by the action calling it will be used. + +### Internal tasks + +Creating tasks with lots of logic makes it hard to extend or customize them. Making multiple small and focused tasks that call each other is better to allow for extension. If you design your tasks in this way, users that want to change only a small aspect of them can override one of your internal tasks. + +For example, the `compile` task is implemented as a pipeline of several tasks. It just calls internal tasks like `compile:get-source-paths`, `compile:get-dependency-graph`, and `compile:build-artifacts`. We recommend prefixing intermediate tasks with their main task and a colon. + +To avoid help messages getting cluttered with lots of intermediate tasks, you can define those using the `internalTask` config DSL function. The `internalTask` function works almost exactly like `task`. The only difference is that tasks defined with it won't be included in help messages. + +To run an internal task, or any task whatsoever, you can use the `run` function. It takes two arguments: the name of the task to be run, and an object with its arguments. + +This is an example of a task running an internal task: + +```js +task("hello-world", "Prints a hello world message") + .setAction(async () => { + await run("print", {message: "Hello, World!"}) + }); + +internalTask("print", "Prints a message") + .addParam("message", "The message to print") + .setAction(async (taskArgs) => { + console.log(taskArgs.message) + }); +``` For any questions or feedback you may have, you can find us in the [Buidler Support Telegram group](http://t.me/BuidlerSupport). diff --git a/docs/guides/deploying.md b/docs/guides/deploying.md new file mode 100644 index 0000000000..090ae35abc --- /dev/null +++ b/docs/guides/deploying.md @@ -0,0 +1,41 @@ +# Deploying your contracts + +When it comes to deploying, there are no plugins that implement +a deployment system for Buidler yet, but there's +[an open issue](https://github.com/nomiclabs/buidler/issues/381) +with some ideas and we'd value your opinion on how to best design it. + +In the meantime, we recommend deploying your smart contracts using +scripts. You can deploy the `Greeter` contract from the sample project +by creating a file `scripts/deploy.js` with this contents + +```js +// This script uses @nomiclabs/buidler-truffle5 +const Greeter = env.artifacts.require("Greeter"); + +async function main() { + const greeter = await Greeter.new("Hello, world!"); + + console.log("Greeter address:", greeter.address); +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); +``` + +You can run it with + +```sh +npx buidler --network your-network scripts/deploy.js +``` + +### Truffle migrations support + +You can use Buidler alongside Truffle if you want to use its migration system. +Your contracts written using Buidler will just work with Truffle. + +All you need to do is installing Truffle, and follow their [migrations guide](https://www.trufflesuite.com/docs/truffle/getting-started/running-migrations). diff --git a/docs/guides/ganache-tests.md b/docs/guides/ganache-tests.md new file mode 100644 index 0000000000..965c343cb4 --- /dev/null +++ b/docs/guides/ganache-tests.md @@ -0,0 +1,43 @@ +# Running tests with Ganache + +We recommend using the built-in [Buidler EVM](../buidler-evm/README.md) network to test your +smart contracts, as it generates [combined JavaScript and Solidity stack traces](../buidler-evm/README.md#solidity-stack-traces), +making debugging easier. + +If you still want to run your tests using Ganache, you can do it in two ways. + +## Manually running Ganache + +You don't need to do anything especial to use Ganache if you don't want to. + +Just start Ganache and run Buidler with + +```cmd +npx buidler --network localhost test +``` + +## Using the `buidler-ganache` plugin + +If you don't want to manually start and stop Ganache every time, you can use +the `buidler-ganache` plugin. + +This plugin creates a especial network called `ganache`, and automatically +starts and stops Ganache before and after running your tests and scripts. + +To use it, you have to install it with `npm` + +```cmd +npm install --save-dev @nomiclabs/buidler-ganache +``` + +and add this line at the beginning of your `buidler.config.js` + +```js +usePlugin("@nomiclabs/buidler-ganache"); +``` + +Finally, you can run your tests with + +```cmd +npx buidler --network ganache test +``` diff --git a/docs/guides/project-setup.md b/docs/guides/project-setup.md new file mode 100644 index 0000000000..a03e9e0888 --- /dev/null +++ b/docs/guides/project-setup.md @@ -0,0 +1,81 @@ +# Setting up a project + +A Buidler project is any directory with a valid `buidler.config.js` file in it. If you run `npx buidler` in a path without one you will be shown two options to facilitate project creation: +``` +$ npx buidler +888 d8b 888 888 +888 Y8P 888 888 +888 888 888 +88888b. 888 888 888 .d88888 888 .d88b. 888d888 +888 "88b 888 888 888 d88" 888 888 d8P Y8b 888P" +888 888 888 888 888 888 888 888 88888888 888 +888 d88P Y88b 888 888 Y88b 888 888 Y8b. 888 +88888P" "Y88888 888 "Y88888 888 "Y8888 888 + +👷 Welcome to Buidler v1.0.0 👷‍‍ + +? What do you want to do? … +❯ Create a sample project + Create an empty buidler.config.js + Quit +``` + +If you select _Create an empty buidler.config.js_, Buidler will create a `buidler.config.js` with the following content: +```js +module.exports = {}; +``` +And this is enough to run Buidler using a default project structure. + +### Sample Buidler project + +If you select _Create a sample project_ a simple project creation wizard will ask you some questions and create a project with the following structure: +``` +contracts/ +scripts/ +tests/ +buidler.config.js +``` + +These are the default paths for a Buidler project. Except for `scripts/`, which is just a normal directory unrelated to your config. + +- `contracts/` is where the source files for your contracts should be. +- `test/` is where your tests should go. + +If you need to change these paths, take a look at the [paths configuration section](../config/README.md#path-configuration). + +### Testing and Ethereum networks + +When it comes to testing your contracts, Buidler comes with some built-in defaults: +- [Mocha](https://mochajs.org/) as the test runner +- The built-in [Buidler EVM](../buidler-evm/README.md) as the development network to test on + +If you need to use an external network, like an Ethereum testnet, mainnet or some other specific node software, you can set it up using the `networks` configuration entries in the exported object in `buidler.config.js`, which is how Buidler projects manage settings. Make use of the `--network` CLI parameter to quickly change the network. + +Take a look at the [networks configuration section](../config/README.md#networks-configuration) to learn more about setting up different networks. + +### Plugins and dependencies + +You may have seen this notice when creating the sample project: + +``` +You need to install these dependencies to run the sample project: + npm install --save-dev web3 @nomiclabs/buidler-web3 @nomiclabs/buidler-truffle5 +``` + +This stems from the fact that **most of Buidler's functionality comes from plugins**, so check out the [plugins section](../plugins/README.md) for the official list and see if there are any other ones that look interesting. + +The sample project uses the `@nomiclabs/buidler-truffle5` plugin, which depends on the `@nomiclabs/buidler-web3` plugin. These integrate the Web3.js and Truffle tools into your project. + +To use a plugin, the first step is always to install it using `npm` or `yarn`, and then adding a call to `usePlugin()` in your config file, like this: + +```js +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports = {}; +``` + +Plugins are **essential** to Buidler projects, so make sure to check out all the available ones and also build your own ones! + +For any help or feedback you may have, you can find us in the [Buidler Support Telegram group](http://t.me/BuidlerSupport). + + diff --git a/docs/guides/scripts.md b/docs/guides/scripts.md index 9bfc2910f4..68221274ea 100644 --- a/docs/guides/scripts.md +++ b/docs/guides/scripts.md @@ -1,14 +1,22 @@ -# Standalone scripts +# Writing scripts with Buidler -In this guide we will go through the steps of creating a standalone script with Buidler. For a general overview of using Buidler refer to the [Getting started guide](/guides/#getting-started). +In this guide we will go through the steps of creating a script with Buidler. For a general overview of using Buidler refer to the [Getting started guide]. -The classic use case is writing a deployment script for your smart contracts, and there are two ways of writing a script that accesses the [Buidler Runtime Environment]. +You can write your custom scripts that can use all of Buidler's functionality. A classic use case is writing a deployment script for your smart contracts. + +There are two ways of writing a script that accesses the [Buidler Runtime Environment]. ## Buidler CLI dependant -The first option injects an instance of the [Buidler Runtime Environment] into the global scope, and then executes the script. These scripts must be run through Buidler: `npx buidler run script.js`. This makes it easy to reuse scripts that were developed for Truffle, which follows this approach. By using the [buidler-truffle5](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle5) the scripts are fully compatible. +You can write scripts that access the [Buidler Runtime Environment]'s properties +as global variables. + +These scripts must be run through Buidler: `npx buidler run script.js`. + +This makes it easy to port scripts that were developed for Truffle, which follows this approach, +by using the [buidler-truffle5](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle5). -## Fully standalone. Buidler as a library. +## Standalone scripts: using Buidler as a library The second option leverages Buidler's architecture to allow for more flexibility. Buidler has been designed as a library, allowing you to get creative and build standalone CLI tools that access your development environment. This means that by simply requiring it: @@ -34,15 +42,18 @@ drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 test Inside `scripts/` you will find `sample-script.js`: ```js -// We require the Buidler Runtime Environment explicitly here. This is optional. const env = require("@nomiclabs/buidler"); async function main() { + // You can run Buidler tasks from a script. + // For example, we make sure everything is compiled by running "compile" await env.run("compile"); - const accounts = await env.ethereum.send("eth_accounts"); + // We require the artifacts once our contracts are compiled + const Greeter = env.artifacts.require("Greeter"); + const greeter = await Greeter.new("Hello, world!"); - console.log("Accounts:", accounts); + console.log("Greeter address:", greeter.address); } main() @@ -58,33 +69,31 @@ And there you can see how the [Buidler Runtime Environment] is accessed at the t ``` $ node scripts/sample-script.js All contracts have already been compiled, skipping compilation. -Accounts: [ '0x494d39079b81c620c0ebea503b9295331bfc34c2', - '0x125dc724edc761400dfc87eed3709799d8c1a7e2', - '0x4040a6e01eb8c196cda46921cad8d946c9d21f0b', - '0x908ec1e984e0eb00771601ea726ad2d859cccb2e', - '0xd0d23d20fd000ac9330d380b32d64a0ae10441bb', - '0xc0374e60de5bec55e7da971bb75333fef8f577fb', - '0x1f670b090d7490a3815b5140936c2e08f597e669', - '0x655d8651b5494b6635f2bc038a8b2eaf7ccf59fb', - '0x88523b122e819424ead8cc6007869186bf21f234', - '0xf6eb3c71526fc84a41479a88af4ff5b15f0ba4f7' ] +Greeter address: 0x494d39079b81c620c0ebea503b9295331bfc34c2 ``` -But the script can also run through Buidler, Truffle-style: +But the script can also run through Buidler: + ``` $ npx buidler run scripts/sample-script.js All contracts have already been compiled, skipping compilation. -Accounts: [ '0x494d39079b81c620c0ebea503b9295331bfc34c2', - '0x125dc724edc761400dfc87eed3709799d8c1a7e2', - '0x4040a6e01eb8c196cda46921cad8d946c9d21f0b', - '0x908ec1e984e0eb00771601ea726ad2d859cccb2e', - '0xd0d23d20fd000ac9330d380b32d64a0ae10441bb', - '0xc0374e60de5bec55e7da971bb75333fef8f577fb', - '0x1f670b090d7490a3815b5140936c2e08f597e669', - '0x655d8651b5494b6635f2bc038a8b2eaf7ccf59fb', - '0x88523b122e819424ead8cc6007869186bf21f234', - '0xf6eb3c71526fc84a41479a88af4ff5b15f0ba4f7' ] +Greeter address: 0x494d39079b81c620c0ebea503b9295331bfc34c2 ``` +### Buidler arguments + +You can still pass arguments to Buidler when using it as a library. This is done +by setting environment variables. These are: + +* `BUIDLER_NETWORK`: Sets the network to connect to. + +* `BUIDLER_SHOW_STACK_TRACES`: Enables JavaScript stack traces of expected errors. + +* `BUIDLER_VERBOSE`: Enables Buidler verbose logging. + +* `BUIDLER_MAX_MEMORY`: Sets the maximum amount of memory that Buidler can use. + + -[Buidler Runtime Environment]: /documentation/#buidler-runtime-environment-bre \ No newline at end of file +[Buidler Runtime Environment]: ../advanced/buidler-runtime-environment.md +[Getting started guide]: ../getting-started/README.md diff --git a/docs/guides/testing.md b/docs/guides/testing.md deleted file mode 100644 index 7d6dedc70c..0000000000 --- a/docs/guides/testing.md +++ /dev/null @@ -1,116 +0,0 @@ -# Testing contracts - -In this guide, we will explore the testing of smart contracts with Buidler. For a general overview of using Buidler refer to the [Getting started guide](/guides/#getting-started). - -The built-in task `test` allows smart contracts to be tested using Mocha as the test runner, and the testing framework of your choice. - -For compatibility purposes with other JavaScript tools, Buidler injects the properties in the [Buidler Runtime Environment] into the global scope when running tests. Let's create a new sample project to see how this plays out. - -Run these to start: -``` -mkdir my-project -cd my-project -npm init --yes -npm install @nomiclabs/buidler -``` - -Now run `npx buidler` inside your project folder and create a sample project. This is what the file structure should look like once you're done: - -``` -$ ls -l -total 296 --rw-r--r-- 1 fzeoli staff 195 Aug 8 15:04 buidler.config.js -drwxr-xr-x 3 fzeoli staff 96 Aug 8 15:04 contracts -drwxr-xr-x 378 fzeoli staff 12096 Aug 7 16:12 node_modules --rw-r--r-- 1 fzeoli staff 139778 Aug 7 16:12 package-lock.json --rw-r--r-- 1 fzeoli staff 294 Aug 7 16:12 package.json -drwxr-xr-x 3 fzeoli staff 96 Aug 8 15:04 scripts -drwxr-xr-x 3 fzeoli staff 96 Aug 8 15:04 test -``` - -If you look at the file `test/sample-test.js`, you'll find this sample test: - -```js -const assert = require("assert"); - -describe("Ethereum provider", function() { - it("Should return the accounts", async function() { - const accounts = await ethereum.send("eth_accounts"); - assert(accounts.length !== 0, "No account was returned"); - }); -}); -``` - -Which is a vanilla [Mocha](https://mochajs.org/) test that you can run by running `npx buidler test` -``` -$ npx buidler test -All contracts have already been compiled, skipping compilation. - - - Ethereum provider - ✓ Should return the accounts (104ms) - - - 1 passing (113ms) -``` - -Now, if you look closely at the test, you can see that in this line: -```js -const accounts = await ethereum.send("eth_accounts"); -``` - -the `ethereum` object is being accessed from the global scope. It's coming from the [Buidler Runtime Environment] injecting its properties into it. - -In a traditional Ethereum project, you most likely have your tests written using Truffle, which also injects its main testing utilities into the global scope. By using the [buidler-truffle5](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle5) plugin, you can get the same utilities in the global scope. Let's install it quickly: -``` -$ npm install -D @nomiclabs/buidler-truffle5 @nomiclabs/buidler-web3 -``` -And add `usePlugin("@nomiclabs/buidler-truffle5")` to the top of `buidler.config.js`, so that it looks like this: - -```js -usePlugin("@nomiclabs/buidler-truffle5"); - -task("accounts", "Prints a list of the available accounts", async () => { - const accounts = await ethereum.send("eth_accounts"); - - console.log("Accounts:", accounts); -}); - -module.exports = {}; -``` - -Checkout the plugin's [README file](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle5) for more information about it. - -Once you've installed the plugin, you will have access to `contract()` and `artifacts.require()` in the global scope, which you can use for a standard Truffle test. Let's add the following test to `test/sample-test.js`: - -```js -const Greeter = artifacts.require("Greeter"); - -contract("Greeter", accounts => { - it("should greet", async function() { - const greeting = "Hello, Ethereum"; - const greeter = await Greeter.new(greeting); - - assert.equal(await greeter.greet(), greeting); - }); -}); -``` - -``` -$ npx buidler test -All contracts have already been compiled, skipping compilation. - - - Ethereum provider - ✓ Should return the accounts - - Greeter - ✓ should greet (227ms) - - - 2 passing (236ms) -``` - -This setup should allow you to use your Truffle tests with Buidler, as long as they don't use the Migrations feature, which is currently under development. - -[Buidler Runtime Environment]: /documentation/#buidler-runtime-environment-bre \ No newline at end of file diff --git a/docs/guides/truffle-migration.md b/docs/guides/truffle-migration.md index 81cca58859..4cb1d3058e 100644 --- a/docs/guides/truffle-migration.md +++ b/docs/guides/truffle-migration.md @@ -1,49 +1,80 @@ ---- -prev: false -next: false ---- - # Migrating from Truffle -In this guide, we will show you how to use the Buidler Truffle integration plugins that allow you to use TruffleContract with Buidler. This means that you can use the `contract()` function you always use in your Truffle tests and elsewhere. +To migrate an existing Truffle project onto Buidler there are +two main things to consider: testing and deployment. -Use the plugin that corresponds to the Truffle version you wrote your tests with: [buidler-truffle4](https://github.com/nomiclabs/buidler-truffle4) or [buidler-truffle5](https://github.com/nomiclabs/buidler-truffle5). To make it a real example, let’s go through the process of running an existing project’s Truffle 5 tests with Buidler. +### Testing -What better project to showcase this than [OpenZeppelin](https://openzeppelin.org), the widely-used smart contract development framework from our friends at [Zeppelin](https://zeppelin.solutions/). +When it comes to unit tests, there are two Buidler plugins +that support the Truffle testing APIs: `buidler-truffle4` and `buidler-truffle5`. +Both plugins support Solidity 4 and 5. Using these you can run your existing tests with Buidler. -Let’s checkout the Github repo and install its dependencies: +Read [this guide](./truffle-testing.md) If you want to learn the details of writing Truffle tests to run in Buidler, but it's not necessary to migrate your existing test suite. -```bash -git clone git@github.com:OpenZeppelin/openzeppelin-solidity.git -cd openzeppelin-solidity/ -git checkout v2.1.2 -b buidler-migration -npm install -``` +#### Migrations and buidler-truffle fixtures -Install Buidler and the Truffle 5 plugin: +If your project uses [Truffle Migrations](https://www.trufflesuite.com/docs/truffle/getting-started/running-migrations) to initialize your testing environment (i.e. your tests call `Contract.deployed()`), then there's some more work to do to be able to run your tests. -```bash -npm install @nomiclabs/buidler @nomiclabs/buidler-truffle5 @nomiclabs/buidler-web3 web3 -``` +The Truffle plugins currently don't fully support Migrations. +Instead, you need to adapt your Migrations to become a buidler-truffle fixture. +This file, located at `test/truffle-fixture.js`, deploys your contracts +and calls the `setAsDeployed()` method on each of the contract abstractions +you want to test. -Then put the following into `buidler.config.js`: +For example, this migration: ```js -usePlugin("@nomiclabs/buidler-truffle5"); +const Greeter = artifacts.require("Greeter"); -module.exports = { - solc: { version: "0.5.2" } +module.exports = function(deployer) { + deployer.deploy(Greeter); }; + ``` -And that’s it. Run `npx buidler test` to run all the tests. They will work. +should become this buidler-truffle fixture: -You may think “What if my tests are written with Truffle 4?” Well, there’s a plugin for that. +```js +const Greeter = artifacts.require("Greeter"); -```bash -npm install @nomiclabs/buidler-truffle4 @nomiclabs/buidler-web3-legacy web3@0.20.7 +module.exports = async () => { + const greeter = await Greeter.new(); + Greeter.setAsDeployed(greeter); +} ``` -Set the appropriate compiler version in `buidler.config.js`, load the plugin with `usePlugin()`, and you’re good to go. +These fixtures will run on Mocha's `before`, which runs before each `contract()` function runs, just like Truffle migrations do. + +If you have multiple migrations, you don't need to create multiple +buidler-truffle fixture files. You can deploy all your contracts from the same one. + +### Deployment + +When it comes to deploying, there are no plugins that implement a deployment system for Buidler yet, but there's [an open issue](https://github.com/nomiclabs/buidler/issues/381) with some ideas and we'd value your opinion on how to best design it. + +### Truffle 4 and Web3.js' synchronous calls + +Truffle 4 uses Web3.js `0.20.x`, which supports doing synchronous calls. +These aren't supported by the `buidler-web3-legacy` plugin, which is the plugin that integrates Web3.js `0.20.x`. + +Instead, you should use the promisified version of Web3.js offered by the plugin: `pweb3`. It's available +as a global variable in your tests and tasks, and in the [Buidler Runtime Environment](../advanced/buidler-runtime-environment.md). +It has the same API as Web3.js, but asynchronous operations return promises. + +For example, this code: + +```js +console.log(web3.eth.accounts) +``` + +should become: + +```js +console.log(await pweb3.eth.getAccounts()) +``` + + + + -For any questions or feedback you may have, you can find us in the [Buidler Support Telegram group](http://t.me/BuidlerSupport). +For any help or feedback you may have, you can find us in the [Buidler Support Telegram group](http://t.me/BuidlerSupport). diff --git a/docs/guides/truffle-testing.md b/docs/guides/truffle-testing.md new file mode 100644 index 0000000000..0211b3f754 --- /dev/null +++ b/docs/guides/truffle-testing.md @@ -0,0 +1,74 @@ +# Testing with Web3.js & Truffle + +Buidler allows you to use Truffle to test your smart contracts. This mainly means compatibility with the [`@truffle/contract`](https://www.npmjs.com/package/@truffle/contract) package to interact with your smart contracts. + +Truffle 4 and Truffle 5 are supported using the `@nomiclabs/buidler-truffle4` and `@nomiclabs/buidler-truffle5` plugins respectively. Both work with either Solidity 4 or 5. + +Let's see how to do this using the Buidler sample project. +Run these to start: +``` +mkdir my-project +cd my-project +npm init --yes +npm install --save-dev @nomiclabs/buidler +``` + +Now run `npx buidler` inside your project folder and create a sample project. This is what the file structure should look like once you're done: + +``` +$ ls -l +total 296 +drwxr-xr-x 378 fzeoli staff 12096 Aug 7 16:12 node_modules/ +drwxr-xr-x 3 fzeoli staff 96 Aug 8 15:04 scripts/ +drwxr-xr-x 3 fzeoli staff 96 Aug 8 15:04 test/ +drwxr-xr-x 3 fzeoli staff 96 Aug 8 15:04 contracts/ +-rw-r--r-- 1 fzeoli staff 195 Aug 8 15:04 buidler.config.js +-rw-r--r-- 1 fzeoli staff 139778 Aug 7 16:12 package-lock.json +-rw-r--r-- 1 fzeoli staff 294 Aug 7 16:12 package.json +``` +Look at the `buidler.config.js` file and you'll see that the Truffle 5 plugin is enabled: + +<<< @/../packages/buidler-core/sample-project/buidler.config.js{1} + +Look at the file `test/sample-test.js` and you'll find these sample tests: + +<<< @/../packages/buidler-core/sample-project/test/sample-test.js{1} + +As you can see in the highlighted line, the `artifacts` object is present in the global scope and you can use it to access the Truffle contract abstractions. + +These examples show two approaches towards testing: +- Using `contract()`, which is the traditional way to test with Truffle +- Using `describe()`, which is the traditional way to test using Mocha + +Truffle runs its tests with Mocha, but a few tools that integrate Mocha don't expect `contract()` and don't always work well. We recommend using the `describe()` approach. + +You can run these tests by running `npx buidler test`: +``` +$ npx buidler test +All contracts have already been compiled, skipping compilation. + + +Contract: Greeter + ✓ Should return the new greeting once it's changed (265ms) + + Greeter contract + Deployment + ✓ Should deploy with the right greeting (114ms) + + + 2 passing (398ms) +``` + +If you want to use Truffle Migrations to initialize your tests and call `deployed()` on the contract abstractions, both `@nomiclabs/buidler-truffle4` and `@nomiclabs/buidler-truffle5` offer a fixtures feature to make this possible. Take a look at the [Truffle migration guide](./truffle-migration.md) to learn more. + +## Using Web3.js + +To use Web3.js in your tests, an instance of it is available in the global scope. You can see this in the `describe()` test in `sample-test.js`: + +<<< @/../packages/buidler-core/sample-project/test/sample-test.js{20} + +Checkout the plugin's [README file](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle5) for more information about it. + + +[Buidler Runtime Environment]: /documentation/#buidler-runtime-environment-bre + diff --git a/docs/guides/typescript.md b/docs/guides/typescript.md index 736553d5ab..c907c04e3f 100644 --- a/docs/guides/typescript.md +++ b/docs/guides/typescript.md @@ -1,17 +1,23 @@ - # TypeScript Support -In this guide, we will go through the steps to get a Buidler project working with TypeScript. This means that you can write your Buidler config, tasks, scripts and tests in [TypeScript](https://www.typescriptlang.org/). For a general overview of using Buidler refer to the [Getting started guide](/guides/#getting-started). +In this guide, we will go through the steps to get a Buidler project working with TypeScript. This means that you can write your Buidler config, tasks, scripts and tests in [TypeScript](https://www.typescriptlang.org/). For a general overview of using Buidler refer to the [Getting started guide](../getting-started). +## Installing dependencies -To use Buidler with TypeScript you need to be able to import Buidler from your project to access the [Buidler Runtime Environment], and this wouldn't be possible with a global installation. Because of this Buidler only supports TypeScript on local installations. +Buidler detects if `typescript` and `ts-node` are installed in its npm project, +and automatically enables TypeScript support. -## Installing dependencies +To install them, open your terminal, go to your Buidler project, and run: -We will need to install the TypeScript packages to do this. +```sh +npm install --save-dev ts-node typescript +``` + +You also need these typings: -In your terminal, run -```npm i -D ts-node typescript``` +```sh +npm install --save-dev @types/node @types/mocha +``` ## Configuration @@ -30,16 +36,59 @@ drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 test ``` Now we are going to rename the config file from `buidler.config.js` to `buidler.config.ts`, run: - ```mv buidler.config.js buidler.config.ts``` + +```sh +mv buidler.config.js buidler.config.ts +``` + +We also need to adapt it to explicitly import the Buidler config DSL, and use the [Buidler Runtime Environment] explicitly. + +For example, the sample project's config turns from this +```js{1,6,13} +usePlugin("@nomiclabs/buidler-truffle5"); + +// This is a sample Buidler task. To learn how to create your own go to +// https://buidler.dev/guides/create-task.html +task("accounts", "Prints the list of accounts", async () => { + const accounts = await web3.eth.getAccounts(); + + for (const account of accounts) { + console.log(account); + } +}); + +module.exports = {}; +``` + +into this + +```typescript{1,7,8,15} +import { task, usePlugin } from "@nomiclabs/buidler/config"; + +usePlugin("@nomiclabs/buidler-truffle5"); + +// This is a sample Buidler task. To learn how to create your own go to +// https://buidler.dev/guides/create-task.html +task("accounts", "Prints the list of accounts", async (taskArgs, env) => { + const accounts = await env.web3.eth.getAccounts(); + + for (const account of accounts) { + console.log(account); + } +}); + +export default {}; +``` + Next, create a file `tsconfig.json` in your project directory and put the following in it: ```json { "compilerOptions": { - "target": "es5", + "target": "es5", "module": "commonjs", - "strict": true, + "strict": true, "esModuleInterop": true, "outDir": "dist" }, @@ -50,78 +99,74 @@ Next, create a file `tsconfig.json` in your project directory and put the follow } ``` -And that's really all it takes. Now the configuration file will be run as TypeScript. Let's add some code to `buidler.config.ts` to test it out: +And that's really all it takes. Now the configuration file will be run as TypeScript. -```ts -import { task } from '@nomiclabs/buidler/config' +## Type-safe configuration -class PointlessLogger { - log(content: string) { - console.log(content); - } -} +One of the advantages of using TypeScript, is that you can have an type-safe configuration, and avoid typos and other common errors. -task("accounts", "Prints a list of the available accounts", async (taskParams, env, runSuper) => { - const accounts = await env.ethereum.send("eth_accounts"); - const logger = new PointlessLogger(); +To do that, you have to write your config in TypeScript in this way: - logger.log("Accounts:\n" + accounts.join("\n")); -}); +```ts +import { BuidlerConfig } from "@nomiclabs/buidler/config"; -module.exports = {}; -``` -And run it with `npx buidler accounts`. +const config: BuidlerConfig = { + // Your type-safe config goes here +}; +export default config; +``` ## Plugin type extensions -Some Buidler plugins, like [buidler-truffle5](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle5) and [buidler-web3](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3), provide type extensions to the [Buidler Runtime Environment] for the variables and types they inject. + +Some Buidler plugins, like [buidler-truffle5](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle5) and [buidler-web3](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3), add new properties to the [Buidler Runtime Environment]. To keep everything type-safe and make using them with TypeScript possible, they provide type extension files. For these to be taken into account, you'll need to add the type extension files to the `files` field in your `tsconfig.json`, like this: -```js + +```json "files": [ - "./buidler.config.ts", - "./node_modules/@nomiclabs/buidler-web3/src/type-extensions.d.ts", - "./node_modules/@nomiclabs/buidler-truffle5/src/type-extensions.d.ts" - ] + "./buidler.config.ts", + "./node_modules/@nomiclabs/buidler-web3/src/type-extensions.d.ts", + "./node_modules/@nomiclabs/buidler-truffle5/src/type-extensions.d.ts" +] ``` Plugins that include type extensions should have documentation detailing their existance and the path to the type extension file. ## Writing tests and scripts -To write your smart contract tests and scripts you'll most likely need access to an Ethereum library to interact with your smart contracts. This will probably be one of [buidler-truffle5](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle5), [buidler-web3](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3) or [buidler-ethers](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3), all of which inject instances into the [Buidler Runtime Environment]. When using JavaScript, all the properties in the BRE are injected into the global scope, and are also available by getting the BRE explicitly. When using TypeScript nothing will be available in the global scope and you will need to import everything explicitly. +To write your smart contract tests and scripts you'll most likely need access to an Ethereum library to interact with your smart contracts. This will probably be one of [buidler-truffle5](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle5), [buidler-web3](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3) or [buidler-ethers](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3), all of which inject instances into the [Buidler Runtime Environment]. + +When using JavaScript, all the properties in the BRE are injected into the global scope, and are also available by getting the BRE explicitly. When using TypeScript nothing will be available in the global scope and you will need to import everything explicitly. An example for tests: -```ts -import env from '@nomiclabs/buidler' -const web3 = env.web3; -// Could also be -// import { web3 } form '@nomiclabs/buidler' +```typescript +import { web3 } from "@nomiclabs/buidler"; + +describe("Token", function() { + let accounts: string[]; -describe('Token', function() { - - let accounts; - beforeEach(async function() { accounts = await web3.eth.getAccounts(); }); - it('should test', async function() { - ... + it("should do something right", async function() { + // Do something with the accounts }); -} +}); + ``` An example for scripts: -```ts -import env from "@nomiclabs/buidler"; +```typescript +import { run, web3 } from "@nomiclabs/buidler"; async function main() { - await env.run("compile"); + await run("compile"); - const accounts = await env.ethereum.send("eth_accounts"); + const accounts = await web3.eth.getAccounts(); console.log("Accounts:", accounts); } @@ -133,4 +178,23 @@ main() process.exit(1); }); ``` -[Buidler Runtime Environment]: /documentation/#buidler-runtime-environment-bre \ No newline at end of file + +## Performance optimizations + +Under the hood, Buidler uses [ts-node](https://www.npmjs.com/package/ts-node) to support TypeScript. By default, it +will recompile and type-check everything on every run. Depending on your project's size, this can get slow. + +You can make Buidler run faster by preventing `ts-node` from type-checking your project. This is done by setting the +`TS_NODE_TRANSPILE_ONLY` en variable to `1`. For example, you can run your TypeScript-based tests faster like this +`TS_NODE_TRANSPILE_ONLY=1 npx buidler test`. + +## `ts-node` support + +When running Buidler scripts without the CLI, you need to use `ts-node`'s [`--files` flag](https://www.npmjs.com/package/ts-node#help-my-types-are-missing). +This can also be enabled with `TS_NODE_FILES=true`. + +## Limitations + +To use Buidler with TypeScript you need to be able to import Buidler from your project to access the [Buidler Runtime Environment], and this wouldn't be possible with a global installation. Because of this Buidler only supports TypeScript on local installations. + +[Buidler runtime environment]: ../advanced/buidler-runtime-environment.md diff --git a/docs/guides/vscode-tests.md b/docs/guides/vscode-tests.md new file mode 100644 index 0000000000..dba257c0be --- /dev/null +++ b/docs/guides/vscode-tests.md @@ -0,0 +1,26 @@ +# Running tests on Visual Studio Code + +You can run your tests from [Visual Studio Code](https://code.visualstudio.com) +by using one of its Mocha integration extensions. We recommend using [Mocha Test Explorer](https://marketplace.visualstudio.com/items?itemName=hbenl.vscode-mocha-test-adapter). + +To use [Mocha Test Explorer](https://marketplace.visualstudio.com/items?itemName=hbenl.vscode-mocha-test-adapter), just +install it and create a file named `.mocharc.json` in your project's root directory with the following contents: + +```json +{ + "require": ["@nomiclabs/buidler/register"], + "timeout": 20000, + "recursive": "test" +} +``` + +Finally, make sure you have the latest version of Mocha by running: + +```sh +node install --save-dev mocha +``` + +Now, you can set a shortcut for this VS Code command `test-explorer.run-test-at-cursor`, and you +will be to run the test you are currently editing with it. + +For any help or feedback you may have, you can find us in the [Buidler Support Telegram group](http://t.me/BuidlerSupport). diff --git a/docs/guides/waffle-testing.md b/docs/guides/waffle-testing.md new file mode 100644 index 0000000000..14e963aa14 --- /dev/null +++ b/docs/guides/waffle-testing.md @@ -0,0 +1,145 @@ +# Testing with ethers.js & Waffle + +[Waffle](https://getwaffle.io/) is a simple smart contract testing library built on `ethers.js` that supports TypeScript. It's our recommended choice for testing. + +This guide will cover setting up a Buidler project to use Waffle and TypeScript, and to do so we will pick up from the [TypeScript Support](./typescript.md) guide. Follow that guide to setup your TypeScript project and come back. + +Done? Great. Let's now install `ethers.js` and the `buidler-ethers` plugin, which will allow Waffle to use [Buidler EVM] and get stack traces functionality. + +``` +$ npm install --save-dev @nomiclabs/buidler-ethers ethers +``` + +Add the `buidler-ethers` type extensions to your `tsconfig.json` that you should've created following the TypeScript guide: + +```json{12} +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "outDir": "dist" + }, + "include": ["./scripts", "./test"], + "files": [ + "./buidler.config.ts", + "./node_modules/@nomiclabs/buidler-ethers/src/type-extensions.d.ts" + ] +} +``` + +And let's enable the `buidler-ethers` plugin in `buidler.config.ts`: + +```typescript +import { usePlugin } from "@nomiclabs/buidler/config"; + +usePlugin("@nomiclabs/buidler-ethers"); + +export default {}; +``` + +## Migrating an existing Waffle project + +If you're starting a project from scratch and looking to use Waffle, you can skip this section. If you're setting up an existing Waffle project to use Buidler you'll need to migrate the [configuration options](https://ethereum-waffle.readthedocs.io/en/latest/configuration.html) Waffle offers. The following table maps Waffle configurations to their Buidler equivalents: +|Waffle|Buidler| +|---|---| +|`sourcesPath`|`paths.sources`| +|`targetPath`|`paths.artifacts`| +|`solcVersion`|`solc.version` (version number only)| +|`compilerOptions.evmVersion`|`solc.evmVersion`| +|`compilerOptions.optimizer`|`solc.optimizer`| + +As an example, this Waffle configuration file: + +```json +{ + "sourcesPath": "./some_custom/contracts_path", + "targetPath": "../some_custom/build", + "solcVersion": "v0.4.24+commit.e67f0147", + "compilerOptions": { + "evmVersion": "constantinople", + "optimizer": { + "enabled": true, + "runs": 200 + } + } +} +``` + +Would translate into this Buidler config: + +```typescript +export default { + paths: { + sources: "./some_custom/contracts_path", + artifacts: "../some_custom/build" + }, + solc: { + version: "0.4.24", // Note that this only has the version number + evmVersion: "constantinople", + optimizer: { + enabled: true, + runs: 200 + } + } +}; +``` + +If you're migrating an existing Waffle project to Buidler, then the minimum configuration you'll need is changing Buidler's compilation output path, since Waffle uses a different one by default: + +```typescript +import { usePlugin } from "@nomiclabs/buidler/config"; + +usePlugin("@nomiclabs/buidler-ethers"); + +export default { + paths: { + artifacts: "./build" + } +}; +``` + +## Connecting Waffle and Buidler EVM + +Next we'll tweak the configuration to synchronize Waffle's default accounts with [Buidler EVM]. Soon this will be handled by a Waffle integration plugin. + +```typescript +import { usePlugin } from "@nomiclabs/buidler/config"; +import waffleDefaultAccounts from "ethereum-waffle/dist/config/defaultAccounts"; + +usePlugin("@nomiclabs/buidler-ethers"); + +export default { + paths: { + artifacts: "./build" + }, + networks: { + buidlerevm: { + accounts: waffleDefaultAccounts.map(acc => ({ + balance: acc.balance, + privateKey: acc.secretKey + })) + } + } +}; +``` + +## Adapting the tests + +Now, when testing using a standalone Waffle setup, this is how the provider is initialized for testing: + +```js +const provider = createMockProvider(); +``` + +To use Waffle with Buidler you should do this instead: + +```js +import { ethers } from "@nomiclabs/buidler"; +const provider = ethers.provider; +``` + +And you're set. Run your tests with `npx buidler test` and you should get stack traces when a transaction fails. + +[buidler evm]: ../buidler-evm/README.md diff --git a/docs/package-lock.json b/docs/package-lock.json index f022eea0a5..d90deb8833 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1070,9 +1070,9 @@ } }, "@vue/component-compiler-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-2.6.0.tgz", - "integrity": "sha512-IHjxt7LsOFYc0DkTncB7OXJL7UzwOLPPQCfEUNyxL2qt+tF12THV+EO33O1G2Uk4feMSWua3iD39Itszx0f0bw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.0.0.tgz", + "integrity": "sha512-am+04/0UX7ektcmvhYmrf84BDVAD8afFOf4asZjN84q8xzxFclbk5x0MtxuKGfp+zjN5WWPJn3fjFAWtDdIGSw==", "dev": true, "requires": { "consolidate": "^0.15.1", @@ -1093,9 +1093,9 @@ "dev": true }, "postcss": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", - "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", + "version": "7.0.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.18.tgz", + "integrity": "sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -1314,18 +1314,6 @@ "webpack-log": "^1.1.2" }, "dependencies": { - "cosmiconfig": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.0.tgz", - "integrity": "sha512-nxt+Nfc3JAqf4WIWd0jXLjTJZmsPLrA9DDc4nRw2KFJQJK7DNooqSXrNI7tzLG50CF8axczly5UV929tBmh/7g==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.0", - "parse-json": "^4.0.0" - } - }, "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", @@ -1390,13 +1378,30 @@ "dev": true }, "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "dev": true, "requires": { - "mime-types": "~2.1.18", - "negotiator": "0.6.1" + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "dependencies": { + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dev": true, + "requires": { + "mime-db": "1.40.0" + } + } } }, "acorn": { @@ -1469,9 +1474,9 @@ "dev": true }, "algoliasearch": { - "version": "3.32.1", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-3.32.1.tgz", - "integrity": "sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA==", + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-3.35.0.tgz", + "integrity": "sha512-Om4aLzkGbUi+Rc3sa8s48CRj2Qe7u5TXS7lK7Z681x2EiAa5Qx5uB/kbp8A6qY6dFDX7vstYRIYZ7t9XgdJ1dw==", "dev": true, "requires": { "agentkeepalive": "^2.2.0", @@ -1501,9 +1506,9 @@ } }, "isarray": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", - "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, "ms": { @@ -1520,12 +1525,6 @@ "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", "dev": true }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, "ansi-align": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", @@ -2045,9 +2044,9 @@ "dev": true }, "autocomplete.js": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/autocomplete.js/-/autocomplete.js-0.33.0.tgz", - "integrity": "sha512-J0F7BkPhYwXvfs8Skp6v2e2IHYv0SL8INyHYwb7nUpvKHr96g6zS8RNEFGEfEuO3ND+XUsesEMM59LlwQoLfoA==", + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/autocomplete.js/-/autocomplete.js-0.36.0.tgz", + "integrity": "sha512-jEwUXnVMeCHHutUt10i/8ZiRaCb0Wo+ZyKxeGsYwBDtw6EJHqEeDrq4UwZRD8YBSvp3g6klP678il2eeiVXN2Q==", "dev": true, "requires": { "immediate": "^3.2.3" @@ -2634,15 +2633,15 @@ } }, "caniuse-db": { - "version": "1.0.30000957", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000957.tgz", - "integrity": "sha512-13rVZZO/75kPKJhJsi86lPUme7zlvfGDnnvSYx3TA+kYQxLtGywth5+81pyVZDjUfYyzatwA/yjv6DNsh66gmQ==", + "version": "1.0.30000997", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000997.tgz", + "integrity": "sha512-rK1Jo9VT5F/cJ333iLURdNXecYvVn3erJheoPAETrccJVw4w/557HfkNPADB5agHKjGuhJETf1l6lssvgbqA0Q==", "dev": true }, "caniuse-lite": { - "version": "1.0.30000957", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000957.tgz", - "integrity": "sha512-8wxNrjAzyiHcLXN/iunskqQnJquQQ6VX8JHfW5kLgAPRSiSuKZiNfmIkP5j7jgyXqAQBSoXyJxfnbCFS0ThSiQ==", + "version": "1.0.30000997", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000997.tgz", + "integrity": "sha512-BQLFPIdj2ntgBNWp9Q64LGUIEmvhKkzzHhUHR3CD5A9Lb7ZKF20/+sgadhFap69lk5XmK1fTUleDclaRFvgVUA==", "dev": true }, "capture-stack-trace": { @@ -3226,9 +3225,9 @@ } }, "core-js": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", - "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", "dev": true }, "core-util-is": { @@ -3238,15 +3237,15 @@ "dev": true }, "cosmiconfig": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", - "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, "requires": { + "import-fresh": "^2.0.0", "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^4.0.0", - "require-from-string": "^2.0.1" + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" } }, "create-ecdh": { @@ -3333,6 +3332,18 @@ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", "dev": true }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, "css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", @@ -3424,10 +3435,13 @@ } }, "css-parse": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", - "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", + "dev": true, + "requires": { + "css": "^2.0.0" + } }, "css-select": { "version": "1.2.0", @@ -3673,12 +3687,13 @@ "dev": true }, "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "dev": true, "requires": { - "es5-ext": "^0.10.9" + "es5-ext": "^0.10.50", + "type": "^1.0.1" } }, "dashdash": { @@ -3925,13 +3940,13 @@ } }, "docsearch.js": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/docsearch.js/-/docsearch.js-2.6.2.tgz", - "integrity": "sha512-qyQ+raZlHSkfdpFg8wJNhjiz9WsjdQkRGe2LiiKS6vIIsouNNole2Kg/9UvGoUIK9PLLl31uL3I4YDwnrXt5yQ==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/docsearch.js/-/docsearch.js-2.6.3.tgz", + "integrity": "sha512-GN+MBozuyz664ycpZY0ecdQE0ND/LSgJKhTLA0/v3arIS3S1Rpf2OJz6A35ReMsm91V5apcmzr5/kM84cvUg+A==", "dev": true, "requires": { "algoliasearch": "^3.24.5", - "autocomplete.js": "0.33.0", + "autocomplete.js": "0.36.0", "hogan.js": "^3.0.2", "request": "^2.87.0", "stack-utils": "^1.0.1", @@ -3949,13 +3964,27 @@ } }, "dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", + "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", "dev": true, "requires": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", + "dev": true + }, + "entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", + "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==", + "dev": true + } } }, "dom-walk": { @@ -4054,9 +4083,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.124", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.124.tgz", - "integrity": "sha512-glecGr/kFdfeXUHOHAWvGcXrxNU+1wSO/t5B23tT1dtlvYB26GY8aHzZSWD7HqhqC800Lr+w/hQul6C5AF542w==", + "version": "1.3.272", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.272.tgz", + "integrity": "sha512-TjsDKYOZGgaD8tUJtRiiBNlIrv2Ol6SxNMy4yeTX0goRmoBhV941m4EN8QjA3vfshs16F5KLDyUv2m7GdTqIgg==", "dev": true }, "elliptic": { @@ -4080,6 +4109,12 @@ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -4149,17 +4184,21 @@ "dev": true }, "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.2.tgz", + "integrity": "sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==", "dev": true, "requires": { "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", "has": "^1.0.3", + "has-symbols": "^1.0.0", "is-callable": "^1.1.4", "is-regex": "^1.0.4", - "object-keys": "^1.0.12" + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.0.0", + "string.prototype.trimright": "^2.0.0" } }, "es-to-primitive": { @@ -4174,9 +4213,9 @@ } }, "es5-ext": { - "version": "0.10.49", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.49.tgz", - "integrity": "sha512-3NMEhi57E31qdzmYp2jwRArIUsj1HI/RxbQ4bgnSB+AIKIxsAmTiK83bYMifIcpWvEc3P1X30DhUKOqEtF/kvg==", + "version": "0.10.51", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.51.tgz", + "integrity": "sha512-oRpWzM2WcLHVKpnrcyB7OW8j/s67Ba04JCm0WnNv3RiABSvs7mrQlutB8DBv793gKcp0XENR8Il8WxGTlZ73gQ==", "dev": true, "requires": { "es6-iterator": "~2.0.3", @@ -4196,19 +4235,19 @@ } }, "es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", "dev": true }, "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.2.tgz", + "integrity": "sha512-/ZypxQsArlv+KHpGvng52/Iz8by3EQPxhmbuz8yFG89N/caTFBSbcXONDw0aMjy827gQg26XAjP4uXFvnfINmQ==", "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "d": "^1.0.1", + "es5-ext": "^0.10.51" } }, "escape-html": { @@ -4384,9 +4423,9 @@ "dev": true }, "fast-glob": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.6.tgz", - "integrity": "sha512-0BvMaZc1k9F+MeWWMe8pL6YltFzZYcJsYU7D4JyDA6PAczaXvxqQQ/z+mDF7/4Mw01DeUc+i3CTKajnkANkV4w==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", "dev": true, "requires": { "@mrmlnc/readdir-enhanced": "^2.2.1", @@ -5607,13 +5646,13 @@ "dev": true }, "global": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", - "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", "dev": true, "requires": { "min-document": "^2.19.0", - "process": "~0.5.1" + "process": "^0.11.10" } }, "global-dirs": { @@ -5626,9 +5665,9 @@ } }, "globals": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, "globby": { @@ -5905,9 +5944,9 @@ } }, "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", + "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", "dev": true }, "html-comment-regex": { @@ -5981,9 +6020,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz", - "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -5994,26 +6033,34 @@ } }, "http-assert": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.4.0.tgz", - "integrity": "sha512-tPVv62a6l3BbQoM/N5qo969l0OFxqpnQzNUPeYfTP6Spo4zkgWeDBD1D5thI7sDLg7jCCihXTLB0X8UtdyAy8A==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.4.1.tgz", + "integrity": "sha512-rdw7q6GTlibqVVbXr0CKelfV5iY8G2HqEUkhSk297BMbSpSL8crXC+9rjKoMcZZEsksX30le6f/4ul4E28gegw==", "dev": true, "requires": { "deep-equal": "~1.0.1", - "http-errors": "~1.7.1" + "http-errors": "~1.7.2" } }, "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", "dev": true, "requires": { "depd": "~1.1.2", - "inherits": "2.0.3", + "inherits": "2.0.4", "setprototypeof": "1.1.1", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + } } }, "http-signature": { @@ -6422,9 +6469,9 @@ "dev": true }, "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", "dev": true }, "is-stream": { @@ -6671,9 +6718,9 @@ } }, "koa": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/koa/-/koa-2.7.0.tgz", - "integrity": "sha512-7ojD05s2Q+hFudF8tDLZ1CpCdVZw8JQELWSkcfG9bdtoTDzMmkRF6BQBU7JzIzCCOY3xd3tftiy/loHBUYaY2Q==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.8.2.tgz", + "integrity": "sha512-q1uZOgpl3wjr5FS/tjbABJ8lA5+NeKa9eq7QyBP5xxgOBwJN4iBrMEgO3LroE51lrIw3BsO0WZZ0Yi6giSiMDw==", "dev": true, "requires": { "accepts": "^1.3.5", @@ -6685,6 +6732,7 @@ "delegates": "^1.0.0", "depd": "^1.1.2", "destroy": "^1.0.4", + "encodeurl": "^1.0.2", "error-inject": "^1.0.0", "escape-html": "^1.0.3", "fresh": "~0.5.2", @@ -6880,9 +6928,9 @@ } }, "linkify-it": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz", - "integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", "dev": true, "requires": { "uc.micro": "^1.0.1" @@ -6987,22 +7035,22 @@ "dev": true }, "lodash.template": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", - "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "dev": true, "requires": { - "lodash._reinterpolate": "~3.0.0", + "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" } }, "lodash.templatesettings": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", - "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "dev": true, "requires": { - "lodash._reinterpolate": "~3.0.0" + "lodash._reinterpolate": "^3.0.0" } }, "lodash.throttle": { @@ -7132,9 +7180,9 @@ } }, "markdown-it-anchor": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.0.2.tgz", - "integrity": "sha512-AFM/woBI8QDJMS/9+MmsBMT5/AR+ImfOsunQZTZhzcTmna3rIzAzbOh5E0l6mlFM/i9666BpUtkqQ9bS7WApCg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.4.tgz", + "integrity": "sha512-n8zCGjxA3T+Mx1pG8HEgbJbkB8JFUuRkeTZQuIM8iPY6oQ8sWOPRZJDFC9a/pNg2QkHEjjGkhBEl/RSyzaDZ3A==", "dev": true }, "markdown-it-container": { @@ -7242,9 +7290,9 @@ } }, "merge2": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", - "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", "dev": true }, "micromatch": { @@ -7279,9 +7327,9 @@ } }, "mime": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.2.tgz", - "integrity": "sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", "dev": true }, "mime-db": { @@ -7433,9 +7481,9 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "mz": { @@ -7532,9 +7580,9 @@ } }, "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", "dev": true }, "neo-async": { @@ -7733,6 +7781,12 @@ } } }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -8006,9 +8060,9 @@ "dev": true }, "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, "pascalcase": { @@ -8109,9 +8163,9 @@ "dev": true }, "portfinder": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", - "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "version": "1.0.24", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.24.tgz", + "integrity": "sha512-ekRl7zD2qxYndYflwiryJwMioBI7LI7rVXg3EnLK3sjkouT5eOuhS3gS255XxBksa30VG8UPZYZCdgfGOfkSUg==", "dev": true, "requires": { "async": "^1.5.2", @@ -8799,12 +8853,12 @@ } }, "postcss-load-config": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz", - "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", + "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", "dev": true, "requires": { - "cosmiconfig": "^4.0.0", + "cosmiconfig": "^5.0.0", "import-cwd": "^2.0.0" } }, @@ -10104,9 +10158,9 @@ "dev": true }, "prismjs": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.16.0.tgz", - "integrity": "sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.17.1.tgz", + "integrity": "sha512-PrEDJAFdUGbOP6xK/UsfkC5ghJsPJviKgnQOoxaDbBjwc8op68Quupwt1DeAFoG8GImPhiKXAvvsH7wDSLsu1Q==", "dev": true, "requires": { "clipboard": "^2.0.0" @@ -10119,9 +10173,9 @@ "dev": true }, "process": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", "dev": true }, "process-nextick-args": { @@ -10286,9 +10340,9 @@ } }, "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true }, "rc": { @@ -10697,20 +10751,12 @@ } }, "reduce-function-call": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", - "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz", + "integrity": "sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ==", "dev": true, "requires": { - "balanced-match": "^0.4.2" - }, - "dependencies": { - "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", - "dev": true - } + "balanced-match": "^1.0.0" } }, "regenerate": { @@ -10720,9 +10766,9 @@ "dev": true }, "regenerate-unicode-properties": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz", - "integrity": "sha512-SbA/iNrBUf6Pv2zU8Ekv1Qbhv92yxL4hiDa2siuxs4KKn4oOoMDHXjAf7+Nz9qinUQ46B1LcWEi/PhJfPWpZWQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", "dev": true, "requires": { "regenerate": "^1.4.0" @@ -10763,13 +10809,13 @@ } }, "regexpu-core": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", - "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", "dev": true, "requires": { "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.0.2", + "regenerate-unicode-properties": "^8.1.0", "regjsgen": "^0.5.0", "regjsparser": "^0.6.0", "unicode-match-property-ecmascript": "^1.0.4", @@ -10933,12 +10979,6 @@ "tough-cookie": "^2.3.3" } }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, "resolve": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", @@ -11433,9 +11473,9 @@ } }, "spdx-license-ids": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", - "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, "split-string": { @@ -11605,6 +11645,26 @@ } } }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -11675,47 +11735,47 @@ "dev": true }, "stylus": { - "version": "0.54.5", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", - "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", + "version": "0.54.7", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", + "integrity": "sha512-Yw3WMTzVwevT6ZTrLCYNHAFmanMxdylelL3hkWNgPMeTCpMwpV3nXjpOHuBXtFv7aiO2xRuQS6OoAdgkNcSNug==", "dev": true, "requires": { - "css-parse": "1.7.x", - "debug": "*", - "glob": "7.0.x", - "mkdirp": "0.5.x", - "sax": "0.5.x", - "source-map": "0.1.x" + "css-parse": "~2.0.0", + "debug": "~3.1.0", + "glob": "^7.1.3", + "mkdirp": "~0.5.x", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.0.0", + "source-map": "^0.7.3" }, "dependencies": { - "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "ms": "2.0.0" } }, - "sax": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", - "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true } } }, @@ -12069,9 +12129,9 @@ } }, "time-fix-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/time-fix-plugin/-/time-fix-plugin-2.0.5.tgz", - "integrity": "sha512-veHRiEsQ50KSrfdhkZiFvZIjRoyfyfxpgskD+P7uVQAcNe6rIMLZ8vhjFRE2XrPqQdy+4CF+jXsWAlgVy9Bfcg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/time-fix-plugin/-/time-fix-plugin-2.0.6.tgz", + "integrity": "sha512-2cjjg3672ppNm/uKhHAoCFp1ItEAiH+xJOjO9WGIF8hXuxPAJ2adfYgFiyooVbsOb948c+WrRh+edxFUMxYHoQ==", "dev": true }, "timed-out": { @@ -12250,6 +12310,12 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -12260,13 +12326,30 @@ } }, "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "~2.1.18" + "mime-types": "~2.1.24" + }, + "dependencies": { + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dev": true, + "requires": { + "mime-db": "1.40.0" + } + } } }, "typedarray": { @@ -12650,9 +12733,9 @@ "dev": true }, "v8-compile-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz", - "integrity": "sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", "dev": true }, "validate-npm-package-license": { @@ -12672,9 +12755,9 @@ "dev": true }, "vendors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz", - "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz", + "integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==", "dev": true }, "verror": { @@ -12704,18 +12787,18 @@ "dev": true }, "vue-hot-reload-api": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.3.tgz", - "integrity": "sha512-KmvZVtmM26BQOMK1rwUZsrqxEGeKiYSZGA7SNWE6uExx8UX/cj9hq2MRV/wWC3Cq6AoeDGk57rL9YMFRel/q+g==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", + "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", "dev": true }, "vue-loader": { - "version": "15.7.0", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.7.0.tgz", - "integrity": "sha512-x+NZ4RIthQOxcFclEcs8sXGEWqnZHodL2J9Vq+hUz+TDZzBaDIh1j3d9M2IUlTjtrHTZy4uMuRdTi8BGws7jLA==", + "version": "15.7.1", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.7.1.tgz", + "integrity": "sha512-fwIKtA23Pl/rqfYP5TSGK7gkEuLhoTvRYW+TU7ER3q9GpNLt/PjG5NLv3XHRDiTg7OPM1JcckBgds+VnAc+HbA==", "dev": true, "requires": { - "@vue/component-compiler-utils": "^2.5.1", + "@vue/component-compiler-utils": "^3.0.0", "hash-sum": "^1.0.2", "loader-utils": "^1.1.0", "vue-hot-reload-api": "^2.3.0", @@ -12723,9 +12806,9 @@ } }, "vue-router": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.0.4.tgz", - "integrity": "sha512-wjirAFeMR53FFTRIM2ofLKH5BJte6Q9+MUiOj6fLzqhgerjVyQVeMmvgiQDslPJJHSqFfQ559EDvIi0lA1Lr6g==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.1.3.tgz", + "integrity": "sha512-8iSa4mGNXBjyuSZFCCO4fiKfvzqk+mhL0lnKuGcQtO1eoj8nq3CmbEG8FwK5QqoqwDgsjsf1GDuisDX4cdb/aQ==", "dev": true }, "vue-server-renderer": { @@ -12804,9 +12887,9 @@ "dev": true }, "vuepress": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-0.14.10.tgz", - "integrity": "sha512-upD0br3AUmZQ+kNJMg135jW36JjYAdShl6XYwDmVMw4XbtcLDSMGWTLqLCQN3PTIs/7TgiJ3cLWNL1ps63gyUQ==", + "version": "0.14.11", + "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-0.14.11.tgz", + "integrity": "sha512-5iB7iWeEG7GtEiNwmS2LOcifp2V93aZ4+oO9pq8OcUgOWay9/NqmNqzg7KQ7AJ0puZGg0tYwUKKjifIWIPE8jQ==", "dev": true, "requires": { "@babel/core": "7.0.0-beta.47", @@ -13275,14 +13358,15 @@ } }, "webpack-dev-middleware": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.6.2.tgz", - "integrity": "sha512-A47I5SX60IkHrMmZUlB0ZKSWi29TZTcPz7cha1Z75yYOsgWh/1AcPmQEbC8ZIbU3A1ytSv1PMU0PyPz2Lmz2jg==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", "dev": true, "requires": { "memory-fs": "^0.4.1", - "mime": "^2.3.1", - "range-parser": "^1.0.3", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", "webpack-log": "^2.0.0" }, "dependencies": { @@ -13352,12 +13436,20 @@ } }, "webpack-merge": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.1.tgz", - "integrity": "sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", "dev": true, "requires": { - "lodash": "^4.17.5" + "lodash": "^4.17.15" + }, + "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + } } }, "webpack-serve": { @@ -13390,20 +13482,6 @@ "v8-compile-cache": "^2.0.0", "webpack-hot-client": "^3.0.0", "webpack-log": "^1.1.2" - }, - "dependencies": { - "cosmiconfig": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.0.tgz", - "integrity": "sha512-nxt+Nfc3JAqf4WIWd0jXLjTJZmsPLrA9DDc4nRw2KFJQJK7DNooqSXrNI7tzLG50CF8axczly5UV929tBmh/7g==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.0", - "parse-json": "^4.0.0" - } - } } }, "webpack-sources": { @@ -13709,9 +13787,9 @@ "dev": true }, "write-file-atomic": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", - "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", diff --git a/docs/package.json b/docs/package.json index e786b8c17b..cd963ec040 100644 --- a/docs/package.json +++ b/docs/package.json @@ -10,7 +10,7 @@ "typedoc": "^0.14.2", "typedoc-plugin-markdown": "^1.1.27", "typedoc-plugin-no-inherit": "^1.1.6", - "vuepress": "^0.14.10", + "vuepress": "^0.14.11", "webpack": "^4.28.4" }, "private": true diff --git a/docs/plugins/.gitignore b/docs/plugins/.gitignore new file mode 100644 index 0000000000..88b06327ab --- /dev/null +++ b/docs/plugins/.gitignore @@ -0,0 +1,2 @@ +*.md +!README.md diff --git a/docs/plugins/README.md b/docs/plugins/README.md index f7f88f9c45..7068812be0 100644 --- a/docs/plugins/README.md +++ b/docs/plugins/README.md @@ -2,28 +2,3 @@ layout: Plugins --- -# Plugins - -- [@nomiclabs/buidler-truffle4](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle4): integration with TruffleContract from Truffle 4. -- [@nomiclabs/buidler-truffle5](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle5): integration with TruffleContract from Truffle 5. -- [@nomiclabs/buidler-web3](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3): injects Web3 1.x into the Buidler Runtime Environment. -- [@nomiclabs/buidler-web3-legacy](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-web3-legacy): injects Web3 0.20.x into the Buidler Runtime Environment. -- [@nomiclabs/buidler-ethers](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-ethers): injects ethers.js into the Buidler Runtime Environment. -- [@nomiclabs/buidler-solpp](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-solpp): automatically run the solpp preprocessor before each compilation. -- [@nomiclabs/buidler-solhint](https://github.com/nomiclabs/buidler/tree/master/packages/buidler-solhint): easily run solhint to lint your Solidity code. - -# Under development - -These plugins are under development and we would love your help to get them to the finish line: - -- [@nomiclabs/buidler-solc-docker](https://github.com/nomiclabs/buidler-docker-solc/pull/2): compile contracts using a native solc binary running inside a Docker container for faster compilation times. -- [@nomiclabs/buidler-etherscan](https://github.com/nomiclabs/buidler/pull/234): automatic Etherscan source code verification - -# Plugin ideas - -These are ideas for plugins that we haven't gotten around to building yet, but feel free to use them as inspiration if you want to build one: - -- buidler-ganache: Automatically manage a Ganache instance for running unit tests. -- buidler-faucets: Add a few tasks to easily get testnet ETH into an address. -- buidler-ens: Makes it really easy to integrate ENS resolution into tasks. e.g. `env.ens.resolve('buidler.eth')` -- buidler-infura: Makes it easier to work with Infura nodes. diff --git a/docs/troubleshooting/common-problems.md b/docs/troubleshooting/common-problems.md new file mode 100644 index 0000000000..ed808803df --- /dev/null +++ b/docs/troubleshooting/common-problems.md @@ -0,0 +1,16 @@ +# Common problems + +This section describes common problems with working with Buidler and how to solve them. + +## Out of memory errors when compiling large projects + +If your project has lots of smart contracts, compiling them may require more memory than what +Node allows by default and crash. + +If you are experiencing this problem, you can use Buidler's `--max-memory` argument: + +```sh +npx buidler --max-memory 4096 compile +``` + +If you find yourself using this all the time, you can set it with an environment variable in your `.bashrc`: `export BUIDLER_MAX_MEMORY=4096`. diff --git a/docs/troubleshooting/verbose-logging.md b/docs/troubleshooting/verbose-logging.md new file mode 100644 index 0000000000..f349e36d48 --- /dev/null +++ b/docs/troubleshooting/verbose-logging.md @@ -0,0 +1,61 @@ +# Verbose logging + +You can enable Buidler's verbose mode by running it with its `--verbose` flag, or by setting the `BUIDLER_VERBOSE` environment variable to `true`. + +This mode will print a lot of output that can be super useful for debugging. An example of Buidler run in verbose mode is: + +``` +pato@pmbp:asd% npx buidler --verbose + buidler:core:plugins Loading plugin file /Users/pato/projects/buidler/buidler/packages/buidler-core/internal/core/tasks/builtin-tasks +0ms + buidler:core:plugins Loading plugin file /Users/pato/projects/buidler/buidler/packages/buidler-core/builtin-tasks/clean +3ms + buidler:core:plugins Loading plugin file /Users/pato/projects/buidler/buidler/packages/buidler-core/builtin-tasks/compile +2ms + buidler:core:plugins Loading plugin file /Users/pato/projects/buidler/buidler/packages/buidler-core/builtin-tasks/console +53ms + buidler:core:plugins Loading plugin file /Users/pato/projects/buidler/buidler/packages/buidler-core/builtin-tasks/flatten +3ms + buidler:core:plugins Loading plugin file /Users/pato/projects/buidler/buidler/packages/buidler-core/builtin-tasks/help +1ms + buidler:core:plugins Loading plugin file /Users/pato/projects/buidler/buidler/packages/buidler-core/builtin-tasks/run +2ms + buidler:core:plugins Loading plugin file /Users/pato/projects/buidler/buidler/packages/buidler-core/builtin-tasks/test +1ms + buidler:core:plugins Loading plugin @nomiclabs/buidler-truffle5 +2ms + buidler:core:plugins Buidler is linked, searching for plugin starting from CWD /private/tmp/asd +0ms + buidler:core:plugins Loading plugin file /Users/pato/projects/buidler/buidler/packages/buidler-truffle5/dist/index.js +5ms + buidler:core:plugins Loading plugin @nomiclabs/buidler-web3 +60ms + buidler:core:plugins Buidler is linked, searching for plugin starting from CWD /private/tmp/asd +0ms + buidler:core:plugins Loading plugin file /Users/pato/projects/buidler/buidler/packages/buidler-web3/dist/index.js +0ms + buidler:core:analytics Computing Project Id for /private/tmp/asd +0ms + buidler:core:analytics Project Id set to acce19ef71fcff30788e87c9d69ca4d0a5aee84c8f8cf696183a21b788730078 +1ms + buidler:core:analytics Looking up Client Id at /Users/pato/.buidler/config.json +1ms + buidler:core:analytics Client Id found: 61cf5dde-8c57-447b-bfe0-d57bdd80ab68 +1ms + buidler:core:bre Creating BuidlerRuntimeEnvironment +0ms + buidler:core:bre Running task help +1ms +Buidler version 1.0.0 + +Usage: buidler [GLOBAL OPTIONS] [TASK OPTIONS] + +GLOBAL OPTIONS: + + --config A Buidler config file. + --emoji Use emoji in messages. + --help Shows this message, or a task's help if its name is provided + --max-memory The maximum amount of memory that Buidler can use. + --network The network to connect to. + --show-stack-traces Show stack traces. + --verbose Enables Buidler verbose logging + --version Shows buidler's version. + + +AVAILABLE TASKS: + + clean Clears the cache and deletes all artifacts + compile Compiles the entire project, building all artifacts + console Opens a buidler console + flatten Flattens and prints all contracts and their dependencies + help Prints this message + run Runs a user-defined script after compiling the project + sample-task A sample Buidler task + test Runs mocha tests + +To get help for a specific task run: buidler help [task] + + buidler:core:cli Killing Buidler after successfully running task help +0ms +``` + +Buidler uses the [debug](https://github.com/visionmedia/debug) package to manage logging. The `DEBUG` environment variable that can be used to turn on the verbose logging and filter it using a simple wildcard pattern. diff --git a/docs/typedoc.json b/docs/typedoc.json index 587605e4dc..fc07ff1862 100644 --- a/docs/typedoc.json +++ b/docs/typedoc.json @@ -8,52 +8,54 @@ "out": "./api", "ignoreCompilerErrors": true, "exclude": [ - "internal/core/tasks/builtin-tasks.ts", - "internal/core/config/config-loading.ts", - "internal/core/config/extenders.ts", - "internal/core/config/default-config.ts", - "internal/core/config/extenders-instance.ts", - "internal/core/config/tasks-dsl-instance.ts", - "internal/core/config/config-resolution.ts", - "internal/core/providers/network.ts", - "internal/core/providers/gas-providers.ts", - "internal/core/providers/construction.ts", - "internal/core/providers/accounts.ts", - "internal/core/providers/wrapper.ts", - "internal/core/params/buidler-params.ts", - "internal/core/params/env-variables.ts", - "internal/core/project-structure.ts", - "internal/util/lazy.ts", - "internal/util/scripts-runner.ts", - "internal/util/caller-package.ts", - "internal/util/unsafe.ts", - "internal/util/glob.ts", - "internal/util/console.ts", - "internal/util/lang.ts", - "internal/util/packageInfo.ts", - "internal/cli/cli-with-a-typo.ts", - "internal/cli/ArgumentsParser.ts", - "internal/cli/project-creation.ts", - "internal/cli/cli.ts", - "internal/cli/emoji.ts", - "internal/cli/HelpPrinter.ts", - "internal/solidity/resolver.ts", - "internal/solidity/imports.ts", - "internal/solidity/compiler/index.ts", - "internal/solidity/compiler/downloader.ts", - "internal/solidity/dependencyGraph.ts", - "internal/constants.ts", - "internal/lib/buidler-lib.ts", - "builtin-tasks/help.ts", - "builtin-tasks/compile.ts", - "builtin-tasks/utils/cache.ts", - "builtin-tasks/test.ts", - "builtin-tasks/task-names.ts", - "builtin-tasks/flatten.ts", - "builtin-tasks/clean.ts", - "builtin-tasks/check.ts", - "builtin-tasks/console.ts", - "builtin-tasks/run.ts", - "register.ts" + "**/internal/core/tasks/builtin-tasks.ts", + "**/internal/core/config/config-loading.ts", + "**/internal/core/config/extenders.ts", + "**/internal/core/config/default-config.ts", + "**/internal/core/config/extenders-instance.ts", + "**/internal/core/config/tasks-dsl-instance.ts", + "**/internal/core/config/config-resolution.ts", + "**/internal/core/providers/network.ts", + "**/internal/core/providers/gas-providers.ts", + "**/internal/core/providers/construction.ts", + "**/internal/core/providers/accounts.ts", + "**/internal/core/providers/wrapper.ts", + "**/internal/core/params/buidler-params.ts", + "**/internal/core/params/env-variables.ts", + "**/internal/core/project-structure.ts", + "**/internal/util/lazy.ts", + "**/internal/util/scripts-runner.ts", + "**/internal/util/caller-package.ts", + "**/internal/util/unsafe.ts", + "**/internal/util/glob.ts", + "**/internal/util/console.ts", + "**/internal/util/lang.ts", + "**/internal/util/packageInfo.ts", + "**/internal/cli/cli-with-a-typo.ts", + "**/internal/cli/ArgumentsParser.ts", + "**/internal/cli/project-creation.ts", + "**/internal/cli/cli.ts", + "**/internal/cli/emoji.ts", + "**/internal/cli/HelpPrinter.ts", + "**/internal/solidity/resolver.ts", + "**/internal/solidity/imports.ts", + "**/internal/solidity/compiler/index.ts", + "**/internal/solidity/compiler/downloader.ts", + "**/internal/solidity/dependencyGraph.ts", + "**/internal/constants.ts", + "**/internal/lib/buidler-lib.ts", + "**/builtin-tasks/help.ts", + "**/builtin-tasks/compile.ts", + "**/builtin-tasks/utils/cache.ts", + "**/builtin-tasks/test.ts", + "**/builtin-tasks/task-names.ts", + "**/builtin-tasks/flatten.ts", + "**/builtin-tasks/clean.ts", + "**/builtin-tasks/check.ts", + "**/builtin-tasks/console.ts", + "**/builtin-tasks/run.ts", + "**/register.ts", + "**/internal/core/config/config-validation.ts", + "**/internal/buidler-evm/**/*.ts" ] } diff --git a/package.json b/package.json index f8bec7afc3..a722ca76a4 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,10 @@ { "name": "root", "version": "0.0.0", - "author": "Nomic Labs SRL", - "license": "MIT", + "author": "Nomic Labs LLC", + "license": "SEE LICENSE IN EACH PACKAGE'S LICENSE FILE", "private": true, "devDependencies": { - "@types/chai": "^4.1.7", "@types/mocha": "^5.2.6", "@types/node": "^8.10.44", "chai": "^4.2.0", @@ -15,7 +14,7 @@ "mocha": "^5.2.0", "nyc": "^14.1.0", "prettier": "1.18.2", - "source-map-support": "^0.5.12", + "source-map-support": "^0.5.13", "ts-node": "^8.1.0", "tslint": "^5.16.0", "tslint-config-prettier": "^1.18.0", diff --git a/packages/buidler-core/LICENSE b/packages/buidler-core/LICENSE index 74ad66fc0f..39a4611e22 100644 --- a/packages/buidler-core/LICENSE +++ b/packages/buidler-core/LICENSE @@ -1,6 +1,13 @@ +The Buidler EVM functionality is licensed under the NOMIC LABS DEVELOPER +LICENSE AGREEMENT as defined below. This includes the source code contained +in the directories "src/internal/buidler-evm" and "test/internal/buidler-evm" +as well as the compiled code in the "internal/buidler-evm" directory of the +"@nomiclabs/buidler" NPM package. All other Buidler code is licensed under +the MIT License as defined below. + The MIT License -Copyright (c) 2018 Nomic Labs SRL +Copyright (c) 2019 Nomic Labs LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +25,55 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file +THE SOFTWARE. + +NOMIC LABS DEVELOPER LICENSE AGREEMENT + +This Nomic Labs Developer License Agreement (the "Agreement") governs the use of +the Buidler EVM software (the "Software") distributed by Nomic Labs LLC +("Nomic Labs") as a component of the buidler-core software. By using the +Software, you (or the entity on whose behalf you are using the Software) +("Licensee") agree to be bound by this Agreement. + +1. License Grant. Nomic Labs grants to Licensee a non-exclusive, revocable and +non-transferable right to: (a) reproduce and distribute verbatim copies of the +Software, (b) run the Software for Licensee's internal business purposes, +(c) produce derivative works of buidler-core that incorporate the Software +unmodified, and (d) use the software as a developer tool to produce and test +Licensee's own software products ("Licensee Products"). Licensee Products are +not restricted by this Agreement so long as they do not incorporate any portion +of the Software and are not designed to interface directly with the Software. + +2. Use Restrictions. Except as expressly permitted by Section 1 of this +Agreement, Licensee shall not, directly or indirectly: (a) sublicense, resell, +rent, lease, distribute, market, commercialize, or otherwise transfer the +Software, or any rights therein; (b) modify, alter, or translate the Software +(whether in source code form or during runtime); (c) prepare any derivative work +based on the Software; (d) remove or alter any copyright, trademark or +proprietary notice in the Software or (e) use the Software for the purpose of +building a competitive product or service or copying its features or user +interface. + +3. Term and Termination. This Agreement shall terminate immediately upon +Licensee's material breach of the Agreement. Upon termination of this Agreement, +all licenses granted herein will automatically terminate, and Licensee will +discontinue all use of the Software and destroy any copies of the Software in +its possession. Sections 2, 4, and 5 of this Agreement shall survive termination +or expiration of the Agreement. + +4. Disclaimer of Warranties. THE SOFTWARE IS PROVIDED TO LICENSEE ON AN "AS IS" +BASIS. ALL CONDITIONS, REPRESENTATIONS AND WARRANTIES, WHETHER EXPRESS, IMPLIED, +STATUTORY OR OTHERWISE, ARE HEREBY DISCLAIMED TO THE MAXIMUM EXTENT PERMITTED BY +APPLICABLE LAW, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTY OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT OF THIRD +PARTY RIGHTS. + +5. Limitation of Liability. EXCEPT FOR A BREACH BY LICENSEE OF SECTIONS 1 OR 2, +IN NO EVENT SHALL EITHER PARTY BE LIABLE TO THE OTHER PARTY FOR ANY LOST PROFITS +OR REVENUE OR FOR ANY INDIRECT, SPECIAL, COVER, PUNITIVE, INCIDENTAL OR +CONSEQUENTIAL DAMAGES, ARISING UNDER THIS AGREEMENT AND WHETHER OR NOT SUCH +PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE FOREGOING +DISCLAIMER SHALL NOT APPLY TO THE EXTENT PROHIBITED BY APPLICABLE LAW. IN NO +EVENT SHALL NOMIC LABS'S AGGREGATE LIABILITY ARISING OUT OF OR RELATED TO THIS +AGREEMENT, WHETHER IN CONTRACT, TORT OR UNDER ANY OTHER THEORY OF LIABILITY, +EXCEED $100. diff --git a/packages/buidler-core/README.md b/packages/buidler-core/README.md index e8b5d64904..1c25a1e4b0 100644 --- a/packages/buidler-core/README.md +++ b/packages/buidler-core/README.md @@ -1,13 +1,12 @@ ![](https://user-images.githubusercontent.com/232174/57331293-9a042100-70ee-11e9-8c37-8a5d52875bf4.png) [![NPM Package](https://img.shields.io/npm/v/@nomiclabs/buidler.svg?style=flat-square)](https://www.npmjs.org/package/@nomiclabs/buidler) [![Build Status](https://travis-ci.com/nomiclabs/buidler.svg?branch=master)](https://travis-ci.com/nomiclabs/buidler) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) --------- Buidler is a task runner for Ethereum smart contract developers. It facilitates performing frequent tasks, such as running tests, automatically checking code for mistakes or interacting with a smart contract. Check out the [plugin list](https://buidler.dev/plugins/) to use it with your existing tools. Developed by [Nomic Labs](https://nomiclabs.io/) and funded by an Ethereum Foundation grant. -Join our read-only [Buidler News Telegram group](https://t.me/BuidlerNews) to stay up to date on new releases, plugins and tutorials. +Join our [Buidler Telegram group](http://t.me/BuidlerSupport) to stay up to date on new releases, plugins and tutorials. ## Installation @@ -21,7 +20,7 @@ The recommended way of using Buidler is through a local installation in your pro Be careful about inconsistent behavior across different projects that use different Buidler versions. - npm -g install @nomiclabs/buidler + npm install --global @nomiclabs/buidler If you choose to install Buidler globally, you have to do the same for its plugins and their dependencies. @@ -29,10 +28,11 @@ If you choose to install Buidler globally, you have to do the same for its plugi On [Buidler's website](https://buidler.dev) you will find: -- [Guides to get started](https://buidler.dev/guides/#getting-started) -- [Advanced documentation](https://buidler.dev/documentation/#overview) -- [API docs](https://buidler.dev/api/) +- [Guides to get started](https://buidler.dev/getting-started/) +- [Buidler EVM](https://buidler.dev/buidler-evm/) - [Plugin list](https://buidler.dev/plugins/) +- [API docs](https://buidler.dev/api/) + ## Contributing @@ -44,13 +44,8 @@ Go to [CONTRIBUTING.md](./CONTRIBUTING.md) to learn about how to set up Buidler' [Buidler Support Telegram group](http://t.me/BuidlerSupport): for questions and feedback. -[Buidler News Telegram group](http://t.me/BuidlerNews): to remain up to date on Buidler releases, tutorials and news all around. Low-bandwith, read-only group. - [Follow Nomic Labs on Twitter.](https://twitter.com/nomiclabs) -## License - -MIT ## Happy buidling! diff --git a/packages/buidler-core/package.json b/packages/buidler-core/package.json index c72b5f52ff..b454b1a304 100644 --- a/packages/buidler-core/package.json +++ b/packages/buidler-core/package.json @@ -1,8 +1,8 @@ { "name": "@nomiclabs/buidler", - "version": "1.0.0-beta.13", - "author": "Nomic Labs SRL", - "license": "MIT", + "version": "1.0.1", + "author": "Nomic Labs LLC", + "license": "SEE LICENSE IN LICENSE", "homepage": "https://buidler.dev", "repository": "github:nomiclabs/buidler", "main": "internal/lib/buidler-lib.js", @@ -51,6 +51,7 @@ "recommended-gitignore.txt" ], "devDependencies": { + "@types/chai": "^4.2.0", "@types/debug": "^4.1.4", "@types/download": "^6.2.4", "@types/find-up": "^2.1.1", @@ -58,7 +59,7 @@ "@types/glob": "^7.1.1", "@types/lodash": "^4.14.123", "@types/node-fetch": "^2.3.7", - "@types/semver": "^5.5.0", + "@types/semver": "^6.0.2", "@types/ci-info": "^2.0.0", "@types/qs": "^6.5.3", "@types/uuid": "^3.4.5", @@ -67,6 +68,7 @@ }, "dependencies": { "@types/bn.js": "^4.11.5", + "@types/lru-cache": "^5.1.0", "abort-controller": "^3.0.0", "bip32": "^2.0.3", "bip39": "^3.0.2", @@ -76,9 +78,14 @@ "deepmerge": "^2.1.0", "download": "^7.1.0", "enquirer": "^2.3.0", - "ethereumjs-common": "^1.3.0", - "ethereumjs-tx": "^2.0.0", + "@nomiclabs/eth-sig-util": "^2.4.4", + "ethereumjs-abi": "^0.6.8", + "ethereumjs-account": "^3.0.0", + "ethereumjs-block": "^2.2.0", + "ethereumjs-common": "^1.3.2", + "ethereumjs-tx": "^2.1.1", "ethereumjs-util": "^6.1.0", + "@nomiclabs/ethereumjs-vm": "^4.1.0", "find-up": "^2.1.0", "fp-ts": "1.19.3", "fs-extra": "^7.0.1", @@ -86,13 +93,14 @@ "io-ts": "1.10.4", "is-installed-globally": "^0.2.0", "lodash": "^4.17.11", + "merkle-patricia-tree": "^3.0.0", "mocha": "^5.2.0", "node-fetch": "^2.6.0", "qs": "^6.7.0", - "semver": "^5.6.0", - "solc": "0.5.8", + "semver": "^6.3.0", + "solc": "0.5.11", "solidity-parser-antlr": "^0.4.2", - "source-map-support": "^0.5.12", + "source-map-support": "^0.5.13", "ts-essentials": "^2.0.7", "tsort": "0.0.1", "uuid": "^3.3.2" diff --git a/packages/buidler-core/sample-project/buidler.config.js b/packages/buidler-core/sample-project/buidler.config.js index e09bae41d9..722c271fb8 100644 --- a/packages/buidler-core/sample-project/buidler.config.js +++ b/packages/buidler-core/sample-project/buidler.config.js @@ -1,7 +1,13 @@ -task("sample-task", "A sample Buidler task", async () => { - console.log( - "To learn how to create your own tasks go to https://buidler.dev/guides/create-task.html" - ); +usePlugin("@nomiclabs/buidler-truffle5"); + +// This is a sample Buidler task. To learn how to create your own go to +// https://buidler.dev/guides/create-task.html +task("accounts", "Prints the list of accounts", async () => { + const accounts = await web3.eth.getAccounts(); + + for (const account of accounts) { + console.log(account); + } }); module.exports = {}; diff --git a/packages/buidler-core/sample-project/contracts/Greeter.sol b/packages/buidler-core/sample-project/contracts/Greeter.sol index 8455fbe774..10b2aa4715 100644 --- a/packages/buidler-core/sample-project/contracts/Greeter.sol +++ b/packages/buidler-core/sample-project/contracts/Greeter.sol @@ -5,11 +5,15 @@ contract Greeter { string greeting; constructor(string memory _greeting) public { - greeting = _greeting; + setGreeting(_greeting); } function greet() public view returns (string memory) { return greeting; } + function setGreeting(string memory _greeting) public { + greeting = _greeting; + } + } diff --git a/packages/buidler-core/sample-project/scripts/sample-script.js b/packages/buidler-core/sample-project/scripts/sample-script.js index 17541f5cfc..0d8d894f0e 100644 --- a/packages/buidler-core/sample-project/scripts/sample-script.js +++ b/packages/buidler-core/sample-project/scripts/sample-script.js @@ -1,14 +1,22 @@ -// We require the Buidler Runtime Environment explicitly here. This is optional. +// We require the Buidler Runtime Environment explicitly here. This is optional +// when running the script with `buidler run