最終更新:
編集

バイナリフォーマット

[ソース]

このページでは、XRP Ledgerのトランザクションとその他のデータの正規バイナリフォーマットについて説明します。このバイナリフォーマットは、トランザクションの内容のデジタル署名を作成および検証するために必要であり、サーバ間のピアツーピア通信を含む他の用途にも使用されます。通常、rippled APIは、JSONを使用してクライアントアプリケーションと通信します。ただしJSONは、同じデータをさまざまな同等の方法で表現できるため、デジタル署名を付与するトランザクションをシリアル化するのに適したフォーマットではありません。

トランザクションをJSONまたはその他の表現から正規バイナリフォーマットへシリアル化するプロセスのステップを、以下にまとめます。

  1. すべての必須フィールドが指定されていること(必須の「自動入力可能」フィールドを含む)を確認します。

    トランザクションフォーマットリファレンスに、XRP Ledgerトランザクションの必須フィールドと省略可能なフィールドが定義されています。

    注記
    SigningPubKeyもこのステップで指定する必要があります。署名の際に、署名用に指定された秘密鍵からこのキーを導出できます。

  2. 各フィールドのデータを「内部」バイナリフォーマットに変換します。

  3. フィールドを正規順序でソートします。

  4. 各フィールドの前にフィールドIDを付加します。

  5. フィールド(プレフィクスを含む)をソート順に連結します。

その結果、ECDSA(secp256k1楕円曲線を使用)やEd25519などの既知の署名アルゴリズムを使用して署名できるバイナリBlobが1つ作成されます。XRP Ledgerのために、適切なプレフィクス(シングル署名の場合は0x53545800、マルシグの場合は0x534D5400)を使用してデータをハッシュ化する必要があります。署名後に、指定されているTxnSignatureフィールドを使用してトランザクションを再度シリアル化する必要があります。

注記
XRP Ledgerでは、レジャーオブジェクトや処理済みのトランザクションなど他のタイプのデータを表す場合にも同じシリアル化フォーマットが使用されます。ただし、署名されるトランザクションに追加するのに適切なフィールドは限られています。(たとえば署名自体が指定されているTxnSignatureフィールドは、署名するバイナリBlobに含まれていてはなりません。)このように、「署名」フィールドとされてオブジェクトに署名するときにオブジェクトに含まれるフィールドもあれば、「非署名」とされてオブジェクトに含まれないフィールドもあります。

署名済みトランザクションと未署名のトランザクションはいずれも、JSONフォーマットとバイナリフォーマットの両方で表すことができます。同じ署名済みトランザクションのJSONフォーマットとバイナリフォーマットの例を以下に示します。

JSON:

{
  "Account": "rMBzp8CgpE441cp5PVyA9rpVV7oT8hP3ys",
  "Expiration": 595640108,
  "Fee": "10",
  "Flags": 524288,
  "OfferSequence": 1752791,
  "Sequence": 1752792,
  "SigningPubKey": "03EE83BB432547885C219634A1BC407A9DB0474145D69737D09CCDC63E1DEE7FE3",
  "TakerGets": "15000000000",
  "TakerPays": {
    "currency": "USD",
    "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
    "value": "7072.8"
  },
  "TransactionType": "OfferCreate",
  "TxnSignature": "30440220143759437C04F7B61F012563AFE90D8DAFC46E86035E1D965A9CED282C97D4CE02204CFD241E86F17E011298FC1A39B63386C74306A5DE047E213B0F29EFA4571C2C",
  "hash": "73734B611DDA23D3F5F62E20A173B78AB8406AC5015094DA53F53D39B9EDB06C"
}

バイナリ(16進数として表現):

