importjsonimportosimporturllib.requestfromsymbolchain.CryptoTypesimportHash256fromsymbolchain.symbol.MerkleimportMerklePart,prove_merkleNODE_URL=os.getenv('NODE_URL','https://reference.symboltest.net:3001')print(f'Using node {NODE_URL}')TX_HASH=os.getenv('TRANSACTION_HASH','99011A8DBC086E0C359E9D8A38FEC6714C33726FCD0C1B5C0F772A82400D808B')print(f'Transaction hash: {TX_HASH}')try:# Fetch the confirmed transaction to get its block heighttx_path=f'/transactions/confirmed/{TX_HASH}'print(f'Fetching transaction from {tx_path}')withurllib.request.urlopen(f'{NODE_URL}{tx_path}')asresponse:tx_data=json.loads(response.read().decode())print(json.dumps(tx_data['meta'],indent=2))block_height=tx_data['meta']['height']merkle_component_hash=Hash256(tx_data['meta']['merkleComponentHash'])# Fetch the block header to get the transactions hashblock_path=f'/blocks/{block_height}'print(f'Fetching block from {block_path}')withurllib.request.urlopen(f'{NODE_URL}{block_path}')asresponse:block_data=json.loads(response.read().decode())print(json.dumps({'height':block_data['block']['height'],'transactionsHash':block_data['block']['transactionsHash'],},indent=2))transactions_hash=Hash256(block_data['block']['transactionsHash'])# Fetch the merkle proof path for the transactionmerkle_path=(f'/blocks/{block_height}'f'/transactions/{TX_HASH}/merkle')print('Fetching merkle proof:')print(f' {merkle_path}')withurllib.request.urlopen(f'{NODE_URL}{merkle_path}')asresponse:merkle_data=json.loads(response.read().decode())print(json.dumps(merkle_data,indent=2))# Convert the API response to the format expected by the SDKmerkle_proof_path=[MerklePart(Hash256(part['hash']),part['position']=='left')forpartinmerkle_data['merklePath']]print(f' Merkle path length: {len(merkle_proof_path)}')# Verify that the transaction is included in the blockis_proven=prove_merkle(merkle_component_hash,merkle_proof_path,transactions_hash)ifis_proven:print(f'Transaction {TX_HASH[:16]}...'f' proven in block {block_height}')else:raiseRuntimeError(f'Transaction {TX_HASH[:16]}...'f' NOT proven in block {block_height}')exceptExceptionase:print(e)
import{Hash256}from'symbol-sdk';import{proveMerkle}from'symbol-sdk/symbol';constNODE_URL=process.env.NODE_URL||'https://reference.symboltest.net:3001';console.log('Using node',NODE_URL);constTX_HASH=process.env.TRANSACTION_HASH||'99011A8DBC086E0C359E9D8A38FEC6714C33726FCD0C1B5C0F772A82400D808B';console.log('Transaction hash:',TX_HASH);try{// Fetch the confirmed transaction to get its block heightconsttxPath=`/transactions/confirmed/${TX_HASH}`;console.log('Fetching transaction from',txPath);consttxResponse=awaitfetch(`${NODE_URL}${txPath}`);consttxData=awaittxResponse.json();console.log(JSON.stringify(txData.meta,undefined,2));constblockHeight=txData.meta.height;constmerkleComponentHash=newHash256(txData.meta.merkleComponentHash);// Fetch the block header to get the transactions hashconstblockPath=`/blocks/${blockHeight}`;console.log('Fetching block from',blockPath);constblockResponse=awaitfetch(`${NODE_URL}${blockPath}`);constblockData=awaitblockResponse.json();console.log(JSON.stringify({height:blockData.block.height,transactionsHash:blockData.block.transactionsHash,},undefined,2));consttransactionsHash=newHash256(blockData.block.transactionsHash);// Fetch the merkle proof path for the transactionconstmerklePath=`/blocks/${blockHeight}`+`/transactions/${TX_HASH}/merkle`;console.log('Fetching merkle proof:');console.log(` ${merklePath}`);constmerkleResponse=awaitfetch(`${NODE_URL}${merklePath}`);constmerkleData=awaitmerkleResponse.json();console.log(JSON.stringify(merkleData,undefined,2));// Convert the API response to the format expected by the SDKconstmerkleProofPath=merkleData.merklePath.map(part=>({hash:newHash256(part.hash),isLeft:part.position==='left',}));console.log(' Merkle path length:',merkleProofPath.length);// Verify that the transaction is included in the blockconstisProven=proveMerkle(merkleComponentHash,merkleProofPath,transactionsHash);if(isProven){console.log(`Transaction ${TX_HASH.slice(0,16)}...`+` proven in block ${blockHeight}`);}else{thrownewError(`Transaction ${TX_HASH.slice(0,16)}...`+` NOT proven in block ${blockHeight}`);}}catch(e){console.error(e.message);}
# Fetch the confirmed transaction to get its block heighttx_path=f'/transactions/confirmed/{TX_HASH}'print(f'Fetching transaction from {tx_path}')withurllib.request.urlopen(f'{NODE_URL}{tx_path}')asresponse:tx_data=json.loads(response.read().decode())print(json.dumps(tx_data['meta'],indent=2))block_height=tx_data['meta']['height']merkle_component_hash=Hash256(tx_data['meta']['merkleComponentHash'])
// Fetch the confirmed transaction to get its block heightconsttxPath=`/transactions/confirmed/${TX_HASH}`;console.log('Fetching transaction from',txPath);consttxResponse=awaitfetch(`${NODE_URL}${txPath}`);consttxData=awaittxResponse.json();console.log(JSON.stringify(txData.meta,undefined,2));constblockHeight=txData.meta.height;constmerkleComponentHash=newHash256(txData.meta.merkleComponentHash);
# Fetch the block header to get the transactions hashblock_path=f'/blocks/{block_height}'print(f'Fetching block from {block_path}')withurllib.request.urlopen(f'{NODE_URL}{block_path}')asresponse:block_data=json.loads(response.read().decode())print(json.dumps({'height':block_data['block']['height'],'transactionsHash':block_data['block']['transactionsHash'],},indent=2))transactions_hash=Hash256(block_data['block']['transactionsHash'])
// Fetch the block header to get the transactions hashconstblockPath=`/blocks/${blockHeight}`;console.log('Fetching block from',blockPath);constblockResponse=awaitfetch(`${NODE_URL}${blockPath}`);constblockData=awaitblockResponse.json();console.log(JSON.stringify({height:blockData.block.height,transactionsHash:blockData.block.transactionsHash,},undefined,2));consttransactionsHash=newHash256(blockData.block.transactionsHash);
# Fetch the merkle proof path for the transactionmerkle_path=(f'/blocks/{block_height}'f'/transactions/{TX_HASH}/merkle')print('Fetching merkle proof:')print(f' {merkle_path}')withurllib.request.urlopen(f'{NODE_URL}{merkle_path}')asresponse:merkle_data=json.loads(response.read().decode())print(json.dumps(merkle_data,indent=2))# Convert the API response to the format expected by the SDKmerkle_proof_path=[MerklePart(Hash256(part['hash']),part['position']=='left')forpartinmerkle_data['merklePath']]print(f' Merkle path length: {len(merkle_proof_path)}')
// Fetch the merkle proof path for the transactionconstmerklePath=`/blocks/${blockHeight}`+`/transactions/${TX_HASH}/merkle`;console.log('Fetching merkle proof:');console.log(` ${merklePath}`);constmerkleResponse=awaitfetch(`${NODE_URL}${merklePath}`);constmerkleData=awaitmerkleResponse.json();console.log(JSON.stringify(merkleData,undefined,2));// Convert the API response to the format expected by the SDKconstmerkleProofPath=merkleData.merklePath.map(part=>({hash:newHash256(part.hash),isLeft:part.position==='left',}));console.log(' Merkle path length:',merkleProofPath.length);
# Verify that the transaction is included in the blockis_proven=prove_merkle(merkle_component_hash,merkle_proof_path,transactions_hash)ifis_proven:print(f'Transaction {TX_HASH[:16]}...'f' proven in block {block_height}')else:raiseRuntimeError(f'Transaction {TX_HASH[:16]}...'f' NOT proven in block {block_height}')
// Verify that the transaction is included in the blockconstisProven=proveMerkle(merkleComponentHash,merkleProofPath,transactionsHash);if(isProven){console.log(`Transaction ${TX_HASH.slice(0,16)}...`+` proven in block ${blockHeight}`);}else{thrownewError(`Transaction ${TX_HASH.slice(0,16)}...`+` NOT proven in block ${blockHeight}`);}