🎛

世界初のDEXを使ってみよう!

2023/02/20に公開

XRP LedgerのDEXについて

XRP Ledgerは2012年に誕生したパブリックブロックチェーンです。XRP Ledgerにスマートトランザクタ(ネイティブな機能)として搭載されているDEXも2012年からXRP Ledgerで利用可能です。

このDEXではネイティブトークンであるXRPとアカウントが発行するトークン(発行トークン/IOUとも呼ばれます)が取引可能です。

以下のような特徴があります。

執筆時点ではメインネットで利用可能なDEXはCLOB形式のみですが、コミュニティメンバーであるRipple社の主導でAMMの開発も進められています。

https://xrpl.org/ja/decentralized-exchange.html

https://github.com/XRPLF/rippled/pull/4294

ネイティブなDEX

XRPLのDEXはプロトコルでネイティブであるため、DEXプロジェクト毎に流動性が分散するようなこともなく、それぞれのペア毎にただ一つの流動性を持つことになります。

オートブリッジ

XRPLのDEXにはオーダーブックを自動的に合成するオートブリッジという機能が搭載されています。
例えば、USD/EURのオーダーブックに対して注文した場合に、USD/EURの流動性だけでなく、XRPとのペアであるUSD/XRPとEUR/XRPの流動性も利用することでより良いレートでの取引を実現させる仕組みです。
つまり、USD/EURの流動性が全くない場合でもXRP建のペアの流動性さえ存在すれば、XRP建のペアを意識することなく、USD/EURでの取引が可能だということです。

https://xrpl.org/ja/autobridging.html

トランザクション

DEXでの取引に関連するトランザクションとして主に次の2つがあります。

OfferCreateトランザクション

注文を作成するトランザクションです。指値注文・成行注文どちらも使用可能です。
未約定の注文の上書きもできます。

https://xrpl.org/ja/offercreate.html

OfferCancelトランザクション

注文をキャンセルするトランザクションです。

https://xrpl.org/ja/offercancel.html

対象

本記事ではテストネット上でオファーの作成およびオファーのキャンセルまでを行います。

今回はXRP LedgerのJavaScript/TypeScriptライブラリであるxrpl.jsを使用します。

https://github.com/XRPLF/xrpl.js

https://www.npmjs.com/package/xrpl

Javascript以外にもPythonなどの他の言語のライブラリも存在します。
チェックしてみてください。

https://xrpl.org/ja/client-libraries.html

テストネットアカウントの取得

XRP FaucetsまたはXRP Ledger Faucetからテストネット(testnet)用のアカウントを取得します。

https://xrpl.org/ja/xrp-testnet-faucet.html

https://faucet.tequ.dev/

DEXへの注文を作成する

100XRPで100TSTトークンを購入するオファーを作成してみます。
デフォルトでは指定した価格かそれよりも有利な価格の注文が存在する場合は、即座に約定します。残りの数量はオーダーブックに注文を配置します。

TakerGetsに自身が提供する資産、TakerPaysに受け取る資産を設定します。
下の例だと100XRPを提供し、100TSTを受け取る注文になります。

OfferCreateトランザクション
import { Client, Wallet, xrpToDrops } from 'xrpl'

const secret = 'sEd****************************')'

const wallet = Wallet.fromSecret(secret)
const client = new Client('wss://testnet.xrpl-labs.com')

await client.connect()
await client.submitAndWait({
  TransactionType: 'OfferCreate',
  Account: wallet.address,
  TakerGets: xrpToDrops(100),
  TakerPays: {
    currency: "TST",
    issuer: "r3De1gWJjUQhU7jKpjFaTZFVTX8qWQUWnX",
    value: "100",
  },
  Flags: 0
}, { wallet })

こちらが実行結果です。
https://test.bithomp.com/explorer/FCB7C1FAD7A139015DE6F3B74B209A1C2EF466BAA77A9C3D42419AFD3A216E7A

Raw TX dataからOfferオブジェクトが作成されていることが確認できます。