120007220008000024001ABED82A2380BF2C2019001ABED764D55920AC9391400000000000000000000000000055534400000000000A20B3C85F482532A9578DBB3950B85CA06594D165400000037E11D60068400000000000000A732103EE83BB432547885C219634A1BC407A9DB0474145D69737D09CCDC63E1DEE7FE3744630440220143759437C04F7B61F012563AFE90D8DAFC46E86035E1D965A9CED282C97D4CE02204CFD241E86F17E011298FC1A39B63386C74306A5DE047E213B0F29EFA4571C2C8114DD76483FACDEE26E60D8A586BB58D09F27045C46

サンプルコード

ここで説明するシリアル化プロセスは複数の場所にさまざまなプログラミング言語で実装されています。

これらのすべての実装には、一般利用が可能なオープンソースライセンスが提供されているので、学習のためにドキュメントと合わせて使用するだけでなく、必要に応じてコードをインポート、使用、または変更することができます。

内部フォーマット

各フィールドには「内部」バイナリフォーマットがあります。このフォーマットは、rippledソースコードで署名時に(およびその他のほとんどの場合に)そのフィールドを表示するのに使用されます。すべてのフィールドの内部フォーマットは、SField.cppのソースコードに定義されています。(このフィールドには、トランザクションフィールド以外のフィールドも含まれています。)トランザクションフォーマットリファレンスにも、すべてのトランザクションフィールドの内部フォーマットが記載されています。

たとえばFlags共通トランザクションフィールドはUInt32(32ビット符号なし整数)になります。

定義ファイル

以下のJSONファイルには、XRP Ledgerデータをそのバイナリフォーマットにシリアル化し、バイナリからシリアル化解除するのに必要な重要な定数が定義されています。

https://github.com/ripple/ripple-binary-codec/blob/master/src/enums/definitions.json

この定義ファイルの最上位フィールドの定義を以下の表に示します。

フィールド内容
TYPESフィールドIDの作成と正規順序でのフィールドのソートのためのデータタイプからその「タイプコード」へのマップ。1未満のコードは実際のデータには含まれません。10000を超えるコードは、他のオブジェクト内部ではシリアル化できない「トランザクション」などの特殊な「上位」オブジェクトタイプを表します。各タイプのシリアル化方法についての詳細は、タイプリストをご覧ください。
LEDGER_ENTRY_TYPESレジャーオブジェクトから対応するデータタイプへのマップ。これはレジャー状態データと、処理されたトランザクションのメタデータの「affected nodes」セクションに含まれます。
FIELDSトランザクション、レジャーオブジェクト、あるいはその他のデータに含まれる可能性があるすべてのフィールドを表すタプルからなるソート済み配列。各タプルの1番目のメンバーはフィールドの文字列名であり、2番目のメンバーはそのフィールドのプロパティーが含まれているオブジェクトです。(これらのフィールドの定義については、以下の「フィールドプロパティー」の表をご覧ください。)
TRANSACTION_RESULTSトランザクション結果コードから対応する数値へのマップ。レジャーに含まれない結果タイプにはマイナスの値が含まれています。tesSUCCESSに数値0が含まれています。tecクラスコードは、レジャーに含まれている失敗を示しています。
TRANSACTION_TYPESトランザクションのタイプから対応する数値へのマップ。

署名と送信のためにトランザクションをシリアル化するという目的から、FIELDSTYPES、およびTRANSACTION_TYPESフィールドが必要です。

FIELDS配列のフィールド定義オブジェクトには以下のフィールドが含まれています。

フィールド内容
nth数値このフィールドのフィールドコード。このコードは、フィールドIDの作成時と、同一データタイプの他のフィールドとのソート時に使用されます。
isVLEncodedブール値trueの場合、このフィールドには長さプレフィクスが付加されています
isSerializedブール値trueの場合、このフィールドはシリアル化バイナリデータにエンコードされる必要があります。このフィールドがfalseの場合、一般にフィールドは保管されず、オンデマンドで再作成されます。
isSigningFieldブール値trueの場合、署名のためにトランザクションを準備する際にこのフィールドをシリアル化する必要があります。falseの場合、このフィールドは署名対象データから省略する必要があります。(これはトランザクションに含まれていない可能性があります。)
type文字列このフィールドの内部データタイプ。これは、このフィールドのタイプコードを示すTYPESマップのキーにマップします。

