3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

nem / symbolAdvent Calendar 2024

Day 21

Windows と TypeScript ではじめる Symbol 通信 11【ブロック情報】

Last updated at Posted at 2024-12-20

さて、今回からは普段使いしないところを取得していきます。

ブロックデータの取得

ノードへリクエスト

ブロック情報を取得するパケットタイプは、0x004です。ペイロードにブロック高を指定します。

Catapult.ts
/** パケットタイプ */
private PacketType = {
  PULL_BLOCK: 0x0_04,
  CHAIN_STATISTICS: 0x0_05,
  PUSH_TRANSACTIONS: 0x0_09,
  PUSH_PARTIAL_TRANSACTIONS: 0x1_00,
  NODE_DISCOVERY_PULL_PING: 0x1_11,
  TIME_SYNC_NETWORK_TIME: 0x1_20,
  FINALIZATION_STATISTICS: 0x1_32,
  UNLOCKED_ACCOUNTS: 0x3_04,
}

async getBlock(blockHeight: bigint) {
  let block: models.Block | undefined = undefined
  try {
    const payloadBuffer = new ArrayBuffer(8)
    const payloadDataView = new DataView(payloadBuffer)
    payloadDataView.setBigUint64(0, blockHeight, true)
    const socketData = await this.request(
      this.PacketType.PULL_BLOCK,
      new Uint8Array(payloadBuffer)
    )
    if (socketData) block = models.BlockFactory.deserialize(socketData)
  } catch (e) {
    if (e instanceof Error) console.error(e.message)
    else console.error(e)
  } finally {
    this.close()
  }
  return block
}

レスポンスデータの解析

レスポンスデータの解析は、SDK の models にある BlockFactory クラスのデシリアライザを使用しています。

メインの作成

実行するコードを作成します。

src/mainPullBlock.ts
import { Catapult } from './Catapult.js'

const catapult = new Catapult(
  'cert/ca.crt.pem',
  'cert/node.crt.pem',
  'cert/node.key.pem',
  '127.0.0.1'
)

const block = await catapult.getBlock(1957514n)
if (block) console.log(JSON.stringify(block.toJson(), null, 2))

実行

yarn tsx .\src\mainPullBlock.ts

実行すると以下の様にブロック情報が出力されます。

