以太坊学习笔记(七)——Truffle集成Nodejs

论坛 期权论坛 区块链     
古川不爱笑   2018-11-20 23:35   6076   0
            这篇文章的内容紧接着上章的内容,上一篇讲了
  1. truffle
复制代码
合约部署的基本操作,文章最后讲了通过
  1. console
复制代码
来调用部署成功的合约中的方法,之所以
  1. truffle console
复制代码
能够直接调用合约中的方式,是因为
  1. truffle console
复制代码
默认集成了
  1. web3
复制代码
。如果想在
  1. NodeJS
复制代码
环境使用
  1. Truffle
复制代码
合约,就要手动集成这两个模块。
集成NodeJS
1.首先需要安装
  1. npm
复制代码
包管理器,这里就不讲安装过程,如果已经安装过最好把
  1. npm
复制代码
更新到最新版本,不然在后面的操作中可能会报错,以下就是我在操作过程中遇到的一个错误。
  1. var BigNumber = (new Web3()).toBigNumber(0).constructor;                               ^TypeError: (intermediate value).toBigNumber is not a function
复制代码
2.创建工程的
  1. npm
复制代码
包管理器,这里我们还是以上一个项目为例,进入项目所在的目录,使用
  1. npm init
复制代码
来初始化工程的
  1. npm
复制代码
包管理环境。
  1. $ npm initThis 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 fieldsand exactly what they do.Use `npm install ` afterwards to install a package andsave it as a dependency in the package.json file.Press ^C at any time to quit.package name: (truffletest) truffletest //回车或输入括号内的包名version: (1.0.0) 1.0.0 //同上license: (ISC) //同上About to write to /Users/cyril/Desktop/truffleTest/package.json:{  "name": "truffletest",  "version": "1.0.0",  "description": "truffle with nodejs",  "main": "main.js",  "directories": {    "test": "test"  },  "scripts": {    "test": "truffletest"  },  "repository": {    "type": "git",    "url": "main.js"  },  "keywords": [    "truffletest"  ],  "author": "cyril",  "license": "ISC",  "dependencies": {    "truffle-contract": "^3.0.6",    "web3": "^1.0.0-beta2"  }}Is this OK? (yes) yes //同前面的操作
复制代码
这个时候项目会生成
  1. package.json
复制代码
  1. package-lock.json
复制代码
同时会添加
  1. node-modules
复制代码
相关的库依赖,生成的这些文件没必要去修改
项目结构如下:



安装
  1. NodeJS
复制代码
中用到的
  1. Truffle
复制代码
合约抽象层运行环境
  1. truffle-contract
复制代码
  1. Truffle
复制代码
提供的,用于在
  1. NodeJS
复制代码
和浏览器中集成
  1. Truffle
复制代码
的合约抽象运行环境。
  1. $ npm install truffle-contractnpm notice created a lockfile as package-lock.json. You should commit this file.+ truffle-contract@3.0.6added 24 packages from 18 contributors and audited 25 packages in 13.15sfound 0 vulnerabilities
复制代码
安装
  1. NodeJS
复制代码
中用到的
  1. Truffle
复制代码
运行时需要的
  1. web3
复制代码
环境
  1. $ npm install web3npm WARN deprecated web3@1.0.0-beta2: This version has faulty dependecy links.+ web3@1.0.0-beta2added 1 package from 1 contributor and audited 26 packages in 1.752sfound 0 vulnerabilities
复制代码
测试合约
这里就用前面的
  1. Test.sol
复制代码
  1. Greeter.sol
复制代码
,部署流程就不讲了,在项目根目录下创建
  1. main.js
复制代码
,内容大体结构如下
  1. //引入依赖,并初始化一个实例Web3var Web3 = require('web3');var provider = new Web3.providers.HttpProvider("http://localhost:8545");//省略了无关代码//合约初始化var Test = contract(/*合约JSON*/);//合约的元数据 //设置连接Test.setProvider(provider);//设置默认地址Test.defaults({  from : "0x299127d72e28cb92d09f856aaedeb139d1e7e74a"});//函数调用//TODO
复制代码
我们拿
  1. Test
复制代码
举个例子:
  1. 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({    "contractName": "Test",    "abi": [        {            "constant": true,            "inputs": [],            "name": "f",            "outputs": [                {                    "name": "",                    "type": "string"                }            ],            "payable": false,            "stateMutability": "pure",            "type": "function"        },        {            "constant": true,            "inputs": [],            "name": "g",            "outputs": [                {                    "name": "",                    "type": "string"                }            ],            "payable": false,            "stateMutability": "pure",            "type": "function"        }    ],    "networks": {        "1536568575803": {            "events": {},            "links": {},            "address": "0x57fec0a6d60ce7a133bbc6f7ac64f99a7b97425f",            "transactionHash": "0x84463c7b8bce644a4df200ed1afdb3714514696cb32eef443854ca2dc2e56a70"        },        "1536655141628": {            "events": {},            "links": {},            "address": "0x03873f72987988a143d514f43a6c548fe8d252b9",            "transactionHash": "0xd3b7577fb5aae6a5950c0b2e04e1211f26ce487dda065d264bf6c61e2b453983"        }    },    "schemaVersion": "2.0.1",    "updatedAt": "2018-09-11T09:04:16.743Z"});Test.setProvider(provider);//随便从testrpc提供的地址中拷贝一个Test.defaults({    from: "0x807b0d9ffc27ecdc481bd1fc84fd3d4fb054c324" });//调用合约方法var instance;Test.deployed().then(function (func) {    instance = func;    return instance.f.call();}).then(function (value) {    console.log(value);    return instance.g.call();}).then(function (value) {    console.log(value);});