フィールドID

[ソース - エンコード] [ソース - デコード]

フィールドのタイプコードとフィールドコードを結合すると、フィールドの一意のIDになります。このIDは、最終的なシリアル化Blobでこのフィールドの前に付加されます。フィールドIDのサイズは、タイプコードとその結合対象のフィールドコードに応じて1~3バイトとなります。以下の表をご覧ください。

タイプコード < 16タイプコード >= 16
フィールドコード < 161バイト: 上位4ビットがタイプを定義し、下位4ビットがフィールドを定義します。2バイト: 1番目のバイトの下位4ビットがフィールドを定義し、次のバイトがタイプを定義します。
フィールドコード >= 162バイト: 1番目のバイトの上位4ビットがタイプを定義し、1番目のバイトの下位4ビットは0になります。次のバイトがフィールドを定義します。3バイト: 1番目のバイトは0x00、2番目のバイトはタイプを定義します。3番目のバイトはフィールドを定義します。

デコードの際には、1番目のバイトのどのビットがゼロであるかによって、フィールドIDのバイト数を把握できます。これは、上記の表の例に対応しています。

上位4ビットがゼロ以外である上位4ビットがゼロである
下位4ビットがゼロ以外である1バイト: 上位4ビットがタイプを定義し、下位4ビットがフィールドを定義します。2バイト: 1番目のバイトの下位4ビットがフィールドを定義し、次のバイトがタイプを定義します。
下位4ビットがゼロである2バイト: 1番目のバイトの上位4ビットがタイプを定義し、1番目のバイトの下位4ビットは0になります。次のバイトがフィールドを定義します。3バイト: 1番目のバイトは0x00、2番目のバイトはタイプを定義します。3番目のバイトはフィールドを定義します。

注意
フィールドIDは、フィールドのソートに使用される2つの要素で構成されますが、シリアル化されたフィールドID自体に基づいてソートを実行しないでください。これは、フィールドIDのバイト構造によってソート順序が変わるためです。

長さプレフィクスを付加する

一部の可変長フィールドの前には、長さインディケーターが付加されています。Blobフィールド(任意のバイナリデータを含む)がこれに該当します。長さプレフィクスが付加されているタイプのリストについては、タイプリストの表をご覧ください。

注記
一部のタイプの可変長フィールドには、長さプレフィクスが付加されません。このようなタイプでは、他の方法で内容の終わりが示されます。

長さプレフィクスはフィールドの長さを示す1~3バイトで構成され、タイププレフィクスと内容の間に挿入されます。

  • フィールドに0~192バイトのデータが含まれている場合、1番目のバイトは内容の長さを示し、長さバイトの直後にそのバイト数のデータが続きます。

  • フィールドに193~12480バイトのデータが含まれている場合、最初の2バイトは以下の式で算出されるフィールドの長さを示します。

    193 + ((byte1 - 193) * 256) + byte2
    
  • フィールドに12481~918744バイトのデータが含まれている場合、最初の3バイトは以下の式で算出されるフィールドの長さを示します。

    12481 + ((byte1 - 241) * 65536) + (byte2 * 256) + byte3
    
  • 長さプレフィクスが付加されているフィールドに格納できる最大データは918744バイトです。

デコード時に、1番目の長さバイトの値から、追加の長さバイト(0、1、または2)が存在するかどうかを把握できます。

  • 1番目の長さバイトの値が192以下の場合、これは唯一の長さバイトであり、フィールドの内容の長さはこのバイトが示すバイト数です。
  • 1番目の長さバイトの値が193~240の場合、2つの長さバイトがあります。
  • 1番目の長さバイトの値が241~254の場合、3つの長さバイトがあります。

フィールドの正規順序

トランザクションのすべてのフィールドは、まずフィールドのタイプ(特に各タイプに割り当てられている数値の「タイプコード」)に基づいて特定の順序でソートされ、次にフィールド自体(「フィールドコード」)に基づいてソートされます。(たとえば、姓がフィールドのタイプ、名前がフィールド自体とすると、姓で最初にソートし、次に名でソートすることになります。)

タイプコード

各フィールドタイプには任意のタイプコードが含まれており、番号が小さいコードから最初にソートされます。これらのコードはSField.hで定義されています。

たとえば UInt32のタイプコードが2であるので、すべてのUInt32フィールドは、すべてのAmountフィールド(タイプコード6)よりも前に位置します。

定義ファイルには、TYPESマップの各タイプのタイプコードがリストされています。

フィールドコード

各フィールドにはフィールドコードが含まれています。フィールドコードは、同じタイプのフィールドをソートするときに使用され、番号が小さいコードが最初になるようにソートされます。これらのフィールドはsfields/macroで定義されています。

たとえばPaymentトランザクションAccountフィールドのソートコードが1である場合、このフィールドはDestinationフィールド(ソートコードが3であるフィールド)よりも前に位置します。

フィールドコードは異なるフィールドタイプのフィールドで再利用されますが、同じタイプのフィールドに同じフィールドコードが含まれることはありません。タイプコードとフィールドコードを組み合わせると、フィールドの一意のフィールドIDになります。

タイプリスト

トランザクションの指示には、以下のタイプのフィールドを指定できます。

タイプ名タイプコードビット長長さプレフィクスを付加する?説明
AccountID8160はいアカウントの一意のID。
Amount664または384いいえXRPまたはトークンの金額。フィールドの長さは、XRPの場合は64ビット、トークンの場合は384ビット(64+160+160)です。
Blob7可変はい任意のバイナリデータ。このようなフィールドの中で重要なフィールドとして、TxnSignature(トランザクションを承認する署名)があります。
Hash1284128いいえ128ビットの任意のバイナリ値。該当する唯一のフィールドはEmailHashです。これは、Gravatarを取得する目的でアカウント所有者のメールのMD-5ハッシュを保管するフィールドです。
Hash16017160いいえ160ビットの任意のバイナリ値。これにより通貨コードまたはイシュアーが定義されます。
Hash2565256いいえ256ビットの任意のバイナリ値。これは通常、トランザクション、レジャーバージョン、またはレジャーデータオブジェクトの「SHA-512ハーフ」ハッシュを表します。
PathSet18可変いいえクロスカレンシー支払いの有効なペイメントパスのセット。
STArray15可変いいえ可変数のメンバーからなる配列。フィールドによってタイプが異なる場合があります。この例として、memosマルチ署名で使用される署名者のリストがあります。
STIssue24160 or 320いいえ数量を含まない、資産(XRPまたはトークン)を指定します。
STObject14可変いいえ1つ以上のネストされたフィールドを含むオブジェクト。
UInt8168いいえ8ビットの符号なし整数。
UInt16116いいえ16ビットの符号なし整数。TransactionTypeは、このタイプの特殊なフィールドで、特定の文字列から整数値へのマッピングを含みます。
UInt32232いいえ32ビットの符号なし整数。このタイプの例として、すべてのトランザクションのFlagsフィールドとSequenceフィールドがあります。
XChainBridge25可変いいえ2つのブロックチェーン間のブリッジで、両方のチェーン上のドアアカウントと発行された資産によって識別されます。

上記のフィールドタイプの他に、レジャーオブジェクトトランザクションメタデータなどのコンテキストでは以下のタイプが含まれることがあります。

タイプ名タイプコード長さプレフィクスを付加する?説明
Transaction10001いいえトランザクション全体を含む「上位」タイプ。
LedgerEntry10002いいえレジャーオブジェクト全体を含む「上位」タイプ。
Validation10003いいえピアツーピア通信でコンセンサスプロセスの検証投票を表すために使用される「上位」タイプ。
Metadata10004いいえ1つのトランザクションのメタデータを含む「上位」タイプ。
UInt643いいえ64ビットの符号なし整数。このタイプはトランザクションの指示には含まれませんが、さまざまなレジャーオブジェクトでこのタイプのフィールドが使用されます。
Vector25619はいこのタイプはトランザクションの指示には含まれませんが、AmendmentレジャーオブジェクトAmendmentsフィールドでは、現在有効なAmendmentを示すためにこのタイプが使用されます。

