以太坊學習筆記(七)——Truffle集成Nodejs

這篇文章的內容緊接著上章的內容粘昨,上一篇講了truffle合約部署的基本操作壹哺,文章最后講了通過console來調用部署成功的合約中的方法抄伍,之所以truffle console能夠直接調用合約中的方式,是因為truffle console默認集成了web3管宵。如果想在NodeJS環(huán)境使用Truffle合約逝慧,就要手動集成這兩個模塊昔脯。
集成NodeJS
1.首先需要安裝npm包管理器,這里就不講安裝過程笛臣,如果已經安裝過最好把npm更新到最新版本云稚,不然在后面的操作中可能會報錯,以下就是我在操作過程中遇到的一個錯誤沈堡。

 var BigNumber = (new Web3()).toBigNumber(0).constructor;
                               ^
TypeError: (intermediate value).toBigNumber is not a function

2.創(chuàng)建工程的npm包管理器静陈,這里我們還是以上一個項目為例,進入項目所在的目錄诞丽,使用npm init來初始化工程的npm包管理環(huán)境鲸拥。

$ 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>` afterwards to install a package and
save 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 //同前面的操作

這個時候項目會生成package.jsonpackage-lock.json同時會添加node-modules相關的庫依賴,生成的這些文件沒必要去修改
項目結構如下:


安裝NodeJS中用到的Truffle合約抽象層運行環(huán)境
truffle-contractTruffle提供的僧免,用于在NodeJS和瀏覽器中集成Truffle的合約抽象運行環(huán)境刑赶。

$ npm install truffle-contract

npm notice created a lockfile as package-lock.json. You should commit this file.
+ truffle-contract@3.0.6
added 24 packages from 18 contributors and audited 25 packages in 13.15s
found 0 vulnerabilities

安裝NodeJS中用到的Truffle運行時需要的web3環(huán)境

$ npm install web3

npm WARN deprecated web3@1.0.0-beta2: This version has faulty dependecy links.
+ web3@1.0.0-beta2
added 1 package from 1 contributor and audited 26 packages in 1.752s
found 0 vulnerabilities

測試合約
這里就用前面的Test.solGreeter.sol,部署流程就不講了懂衩,在項目根目錄下創(chuàng)建main.js撞叨,內容大體結構如下

//引入依賴,并初始化一個實例Web3
var Web3 = require('web3');
var provider = new Web3.providers.HttpProvider("http://localhost:8545");

//省略了無關代碼
//合約初始化
var Test = contract(/*合約JSON*/);//合約的元數據 

//設置連接
Test.setProvider(provider);

//設置默認地址
Test.defaults({
  from : "0x299127d72e28cb92d09f856aaedeb139d1e7e74a"
});

//函數調用
//TODO

我們拿Test舉個例子:

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文件的內容拷貝過來浊洞,為了節(jié)約篇幅牵敷,我就只粘貼了部分,雖然不影響正常測試法希,但可能遇到下面的錯誤:

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.必須設置默認賬戶枷餐,truffle-contract框架默認沒有讀取coinbase的默認地址,所以需要主動設置苫亦,不然會報如下錯誤:

(node:26922) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: invalid address

運行main.js
運行main.js毛肋,然后報了如下錯:

$ node main.js 

module.js:487
    throw err;
    ^
Error: Cannot find module 'web3-requestManager'

這個問題就是我開篇說的一定要注意運行環(huán)境的版本,這個問題是因為package.json中依賴的web3版本是^1.0.0-beta2屋剑,這個問題可以通過安裝依賴解決

$ npm install ethereum/web3.js

+ web3@0.20.7
added 4 packages from 4 contributors, updated 1 package and audited 32 packages in 58.834s
found 0 vulnerabilities

再次查看package.json中的web3版本已經變成了github:ethereum/web3.js润匙,然后再次運行main.js

$ node main.js 

method f()
method g()

輸出結果跟上篇內容的一樣,也在預料之中饼丘。不論是合約中的f()方法還是g()方法趁桃,都不會改寫區(qū)塊鏈狀態(tài),使用instance.f.call()調用肄鸽;而對于一個會改寫區(qū)塊鏈狀態(tài)的函數f()卫病,使用instance.f()調用,我們在以Greeter.sol為例來演示一下
下面的代碼依然是放在main.js

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);
});

運行

$ 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

因為ins.setGreeting ()方法會改變區(qū)塊鏈狀態(tài)典徘,所以需要消耗gas蟀苛,同時在調用的時候返回對應的交易狀態(tài)結果。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末逮诲,一起剝皮案震驚了整個濱河市帜平,隨后出現的幾起案子幽告,更是在濱河造成了極大的恐慌,老刑警劉巖裆甩,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冗锁,死亡現場離奇詭異,居然都是意外死亡嗤栓,警方通過查閱死者的電腦和手機冻河,發(fā)現死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茉帅,“玉大人叨叙,你說我怎么就攤上這事】芭欤” “怎么了擂错?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長樱蛤。 經常有香客問我钮呀,道長,這世上最難降的妖魔是什么刹悴? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任行楞,我火速辦了婚禮攒暇,結果婚禮上土匀,老公的妹妹穿的比我還像新娘。我一直安慰自己形用,他們只是感情好就轧,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著田度,像睡著了一般妒御。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上镇饺,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天乎莉,我揣著相機與錄音,去河邊找鬼奸笤。 笑死惋啃,一個胖子當著我的面吹牛,可吹牛的內容都是我干的监右。 我是一名探鬼主播边灭,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼健盒!你這毒婦竟也來了绒瘦?” 一聲冷哼從身側響起称簿,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惰帽,沒想到半個月后憨降,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡该酗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年券册,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片垂涯。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡烁焙,死狀恐怖,靈堂內的尸體忽然破棺而出耕赘,到底是詐尸還是另有隱情骄蝇,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布操骡,位于F島的核電站九火,受9級特大地震影響,放射性物質發(fā)生泄漏册招。R本人自食惡果不足惜岔激,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望是掰。 院中可真熱鬧虑鼎,春花似錦、人聲如沸键痛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽絮短。三九已至江兢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間丁频,已是汗流浹背杉允。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留席里,地道東北人叔磷。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像胁勺,于是被迫代替她去往敵國和親世澜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內容

  • 我這人很念舊長情署穗,又一直比較喜歡和擅長整理寥裂,所以之前家里東西不算少嵌洼,但勝在整理的清楚,打開每個柜子封恰,物品塞得滿滿的...
    Karen靜閱讀 1,840評論 4 20
  • 我的老家下雪了 我來自北方麻养,我的家鄉(xiāng)迎來18年的第一場雪。我后知后覺...
    我在圖書館閱讀 239評論 0 0
  • 鐵木山 如來佛珠墜人間诺舔, 巧變秀峰嵌高原鳖昌。 青天白云常相伴, 日夜聽經會圣賢低飒。 西巖山 巍峨屹立古城前许昨, 剎頂直插...
    坦人閱讀 201評論 0 3
  • 那天,婚禮結束褥赊。眾仙散場后糕档,東華就回了太晨宮。 姬蘅看見東華回來了拌喉,心中一喜速那,面露微笑,急忙跑去迎接“老師尿背,您回來...
    移舟w閱讀 2,883評論 6 25
  • 前言 上次的分享還是兩個月以前—用了這些工具軟件田藐,百分之百能提高 Windows 使用效率荔烧,當時介紹了一些Wind...
    xzonepiece閱讀 2,897評論 1 33