@gnidan gnidan released this Dec 18, 2018 · 374 commits to master since this release

It's about to be 2019! Guess we won't be needing this anymore:

2018 New Year's Resolutions

  • Release Truffle v5 🎊
  • Don't eat so much chocolate 🍫

Wait. That second one seems suspect. What is that? 🤷‍♀️

Okay, from now on, Truffle's official stance on New Years' Resolutions is not to let anything get in the way of a life of simple luxuries, whether that means confectionary quantities bordering on "medically ill-advised", or anything else similar to that, like what we have for you today.

Just kidding...

That's always been the official stance.

But really...

Please remember that healthy habits are a useful means of being able to enjoy as much delicious chocolate for as many years as possible. 😋

Wishing you happy and restful holidays, and a merry 2019! ❄️


Presenting Truffle v5.0.0! 📯

This major release is the biggest Truffle release yet, in terms of the number of new features, the release notes word-count, and most excitingly, the number of individual contributors from all around the world.

To keep this introduction brief, this marks the end of the v5 beta series. We hope you share our feelings when we say that we are truly impressed by the scope of changes and the wonder at the possibilities ahead.

These release notes seek to cover the changes as completely as possible, but if you're looking for historical information, it may be helpful to refer to the release notes from the betas:

Anyway, keep scrolling if you're looking for the table of contents, or first read about some highlights. 🔆


Highlights

Perhaps most notably, Truffle v5 now features:

  • Improved async/await support everywhere we could manage: in tests, migrations, truffle exec scripts, presumably any love letters, truffle develop / truffle console, et cetera.

    Much of this is thanks to upgrading to Web3.js v1.0, which paves the way with its vastly improved interface.

    Skip ahead to read about Interacting with your contracts or about async Migrations.

  • "Bring your own compiler" is an old name for a new feature that's been on the roadmap for a long time. Truffle v5 offers unprecedented flexibility in its support for compiler integrations. Besides the native solc support that the name implies, this includes support for solc in Docker, automatically downloading solc to match a specified version, an initial implementation of compatibility with the Vyper programming language, and an integration point for more advanced arbitrary compilation workflows.

    See the section on truffle compile to learn more.

  • A sweet new migrations system that gives you tons of useful information about your deployments, automatic dry-runs, and the ability to configure Truffle to wait for transaction confirmations or to increase block timeouts.

    More below about truffle migrate.

  • The beginnings of a plugins system with a new Truffle command: truffle run <external-plugin-command>.

    It's still early, so we'd love to solicit your feedback on this! This feature is intentionally minimal to start, so we'd appreciate your thoughts and ideas for it.

    See truffle run notes for more.

  • Opt-in usage analytics 🎉 to make Truffle better! Please consider enabling this by running:

    truffle config --enable-analytics
    

    Real talk: admittedly, we mention this here because we want you to see it.

    To make Truffle the best smart contract development tool it can be, good decisions about future updates rely on informed consideration. We promise to limit the data we collect and thank you in advance for helping us adapt to and inform new best practices.


💌


Contents

How to upgrade

npm uninstall -g truffle
npm install -g truffle

Breaking changes

