在以太坊錢(qián)包的開(kāi)發(fā)1 與以太坊錢(qián)包的開(kāi)發(fā)2 中,我們用NodeJs搭了個(gè)以太坊錢(qián)包的后臺(tái),實(shí)現(xiàn)了查詢(xún)余額扮休、轉(zhuǎn)賬、查看交易等的功能贱案,現(xiàn)在介紹用NodeJs寫(xiě)接口給移動(dòng)端或者前端使用肛炮。
前面搭建本地或者遠(yuǎn)程服務(wù)器的區(qū)塊鏈節(jié)點(diǎn)后止吐,我們還安裝了NodeJs環(huán)境。
// 創(chuàng)建wallet文件夾侨糟,進(jìn)入
cd wallet
//初始化node模塊, 并填寫(xiě)相關(guān)信息
npm init
// 安裝eth包
npm install ethereumjs-tx --save
// 安裝express模塊
npm install express --save
express 是基于NodeJs的一種簡(jiǎn)單使用的Web框架
代碼如下:
var express = require('express');
//實(shí)例化express類(lèi)
var app = express();
var bodyParser = require('body-parser');
var Web3 = require('web3');
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
console.log('~defined~:'+web3);
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
var version = web3.version.api;
console.log(version);
}
/* Post方法
* url: yourHost/transaction
* param:
* to 目標(biāo)地址
* value 轉(zhuǎn)賬的數(shù)額
* privateKey 自己的私鑰碍扔,可與客戶(hù)端規(guī)定好,使用一些加密方法
*/
app.post("/transaction", function (req, res) {
if (req.body.to && req.body.value && req.body.privateKey) {
/* 獲取公鑰 */
var publicKey = catchPublicFromPrivate(req.body.privateKey);
var nonceNumber = web3.eth.getTransactionCount(publicKey);
// nonceNumber++;
console.log('nonceNumber:'+nonceNumber);
try {
sendMyTransaction(req.body.to, req.body.privateKey, req.body.value, nonceNumber, function (error, hash) {
if (!error) {
res.status(200);
res.json({status:1 ,msg:'請(qǐng)求成功' , result:{hash:hash}});
}
else {
res.status(500);
res.json({status:0 ,msg:'請(qǐng)求失旓踔亍:'+error , result:''});
}
});
} catch (e) {
console.log('yichang');
res.status(500);
res.json({status:0 ,msg:'請(qǐng)求失敗:' + e , result:''});
}
} else {
res.status(202);
res.json({status:0 ,msg:'參數(shù)錯(cuò)誤', result:''});
return;
}
});
/*
* 開(kāi)啟監(jiān)聽(tīng)3000端口 不同,這樣你的接口才有效
*/
app.listen(3000, function(){
console.log("App started on port 3000");
});
tips: 編寫(xiě)NodeJs的get方法與此類(lèi)似:app.get("/abc/aaa",function( request, response){ // to do });
內(nèi)部封裝的方法實(shí)現(xiàn):
/*
* ---- ---- ---- Common Method ---- ---- ----
* */
/*
* 從私鑰獲取公鑰(解密的過(guò)程) 具體實(shí)現(xiàn)從官網(wǎng)獲得
* */
function catchPublicFromPrivate (privateKey) {
var secp256k1 = require('secp256k1') ;
var SHA3 = require('keccakjs');
var privateKeyBuffer = new Buffer(privateKey, 'hex');
var publicKey = secp256k1.publicKeyCreate(privateKeyBuffer, false).slice(1);
var h = new SHA3(256);
h.update(publicKey);
var hh = h.digest('hex').slice(-40);
return '0x'+hh;
}
/*
* 封裝的交易方法
* */
function sendMyTransaction (to, privateKey, value, nonce, callback) {
var Tx = require('ethereumjs-tx');
var privateKey = new Buffer(privateKey, 'hex');
var rawTx = {
nonce: nonce,
gasPrice: '0x3b9aca00',
gasLimit: '0x493e0',
to: to,
value: value,
data: ''
};
var tx = new Tx(rawTx);
tx.sign(privateKey);
var serializedTx = tx.serialize();
web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function(err, hash) {
console.log('交易結(jié)果:'+hash);
if (callback && typeof(callback) === "function") {
if (!err)
callback(null, hash);
else
callback(err, null);
}
});
}
至此,在客戶(hù)端就可以用接口實(shí)現(xiàn)轉(zhuǎn)賬的功能了溶耘。