升级到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/docsCommands:Compile: truffle compileMigrate: truffle migrateTest:    truffle test

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

集成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 definedat Object.<anonymous> (/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.jsReplacing Migrations...Migrations: 0xdc59c5de4e7b1dcf23f864425a704020e53666b5
Saving successful migration to network...
Saving artifacts...
Running migration: 2_deploy_contracts.jsReplacing ConvertLib...ConvertLib: 0x19cf958fede2e0f082cbcf5629f1a1344b221bf3Linking ConvertLib to MetaCoinReplacing MetaCoin...MetaCoin: 0x39073d502491f57537f999584071691d19cf5f24Replacing 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-contractcontract()方法

要在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:56contract.abi.filter(function (json) {^TypeError: Cannot read property 'filter' of undefinedat 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.<anonymous> (/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 address [4] 。

语法注意

对于新的Truffle3.0语法,需要注意的是函数调用方式要遵循调用规则 [3] 。对于一个不会改写区块链状态的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: [] }

参考资料

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

[2] : 5. 移植详解

[3] : 合约交互详解

[4] : 关于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

原文地址:https://bitshuo.com/topic/58e2552c9a87f1a331fa292b

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

  1. 语义分割yolov5 v4.0 baseline快速复现 快速跑通 图像分割 图像分类 重新训练,训练结果,测试结果,实验图片-20210227

    本机环境说明 操作系统版本 :~$ cat /etc/*release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic ...

  2. 跑通GVINS——港科大新作

    跑通GVINS--港科大新作 0.简介 1.环境 2.跑通GVINS 3.数据集 4.相关资料打包下载(不包括数据集) 6.泡泡机器人解读 港科大又一力作!vins-mono以及vins-fusion ...

  3. 跑通SpringBoot + dubbo3.0.8 + zookeeper

    跑通SpringBoot + dubbo + zookeeper 先安装并启动zookeeper 安装dubbo-admin进行dubbo监控 新建项目 创建统一接口 创建服务提供者 pom: yml ...

  4. Ros noetic opencv4.2.0 cv_bridge 冲突 适配Opencv3.2.0完成自己的USB_Camera 跑通 Orb_slam2

    前言: 本文附上使用自己的USB_Cam 跑通Orb_Slam2 算法的过程,以及解决cv_bridge冲突的方案 Orb_Slam2 需要opencv3.2.0 的cv版本 但是ubantu20.0 ...

  5. 装不了 pytorch=0.4.0? ubuntu下 基于 cuda=92 和 pytorch=1.2 配置环境跑通 CornerNet 训练和测试流程 步骤详解(包括GPU限制问题详解)

    ubuntu下跑通CornerNet的流程步骤 环境配置 写这篇博客原因? 更改conda_packagelist.txt conda下基于conda_packagelist.txt创建新环境 安装p ...

  6. 【全网唯一】全网唯一能够跑通的,跑不通你来找我~用node.js完成微信支付下单功能,且只需要一个文件wxpay.js就解决业务流程的node.js程序

    先吐为敬! 最近心血来潮研究nodejs如何完成微信支付功能,结果网上一搜索,一大堆"代码拷贝党"."留一手"."缺斤少两"."不 ...

  7. QCC512x QCC302x Earbud 跑通新建工程 —— ADK6.x 环境搭建、 自带例程

    QCC512x 和 QCC302x 都是用同一套开发环境,因此都是可以通用的.这里的方法在 QCC5124 上跑通过,这篇文章就写下 QCC3020的,刚好目前要做 3020. 一.安装环境 我在 w ...

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

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

  9. Jenkins中集成NodeJS插件问题对应

    在Jenkins的镜像中集成NodeJS插件,发现node和npm都无法执行,最终确认之后定位为libc的问题,在这篇文章中进行memo.中介来说,这个问题还可以描述为:如何在Alpine镜像中支持N ...

最新文章

  1. java中final class的一点思考
  2. SpiderData 2019年2月12日 DApp数据排行榜
  3. 字节流的 创建 写入文字 复制文件
  4. Spread for Windows Forms快速入门(2)---设置Spread表单
  5. 产品操作-查询全部产品
  6. unity3d 动态合批设置_【CocosCreator】突破动态合图
  7. 基于PHP的简单BBS论坛系统
  8. 独自去旅行你必须知道的事—勇气小姐独行攻略(内有拍照秘籍哦)
  9. 2023软件测试最难求职季,哪些测试技能更容易拿到offer?
  10. 实战 —— 生存唯一随机数
  11. wireshark编译基于openflow1.3协议开发
  12. uestudio自动补全html代码,UEStudio Suite,强大的代码编辑工具套件
  13. 仿真及设计工具下载安装方法详细说明
  14. 仪表板工具Stimulsoft Dashboards中的面板组件介绍
  15. Lanenet 车道线检测网络模型学习(论文解读+官方模型)
  16. 中心计算机集中控制方式必须方式,「1」专科-8707信息技术与信息管理
  17. 托管网站需要知道的网站优化指标有哪些
  18. 音乐制作软件的选择与学习应用
  19. 倒车与移库-汽车倒车移库技巧
  20. 数据结构-链表及相关算法

热门文章

  1. 线程同步-AutoResetEvent
  2. 手机web——自适应网页设计(html/css控制) - 51CTO.COM
  3. ChartDirector资料小结
  4. 掌握 Ajax,第 8 部分: 在请求和响应中使用 XML
  5. Python学习笔记:高级特性
  6. Python基础入门一(2)
  7. [云炬创业基础笔记] 第四章测试15
  8. [云炬创业基础笔记] 第四章测试13
  9. 系列笔记 | 深度学习连载(4):优化技巧(上)
  10. Adaboost(自适应提升树)算法原理