AccountIDフィールド

このタイプのフィールドには、XRP Ledgerアカウントの160ビットのIDが含まれています。JSONではこれらのフィールドはbase58 XRP Ledger「アドレス」および追加のチェックサムデータとして表示されます。このため、スペルミスが有効なアドレスとなることがありません。(このエンコードは「Base58Check」とも呼ばれ、誤ったアドレスへの送金を防止します。)これらのフィールドのバイナリフォーマットにはチェックサムデータは含まれておらず、またアドレスのbase58エンコードで使用される0x00「タイププレフィクス」も含まれていません。(ただし、バイナリフォーマットは主に署名済みトランザクションに使用されるため、署名済みトランザクションを転記する際にスペルミスなどのエラーが発生すると署名が無効となり、送金できなくなります。)

スタンドアロンフィールドとして表示されるAccountID(AccountDestinationなど)の長さは固定長の160ビットですが、長さプレフィクスが付加されます。その結果、これらのフィールドの長さインディケーターは常に0x14バイトになります。特殊フィールドの子として示されるAccountID(Amount issuerPathSet accountなど)では長さプレフィクスは付加 されません

Amountフィールド

「Amount」タイプは、通貨(XRPまたはトークン)の額を表す特殊なフィールドタイプです。このタイプは2つのサブタイプで構成されます。

  • XRP

    XRPは64ビット符号なし整数(ビッグエンディアンオーダー)としてシリアル化されます。ただし、XRPであることを示すため最上位ビットが常に0であり、プラスの値であることを示す最上位から2番目のビットは1となります。XRPの最大額(1017 drop)には57ビットが必要であるため、XRPのシリアル化フォーマットを計算するには、標準の64ビット符号なし整数をとり、0x4000000000000000のビットOR演算を行います。

  • トークン

