The first step to creating a Dapp is to deploy a smart contract on the Tezos network, whether for testing or real-life use. There are several ways to do this, such as using the Tezos CLI.
However, during development, the smart contracts and the associated storage are likely to change: new field, field removal, structure change. For each change, a new deployment must be done.
Thus, the way that the contract is deployed will change accordingly, especially the initial storage. A minimal change in the storage definition can make the next deployments tiresome when using the Tezos CLI, especially if changes are made several times.
Mooreover, there are times when you need to deploy several smart contracts that will interact with one another. The deployment of a smart contract depends on the deployment of a previous one to get its address. Instead of deploying one after the other the smart contracts and retrieving their address, it should be possible to have an automated script that performs these actions.
Truffle, developed and maintained by ConsenSys Software Inc, solves these difficulties. This tool uses scripts to perform smart contract deployments. It uses a CLI and a few configuration files to make deployments easier and faster.
In this chapter, we will deploy the Raffle smart contract, as developed in the LIGO module onto a testnet using Truffle.
Truffle is part of a suite of tools that make it easier to deploy written smart contracts onto a blockchain, called The Truffle Suite. It provides:
- Truffle: for smart contract compilation and deployment onto a network.
- Ganache: for running a local blockchain network and test smart contracts on it.
- Drizzle: for easy integration with frontend applications by providing a library to interact with deployed smart contracts.
- Truffle Teams: for monitoring smart contracts
The Truffle Suite is not available for all blockchains. It supports:
- Hyperledger Fabric
Only Truffle and Ganache (still in beta) are available for Tezos for now.
Truffle can compile and deploy LIGO or SmartPy scripts on the Tezos network with a single command.
Truffle can be installed with a docker or npm. The easiest way is to use Truffle from the npm package.
You'll need to have NodeJS v8.9.4 or later on your machine.
Open a terminal and run:
Truffle will be installed globally using the
For more info, you can refer to the official documentation
As described below, Truffle is working with configuration files and scripts, which must be located in specific repositories. You can set up your Truffle project from scratch, but it is easier to use one of the two ways provided by Truffle:
- Initializing an empty project
- Using a Truffle Box
These two methods generate the project structure and the configuration files (with predefined settings like accounts, networks...): the Truffle box comes with three smart contract examples.
Create a folder for your Truffle project, and run:
A Truffle box is a project already set up for interacting with a smart contract, that can easily and quickly be adjusted to the specific needs of a project. They can be launched instantly and modified with little work. Truffle provides users with a global boxes repository at trufflesuite.com/boxes. More particularly, a Tezos box is available at trufflesuite.com/boxes/tezos-example
tezos-example box is helpful for the deployment of Dapps.
You can download this box with:
The Truffle unbox command will not create a new tezos-example folder, but will unpack all the content in the current folder.
You can find a Truffle box with SmartPy scripts at github.com/truffle-box/tezos-smartpy-example-box
Using Truffle can be divided in two steps:
- Configuration: modifying scripts to define the way smart contracts are deployed.
- Compilation and deployment, with the Truffle CLI.
A Truffle project follows this structure:
- build: the folder containing the Michelson code, compiled by Truffle and used for the contract deployments. The build folder will be created or updated after each compilation command.
- contracts: the folder containing all the LIGO smart contracts that Truffle has to compile.
- migrations: the folder containing the Truffle deployement scripts for the deployment of the contracts.
- node_modules: the node modules used by the Truffle project.
- package.json: the file containing the script commands, which launches a sandbox with Ganache.
- scripts: the folder containing scripts that can be run from the CLI to execute some operation on the smart contracts.
- sandbox: the folder containing two accounts to use on a sandbox environment.
- truffle-config.js: the configuration file which defines networks and accounts to be used for the deployment.
The Truffle CLI provides various commands that can be displayed with:
The main commands are:
In this part, the
tezos-example box is used as an example.
Truffle is mainly used for smart contract compilation and deployment. It can also launch tests, but other tools such as PyTezos can be used for that.
Compiling smart contracts can be done with:
Input: valid smart contracts (i.e compiling smart contracts), located in
Output: Truffle artifacts, stored into the build/contracts directory.
Truffle can compile LIGO smart contracts, using the installed LIGO compiler. But they MUST be stored in the contracts folder. Truffle considers each LIGO file as an independent smart contract. Thus, if a smart contract is split into several LIGO files, Truffle will try to compile each file as a separate smart contract, resulting in a failed compilation. There is a workaround for this behavior:
- Create a new folder in the project root directory, called
- Move all your smart contracts files into
- Create a LIGO file, importing the main file from
Truffle will successfully compile your split smart contract.
For each LIGO file found in the contract, Truffle will yield an artifact in build/contracts.
An artifact is a JSON file containing the compiled smart contract, the LIGO source code and the deployment information.
The example below is the artifact yielded for the
Counter.ligo file fron the LIGO module:
These artifacts are then used in the deployment scripts.
Let's create a truffle project for the Raffle Smart contract, and compile the LIGO code into a Michelson code, with Truffle.
First, we will download the
tezos-example box and then remove the example contracts.
Let's put the Raffle smart contract into our Truffle project:
Let's copy and paste the LIGO code into this file.
Everything is ready for the compilation:
A new JSON file has been created in the
At this point, the smart contract is compiled and ready to be deployed. However, Truffle needs to be configured so that the deployment is done on a given network, with a given account, a given initial storage, etc.
Originating a contract costs some Tez. Thus, an account holding funds is necessary. Accounts with funds on testnets can freely be created as a JSON file using a faucet.
The network configuration is handled in the
There are two ways of importing an account:
- Importing an account into the
Truffle will activate this account before the contract origination.
- Setting already activated accounts in the scripts folder. Accounts can be defined according to the network. By default, a sandbox folder is present, with two defined accounts (these two accounts are found in any sandbox). New accounts can be defined by creating a new folder, named after the network name by convention, with an
Obviously faucet accounts can be imported into the
accounts.js file as well.
The networks are defined in the
truffle-config.js file. It exports an object that defines networks. Each key in networks sets a network, which requires:
- host: An RPC node (https://tezostaquito.io/docs/rpc_nodes/) or a local node (as shown in the development network).
- port: running node port.
- network_id: each Tezos network has an id. For instance, Florencenet id is
*matches any network.
- type: network type, here
- A private key to create a transaction, either:
- secret, mnemonic, password, email
We will deploy our Raffle smart contract onto Edonet. We'll need to add this network into the
truffle-config.js file. First, we need a faucet account. Let's download a faucet from https://faucet.tzalpha.net/ into our root project folder.
Let's define an Edonet network, that will use this faucet:
Now that the smart contracts and the deployment network are ready, the next step is to write the deployment script. Such scripts are also called migrations: they usually update the storage structure or initial data and the smart contract code. These scripts are located in the migrations directory.
tezos-example box comes with tree migrations:
A migration script defines:
- the initial storage of the smart contract(s)
- the contract deployment steps: the order of deployment of smart contracts, networks, accounts
These migration scripts are used the same way whether you deploy your smart contract for the first time, or you update a new version of a smart contract.
The first step is to specify which smart contract is to be deployed:
Truffle will look for a MyContract.ligo file in the contract directory. Thus, to import a contract, the filename of the contract (without the extension) is used (
artifacts is a Truffle keyword). It is here possible to import several smart contracts:
|Big_map, Map||const bigMap = new MichelsonMap() |
(from taquito module)
|int, nat, mutez||number|
Here is a migration example, defining a storage with essential types:
Any type and structure change in the LIGO smart contract storage must be mirrored in the
initialStorage variable. This way, the evolution of the storage used can be versioned.
The last step of the migration is the deployment definition. It's a function export, which defines how the contracts should be deployed.
This function takes three arguments:
deployer: truffle object which deploys a contract.
network: the network used.
account: the account used.
deployer object deploys the code on the specified network. The deployer takes the
initialStorage object and a few options as input.
A minimal viable migration could be:
The execution returns some data such as the contract address, the cost, etc.
It can be useful to deploy a smart contract differently according to the network. For instance, if the storage holds an administator address, it's likely to be different on the mainnet and on testnet. The migration can be branched according to the network, like this:
The deployment changes according to the network. Here, the storage is different on each network.
The admin account can be set at deployment.
A migration can deploy several contracts at the same time. This is useful when the migration data has to be used for the deployment of another contract. Below is an example with two contracts. The second contract needs to have the address of the first contract in its initial storage.
Let's create the migration file for our Raffle contract:
We need to import the contract (step 1) then define the initial storage, which should have the following fields:
nat address big_map
web3 will be used for the
bytes types. The initial storage that is defined contains an open raffle (step 2).
Finally, the deployment is defined and the admin of the contract is set to the address used for the deployment (step 3).
Everything is now ready for deployment. The network and the migration account are set, the initial storage and the deployment step are defined. From the project directory, you can run:
This command can be broken down into two steps:
- Verifying that the smart contracts are already compiled. If not, it will launch a compilation.
- Deploying the smart contracts, following the migration scripts under the migration folder. Before the deployment, Truffle checks if the initial storage is compliant with its Michelson definition. If not, it will raise an exception.
Each migration generally takes up to 30 seconds. Here is the console output:
The most useful data here is the deployed contract address (to later interact with it), the cost of the origination and the transaction hash (to check its status on an explorer for instance).
You can find some of these data in the automatically generated JSON file under the
Once the migration is done, it can be useful to verify that the contract is deployed correctly. There are many tools for this: CLI, libraries, explorers, etc. In this section, we'll keep it simple with a GUI.
tzstats.com provides information about any public Tezos network: transactions, accounts, contracts (origination, storage, entrypoints), etc.
If you deployed your contract on a testsnet, e.g. Edonet you can check its status on the corresponding version of tzstats: edo.tzstats.com/<contract_address>.
You should see New Smart contract created by... line in the Calls section. The contract storage is also visible.
The first step in developing a Dapp is to deploy the smart contracts. Truffle takes LIGO code, compiles it into Michelson code and deploys it onto any public or private network.
Each migration needs an initial storage that is compliant with the storage type of the Michelson code.
Thanks to its configuration and easily readable and versioned migration files, Truffle is an essential tool throughout the development and deployment of a Dapp.