复制代码
注意:
1.最好原封不动的把json文件的内容拷贝过来,为了节约篇幅,我就只粘贴了部分,虽然不影响正常测试,但可能遇到下面的错误:
  1. node_modules/truffle->contract/node_modules/web3/lib/web3/contract.js:56 contract.abi.filter(function (json) {               ^TypeError: Cannot read property 'filter' of undefined
复制代码
2.必须设置默认账户,
  1. truffle-contract
复制代码
框架默认没有读取
  1. coinbase
复制代码
的默认地址,所以需要主动设置,不然会报如下错误:
  1. (node:26922) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: invalid address
复制代码
运行
  1. main.js
复制代码

运行
  1. main.js
复制代码
,然后报了如下错:
  1. $ node main.js module.js:487    throw err;    ^Error: Cannot find module 'web3-requestManager'
复制代码
这个问题就是我开篇说的一定要注意运行环境的版本,这个问题是因为
  1. package.json
复制代码
中依赖的
  1. web3
复制代码
版本是
  1. ^1.0.0-beta2
复制代码
,这个问题可以通过安装依赖解决
  1. $ npm install ethereum/web3.js+ web3@0.20.7added 4 packages from 4 contributors, updated 1 package and audited 32 packages in 58.834sfound 0 vulnerabilities
复制代码
再次查看
  1. package.json
复制代码
中的
  1. web3
复制代码
版本已经变成了
  1. github:ethereum/web3.js
复制代码
,然后再次运行
  1. main.js
复制代码
  1. $ node main.js method f()method g()
复制代码
输出结果跟上篇内容的一样,也在预料之中。不论是合约中的
  1. f()
复制代码
方法还是
  1. g()
复制代码
方法,都不会改写区块链状态,使用instance.f.call()调用;而对于一个会改写区块链状态的函数
  1. f()
复制代码
,使用
  1. instance.f()
复制代码
调用,我们在以
  1. Greeter.sol
复制代码
为例来演示一下
下面的代码依然是放在
  1. main.js
复制代码
  1. var Web3 = require('web3');var contract = require("truffle-contract");var provider = new Web3.providers.HttpProvider("http://localhost:8545");var Greeter = contract({    "contractName": "Greeter",    "abi": [        {            "inputs": [],            "payable": false,            "stateMutability": "nonpayable",            "type": "constructor"        },        {            "constant": true,            "inputs": [],            "name": "greet",            "outputs": [                {                    "name": "",                    "type": "string"                }            ],            "payable": false,            "stateMutability": "view",            "type": "function"        },        {            "constant": false,            "inputs": [                {                    "name": "_newgreeting",                    "type": "string"                }            ],            "name": "setGreeting",            "outputs": [],            "payable": false,            "stateMutability": "nonpayable",            "type": "function"        },        {            "constant": false,            "inputs": [],            "name": "kill",            "outputs": [],            "payable": false,            "stateMutability": "nonpayable",            "type": "function"        }    ],    "networks": {        "1536568575803": {            "events": {},            "links": {},            "address": "0x4cf91392df7740176d74f63faf9991ec838a6473",            "transactionHash": "0x33b9776384f25342d51799970744b44dcfedf55a36093d55a72c5323dcbc8cf5"        },        "1536655141628": {            "events": {},            "links": {},            "address": "0x2eb0113712145ffb42889c9421a6881e864ff2b4",            "transactionHash": "0x748948df55b1597223d54cc6184d7a43ac47a04a559fafd9eb49e3c02c1abe98"        }    },    "schemaVersion": "2.0.1",    "updatedAt": "2018-09-11T09:04:16.744Z"});Greeter.setProvider(provider);Greeter.defaults({    from: "0xd10e318f0ef3e74c6e75e0827b840b2d00a49af5"});var ins;Greeter.deployed().then(function (value) {    ins = value;    return ins.setGreeting("hello");}).then(function (value) {    console.log(value);    return ins.greet.call();}).then(function (value) {    console.log(value);});
复制代码
运行
  1. $ node main.js { tx: '0x887d1043feb6f1e65bd90c71840b6b8fe8b2eea6ac19ad82dbd3c61c8eccae4c',  receipt:    { transactionHash: '0x887d1043feb6f1e65bd90c71840b6b8fe8b2eea6ac19ad82dbd3c61c8eccae4c',     transactionIndex: 0,     blockHash: '0x323b5d22dbea9f4d7c1e70da5a0dc2b4b96f453afd6a3ae80c989470804c6562',     blockNumber: 17,     gasUsed: 33090,     cumulativeGasUsed: 33090,     contractAddress: null,     logs: [],     status: 1 },  logs: [] }//greet()方法输出内容hello
复制代码
因为
  1. ins.setGreeting ()
复制代码
方法会改变区块链状态,所以需要消耗
  1. gas
复制代码
,同时在调用的时候返回对应的交易状态结果。
         
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:50
帖子:9
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP