truffle migrate命令的使用

truffle migrate命令的使用

概述

Migrations 是帮助你向以太坊网络中部署合约的JavaScript文件。这些文件负责部署你的合约文件,而且它们会在假设你的部署需求会随着时间的变化而被重写。随着项目的进展,你会创建新的migrate脚本以便在区块链上进一步的演化。以前运行的迁移历史会通过特殊的Migrations合约被记录在链条上,下面会详细讨论。

使用方式

命令:truffle migrate

Windows 示例:
打开终端(cmd)窗口,并进入truffle项目的合约目录,输入truffle migrate即可,如图:
truffle migrate命令的使用_第1张图片

注意事项:
1. 开启truffle客户端
2. 配置truffle的配置文件:truffle.js
配置方式:编辑truffle项目根目录下的truffle.js文件

module.exports = {
  networks: {
    development: {
      host: "127.0.0.1",
      port: 8545,
      network_id: "*" // Match any network id
    }
  }
};

如果上述两步没有做,会遇到以下的问题:
truffle migrate命令的使用_第2张图片

这个命令会运行所有位于truffle项目中migrations这个目录下的所有migrations文件。简单的说,migrations是一组托管的部署脚本。如果你之前成功的运行过这些migrations文件,truffle migrate会从运行的最后一个migrate文件开始执行,只运行新创建的migrations文件。如果不存在新的migrations文件,truffle migrate 任何的动作都不执行。你可以使用--reset选项来运行所有从一开始就运行的migrations文件。对于本地测试,确保有一个测试区块链,例如在执行migrate命令之前安装Ganache(也就是上面提到的注意事项)。

migrate 文件

一个简单的migration文件看起来是这样的:
文件名称:4_example_migration.js

var MyContract = artifacts.require("MyContract");

module.exports = function(deployer) {
  // deployment steps
  deployer.deploy(MyContract);
};

注意,文件名称是以数字开头以文件描述结尾。为了记录migration文件是否成功运行,所以文件名称中的前缀编号是必需的。后缀纯粹是为了便于增加阅读者的可读性和理解。

ARTIFACTS.REQUIRE():

在migrate文件的开头,我们通过artifacts.require()这个方法告诉Truffle,哪些合约是我们想要互相作用,互相影响的。这个方法和NodeJS中的require类似。但是在我们的案例中,它明确的返回了一个合约抽象,我们可以其余的部署脚本中使用它。指定的名称应该与源文件中合约定义的名称匹配。不要跳过源文件名称,因为一个文件可以包含不止一个合约。

思考这样的一个示例:在同一个源文件内指定两份合约:
文件名称:./contracts/Contracts.sol

contract ContractOne {
  // ...
}

contract ContractTwo {
  // ...
}

如果只使用ContractTwo, artifacts.require()的结构应该是这样的:

var ContractTwo = artifacts.require("ContractTwo");

如果使用两份合约都使用,你需要两个artifacts.require()这样的声明:

var ContractOne = artifacts.require("ContractOne");
var ContractTwo = artifacts.require("ContractTwo");

MODULE.EXPORTS

所有的migrations文件都必须通过module.exports这个语法来输出一个函数。每一个migrate导出的函数都必须接收一个deployer对象作为它的第一个参数。这个对象为部署智能合约提供一种简单的语法,除了执行一些更普通的职责之外,例如保存已部署的工件供以后使用。deployer对象是你分段部署任务的主要的接口,下面会介绍它的API。

你的迁移函数也可以接受其它的参数,看下面的示例。

INITIAL MIGRATION

为了使用Migrations的特性,Truffle 要求你要有一个Migrations的合约。这个合约一定要包含一个特殊的接口,但是你可以随意的编辑这份合约。对于大多数项目来说,这份合约最初将被作为第一次迁移部署,而且不需要再次更新。你将在第一次使用truffle init创建一个新项目时默认的接收这个合约。

文件名称:contracts/Migrations.sol

pragma solidity ^0.4.8;

contract Migrations {
  address public owner;

  // A function with the signature `last_completed_migration()`, returning a uint, is required.
  // 一个带有`last_completed_migration()`签名的函数,返回一个unit,是必须的
  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);
  }
}

为了使用Migrations特性的优势,你必须在第一次迁移中部署这份合约。这样做以后,再创建下面的迁移。

文件名称:migrations/1_initial_migration.js

var Migrations = artifacts.require("Migrations");

module.exports = function(deployer) {
  // Deploy the Migrations contract as our only task
  deployer.deploy(Migrations);
};

从这里开始,你可以通过使用递增编号的前缀来创建新的迁移来部署其它的合约,执行进一步的部署步骤。

DEPLOYER

你的迁移文件将使用deployer来分段部署任务。同样的,你可同步的编写部署任务,它们会按正确的顺序去执行。

// Stage deploying A before B
// 在部署B之前部署A
deployer.deploy(A);
deployer.deploy(B);

或者,deployer中的每一个函数都可以作为一个承诺,对于需要依赖前一个任务执行的部署任务进行排队:

// Deploy A, then deploy B, passing in A's newly deployed address
deployer.deploy(A).then(function() {
  return deployer.deploy(B, A.address);
});

如果你发现语法更加的清晰,就可以将你的部署作为一个单一的单一的承诺链来编写。deployer的API会在下面的讨论。

NETWORK CONSIDERATIONS

可以根据部署的网络来有条件的运行部署步骤。这是一个高级特性,在继续学习之前可以先看一下Networks这部分。

有条件的进行分段部署,写下你的迁移,可以接收第二个参数,叫network。例如:

module.exports = function(deployer, network) {
  if (network == "live") {
    // Do something specific to the network named "live".
  } else {
    // Perform a different step otherwise.
  }
}

AVAILABLE ACCOUNTS

Migrations也通过以太坊客户端和web3提供程序向你提供了一组账号,以便你在部署期间使用。这是一个从web3.eth.getAccounts()这里获取的准确的账号列表。

module.exports = function(deployer, network, accounts) {
  // Use the accounts within your migrations.
}

DEPLOYER API

deployer包含了很多的函数来简化你的迁移。

DEPLOYER.DEPLOY(CONTRACT, ARGS…, OPTIONS)

部署特殊的合约,由合约对象来指定,并带有可选的构造参数函数。这对单一合约是非常有用的,例如:在你的dapp中只存在一个合约实例。这将在部署之后设置合约地址(Contract.address等同于新的部署地址),它将覆盖任何一个之前存储的地址。

你可能感兴趣的:(Truffle)