diff --git a/src/helpers/dbHelper.ts b/src/helpers/dbHelper.ts index 1aff5e5..5022db3 100755 --- a/src/helpers/dbHelper.ts +++ b/src/helpers/dbHelper.ts @@ -14,7 +14,6 @@ import { PgUtil } from '../utilz/pgUtil' import StrUtil from '../utilz/strUtil' import { arrayToMap } from '../utilz/typeConversionUtil' import { WinstonUtil } from '../utilz/winstonUtil' -import { BlockUtil } from '../services/messaging-common/BlockUtil' // postgres // todo fix variable substitution, see #putValueInTable() diff --git a/src/rpc/index.ts b/src/rpc/index.ts index f5dc014..06d0c20 100644 --- a/src/rpc/index.ts +++ b/src/rpc/index.ts @@ -1,24 +1,26 @@ // import the cpntrolers from the controllers folder +// TODO convert this to a single rpc object??? + import { GetAccountInfo } from './get_accountInfo' +import { PushPutBlock } from './push_putBlock' +import { PushPutBlockHash } from './push_putBlockHash' import { StorageGetTransaction } from './storage_getTransaction' import { StorageGetTransactions } from './storage_getTransactions' -import { PushPutBlockHash } from './push_putBlockHash' -import { PushPutBlock } from './push_putBlock' // put the controllers here const controllers = { - storage_getTransactions: StorageGetTransactions.storageGetTransactions, + push_getTransactions: StorageGetTransactions.storageGetTransactions, storage_getTransaction: StorageGetTransaction.storageGetTransaction, - get_accountInfo: GetAccountInfo.getAccountInfo, + push_accountInfo: GetAccountInfo.getAccountInfo, push_putBlockHash: PushPutBlockHash.pushPutBlockHash, push_putBlock: PushPutBlock.pushPutBlock } // put the after test controllers here, keep in mind to keep the function name same as controller const afterController = { - storage_getTransactions: StorageGetTransactions.afterStorageGetTransactions, + push_getTransactions: StorageGetTransactions.afterStorageGetTransactions, storage_getTransaction: StorageGetTransaction.afterStorageGetTransaction, - get_accountInfo: GetAccountInfo.afterGetAccountInfo, + push_accountInfo: GetAccountInfo.afterGetAccountInfo, push_putBlockHash: PushPutBlockHash.afterPushPutBlockHash, push_putBlock: PushPutBlock.afterPushPutBlock } diff --git a/src/rpc/push_putBlock.ts b/src/rpc/push_putBlock.ts index 3114193..2ccbd04 100644 --- a/src/rpc/push_putBlock.ts +++ b/src/rpc/push_putBlock.ts @@ -1,8 +1,8 @@ +import Container from 'typedi' import { z } from 'zod' import LoggerInstance from '../loaders/logger' import StorageNode from '../services/messaging/storageNode' -import Container from 'typedi' const BlockItem = z.object({ id: z.number().optional(), diff --git a/src/services/block/block.ts b/src/services/block/block.ts index 9c327ab..215f5bf 100644 --- a/src/services/block/block.ts +++ b/src/services/block/block.ts @@ -13,18 +13,17 @@ export class Block { } static async getBulkBlocksByHash(blockHashes: string[]) { - const query = `SELECT object_hash FROM blocks WHERE object_hash = ANY($1::text[])`; + const query = `SELECT object_hash FROM blocks WHERE object_hash = ANY($1::text[])` const result = await PgUtil.queryArr<{ id: number; object: string; object_hash: string }>( query, - [blockHashes] - ); - console.log('result:', result); - const foundHashes = result.map((row) => row.object_hash); + [blockHashes] + ) + console.log('result:', result) + const foundHashes = result.map((row) => row.object_hash) const statusArray = blockHashes.map((hash) => foundHashes.includes(hash) ? 'SEND' : 'NOT_SEND' - ); - return { result: statusArray }; -} - + ) + return { result: statusArray } + } } diff --git a/src/services/messaging-common/BlockUtil.ts b/src/services/messaging-common/BlockUtil.ts index bcb66f8..aea087a 100644 --- a/src/services/messaging-common/BlockUtil.ts +++ b/src/services/messaging-common/BlockUtil.ts @@ -1,3 +1,6 @@ +import { Wallet } from 'ethers' +import { Logger } from 'winston' + import { AttestBlockResult, Block, @@ -8,21 +11,19 @@ import { TxValidatorData, Vote } from '../../generated/push/block_pb' -import { EnvLoader } from '../../utilz/envLoader' -import { HashUtil } from '../../utilz/hashUtil' +import { ArrayUtil } from '../../utilz/arrayUtil' import { BitUtil } from '../../utilz/bitUtil' -import StrUtil from '../../utilz/strUtil' import { ChainUtil } from '../../utilz/chainUtil' import { Check } from '../../utilz/check' -import { NumUtil } from '../../utilz/numUtil' -import { EthUtil } from '../../utilz/ethUtil' -import { Logger } from 'winston' -import { WinstonUtil } from '../../utilz/winstonUtil' import DateUtil from '../../utilz/dateUtil' -import { Wallet } from 'ethers' -import { ArrayUtil } from '../../utilz/arrayUtil' +import { EnvLoader } from '../../utilz/envLoader' +import { EthUtil } from '../../utilz/ethUtil' +import { HashUtil } from '../../utilz/hashUtil' +import { NumUtil } from '../../utilz/numUtil' import { SolUtil } from '../../utilz/solUtil' import { StarkNetUtil } from '../../utilz/starkNetUtil' +import StrUtil from '../../utilz/strUtil' +import { WinstonUtil } from '../../utilz/winstonUtil' export class BlockUtil { public static readonly log: Logger = WinstonUtil.newLog(BlockUtil) @@ -94,10 +95,10 @@ export class BlockUtil { // this is used to cache the block contents // Deprecated public static hashBlockIncomplete(blockObj: Block): string { - let txHashes: Uint8Array[] = [] - for (let txObj of blockObj.getTxobjList()) { - let tx = txObj.getTx() - let txHash = BlockUtil.hashTx(tx.serializeBinary()) + const txHashes: Uint8Array[] = [] + for (const txObj of blockObj.getTxobjList()) { + const tx = txObj.getTx() + const txHash = BlockUtil.hashTx(tx.serializeBinary()) txHashes.push(txHash) } return BitUtil.bytesToBase16(HashUtil.sha256ArrayAsBytes(txHashes)) @@ -137,9 +138,9 @@ export class BlockUtil { if (!(caip != null && !StrUtil.isEmpty(caip.addr) && caip.addr.length > 4)) { return null } - let addrWithoutPrefix = !caip.addr.startsWith('0x') ? caip.addr : caip.addr.substring(2) + const addrWithoutPrefix = !caip.addr.startsWith('0x') ? caip.addr : caip.addr.substring(2) const sha = HashUtil.sha256AsBytesEx(BitUtil.stringToBytesUtf(addrWithoutPrefix)) - let shardId = sha[0] + const shardId = sha[0] Check.notNull(shardId) Check.isTrue(shardId >= 0 && shardId <= 255 && NumUtil.isRoundedInteger(shardId)) Check.isTrue(shardCount >= 1) @@ -159,7 +160,7 @@ export class BlockUtil { static calculateAffectedShards(block: Block, shardCount: number): Set { const shards = new Set() for (const txObj of block.getTxobjList()) { - let senderAndRecipients = [txObj.getTx().getSender(), ...txObj.getTx().getRecipientsList()] + const senderAndRecipients = [txObj.getTx().getSender(), ...txObj.getTx().getRecipientsList()] for (const wallet of senderAndRecipients) { const shardId = this.calculateAffectedShard(wallet, shardCount) if (shardId == null) { @@ -172,7 +173,7 @@ export class BlockUtil { } public static checkValidatorTokenFormat(apiTokenBytes: Uint8Array): CheckR { - let token = BitUtil.bytesUtfToString(apiTokenBytes) + const token = BitUtil.bytesUtfToString(apiTokenBytes) if (StrUtil.isEmpty(token) || !token.startsWith(BlockUtil.VAL_TOKEN_PREFIX)) { return CheckR.failWithText( `invalid attestor token; ${StrUtil.fmt(apiTokenBytes)} should start with ${BlockUtil.ATT_TOKEN_PREFIX}` @@ -182,7 +183,7 @@ export class BlockUtil { } public static checkAttestTokenFormat(attestorTokenBytes: Uint8Array): CheckR { - let token = BitUtil.bytesUtfToString(attestorTokenBytes) + const token = BitUtil.bytesUtfToString(attestorTokenBytes) if (StrUtil.isEmpty(token) || !token.startsWith(BlockUtil.ATT_TOKEN_PREFIX)) { return CheckR.failWithText( `invalid attestor token; ${StrUtil.fmt(attestorTokenBytes)} should start with ${BlockUtil.ATT_TOKEN_PREFIX}` @@ -196,8 +197,8 @@ export class BlockUtil { ArrayUtil.isEmpty(tx.getSignature_asU8()), ' clear the signature field first, signature is:' + tx.getSignature() ) - let tmpBytes = tx.serializeBinary() - let sig = await EthUtil.signBytes(evmWallet, tmpBytes) + const tmpBytes = tx.serializeBinary() + const sig = await EthUtil.signBytes(evmWallet, tmpBytes) tx.setSignature(sig) } @@ -206,8 +207,8 @@ export class BlockUtil { ArrayUtil.isEmpty(tx.getSignature_asU8()), ' clear the signature field first, signature is:' + tx.getSignature() ) - let tmpBytes = tx.serializeBinary() - let sig = SolUtil.signBytes(solanaPrivateKey, tmpBytes) + const tmpBytes = tx.serializeBinary() + const sig = SolUtil.signBytes(solanaPrivateKey, tmpBytes) tx.setSignature(sig) } @@ -216,8 +217,8 @@ export class BlockUtil { ArrayUtil.isEmpty(tx.getSignature_asU8()), ' clear the signature field first, signature is:' + tx.getSignature() ) - let tmpBytes = tx.serializeBinary() - let sig = StarkNetUtil.signBytes(starkNetPrivateKey, tmpBytes) + const tmpBytes = tx.serializeBinary() + const sig = StarkNetUtil.signBytes(starkNetPrivateKey, tmpBytes) tx.setSignature(sig) } @@ -231,10 +232,10 @@ export class BlockUtil { } this.log.debug('checking signature `%s`', StrUtil.fmt(tx.getSignature_asU8())) // todo if(tx.getCategory() === 'INIT_DID') or === startsWith("CUSTOM:") or ANY OTHER ? - let sig = tx.getSignature_asU8() - let tmp = Transaction.deserializeBinary(tx.serializeBinary()) + const sig = tx.getSignature_asU8() + const tmp = Transaction.deserializeBinary(tx.serializeBinary()) tmp.setSignature(null) - let tmpBytes = tmp.serializeBinary() + const tmpBytes = tmp.serializeBinary() if (caip.namespace === 'eip155') { // EVM SIGNATURES const recoveredAddr = EthUtil.recoverAddressFromMsg(tmpBytes, sig) @@ -297,7 +298,7 @@ export class BlockUtil { ) } - let validSignature = await BlockUtil.checkTxSignature(tx) + const validSignature = await BlockUtil.checkTxSignature(tx) if (!validSignature.success) { return CheckR.failWithText(`signature field is invalid`) } @@ -306,7 +307,7 @@ export class BlockUtil { public static async checkTxPayload(tx: Transaction): Promise { if (tx.getCategory() === 'INIT_DID') { - let txData = InitDid.deserializeBinary(tx.getData_asU8()) + const txData = InitDid.deserializeBinary(tx.getData_asU8()) if (StrUtil.isEmpty(txData.getMasterpubkey())) { CheckR.failWithText(`masterPubKey missing`) } @@ -327,14 +328,14 @@ export class BlockUtil { // for tests public static async signBlockAsValidator(wallet: Wallet, blockNoSigs: Block) { Check.isTrue(blockNoSigs.getSignersList().length == 0) - for (let txObj of blockNoSigs.getTxobjList()) { - let voteObj = new TxValidatorData() + for (const txObj of blockNoSigs.getTxobjList()) { + const voteObj = new TxValidatorData() voteObj.setVote(Vote.ACCEPTED) txObj.setValidatordata(voteObj) txObj.clearAttestordataList() } const ethSig = await EthUtil.signBytes(wallet, blockNoSigs.serializeBinary()) - let vSign = new Signer() + const vSign = new Signer() vSign.setSig(ethSig) blockNoSigs.setSignersList([vSign]) } @@ -344,12 +345,12 @@ export class BlockUtil { wallet: Wallet, blockSignedByV: Block ): Promise { - let tmpBlock = Block.deserializeBinary(blockSignedByV.serializeBinary()) + const tmpBlock = Block.deserializeBinary(blockSignedByV.serializeBinary()) Check.isTrue(blockSignedByV.getSignersList().length == 1) // tmp block with vsig + attestor data gets signed - let ar = new AttestBlockResult() - for (let txObj of tmpBlock.getTxobjList()) { - let attestorData = new TxAttestorData() + const ar = new AttestBlockResult() + for (const txObj of tmpBlock.getTxobjList()) { + const attestorData = new TxAttestorData() attestorData.setVote(Vote.ACCEPTED) ar.getAttestordataList().push(attestorData) @@ -359,7 +360,7 @@ export class BlockUtil { const ethSig = await EthUtil.signBytes(wallet, tmpBlock.serializeBinary()) // embed attestor data and signature into real object - let aSign = new Signer() + const aSign = new Signer() aSign.setSig(ethSig) ar.setSigner(aSign) return ar @@ -372,7 +373,7 @@ export class BlockUtil { ar: AttestBlockResult ): Promise { for (let txIndex = 0; txIndex < blockSignedByVA.getTxobjList().length; txIndex++) { - let attestDataPerTx = ar.getAttestordataList()[txIndex] + const attestDataPerTx = ar.getAttestordataList()[txIndex] blockSignedByVA.getTxobjList()[txIndex].getAttestordataList().push(attestDataPerTx) } blockSignedByVA.getSignersList().push(ar.getSigner()) @@ -383,17 +384,17 @@ export class BlockUtil { blockSignedByVA: Readonly, ar: AttestBlockResult ): Promise { - let tmpBlock = Block.deserializeBinary(blockSignedByVA.serializeBinary()) + const tmpBlock = Block.deserializeBinary(blockSignedByVA.serializeBinary()) // tx0 -> attest0, ... // is restructured into // block.txObj[0].tx -> attest0, ... for (let txIndex = 0; txIndex < tmpBlock.getTxobjList().length; txIndex++) { - let attestDataPerTx = ar.getAttestordataList()[txIndex] + const attestDataPerTx = ar.getAttestordataList()[txIndex] tmpBlock.getTxobjList()[txIndex].setAttestordataList([attestDataPerTx]) } - let aSignatureBytes = ar.getSigner().getSig_asU8() - let tmpBlockBytes = tmpBlock.serializeBinary() + const aSignatureBytes = ar.getSigner().getSig_asU8() + const tmpBlockBytes = tmpBlock.serializeBinary() this.log.debug('recovery pub key from block with hash: %s', EthUtil.ethHash(tmpBlockBytes)) const attestorNodeId = EthUtil.recoverAddressFromMsg(tmpBlockBytes, aSignatureBytes) this.log.debug('attestorNodeId %o', attestorNodeId) @@ -412,12 +413,12 @@ export class BlockUtil { // validator const validatorSignature = blockSignedByVA.getSignersList()[0]?.getSig_asU8() Check.notNull(validatorSignature, 'validator signature is required') - let tmpBlock = Block.deserializeBinary(blockSignedByVA.serializeBinary()) + const tmpBlock = Block.deserializeBinary(blockSignedByVA.serializeBinary()) tmpBlock.clearSignersList() for (const txObj of tmpBlock.getTxobjList()) { txObj.clearAttestordataList() } - let blockBytesNoSigners = tmpBlock.serializeBinary() + const blockBytesNoSigners = tmpBlock.serializeBinary() const blockValidatorNodeId = EthUtil.recoverAddressFromMsg( blockBytesNoSigners, validatorSignature @@ -425,19 +426,19 @@ export class BlockUtil { BlockUtil.log.debug('signature # %s by %s (validator) ', 0, blockValidatorNodeId) return blockValidatorNodeId } else { - let tmpBlock = Block.deserializeBinary(blockSignedByVA.serializeBinary()) - let onlyVSignature = [blockSignedByVA.getSignersList()[0]] + const tmpBlock = Block.deserializeBinary(blockSignedByVA.serializeBinary()) + const onlyVSignature = [blockSignedByVA.getSignersList()[0]] tmpBlock.setSignersList(onlyVSignature) for (let txIndex = 0; txIndex < tmpBlock.getTxobjList().length; txIndex++) { const txObj = tmpBlock.getTxobjList()[txIndex] - let onlyOneAttestation = blockSignedByVA.getTxobjList()[txIndex].getAttestordataList()[ + const onlyOneAttestation = blockSignedByVA.getTxobjList()[txIndex].getAttestordataList()[ signerIndex - 1 ] txObj.setAttestordataList([onlyOneAttestation]) } - let blockBytesNoSignersAnd1Attest = tmpBlock.serializeBinary() - let attSignature = blockSignedByVA.getSignersList()[signerIndex].getSig_asU8() + const blockBytesNoSignersAnd1Attest = tmpBlock.serializeBinary() + const attSignature = blockSignedByVA.getSignersList()[signerIndex].getSig_asU8() const attNodeId = EthUtil.recoverAddressFromMsg(blockBytesNoSignersAnd1Attest, attSignature) BlockUtil.log.debug('signature # %s by %s ', signerIndex - 1, attNodeId) return attNodeId @@ -472,7 +473,7 @@ export class BlockUtil { let totalTxBytes = 0 for (let i = 0; i < blockSignedByV.getTxobjList().length; i++) { const txObj = blockSignedByV.getTxobjList()[i] - let tx = txObj.getTx() + const tx = txObj.getTx() if (tx == null) { return CheckR.failWithText('empty transaction found!') } @@ -489,11 +490,11 @@ export class BlockUtil { ) { return CheckR.failWithText(`tx # ${i} has invalid validator data`) } - let check1 = await BlockUtil.checkTx(tx) + const check1 = await BlockUtil.checkTx(tx) if (!check1.success) { return check1 } - let check2 = await BlockUtil.checkTxPayload(tx) + const check2 = await BlockUtil.checkTxPayload(tx) if (!check2.success) { return check2 } @@ -528,7 +529,7 @@ export class BlockUtil { validatorsFromContract: Set, valPerBlockFromContract: number ) { - let check1 = await BlockUtil.checkBlockAsAttestor(blockSignedByVA, validatorsFromContract) + const check1 = await BlockUtil.checkBlockAsAttestor(blockSignedByVA, validatorsFromContract) if (!check1.success) { return check1 } @@ -546,10 +547,10 @@ export class BlockUtil { } } - let attestorCount = sigCount - 1 + const attestorCount = sigCount - 1 for (let txIndex = 0; txIndex < blockSignedByVA.getTxobjList().length; txIndex++) { const txObj = blockSignedByVA.getTxobjList()[txIndex] - let tx = txObj.getTx() + const tx = txObj.getTx() if (tx == null) { return CheckR.failWithText('empty transaction found!') } @@ -570,8 +571,8 @@ export class BlockUtil { // do A signature check // this requires clearing all signatures + all attestor data except the current one - let tmpBlock = Block.deserializeBinary(blockSignedByVA.serializeBinary()) - let onlyVSignature = [blockSignedByVA.getSignersList()[0]] + const tmpBlock = Block.deserializeBinary(blockSignedByVA.serializeBinary()) + const onlyVSignature = [blockSignedByVA.getSignersList()[0]] tmpBlock.setSignersList(onlyVSignature) for (let attIndex = 1; attIndex < sigCount; attIndex++) { const attNodeId = await BlockUtil.recoverSignerAddress(blockSignedByVA, attIndex) diff --git a/src/services/messaging/IndexStorage.ts b/src/services/messaging/IndexStorage.ts index b961e47..f118113 100644 --- a/src/services/messaging/IndexStorage.ts +++ b/src/services/messaging/IndexStorage.ts @@ -11,7 +11,6 @@ import { BlockUtil } from '../messaging-common/BlockUtil' import { MessageBlockUtil } from '../messaging-common/messageBlock' import { StorageContractState } from '../messaging-common/storageContractState' import { ValidatorContractState } from '../messaging-common/validatorContractState' -import { BitUtil } from '../../utilz/bitUtil' // stores everything in Postgres (!) @Service() diff --git a/tests/parseBlock.test.ts b/tests/parseBlock.test.ts index 9ec6979..5b9e37b 100644 --- a/tests/parseBlock.test.ts +++ b/tests/parseBlock.test.ts @@ -1,18 +1,15 @@ import { expect } from 'chai' -import { BitUtil } from '../src/utilz/bitUtil' -import { BlockUtil } from '../src/services/messaging-common/BlockUtil' +import { Wallet } from 'ethers' + import { Block, EncryptedText, InitDid, - Signer, Transaction, - TransactionObj, - TxAttestorData, - TxValidatorData, WalletToEncDerivedKey } from '../src/generated/push/block_pb' -import { Wallet } from 'ethers' +import { BlockUtil } from '../src/services/messaging-common/BlockUtil' +import { BitUtil } from '../src/utilz/bitUtil' import StrUtil from '../src/utilz/strUtil' type WalletInfo = { @@ -22,7 +19,7 @@ type WalletInfo = { } // test eth user private keys from hardhat (these are publicly known) -let USER_KEYS: WalletInfo[] = [ +const USER_KEYS: WalletInfo[] = [ { address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', publicKey: null, @@ -50,13 +47,13 @@ async function buildSampleTranaction1() { data.setDerivedkeyindex(1) data.setDerivedpubkey('0xCC') - let et = new EncryptedText() + const et = new EncryptedText() et.setSalt('qaz') et.setNonce('') et.setVersion('push:v5') et.setPrekey('') et.setCiphertext('qwe') - let wa = new WalletToEncDerivedKey() + const wa = new WalletToEncDerivedKey() wa.setEncderivedprivkey(et) wa.setSignature(BitUtil.base16ToBytes('112233')) data.getWallettoencderivedkeyMap().set('0xAA', wa) @@ -82,9 +79,9 @@ async function buildSampleTranaction1() { describe('parsing tests', async function () { it('parse one random transaction', async function () { - let hex = + const hex = '1208494e49545f4449441a336569703135353a313a30786633394664366535316161643838463646346365366142383832373237396366664662393232363622336569703135353a313a30783730393937393730433531383132646333413031304337643031623530653064313764633739433822336569703135353a313a3078334334344364446442366139303066613262353835646432393965303364313246413432393342432a320a043078424210011a043078434322220a0430784141121a0a130a03717765120371617a2207707573683a76351203112233321071d60eecc00f4cc8ac898784a7eeb98f3a9f0f56543165794a756232526c6379493657337369626d396b5a556c6b496a6f694d48686d524546465957593359575a44526d4a694e4755305a44453252454d324e6d4a454d6a417a4f575a6b4e6a41774e454e47593255344969776964484e4e6157787361584d694f6a45334d6a67324e7a45794f4441774d6a4d73496e4a68626d52766255686c65434936496d466a4d32597a4e6a67355a4749794d446c6c596a686d4e4456695a57457a4e4455354d6a526b4e325a6c59545a6a4d546c684e6d4d694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67324e7a45794e5441774d6a4573496e4e3059585231637949364d58307365794a756232526c535751694f69497765446b34526a6c454f5445775157566d4f55497a516a6c424e4455784d7a64685a6a4644515463324e7a566c52446b775954557a4e5455694c434a306330317062477870637949364d5463794f4459334d5449314d4441794d537769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344d5441305a6d49774e54457a4e544a6959546378596a4d345a6a6b354d325a684e445a69593255324e474d325a444d79597a42685a44526c5a5759785a5467784f44566a5a6a56694d44526d596d566a4f474d345954526d4d44686d597a67334d7a426a5a4749344e4463794d6d5a6b595449784d4455334d7a526b4f5755354d474e6a4d7a6c6d5a4745305a6a566b4d5459785a6a6c6a4f5746694e4745794d7a49784d32526c5a47457859794a394c487369626d396b5a556c6b496a6f694d4867354f45593552446b784d45466c5a6a6c434d304935515451314d544d3359575978513045334e6a63315a5551354d4745314d7a55314969776964484e4e6157787361584d694f6a45334d6a67324e7a45794f4441774d6a4173496e4a68626d52766255686c65434936496a6b354e544179596d4d344d5751794e5745324e6a646c4f446c6d59545a6b4e6d59335a44426a5a6d55784e7a646d4f446b795a6a4d694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67324e7a45794e5441774d6a4973496e4e3059585231637949364d58307365794a756232526c535751694f69497765475a45515556685a6a64685a6b4e47596d49305a54526b4d545a45517a5932596b51794d444d355a6d51324d44413051305a6a5a5467694c434a306330317062477870637949364d5463794f4459334d5449314d4441794d537769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344d6d52694e6a59344d5449354e4759304e4756684d7a566d595755785a4752684f4468684d5449795a6a6b314e54426c4e6a67344d7a49775a4759314d7a55314d444a6d4e6a51314e325532596d59794e6d4577597a497a4f47566a4e446c6b4e5446684e474d334d546c6d4f446868597a457a4d57466d4f4749795a5463784f5464684f5759344d47517a4d4441795954686b4f545134597a4d35595455344e44677a4e545977597a517859694a394c487369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67324e7a45794f4441774d6a5173496e4a68626d52766255686c65434936496a597a59574978595755345a446b304d444e6b593249314e7a4d344e475a694e7a45304e445179596d49794d6d49304e6a59784e3255694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d48686d524546465957593359575a44526d4a694e4755305a44453252454d324e6d4a454d6a417a4f575a6b4e6a41774e454e47593255344969776964484e4e6157787361584d694f6a45334d6a67324e7a45794e5441774d6a4973496e4e3059585231637949364d58307365794a756232526c535751694f69497765446b34526a6c454f5445775157566d4f55497a516a6c424e4455784d7a64685a6a4644515463324e7a566c52446b775954557a4e5455694c434a306330317062477870637949364d5463794f4459334d5449314d4441794d697769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344d3251335a4441784d7a64694e4745304d574e6c4e44637a5a546c6a5a6a426b4e446b7a5a5745344f544d30595746685a574978595468695a47466c4e7a466c4d5759794e544d314d4459785a4463324d6a41784d5449794d4459355a54597a4f4755335a54426b4d6d4e69593255314d6d46694e324933597a5a6c4d546b77597a4a6c4e57457a4d3255315954566b5a6a67305a544a6d593256695a6a6c6c5a4467774f446c6b4d6a677859794a395858303d42419d15e53d0e2c03f840553f65a6a09a44912213ff3145b4f5140e8ca8b6f643b7674379a22d64b2ced6b9acfa775fd1195c34b3d072e47a73077c9913a07809a51c4a0130' - let tx = Transaction.deserializeBinary(BitUtil.base16ToBytes(hex)) + const tx = Transaction.deserializeBinary(BitUtil.base16ToBytes(hex)) console.log('signed tx %o', tx.toObject()) const check = await BlockUtil.checkTx(tx) console.log(check) @@ -93,16 +90,16 @@ describe('parsing tests', async function () { }) it('parse one random block', async function () { - let hex = + const hex = '088a83b1fea832229f0f41543165794a756232526c6379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774d7a5973496e4a68626d52766255686c65434936496a4d774d5445304d6a6c694e44457a4d6d49344d5467344d6d4a6c59544a68595746684e445a694d4751774d6d566b4d6a45324e324d694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d48686d524546465957593359575a44526d4a694e4755305a44453252454d324e6d4a454d6a417a4f575a6b4e6a41774e454e47593255344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e4441774f446b73496e4e3059585231637949364d58307365794a756232526c535751694f69497765446b34526a6c454f5445775157566d4f55497a516a6c424e4455784d7a64685a6a4644515463324e7a566c52446b775954557a4e5455694c434a306330317062477870637949364d5463794f446b344f544d304d4441324f537769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344d4441345a546b78595455335a6a6b78595755794d6d4d335a6d4a684e7a4e6b4f4455794d6d5933595441794e7a426a4d324e684d6d49354e324d315a6d5135596a4e6d4d4745774f446b355a6a686a5a5751334d4451794e474e6a5a4459324e4455334e54686d4d4759315a4745784d445a6b4d6a4133595445314d4759334f544934595441774e4441334e446b35597a6c6c5954526b4f5749794d7a597a597a4a694f4749784e7a637859794a394c487369626d396b5a556c6b496a6f694d48686d524546465957593359575a44526d4a694e4755305a44453252454d324e6d4a454d6a417a4f575a6b4e6a41774e454e47593255344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774e544973496e4a68626d52766255686c65434936496a5a6a4e54686b4f5749354d44566d5a5759345a544e6d4e6d51325a4451344e6d55794e7a6c694f5745324f4455774d324d334e6a63694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e4441774e6a4573496e4e3059585231637949364d58307365794a756232526c535751694f69497765446b34526a6c454f5445775157566d4f55497a516a6c424e4455784d7a64685a6a4644515463324e7a566c52446b775954557a4e5455694c434a306330317062477870637949364d5463794f446b344f544d304d4441314e697769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344d5451785957526d4f57497a4e3252684e6d4a6d4f574669593249774d54493259546b304e574a6b4e6d45775a544a695a4749314e6a55774d54466a4e5445775a6a426d5a4749784d444268596a566c4f544d304f4464695a4449794d6a63354d474d305a5445345a445934597a5131595459354e574e6c4e57566b596a526a595451334d4749304f444131596a67354d44686d4e7a63305a57566d4e7a49324d54466c4e6a67335a474d7859794a394c487369626d396b5a556c6b496a6f694d4867354f45593552446b784d45466c5a6a6c434d304935515451314d544d3359575978513045334e6a63315a5551354d4745314d7a55314969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774e6a4573496e4a68626d52766255686c65434936496a59305a574d334e7a6b7a5a44466a4f47526c4d5468694d54466b4f474d354d6d4d784e5749325a444d325a445669596a457a5a446b694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774d7a5173496e4e3059585231637949364d58307365794a756232526c535751694f69497765475a45515556685a6a64685a6b4e47596d49305a54526b4d545a45517a5932596b51794d444d355a6d51324d44413051305a6a5a5467694c434a306330317062477870637949364d5463794f446b344f544d334d4441314d437769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42345a54566b4e4452684d6a59305a6d497a595749305a546732597a4d795a4759795a5451314f446b354d6a5a695a4456684d6a4131595459325a6a426a4d6d517a595445354e44457a4d6d5934595756695a4755325a444a6b5957566d5a575978597a49324d4456694d7a49774d575a6b5a4751334f475130597a426d4f5451354d6a41354e4467344e4449314d545a695957557a4d5449774d5459334e6a5a6b4f44466a4e544d334d7a6b7859794a395858303d12b0120aa1121208494e49545f4449441a37707573683a6465766e65743a7075736831637a786a75707274746465393665386e746a6c746c68753637376d356a64736730667030337422336569703135353a313a30783335423834643638343844313634313531373763363444363435303436363362393938413661623422346569703135353a39373a3078443836333443333942424664343033336330643332383943343531353237353130323432333638312a780a0e6d61737465725f7075625f6b65791a0f646572697665645f7075625f6b657922550a37707573683a6465766e65743a7075736831786b757936367a6736396a7032396d75766e7479327072783877766335363435663979357578121a0a130a03717765120371617a2207707573683a7635120301020332100488e6448aea455f9bd685e2386117143a9f0f56543165794a756232526c6379493657337369626d396b5a556c6b496a6f694d48686d524546465957593359575a44526d4a694e4755305a44453252454d324e6d4a454d6a417a4f575a6b4e6a41774e454e47593255344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774e444973496e4a68626d52766255686c65434936496d5a68597a68684f544d785a474d304d47597a4e324d30596d4e6d59544a694d4451354d444d774f4749325957526b59544e69595751694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e4441774e6a4573496e4e3059585231637949364d58307365794a756232526c535751694f69497765446b34526a6c454f5445775157566d4f55497a516a6c424e4455784d7a64685a6a4644515463324e7a566c52446b775954557a4e5455694c434a306330317062477870637949364d5463794f446b344f544d304d4441314e697769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344f4464684d54646d4f444d314e446332595449794f4455794e32497a596d49345a6a59784f44646a4e475977597a51304e5745354d6d526a4e4455305a6d526b4f47566d4d4467325a54557a5a5451774f5746685a54526b4f544d3059324e6a5a4449334d475a6a4e444d785954557a4e6d566c4e444a6c4d4752695a6d56685a6a557a4d4442694e7a45314d6a4d344e6a41324e7a42685a6d526b5a5463345a5467334d5755774e6a417859694a394c487369626d396b5a556c6b496a6f694d4867354f45593552446b784d45466c5a6a6c434d304935515451314d544d3359575978513045334e6a63315a5551354d4745314d7a55314969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774d7a5173496e4a68626d52766255686c65434936496a5177597a646c4e54466a4d7a686b4d6a5268596a49334d5445784e325a6b4f5756684d5449304d546b774e4467774d574534596a67694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e4441774e7a6b73496e4e3059585231637949364d58307365794a756232526c535751694f69497765475a45515556685a6a64685a6b4e47596d49305a54526b4d545a45517a5932596b51794d444d355a6d51324d44413051305a6a5a5467694c434a306330317062477870637949364d5463794f446b344f544d304d4441344f437769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344e6a6c6a4e32597a5a5445784d44526c596d59784d6a5531597a4d304d6a426b5a475268593245344e7a5a6b596a5a68596a49345932566d595449334e546b30597a566d4d575130596a4d355a546731597a517a5a6a526b4f5751794e7a6b774f5751324e4759785a4459334e4459304e47497a4d5745344e3252684f5749354e544e6d5a6a566b4e4755774e47466b597a5a6d4d4455314d7a59305a574a68595449344d7a59355954517859794a394c487369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774e544173496e4a68626d52766255686c65434936496a4d7a4e4751785a54466959545a6b4e7a5533595459774e7a6c6b4d324a684d6a4269595467344d6d597a5a54566c4e7a51324d5755694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d48686d524546465957593359575a44526d4a694e4755305a44453252454d324e6d4a454d6a417a4f575a6b4e6a41774e454e47593255344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774d7a6373496e4e3059585231637949364d58307365794a756232526c535751694f69497765446b34526a6c454f5445775157566d4f55497a516a6c424e4455784d7a64685a6a4644515463324e7a566c52446b775954557a4e5455694c434a306330317062477870637949364d5463794f446b344f544d334d44417a4d437769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344d7a6c6d5a6a4d335a4745324e7a526b4e474d334d54646a4e7a59354e54566c4d6a45334f4441305a6d5930595452695a446b335a6a6c6b4d44466a4e5759315a5755344e6a59794e4759794d325a694e57497a4f44426c4e324d794d54426a597a646a5a6a5a69596d59344d4463784d4451315a47466c4d546b78596a45355a4749304e32526959544934596a49314d546b304f546868597a4e6d4d474e694e5459324f574e6a4d6d457859794a395858303d424041863861637a97d94ab2fdb78aea7821a037e40b2cb62c0ac474790c92ff675558a9f0ab2edbdbb389100c4ca56724578ca296e5d8f36f8cc3621fd782a00a534a0130120208011a0208011a0208011a430a415f4164f72053d9a3e214fa018253e4c5cf3e91e4b9a715f0693a8b0404f2467768590cb40a5d80e75e43d6935f80217f43f5f17a809fadca7f0330af828b343e1b1a430a410fb7a01c3de228bae14fa0475106cb4a11119472e9d910c83cd17ef2b6632b540923c00cd8eb95198adea16c01ccd444b5bea6642d59a9dc699a0a56452dc8f71c1a430a418be571593d353019019fe2a17017b7669598a9ed134b052ac553cca0d96955d832fd6f3c027a44519108e8fd5b903461088697725fbb47076fe660b6ea8adb5a1b' - let b = Block.deserializeBinary(BitUtil.base16ToBytes(hex)) + const b = Block.deserializeBinary(BitUtil.base16ToBytes(hex)) console.log('b %o', b.toObject()) }) }) describe('normal tests', async function () { it.only('generate a transaction', async function () { - let tx = await buildSampleTranaction1() + const tx = await buildSampleTranaction1() console.log('signed tx %s bytes', BitUtil.bytesToBase16(tx.serializeBinary())) console.log('signed tx %o', tx.toObject()) console.log('signed tx %s (compact print)', StrUtil.fmtProtoObj(tx)) @@ -114,9 +111,9 @@ describe('normal tests', async function () { }) it('parse one random block', async function () { - let hex = + const hex = '088a83b1fea832229f0f41543165794a756232526c6379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774d7a5973496e4a68626d52766255686c65434936496a4d774d5445304d6a6c694e44457a4d6d49344d5467344d6d4a6c59544a68595746684e445a694d4751774d6d566b4d6a45324e324d694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d48686d524546465957593359575a44526d4a694e4755305a44453252454d324e6d4a454d6a417a4f575a6b4e6a41774e454e47593255344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e4441774f446b73496e4e3059585231637949364d58307365794a756232526c535751694f69497765446b34526a6c454f5445775157566d4f55497a516a6c424e4455784d7a64685a6a4644515463324e7a566c52446b775954557a4e5455694c434a306330317062477870637949364d5463794f446b344f544d304d4441324f537769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344d4441345a546b78595455335a6a6b78595755794d6d4d335a6d4a684e7a4e6b4f4455794d6d5933595441794e7a426a4d324e684d6d49354e324d315a6d5135596a4e6d4d4745774f446b355a6a686a5a5751334d4451794e474e6a5a4459324e4455334e54686d4d4759315a4745784d445a6b4d6a4133595445314d4759334f544934595441774e4441334e446b35597a6c6c5954526b4f5749794d7a597a597a4a694f4749784e7a637859794a394c487369626d396b5a556c6b496a6f694d48686d524546465957593359575a44526d4a694e4755305a44453252454d324e6d4a454d6a417a4f575a6b4e6a41774e454e47593255344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774e544973496e4a68626d52766255686c65434936496a5a6a4e54686b4f5749354d44566d5a5759345a544e6d4e6d51325a4451344e6d55794e7a6c694f5745324f4455774d324d334e6a63694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e4441774e6a4573496e4e3059585231637949364d58307365794a756232526c535751694f69497765446b34526a6c454f5445775157566d4f55497a516a6c424e4455784d7a64685a6a4644515463324e7a566c52446b775954557a4e5455694c434a306330317062477870637949364d5463794f446b344f544d304d4441314e697769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344d5451785957526d4f57497a4e3252684e6d4a6d4f574669593249774d54493259546b304e574a6b4e6d45775a544a695a4749314e6a55774d54466a4e5445775a6a426d5a4749784d444268596a566c4f544d304f4464695a4449794d6a63354d474d305a5445345a445934597a5131595459354e574e6c4e57566b596a526a595451334d4749304f444131596a67354d44686d4e7a63305a57566d4e7a49324d54466c4e6a67335a474d7859794a394c487369626d396b5a556c6b496a6f694d4867354f45593552446b784d45466c5a6a6c434d304935515451314d544d3359575978513045334e6a63315a5551354d4745314d7a55314969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774e6a4573496e4a68626d52766255686c65434936496a59305a574d334e7a6b7a5a44466a4f47526c4d5468694d54466b4f474d354d6d4d784e5749325a444d325a445669596a457a5a446b694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774d7a5173496e4e3059585231637949364d58307365794a756232526c535751694f69497765475a45515556685a6a64685a6b4e47596d49305a54526b4d545a45517a5932596b51794d444d355a6d51324d44413051305a6a5a5467694c434a306330317062477870637949364d5463794f446b344f544d334d4441314d437769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42345a54566b4e4452684d6a59305a6d497a595749305a546732597a4d795a4759795a5451314f446b354d6a5a695a4456684d6a4131595459325a6a426a4d6d517a595445354e44457a4d6d5934595756695a4755325a444a6b5957566d5a575978597a49324d4456694d7a49774d575a6b5a4751334f475130597a426d4f5451354d6a41354e4467344e4449314d545a695957557a4d5449774d5459334e6a5a6b4f44466a4e544d334d7a6b7859794a395858303d12b0120aa1121208494e49545f4449441a37707573683a6465766e65743a7075736831637a786a75707274746465393665386e746a6c746c68753637376d356a64736730667030337422336569703135353a313a30783335423834643638343844313634313531373763363444363435303436363362393938413661623422346569703135353a39373a3078443836333443333942424664343033336330643332383943343531353237353130323432333638312a780a0e6d61737465725f7075625f6b65791a0f646572697665645f7075625f6b657922550a37707573683a6465766e65743a7075736831786b757936367a6736396a7032396d75766e7479327072783877766335363435663979357578121a0a130a03717765120371617a2207707573683a7635120301020332100488e6448aea455f9bd685e2386117143a9f0f56543165794a756232526c6379493657337369626d396b5a556c6b496a6f694d48686d524546465957593359575a44526d4a694e4755305a44453252454d324e6d4a454d6a417a4f575a6b4e6a41774e454e47593255344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774e444973496e4a68626d52766255686c65434936496d5a68597a68684f544d785a474d304d47597a4e324d30596d4e6d59544a694d4451354d444d774f4749325957526b59544e69595751694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e4441774e6a4573496e4e3059585231637949364d58307365794a756232526c535751694f69497765446b34526a6c454f5445775157566d4f55497a516a6c424e4455784d7a64685a6a4644515463324e7a566c52446b775954557a4e5455694c434a306330317062477870637949364d5463794f446b344f544d304d4441314e697769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344f4464684d54646d4f444d314e446332595449794f4455794e32497a596d49345a6a59784f44646a4e475977597a51304e5745354d6d526a4e4455305a6d526b4f47566d4d4467325a54557a5a5451774f5746685a54526b4f544d3059324e6a5a4449334d475a6a4e444d785954557a4e6d566c4e444a6c4d4752695a6d56685a6a557a4d4442694e7a45314d6a4d344e6a41324e7a42685a6d526b5a5463345a5467334d5755774e6a417859694a394c487369626d396b5a556c6b496a6f694d4867354f45593552446b784d45466c5a6a6c434d304935515451314d544d3359575978513045334e6a63315a5551354d4745314d7a55314969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774d7a5173496e4a68626d52766255686c65434936496a5177597a646c4e54466a4d7a686b4d6a5268596a49334d5445784e325a6b4f5756684d5449304d546b774e4467774d574534596a67694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e4441774e7a6b73496e4e3059585231637949364d58307365794a756232526c535751694f69497765475a45515556685a6a64685a6b4e47596d49305a54526b4d545a45517a5932596b51794d444d355a6d51324d44413051305a6a5a5467694c434a306330317062477870637949364d5463794f446b344f544d304d4441344f437769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344e6a6c6a4e32597a5a5445784d44526c596d59784d6a5531597a4d304d6a426b5a475268593245344e7a5a6b596a5a68596a49345932566d595449334e546b30597a566d4d575130596a4d355a546731597a517a5a6a526b4f5751794e7a6b774f5751324e4759785a4459334e4459304e47497a4d5745344e3252684f5749354e544e6d5a6a566b4e4755774e47466b597a5a6d4d4455314d7a59305a574a68595449344d7a59355954517859794a394c487369626d396b5a556c6b496a6f694d4867345a5445795a4555784d6b4d7a4e575642516d597a4e5749314e6d49774e4555314d304d30525451324f4755304e6a63794e3055344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774e544173496e4a68626d52766255686c65434936496a4d7a4e4751785a54466959545a6b4e7a5533595459774e7a6c6b4d324a684d6a4269595467344d6d597a5a54566c4e7a51324d5755694c434a776157356e556d567a645778306379493657337369626d396b5a556c6b496a6f694d48686d524546465957593359575a44526d4a694e4755305a44453252454d324e6d4a454d6a417a4f575a6b4e6a41774e454e47593255344969776964484e4e6157787361584d694f6a45334d6a67354f446b7a4e7a41774d7a6373496e4e3059585231637949364d58307365794a756232526c535751694f69497765446b34526a6c454f5445775157566d4f55497a516a6c424e4455784d7a64685a6a4644515463324e7a566c52446b775954557a4e5455694c434a306330317062477870637949364d5463794f446b344f544d334d44417a4d437769633352686448567a496a6f7866563073496e4e705a323568644856795a534936496a42344d7a6c6d5a6a4d335a4745324e7a526b4e474d334d54646a4e7a59354e54566c4d6a45334f4441305a6d5930595452695a446b335a6a6c6b4d44466a4e5759315a5755344e6a59794e4759794d325a694e57497a4f44426c4e324d794d54426a597a646a5a6a5a69596d59344d4463784d4451315a47466c4d546b78596a45355a4749304e32526959544934596a49314d546b304f546868597a4e6d4d474e694e5459324f574e6a4d6d457859794a395858303d424041863861637a97d94ab2fdb78aea7821a037e40b2cb62c0ac474790c92ff675558a9f0ab2edbdbb389100c4ca56724578ca296e5d8f36f8cc3621fd782a00a534a0130120208011a0208011a0208011a430a415f4164f72053d9a3e214fa018253e4c5cf3e91e4b9a715f0693a8b0404f2467768590cb40a5d80e75e43d6935f80217f43f5f17a809fadca7f0330af828b343e1b1a430a410fb7a01c3de228bae14fa0475106cb4a11119472e9d910c83cd17ef2b6632b540923c00cd8eb95198adea16c01ccd444b5bea6642d59a9dc699a0a56452dc8f71c1a430a418be571593d353019019fe2a17017b7669598a9ed134b052ac553cca0d96955d832fd6f3c027a44519108e8fd5b903461088697725fbb47076fe660b6ea8adb5a1b' - let b = Block.deserializeBinary(BitUtil.base16ToBytes(hex)) + const b = Block.deserializeBinary(BitUtil.base16ToBytes(hex)) console.log('b %o', b.toObject()) }) })