区块链的一个显著特点是,数据一旦写入链中,就不可篡改重写。


在墨客区块链中,每一笔交易(transaction),都有一个保存数据的data空间,本文主要讲解如何将自定义数据(可以是一句话、一篇文章等)写入区块链的交易中,并读取出来。

当然,保存数据到区块链是会消耗gas费的,且gas费跟数据量是正相关的。

本文内容不适用于有强逻辑性和关系型的大数据存储。

1.做一笔交易,将数据写入区块链

该笔交易没有发送mc,或者其他token,仅将数据写到区块链。

代码文档sendData.js如下:
var Chain3 = require('chain3'); var chain3 = new Chain3(new
Chain3.providers.HttpProvider('http://localhost:8545')); var address =
"0x745c57ca5318093115d61bbca368XXXXXXXXXXXX"; var account =
{address:"0x745c57ca5318093115d61bbca368XXXXXXXXXXXX",secret:"bb673026deda3c3cd0c63f6ccddfb02a7aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"};
send(chain3, account.address, account.secret, txCount = -1); function
send(chain3, fromAddress, fromSecret, txCount = -1){ var mc = chain3.mc; var
txcount = txCount >= 0 ? txCount : chain3.mc.getTransactionCount(fromAddress);
console.log("Get tx account", txcount); var gasPrice = 25000000000; var
gasLimit = 100000; var gasTotal = gasPrice * gasLimit; console.log(gasPrice,
gasLimit, chain3.fromSha(gasTotal, 'mc')); //以下为写入数据log let log = { time:(new
Date).getTime(), type:"info", msg:"Hello MOAC!!!" }; //转换log数据格式 let str =
JSON.stringify(log); console.log(str); let data =
Buffer.from(str).toString('hex'); data = '0x'+data; console.log(data); var
rawTx = { from: fromAddress, nonce: chain3.intToHex(txcount), gasPrice:
chain3.intToHex(gasPrice), gasLimit: chain3.intToHex(gasLimit), data: data ,
shardingFlag: 0, //default is global contract chainId: chain3.version.network
}; var signedTx = chain3.signTransaction(rawTx, fromSecret);
mc.sendRawTransaction(signedTx, function(err, hash) { if (!err){
console.log("succeed: ", hash); return hash; }else{ console.log("error:", err);
console.log('raw tx:', rawTx); } }); }
代码使用sendRawTransaction时需要私钥签名,得到本地节点账号的私钥方法见:

《第八篇 墨客区块链(MOAC BlockChain) 程序猿怎么部署和调用智能合约
<https://blog.csdn.net/lyq13573221675/article/details/81285250>》的第三节“3.部署智能合约”。

直接node,运行结果如下:



返回信息中包含:

本次交易写入数据“Hello MOAC!!!”及其十六进制表示。

本次交易的hash值:0x7834667df3890d0a4bc2fc949d45206fec8fe4b63853181dd9cc20c1b6c009dc。

到浏览器
<http://explorer.moac.io/tx/0x7834667df3890d0a4bc2fc949d45206fec8fe4b63853181dd9cc20c1b6c009dc>
查询hash:



其中的Input Data就是本次交易写入的数据。与node sendData.js时显示的hex格式数据内容一致。

 

2.查看区块链里的数据字段

当前,每笔交易里的数据在浏览器还显示为hex。因此需要自己写代码解读出其中的内容。

