🏢

XRPLのCredentials実装ガイド:資格証明の発行から管理・運用まで

に公開

はじめに

XRP Ledger(XRPL)はBitcoinに次ぐ長い歴史を持つ、パブリック・ブロックチェーンです。
特徴としては、一般的に取引処理が速くコストが低いことが強みと知られていますが、多くのユーティリティを持つことが特徴です。

XRPLでは、XLS-70のCredentials(資格情報)機能が2024年にDevnet環境で有効化されました。
この機能は現在Devnetでのみ利用可能であり、メインネットではまだ有効化されていません。Devnet環境を使うことで、実際の資産を使わずに機能のテストができます。

本記事では、Devnet環境を使ってxrpl.jsによるCredentials機能の基本的な実装方法を解説します。

XRPLのCredentials機能とは

Credentialsは、XRPLにおいて分散型の資格認証システムを提供します。
XRPLのCredentialsは以下の特徴があります。

  • 発行者(Issuer)が対象(Subject)に対して資格証明書を発行できます
  • 資格証明書には有効期限や追加情報(URI)を設定できます
  • 受信者は資格証明書を受け入れる(Accept)ことができます
  • 発行者は資格証明書を取り消す(Delete)ことができます
  • 第三者機関(Verity)は、信頼する発行者の資格情報(例:KYC情報)に基づき、取引する相手を制限することができます
  • 資格証明書の状態(発行済み、受け入れ済み)はブロックチェーン上で検証可能です

1. 環境準備

npm i xrpl

Devnetは、XRPLの新機能をテストするための環境です。実際の資産を使わずにトランザクションを送信できます。

Devnetに接続するコードは以下の通りです:

import { Client } from "xrpl";

// XRPLへの接続
const client = new Client("https://s.devnet.rippletest.net:51234/");

// 開始
await client.connect();

// ここに処理を記述

// 終了
await client.disconnect();

注意: 2025/04/22時点ではCredentials機能はDevnetでのみ利用可能なため、必ずDevnetに接続してください。メインネットやテストネットでは機能しません。

2. アカウント準備と役割

アカウント作成

Credential機能を一通りシナリオに基づき、試すためには複数のアカウントを用意する必要があります。

ローカルで作成したDevnetのアカウントは手元のメモに保存しておき、その他トランザクションで再利用します。

アカウントを作成するコードは以下の通りです:

import { Client } from "xrpl"

// Devnetでテストアカウントを作成
const issuerWallet = await Client.fundWallet();
const aliceWallet = await Client.fundWallet();
const bobWallet = await Client.fundWallet();
const verityWallet = await Client.fundWallet();

console.log("Issuer Wallet:", {
  address: issuerWallet.wallet.classicAddress,
  seed: issuerWallet.wallet.seed,
  balance: issuerWallet.balance,
})

const aliceWallet = await Client.fundWallet()
console.log("Alice Wallet:", {
  address: aliceWallet.wallet.classicAddress,
  seed: aliceWallet.wallet.seed,
  balance: aliceWallet.balance,
})

const bobWallet = await Client.fundWallet()
console.log("Bob Wallet:", {
  address: bobWallet.wallet.classicAddress,
  seed: bobWallet.wallet.seed,
  balance: bobWallet.balance,
})

const verityWallet = await Client.fundWallet()
console.log("Verity Wallet:", {
  address: verityWallet.wallet.classicAddress,
  seed: verityWallet.wallet.seed,
  balance: verityWallet.balance,
})

上記のスクリプトを実行することで、Devnetのアカウントにテスト用のXRPが自動的に入金されます。

各アカウントの役割は以下のとおりです:

  • Issuer: 資格証明書の発行者。特定の資格を認証・発行する権限を持ちます。
  • Alice: 資格証明書の受信者。発行された資格証明書を受け取り、それを使って特別な取引を行えます。
  • Bob: 資格証明書を持たないユーザー。
  • Verity: 資格検証者。特定の資格証明書を持つアカウントとのみ取引を行うように設定します。

3. CredentialCreate - 資格証明書の作成

準備が整ったら、CredentialCreateトランザクションを送信して、資格証明書を発行してみましょう。

