Migrating CosmWasm contracts on Terra#

Contracts on Terra can be initialized as migratable, which allows the administrator to upload a new version of the contract and then send a migrate message to move to the new code.

This tutorial uses Terrain, a Terra development suite designed to simplify the scaffolding, deployment, and migration of your contracts.

If this is your first time using Terrain, visit the Initial setup guide.


There are two key components to a migratable contract:

  • A MigrateMsg transaction.

  • An admin set, which is the address that’s allowed to perform migrations.

1. Add MigrateMsg to contract#

To implement support for MigrateMsg, add the following to msg.rs:

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct MigrateMsg {}


You can place this message anywhere, however; it is usually placed above the InstantiateMsg struct.

2. Update contract.rs#

Now that MigrateMsg is defined, you will need to update contract.rs:

  1. Update the import from crate::msg to include MigrateMsg:

    use crate::msg::{CountResponse, ExecuteMsg, InstantiateMsg, QueryMsg, MigrateMsg};
  2. Add the following method above instantiate:

    #[cfg_attr(not(feature = "library"), entry_point)]
    pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult<Response> {

3. Call migrate#

In previous Terrain tutorials, you learned how to deploy the contract. Now you will be able to initialize it as migratable.

After adding MigrateMsg to the smart contract, redeploy and add the --set-signer-as-admin flag. This flag tells Terra that the transaction signer is allowed to migrate the contract in the future:

terrain deploy counter --signer test1 --set-signer-as-admin

With the new contract deployed you can make some changes then migrate to the new code with the following command:

terrain contract:migrate counter --signer test1