トークンは以下の3つのセグメントで構成され、セグメントの順序は以下のとおりです。

  1. トークンの数量フォーマットの額を示す64ビット。1番目のビットは、これがXRPではないことを示す1です。
  2. 通貨コードを示す160ビット。標準APIでは、標準通貨コードフォーマットを使用して「USD」などの3文字のコードが160ビットのコードに変換されますが、160ビットのカスタムコードも使用できます。
  3. イシュアーのアカウントIDを示す160ビット。(関連項目: アカウントアドレスエンコード

1番目のビットに基づいて2つのサブタイプのいずれに該当するかを確認できます。0の場合はXRP、1の場合はトークンです。

以下の図に、XRPの額とトークン額のシリアル化フォーマットを示します。

標準通貨コードのフォーマットトークン金額のフォーマットXRP金額のフォーマットdropsの整数値 (62 bits)"非XRP" bit(0=XRP, 1=非XRP)符号 bit (常に正数を表す1)103文字のASCIIISOコード (24 bits)予約済み (40 bits)予約済み (88 bits)種類コード (8 bits) SO 4217向けの0x00/擬似ISO通貨00発行者のAccountID (160 bits)通貨コード(160 bits)"非XRP" bit(0=XRP, 1=非XRP)符号 bit (0=負数, 1=正数)有効数字(54 bits)指数(8 bits)1

トークンの数量フォーマット

[ソース]

最上位bitが1、残りが00x8000000000000000000000000000000000000000トークンの数量フォーマット(10¹⁵、10¹⁶-1)の範囲で正規化符号なし整数; 元の値+97"非XRP" bit (0=XRP, 1=非XRP)符号 bit (0=負数, 1=正数)有効数字 (54 bits)指数 (8 bits)特殊なケース(トークンの数量 = 0)

XRP Ledgerは64ビットを使って(代替可能な)トークンの金額をシリアライズします。(JSONフォーマットでは、通貨量オブジェクトのvalueフィールドが数値量になります)。バイナリ形式では、数値は"非XRP"ビット、符号ビット、指数、有効数字の順で構成されます。

  1. トークン数量の最初の(最上位)ビットは1で、XRP数量ではないことを示します。(XRPの金額は、このフォーマットと区別するために、最上位ビットが常に0に設定されています)。
  2. 符号ビットは、金額がプラスかマイナスかを示します。標準的な2の補数整数とは異なり、XRP Ledgerフォーマットでは1を表し、0を表します。
  3. 次の8ビットは指数を符号なし整数で表します。指数は、-96から+80(含む)の範囲でスケール(有効桁を10の何乗にするか)を示します。しかし、シリアライズするときには、指数に97を加えて符号なし整数としてシリアライズできるようにします。したがって、シリアル化された値1は指数-96を表し、シリアル化された値177は指数80を表します。
  4. 残りの54ビットは、符号なし整数として有効数字(mantissa と呼ばれることもあります)を表します。シリアライズするとき、この値は1015(1000000000000000)から1016-1(9999999999)の範囲に正規化されます。0の特別なケースでは、符号ビット、指数、有効数字はすべて0ですので、64ビットの値は0x800000000000000000000000としてシリアライズされます。

数値の金額は、通貨コードおよび発行者とともにシリアライズされ、完全なトークン金額を形成します。

通貨コード

プロトコルレベルでは、XRP Ledgerの通貨コードは任意の160bit値ですが、以下の値には特別な意味があります。

  • 通貨コード0x0000000000000000000000005852500000000000使用できません 。(これは"標準フォーマット"において"XRP"を表します)。
  • 通貨コード0x0000000000000000000000000000000000000000(すべてゼロ)は、許可されません。通常、XRPの金額を通貨コードで指定することはありません。しかし、XRPの通貨コードを指定しなければならないフィールドが存在する場合、このコードはXRPを示すために使用されます。

rippled APIは、3文字のASCIIコードを160ビットの16進数に変換するための標準フォーマットを以下のようにサポートしています。

0x00000000000000000000000000000000000000000 (0の160bits)XRPの特殊なケースASCII 3文字("XRP"以外)トークンの通貨コードのフォーマットISOコード (24 bits)予約済み (40 bits)予約済み (88 bits)種類コード (8 bits)ISO 4217向けの0x00または擬似ISO通貨00

  1. 最初の8ビットは0x00でなければなりません。
  2. 次の88ビットは予約済みで、すべて0でなければなりません。
  3. 次の24ビットはASCIIの3文字を表します。 ISO 4217 コード、または "BTC"のような一般的な擬似 ISO 4217コードの使用を推奨します。すべての大文字と小文字、数字、記号 ?, !, @, #, $, %, ^, &, *, <, >, (, ), {, }, [, ], |が利用可能です。 通貨コードXRP(すべて大文字)はXRPのために予約済みであり、トークンで使用することはできません。
  4. 次の40ビットは予約済みで、すべて0でなければなりません。

非標準フォーマットは、最初の8ビットが0x00以外の160ビットのデータです。

配列フィールド

一部のトランザクションフィールド(SignerListSetトランザクションSignerEntriesMemosなど)はオブジェクトの配列です(「STArray」タイプと呼ばれます)。

配列には、さまざまなオブジェクトフィールドがそのネイティブバイナリフォーマットで特定の順序で含まれています。JSONでは、各配列メンバーが1つのフィールド(メンバーオブジェクトフィールドの名前)を含むJSON「ラッパー」オブジェクトです。そのフィールドの値は(「内部」)オブジェクト自体です。

バイナリフォーマットでは、配列の各メンバーにはフィールドIDプレフィクス(ラッパーオブジェクトの単一キーに基づく)と内容(オブジェクトとしてシリアル化された内部オブジェクトからなる)が含まれています。配列の終わりをマークするため、アイテムにフィールドID 0xf1(配列のタイプコードとフィールドコード1)を付加し、内容は指定しません。

以下の例は、配列のシリアル化フォーマットを示します(SignerEntriesフィールド)。

SignerEntries (配列)フィールド(SignerEntryの内容)0xebSignerEntryフィールドID(SignerEntryの内容)配列の終了フィールドID;内容なし0xf10xebSignerEntriesフィールドID0xf4

Blobフィールド

Blobタイプは、任意のデータを持つ長さプレフィクスが付加されているフィールドです。このタイプを使用する2種類の一般的なフィールドとして、SigningPubKeyTxnSignatureがあります。これらのフィールドにはそれぞれ、トランザクションの実行を承認する公開鍵と署名が含まれています。

両方のフィールドにはこれ以上の内容構造がないため、フィールドIDと長さプレフィクスの後に可変長エンコードで示される正確なバイト数で構成されます。

ハッシュフィールド

XRP LedgerのハッシュタイプにはHash128、Hash160、Hash256があります。これらのフィールドには特定のビット数のバイナリデータが含まれており、それらのデータはハッシュ演算の結果を表す場合とそうでない場合があります。

これらのフィールドは、長さインディケーターを使用せずに、ビッグエンディアンバイトオーダーで特定数のビットとしてシリアル化されます。

Issueフィールド

いくつかのフィールドは、XRPやトークンといったアセットタイプを指定します。これらのフィールドは、1つまたは2つの160ビットから構成されています:

  1. 最初の160ビットはアセットの通貨コードです。XRPの場合、これはすべて0です。
  2. 最初の160ビットが全て0の場合(アセットがXRPの場合)、フィールドはそこで終了します。そうでない場合、アセットはトークンであり、次の160ビットはトークン発行者のAccountIDです。

オブジェクトフィールド

トランザクションフィールドの一部(SignerListSetトランザクションSignerEntryMemos配列のMemoなど)はオブジェクトです(「STObject」タイプと呼ばれます)。オブジェクトのシリアル化は配列のシリアル化に似ていますが、唯一異なる点としてオブジェクトフィールド内ではオブジェクトのメンバーを正規順序に従って配置する必要がある点があげられます。配列フィールドではすでに順序が明示的に設定されています。

オブジェクトフィールドの正規フィールド順序は、すべての最上位フィールドの正規フィールド順序と同じですが、オブジェクトのメンバーはオブジェクト内でソートする必要があります。最終メンバーの後には、「オブジェクトの終わり」を示すフィールドID(0xe1)があり、このフィールドには内容がありません。

以下の例は、オブジェクトのシリアル化フォーマットを示します(Memos配列内の1つのMemoオブジェクト)。

Memo (オブジェクト) フィールド長さ接頭辞MemoData フィールドID正規順序でのオブジェクトの内容MemoDataの内容MemoTypeフィールドID0x7dMemoTypeの内容"オブジェクト終了"フィールドID;内容なし0xe10x7cMemoフィールドID0xea

PathSetフィールド

クロスカレンシーのPaymentトランザクションPathsフィールドは、JSONで配列からなる配列として表される「PathSet」です。使用されるパスについての詳細は、パスをご覧ください。

PathSetは、1~6の個別パスとして順序どおりにシリアル化されます[ソース]。それぞれの完全なパスの後には、パスの後に続く内容を示すバイトが配置されます。

  • 0xffは別のパスが続くことを示します。
  • 0x00はPathSetの終わりを示します。

各パスには1~8のパスステップがこの順序で含まれています[ソース]。各ステップはタイプを示すバイトで始まり、その後にパスステップを記述する1つ以上のフィールドが続きます。タイプは、ビット単位のフラグを使用してそのパスステップに含まれるフィールドを示します。(たとえば値が0x30の場合、通貨とイシュアーの両方が変更されます。)複数のフィールドが含まれている場合、フィールドは常に特定の順序で配置されます。

以下の表に、有効なフィールドと、タイプバイトでフィールドを示すために設定されるビット単位のフラグを示します。

タイプフラグ含まれるフィールドフィールドタイプビットサイズ順序
0x01accountAccountID160ビット1番目
0x10currency通貨コード160ビット2番目
0x20issuerAccountID160ビット3番目

いくつかの組み合わせは無効です。詳細は、パスの仕様をご覧ください。

accountフィールドとissuerフィールドのAccountIDには、長さプレフィクスは付加 されていませんcurrencyがXRPの場合、通貨コードは160ビットのゼロとして表されます。

各ステップの直後にはパス上の次のステップが続きます。前述したように、パスの最終ステップの後には0xff(別のパスが続く場合)または0x00(これが最終パスの終わりの場合)が続きます。

以下の例は、PathSetのシリアル化フォーマットを示します。

PathPathSet"End"バイト"Continue"バイトより多くのパスステップより多くのパスパスステップ...アカウント(160 bits)0x01発行者(160 bits)通貨(160 bits)0x00最後のパス...0xff2つ目のパスパスステップのtypeバイト最初のパス0xff0x30

UIntフィールド

XRP Ledgerには符号なし整数タイプUInt8、UInt16、UInt32、UInt64があります。これらのタイプはすべて、指定されたビット数の標準ビッグエンディアンバイナリー符号なし整数です。

JSONオブジェクトにこれらのフィールドが含まれている場合、ほとんどはデフォルトでJSONの数値として表されます。例外として、UInt64は文字列として表されます。これは、一部のJSONデコーダーがこれらの整数を64ビットの「倍精度」浮動小数点数として表現しようとするためです。64ビットの「倍精度」浮動小数点数では、すべてのUInt64値を完全な精度で表現することができません。

もう1つの特殊なケースとしてTransactionTypeフィールドがあります。JSONではこのフィールドは便宜上、トランザクションタイプの名前の文字列として表現されますが、バイナリではこのフィールドはUInt16です。定義ファイル内のTRANSACTION_TYPESオブジェクトにより、これらの文字列が特定の数値にマップされます。

XChainBridgeフィールド

注記:ObjectフィールドやArrayフィールドとは異なり、ネストされたSTIssueタイプはフィールドIDで始まりません。通貨コードが全て0の場合は省略発行チェーンの発行者発行チェーンのドア(160bits)0x14ドアアカウントの長さ接頭辞(8bits)常に0x140x14ロックチェーンの発行者ロックチェーンのドア(160bits)STIssueのフォーマットXChainBridgeのフォーマット通貨コード(160bits)発行者のAccountID(160bits)

XChainBridgeフィールドは、クロスチェーンブリッジに関連するトランザクションとレジャーエントリで使用され、XChainBridgeタイプの唯一のフィールドです。XChainBridgeフィールドは4つの要素から構成され、ブロックチェーン間のブリッジを定義します。

  • ロックチェーンのドアアカウント、長さ接頭辞付きのAccountID
  • ロックチェーンの資産タイプ、STIssue
  • 発行チェーンのドアアカウント、長さ接頭辞付きのAccountID
  • 発行チェーンの資産タイプ、STIssue

ネストされた2つのSTIssueタイプは、それぞれ160ビットまたは320ビットです。STIssueフィールドに含まれる通貨コードがすべて0の場合、STIssueフィールドは160ビットで、ブリッジされた資産がそれぞれのチェーンのネイティブ資産、例えばXRP Ledger MainnetのXRPであることを意味します。通貨コードが0でない場合、STIssueフィールドにはトークンのネイティブチェーンにおける発行者の(長さ接頭辞のない)AccountIDも含まれます。

注記
ドアアカウントのAccountIDの値は長さ接頭辞付きですが、発行者のAccountIDの値は長さ接頭辞付きではありません。

全体として、XChainBridgeフィールドは常に656、816、または976ビット(82、102、または122バイト)のいずれかになります。