Solidity的Truffle框架实战(手把手)
前置工作:
安装Solidity的开发框架Truffle,参见:Truffle框架安装
安装开发客户端,参见:Truffle客户端
1. 创建工程目录
在你想放工程的任何位置,创建一个文件夹truffleTest,来做为你的工程根目录。
$ mkdir -p /Users/admin/develop/blockchain_workspace/truffleTest
2. 初始化框架
进入到工程根目录下(现在应该是个空目录),并执行下述命令。
cd/Users/admin/develop/blockchainworkspace/truffleTest c d / U s e r s / a d m i n / d e v e l o p / b l o c k c h a i n w o r k s p a c e / t r u f f l e T e s t truffle init
正确执行后,我们将得到下面这样的目录结构:
目录结构简单说明如下:
app/ - 你的应用文件运行的默认目录。这里面包括推荐的javascript文件和css样式文件目录,但你可以完全决定如何使用这些目录。
contract/ - Truffle默认的合约文件存放地址。
migrations/ - 存放发布脚本文件
test/ - 用来测试应用和合约的测试文件
truffle.js - Truffle的配置文件
相关详细说明,详见:初始化Truffle
3.放入自己的合约
删除./contract目录下的自带demo合约,切记不要删除./contract/Migrations.sol合约,它是Truffle用来帮助部署的。
$ cd /Users/admin/develop/blockchain_workspace/truffleTest/contracts
$ rm ConvertLib.sol MetaCoin.sol
在./contract目录下创建一个自己的合约文件Greeter.sol。
pragma solidity ^0.4.0;
contract Greeter
{
address creator;
string greeting;
function Greeter(string _greeting) public
{
creator = msg.sender;
greeting = _greeting;
}
function greet() constant returns (string)
{
return greeting;
}
function setGreeting(string _newgreeting)
{
greeting = _newgreeting;
}
/**********
Standard kill() function to recover funds
**********/
function kill()
{
if (msg.sender == creator)
suicide(creator); // kills this contract and sends remaining funds back to creator
}
}
代码来自fiveDogIt的一段入门代码05_greeter.sol。
module.exports = function(deployer) {
deployer.deploy(ConvertLib);
deployer.autolink();
deployer.deploy(MetaCoin);
};
修改为:
module.exports = function(deployer) {
deployer.deploy(Greeter);
};
目的是去掉原有自带的Demo部署流程,修改为要部署的合约。修改完后,记得保存,不然发布时会报错,找不到相关合约。详细发布流程参考:部署(migrate)
$ truffle compile
Compiling Greeter.sol…
Writing artifacts to ./build/contracts
6. 启动你的客户端
启动之前安装好的EthereumJS RPC客户端。
$ testrpc
EthereumJS TestRPC v3.0.3
Mnemonic: degree debate income mask fiber issue album diet unfair police race car
Base HD Path: m/44’/60’/0’/0/{account_index}
Listening on localhost:8545
7. 部署合约(migrate)
部署合约到网络上:
$ truffle migrate
Running migration: 2_deploy_contracts.js
Deploying Greeter…
Greeter: 0xe66038995cf64b14da96d26cbe1c96d30dec0e95
Saving successful migration to network…
Saving artifacts…
备注
如果报错出现了一些你之前编译部署过,但你已经不需要的合约,可以用truffle migrate –reset来重置部署,但可能根据情况,你需要更新移植版本号,来管理不同的版本,详见部署(migrate)。
若误删Truffle自带用来部署的合约./contracts/Migrations.sol,会出现下述报错,需要补回到./contract目录,重初始化一次得到。
$ truffle migrate
Running migration: 1_initial_migration.js
/Users/admin/develop/blockchain_workspace/truffleTest/migrations/1_initial_migration.js:2
deployer.deploy(Migrations);
^
ReferenceError: Migrations is not defined
at module.exports (/Users/admin/develop/blockchain_workspace/truffleTest/migrations/1_initial_migration.js:2:19)
at /usr/local/lib/node_modules/truffle/lib/migrate.js:109:7
at /usr/local/lib/node_modules/truffle/lib/require.js:82:7
at tryToString (fs.js:425:3)
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:412:12)
8. 看一下效果
我们使用truffle console功能在控制台与合约交互,来看下效果。
truffleconsoletruffle(default)>Greeter.deployed().setGreeting(“Helloworld!”);‘0xf6a00b4466c9ab38d7eb60dc9f8d15f5f1e500e24ea91bd9e28f6233bad08aed′truffle(default)>Greeter.deployed().greet.call();‘Helloworld!′truffle(default)>在console中为简单需要,与使用直接使用代码方式在返回结果处理上有一点点差异,参见控制台要直接使用代码与合约交互,参见合约交互控制台内,可以通过声明变量来减少输入的内容,比如varg=Greeter.deployed();g.greet();。更多详见控制台常见报错以太坊客户端连接配置不正确,或未正常启动时。 t r u f f l e c o n s o l e t r u f f l e ( d e f a u l t ) > G r e e t e r . d e p l o y e d ( ) . s e t G r e e t i n g ( “ H e l l o w o r l d ! ” ) ; ‘ 0 x f 6 a 00 b 4466 c 9 a b 38 d 7 e b 60 d c 9 f 8 d 15 f 5 f 1 e 500 e 24 e a 91 b d 9 e 28 f 6233 b a d 08 a e d ′ t r u f f l e ( d e f a u l t ) > G r e e t e r . d e p l o y e d ( ) . g r e e t . c a l l ( ) ; ‘ H e l l o w o r l d ! ′ t r u f f l e ( d e f a u l t ) > 在 c o n s o l e 中 为 简 单 需 要 , 与 使 用 直 接 使 用 代 码 方 式 在 返 回 结 果 处 理 上 有 一 点 点 差 异 , 参 见 控 制 台 要 直 接 使 用 代 码 与 合 约 交 互 , 参 见 合 约 交 互 控 制 台 内 , 可 以 通 过 声 明 变 量 来 减 少 输 入 的 内 容 , 比 如 v a r g = G r e e t e r . d e p l o y e d ( ) ; g . g r e e t ( ) ; 。 更 多 详 见 控 制 台 常 见 报 错 以 太 坊 客 户 端 连 接 配 置 不 正 确 , 或 未 正 常 启 动 时 。 truffle console
/usr/local/lib/node_modules/truffle/lib/repl.js:25
if (err) return done(err);
^
ReferenceError: done is not defined
at /usr/local/lib/node_modules/truffle/lib/repl.js:25:21
at /usr/local/lib/node_modules/truffle/lib/repl.js:57:21
at /usr/local/lib/node_modules/truffle/lib/contracts.js:46:25
at /usr/local/lib/node_modules/truffle/node_modules/web3/lib/web3/property.js:119:13
at /usr/local/lib/node_modules/truffle/node_modules/web3/lib/web3/requestmanager.js:82:20
at exports.XMLHttpRequest.request.onreadystatechange (/usr/local/lib/node_modules/truffle/node_modules/web3/lib/web3/httppro
vider.js:114:13)
at exports.XMLHttpRequest.dispatchEvent (/usr/local/lib/node_modules/truffle/node_modules/xmlhttprequest/lib/XMLHttpRequest.
js:591:25)
at setState (/usr/local/lib/node_modules/truffle/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:610:14)
at exports.XMLHttpRequest.handleError (/usr/local/lib/node_modules/truffle/node_modules/xmlhttprequest/lib/XMLHttpRequest.js
:532:5)
at ClientRequest.errorHandler (/usr/local/lib/node_modules/truffle/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:459:14)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at Socket.socketErrorListener (_http_client.js:309:9)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at emitErrorNT (net.js:1281:8)
若合约未进行部署就进行调用,可能出现下述报错:
truffle(default)> Greeter.deployed().setGreeting(“Hello world!”);
Error: Cannot find deployed address: Greeter not deployed or address not set.
at Function.Contract.deployed (/Users/admin/develop/blockchain_workspace/truffleTest/build/contracts/Greeter.sol.js:311:1
3)
at evalmachine.:1:-53
at ContextifyScript.Script.runInContext (vm.js:37:29)
at Object.exports.runInContext (vm.js:69:17)
at TruffleInterpreter.interpret (/usr/local/lib/node_modules/truffle/lib/repl.js:99:17)
at bound (domain.js:280:14)
at REPLServer.runBound [as eval] (domain.js:293:12)
at REPLServer.onLine (repl.js:513:10)
at emitOne (events.js:96:13)
at REPLServer.emit (events.js:188:7)
部署时填合约名称有误,本应该写为deployer.deploy(IntegerLiteral);,却写成了deployer.deploy(“IntegerLiteral”);
Deploying undefined…
Error encountered, bailing. Network state unknown. Review successful transactions manually.
TypeError: Cannot read property ‘apply’ of undefined
at /usr/local/lib/node_modules/truffle/lib/deployer.js:62:28
at process._tickDomainCallback (internal/process/next_tick.js:129:7)