1.1.1 • Published 4 years ago

neoblocks-common v1.1.1

Weekly downloads
2
License
MIT
Repository
github
Last release
4 years ago

Summary

The NeoBlocks common JavaScript library is a helper module to fetch and construct NEO blocks from a compatible NeoBlocks node. The constructed blocks will include transactions, transfers and execution events.

Installation

Build the module from source:

git clone https://github.com/NeoBlocks/neoblocks-common.git
cd neoblocks-common
npm install

Or install it from the npm repository:

npm install --save neoblocks-common

Usage

Include the module in a JavaScript project.

Example

Get the lastest block from a local NEO node.

const NeoBlocks = require("neoblocks-common");

const config = {
	request: {
		node: "http://127.0.0.1:10332",
		timeout: 30000
	}
};

let service = new NeoBlocks.Service(config);
let blockchain = new NeoBlocks.Blockchain(config);

service.log(["NeoBlocks Agent"]);

const init = async () => {
	let block, height;

	try {
		height = await service.fetch("getblockcount", []);
	} catch (error) {
		service.exit(error)
	};

	try {
		service.log(["Requesting block from node:", (height-1)], "debug");
		block = await service.fetch("getblock", [(height-1), 1]);
	} catch (error) {
		service.exit(error)
	};

	let Block;

	try {
		Block = new blockchain.Block(block);
	} catch (error) {
		service.exit(error);
	};

	if (!service.is.array(block.tx)) { service.exit("Unable to retrieve transactions from block"); };

	for (let index in block.tx) {
		let transaction = block.tx[index];
		try {
			let Transaction = new blockchain.Transaction(transaction);
			for (let index in transaction["vin"]) {
				let Input = new blockchain.Input(transaction["vin"][index]);
				Transaction.vin.push(Input);
			};
			for (let index in transaction["vout"]) {
				let Output = new blockchain.Output(transaction["vout"][index]);
				Transaction.vout.push(Output);
			};
			switch (transaction["type"]) {
				case "MinerTransaction":
					service.validate(transaction, {nonce:0});
					break;
				case "ClaimTransaction":
					service.validate(transaction, {claims:[]});
					Transaction.assign({
						claims: []
					});
					for (let index in transaction["claims"]) {
						let Claim = new blockchain.Claim(transaction["claims"][index]);
						Transaction.claims.push(Claim);
					};
					break;
				case "EnrollmentTransaction":
					service.validate(transaction, {pubkey:""});
					Transaction.assign({
						pubkey: transaction["pubkey"]
					});
					break;
				case "RegisterTransaction":
					service.validate(transaction, {asset:{type:"",name:[],amount:"",precision:0,admin:""}});
					Transaction.assign({
						asset: {
							type: transaction["asset"]["type"],
							name: transaction["asset"]["name"],
							amount: transaction["asset"]["amount"],
							precision: transaction["asset"]["precision"],
							admin: transaction["asset"]["admin"]
						}
					});
					break;
				case "StateTransaction":
					service.validate(transaction, {descriptors:[]});
					Transaction.assign({
						descriptors: []
					});
					for (let index in transaction["descriptors"]) {
						let Descriptor = new blockchain.Descriptor(transaction["descriptors"][index]);
						Transaction.descriptors.push(Descriptor);
					};
					break;
				case "PublishTransaction":
					service.validate(transaction, {contract:{code:{hash:"",script:"",parameters:[],returntype:""},needstorage:true,name:"",version:"",author:"",email:"",description:""}});
					Transaction.assign({
						contract: {
							code: {
								hash: transaction["contract"]["code"]["hash"],
								script: transaction["contract"]["code"]["script"],
								parameters: transaction["contract"]["code"]["parameters"],
								returntype: transaction["contract"]["code"]["returntype"]
							},
							needstorage: transaction["contract"]["needstorage"],
							name: transaction["contract"]["name"],
							version: transaction["contract"]["version"],
							author: transaction["contract"]["author"],
							email: transaction["contract"]["email"],
							description: transaction["contract"]["description"]
						}
					});
					break;
				case "InvocationTransaction":
					service.validate(transaction, {gas:"",script:""});
					Transaction.assign({
						gas: transaction["gas"],
						script: transaction["script"],
						executions: []
					});
					try {
						service.log(["Fetching events for transaction:",transaction["txid"]], "debug");
						let data = await service.fetch("geteventlog", [transaction["txid"]]);
						service.validate(data, {txid:"",executions:[]});
						for (let index in data["executions"]) {
							let execution = data["executions"][index];
							let Execution = new blockchain.Execution(execution);
							let transfers = function (event) {
								let from, to, amount, integer = false;
								if (event["type"] != "Runtime.Notify") { return; };
								if (event["state"]["type"] != "Array") { return; };
								if (event["state"]["value"].length != 4) { return; };
								if (event["state"]["value"][0]["type"] == "ByteArray" && event["state"]["value"][0]["value"] == "7472616e73666572") {
									if (event["state"]["value"][1]["type"] != "ByteArray") { return; }
									if (event["state"]["value"][2]["type"] != "ByteArray") { return; }
									if (event["state"]["value"][3]["type"] != "ByteArray" && event["state"]["value"][3]["type"] != "Integer") { return; }
									try {
										if (event["state"]["value"][1]["value"] == "") {
											from = "";
										} else {
											from = service.neon.wallet.getAddressFromScriptHash(service.neon.u.reverseHex(event["state"]["value"][1]["value"]));
											if (!service.neon.wallet.isAddress(from)) { from = ""; };
										};
										if (event["state"]["value"][2]["value"] == "") {
											to = "";
										} else {
											to = service.neon.wallet.getAddressFromScriptHash(service.neon.u.reverseHex(event["state"]["value"][2]["value"]));
											if (!service.neon.wallet.isAddress(to)) { to = ""; };
										};
										if (event["state"]["value"][3]["value"] == "") {
											amount = 0;
										} else {
											if (event["state"]["value"][3]["type"] == "ByteArray") {
												amount = service.neon.u.Fixed8.fromReverseHex(event["state"]["value"][3]["value"]).toString();
											} else if (event["state"]["value"][3]["type"] == "Integer") {
												amount = event["state"]["value"][3]["value"];
												integer = true;
											};
										};
										return { contract: event["contract"], from: from, to: to, amount: amount, integer: integer };
									} catch (error) {
										return;
									};
								} else {
									return;
								};
							};
							for (let index in execution["events"]) {
								let Event = new blockchain.Event(execution["events"][index]);
								let transfer = transfers(execution["events"][index]);
								Execution.events.push(Event);
								if (transfer) {
									service.log(['Pushing transfer:', transfer])
									Execution.transfers.push(transfer);
								};
							};
							Transaction.executions.push(Execution);
						};
					} catch (error) {
						service.exit(error)
					};				
					break;
			};
			Block.transactions.push(Transaction);
		} catch (error) {
			service.exit(error);
		};
	}

	service.log(JSON.stringify(Block));
};

init();