truffle的调用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 ↩
- 移植详解 ↩
关于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 ↩
合约交互详解 ↩
truffle的调用nodeJs的问题的更多相关文章
- 如何在.Net Core调用NodeJs
概述 Microsoft.AspNetCore.NodeServices库 实例 新建aspnet core站点 添加nuget包 建立node环境,此处示例用于扫描wifi环境 建立nodejs的程 ...
- 区块链技术(一):Truffle开发入门
以太坊是区块链开发领域最好的编程平台,而truffle是以太坊(Ethereum)最受欢迎的一个开发框架,这是我们第一篇区块链技术文章介绍truffle的原因,实战是最重要的事情,这篇文章不讲原理,只 ...
- truffle Dapp 搭建
安装truffle $ npm install -g truffle 依赖环境 NodeJS 访问https://nodejs.org 官方网站下载安装 系统:Windows, Linux or Ma ...
- 【转】前端工程筹建NodeJs+gulp+bower
转自:http://www.myexception.cn/javascript/1781968.html npm nodejs 安装过程中会自动安装npm,nodejs安装程序会在环境变量中添加两个变 ...
- 前端MVC学习总结(四)——NodeJS+MongoDB+AngularJS+Bootstrap书店示例
这章的目的是为了把前面所学习的内容整合一下,这个示例完成一个简单图书管理模块,因为中间需要使用到Bootstrap这里先介绍Bootstrap. 示例名称:天狗书店 功能:完成前后端分离的图书管理功能 ...
- 前端工程筹建NodeJs+gulp+bower
1.安装nodejs nodejs 官网下载安装文件 安装完成之后,在命令窗口执行,(显示nodejs版本) 和(显示npm版本)可以使用这两个命令查看是否安装成功: node -v npm -v 2 ...
- 前端工程搭建NodeJs+gulp+bower
需要node.npm的事先安装!! 1.nodejs安装程序会在环境变量中添加两个变量: 系统环境变量中:path 增加C:\Program Files\nodejs\ 因为在该目下存在node.ex ...
- windows命令行编码与nodejs编码格式冲突的解决方式
今天写一个工具,由于大部分人使用的机器都是windows,在和nodejs结合的时候出问题了. win命令行的编码格式是gbk,而nodejs支持的编码只有:utf8 ascii和base64,必须让 ...
- 前端MVC学习笔记(四)——NodeJS+MongoDB+AngularJS+Bootstrap书店示例
这章的目的是为了把前面所学习的内容整合一下,这个示例完成一个简单图书管理模块,因为中间需要使用到Bootstrap这里先介绍Bootstrap. 示例名称:天狗书店 功能:完成前后端分离的图书管理功能 ...
随机推荐
- 在文件中的AngularJS模块
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- 前端html,css基础总结
0.1.css引入界面的方式: 内联式:通过标签的style属性,在标签上直接写样式. <div style="width:100px; height:100px; backgroun ...
- Openresty最佳案例 | 第3篇:Openresty的安装
转载请标明出处: http://blog.csdn.net/forezp/article/details/78616645 本文出自方志朋的博客 我的服务器为一台全新的centos 7的服务器,所以从 ...
- WebGL学习笔记(2)
根据上一篇学习笔记,理解WebGL的工作原理及基本调用代码后,可以开始研究3D顶点对象的缩放.旋转.以及对对象进行可交互(鼠标或键盘控制)的旋转或者缩放. 要理解对象的旋转/缩放需要首先学习矩阵的计算 ...
- Linux基础 ppt pptx
引言 以前写过一个讲 Linux 基础的ppt,琢磨着把它分享出来,有需要的请自取. 部分截图如下 下载地址 下载地址1
- 洛谷P1196 [NOI2002]银河英雄传说(带权并查集)
题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山压顶 ...
- 快速玩转linux(4)
websever安装配置 Nginx & Apache 并发量. Apache基本操作 解释 命令 安装 yum install httpd 启动 service httpd start 停止 ...
- css表格
今天写某个平台的前端数据展示 主要使用表格展示 正好复习总结一下css的表格 首先说说thead.tbody.tfoot <thead></thead> <tbody&g ...
- vue 中父子组件之间的交互
1,最直接的也是最简单的方法是利用props来数据传值. 子组件定义如下: props: { iconClass: { type: String, required: true }, classNam ...
- 一个好用的C# HttpHelper类
/// <summary> /// 类说明:HttpHelper类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理 /// 重要提 ...