socket connected.
{
  "signature": "0506F8B9B00A5FDABBFDFB2702862DB6ED9258A80049C25E9D381AB0F8DBB7546A869F603F41BE6CEE2F3EFADD55B4B7739D7157E5B80DEF8E474DC1593DB10A",
  "signerPublicKey": "08FE7A2FEF4660B2E9967C7B457DB8ED280B468E51A608F4DEB8DC400D37B277",
  "version": 1,
  "network": 152,
  "type": 33091,
  "height": "1957514",
  "timestamp": "66642051954",
  "difficulty": "10000000000000",
  "generationHashProof": {
    "gamma": "B3BB75611E082872BC454EADAB81776932308982F36A1F0EA9EB74EFE68F5556",
    "verificationHash": "5D97A1F67DB7AAA8D44E3DB526786F74",
    "scalar": "FAD25677C476173F4919E39B6F2C303AF4B9E9F2534CBA4CC251A9B6CDAE580B"
  },
  "previousBlockHash": "A3EA535C74EA28DC658F5E67090FB6F40727FE223BF1B0EC3C15794C96D06E35",
  "transactionsHash": "3916254AB161D5B50402FE362D909EAAF6795BB76508999EE0E6DE352FE9C224",
  "receiptsHash": "854EB4729606CA953825DF5DE4010ABEB2B5587A4FFB7EBA19236251CD821CA7",
  "stateHash": "5D1E5D787B131A0082364E293F0B75F9D937B5B594F9E4C9411775BEE88DFEA4",
  "beneficiaryAddress": "98E66F6BA1517F5BFB7674F82F628C410C58F057C7AFE33C",
  "feeMultiplier": 100,
  "transactions": [
    {
      "signature": "EE2AA0CC9EE40FE30534989CD6C6E259D368349F7CAD71C71EE201744C5A57DFA6A88354899C778F90B284071399B84FD58C07CE49D7D45B075F1397EDAB070B",
      "signerPublicKey": "769BCFBFFCB5287A902BD83B5CAACB5C2EEFA7FE6129553CA237AD2BCA147A59",
      "version": 2,
      "network": 152,
      "type": 16705,
      "fee": "49600",
      "deadline": "66649216943",
      "transactionsHash": "820A8646B1723B2B18AEC050EB5918574F2AEA846796384A0C19ADDE02206BC1",
      "transactions": [
        {
          "signerPublicKey": "C2C3344415044113C1AA1C119F1CC9EC072000B11BE987A3A9554781EF02F5A2",
          "version": 1,
          "network": 152,
          "type": 16724,
          "recipientAddress": "981797FA9D96B16786AA38F66C6DA7C06B9232442AAE031F",
          "mosaics": [],
          "message": "0048656C6C6F206163636F756E74412046726F6D204D756C7469736967204163636F756E7421"
        }
      ],
      "cosignatures": [
        {
          "version": "0",
          "signerPublicKey": "561B1F2C7A2BB46279E2CC26511755D7DBC55E784F1BF2ED78B938BBEE2C04B3",
          "signature": "16C8B20F5128154ADB3A5E79ABB327994C7E4CBEC88C4AA51C313677B9A4576C7AFD21827782CC253887C1D7E4B658F260EB20D0CA8F53AD3193EF39B097F009"
        },
        {
          "version": "0",
          "signerPublicKey": "958B9422915F544BA56857B0E518839494E893CACBD583C8C2A36028EB04E181",
          "signature": "13E29B3CF4DB1BF4CFCC52E9BD120AD3D35C61065F2953BA76745E10DCA014FA2B85F851EF8A073CA903DDE17E762517C5A6EE98E64898E8453261652532DB0C"
        }
      ]
    },
    {
      "signature": "F50DBE253695FBD1D565A29D858DCA12DBC8A40814F796792537D33C32C0A143E041DEB4F344701D67E872ADA5416F158563292888738C468C6590A3AA35130A",
      "signerPublicKey": "F0B829E77A702AA5BBA2E273ED2E08D44BE66529DC6E3B4118F4AA5D9AD04808",
      "version": 2,
      "network": 152,
      "type": 16705,
      "fee": "47200",
      "deadline": "66649225830",
      "transactionsHash": "A87EA83D7D775D4734D5892F2E4FD7FE975B06C5E5069612446D0C2E9D0E6E73",
      "transactions": [
        {
          "signerPublicKey": "F0B829E77A702AA5BBA2E273ED2E08D44BE66529DC6E3B4118F4AA5D9AD04808",
          "version": 1,
          "network": 152,
          "type": 16724,
          "recipientAddress": "988D15E5136B1C8C3281D390CBF8E5AB83CD564FAC32DCF1",
          "mosaics": [],
          "message": "0048656C6C6F2C206163636F756E7442"
        },
        {
          "signerPublicKey": "3E1D376049A25DC43C6392BF3D980BE9288CCD5F3C017BBD10B74070E80082CB",
          "version": 1,
          "network": 152,
          "type": 16724,
          "recipientAddress": "981797FA9D96B16786AA38F66C6DA7C06B9232442AAE031F",
          "mosaics": [],
          "message": "0048656C6C6F2C206163636F756E744121"
        }
      ],
      "cosignatures": [
        {
          "version": "0",
          "signerPublicKey": "3E1D376049A25DC43C6392BF3D980BE9288CCD5F3C017BBD10B74070E80082CB",
          "signature": "00E50CC87F4BAFB83646DDC8B4E5CEE5F810D824752E593B0F07351832B34F019A5C4511793F750E1FFB2B7C8271BEBFBF5E492FB0BF11F4D983773E8DAF3108"
        }
      ]
    }
  ]
}
socket close: 4

