基于hyperledger聯盟鍊的汽車軌迹追溯系統
- 一、後端接口搭建
-
- 引入子產品
- 插入軌迹完整流程
- 區塊鍊驗證
- 封裝區塊資訊查詢
- 查詢
- 二、配置路由
- 三、簡單的測試調用
一、後端接口搭建
引入子產品
引入之前封裝的子產品
const tool = require('./tool')
const influxdb = require('./influxdb')
module.exports = {
}
插入軌迹完整流程
插入軌迹,軌迹先流入大資料處理平台influxdb,根據算法hashFnc32a可以将上傳的資料打包成唯一編碼hash,然後hash上鍊,最後再刻入第一次的交易hsh,以便日後進行交易回溯
async insertTrail (ctx) {
const queryBody = ctx.request.query
const Trid = queryBody.Trid
console.log(`Trid.....${Trid}`)
const jsonStr = queryBody.jsonStr;
console.log(`jsonStr.....${jsonStr}`)
var DataHash = tool.hashFnv32a(jsonStr,true)
console.log(`DataHash.....${DataHash}`)
var trail = JSON.parse(jsonStr)
var trailToBlockChain = {
username: trail.username,
userid : trail.userid,
devid : trail.devid,
devstr : trail.devstr,
trid : trail.trid,
datahash : DataHash,
tranhash : ""
}
var trailToBlockChainStr = JSON.stringify(trailToBlockChain)
// 執行資料流入influxdb
await influxdb.writePoints(Trid, trail.userid, jsonStr)
var tx_id = null
const request = {
//targets : --- letting this default to the peers assigned to the channel
chaincodeId: 'trail',
fcn: 'insertTrail',
args : [Trid,trailToBlockChainStr],
chainId: 'mychannel',
txId: tx_id
}
TranHash = await tool.executeTranSaction(request)
// 獲得交易完成的hash
console.log(`TranHash.....${TranHash}`)
trailToBlockChain.tranhash = TranHash
trailToBlockChainStr = JSON.stringify(trailToBlockChain)
console.log(`addHash....${trailToBlockChainStr}`)
const nrequest = {
//targets : --- letting this default to the peers assigned to the channel
chaincodeId: 'trail',
fcn: 'updateTrail',
args : [Trid,trailToBlockChainStr],
chainId: 'mychannel',
txId: tx_id
}
await tool.executeTranSaction(nrequest)
// 重新寫入記錄第一次插入的交易hash
ctx.body = TranHash
},
區塊鍊驗證
将取出的json字元串進行hash計算同區塊鍊上鍊的DataHash進行比對,證明未被篡改
async blockChainExamine (ctx) {
const queryBody = ctx.request.query
const trid = queryBody.trid
console.log(`trid.....${trid}`)
console.log(trid)
var tx_id = null
const request = {
chaincodeId: 'trail',
txId: tx_id,
fcn: 'searchOneTrail',
args: [trid],
}
trailToBlockChainStr = await tool.excuteQuery(request)
console.log(`trailToBlockChainStr.....${trailToBlockChainStr}`)
var trailToBlockChain = JSON.parse(trailToBlockChainStr)
var DataHash = trailToBlockChain.datahash
console.log(`DataHash....${DataHash}`)
var influxTrail = await influxdb.queryPointsByTrid(trid)
// console.log(influxTrail[0])
console.log(`influxTrail.jsonStr....${influxTrail[0].jsonStr}`)
var influxDataHash = tool.hashFnv32a(influxTrail[0].jsonStr, true)
console.log(`influxDataHash....${influxDataHash}`)
if(influxDataHash === DataHash){
ctx.body = "區塊鍊hash驗證成功,軌迹唯一hash編碼為:"+DataHash
}else {
ctx.body = "區塊鍊系統比對異常,該資料非原始資料,原資料唯一hash編碼為:"+DataHash
}
}
封裝區塊資訊查詢
async searchBlockByTrid ( ctx ) {
// 這個接口提供給使用者,友善使用者根據trid查詢區塊鍊的存證資訊
const queryBody = ctx.request.query;
const trid = queryBody.trid;
console.log(`trid.....${trid}`)
var tx_id = null
const request = {
chaincodeId: 'trail',
txId: tx_id,
fcn: 'searchOneTrail',
args: [trid],
};
var trailJson = await tool.excuteQuery(request);
var trail = JSON.parse(trailJson);
var blockDetail = await tool.excuteRecall(trail.tranhash)
console.log("所在區塊号為:"+blockDetail.header.number);
console.log("所在區塊hash為:"+blockDetail.header.data_hash);
console.log("交易hash為為:"+blockDetail.data.data[0].payload.header.channel_header.tx_id);
console.log("交易時間戳為為:"+blockDetail.data.data[0].payload.header.channel_header.timestamp);
var json_date = new Date(blockDetail.data.data[0].payload.header.channel_header.timestamp).toJSON();
var theTime = new Date(new Date(json_date) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '');
var block = {
transactionIndex: "汽車軌迹鍊",
hash: blockDetail.data.data[0].payload.header.channel_header.tx_id,
blockNumber: blockDetail.header.number,
blockHash: blockDetail.header.data_hash,
timestamp: theTime
};
ctx.body = block;
}
查詢
這裡支援直接從influxdb時序資料庫拿取時序資料(開放使用者)、從區塊鍊拿取DataHash資料(開放管理者)、查詢區塊鍊世界狀态痕迹(開放管理者)、回溯交易資訊(開放管理者)
async searchAllTrail ( ctx ) {
// 這個接口開放給管理者,檢視區塊鍊上上鍊的軌迹資訊
var tx_id = null;
const request = {
chaincodeId: 'trail',
txId: tx_id,
fcn: 'searchAllTrail',
args: [""]
};
ctx.body = await tool.excuteQuery(request)
},
async searchOneTrail ( ctx ) {
// 這個接口開放給管理者,檢視區塊鍊上上鍊的軌迹資訊
const queryBody = ctx.request.query;
const trid = queryBody.trid;
console.log(`trid.....${trid}`)
var tx_id = null
const request = {
chaincodeId: 'trail',
txId: tx_id,
fcn: 'searchOneTrail',
args: [trid],
};
ctx.body = await tool.excuteQuery(request);
},
async updateTrail (ctx) {
const queryBody = ctx.request.query;
const Trid = queryBody.Trid;
console.log(`Trid.....${Trid}`)
const jsonStr = queryBody.jsonStr;
console.log(`jsonStr.....${jsonStr}`)
var DataHash = tool.hashFnv32a(jsonStr,true)
console.log(`DataHash.....${DataHash}`)
var trail = JSON.parse(jsonStr)
var trailToBlockChain = {
username: trail.username,
userid : trail.userid,
devid : trail.devid,
devstr : trail.devstr,
trid : trail.trid,
datahash : DataHash,
tranhash : trail.tranhash
}
var trailToBlockChainStr = JSON.stringify(trailToBlockChain)
var tx_id = null;
const request = {
//targets : --- letting this default to the peers assigned to the channel
chaincodeId: 'trail',
fcn: 'updateTrail',
args : [Trid,trailToBlockChainStr],
chainId: 'mychannel',
txId: tx_id
};
ctx.body = await tool.executeTranSaction(request)
},
async searchBlockByHash ( ctx ) {
const queryBody = ctx.request.query;
const hash = queryBody.hash;
console.log(`hash.....${hash}`)
ctx.body = await tool.excuteRecall(hash)
},
async searchTrailByTrid ( ctx ) {
//開放給使用者,支援使用者的軌迹查詢
const queryBody = ctx.request.query;
const trid = queryBody.trid;
ctx.body = await influxdb.queryPointsByTrid(trid)[0]
},
async searchTrailByid ( ctx ) {
//開放給使用者,支援使用者的軌迹查詢
const queryBody = ctx.request.query;
const userid = queryBody.userid;
ctx.body = await influxdb.queryPointsByUserid(userid)
},
async searchTrailFromBlockByid ( ctx ) {
//開放給使用者,支援使用者的軌迹查詢
const queryBody = ctx.request.query;
const userid = queryBody.userid;
根據使用者查詢鍊上的軌迹資訊
var tx_id = null;
console.log(`userid.....${userid}`)
console.log(userid);
const request = {
chaincodeId: 'trail',
txId: tx_id,
fcn: 'searchTrailByid',
args: [userid],
};
ctx.body = await tool.excuteQuery(request);
},
async getHistoryForTrail ( ctx ) {
const queryBody = ctx.request.query;
const trid = queryBody.trid;
console.log(`trid.....${trid}`)
console.log(trid);
var tx_id = null;
const request = {
chaincodeId: 'trail',
txId: tx_id,
fcn: 'getHistoryForTrail',
args: [trid],
};
ctx.body = await tool.excuteQuery(request)
},
二、配置路由
const router = require('koa-router')()
const IndexController = require('./../controllers/index')
router
// .get('/',IndexController.indexPage)
.get('/insertTrail',IndexController.insertTrail)
.get('/searchAllTrail',IndexController.searchAllTrail)
.get('/searchOneTrail',IndexController.searchOneTrail)
// .get('/deleteTrail',IndexController.deleteTrail)
.get('/updateTrail',IndexController.updateTrail)
.get('/searchBlockByHash',IndexController.searchBlockByHash)
.get('/searchTrailByid',IndexController.searchTrailByid)
.get('/getHistoryForTrail',IndexController.getHistoryForTrail)
// .get('/getDeletedTrails',IndexController.getDeletedTrails)
.get('/blockChainExamine',IndexController.blockChainExamine)
.get('/searchTrailFromBlockByid',IndexController.searchTrailFromBlockByid)
.get('/searchTrailByTrid',IndexController.searchTrailByTrid)
.get('/searchBlockByTrid',IndexController.searchBlockByTrid)
module.exports = router
三、簡單的測試調用
hash上鍊
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNyZuBnL1MjM3AzN0UTM0ATNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
區塊鍊校驗
交易追溯
大資料流入時序資料庫
取時序資料
曆史世界狀态回溯