读数据代码callData.js如下:
var Chain3 = require('chain3'); var chain3 = new Chain3(new
Chain3.providers.HttpProvider('http://localhost:8545')); //设置API访问moac节点方式
//获取交易信息 hash =
"0x7834667df3890d0a4bc2fc949d45206fec8fe4b63853181dd9cc20c1b6c009dc"; var
receipt = chain3.mc.getTransaction(hash); console.log('get transaction from
hash :'+ JSON.stringify(receipt)); console.log(); //获取交易内保存的数据data,需要提前写入 hash
= "0x7834667df3890d0a4bc2fc949d45206fec8fe4b63853181dd9cc20c1b6c009dc";
chain3.mc.getTransaction(hash,function(error, result){ //console.log(result);
inputData = result.input; res_str =
Buffer.from(inputData.replace('0x',''),'hex').toString(); res_json =
JSON.parse(res_str); console.log('your data :',res_json); console.log('your msg
:',res_json.msg); });
直接node,运行结果如下:



通过交易hash得到交易的所有信息,并分析出data数据。

 

3.将数据批量写入区块链

结合对excel表格的读写操作,可以简单地将批量数据写入到区块链中去。

首先设计一个excel文件,保存要写到区块链的数据。命名为testMessage.xlsx。



本实例用到message。id和name不在代码里使用,仅用于文档记录。time用于返回时间,在成功后会新建一个文件,返回每次信息发送的时间。

代码文件goMessage.js。node执行即可。

注意:1. 将数据上链的交易会收取gas费,且收取的费用跟数据大小正相关;
           2. 该代码里包含手动设置nonce完成tx的实例。
var Chain3 = require('chain3'); var chain3 = new Chain3(new
Chain3.providers.HttpProvider('http://localhost:8545'));
//通过node-xlsx读取的excel文件就是一个json数据 var xlsx = require('node-xlsx');
//定义xlsx,自行npm install node-xlsx var fs = require('fs'); //定义fs,自行npm install
fs var address = "0x745c57ca5318093115d61bbca36XXXXXXXXXXXX"; var account = {
address: "0x745c57ca5318093115d61bbca36XXXXXXXXXXXX", secret:
"bb673026deda3c3cd0c63f6ccddfb02a7ae320078aa8XXXXXXXXXXXXXXXXXXXX" }; //主要参数
var thisTxCount = -1; //nonce值,本例手动设置,初始为-1,读取实际值后,每次自增1 var interval = 2;
//发送一次信息的间隔时间,秒 var message = "Hello MOAC!!!"; //定义要发送的信息,从cxcel文件读取 var obj =
xlsx.parse(__dirname + '/testMessage.xlsx');//配置excel文件的路径 var excelObj =
obj[0].data; //obj[i].data表示excel文件第i+1个sheet文档的全部内容 var data = []; var
promiseList = []; //用于异步返回 for (var i in excelObj) { var arr = []; if (i > 0) {
//数据从第二行开始,通常在excel中第一行(i=0)就是每一列的title sleep(interval * 1000); //每隔2秒,发送一次信息
message = excelObj[i][2]; //得到要发送的信息内容 excelObj[i][3] = (new
Date).toLocaleString(); //记录发送交易的时间 promiseList.push(send(chain3,
account.address, account.secret, message, thisTxCount, i)); } }
Promise.all(promiseList).then(function (objList) { //所有异步完成后回调 //遍历objList
objList.forEach(item=>{ excelObj[item.index][4] = item.hash; //记录发送交易的哈希 }) var
buffer = xlsx.build([ { name: 'sheet1', data: excelObj } ]);
//创建新文件,将发送时间等记录到文件中 fs.writeFileSync((new Date).toLocaleDateString() + '-' +
(new Date).getTime() + '-' + 'hadSendMessage.xlsx', buffer, {'flag': 'w'}); });
//自己写的休眠函数 function sleep(numberMillis) { var now = new Date(); var exitTime =
now.getTime() + numberMillis; while (true) { now = new Date(); if
(now.getTime() > exitTime) return; } } function send(chain3, fromAddress,
fromSecret, message, txCount = -1, index) { var mc = chain3.mc; var txcount =
txCount >= 0 ? txCount : chain3.mc.getTransactionCount(fromAddress);//获取nounce值
//console.log("Get tx account", txcount); thisTxCount = txcount + 1;
//手动设置nounce,每次自增1 var gasPrice = 25000000000; var gasLimit = 100000;
//数据量越大,gas费应该设置得越高 var gasTotal = gasPrice * gasLimit; //console.log(gasPrice,
gasLimit, chain3.fromSha(gasTotal, 'mc')); //以下为写入数据log let log = { time: (new
Date).getTime(), //获取当前时间(从1970.1.1开始的毫秒数) type: "info", msg: message };
//转换log数据格式,将数据转换为16进制字符串 let str = JSON.stringify(log); console.log(str); let
data = Buffer.from(str).toString('hex'); data = '0x' + data; console.log(data);
var rawTx = { from: fromAddress, nonce: chain3.intToHex(txcount), gasPrice:
chain3.intToHex(gasPrice), gasLimit: chain3.intToHex(gasLimit), data: data,
shardingFlag: 0, //default is global contract chainId: chain3.version.network
}; var signedTx = chain3.signTransaction(rawTx, fromSecret); return new
Promise(function (resolve, reject) { //异步调用方法 mc.sendRawTransaction(signedTx,
function (err, hash) { if (!err) { console.log('i=', index);
console.log("succeed: ", hash); let objBack = { //index及对应的hash hash, index }
resolve(objBack); } else { console.log("error:", err); console.log('raw tx:',
rawTx); reject(err); } }); }) }
执行结果:返回所有交易的hash值。



并且建立一个新的文件2018-8-12-1534085632480-hadSendMessage.xlsx。



 

4.在交易里发送 mc + data

发送一笔交易,包含发送mc,同时把数据写到data字段。
var Chain3 = require('chain3'); var chain3 = new Chain3(new
Chain3.providers.HttpProvider('http://localhost:8545')); var address =
"0x745c57ca5318093115d61bbca368XXXXXXXXXXXX"; var account =
{address:"0x745c57ca5318093115d61bbca368XXXXXXXXXXXX",secret:"bb673026deda3c3cd0c63f6ccddfb02a7ae320078aa8XXXXXXXXXXXXXXXXXXXX"};
var toAddress = "0x68986c1bcd54ae5dae69310fc64eXXXXXXXXXXXX"; var amount =
0.002; send(chain3, account.address, account.secret, toAddress, amount, txCount
= -1) function send(chain3, fromAddress, fromSecret, toAddress, amount, txCount
= -1){ var mc = chain3.mc; var txcount = txCount >= 0 ? txCount :
chain3.mc.getTransactionCount(fromAddress); console.log("Get tx account",
txcount); var gasPrice = 25000000000; var gasLimit = 100000; var value =
chain3.toSha(amount, 'mc'); var gasTotal = gasPrice * gasLimit + Number(value);
console.log(gasPrice, gasLimit, value, chain3.fromSha(gasTotal, 'mc'));
//以下为写入数据log let log = { time:(new Date).getTime(), type:"info", msg:"MOAC
GO!!!" }; let str = JSON.stringify(log); console.log(str); let data =
Buffer.from(str).toString('hex'); data = '0x'+data; console.log(data); var
rawTx = { from: fromAddress, to: toAddress, nonce: chain3.intToHex(txcount),
gasPrice: chain3.intToHex(gasPrice), gasLimit: chain3.intToHex(gasLimit),
value: chain3.intToHex(value), data: data , shardingFlag: 0, //default is
global contract chainId: chain3.version.network }; var signedTx =
chain3.signTransaction(rawTx, fromSecret); mc.sendRawTransaction(signedTx,
function(err, hash) { if (!err){ console.log("succeed: ", hash); return hash;
}else{ console.log("error:", err); console.log('raw tx:', rawTx); } }); }
 

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信