Hyperledger is an open source blockchain solution that you can use for setting up private blockchains. The product is becoming more useful in providing blockchain solutions to industries but there is still little documentation on how to make it as customisable at possible.
The instructions for setting up hyperledger can be found here fabric installation and setup . Instructions for setting up blockchain explorer are also available here blockexplorer for hyperledger.
We will focus now searching though the blockchain with details saved in a specific transaction in hyperledger. The blockchain explorer makes use of a postgres database. By default the blochain explorer can search through the blockchain using transaction hash, block hash and channel names, it is however not configured to search through information specific to a transaction. This information is saved in the column write_set of the table transactions in the postgres database and the datatype of the column is json.
The blockchain explorer has APIs which you can also extend to make your own APIs that you can use to search through the blockchain.
- Creating your own customised query to search through transactions and get a list.
You will need to update the file blockexplorer/blockchain-explorer/app/persistence/postgreSQL/CRUDService.js
In this file you will find the following piece of code, this will be your guide to creating a new function with your custom query.
getTxList(channel_genesis_hash, blockNum, txid, from, to, orgs) {
let orgsSql = '';
if (orgs && orgs != '') {
orgsSql = `and t.creator_msp_id in (${orgs})`;
}
let sqlTxList = ` select t.creator_msp_id,t.txhash,t.type,t.chaincodename,t.createdt,channel.name as channelName from transactions as t
inner join channel on t.channel_genesis_hash=channel.channel_genesis_hash where t.blockid >= ${blockNum} and t.id >= ${txid} ${orgsSql} and
t.channel_genesis_hash = '${channel_genesis_hash}' and t.createdt between '${from}' and '${to}' order by t.id desc`;
return sql.getRowsBySQlQuery(sqlTxList);
}
From this query above it will search through the transactions and provide you a list of results. We can then create our own function that can search through the data to also find those matching the information that was part of the transaction. Below is an example of how such a function can look like.
getTxListWithOtherInfo(channel_genesis_hash, blockNum, txid, from, to, orgs,otherInfoToSearch) {
let orgsSql = '';
if (orgs && orgs != '') {
orgsSql = `and t.creator_msp_id in (${orgs})`;
}
let sqlTxList = ` select t.creator_msp_id,t.txhash,t.type,t.chaincodename,t.createdt,channel.name as channelName from transactions as t
inner join channel on t.channel_genesis_hash=channel.channel_genesis_hash where t.blockid >= ${blockNum} and t.id >= ${txid} ${orgsSql} and
t.channel_genesis_hash = '${channel_genesis_hash}' and t.createdt between '${from}' and '${to}' and t.write_set::json->>0 LIKE '%${otherInfoToSearch}%' order by t.id desc`;
return sql.getRowsBySQlQuery(sqlTxList);
}
Take note of this part of code here
and t.write_set::json->>0 LIKE '%${otherInfoToSearch}%'
This is the part the searches through the json datatype column and converting the data to a string using ->> and looking for a match with the resultant string text.
Common problem
A common problem encountered is that of the search failing because of invalid values caused by \u0000 which is imported as part of the data by the explorer which its building the database and filling it with data from the blockchain. A solution for this is to remove this as data is being imported so that it is not saved in the database. This can be archived by updating the file
blockexplorer/blockchain-explorer/app/persistence/postgreSQL/db/pgservice.js
In this file We update the function saveRow and update it to this.
function saveRow(tablename, columnValues) {
return new Promise(function(resolve, reject) {
var addSqlParams = [];
var updatesqlcolumn = [];
var updatesqlflag = [];
var i = 1;
Object.keys(columnValues).forEach(k => {
let v = columnValues[k];
console.log(v);
if(tablename==="transactions"){
if(v && (k==="read_set" || k==="write_set")){
v = v.replace(/\\u0000/gi, "");
}
}
addSqlParams.push(v);
updatesqlcolumn.push(JSON.stringify(k));
updatesqlflag.push('$' + i);
i = i + 1;
});
var updatesqlparmstr = updatesqlcolumn.join(',').replace(/\\u0000/gi, "");
var updatesqlflagstr = updatesqlflag.join(',');
var addSql = `INSERT INTO ${tablename} ( ${updatesqlparmstr} ) VALUES( ${updatesqlflagstr} ) RETURNING *;`;
logger.debug(`Insert sql is ${addSql}`);
client.query(addSql, addSqlParams, (err, res) => {
if (err) {
logger.error('[INSERT ERROR] - ', err.message);
console.log(err.stack);
reject(err);
}
resolve(res.rows[0].id);
});
});
}
The main focus for this change is on this section:
if(tablename==="transactions"){
if(v && (k==="read_set" || k==="write_set")){
v = v.replace(/\\u0000/gi, "");
}
}
With these changes you should be able to do a lot more like creating custom APIs to search through you hyperledger blockchain.
Congratulations @bmukorera! You have received a personal award!
1 Year on Steemit
Click on the badge to view your Board of Honor.
Do not miss the last post from @steemitboard:
Congratulations @bmukorera! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Do not miss the last post from @steemitboard:
Vote for @Steemitboard as a witness to get one more award and increased upvotes!
Congratulations @bmukorera! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Do not miss the last post from @steemitboard:
Vote for @Steemitboard as a witness to get one more award and increased upvotes!