创建并初始化项目
truffle init
contracts/ - 存放我们编写的合约。
migrations/ - 存放迁移部署脚本。
test/ - 存放合约测试脚本
truffle.js - Truffle的配置文件
接下来我们创建一个我们自己的合约,进入contracts目录,创建Storage.sol合约文件
在truffle中部署合约需要用到迁移脚本。下面我们进入migrations目录中为Storage合约创建一个迁移脚本
移脚本的命名规则:文件名以数字开头,一个描述性的后缀结尾。数字前缀是必须的,用于记录移植是否成功。后缀仅是为了提高可读性,以方便理解
1_storage_migrations.js
artifacts.require()
在迁移脚本开头,我们通过artifacts.require()方法告诉truffle我们将要与那个合约交互。这个方法类似于NodeJs中的require,但在这里,它返回的是一个合约抽象,我们可以在我们的迁移脚本的其余部分中使用这个合约抽象。artifacts.require()中使用的名字不是必须与合约源文件的文件名相同,相反,它应该与在合约源代码中定义的合约类的名称相同。
module .exports
在迁移脚本最后,我们通过module.exports到处一个函数,被迁移脚本导出的函数都应该接受一个 deployer 对象作为其第一个参数。deployer对象中的辅助函数在部署过程中提供了一种清晰的语法,用于部署智能合约,以及执行一些常见的任务,比如把发布后的对象保存下来供以后使用。这个 deployer 对象是部署任务的主接口,它的API在本文后面有讲解
部署器(deployer)
你的迁移脚本会使用这deployer对象来组织部署任务。deployer对象会同步执行部署任务,因此你可以按顺序编写部署任务。
// 先部署A,再部署B deployer.deploy(A); deployer.deploy(B);
另外,deployer上的每一个函数都会返回一个promise,通过promise可以把有执行顺序依赖关系的部署任务组成队列。
// 部署A, 然后部署 B, 把A 部署后的地址传给B deployer.deploy(A).then( function () { return deployer.deploy(B, A.address); });
deployer API
deployer对象包含许多方法,可以用来简化你的迁移工作。
(1) deployer.deploy(CONTRACT, ARGS…, OPTIONS)
这个API是用来部署合约的,contract参数传入需要部署的合约名字,args参数传入合约的构造函数需要的参数,options是一个可选参数它的值是{overwrite: true/false}, 如果 overwrite 被设置成 false, 那么当这个合约之前已经部署过了,这个deployer就不会再部署这个合约,这在当一个合约的依赖是由一个外部合约地址提供的情况下是有用的。
为了快速进行部署多个合约,你可以向deployer.deploy(.....)函数中传入一个或多个数组。
例子:
// 部署单个合约,不带任何构造参数 deployer.deploy(A); // 部署单个合约带有构造参数 deployer.deploy(A, arg1, arg2, ...); // 部署多个合约,一些带构造参数,一些不带构造参数. // 比写3次 `deployer.deploy()` 语句更快, 因为deployer可以把所有的合约部署都一次性打包提交 deployer.deploy([ [A, arg1, arg2, ...], B, [C, arg1] ]); // 外部依赖的例子: // // overwrite: false 表示,如果 SomeDependency 合约之前已经被部署过,那么不在重新部署,直接使用之前已部署好的地址 // 如果我们的合约要运行在自己的测试链上,或者将要运行的链上没有SomeDependency合约, // 那么把overwrite: false改成overwrite: true,表示不在检查之前SomeDependency有没有部署过,一律覆盖部署。 deployer.deploy(SomeDependency, {overwrite: false});
(2) deployer.link(LIBRARY, DESTINATIONS)
把一个已部署好的库链接到一个或多个合约里. destinations 可以传入一个合约,也可以传入一组合约. 如果 destinations中的某个合约不依赖这个库, 那deployer 的link函数就会忽略这个合约。
// 部署库LibA,然后把LibA 链接到合约B,然后部署合约B. deployer.deploy(LibA); deployer.link(LibA, B); deployer.deploy(B); //库LibA链接到多个合约 deployer.link(LibA, [B, C, D]);
(3) deployer.then(function() {...})
在迁移过程中使用它调用特定合约的函数来部署新的合约,为已部署的合约做一些初始化工作等。
例子:
vara, b; deployer.then( function() { // 部署合约A的一个新版本到网络上 returnA.new(); }).then( function(instance) { a=instance; // 获取已部署的合约B的实例 returnB.deployed(); }).then( function(instance) { b=instance; // 使用合约B的setA()方法设置A的地址的新实例. returnb.setA(a.address); });
网络相关
在执行迁移时,迁移脚本会把truffle-config.js里配置的networks传递给你,你可以在module.exports导出函数中第二个参数位置接受这个值。
文件:truffle-config.js
例子:
module.exports=function(deployer, network) {
if(network=="live") {
// 当不在"live"的网络上的时候,做一些特定的操作.
} else{
// 当在的时候,做一些其他的操作.
}
}
在Ganache中端口号与truffle-config.js里配置的networks的port一致
修改后点击右上角RESTART
出现测试账户
truffle-config.js里的solidity版本,尽量要与编写的合约文件的版本一致
之后进入test目录,进行编写测试文件
点击truffle插件,创建链接(因为已经链接,所以输入端口号时报错)
进入终端,编译truffle complie
编译后自动生成一个build目录
在Truffle中,当你运行truffle compile
命令后,它会将你的智能合约编译成字节码,并生成一个build
目录。build
目录中包含了编译后的合约的相关信息和构建文件。
contracts
目录:该目录下包含了每个智能合约的编译结果。每个合约都有一个对应的JSON文件,其中包含了合约的ABI(Application Binary Interface,应用程序二进制接口)、字节码、部署相关的信息等
部署 truffle migrate
测试 truffle test
ganache出现测试信息