...
{
    "CreatedNode": {
        "LedgerEntryType": "Offer",
        "LedgerIndex": "0AF5D0E55A349E447410B8B145FDC89B819C2684D725BFB02AB8AE8DA2713045",
        "NewFields": {
            "Account": "rGNNciFFFiyV4ZuAUk4QizcaYyY4T9Yzft",
            "BookDirectory": "980173F5730D9EF970D6D92AED2932CFFC056F0B4B75A54A4F038D7EA4C68000",
            "Sequence": 35104587,
            "TakerGets": "100000000",
            "TakerPays": {
                "currency": "TST",
                "issuer": "r3De1gWJjUQhU7jKpjFaTZFVTX8qWQUWnX",
                "value": "100"
            }
        }
    }
}
...

フラグ

OfferCreteトランザクションにはFlagsフィールドに幾つかのフラグを設定することで、注文の挙動を変更できます。

tsPassive

指定した価格と一致したオファーでは約定せず、オーダーブックに注文を配置します。指定した価格より有利な注文の場合は約定します。

tfImmediateOrCancel

成行注文
IOC注文として扱います。指定した価格かそれよりも有利な注文に対して約定し、残りの数量はオーダーブックに配置しません。

tfFillOrKill

成行注文
FOK注文として扱います。指定した価格かそれよりも有利な注文に対して注文の全額を約定可能な場合は約定し、全額を約定不可の場合はキャンセルされます。

tfSell

指定レートよりも良いレートが存在するようなTakerPaysで指定した金額以上を調達できる場合でも、TakerGetsの全額を取引します。
つまり指定したTakerGetsは全てTakerPaysで指定したトークンへ交換されます。

DEXの注文をキャンセルする

オファーのシーケンス番号を取得

キャンセル対象のオファーのシーケンス番号を取得する必要があります。
book_offers メソッドを使用し、オファーの一覧を取得できます。

https://xrpl.org/ja/book_offers.html

book_offersメソッド
const response = await client.request({
  command: 'book_offers',
  taker_gets: {
    currency: "XRP"
  },
  taker_pays: {
    currency: "TST",
    issuer: "r3De1gWJjUQhU7jKpjFaTZFVTX8qWQUWnX",
  },
})
console.log(response.result.offers)
offers
[
  {
    Account: 'rGNNciFFFiyV4ZuAUk4QizcaYyY4T9Yzft',
    BookDirectory: '980173F5730D9EF970D6D92AED2932CFFC056F0B4B75A54A4F038D7EA4C68000',
    BookNode: '0',
    Flags: 0,
    LedgerEntryType: 'Offer',
    OwnerNode: '0',
    PreviousTxnID: 'FCB7C1FAD7A139015DE6F3B74B209A1C2EF466BAA77A9C3D42419AFD3A216E7A',
    PreviousTxnLgrSeq: 35395951,
    Sequence: 35104587,
    TakerGets: '100000000',
    TakerPays: {
      currency: 'TST',
      issuer: 'r3De1gWJjUQhU7jKpjFaTZFVTX8qWQUWnX',
      value: '100'
    },
    index: '0AF5D0E55A349E447410B8B145FDC89B819C2684D725BFB02AB8AE8DA2713045',
    owner_funds: '866047607',
    quality: '0.000001'
  }
]

このオファーのシーケンス番号は Sequence フィールドの 35104587 です。

OfferCancel

await client.submitAndWait({
  TransactionType: 'OfferCancel',
  Account: wallet.address,
  OfferSequence: 35104587
}, { wallet })

こちらが実行結果です。
https://test.bithomp.com/explorer/B60035464B6F1696E27CA3902C582C0983BCBB994B746B71B7E050C1F9632987

再度 book_offers メソッドを実行するとオーダーブックが空になっていることが確認できます。

offers
[]

まとめ

XRP Ledgerではスマートトランザクタ(プロトコルネイティブな機能)なDEX機能が実装されており、低いセキュリティリスクでトークンの取引が可能です。オートブリッジ機能はXRPL全体の流動性を有効活用し、より良い価格でのトレードを可能にします。
開発中のAMM機能はこのDEX(CLOB)機能と統合されるため、メインネットで有効化された場合、流動性のさらなる向上が期待されます。

今回使用したコードは以下のリポジトリからも参照できます。
https://github.com/develoQ/xrpl-sample/tree/main/samples/use-dex

興味を持たれた方はXRP Ledger開発者のDiscordチャンネルへ是非お越しください!
日本語チャンネルもありますので、英語ができなくても大丈夫です!
https://xrpldevs.org

Discussion