Truffle3.0集成NodeJS并完全跑通(附详细实例,可能的错误)

时间:2022-09-20 19:37:03

Truffle3.0集成NodeJS并完全跑通(附详细实例,可能的错误)

Truffle3.0集成NodeJS并完全跑通(附详细实例,可能的错误)

升级到Truffle3.0

如果之前安装的是Truffle2.0版本,需要主动升级到Truffle3.0,两者的语法变化有点大。

由于Truffle是一个命令行工具,需要更新全局空间安装的Truffle。

$ sudo npm update -g truffle

注意需要root权限运行命令,否则可能会报错无足够的访问权限,导致升级失败。

安装成功后,可以通过版本命令查看当前的版本,如出现下述类似字样说明升级成功:

$ truffle version

Truffle v3.1.2

初始化工程

使用Truffle3.0初始化工程

我们创建一个新工程目录,并在truffle3目录内初始化Truffle框架。

$ mkdir truffle3 && cd truffle3

$ truffle init

Downloading project...

Project initialized.

Documentation: http://truffleframework.com/docs

Commands:

Compile: truffle compile

Migrate: truffle migrate

Test: truffle test

我们创建了一个新工程目录truffle3,进入到这个目录,使用truffle init命令,初始化了一个全新的Truffle 3.0的工程,工程目录如下:

truffle3-project

集成NodeJS

truffle console命令会默认集成web3,合约抽象层。如果想要在自已的NodeJS环境使用Truffle合约,就要手动集成这两个模块。在集成前,我们需要创建工程的npm包管理环境,首先进入truffle3工程目录,使用npm init来初始化工程的npm包管理环境:

$ npm init

This utility will walk you through creating a package.json file.

It only covers the most common items, and tries to guess sensible defaults.

See npm help json for definitive documentation on these fields

and exactly what they do.

Use npm install <pkg> --save afterwards to install a package and

save it as a dependency in the package.json file.

Press ^C at any time to quit.

name: (truffle3) TruffleForTest

Sorry, name can no longer contain capital letters.

name: (truffle3) truffle3

version: (1.0.0) 1.0.0

description: This is a sample project for integrate truffle 3.0 with nodejs.

entry point: (truffle.js) main.js

test command: truffle3

git repository:main.js

keywords: truffle3.0

author: TryBlockchain

license: (ISC)

About to write to /Users/TryBlockchain/develop/blockchain_workspace/truffle3/package.json:

{

"name": "truffle3",

"version": "1.0.0",

"description": "This is a sample project for integrate truffle 3.0 with nodejs.",

"main": "main.js",

"directories": {

"test": "test"

},

"scripts": {

"test": "truffle3"

},

"keywords": [

"truffle3.0"

],

"author": "TryBlockchain",

"license": "ISC"

}

Is this ok? (yes) yes

如果不进行npm init初始化,就进行后续模块安装,会报如下错误:

$ npm install truffle-contract

/Users/TryBlockchain

└─┬ truffle-contract@1.1.10

├─┬ ethjs-abi@0.1.9

│ ├── bn.js@4.11.6

│ ├── js-sha3@0.5.5

│ └─┬ number-to-bn@1.7.0

│ ├── bn.js@4.11.6 deduped

│ └─┬ strip-hex-prefix@1.0.0

│ └── is-hex-prefixed@1.0.0

├── truffle-blockchain-utils@0.0.1

├─┬ truffle-contract-schema@0.0.5

│ └── crypto-js@3.1.9-1

└─┬ web3@0.16.0

└── bignumber.js@2.0.7 (git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2)

npm WARN enoent ENOENT: no such file or directory, open '/Users/TryBlockchain/package.json'

npm WARN TryBlockchain No description

npm WARN TryBlockchain No repository field.

npm WARN TryBlockchain No README data

npm WARN TryBlockchain No license field.

由于没有包管理环境,所以对package.json的包依赖写入会失败。报错npm WARN enoent ENOENT: no such file or directory, open '/Users/TryBlockchain/package.json'。要解决这个问题,需要使用npm init来初始化当前工程的包管理环境。

安装NodeJS中用到的Truffle合约抽象层运行环境

这个工具是Truffle提供的,用于在NodeJS和浏览器中集成Truffle的合约抽象运行环境1。

$ npm install truffle-contract

truffle3@1.0.0 /Users/TryBlockchain/develop/blockchain_workspace/truffle3

