- Create and store migration scripts in the ./mirations directory. You can find the directory at the root of your project.
- Each file follows a naming convention that includes a number and description. The number denotes the order of execution and is used to record the status of migration. The suffix includes a human-readable description of the scripts:
2_token_migration.js
- In the migration script file, include the required import statements followed by the deployment steps:
// Import statement
var contract = artifacts.require("contract");
module.exports = function(deployer) {
// Deployment statement
deployer.deploy(contract);
};
-
Reference the contract using artifacts.require(). It is similar to require and import in JavaScript, but returns the contract abstraction with related properties and methods.
- Contracts are imported using their names. Do not use file paths because each file can contain more than one contract. Consider the following utility contract file:
// utility.sol
contract Ownable {
...
}
contract Pausable {
...
}
This file contains two contracts. While importing these contracts, reference them by their names:
var ownable = artifacts.require("Ownable");
var pausable = artifacts.require("Pausable");
- The migrations file should export the migration steps as a function using module.exports. The function should have at least one parameter called deployer, which can assist in the deployment and to keep the artifacts:
module.exports = function(deployer) {
deployer.deploy(contractInstance);
};
- Deploy more than one contract by calling the deployer method multiple times. It will deploy them in the order you dictated:
deployer.deploy(ownable);
deployer.deploy(pausable);
Deployer will also return a promise, which can be used to queue up the process. This can help you do tasks that may depend on the previous deployment:
deployer.deploy(ownable).then(function() {
return deployer.deploy(pausable, ownable.address);
});
- If your contract accepts constructor parameters, specify them as part of the deploy method:
deployer.deploy(<contract>, parameter1, parameter2, ...);
- If you don't want your contract to be overwritten again, specify it with the overwrite parameter. This will not deploy the contract if it has already been deployed:
deployer.deploy(ownable, {
overwrite: false
});
- The last parameter can also include values such as gas and from. This allows us to specify the values individually for each deployment:
deployer.deploy(A, {
gas: 4612388,
from: "0x7f1E4A1DC3eB8233B49Bb8E208cC6aAa8B39C77F"
});
- Multiple contract deployments can be part of a single deploy statement. You can do this by passing each contract and its constructor arguments as arrays:
deployer.deploy([
[ownable],
[pausable, parameter1, parameter2],
...
]);
- The deployer method also supports linking libraries and contracts. You can link an already deployed library to another contract before deploying it. The target for linking can be a single contract or an array of contracts. If the target contract does not use the library, the contract will be ignored:
// To link a deployed library to another contract
deployer.deploy(<Library>);
deployer.link(<Library>, <Contract>);
// To link a deployed library to multiple contracts
deployer.deploy(<Library>);
deployer.link(<Library>, [<Contract1>, <Contract2>]);
- In addition to deployer, the exportable function also supports two more optional parameters: network and accounts. The network parameter allows you to run the deployment steps based on the current network:
module.exports = function(deployer, network) {
if (network == "development") {
// Do something
} else {
// Do something else
}
}
- Use the accounts parameter to get the list of accounts on the current network. This value is similar to web3.eth.accounts:
module.exports = function(deployer, network, accounts) {
...
}
- Include the migrations contract, which is required for the migration's functionality. It follows a predefined interface, but you can edit it to add more features. The default Truffle template comes with the following migration contract:
pragma solidity ^0.4.8;
contract Migrations {
address public owner;
// A getter function with the signature `last_completed_migration()` is required.
// It should return an uint
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner)
_;
}
function Migrations() {
owner = msg.sender;
}
// A function with the signature `setCompleted(uint)` is required.
function setCompleted(uint completed) restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
This contract will be deployed initially as the first migration and won't be updated later. You have to include the contract as part of the initial migration script:
// ./migrations/1_intial_migration.js
var Migrations = artifacts.require("Migrations");
module.exports = function(deployer) {
// Initial migration deploys only the migration contract
deployer.deploy(Migrations);
};
- Once you have configured your contracts and migration scripts, run them using the migrate command:
truffle migrate
If everything goes right and the migrations are successful, you can see the following output: