Migrations are Typescript files that help you deploy contracts to the Terra 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 with coordination. As your project evolves, you'll create new migration scripts to further this evolution on the blockchain. You can either write your own vanilla migration script with client SDK or use Instructionto interact with the blockchain network.
Setting up a node to migrate
To deploy and migrate smart contracts, a RPC node to receive migration requests. In this documentation, it uses Localterra. To setup LocalTerra running in your computer, install Docker and docker-compose. Then, start docker daemon(or app) then run:
git clone https://www.github.com/terra-project/LocalTerra
cd LocalTerra
docker-compose up
With node up and running, you should see the log in the terminal like picture as below:
Writing Migrations with Terra.js
Terra.js is Javascript & Node.js SDK library for Core of Terra. With terra.js, let’s write our first migration. In the 0_deploy_starter.ts file a starter migration script is written like this:
const {
MnemonicKey,
LCDClient,
MsgStoreCode,
MsgInstantiateContract,
Coins,
MsgExecuteContract,
Coin,
MsgSend,
} = require("@terra-money/terra.js");
async function deploy() {
console.log("Setting up accounts and contracts...");
// Setup a network provider to connect
const terra = new LCDClient({
URL: "http://localhost:1317",
chainID: "localterra",
});
// Setup an account with key from mnemonic phrases
const mk1 = new MnemonicKey({
mnemonic:
"notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius",
});
// Create a wallet which points to the network provider
const test1 = terra.wallet(mk1);
// To deploy a contract, you must get an wasm file.
const fs = require("fs");
const starterCode = fs.readFileSync("../wasm/starter.wasm");
// Create tx to sign and send to the blockchain
const storeStarter = new MsgStoreCode(
test1.key.accAddress,
starterCode.toString("base64")
);
// Create a batch of txs to send to the blockchain
const storeCodeTx = await test1
.createAndSignTx({
msgs: [storeStarter],
})
.catch((error: any) => {
console.log(error);
});
// Get results with codeId
const storeCodeTxResult = await terra.tx.broadcast(storeCodeTx);
const starterId = storeCodeTxResult.logs[0].events[1].attributes[1].value;
console.log("Starter code id", starterId);
// Cosmwasm smart contracts need to instantiate from the uploaded wasmer executable binary.
const instantiateStarter = new MsgInstantiateContract(
test1.key.accAddress,
+starterId,
{
default_name: "default",
},
new Coins({}),
false
);
// Create tx batch again
const instantiateTx = await test1.createAndSignTx({
msgs: [instantiateStarter],
});
// Get address from executing tx
const instantiateTxResult = await terra.tx.broadcast(instantiateTx);
const starterAddress =
instantiateTxResult.logs[0].events[0].attributes[2].value;
console.log("Starter address", starterAddress);
// To interact with smart contract, check generated contract's schemas in the schemas/ folder.
// For example, to set name in starter contract
const setName = new MsgExecuteContract(
test1.key.accAddress,
starterAddress,
{
set_name: {
name: "hello world",
},
},
new Coins({})
);
const interactTx = await test1.createAndSignTx({
msgs: [setName],
});
const interactTxResult = await terra.tx.broadcast(interactTx);
console.log(interactTxResult);
}
// execute function
deploy();
Running migrations
In order to run the migration script, libraries are needed to be installed. run the following commands in the terminal:
npm install
houston migrate
Instruction
To ease with setting up network configuration and account for developing smart contract, Houston provides Instruction.
To get the instruction, install Instruction with node package manager:
npm install @terra-money/instruction --save
then write in a migration script:
import Instruction from '@terra-money/instruction'
async function migrate() {
const FLIPPER = Instruction.require('flipper', 'localterra' {signer: who});
await FLIPPER.flip();
}
migrate()
To understand more about Instruction, check out Instruction menu.