ブロックデータの範囲取得

ノードへリクエスト - ブロックデータの範囲取得

パケットタイプを0x008にすると、範囲指定してブロックを取得出来ます。

ペイロードは以下の通りです。

  • 開始ブロック高
  • ブロック数
  • 最大バイト数

最大バイト数を超えた場合、越えたブロックで打ち切ります。

Catapult.ts
/** パケットタイプ */
private PacketType = {
  PULL_BLOCK: 0x0_04,
  CHAIN_STATISTICS: 0x0_05,
  PULL_BLOCKS: 0x0_08,
  PUSH_TRANSACTIONS: 0x0_09,
  PUSH_PARTIAL_TRANSACTIONS: 0x1_00,
  NODE_DISCOVERY_PULL_PING: 0x1_11,
  TIME_SYNC_NETWORK_TIME: 0x1_20,
  FINALIZATION_STATISTICS: 0x1_32,
  UNLOCKED_ACCOUNTS: 0x3_04,
}

async getBlocks(startHeight: bigint, count: number, maxSize: number) {
  const blocks: models.Block[] = []
  try {
    const payloadBuffer = new ArrayBuffer(16)
    const payloadDataView = new DataView(payloadBuffer)
    payloadDataView.setBigUint64(0, startHeight, true)
    payloadDataView.setInt32(8, count, true)
    payloadDataView.setInt32(12, maxSize, true)
    const socketData = await this.request(
      this.PacketType.PULL_BLOCKS,
      Buffer.from(payloadBuffer)
    )
    if (socketData) {
      let offset = 0
      do {
        const block = models.BlockFactory.deserialize(
          socketData.slice(offset)
        ) as models.Block
        blocks.push(block)
        offset += block.size
      } while (offset < socketData.length)
    }
  } catch (e) {
    if (e instanceof Error) console.error(e.message)
    else console.error(e)
  } finally {
    this.close()
  }
  return blocks
}

レスポンスデータの解析 - ブロックデータの範囲取得

レスポンスデータの解析は、SDK の models にある BlockFactory クラスのデシリアライザを使用しています。

メインの作成 - ブロックデータの範囲取得

実行するコードを作成します。

src/mainPullBlocks.ts
import { Catapult } from './Catapult.js'

const catapult = new Catapult(
  'cert/ca.crt.pem',
  'cert/node.crt.pem',
  'cert/node.key.pem',
  '127.0.0.1'
)

const blocks = await catapult.getBlocks(1959301n, 3, 10240)
if (blocks) {
  for (const block of blocks) {
    console.log(JSON.stringify(block.toJson(), null, 2))
  }
}

実行 - ブロックデータの範囲取得

