importjsonimportosimporturllib.requestfromsymbolchain.CryptoTypesimportPublicKeyfromsymbolchain.symbol.NetworkimportAddress,NetworkNODE_URL=os.getenv('NODE_URL','https://reference.symboltest.net:3001')print(f'Using node {NODE_URL}')BLOCK_HEIGHT=os.getenv('BLOCK_HEIGHT','3222290')try:# Get the block headerblock_url=f'{NODE_URL}/blocks/{BLOCK_HEIGHT}'withurllib.request.urlopen(block_url)asresponse:block=json.loads(response.read())signer=Network.TESTNET.public_key_to_address(PublicKey(block['block']['signerPublicKey']))beneficiary=block['block']['beneficiaryAddress']print(f'Block height: {BLOCK_HEIGHT}')print(f'Signer: {signer}')beneficiary_b32=Address.from_decoded_address_hex_string(beneficiary)print(f'Beneficiary: {beneficiary_b32}')# Get the network sink addressproperties_url=f'{NODE_URL}/network/properties'withurllib.request.urlopen(properties_url)asresponse:properties=json.loads(response.read())sink_b32=properties['chain']['harvestNetworkFeeSinkAddress']sink=Address(sink_b32).bytes.hex().upper()print(f'Network sink: {sink_b32}')# Get the inflation reward at this heightinflation_url=f'{NODE_URL}/network/inflation/at/{BLOCK_HEIGHT}'withurllib.request.urlopen(inflation_url)asresponse:inflation=json.loads(response.read())reward=int(inflation['rewardAmount'])print(f'Inflation reward: {reward/1e6:,.6f} XYM')# Get harvest fee receipts for this blockreceipts_url=(f'{NODE_URL}/statements/transaction'f'?height={BLOCK_HEIGHT}'f'&receiptType=8515')withurllib.request.urlopen(receipts_url)asresponse:receipts=json.loads(response.read())# Label and display the reward distributiontotal=0print('\nReward distribution:')foriteminreceipts['data']:forrinitem['statement']['receipts']:ifr['type']!=8515:continueamount=int(r['amount'])total+=amounttarget=r['targetAddress']iftarget==sink:label='Network sink (5%)'eliftarget==beneficiary:label='Beneficiary (25%)'else:label='Harvester'harvester_addr=Address.from_decoded_address_hex_string(target)print(f' Harvester address: {harvester_addr}')print(f' {label}: {amount/1e6:,.6f} XYM')# Summaryfees=total-rewardprint('\nSummary:')print(f' Total block reward: {total/1e6:,.6f} XYM')print(f' Inflation: {reward/1e6:,.6f} XYM')print(f' Transaction fees: {fees/1e6:,.6f} XYM')exceptExceptionaserror:print(error)
import{PublicKey}from'symbol-sdk';import{Address,Network}from'symbol-sdk/symbol';constfmt=v=>(v/1e6).toLocaleString('en-US',{minimumFractionDigits:6});constNODE_URL=process.env.NODE_URL||'https://reference.symboltest.net:3001';console.log(`Using node ${NODE_URL}`);constBLOCK_HEIGHT=process.env.BLOCK_HEIGHT||'3222290';// Get the block headerconstblockUrl=`${NODE_URL}/blocks/${BLOCK_HEIGHT}`;constblock=await(awaitfetch(blockUrl)).json();constsigner=Network.TESTNET.publicKeyToAddress(newPublicKey(block.block.signerPublicKey));constbeneficiary=block.block.beneficiaryAddress;console.log(`Block height: ${BLOCK_HEIGHT}`);console.log(`Signer: ${signer}`);constbeneficiaryB32=Address.fromDecodedAddressHexString(beneficiary);console.log(`Beneficiary: ${beneficiaryB32}`);// Get the network sink addressconstpropertiesUrl=`${NODE_URL}/network/properties`;constproperties=await(awaitfetch(propertiesUrl)).json();constsinkB32=properties.chain.harvestNetworkFeeSinkAddress;constsink=Array.from(newAddress(sinkB32).bytes).map(b=>b.toString(16).padStart(2,'0')).join('').toUpperCase();console.log(`Network sink: ${sinkB32}`);// Get the inflation reward at this heightconstinflationUrl=`${NODE_URL}/network/inflation/at/${BLOCK_HEIGHT}`;constinflation=await(awaitfetch(inflationUrl)).json();constreward=parseInt(inflation.rewardAmount,10);console.log(`Inflation reward: ${fmt(reward)} XYM`);// Get harvest fee receipts for this blockconstreceiptsUrl=`${NODE_URL}/statements/transaction`+`?height=${BLOCK_HEIGHT}&receiptType=8515`;constreceipts=await(awaitfetch(receiptsUrl)).json();// Label and display the reward distributionlettotal=0;console.log('\nReward distribution:');for(constitemofreceipts.data){for(constrofitem.statement.receipts){if(8515===r.type){constamount=parseInt(r.amount,10);total+=amount;letlabel;if(r.targetAddress===sink){label='Network sink (5%)';}elseif(r.targetAddress===beneficiary){label='Beneficiary (25%)';}else{label='Harvester';constharvesterAddress=Address.fromDecodedAddressHexString(r.targetAddress);console.log(` Harvester address: ${harvesterAddress}`);}console.log(` ${label}: ${fmt(amount)} XYM`);}}}// Summaryconstfees=total-reward;console.log('\nSummary:');console.log(` Total block reward: ${fmt(total)} XYM`);console.log(` Inflation: ${fmt(reward)} XYM`);console.log(` Transaction fees: ${fmt(fees)} XYM`);
# Get the block headerblock_url=f'{NODE_URL}/blocks/{BLOCK_HEIGHT}'withurllib.request.urlopen(block_url)asresponse:block=json.loads(response.read())signer=Network.TESTNET.public_key_to_address(PublicKey(block['block']['signerPublicKey']))beneficiary=block['block']['beneficiaryAddress']print(f'Block height: {BLOCK_HEIGHT}')print(f'Signer: {signer}')beneficiary_b32=Address.from_decoded_address_hex_string(beneficiary)print(f'Beneficiary: {beneficiary_b32}')
// Get the block headerconstblockUrl=`${NODE_URL}/blocks/${BLOCK_HEIGHT}`;constblock=await(awaitfetch(blockUrl)).json();constsigner=Network.TESTNET.publicKeyToAddress(newPublicKey(block.block.signerPublicKey));constbeneficiary=block.block.beneficiaryAddress;console.log(`Block height: ${BLOCK_HEIGHT}`);console.log(`Signer: ${signer}`);constbeneficiaryB32=Address.fromDecodedAddressHexString(beneficiary);console.log(`Beneficiary: ${beneficiaryB32}`);
# Get the network sink addressproperties_url=f'{NODE_URL}/network/properties'withurllib.request.urlopen(properties_url)asresponse:properties=json.loads(response.read())sink_b32=properties['chain']['harvestNetworkFeeSinkAddress']sink=Address(sink_b32).bytes.hex().upper()print(f'Network sink: {sink_b32}')
// Get the network sink addressconstpropertiesUrl=`${NODE_URL}/network/properties`;constproperties=await(awaitfetch(propertiesUrl)).json();constsinkB32=properties.chain.harvestNetworkFeeSinkAddress;constsink=Array.from(newAddress(sinkB32).bytes).map(b=>b.toString(16).padStart(2,'0')).join('').toUpperCase();console.log(`Network sink: ${sinkB32}`);
# Get the inflation reward at this heightinflation_url=f'{NODE_URL}/network/inflation/at/{BLOCK_HEIGHT}'withurllib.request.urlopen(inflation_url)asresponse:inflation=json.loads(response.read())reward=int(inflation['rewardAmount'])print(f'Inflation reward: {reward/1e6:,.6f} XYM')
// Get the inflation reward at this heightconstinflationUrl=`${NODE_URL}/network/inflation/at/${BLOCK_HEIGHT}`;constinflation=await(awaitfetch(inflationUrl)).json();constreward=parseInt(inflation.rewardAmount,10);console.log(`Inflation reward: ${fmt(reward)} XYM`);
# Get harvest fee receipts for this blockreceipts_url=(f'{NODE_URL}/statements/transaction'f'?height={BLOCK_HEIGHT}'f'&receiptType=8515')withurllib.request.urlopen(receipts_url)asresponse:receipts=json.loads(response.read())# Label and display the reward distributiontotal=0print('\nReward distribution:')foriteminreceipts['data']:forrinitem['statement']['receipts']:ifr['type']!=8515:continueamount=int(r['amount'])total+=amounttarget=r['targetAddress']iftarget==sink:label='Network sink (5%)'eliftarget==beneficiary:label='Beneficiary (25%)'else:label='Harvester'harvester_addr=Address.from_decoded_address_hex_string(target)print(f' Harvester address: {harvester_addr}')print(f' {label}: {amount/1e6:,.6f} XYM')
// Get harvest fee receipts for this blockconstreceiptsUrl=`${NODE_URL}/statements/transaction`+`?height=${BLOCK_HEIGHT}&receiptType=8515`;constreceipts=await(awaitfetch(receiptsUrl)).json();// Label and display the reward distributionlettotal=0;console.log('\nReward distribution:');for(constitemofreceipts.data){for(constrofitem.statement.receipts){if(8515===r.type){constamount=parseInt(r.amount,10);total+=amount;letlabel;if(r.targetAddress===sink){label='Network sink (5%)';}elseif(r.targetAddress===beneficiary){label='Beneficiary (25%)';}else{label='Harvester';constharvesterAddress=Address.fromDecodedAddressHexString(r.targetAddress);console.log(` Harvester address: ${harvesterAddress}`);}console.log(` ${label}: ${fmt(amount)} XYM`);}}}