Issuerが資格証明書を作成し、対象者(Subject)に発行するトランザクションです。

import { Client, convertStringToHex, unixTimeToRippleTime } from "xrpl"

const oneYearLaterUnix = Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60

const credentialCreateTx = {
  TransactionType: "CredentialCreate",
  Account: issuerWallet.address, // 発行者アドレス
  Subject: aliceWallet.address,  // 対象者アドレス
  CredentialType: convertStringToHex("XRPLCommunityExamCertification"), // 資格タイプ(Hex形式に変換する必要があります)
  // 有効期限(オプション)
  Expiration: unixTimeToRippleTime(oneYearLaterUnix),
  // URI(オプション)
  URI: convertStringToHex("https://xrpl-community.example.com/credentials/XRPL-COMM-2025-XX-XX-001"),
  // メモ情報(オプションの例)
  Memos: [
    {
      Memo: {
        MemoType: convertStringToHex("application/json"),
        MemoFormat: convertStringToHex("text/plain"),
        MemoData: convertStringToHex(JSON.stringify({
          reason: "This person has completed the XRPL Community Exam, please issue credential",
          name: "Alice",
          certificationId: "XRPL-COMM-2025-04-21-89688",
          examScore: 92,
          issueDate: "2025-04-20T15:00:19.107Z"
        }))
      }
    }
  ]
};

const prepared = await Client.autofill(credentialCreateTx);
const signed = issuerWallet.sign(prepared);
const result = await client.submitAndWait(signed.tx_blob);

// 発行されたCredentialのID(LedgerIndex)を取得
const meta = result.result.meta;
if (meta.AffectedNodes) {
  const credentialNode = meta.AffectedNodes.find(
    node => node.CreatedNode && node.CreatedNode.LedgerEntryType === "Credential"
  );
  
  if (credentialNode?.CreatedNode?.LedgerIndex) {
    console.log(`発行されたCredential ID: ${credentialNode.CreatedNode.LedgerIndex}`);
  }
}

Credentials機能で必要となるCredential IDというのは、LedgerIndexとなりますので、メモしておいてください。(実際のプロジェクトなどでは動的に取得するなどの処理が必要となります)

CredentialCreateの主要パラメータ

パラメータ 説明 必須
TransactionType "CredentialCreate"を指定
Account 資格証明書の発行者アドレス
Subject 資格証明書の対象者アドレス
CredentialType 資格の種類(16進数文字列)
Expiration 有効期限(RippleTime形式)
URI 資格に関連するURI(16進数文字列)
Memos 追加情報(JSON、テキストなど)

https://js.xrpl.org/interfaces/CredentialCreate.html

4. CredentialAccept - 資格証明書の承認

受信者は発行された資格証明書を承認することで有効化できます。

import { Client, convertStringToHex, AccountSetAsfFlags } from "xrpl";

const credentialAcceptTx = {
  TransactionType: "CredentialAccept",
  Account: aliceWallet.address,
  Issuer: issuerWallet.address,
  CredentialType: convertStringToHex("XRPLCommunityExamCertification"),
};

const prepared = await Client.autofill(credentialAcceptTx);
const signed = aliceWallet.sign(prepared);
const result = await Client.submitAndWait(signed.tx_blob);

CredentialAcceptの主要パラメータ

パラメータ 説明 必須
TransactionType "CredentialAccept"を指定
Account 資格証明書の対象者(Subject)のアドレス
CredentialType 資格の種類(16進数文字列)
Issuer 資格証明書の発行者アドレス

https://js.xrpl.org/interfaces/CredentialAccept.html

5. DepositPreauth - 資格に基づく取引認証

Verityアカウントは、特定の資格を持つアカウントからのみ入金を受け付けるように設定できます。
まず、DepositAuthを有効にします:

import { Client, AccountSetAsfFlags } from "xrpl";

const accountSetTx = {
  TransactionType: "AccountSet",
  Account: verityWallet.address,
  SetFlag: AccountSetAsfFlags.asfDepositAuth // 9
};

await Client.submitAndWait(accountSetTx, { wallet: verityWallet });

AccountSetのフラグはxrpl.jsからAccountSetAsfFlagsをインポートして指定することを推奨します。

