🖼

XRP LedgerでNFTを触ってみる

2022/10/08に公開

XRP Ledger とは

XRP LedgerはBitcoinやEthereumなどと同じ分散型のパブリックブロックチェーンです。PoWやPoSとは異なる独自のコンセンサスアルゴリズムが用いられています。
EVMによるスマートコントラクトは搭載しておらず、スマートトランザクタ(プロトコルネイティブで提供されている機能)を拡張することで進化し続けています。執筆時点ではNFT機能はコミュニティによる投票中であり、その他にはAMMやXRPL独自の(狭義の)スマートコントラクトについての開発が進められています。
ネイティブトークンとしてXRPが存在し、その最小単位は1 drop(1 XRP = 1,000,000 drop)となっています。

NFT 機能について

これまでXRP LeddgerにはNFT機能が存在しませんでしたが、2021年5月にNik BougalisらによってXRPLにNFTを実装するための標準規格 XLS-20 が提案されました。その後Devnetのリリースなどを経て、執筆時点ではコミュニティによる投票を行なっています。
バリデータによる賛成票が80%超を2週間キープした場合、メインネットで有効化されます。
XRP LedgerでのNFT機能のメリットとして、十分にテストされたネイティブでのNFT機能のため、セキュリティリスクがEVMスマートコントラクトによるNFTよりも低いと考えられます。また、ネイティブでロイヤリティにも対応しており、クリエイターフレンドリーでもあります。

メインネットでの有効化の状況は以下から確認ができます。

https://xrpscan.com/amendment/32A122F1352A4C7B3A6D790362CC34749C5E57FCE896377BFDC6CCD14F6CD627

NFTに関するトランザクションの種類

以下のようなトランザクションを利用することでNFTの発行や売買などが可能となっています。

NFTokenMint

NFTを発行するトランザクションです。

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

NFTokenCreateOffer

NFTの売却オファー/購入オファーを作成するトランザクションです。

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

NFTokenCancelOffer

NFTの売却オファー/購入オファーを取り下げるトランザクションです。

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

NFTokenAcceptOffer

NFTの売却オファー/購入オファーを承認するトランザクションです。

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

NFTokenBurn

NFTをバーンするトランザクションです。

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

1. NFTをミントする。

NFTを発行します。発行したNFTは発行時点では発行者が保有します。

import { Client, Wallet } from "xrpl";

const client = new Client("wss://s.devnet.rippletest.net:51233");

const wallet = Wallet.fromSeed("sncJTGw7U********************");

const mintResult = await client.submitAndWait(
  {
    TransactionType: "NFTokenMint",
    Account: wallet.classicAddress,
    TransferFee: 5 * 1000, // 5%
    NFTokenTaxon: 0,
    Flags: 1 + 8, // Burnable, Transferable
    URI: convertStringToHex('ipfs://*********') // hex形式で指定
  },
  { wallet }
);

2. 発行したNFTのIDを確認する。

XRP Ledger全体で一意に定められているNFTのIDを取得します。

パターン 1. アカウントの NFT 一覧から取得する

XRPLにはアカウントが保有する全てのNFTを取得するメソッド account_nfts があります。
パターン1ではこのメソッドを使用してNFTを取得します。

const response = await client.request({
  command: "account_nfts",
  account: wallet.classicAddress,
});

// NFTokenが配列で格納されている。
// 注意: 発行順ではなくTokenID順で格納されている
console.log(response.result.account_nfts);

パターン 2. NFTokenMintのレスポンスから取得する

NFTのミントトランザクションのレスポンスには、そのトランザクションでXRPLのデータのどのようなオブジェクトに変更があったかを示すmetaフィールドが含まれています。
NFTのミントは NFTokenPage へ影響を与え、NFTokenを追加します。
変更前と変更後を比較し、変更後にのみ存在するNFTokenが新規にミントしたNFTとなります。

const node =
  mintResult.result.meta.AffectedNodes.find(
    (n) => (n.ModifiedNode.LedgerEntryType || "") === "NFTokenPage"
  ).ModifiedNode || [];
// NFTokenMintトランザクション実行後の`NFTokenPage`に格納されているNFTokenIDの一覧を取得
const finalNFTokenIds = node.FinalFields.NFTokens.map(
  (t) => t.NFToken.NFTokenID
);
// NFTokenMintトランザクション実行前の`NFTokenPage`に格納されているNFTokenIDの一覧を取得
const previousNFTokenIds = node.PreviousFields.NFTokens.map(
  (t) => t.NFToken.NFTokenID
);
// // NFTokenMintトランザクション実行後にのみ存在するNFTokenIDを取得
const NFTokenID = finalNFTokenIds.find(
  (token) => !previousNFTokenIds.includes(token)
);
console.log(NFTokenID);

3. 売却オファーを作成する。

XRPLには不要なトークンを他者に保有させることはできないという強い原則があり、受信者の許可なくNFTを送信することは出来ません。
そのため、NFTを転送する場合は、NFT保有者のオファーと受け取り側のオファーの承認が必要となります。
逆に受け取り側がオファーし、保有者がオファーを承認するということも可能です。

await client.submitAndWait(
  {
    TransactionType: "NFTokenCreateOffer",
    Account: wallet.classicAddress,
    Amount: xrpToDrops(100), // 100XRP Amountはdrop単位で指定
    NFTokenID,
    Flags: 1, // 売却オファーを作成する場合は1, 購入オファーを作成する場合は指定しない
  },
  { wallet }
);

4. 購入者アカウントで売却オファーを受け入れる

// NFToken Offer IDを取得
const result = await client.request({
  command: 'nft_sell_offer',
  nft_id: NFTokenID,
})
// 指定したNFTのオファー一覧から受け入れるオファーを選択
const offerId = result.offers[0].nft_offer_index

// 売却オファーの承認
await client.submitAndWait({
  TransactionType: 'NFTokenAcceptOffer',
  Account: wallet.classicAddress,
  NFTokenBuyOffer: offerId
}, { wallet })

まとめ

今回はXRP LedgerにはSBT機能や、他アカウントへのMint権限を委任する機能、マーケットプレイス向けのブローカー機能など多彩な機能が存在し、それら全てがスマートトランザクタとして利用可能です。スマートトランザクタとして実装されていることで、Mint時の Flags フィールドを変えるだけとても簡単にSBT機能を利用できます。

XRP LedgerでのNFTの盛り上がりにも期待されています。

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

Discussion