yarn tsx .\src\mainPullBlocks.ts
socket connected.
{
  "signature": "1697618C2F3CE2B7E2E1A9775AD572F19D4AA069AAE938A94099BC4212D271DD4F8120B1589BAC457D27FC52CF9D9A2C2035EAA71FFFE1EE884F0300FD2B820C",
  "signerPublicKey": "0340F9CA73A93F64CBCCE2E80B2E3F8AF195AAD6DC7B325E5C0A4DE103CDEBEB",
  "version": 1,
  "network": 152,
  "type": 33091,
  "height": "1959301",
  "timestamp": "66697909842",
  "difficulty": "10000000000000",
  "generationHashProof": {
    "gamma": "75194454D16BA9AC22B66F3366686663DAA43B499681C3EDB1A418075F372109",
    "verificationHash": "F3390EB7B89FFD95451EAB10F0EFFD69",
    "scalar": "FCC5BE4DBADCC692C681C5700E571A35BCAADB475170C524B630BB64F5885303"
  },
  "previousBlockHash": "3FD3C84C016F3CCAECCEA61EB3A73E15E053DF22FA9CE896EF550A18E753C8CB",
  "transactionsHash": "0000000000000000000000000000000000000000000000000000000000000000",
  "receiptsHash": "48B520A8D7BF73F375967954C452C2AE653651A260BAEF52D117558C4DADDCC0",
  "stateHash": "FE977512E16227F72E4D2A01D24D5B1F88F6BBEB5169A608169BEBFD86702FB6",
  "beneficiaryAddress": "981B6370BBD45899FA8450342741E92444359C3BE45060A1",
  "feeMultiplier": 0,
  "transactions": []
}
{
  "signature": "5EC54C34B9D29FB233A7C49588EFE0100F278686DD96ECBFC970416A53FF9089864E56677202B76CFA12F6175C540E6793938D1BF6E1FB48724971841B38C704",
  "signerPublicKey": "B8C83E30D74736E90D3318551998016446CF68C98D0932B688FD1463AAE6D125",
  "version": 1,
  "network": 152,
  "type": 33091,
  "height": "1959302",
  "timestamp": "66697943055",
  "difficulty": "10000000000000",
  "generationHashProof": {
    "gamma": "8F1223E615DF66A2368951B3CDF0844F10A1E8380F9C8D9E29EA09113147B423",
    "verificationHash": "CD35F76E5B5FA39309E5957E02581082",
    "scalar": "0E10109F40A49B486FC79F3962D6FF2A51283337102DC184E356EFB17A3F3F0C"
  },
  "previousBlockHash": "B32FFFB785FB598036AB9A71CDA25A0A2AD02FDF76CE477AF8BFA0277B8898FC",
  "transactionsHash": "0000000000000000000000000000000000000000000000000000000000000000",
  "receiptsHash": "5416BE359CBEB0E6EC06BB21F696A8D4D510EB0E80B3980BDEBCA1BBD4DA9ECD",
  "stateHash": "E387BED21A08FE5C2E56158B9CE76243708F1BD7E43EA3F35700B9D0E7EBE326",
  "beneficiaryAddress": "987CCA1A46DDD5D1C4341EA0332FEC10EAF05FA99E53A705",
  "feeMultiplier": 0,
  "transactions": []
}
{
  "signature": "9968D995869A0957FE1866AF59D4B55B4FEA16CD53022076C159D871EEA01F7CCFBB57819DC89BA70C0C9F987DAB4260968612173F3CE669D70336944BE38903",
  "signerPublicKey": "B8C83E30D74736E90D3318551998016446CF68C98D0932B688FD1463AAE6D125",
  "version": 1,
  "network": 152,
  "type": 33091,
  "height": "1959303",
  "timestamp": "66697978241",
  "difficulty": "10000000000000",
  "generationHashProof": {
    "gamma": "74F4CAAA1AC904CE9B8868C07549FEC5ABA35E18EC4553CB61EBCC6CA6356ACD",
    "verificationHash": "97EC11DEC30948DEA97C5ABCDE286CDC",
    "scalar": "B2565845887A6150A9BF261AC13B44F3BC9B75F90B6F16419357536F13884800"
  },
  "previousBlockHash": "8D30DBA16E9EE87097CDA20894F914023ADEA70B3A065D290CA9555D89084171",
  "transactionsHash": "0000000000000000000000000000000000000000000000000000000000000000",
  "receiptsHash": "5416BE359CBEB0E6EC06BB21F696A8D4D510EB0E80B3980BDEBCA1BBD4DA9ECD",
  "stateHash": "BBD845CA7149B3773EE0373F44D9C37026063D1DA5AA0D99DA341E116E07BEE8",
  "beneficiaryAddress": "987CCA1A46DDD5D1C4341EA0332FEC10EAF05FA99E53A705",
  "feeMultiplier": 0,
  "transactions": []
}
socket close: 8
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?