次に、特定の資格を持つアカウントからの入金のみを許可します:

import { Client, convertStringToHex } from "xrpl";

const depositPreauthTx = {
  TransactionType: "DepositPreauth",
  Account: verityWallet.address,
  AuthorizeCredentials: [
    {
      Credential: {
        Issuer: issuerWallet.address,
        CredentialType: convertStringToHex("XRPLCommunityExamCertification")
      }
    }
  ]
};

const prepared = await Client.autofill(depositPreauthTx);
const signed = verityWallet.sign(prepared);
const result = await client.submitAndWait(signed.tx_blob);

DepositPreauthの主要パラメータ

パラメータ 説明 必須
TransactionType "DepositPreauth"を指定
Account 設定するアカウント
Authorize 特定アドレスの承認(通常のDepositPreauth) ❌*
AuthorizeCredentials 資格に基づく承認 ❌*

*AuthorizeとAuthorizeCredentialsのどちらか一方が必要

https://js.xrpl.org/interfaces/LedgerEntry.DepositPreauth.html

6. 資格証明書を使った送金

AliceとBobは、Verityに対して送金を試みます。Aliceは資格証明書を持っているので成功しますが、Bobは持っていないので失敗します。

import { Client, convertStringToHex } from "xrpl";

// Aliceからの送金(成功)
const paymentTx = {
  TransactionType: "Payment",
  Account: aliceWallet.address,
  Destination: verityWallet.address,
  Amount: "1000000" // 1 XRP
};

const prepared = await client.autofill(paymentTx);
const signed = aliceWallet.sign(prepared);
const result = await client.submitAndWait(signed.tx_blob);

// Bobからの送金(失敗)
const paymentTx2 = {
  TransactionType: "Payment",
  Account: bobWallet.address,
  Destination: verityWallet.address,
  Amount: "1000000" // 1 XRP
};

try {
  const prepared = await client.autofill(paymentTx2);
  const signed = bobWallet.sign(prepared);
  const result = await client.submitAndWait(signed.tx_blob);
} catch (error) {
  console.log("Bobからの送金は失敗します:", error.message);
  // "tecNO_PERMISSION" エラーが発生
}

7. CredentialDelete - 資格証明書の削除

発行者は、資格証明書を削除することができます。例えば、有効期限前に資格を失効させたい場合などに使用します。

import { Client, convertStringToHex } from "xrpl";

const credentialDeleteTx = {
  TransactionType: "CredentialDelete",
  Account: issuerWallet.address,      // 発行者
  CredentialType: convertStringToHex("XRPLCommunityExamCertification"),
  Subject: aliceWallet.address        // 対象者
};

const prepared = await Client.autofill(credentialDeleteTx);
const signed = issuerWallet.sign(prepared);
const result = await Client.submitAndWait(signed.tx_blob);

CredentialDeleteの主要パラメータ

パラメータ 説明 必須
TransactionType "CredentialDelete"を指定
Account 削除リクエストするアカウント
CredentialType 削除する資格の種類
Subject 資格の対象者 ❌*
Issuer 資格の発行者 ❌*

*省略された場合、Accountが対象とみなされます。

まとめ

XRPLのCredential機能を使用すると、以下のようなことが可能になります:

  1. 発行者が資格証明書を特定のアカウントに発行できる
  2. 受信者が資格証明書を承認/拒否できる
  3. 第三者機関などが、信頼できる発行者が発行した特定の資格を持つアカウントとのみ取引を行うよう設定可能
  4. 必要に応じて資格証明書を削除できる

これにより、KYC/AML要件の遵守、会員制サービス、教育証明書など、様々な用途に活用できます。Credentials機能は、XRPLエコシステムにおいて、取引の安全性と柔軟性を大幅に向上させる重要な機能です。
XRPLのCredentials機能を活用することで、ブロックチェーン上で資格を直接管理でき、中央集権的な認証機関に依存せずにセキュアなエコシステムを構築することが可能になります。

おまけ

Credentials機能を試すことができる私のリポジトリを参考までに掲載しておきます。

https://github.com/nabe3m/xrpl-devnet-credentials

参考情報

Credential Amendment
Credentials
CredentialCreate

Discussion