Files
js/lib/service.blockchain.js
T
2020-07-27 12:00:42 +02:00

187 lines
5.4 KiB
JavaScript

/*
* This file is part of the Flowee project
* Copyright (C) 2019-2020 Tom Zander <tomz@freedommail.ch>
* Copyright (C) 2020 James Zuccon <zuccon@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
const Message = require('./message');
/**
* Blockchain information service.
* @param {Flowee} instance Instance of Flowee
*/
class BlockchainService {
constructor(network) {
this.network = network;
}
/**
* Get Blockchain Information
* @example
* let blockChainInfo = await flowee.getBlockChainInfo();
*/
async getBlockChainInfo() {
let reply = await this.network.sendMessage(new Message(1, 0));
return {
difficulty: reply[64],
medianTime: reply[65],
chainWork: reply["66str"],
chain: reply[67],
blocks: reply[68],
headers: reply[69],
bestBlockHash: reply[70],
bestBlockId: reply["70str"],
};
}
/**
* Get the best block hash available
* @returns The an object with the block hash as string and buffer.
* @example
* let bestBlockHash = await flowee.getBestBlockHash();
*/
async getBestBlockHash() {
let reply = await this.network.sendMessage(new Message(1, 2));
return {
blockId: reply["1str"],
blockHash: reply[1],
}
}
/**
* Get Block height
* @returns {number} The block height
* @example
* let blockCount = await flowee.getBlockCount();
*/
async getBlockCount() {
let reply = await this.network.sendMessage(new Message(1, 10));
return reply.body[7]; // Block Height (is equal to count since genesis is height=0)
}
/**
* Get Block
* @param param (Number or Hash) The block height
* @returns {number} Object containing details about block
* @example
* let blockHeader = await flowee.getBlock(500000);
*/
async getBlock(param) {
let message = new Message(1, 4);
message.body[44] = true; // Include_OffsetInBlock
message.body[45] = false; // Include_FullTxData
if (typeof param === 'number') {
message.body[7] = param;
} else if (param * 1 == parseInt(param)) { // is really a number
message.body[7] = parseInt(param);
} else if (typeof param === 'string') {
message.body[5] = Buffer.from(param, 'hex').reverse();
if (message.body[5].length != 32)
throw "Invalid argument, not blockId";
} else if (typeof param == 'undefined') {
throw "Missing argument";
} else {
message.body[5] = param;
}
let reply = await this.network.sendMessage(message);
let answer = {
blockId: reply["5str"],
blockHash: reply[5],
blockHeight: reply[7],
transactions: []
}
let tx = null;
for (let prop of reply.body) {
if (prop.key == 0) {
if (tx != null)
answer.transactions.push(tx);
tx = null;
}
else if (prop.key == 8) {
tx = {};
tx.offset = prop.value;
}
}
return answer;
}
async getRawTransaction(blockHeight, offsetInBlock) {
if (blockHeight * 1 == parseInt(blockHeight)) { // is really a number
blockHeight = blockHeight * 1;
}
if (typeof blockHeight === 'string') {
// assume this is a txid
var search = await this.network.search({
jobs: [{
value: blockHeight,
type: this.network.Job.FetchTx,
txFilter: [ this.network.IncludeFullTxData ]
}]});
return search.transactions[0].fullTxData;
}
if (typeof blockHeight === 'number' && typeof offsetInBlock === 'number') {
let message = new Message(1, 12);
message.body[7] = blockHeight;
message.body[8] = offsetInBlock;
message.body[45] = true; // Include_FullTxData
let reply = await this.network.sendMessage(message);
return reply["1"];
}
else
throw "Missing arguments";
}
async getBlockHeader(blockHeight) {
if (blockHeight * 1 == parseInt(blockHeight)) { // is really a number
blockHeight = blockHeight * 1;
}
let message = new Message(1, 8);
if (typeof blockHeight === 'number') {
message.body[7] = blockHeight;
} else if (typeof blockHeight === 'string') {
message.body[5] = Buffer.from(param, 'hex').reverse();
if (message.body[5].length != 32)
throw "Invalid argument, not blockId";
}
else
throw "Missing arguments";
let reply = await this.network.sendMessage(message);
return {
blockId: reply["5str"],
blockHash: reply[5],
confirmations: reply[72],
blockHeight: reply[7],
version: reply[62],
merkleRoot: reply[73],
merkleRootHex: reply["73str"],
time: reply[63],
medianTime: reply[65],
nonce: reply[74],
bits: reply[75],
difficulty: reply[64],
prevBlockHash: reply["76str"],
nextBlockHash: reply["77str"]
};
}
}
module.exports = BlockchainService;