In this tutorial, we’re gonna build API that allows us to explore the data inside of our Blockchain Network. We will have ability to search the entire Blockchain for a specific Block by Hash, for a specific Transaction by Id. We can also fetch data from our Blockchain Network for a specific User/Address.
Previous Post: How to build Consensus Algorithm for Blockchain Network in Javascript
Contents
Explore Data Endpoints
We will make 3 endpoints:
– GET /block/:hash
: shows a specific Block by :hash
.
– GET /transaction/:id
: shows a specific Transaction by Transaction’s :id
.
– GET /address/:address
: shows all Transactions that an :address
is related to (address/user is a sender or a recipient).
These endpoints use 3 Blockchain
class finder methods:
class Blockchain { findBlockByHash(hash) { ... } findTransactionById(id) { ... } findTransactionsByAddress(address) { ... } } |
Practice
Implement Blockchain class Finder Methods
Inside blockchain.js file, add 3 methods to Blockchain
class:
Find specific Block by Hash
class Blockchain { ... findBlockByHash(hash) { let result = null; this.chain.forEach(block => { if (block.hash === hash) { result = block; } }); return result; } } |
Find specific Transaction by Transaction’s Id
class Blockchain { ... findTransactionById(id) { let result = null; this.chain.forEach(block => { block.transactions.forEach(transaction => { if (transaction.id === id) { result = { transaction: transaction, block: block } } }); }); return result; } } |
Find all Transactions by Address/User
class Blockchain { ... findTransactionsByAddress(address) { let transactions = []; this.chain.forEach(block => { block.transactions.forEach(transaction => { if (transaction.sender === address || transaction.recipient === address) { transactions.push(transaction); } }); }); let balance = 0; transactions.forEach(transaction => { if (transaction.sender === address) { balance -= +transaction.amount; } else if (transaction.recipient === address) { balance += +transaction.amount; } }); return { transactions: transactions, balance: balance } } } |
Explore Data Endpoints
Inside api.js file, add 3 endpoints:
Block by Hash
app.get('/block/:hash', function (req, res) { const hash = req.params.hash; const block = bitcoin.findBlockByHash(hash); res.json({ block: block }); }); |
Transaction by Id
app.get('/transaction/:id', function (req, res) { const id = req.params.id; const transactionInfo = bitcoin.findTransactionById(id); if (transactionInfo !== null) { res.json({ transaction: transactionInfo.transaction, block: transactionInfo.block }); } else { res.json({ transaction: null }); } }); |
app.get('/address/:address', function (req, res) { const address = req.params.address; const data = bitcoin.findTransactionsByAddress(address); res.json({ data: data }); }); |
Run & Check results
– Run the API on Terminal with command:
npm run node1
– Broadcast some Transactions and mine on node1, then check with url http://localhost:3001/blockchain
:
{ "chain": [ { "index": 1, "timestamp": 1529052741183, "transactions": [], "nonce": 100, "hash": "Genesis block", "prevBlockHash": "0" }, { "index": 2, "timestamp": 1529052753821, "transactions": [], "nonce": 44, "hash": "00669af06fa8d395bea4f6325d39f43a3c87788152fc3050608aa23e55dfe964", "prevBlockHash": "Genesis block" }, { "index": 3, "timestamp": 1529052774139, "transactions": [ { "amount": 1, "sender": "00000", "recipient": "69f92710-7079-11e8-8995-3541219a9e51", "id": "71e0ed00707911e889953541219a9e51" }, { "amount": "80", "sender": "JACK", "recipient": "KATHERIN", "id": "76b5a690707911e889953541219a9e51" }, { "amount": "120", "sender": "JACK", "recipient": "JASON", "id": "79cfb7d0707911e889953541219a9e51" } ], "nonce": 24, "hash": "00134bdd4d16f9c9a133cae3dd199a60e8538415a5a395a064f27235d5149635", "prevBlockHash": "00669af06fa8d395bea4f6325d39f43a3c87788152fc3050608aa23e55dfe964" }, { "index": 4, "timestamp": 1529052795825, "transactions": [ { "amount": 1, "sender": "00000", "recipient": "69f92710-7079-11e8-8995-3541219a9e51", "id": "7df67e20707911e889953541219a9e51" }, { "amount": "90", "sender": "KATHERIN", "recipient": "JASON", "id": "7f2a1c20707911e889953541219a9e51" }, { "amount": "50", "sender": "KATHERIN", "recipient": "JACK", "id": "839b8000707911e889953541219a9e51" }, { "amount": "300", "sender": "HELEN", "recipient": "JACK", "id": "89f35720707911e889953541219a9e51" } ], "nonce": 117, "hash": "00590443077dd36dd186defbadb224eb50d2e6330e59cccd737dd345c0a5dd2b", "prevBlockHash": "00134bdd4d16f9c9a133cae3dd199a60e8538415a5a395a064f27235d5149635" } ], "pendingTransactions": [ { "amount": 1, "sender": "00000", "recipient": "69f92710-7079-11e8-8995-3541219a9e51", "id": "8ae2e740707911e889953541219a9e51" } ], "nodeUrl": "http://localhost:3001", "networkNodes": [] } |
– Find Block by Hash:
– Find Transaction by Id:
– Find all Transactions by Address/User
Really wonderful tutorial! Very well documented and explained step wise as to how to go about the entire block chain and decentralised part
However, I was wanting to know, how does one deploy such apps to be used on a global scale? Are the files distributed directly and the blockchain storage and all managed de-centrally, or use p2p? if so then how?
Would like to hear your comments