XRPレジャーのトランザクションの基礎
XRPレジャーの学習
こちらの記事にてXRPLの学習フローを作成しました。
(学習フローには記載していませんが)この記事ではXRPLのトランザクションについて説明します。
XRPレジャーのトランザクション
XRPレジャーのトランザクションはXRPレジャーの状態(レジャーオブジェクト)を変更する唯一の手段です。
XRPレジャーのトランザクションはプロトコルネイティブで定義されており、どのようなトランザクションタイプを使用するか、どんなフィールド、フラグを設定するかによりさまざまな処理を行うことができます。
ここでは特定のトランザクションの処理に焦点を当てるのではなく、トランザクションの概要を説明します。
XRPレジャーのトランザクションは非常にヒューマンリーダブルなJSONフォーマットで表され、一部のフィールドはクライアントライブラリなどによって自動的に設定することも可能となっています。
(JSONフォーマットだけでなく16進数のバイナリフォーマットとして表されることもあります。)
重要な共通フィールド
一般的にトランザクションを作成する際に開発者による指定が必須であるフィールドはTransactionType
、Account
の2つになります。
-
TransactionType
: 実行するトランザクションの種類 -
Account
: トランザクションを実行するアカウント
自動入力(autofill)可能なフィールド
クライアントライブラリにより自動入力が行えるフィールドとしてはFee
、Sequence
、LastLedgerSequence
フィールドがあります。
-
Fee
: トランザクションで消費する手数料の額 -
Sequence
: アカウントのトランザクションを識別するための一意な番号、同一アカウントの直前のトランザクションのSequence
に1を加算したもの -
LastLedgerSequence
: トランザクションを登録できるレジャーインデックスの最大値、この値を超えたレジャーインデックスに対してはトランザクションは無効となる
これらのフィールドはネットワークから情報を取得する必要があるため、ネットワークに接続していない環境では自動入力が行えません。手動での入力が必要となります。
署名時に設定されるフィールド
いくつかのフィールドはアカウントのキーによる署名時に自動的に設定されます。
-
SigningPubKey
: 署名したキーの公開鍵、マスターキーによる署名時はトランザクションのAccount
に対応する公開鍵が設定され、レギュラーキーによる署名時はそのレギュラーキーアカウントに対応する公開鍵が設定される -
TxnSignature
: トランザクションを検証するための署名
トランザクション毎の必須フィールド
ほとんどのトランザクションではそのトランザクションタイプ毎に追加の必須フィールドが必要になります。
例えばPaymentトランザクションではDestination
フィールドやAmount
フィールドが必須となります。
トランザクションの作成~送信までの流れ
ここではNFTokenMint
トランザクションを例としてトランザクションの作成から送信までの流れを説明します。
トランザクションペイロードの作成
以下のJSONはNFTokenMint
トランザクションのペイロードです。
NFTokenMint
トランザクションにおける必須フィールドであるNFTokenTaxon
を指定し、Flagsには第三者同士による転送可能なtfTransferable
(8)を指定しています。URIにはipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi
をHEX値で指定しています。
{
"TransactionType": "NFTokenMint",
"Account": "rQH345ETne1nbedLwmpfCzB364QyAjCgZx",
"NFTokenTaxon": 0,
"Flags": 8,
"URI": "697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377932366E6634646675796C71616266336F636C67747179353566627A6469"
}
トランザクションへの自動入力(autofill)
前述したようにFee
をはじめとするいくつかの項目はクライアントライブラリによって自動入力(autofill)が可能となっています。
xrpl.jsでは以下のようなコードで自動入力が可能です。
import { Client } from 'xrpl'
const client = new Client('wss://testnet.xrpl-labs.com')
await client.connect()
const payload = await client.autofill({
TransactionType: "NFTokenMint",
Account: "rQH345ETne1nbedLwmpfCzB364QyAjCgZx",
NFTokenTaxon: 0,
Flags: 8,
URI: "697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377932366E6634646675796C71616266336F636C67747179353566627A6469"
})
console.log(payload)
{
TransactionType: 'NFTokenMint',
Account: 'rQH345ETne1nbedLwmpfCzB364QyAjCgZx',
NFTokenTaxon: 0,
Flags: 8,
URI: '697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377932366E6634646675796C71616266336F636C67747179353566627A6469',
Sequence: 39363365,
Fee: '12',
LastLedgerSequence: 39363481
}
Xummなどのいくつかのウォレットでは署名時に暗黙的に自動入力が行われる場合があります。
トランザクションへの署名
トランザクションへの署名方法はクライアントライブラリやウォレット毎に異なります。
xrpl.jsを使ったローカルでの署名
import { Wallet } from 'xrpl';
const wallet = Wallet.fromSeed("sEd74ejea3NauJfET5gsk7RXbgS4Smg")
const { tx_blob } = wallet.sign(payload)
console.log(tx_blob)
console.log(binaryToJSON(tx_blob))
1200192200000008240258A325201B0258A37B202A0000000068400000000000000C7321EDB8E185460B530E53D121A2F66C108DD7D0331D8E88354666CF032F5EC3E3AE45744092EEFC1F3EB97D6558762FCBD125700D0DBA805C196A9183EC6F748B692BE61693F52CD700162D4F3474C837FC4C284FAB49882FB7D5E2A75EE3550F8CE96C007542697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377932366E6634646675796C71616266336F636C67747179353566627A64698114FF57B4464033F3E31C6BD105233D8F4C96D03F94
{
TransactionType: 'NFTokenMint',
Flags: 8,
Sequence: 39363365,
LastLedgerSequence: 39363481,
NFTokenTaxon: 0,
Fee: '12',
SigningPubKey: 'EDB8E185460B530E53D121A2F66C108DD7D0331D8E88354666CF032F5EC3E3AE45',
TxnSignature: 'AA84D34E86858A8ED9050FE179BCBE6E9166F250B7CF2C84EF9789715C120F9F598D37B8F1E62D08F9CD962DFB4D863D3FEA52E910BF09E8AD3DC7EABC05460A',
URI: '697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377932366E6634646675796C71616266336F636C67747179353566627A6469',
Account: 'rQH345ETne1nbedLwmpfCzB364QyAjCgZx'
}
Xummを使った署名
XummのSDKを使う場合は以下のようなコードになります。
Xummを利用する場合、デフォルトではautofillと署名、トランザクションの送信が全て行われます。
import { Xumm } from "xumm";
const xumm = new Xumm("some-api-key", "some-secret-key");
const payload = await xumm.payload.create({
TransactionType: "NFTokenMint",
Account: "rQH345ETne1nbedLwmpfCzB364QyAjCgZx",
NFTokenTaxon: 0,
Flags: 8,
URI: "697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377932366E6634646675796C71616266336F636C67747179353566627A6469"
});
console.log(payload.next.always)
トランザクションの署名から送信までを1度に(xrpl.js)
submitAndWait
メソッドを利用することで、autofill,sign,submitが1度に行えます。
import { Client } from 'xrpl'
const client = new Client('wss://testnet.xrpl-labs.com')
await client.connect()
const wallet = Wallet.fromSeed("sEd74ejea3NauJfET5gsk7RXbgS4Smg")
const payload = await client.submitAndWait({
"TransactionType": "NFTokenMint",
"Account": "rQH345ETne1nbedLwmpfCzB364QyAjCgZx",
"NFTokenTaxon": 0,
"Flags": 8,
"URI": "697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377932366E6634646675796C71616266336F636C67747179353566627A6469"
}, { wallet })
トランザクションの送信
submit
コマンドを使用し、署名済みのトランザクションデータ(blob)をXRPLネットワークに送信することができます。
import { Client } from 'xrpl'
const client = new Client('wss://testnet.xrpl-labs.com')
await client.connect()
await client.request({
command: 'submit',
tx_blob: '1200192200000008240258A325201B0258A37B202A0000000068400000000000000C7321EDB8E185460B530E53D121A2F66C108DD7D0331D8E88354666CF032F5EC3E3AE45744092EEFC1F3EB97D6558762FCBD125700D0DBA805C196A9183EC6F748B692BE61693F52CD700162D4F3474C837FC4C284FAB49882FB7D5E2A75EE3550F8CE96C007542697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377932366E6634646675796C71616266336F636C67747179353566627A64698114FF57B4464033F3E31C6BD105233D8F4C96D03F94'
}, { wallet })
おわりに
XRPレジャーのトランザクションはローカルや、各ウォレットでのSDKなどの様々な方法で署名することができます。
今回紹介したXumm以外にもSDKを提供しているウォレットサービスはいくつか存在しており、Wallet Connect規格を採用しているウォレットサービスならば、XRPレジャーのトランザクションを署名することができます。
興味を持たれた方はXRPレジャー開発者のDiscordチャンネルへ是非お越しください!
日本語チャンネルもありますので、英語ができなくても大丈夫です!
私のTwitterはこちら!
Discussion