└─┬ truffle-contract@1.1.10

├─┬ ethjs-abi@0.1.9

│ ├── bn.js@4.11.6

│ ├── js-sha3@0.5.5

│ └─┬ number-to-bn@1.7.0

│ ├── bn.js@4.11.6 deduped

│ └─┬ strip-hex-prefix@1.0.0

│ └── is-hex-prefixed@1.0.0

├─┬ truffle-blockchain-utils@0.0.1

│ └─┬ web3@0.18.2

│ ├── bignumber.js@2.0.7 (git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2)

│ ├── crypto-js@3.1.8 deduped

│ ├── utf8@2.1.2 deduped

│ ├── xhr2@0.1.4

│ └── xmlhttprequest@1.8.0 deduped

├─┬ truffle-contract-schema@0.0.5

│ └── crypto-js@3.1.9-1

└─┬ web3@0.16.0

├── bignumber.js@2.0.7 (git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2)

├── crypto-js@3.1.8

├── utf8@2.1.2

└── xmlhttprequest@1.8.0

安装NodeJS中用到的Truffle运行时需要的web3环境

$ npm install web3

  • bignumber.js@2.0.7 node_modules/web3/node_modules/bignumber.js

    truffle3@1.0.0 /Users/TryBlockchain/develop/blockchain_workspace/truffle3

    └── web3@0.18.2

    我们使用npm install web3即可安装web3模块。如果没有集成web3环境,就跑相关的代码,可能会报下述错:

$ node main.js

/Users/TryBlockchain/develop/blockchain_workspace/truffle3/main/main.js:4

var provider = new Web3.providers.HttpProvider("http://localhost:8545");

^

ReferenceError: Web3 is not defined

at Object. (/Users/TryBlockchain/develop/blockchain_workspace/truffle3/main/main.js:4:20)

at Module._compile (module.js:571:32)

at Object.Module._extensions..js (module.js:580:10)

at Module.load (module.js:488:32)

at tryModuleLoad (module.js:447:12)

at Function.Module._load (module.js:439:3)

at Module.runMain (module.js:605:10)

at run (bootstrap_NodeJS:420:7)

at startup (bootstrap_NodeJS:139:9)

at bootstrap_NodeJS:535:3

创建自己的合约文件

新增加测试合约

在truffle3/contracts目录下创建测试合约文件Test.sol

pragma solidity ^0.4.4;

contract Test{

function f() returns (string){

return "method f()";

}

function g() returns (string){

return "method g()";

}

}

在上述代码中,我们提供两个函数,f()和g()。分别返回用于说明它们是哪个函数的返回结果的字符串说明。

增加deploy配置

修改migrations/2_deploy_contracts.js为如下:

var ConvertLib = artifacts.require("./ConvertLib.sol");

var MetaCoin = artifacts.require("./MetaCoin.sol");

var Test = artifacts.require("./Test.sol");

module.exports = function(deployer) {

deployer.deploy(ConvertLib);

deployer.link(ConvertLib, MetaCoin);

deployer.deploy(MetaCoin);

deployer.deploy(Test);

};

上述代码主要增加两行,一行为var Test = artifacts.require("./Test.sol");声明一个新的合约文件实例并命名为Test;增加的另一行内容deployer.deploy(Test);用于将Test进行部署。

编译合约

下面我们使用truffle migrate --reset来强制重编译并发布所有合约,由于合约移植是懒编译的,如果发现已经发布过,且发布的版本号没有变化就不会再发布,所以使用--reset。请务必弄清楚为何使用--reset再使用这个命令2。运行truffle migrate前,需要确认节点处于运行状态。

$ truffle migrate --reset

Using network 'development'.

Running migration: 1_initial_migration.js

Replacing Migrations...

Migrations: 0xdc59c5de4e7b1dcf23f864425a704020e53666b5

Saving successful migration to network...

Saving artifacts...

Running migration: 2_deploy_contracts.js

Replacing ConvertLib...

ConvertLib: 0x19cf958fede2e0f082cbcf5629f1a1344b221bf3

Linking ConvertLib to MetaCoin

Replacing MetaCoin...

MetaCoin: 0x39073d502491f57537f999584071691d19cf5f24

Replacing Test...

Test: 0x8ca770415902e5a64ef53062b5ba85626c3dd5dc

