第十篇 墨客区块链(MOAC BlockChain) 如何将自定义数据写到区块链中

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

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

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

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

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

代码文档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) 程序猿怎么部署和调用智能合约》的第三节“3.部署智能合约”。

直接node,运行结果如下:

返回信息中包含:

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

本次交易的hash值: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. 该代码里包含手动设置nounce完成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 = "0x745c57ca5318093115d61bbca368XXXXXXXXXXXX";
var account = {address:"0x745c57ca5318093115d61bbca368XXXXXXXXXXXX",secret:"bb673026deda3c3cd0c63f6ccddfb02a7ae320078aa8XXXXXXXXXXXXXXXXXXXX"};

//主要参数
var thisTxCount = -1;               //nounce值,本例手动设置,初始为-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 = [];
for(var i in excelObj){
    var arr=[];
    var value=excelObj[i];          //获取数据
    //console.log(i,"  ",value);	
	
	if (i > 0){	                    //数据从第二行开始,通常在excel中第一行(i=0)就是每一列的title
		sleep(interval * 1000);     //每隔2秒,发送一次信息
		message = value[2];         //得到要发送的信息内容

		console.log(i,"  ",message,"  ");
		send(chain3, account.address, account.secret, message, thisTxCount);
	    value[3] = (new Date).toLocaleString();  //记录发送交易的时间
	}
	
    for(var j in value){            //每一条记录内容
        arr.push(value[j]);
        //console.log(j,"  ",value[j]);
    }
    data.push(arr);
}

//创建excel文件
var buffer = xlsx.build([
    {
        name:'sheet1',
        data:data
    }        
]);

//创建新文件,将发送时间等记录到文件中
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){
  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);
  mc.sendRawTransaction(signedTx, function(err, hash) {
      if (!err){
          console.log("succeed: ", hash);
          return hash;
      }else{
          console.log("error:", err);
          console.log('raw tx:', rawTx);
      }
  });
}

执行结果:返回所有交易的hash值。

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

猜你喜欢

转载自blog.csdn.net/lyq13573221675/article/details/81354458
今日推荐