49

As written in Truffle docs:

Migrations are Javascript files that help you deploy contracts to the Ethereum network. These files are responsible for staging your deployment tasks, and they're written under the assumption that your deployment needs will change over time. As your project evolves, you'll create new migration scripts to further this evolution on the blockchain. A history of previously run migrations is recorded on-chain through a special Migrations contract, detailed below.

But what does it really mean? What are the use cases of migrations?

I'm also trying to understand the Migrations.sol file, which is given in Truffle tutorial:

contract Migrations {
  address public owner;
  uint public last_completed_migration;

  modifier restricted() {
    if (msg.sender == owner) _
  }

  function Migrations() {
    owner = msg.sender;
  }

  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);
  }
}

3 Answers 3

28

The Migrations contract stores (in last_completed_migration) a number that corresponds to the last applied "migration" script, found in the migrations folder. Deploying this Migrations contract is always the first such step anyway. The numbering convention is x_script_name.js, with x starting at 1. Your real-meat contracts would typically come in scripts starting at 2_....

So, as this Migrations contract stores the number of the last deployment script applied, Truffle will not run those scripts again. On the other hand, in the future, your app may need to have a modified, or new, contract deployed. For that to happen, you create a new script with an increased number that describes the steps that need to take place. Then, again, after they have run once, they will not run again.

And yes, the last 2 lines are true Solidity. Look at http://solidity.readthedocs.io/en/latest/contracts.html#creating-contracts inside contract OwnedToken {.

9
  • 12
    why do we need migrations? I understand database migrations. They hold the changes made in the db schema. Db migrations let you upgrade your db schema and rollback to the previous schema. Does it have the same meaning here? Sep 15, 2016 at 9:04
  • 7
    Migrations here work in a similar way, but more rudimentary. It only keeps track of the last step, and does not allow rollback. Rollback is not really possible as Ethereum itself does not allow it. Sep 15, 2016 at 9:34
  • 6
    Migrations are files which help deploy new changes in the contract to the ethereum blockchain. And this migration contract helps keep track which migrations have been executed already. So the process is to create a new migration file with an increased number and to deploy just run truffle migrate. Truffle will know which migrations to run based on the file number and last_completed_migration value on the blockchain. Is this correct? Sep 15, 2016 at 10:20
  • 4
    but who cares? why would i care about the contract version? I dont see any connection between the migration file and the real contract(of the Dapp i deploy). moreover, idont see any attempt to update the "last step", the only thing i see is the deployment of a new migration contract to the blockchain
    – gor
    Sep 12, 2017 at 14:56
  • 3
    does this allow the original creators to amend contract clauses after deployment without forking?
    – grandrew
    Sep 13, 2017 at 15:46
9

Here is an example of a real use case of Truffle migrations.

I have a storage contract and an interface contract. The interface needs to know where the storage is and the storage needs to grant permissions to the interface.

So in the second migration (the first one is reserved for Truffle housekeeping) I'm deploying the storage:

var MEStorage = artifacts.require("./MEStorage.sol");

module.exports = function(deployer) {
  deployer.deploy(MEStorage);
};

And in the 3rd I'm getting Storage address and deploying interface with this address as a parameter. And after I have the interface address, I grant permissions to it in the Storage:

var MEInterface = artifacts.require("./MEInterface.sol");
var MEStorage = artifacts.require("./MEStorage.sol");

module.exports = function(deployer) {
  deployer.deploy(MEInterface, MEStorage.address).then(() => {
    MEStorage.deployed().then(storageInstance => {
        return storageInstance.setPermissions(MEInterface.address, 2);
        // 2 - is FULL access
    });
  });
};

Here is a video, explaining this use case and an article about storage pattern I'm using.

3

Migrations are a bunch of boilerplate that Truffle requires and which you will copy-paste and then forget you ever did it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.