Saving successful migration to network...

Saving artifacts...

使用NodeJS集成Truffle3.0代码完整DEMO

var Web3 = require('web3');

var contract = require("truffle-contract");

var provider = new Web3.providers.HttpProvider("http://localhost:8545");

//使用truffle-contract包的contract()方法

//请务必使用你自己编译的.json文件内容

var Test = contract({

"contract_name": "Test",

"abi": [

{

"constant": false,

"inputs": [],

"name": "f",

"outputs": [

{

"name": "",

"type": "string"

}

],

"payable": false,

"type": "function"

},

{

"constant": false,

"inputs": [],

"name": "g",

"outputs": [

{

"name": "",

"type": "string"

}

],

"payable": false,

"type": "function"

}

],

"unlinked_binary": "0x606060405234610000575b6101ff806100196000396000f300606060405263ffffffff60e060020a60003504166326121ff0811461002f578063e2179b8e146100bc575b610000565b346100005761003c610149565b604080516020808252835181830152835191928392908301918501908083838215610082575b80518252602083111561008257601f199092019160209182019101610062565b505050905090810190601f1680156100ae5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b346100005761003c61018e565b604080516020808252835181830152835191928392908301918501908083838215610082575b80518252602083111561008257601f199092019160209182019101610062565b505050905090810190601f1680156100ae5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b604080516020818101835260009091528151808301909252600a82527f6d6574686f642066282900000000000000000000000000000000000000000000908201525b90565b604080516020818101835260009091528151808301909252600a82527f6d6574686f642067282900000000000000000000000000000000000000000000908201525b905600a165627a7a72305820c238bd4de6aa330fcc88946b9948bc265c7ac1408dc5c8b7ee6e648413ae540f0029",

"networks": {

"1489826524891": {

"events": {},

"links": {},

"address": "0x9db90af99faa32ed14dccfb19326e917efac456b",

"updated_at": 1489827968151

}

},

"schema_version": "0.0.5",

"updated_at": 1489827968151

});

Test.setProvider(provider);

//没有默认地址,会报错

//UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Error: invalid address

//务必设置为自己的钱包地址,如果不知道,查看自己的客户端启动时,观察打印到控制台的地址

Test.defaults({

from : "0x299127d72e28cb92d09f856aaedeb139d1e7e74a"

});

var instance;

Test.deployed().then(function(contractInstance) {

instance = contractInstance;

return instance.f.call();

}).then(function(result){

console.log(result);

return instance.g.call();

}).then(function(result){

console.log(result);

});

集成示例详解

引入web3

要在NodeJS中使用Truffle,我们要先引入web3。

var Web3 = require('web3');

var provider = new Web3.providers.HttpProvider("http://localhost:8545");

//省略了无关代码

//合约初始化

var Test = contract(/合约JSON/);

//设置连接

Test.setProvider(provider);

在上例中,我们先通过var Web3 = require('web3');引入依赖,并初始化一个实例Web3,并为实例设置了HttpProvider。

truffle-contract的contract()方法

要在NodeJS初始化Truffle编译好的合约,要使用contract()方法。请将Truffle3.0编译后的.json文件,一般在build/contracts/Test.json。请将此文件的内容放入contract()的括号内。

var contract = require("truffle-contract");

//请使用使用Truffle3.0编译的.json文件内容

var Test = contract(/参数是JSON对象,放入Truffle3.0生成的.json文件内容/)

然后使用.deployed()或at(/某个地址/)来进行调用1。

contract()引入的JSON定义有问题

如果引入的JSON数据有问题,你可能会看到下面的错误:

$ node main.js

/Users/TryBlockchain/develop/blockchain_workspace/truffle3/node_modules/truffle-contract/node_modules/web3/lib/web3/contract.js:56