[ Back to contents | Skip to what's new ]

Truffle v5 is a major release and contains some breaking changes.

Most notably, the upgrades to Web3.js v1.0 and Solidity v0.5 can be a high-impact change to existing projects.

This section identifies many of the updates to be aware of, but note that this list may not be complete. If you find a breaking change not on this list, please let us know so that we can include it!

Truffle

  • Numeric return values are now BN objects instead of the previously default BigNumber.js. These two projects use significantly different API semantics, so you may want to review those.

    Truffle provides a compatibility mode for projects unable to make the switch wholesale. Set numberFormat to "BigNumber", "String", or "BN" to choose.

    See example number format override
    // Choices are:  `["BigNumber", "BN", "String"].
    const Example = artifacts.require("Example");
    Example.numberFormat = "BigNumber";
  • The .at(<address>) method for truffle-contract constructors is now async.

Web3.js v1.0

  • Addresses are now checksummed (mixed-case) instead of all lower-case.

  • Numbers returned directly from Web3 (i.e. not from truffle-contract) are now strings. You can use web3.utils.toBN() to convert these.

    See example string to BN conversion
    const stringBalance = await web3.eth.getBalance('0xabc..');
    const bnBalance = web3.utils.toBN(stringBalance);
  • Many of the Web3 utility functions are now scoped under web3.utils.

    Some of these functions have changed slightly, so be on the lookout if you encounter errors about functions being undefined or strange errors arising from these utilities. (Thanks @Zacharius for pointing this out!)

  • Functions that return multiple values now return an object with both named and indexed keys.

  • Function arguments of type bytes must now be converted to hexadecimal bytestrings using web3.utils.asciiToHex().

  • The underlying .contract property of truffle-contract objects is the completely different web3.eth.Contract.

Solidity v0.5

Note for Quorum users

  • Recently, one user (thanks @EdsonAlcala!) brought to our attention that Truffle v5 may break support for Quorum. After investigating some potential quick solutions to this issue, we have concluded that further development effort is required to ensure we do not incur additional risk at the end of this release cycle.

    We consider maintaining Quorum support to be a top priority and intend to re-establish this support in early January. In the meantime, if you are using Truffle on a Quorum blockchain and run into trouble, please try rolling back to v4 for the time being. We apologize for this inconvenience.

What's new in Truffle v5

Interacting with your contracts

[ Back to contents ]

With this new version comes a whole slew of improvements on contract interaction. Syntax has been modernized, working with events has gotten better, error reporting has gotten clearer, and structured function parameters are now supported! It just feels good...

EventEmitter / Promise interface

Contract objects now have an EventEmitter interface and return a promise. You can now interact with them very much like you would interact with web3.eth.Contract objects!

Events also now have an EventEmitter interface.

See the usage section of the Truffle contract abstraction docs for some examples of working with contract objects and events!

REVERT Reason strings

Another super useful change is support for REVERT reason strings! Now if a transaction needs to be reverted, you will receive the reason string and know why.

Confirmation / block wait timeouts config

Previously when a transaction didn't get mined after 50 blocks, the transaction was dropped. Now Truffle allows you to configure block timeout amounts on your contracts. So for example, say you wanted your contract's transactions to timeout after 1,000 blocks.

Example.timeoutBlocks = 1000; // Set the timeout property on the contract abstraction
const example = await Example.new(1);
await example.setValue(5); // The transaction will retry for 1,000 blocks

WebSockets

Truffle now supports WebSockets via the websockets network config. You will need to enable this if you want to use the confirmations listener or if you want to hear events using .on or .once.

In the Truffle config:

module.exports = {
  networks: {
    development: {
      host: "127.0.0.1",
      port: 8545,
      network_id: "*",
      websockets: true
    }
  }
}

Automated Fueling

You can choose whether you want to have Truffle compute gas amounts for your transactions. If autoGas is enabled then Truffle will use web3 to estimate the gas. Then it will multiply it by a multiplier that is set with gasMultiplier and include that gas amount with the transaction.

Example.autoGas = true;    // Defaults to true
Example.gasMultiplier(1.5) // Defaults to 1.25
const instance = await Example.new();
await instance.callExpensiveMethod();

Overloaded Solidity functions

example.methods['setValue(uint256)'](123);
example.methods['setValue(uint256,uint256)'](11, 55);

Structured function parameters

There is now support for passing/returning structs in Solidity functions.

To use this, you'll have to include the experimental pragma line near the top of your contracts:

pragma experimental ABIEncoderV2;

This allows you to use complex function arguments and return values in Solidity and interact with the resulting contracts via truffle-contract's JS interface.

See example contract
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;

contract Structs {
  struct Coord {
    uint x;
    uint y;
  }

  function swap(Coord memory coord)
    public
    pure
    returns (Coord memory)
  {
    Coord memory reversed = Coord({
      x: coord.y,
      y: coord.x
    });

    return reversed;
  }
}
See example test
const Structs = artifacts.require("Structs");

contract("Structs", (accounts) => {
  it("reverses coordinates", async () => {
    const instance = await Structs.deployed();

    const original = { x: 5, y: 8 };

    const reversed = await instance.swap(original, { from: accounts[0] });

    assert.equal(reversed.y, original.x);
    assert.equal(reversed.x, original.y);
  })
});

truffle compile

[ Back to contents ]

Lots of great improvements to truffle compile! ⚙️

We're really excited by what we've built here, which includes:

  • Use your preferred Solidity version, including native and Docker builds
  • Write your contracts in Vyper
  • Hook into arbitrary compilation workflows (e.g. write contracts in Rust + cargo!)

Keep reading to learn more. This effort is just the beginning—we have ideas for plenty of other potential enhancements, and we can't wait to expand on this foundation that Truffle v5 lays out.

Solidity

Specify your compiler version

Specify the version of Solidity you'd like to use, and Truffle will automatically download the correct compiler for you! 💾

Use this feature by specifying compilers.solc.version in your Truffle config.

Example: Use the latest solc compatible with v0.4.22
module.exports = {
  /* ... rest of config */

  compilers: {
    solc: {
      version: "^0.4.22"
    }
  }
}

Use Docker or native solc

Truffle also supports using the Solidity Docker image or a natively installed solc compiler. Using one of these distributions can provide a >3x speed improvement over the default solc-js.

Speed Comparison

Using Docker or native binaries provides a significant speed improvement, particularly when compiling a large number of files.

Table: Time to run truffle compile on a MacBook Air 1.8GHz, Node v8.11.1:

Project # files solcjs docker native
truffle/metacoin-box 3 4.4s 4.4s 4.7s
gnosis/pm-contracts 34 21.7s 10.9s 10.2s
zeppelin-solidity 107 36.7s 11.7s 11.1s
See example Docker configuration
module.exports = {
  /* ... */

  compilers: {
    solc: {
      version: "0.4.25",
      docker: true
    }
  }
}

Note: Truffle doesn't auto-pull Docker images right now. You'll need to run docker pull ethereum/solc:0.5.1 yourself. Sorry for the inconvenience!

See example native configuration
module.exports = {
  /* ... */

  compilers: {
    solc: {
      version: "native",
    }
  }
}

Note This requires solc to be installed and available on your PATH. For information on installing Solidity, see the Installing section of the Solidity docs.

Note on compilers config

The solc config property has been moved to compilers and normalized a bit. Compiler settings are now grouped inside compilers.solc.settings. For more information, see the compiler configuration docs.

Example compiler settings
module.exports = {
  /* ... rest of config */

  compilers: {
    solc: {
      version: "0.5.1",
      settings: {
        optimizer: {
          enabled: true,
          runs: 200   // Optimize for how many times you intend to run the code
        },
        evmVersion: "homestead"  // Default: "byzantium"
      }
    }
  }
}

Vyper

Truffle now supports Vyper! 🐍

Note: Support for Vyper is still early, so there may be bugs. You'll have to install the Vyper compiler yourself. Please see the docs on Installing Vyper.

Once you have the Vyper compiler installed, Truffle will automatically compile any *.vy files in your contracts/ directory.

Thank you @evgeniuz for implementing this and thank you @vs77bb for funding the GitCoin bounty for this work.

Getting started with Vyper

We've published a Truffle Box to help you get started. If you're curious about using Vyper for your smart contracts, or just want to test it out, you can run:

truffle unbox vyper-example

Let us know what you think!

Other compilers

In cases where you need a bit more customization, you can now add an external property to the config. You would use this in cases where you have a command that generates artifacts, a command that generates custom artifacts from Truffle artifacts, or where you want to customize the artifacts that Truffle generates.

If you were to have a script named myScript.sh which outputs artifacts to ./myBuildFolder, you would configure the truffle config file as follows:

module.exports = {
  compilers: {
    external: {
      command: "myScript.sh",
      targets: [{
        path: "./myBuildFolder/*.json"
      }]
    }
  }
}

This would run your compilation script, locate all the json files in myBuildFolder, and then copy them into your Truffle project's build folder with the rest of your compiled contracts as part of the compilation process.

truffle migrate

[ Back to contents ]

There have been a whole bunch of changes made to Truffle's migration function.

Improved error messaging

Now if Truffle can guess why a deployment failed it tells you and suggests some possible solutions.

More output

The information that Truffle provides during migrations is now more robust. There is much more about what's going on as you deploy, including cost summaries and real-time status updates about how long transactions have been pending. (See GIF below)

Improved dry run

Now if you are deploying to a known public network, Truffle will automatically do a test dry run beforehand. You can also use the --interactive flag at the command line to get a prompt between your dry run and real deployment.

Wait for confirmations and custom block timeouts

You can now configure the number of block confirmations to wait between deployments. This is helpful when deploying to Infura because their load balancer sometimes executes back-to-back transactions out of sequence and noncing can go awry. You can also specify how many blocks to wait before timing out a pending deployment.

module.exports = {
  networks: {
    ropsten: {
      provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io`),
      network_id: 3,
      gas: 5500000,           // Default gas to send per transaction
      gasPrice: 10000000000,  // 10 gwei (default: 20 gwei)
      confirmations: 2,       // # of confs to wait between deployments. (default: 0)
      timeoutBlocks: 200,     // # of blocks before a deployment times out  (minimum/default: 50)
      skipDryRun: true        // Skip dry run before migrations? (default: false for public nets )
    }
  }
}

async Migrations

The deployer interface now works seamlessly with ES6 async/await syntax. (Also backward compatible with Truffle V4's then-able pattern.)

Example Migration using async / await

const One = artifacts.require("One");
const Two = artifacts.require("Two");

module.exports = async function(deployer) {
  await deployer.deploy(One);

  const one = await One.deployed();
  const value = await one.value();

  await deployer.deploy(Two, value);
};

Deploying to Rinkeby...

migrate-rinkeby

truffle console / truffle develop

[ Back to contents ]

Truffle v5 includes a couple handy console enhancements.

await in the console

The await keyword now works in truffle console and truffle develop!

truffle(develop)> let instance = await Example.deployed();
truffle(develop)> await instance.someFunc();

Configure truffle develop

Override the network settings for truffle develop and specify any of the available ganache-core options.

module.exports = {
  /* ... rest of config */

  networks: {
    /* ... other networks */

    "develop": {
      accounts: 5,
      defaultEtherBalance: 500,
      blockTime: 3
    }
  }
};

truffle debug

[ Back to contents ]

Hard work continues on improving the user experience of our Solidity debugger. Most of the changes here are behind the scenes, but there's a handful of updates to pinpoint:

Breakpoints

Debugger breakpoints are now a whole lot better! Specify your breakpoints by file and line number so you can jump ahead to relevant sections of your code.

MagicSquare.sol:

11:   event Generated(uint n);
12:
13:   function generateMagicSquare(uint n)
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

debug(develop:0x91c817a1...)> b SquareLib:5
Breakpoint added at line 5 in SquareLib.sol.

debug(develop:0x91c817a1...)> b +10
Breakpoint added at line 23.

debug(develop:0x91c817a1...)> B +10
Breakpoint removed at line 23.

Inspect variables at end of trace

The debugger no longer automatically exits when you reach the end of a transaction! You can now inspect (v)ariables when execution finishes. This can be helpful, since you no longer need to be as careful when stepping repeatedly!

Reset command

Type r to reset back to the beginning of the trace! Not much else to say about that, we're sure you can appreciate that this might come in handy. Enjoy!

truffle test

[ Back to contents ]

Thanks to the other new features in this release, writing tests for your smart contracts is now a much more pleasant experience. There's not a whole lot to say in terms of feature updates except for a couple changes of note:

Write your tests in TypeScript

Good news for all you TypeScript lovers, Truffle tests now support TypeScript!

All you have to do is add the following require to your truffle config and you should be good to go!

require("ts-node/register");

module.exports = {
  // rest of truffle config
  // ...
}

Internal improvement: Assert.sol builds on separately deployed libraries

This represents no change for Truffle users, but it's been a frustrating limitation that the cost to deploy Assert.sol has always approached the default block gas limits. Depending on the network you want to use to run your Solidity tests, this could often be prohibitive.

Well, now that's changed, and Assert.sol now just links together a bunch of separate assertion libraries.

Breathing room for new things to come! 😮

truffle unbox

[ Back to contents ]

There have been some changes made to the init and unbox commands.

Prompt to overwrite files

To avoid accidentally overwriting files, in the past Truffle would not allow you to unbox or init in a directory that was not empty. With version 5, Truffle allows you to do so. When it finds files that have name conflicts with the files being copied, it will prompt you for each conflict and ask if you want to overwrite the existing files!

--force

If you don't want to deal with the prompts and know what you are doing, you can now also just bypass the prompting stage. You can do this by using a --force option. If you use this option, Truffle automatically overwrites any files that have name conflicts with the files being copied. Make sure you are careful when using this option so you don't overwrite anything you want to keep!

Unbox from a branch or a subdirectory

One last thing that has been changed with these commands is the ability to unbox from a branch or subdirectory. Now you can unbox projects in the following formats:

truffle unbox https://github.com/truffle-box/bare-box#remote-branch-on-github
truffle unbox git@github.com:truffle-box/bare-box#web3-one:directory/subDirectory

New: truffle run

[ Back to contents ]

We have big plans to support third-party plugins, and here's the start of that with the new truffle run command. Let us know what you think!

Special thanks to @rocky and @daniyarchambylov for their feedback and fixes in helping us bring you the first iteration of this feature.

Plugin installation / usage

  1. Install the plugin from NPM.

    npm install --save-dev truffle-plugin-hello
    
  2. Add a plugins section to your Truffle config.

    Example configuration
    module.exports = {
      /* ... rest of truffle-config */
    
      plugins: [
        "truffle-plugin-hello"
      ]
    }
  3. Run the command

    In the command line
    $ truffle run hello
    Hello, World!
    

Creating a custom command plugin

  1. Implement the command as a Node module with a function as its default export.

    Example: hello.js
    /**
     * Outputs `Hello, World!` when running `truffle run hello`,
     * or `Hello, ${name}` when running `truffle run hello [name]`
     * @param {Config} config - A truffle-config object.
     * Has attributes like `truffle_directory`, `working_directory`, etc.
     * @param {(done|callback)} [done=done] - A done callback, or a normal callback.
     */
    module.exports = (config, done) => {
      // config._ has the command arguments.
      // config_[0] is the command name, e.g. "hello" here.
      // config_[1] starts remaining parameters.
      let name = config._.length > 1 ? config._[1] : 'World!';
      console.log(`Hello, ${name}`);
      done();
    }

  2. Define a `truffle-plugin.json` file to specify the command.

    Example: truffle-plugin.json
    {
      "commands": {
        "hello": "hello.js"
      }
    }
  3. Publish to NPM

    For example, publish truffle-plugin-hello

New: truffle help

[ Back to contents ]

Truffle now has a help system on board! Want to figure out what commands are available? Simply run truffle help. Want to figure out usage information for a command and what options are available? Run truffle help <command>.

$ truffle help migrate
  Usage:        truffle migrate [--reset] [-f <number>] [--network <name>] [--compile-all] [--verbose-rpc] [--interactive]
  Description:  Run migrations to deploy contracts
  Options:
                --reset
                    Run all migrations from the beginning, instead of running from the last completed migration.
                -f <number>
                    Run contracts from a specific migration. The number refers to the prefix of the migration file.
                --network <name>
                    Specify the network to use, saving artifacts specific to that network. Network name must exist
                    in the configuration.
                --compile-all
                    Compile all contracts instead of intelligently choosing which contracts need to be compiled.
                --verbose-rpc
                    Log communication between Truffle and the Ethereum client.
                --interactive
                    Prompt to confirm that the user wants to proceed after the dry run.

New: truffle config

[ Back to contents ]

Besides the usual truffle-config.js (the config file formerly known as truffle.js), Truffle now incorporates a user-level configuration. Expect to see more features that take advantage of this!

Unique truffle develop mnemonics

When you run truffle develop, Truffle no longer uses the classic candy maple... mnemonic. Instead, the first time you run the command it will generate a random mnemonic just for you and persist it!

We encourage you to exercise caution when working with mnemonics and private keys, and recommend that everyone do their own research when it comes to protecting their crypto security.

Opt-in Analytics

To try and obtain more information about how we can improve Truffle, we have added an optional new analytics feature. By default it is turned off but if you enable it, the Truffle developers will receive anonymous information about your version number, the commands you run, and whether commands succeed or fail.

We don't use this anonymous information for anything other than to find out how we can make Truffle better and have also ensured that it doesn't make for a slower experience by sending this information in a background process.

To turn this feature on you can run

truffle config --enable-analytics

If you want to turn the analytics off you can run

truffle config --disable-analytics

P.S. feel free to go take a peek at the two places in the code where metrics are gathered: when running a command and to report version and errors. If you go ahead and do a good ol' GitHub search for the word analytics you can verify that these are the only places this code gets invoked. 🎉

More to come!

In the future we plan on providing more infrastructure to make Truffle even more configurable! Perhaps you could configure networks that will be used by multiple projects or something similar for plugin installation. Stay tuned!

Changelog since 5.0.0-beta.2

[ Back to contents ]

The changes listed below only encompass the changes since v5.0.0-beta.2. See the release notes for v5.0.0-beta.0, v5.0.0-beta.1, and v5.0.0-beta.2 for each release's changelog.

New Features

Bug Fixes / Improvements

Dependency Updates

Acknowledgments

[ Back to contents ]

This release has been a long time in the making and represents months of hard work by many contributors, both internal and external. Without your care and service, there would be no Truffle v5, and so we would like to extend our gratitude for helping bring us here today.

First of all, many thanks to Truffle's core engineering team: @eggplantzzz, @haltman-at, @CruzMolina, and @fainashalts. You have ignited this project's development and fuel this fire every day. We are grateful to receive your energy, your intellect, and your adept response to the daily challenges of software development.

Beyond just the core engineering team, Truffle owes its thanks to everyone in the broader Truffle organization. The operational support you provide is what enables this project to function. A special note of deep admiration to Truffle engineer alumnus @cgewecke, whose tireless efforts led to the first v5 beta that provide the bedrock of this release. And of course, thank you @tcoulter for bringing this project together and leading through vision and execution.

To members of the Colony team, your support has resonated loudly. You are surely already aware of the impact of your efforts, but to express our sentiments here: you have been crucial to our developing confidence in our work. Thank you @elenadimitrova and the rest of the team for being early adopters and for the countless hours of investigation into problems along the way.

Humble thanks to members of the Solidity and Web3.js teams. You are the giants upon whose shoulders we stand. Beyond providing the foundational software that Truffle incorporates, special thanks to @axic and @chriseth for the insights you have provided, and to @frozeman and @nivida for going above-and-beyond in helping us address some last minute issues we discovered.

Of course, these few names are just a tiny subset of Truffle's community. To all of our contributors, to those of you who have raised your hand in our Gitter when something was unclear, to those of you who have opened issues, or gone a step further and written pull requests, to every Truffle user— you are why and for whom we build Truffle. Thank you.


☕️


Assets 2