diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index c4960f5ec5..3907ac6a22 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -60,11 +60,11 @@ module.exports = { collapsable: false, depth: 1, children: [ - ["/guides/truffle-migration.md", "Migrating from Truffle", 0], ["/guides/project-setup.md", "Setting up a project", 0], ["/guides/compile-contracts.md", "Compiling your contracts", 0], - ["/guides/truffle-testing.md", "Testing with Web3.js & Truffle", 0], ["/guides/waffle-testing.md", "Testing with ethers.js & Waffle", 0], + ["/guides/truffle-testing.md", "Testing with Web3.js & Truffle", 0], + ["/guides/truffle-migration.md", "Migrating from Truffle", 0], ["/guides/deploying.md", "Deploying your contracts", 0], ["/guides/scripts.md", "Writing scripts", 0], ["/guides/buidler-console.md", "Using the Buidler console", 0], @@ -225,4 +225,4 @@ module.exports = { }, }] ] -}; +}; \ No newline at end of file diff --git a/docs/advanced/buidler-runtime-environment.md b/docs/advanced/buidler-runtime-environment.md index b7e24d100b..5541af5b76 100644 --- a/docs/advanced/buidler-runtime-environment.md +++ b/docs/advanced/buidler-runtime-environment.md @@ -14,7 +14,7 @@ The BRE has a role of centralizing coordination across all Buidler components. T 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. +Plugins can extend the BRE. For example, [buidler-ethers](/~https://github.com/nomiclabs/buidler/tree/master/packages/buidler-ethers) adds a Ethers.js instance to it, making it available to tasks, tests and scripts. ### As global variables @@ -28,17 +28,36 @@ When writing tests or scripts, you can use `require("@nomiclabs/buidler")` to im 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). +## 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 bre = require("@nomiclabs/buidler"); +const assert = require("assert"); + +describe("Buidler Runtime Environment", function() { + it("should have a config field", function() { + assert.notEqual(bre.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). + ## 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. +Everything gets easier when you use higher-level libraries, like [Ethers.js](https://docs.ethers.io/ethers.js/html/) or [ethereum-waffle](https://www.npmjs.com/package/ethereum-waffle), 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: +For example, adding an instance of [Web3.js](https://web3js.readthedocs.io/en/latest/) to the BRE can be done in this way: ```js extendEnvironment(bre => { @@ -49,22 +68,3 @@ extendEnvironment(bre => { bre.web3 = new Web3(new Web3HTTPProviderAdapter(bre.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 bre = require("@nomiclabs/buidler"); -const assert = require("assert"); - -describe("Buidler Runtime Environment", function() { - it("should have a config field", function() { - assert.notEqual(bre.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/buidler-evm/README.md b/docs/buidler-evm/README.md index 3a4917b050..3f62366cd6 100644 --- a/docs/buidler-evm/README.md +++ b/docs/buidler-evm/README.md @@ -16,7 +16,7 @@ Buidler comes built-in with Buidler EVM, a local Ethereum network designed for d - Buidler will always spin up an instance on startup when `defaultNetwork` is empty or set to `buidlerevm`. It's the default behavior. - It can be used to run tests, in the console, scripts, and tasks -- Plugins (web3.js, ethers.js, Truffle, etc) connect directly to the provider +- Plugins (ethers.js, web3.js, Waffle, Truffle, etc) connect directly to the provider - There's no need to make any changes to your tests or scripts. - It's simply another network and it can be used with `--network` @@ -44,7 +44,7 @@ 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: +This is an example of a Buidler EVM exception using `TruffleContract`: ``` Error: Transaction reverted: function selector was not recognized and there's no fallback function @@ -114,8 +114,8 @@ Buidler EVM allows you to print logging messages and contract variables calling - `console.logBytes32(bytes32 b)` - `console.log` implements the same formatting options that can be found in Node.js' [`console.log`](https://nodejs.org/dist/latest-v12.x/docs/api/console.html#console_console_log_data_args), which in turn uses [`util.format`](https://nodejs.org/dist/latest-v12.x/docs/api/util.html#util_util_format_format_args). - Example: `console.log("Changing owner from %s to %s", currentOwner, newOwner)` -- It works with any library: web3.js, ethers.js, truffle-contract, waffle, etc. -- `console.log` is implemented in standard Solidity and then detected in Buidler EVM. This makes its compilation work with any other tools (like Remix or Truffle). +- It works with any library: ethers.js, web3.js, waffle, truffle-contract, etc. +- `console.log` is implemented in standard Solidity and then detected in Buidler EVM. This makes its compilation work with any other tools (like Remix, Waffle or Truffle). - `console.log` calls can run in other networks, like mainnet, kovan, ropsten, etc. They do nothing in those networks, but spend a minimal amount of gas. ## Logging diff --git a/docs/getting-started/README.md b/docs/getting-started/README.md index d9c7ccb018..7b0f9ced10 100644 --- a/docs/getting-started/README.md +++ b/docs/getting-started/README.md @@ -55,15 +55,13 @@ $ npx buidler 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. +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 - -``` -npm install --save-dev @nomiclabs/buidler-truffle5 @nomiclabs/buidler-web3 web3 -``` +The sample project will ask you to install `buidler-waffle` and `buidler-ethers`, which makes Buidler compatible with tests built with Waffle. You can learn more about it [in this guide](../guides/waffle-testing.md). + +::: tip +Buidler will let you know how, but in case you missed it you can install them with `npm install --save-dev @nomiclabs/buidler-waffle ethereum-waffle chai @nomiclabs/buidler-ethers ethers` +::: ### Running tasks @@ -103,21 +101,7 @@ This is the list of built-in tasks, and the sample `accounts` task. Further ahea 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 = {}; -``` +<<< @/../packages/buidler-core/sample-project/buidler.config.js{5-11} To run it, try `npx buidler accounts`: @@ -149,32 +133,7 @@ $ npx buidler accounts Next, if you take a look at `contracts/`, you should be able to find `Greeter.sol:` -```solidity -pragma solidity ^0.5.1; - -import "@nomiclabs/buidler/console.sol"; - -contract Greeter { - - string greeting; - - constructor(string memory _greeting) public { - console.log("Deploying a Greeter with greeting:", _greeting); - greeting = _greeting; - } - - function greet() public view returns (string memory) { - return greeting; - } - - function setGreeting(string memory _greeting) public { - console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); - greeting = _greeting; - } - -} - -``` +<<< @/../packages/buidler-core/sample-project/contracts/Greeter.sol To compile it, simply run: @@ -184,24 +143,9 @@ 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!"); +The sample project comes with these tests that use [Waffle](https://getwaffle.io/) and [Ethers.js](/~https://github.com/ethers-io/ethers.js/). You can use other libraries if you want, check the integrations described in our guides. - await greeter.setGreeting("Hola, mundo!"); - - assert.equal(await greeter.greet(), "Hola, mundo!"); - }); -}); -``` +<<< @/../packages/buidler-core/sample-project/test/sample-test.js You can run your tests with `npx buidler test` @@ -212,48 +156,26 @@ Compiled 2 contracts successfully Contract: Greeter -Deploying a Greeter with greeting: Hello, world! -Changing greeting from 'Hello, world!' to 'Hola, mundo!' - ✓ Should return the new greeting once it's changed (344ms) - - Greeter contract - Deployment -Deploying a Greeter with greeting: Hello, world! -Deploying a Greeter with greeting: Hola, mundo! - ✓ Should deploy with the right greeting (82ms) - - - 2 passing (434ms) + ✓ Should return the new greeting once it's changed (762ms) + 1 passing (762ms) ``` ### 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: +Next, to deploy the contract we will use a Buidler script. +Inside `scripts/` you will find `sample-script.js` with the following code: -```js -async function main() { - const Greeter = artifacts.require("Greeter"); +<<< @/../packages/buidler-core/sample-project/scripts/sample-script.js - const greeter = await Greeter.new("Hello, Buidler!"); - console.log("Greeter deployed to:", greeter.address); -} +Run it with `npx buidler run scripts/sample-script.js`: -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 +Greeter deployed to: 0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F ``` -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. +Congrats! You have created a project, ran a Buidler task, compiled a smart contract, installed a Waffle integration plugin, wrote and ran a test using the Waffle and ethers.js plugins, 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/compile-contracts.md b/docs/guides/compile-contracts.md index 27c6074bfd..0b777e2079 100644 --- a/docs/guides/compile-contracts.md +++ b/docs/guides/compile-contracts.md @@ -19,7 +19,7 @@ To force a compilation you can use the `--force` argument, or run `npx buidler c ## Artifacts -Compiling with Buidler generates one JSON artifact per contract. These are based on Truffle's artifact format, and are compatible with most tools. +Compiling with Buidler generates one JSON artifact per contract. These are compatible with most tools, including Truffle's artifact format. Each artifact consists of a json with the following properties: @@ -72,10 +72,7 @@ module.exports = { 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"); +usePlugin("@nomiclabs/buidler-waffle"); module.exports = { paths: { diff --git a/docs/guides/deploying.md b/docs/guides/deploying.md index 79db8e1398..e99e574e6e 100644 --- a/docs/guides/deploying.md +++ b/docs/guides/deploying.md @@ -7,16 +7,17 @@ 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 these contents +with the deploy script `scripts/sample-script.js`: ```js -// This script uses @nomiclabs/buidler-truffle5 -const Greeter = artifacts.require("Greeter"); - async function main() { - const greeter = await Greeter.new("Hello, world!"); + // We get the contract to deploy + const Greeter = await ethers.getContractFactory("Greeter"); + const greeter = await Greeter.deploy("Hello, Buidler!"); + + await greeter.deployed(); - console.log("Greeter address:", greeter.address); + console.log("Greeter deployed to:", greeter.address); } main() @@ -29,8 +30,8 @@ main() You can run it with -```sh -npx buidler run --network your-network scripts/deploy.js +``` +npx buidler run --network scripts/sample-script.js ``` ### Truffle migrations support diff --git a/docs/guides/project-setup.md b/docs/guides/project-setup.md index a03e9e0888..2a96a6286c 100644 --- a/docs/guides/project-setup.md +++ b/docs/guides/project-setup.md @@ -32,7 +32,7 @@ If you select _Create a sample project_ a simple project creation wizard will as ``` contracts/ scripts/ -tests/ +test/ buidler.config.js ``` @@ -59,17 +59,17 @@ 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 + npm install --save-dev @nomiclabs/buidler-waffle ethereum-waffle chai @nomiclabs/buidler-ethers ethers ``` 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. +The sample project uses the `@nomiclabs/buidler-waffle` plugin, which depends on the `@nomiclabs/buidler-ethers` plugin. These integrate the Ethers.js and Waffle 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"); +usePlugin("@nomiclabs/buidler-waffle"); module.exports = {}; ``` diff --git a/docs/guides/scripts.md b/docs/guides/scripts.md index d9d064eb69..0656f50ed6 100644 --- a/docs/guides/scripts.md +++ b/docs/guides/scripts.md @@ -13,8 +13,7 @@ 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). +This makes it easy to port scripts that were developed for other tools that inject variables into the global state. ## Standalone scripts: using Buidler as a library @@ -40,44 +39,27 @@ drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 scripts drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 test ``` -Inside `scripts/` you will find `sample-script.js`: -```js -const bre = 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 bre.run("compile"); +Inside `scripts/` you will find `sample-script.js`. Read through its comments to have a better idea of what it does. - // We require the artifacts once our contracts are compiled - const Greeter = bre.artifacts.require("Greeter"); - 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); - }); -``` +<<< @/../packages/buidler-core/sample-project/scripts/sample-script.js -And there you can see how the [Buidler Runtime Environment] is accessed at the top, which makes this script work in a standalone fashion: +Done? Let's run the script with `node`: ``` $ node scripts/sample-script.js -All contracts have already been compiled, skipping compilation. -Greeter address: 0x494d39079b81c620c0ebea503b9295331bfc34c2 +Greeter address: 0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F ``` -But the script can also run through Buidler: +By accessing the [Buidler Runtime Environment] at the top, you are allowed to run the script in a standalone fashion. Buidler always runs the compile task when running scripts through it. But in a standalone fashion you may want to call compile manually to make sure everything is compiled. This is done by calling `bre.run('compile')`. Uncomment the following line out and re-run the script with `node`: +```js +await bre.run("compile"); ``` -$ npx buidler run scripts/sample-script.js + +``` +$ node scripts/sample-script.js All contracts have already been compiled, skipping compilation. -Greeter address: 0x494d39079b81c620c0ebea503b9295331bfc34c2 +Greeter address: 0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F ``` ### Buidler arguments diff --git a/docs/guides/truffle-testing.md b/docs/guides/truffle-testing.md index 0211b3f754..cd61474a16 100644 --- a/docs/guides/truffle-testing.md +++ b/docs/guides/truffle-testing.md @@ -4,7 +4,8 @@ Buidler allows you to use Truffle to test your smart contracts. This mainly mean 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. +Let's see how to do this creating a new Buidler project. + Run these to start: ``` mkdir my-project @@ -13,28 +14,92 @@ 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: +Now run npx buidler inside your project folder and select `Create an empty buidler.config.js`. + +Let's now install the `Truffle` and `Web3.js` plugins, as well as `web3.js` itself. ``` -$ 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 +npm install --save-dev @nomiclabs/buidler-truffle5 @nomiclabs/buidler-web3 web3 ``` -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} +Enable the Truffle 5 plugin on your Buidler config file by adding + +```js{1} +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports = {}; +``` + +Create a folder named `contracts` inside your project. Add a file named `Greeter.sol`, copy and paste the code below: + +```c +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; + } + + function setGreeting(string memory _greeting) public { + greeting = _greeting; + } + +} +``` + +## Writing a test + +Create a new directory called `test` inside your project root directory and create a new file called `Greeter.js`. + +Let's start with the code below. We'll explain it next, but for now paste this into `Greeter.js`: -Look at the file `test/sample-test.js` and you'll find these sample tests: +```js +const Greeter = artifacts.require("Greeter"); -<<< @/../packages/buidler-core/sample-project/test/sample-test.js{1} +// 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!"); -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. + await greeter.setGreeting("Hola, mundo!"); + + assert.equal(await greeter.greet(), "Hola, mundo!"); + }); +}); + +// Vanilla Mocha test. Increased compatibility with tools that integrate Mocha. +describe("Greeter contract", function() { + let accounts; + + before(async function() { + accounts = await web3.eth.getAccounts(); + }); + + describe("Deployment", function() { + it("Should deploy with the right greeting", async function() { + const greeter = await Greeter.new("Hello, world!"); + assert.equal(await greeter.greet(), "Hello, world!"); + + const greeter2 = await Greeter.new("Hola, mundo!"); + assert.equal(await greeter2.greet(), "Hola, mundo!"); + }); + }); +}); +``` + +As you can see in the first line, the artifacts object is present in the global scope and you can use it to access the Truffle contract abstractions. + +```js +const Greeter = artifacts.require("Greeter"); +```` These examples show two approaches towards testing: - Using `contract()`, which is the traditional way to test with Truffle @@ -65,7 +130,40 @@ If you want to use Truffle Migrations to initialize your tests and call `deploye 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} +```js{20} +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!"); + }); +}); + +// Vanilla Mocha test. Increased compatibility with tools that integrate Mocha. +describe("Greeter contract", function() { + let accounts; + + before(async function() { + accounts = await web3.eth.getAccounts(); + }); + + describe("Deployment", function() { + it("Should deploy with the right greeting", async function() { + const greeter = await Greeter.new("Hello, world!"); + assert.equal(await greeter.greet(), "Hello, world!"); + + const greeter2 = await Greeter.new("Hola, mundo!"); + assert.equal(await greeter2.greet(), "Hola, mundo!"); + }); + }); +}); +``` Checkout the plugin's [README file](/~https://github.com/nomiclabs/buidler/tree/master/packages/buidler-truffle5) for more information about it. diff --git a/docs/guides/typescript.md b/docs/guides/typescript.md index 5623d8b7ea..dca53373a4 100644 --- a/docs/guides/typescript.md +++ b/docs/guides/typescript.md @@ -44,16 +44,16 @@ 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"); +```js{5,13} +usePlugin("@nomiclabs/buidler-waffle"); // 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(); + const accounts = await ethers.getSigners(); for (const account of accounts) { - console.log(account); + console.log(await account.getAddress()); } }); @@ -65,15 +65,15 @@ into this ```typescript{1,7,8,15} import { task, usePlugin } from "@nomiclabs/buidler/config"; -usePlugin("@nomiclabs/buidler-truffle5"); +usePlugin("@nomiclabs/buidler-waffle"); // 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, bre) => { - const accounts = await bre.web3.eth.getAccounts(); + const accounts = await bre.ethers.getSigners(); for (const account of accounts) { - console.log(account); + console.log(await account.getAddress()); } }); @@ -119,15 +119,15 @@ 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), 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. +Some Buidler plugins, like [buidler-waffle](/~https://github.com/nomiclabs/buidler/tree/master/packages/buidler-waffle) and [buidler-ethers](/~https://github.com/nomiclabs/buidler/tree/master/packages/buidler-ethers), 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: ```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" + "./node_modules/@nomiclabs/buidler-ethers/src/type-extensions.d.ts", + "./node_modules/@nomiclabs/buidler-waffle/src/type-extensions.d.ts" ] ``` @@ -135,20 +135,20 @@ Plugins that include type extensions should have documentation detailing their e ## 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]. +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-ethers](/~https://github.com/nomiclabs/buidler/tree/master/packages/buidler-ethers) or [buidler-web3](/~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: ```typescript -import { web3 } from "@nomiclabs/buidler"; +import { ethers } from "@nomiclabs/buidler"; describe("Token", function() { let accounts: string[]; beforeEach(async function() { - accounts = await web3.eth.getAccounts(); + accounts = await ethers.eth.getSigners(); }); it("should do something right", async function() { @@ -161,12 +161,12 @@ describe("Token", function() { An example for scripts: ```typescript -import { run, web3 } from "@nomiclabs/buidler"; +import { run, ethers } from "@nomiclabs/buidler"; async function main() { await run("compile"); - const accounts = await web3.eth.getAccounts(); + const accounts = await ethers.eth.getSigners(); console.log("Accounts:", accounts); } diff --git a/docs/guides/waffle-testing.md b/docs/guides/waffle-testing.md index c80216bc78..921ec2d5e5 100644 --- a/docs/guides/waffle-testing.md +++ b/docs/guides/waffle-testing.md @@ -2,48 +2,59 @@ [Waffle](https://getwaffle.io/) is a simple smart contract testing library built on top of `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. +Buidler allows you to use Waffle to test your smart contracts using the `@nomiclabs/buidler-waffle` plugin. -Done? Great. Let's now install `ethers.js`, `Waffle` and their Buidler plugins, which will allow Waffle to use [Buidler EVM] and get stack traces and `console.log` functionality. +Let's see how to do this using the Buidler sample project. -```sh -npm install --save-dev @nomiclabs/buidler-ethers ethers @nomiclabs/buidler-waffle ethereum-waffle +Run these to start: +``` +mkdir my-project +cd my-project +npm init --yes +npm install --save-dev @nomiclabs/buidler ``` -Add the `buidler-ethers` and `buidler-waffle` type extensions to your `tsconfig.json` that you should've created following the TypeScript guide: +Now run `npx buidler` inside your project folder and select `Create a sample project`. This is what the file structure should look like once you're done: -```json{8,13,14} -{ - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "strict": true, - "esModuleInterop": true, - "outDir": "dist", - "resolveJsonModule": true - }, - "include": ["./scripts", "./test"], - "files": [ - "./buidler.config.ts", - "./node_modules/@nomiclabs/buidler-ethers/src/type-extensions.d.ts", - "./node_modules/@nomiclabs/buidler-waffle/src/type-extensions.d.ts" - ] -} ``` +$ 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 Waffle plugin is enabled: -Note that we also enabled `resolveJsonModule`, as importing JSON files is common practice when using Waffle. +<<< @/../packages/buidler-core/sample-project/buidler.config.js{1} -Now, let's enable the `buidler-waffle` plugin in `buidler.config.ts`: +::: tip +There's no need for `usePlugin("@nomiclabs/buidler-ethers")`, as `buidler-waffle` already does it. +::: -```typescript -import { usePlugin } from "@nomiclabs/buidler/config"; +Look at the file `test/sample-test.js` and you'll find a sample test: -usePlugin("@nomiclabs/buidler-waffle"); +<<< @/../packages/buidler-core/sample-project/test/sample-test.js -export default {}; +You can run tests by running `npx buidler test`: ``` +$ npx buidler test +All contracts have already been compiled, skipping compilation. -There's no need for `usePlugin("@nomiclabs/buidler-ethers")`, as `buidler-waffle` already does it. + +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) +``` ## Migrating an existing Waffle project @@ -75,8 +86,8 @@ As an example, this Waffle configuration file: Would translate into this Buidler config: -```typescript -export default { +```js +module.exports = { paths: { sources: "./some_custom/contracts_path", artifacts: "../some_custom/build" @@ -94,12 +105,10 @@ export default { 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"; - +```js usePlugin("@nomiclabs/buidler-waffle"); -export default { +module.exports = { paths: { artifacts: "./build" } @@ -118,13 +127,9 @@ const provider = createMockProvider(); const provider = new MockProvider(); ``` -To use Waffle with Buidler you should do this instead: +This initialization is already handled by `@nomiclabs/buidler-waffle`. Just be sure to include `usePlugin("@nomiclabs/buidler-waffle");` in your Buidler config and you'll be set. Run your tests with `npx buidler test` and you should get stack traces when a transaction fails. -```js -import { waffle } from "@nomiclabs/buidler"; -const provider = waffle.provider; -``` +[buidler evm]: ../buidler-evm/README.md -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 +[Buidler Runtime Environment]: /documentation/#buidler-runtime-environment-bre diff --git a/packages/buidler-core/recommended-gitignore.txt b/packages/buidler-core/recommended-gitignore.txt index bbc2e4dc7d..3231a947da 100644 --- a/packages/buidler-core/recommended-gitignore.txt +++ b/packages/buidler-core/recommended-gitignore.txt @@ -1,3 +1,5 @@ +node_modules + #Buidler files cache artifacts diff --git a/packages/buidler-core/sample-project/buidler.config.js b/packages/buidler-core/sample-project/buidler.config.js index 722c271fb8..6770d0abcb 100644 --- a/packages/buidler-core/sample-project/buidler.config.js +++ b/packages/buidler-core/sample-project/buidler.config.js @@ -1,13 +1,22 @@ -usePlugin("@nomiclabs/buidler-truffle5"); +usePlugin("@nomiclabs/buidler-waffle"); // 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(); + const accounts = await ethers.getSigners(); for (const account of accounts) { - console.log(account); + console.log(await account.getAddress()); } }); -module.exports = {}; +// You have to export an object to set up your config +// This object can have the following optional entries: +// defaultNetwork, networks, solc, and paths. +// Go to https://buidler.dev/config/ to learn more +module.exports = { + // This is a sample solc configuration that specifies which version of solc to use + solc: { + version: "0.5.15", + }, +}; diff --git a/packages/buidler-core/sample-project/scripts/sample-script.js b/packages/buidler-core/sample-project/scripts/sample-script.js index 0d8d894f0e..abfce38e8d 100644 --- a/packages/buidler-core/sample-project/scripts/sample-script.js +++ b/packages/buidler-core/sample-project/scripts/sample-script.js @@ -1,18 +1,22 @@ -// We require the Buidler Runtime Environment explicitly here. This is optional -// when running the script with `buidler run