contract.abi.filter(function (json) {

            ^

TypeError: Cannot read property 'filter' of undefined

at addFunctionsToContract (/Users/TryBlockchain/develop/blockchain_workspace/truffle3/node_modules/truffle-contract/node_modules/web3/li

b/web3/contract.js:56:17)

at ContractFactory.at (/Users/TryBlockchain/develop/blockchain_workspace/truffle3/node_modules/truffle-contract/node_modules/web3/lib/we

b3/contract.js:255:5)

at TruffleContract.Contract (/Users/TryBlockchain/develop/blockchain_workspace/truffle3/node_modules/truffle-contract/contract.js:257:33

)

at new TruffleContract (/Users/TryBlockchain/develop/blockchain_workspace/truffle3/node_modules/truffle-contract/contract.js:572:25)

at Function.at (/Users/TryBlockchain/develop/blockchain_workspace/truffle3/node_modules/truffle-contract/contract.js:390:22)

at Object. (/Users/TryBlockchain/develop/blockchain_workspace/truffle3/main/main.js:54:6)

at Module._compile (module.js:571:32)

at Object.Module._extensions..js (module.js:580:10)

at Module.load (module.js:488:32)

at tryModuleLoad (module.js:447:12)

如果你出现了上述报错,请再次确认是否原封不动的把合约编译后的.json文件的内容,复制进contract()的括号内的,不要加任何东西,因为.json文件内就是一个JSON对象。

默认帐户地址

truffle-contract框架默认没有读取coinbase的默认地址,所以需要按如下方式主动设置:

//没有默认地址,会报错

//UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Error: invalid address

Test.defaults({

from : "0x299127d72e28cb92d09f856aaedeb139d1e7e74a"

});

否则会报错UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Error: invalid address3。

语法注意

对于新的Truffle3.0语法,需要注意的是函数调用方式要遵循调用规则4。对于一个不会改写区块链状态的f()函数,使用instance.f.call();;而对于一个会改写区块链状态的函数f(),使用instance.f()。底层在实现调用上,会使用不同gas计算方式。

var instance;

Test.deployed().then(function(contractInstance) {

instance = contractInstance;

return instance.f.call();

}).then(function(result){

console.log(result);

return instance.g.call();

}).then(function(result){

console.log(result);

});

如果对于一个不会改写状态f(),使用instance.f()会返回对应的交易状态结果。

$ node main.js

{ tx: '0x2ac645310278d971e3911e8f880947105f582aa4eab3d3d66d14c95333391ac9',

receipt:

{ transactionHash: '0x2ac645310278d971e3911e8f880947105f582aa4eab3d3d66d14c95333391ac9',

transactionIndex: 0,

blockHash: '0x69a6788032c7bef12d6d51bc045548fa9edb0665bb0fbcf9cf55d30f9744cd61',

blockNumber: 29,

gasUsed: 21803,

cumulativeGasUsed: 21803,

contractAddress: null,

logs: [] },

logs: [] }

{ tx: '0x65aa2c4da73ef5a17221c26e74b9b329bdc353856564f8d1f49c07f6dcd055ea',

receipt:

{ transactionHash: '0x65aa2c4da73ef5a17221c26e74b9b329bdc353856564f8d1f49c07f6dcd055ea',

transactionIndex: 0,

blockHash: '0x837ec6a3df2cc4d9a8ccf8d77c14b88a13b0053a5149a74c1a984fe88a70eaa8',

blockNumber: 30,

gasUsed: 21825,

cumulativeGasUsed: 21825,

contractAddress: null,

logs: [] },

logs: [] }

Truffle contract的github地址及文档: https://github.com/trufflesuite/truffle-contract

  1. 移植详解 ↩

关于invalid address的报错,http://ethereum.stackexchange.com/questions/12957/truffle-invalid-address 报这个错的可能情况: http://www.bullraider.com/ethereum/tutorials/342-understanding-invalid-address-error-in-dapps-or-geth-console

合约交互详解 ↩

感谢您的支持

Truffle3.0集成NodeJS并完全跑通(附详细实例,可能的错误)的更多相关文章

  1. 简介及环境搭建跑通Hello

    简介及环境搭建跑通Hello Spring Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.是为了解决企业应用程序开 ...

  2. *测试框架Jest指南:跑通一个完美的程序,就是教出一群像样的学生

    facebook三大项目:yarn jest metro,有横扫宇宙之势. 而jest项目的宗旨为:减少测试一个项目所花费的时间成本和认知成本. --其实,它在让你当一个好老师. jest文档非常简略 ...

  3. ASP&period;NET MVC5&plus;EF6&plus;EasyUI 后台管理系统(21)-权限管理系统-跑通整个系统

    系列目录 这一节我们来跑通整个系统,验证的流程,通过AOP切入方式,在访问方法之前,执行一个验证机制来判断是否有操作权限(如:增删改等) 原理:通过MVC自带筛选器,在筛选器分解路由的Action和c ...

  4. 构建ASP&period;NET MVC4&plus;EF5&plus;EasyUI&plus;Unity2&period;x注入的后台管理系统(21)-权限管理系统-跑通整个系统

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(21)-权限管理系统-跑通整个系统 这一节我们来跑通整个系统,验证的流程,通过AOP切入方式,在访问方法之 ...

  5. rails跑通第一个demo

    rails -h 查看帮助 Usage: rails new APP_PATH [options] Options: -r, [--ruby=PATH] # Path to the Ruby bina ...

  6. ubuntu12&period;04&plus;fuerte 下跑通lsd-slam——数据集

    lsd-slam(下载链接:https://github.com/tum-vision/lsd_slam)提供了两种方法,一种是用数据集(下载地址http://vision.in.tum.de/lsd ...

  7. CocoStuff—基于Deeplab训练数据的标定工具【二、用已提供的标注数据跑通项目】

    一.说明 本文为系列博客第二篇,主要讲述笔者在使用该团队提供已经标注好的COCO数据集进行训练的过程. 由于在windows中编译Caffe和Deeplab特别的麻烦,笔者并没有去探索,后续可能会去尝 ...

  8. 师傅领进门之6步教你跑通一个AI程序!

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由云计算基础发表于云+社区专栏 源码下载地址请点击原文查看. 初学机器学习,写篇文章mark一下,希望能为将入坑者解点惑.本文介绍一些机 ...

  9. 网易短信接口集成 nodejs 版

    /* name:网易短信服务集成nodejs版: author:zeq time:20180607 test: // checkValidCode('157****6954','284561').th ...

随机推荐

  1. cve-2015-5199漏洞分析

    继续之前hackteam的flash漏洞,这次的对象为cve-2015-5199,遂做一下记录. 首先,在该exp中TryExpl函数为漏洞的触发函数,该函数也为本次调试的主要对象,函数的开始首先创建 ...

  2. Android深度探索HAL与驱动开发 第三章 Git入门

    Git功能十分复杂,简单来说它使你的开发更为快捷和可控,尤其是在开源项目上展现的友好的交互和回馈. 熟悉一些git指令操作对开发者的帮助可以避免开发者受到一些外在因素打断开发进度,甚至延误项目的che ...

  3. bwa用法

    一 建立索引 比对之前,需要对fasta文件构建FM-index索引:bwa index -a bwtsw hg19.fasta 生成 hg19.fasta.amb.hg19.fasta.ann.hg ...

  4. C&num;调用C&plus;&plus; DLL 文件

    说来惭愧,都注册一年多了,却没有发表过一篇正式的博文,中间很多学习的过程也没有记录下来.如今到了一个新的环境,也有了学习的机会,一定要把每天的收获记录一下. 要做的东西需要引用C++编写的DLL,刚开 ...

  5. POJ1191 棋盘分割(DP)

    化简一下那个方差得到:$$\sqrt\frac{(\Sigma_{i=1}^nx_i)-n\bar x^2}{n}$$ 除了$\Sigma_{i=1}^nx_i$这部分未知,其余已知,而那部分显然越大 ...

  6. 一个考察for循环题 讨论一下

    一道Java程序题,主要是考察for循环如下所示: public class Test { static boolean fun(char c) { System.out.print(c); retu ...

  7. poj 2367 Genealogical tree (拓扑排序)

    火星人的血缘关系很奇怪,一个人可以有很多父亲,当然一个人也可以有很多孩子.有些时候分不清辈分会产生一些尴尬.所以写个程序来让n个人排序,长辈排在晚辈前面. 输入:N 代表n个人 1~n 接下来n行 第 ...

  8. SSH整合缓存之-Memcached作为hibernate的二级缓存

    Hibernate本身不提供二级缓存,所以需要使用第三方插件来作为二级缓存:本次使用memcached作为Hiberbate的二级缓存:添加步骤如下: 一.需要安装memcached服务端 1. 下载 ...

  9. JavaScript异步编程

    前言 如果你有志于成为一个优秀的前端工程师,或是想要深入学习JavaScript,异步编程是必不可少的一个知识点,这也是区分初级,中级或高级前端的依据之一.如果你对异步编程没有太清晰的概念,那么我建议 ...

  10. hackrf入门

    http://www.hackrf.net/hackrf%E4%B8%8Egnuradio%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/