🖼

XRP LedgerでNFTを触ってみる

2022/10/08に公開約3,600字

XRP Ledger とは

Bitcoin や Ethereum などと同じ分散型のパブリックブロックチェーンです。PoW や PoS とは異なる独自のコンセンサスアルゴリズムが用いられています。
EVM によるスマートコントラクトは搭載しておらず、ネイティブでの機能(広義のスマートコントラクト)拡張を行うことで進化し続けています。執筆時点では NFT 機能の有効化についてコミュニティによる投票中であり、AMM や独自の(狭義の)スマートコントラクトについての開発が進められています。
ネイティブトークンとして 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 をミントする。

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 を確認する。

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

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

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

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

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. 売却オファーを作成する。

await client.submitAndWait(
  {
    TransactionType: "NFTokenCreateOffer",
    Account: wallet.classicAddress,
    Amount: xrpToDrops(100), // 100XRP Amountはdrop単位で指定
    NFTokenID,
    Flags: 1, // 売却オファーを作成する場合は1, 購入オファーを作成する場合は0
  },
  { 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のNFT機能の基本的な部分についての記事でした。実際には他にも考慮すべき点がありますが、個々の事例によるところもあり、割愛しています。
XRP LedgerでのNFTの盛り上がりも期待されています。

Discussion

ログインするとコメントできます