2026年6月17日

2026年6月17日

WordPressとWeb3 dAppを連携する方法(ウォレット接続の仕組みと安全な実装)

WordPressとWeb3のdApp(分散型アプリケーション)を連携させる場合、WordPressが担うのは「訪問者のブラウザにあるウォレットと会話する画面を出すこと」までです。秘密鍵はユーザーのウォレットの中にあり、署名もウォレットの中で行われます。サーバー側のWordPressが鍵を預かったり署名を代行したりする構成は避けてください。この記事では、連携のパターンの整理、EIP-1193に沿ったウォレット接続のコード、スクリプトの読み込み方、署名要求とフィッシングのリスク、テストの進め方を技術面に絞って説明します。投資や価格、特定のトークンの話は扱いません。

「連携」には4つの段階がある

一口にWeb3連携と言っても、実装の重さとリスクは段階によって大きく違います。まず自分のサイトでどこまで必要かを決めてください。

  1. チェーンのデータを表示するだけ: コントラクトの公開情報を読み取って表示する。ウォレット接続は不要
  2. ウォレットを接続してアドレスを表示する: 訪問者が自分のアドレスをサイトに知らせる。署名は発生しない
  3. 署名でログインや本人確認をする: 訪問者に文章へ署名してもらい、そのアドレスの持ち主であることを確かめる
  4. トランザクションを送る: コントラクトの関数を呼び、チェーン上の状態を変える。手数料(ガス代)がかかり、取り消しはできない

1と2はWordPressの通常のスクリプト開発の延長でできます。3はサーバー側での署名検証が必要になり、4はユーザーの資産に直接関わる処理です。4が必要な場合でも、WordPressに独自実装するより、dAppの公式の画面へリンクで案内するほうが安全なことが多くあります。

ウォレット接続の仕組み: EIP-1193

MetaMask などのブラウザ拡張ウォレットは、ページに window.ethereum というオブジェクトを差し込みます。このオブジェクトの決まりごとを定めたのがEIP-1193という仕様で、request() メソッドにJSON-RPCのメソッド名を渡して操作します。

複数のウォレット拡張を入れている環境では window.ethereum が取り合いになるため、各ウォレットが自分の存在を知らせるEIP-6963という仕組みも広まっています。ethers.js や viem などのライブラリ、ウォレット接続用のUIライブラリを使うと、こうした違いを吸収できます。対応状況はライブラリごとに異なるため、採用前にドキュメントを確認してください(2026年10月現在)。

以下は、ライブラリを使わずにEIP-1193だけで接続ボタンを作る最小の例です。

<!-- 固定ページやカスタムHTMLブロックに置くマークアップ -->
<button type="button" id="wallet-connect">ウォレットを接続</button>
<p id="wallet-status" aria-live="polite"></p>
// wallet-connect.js
(() => {
  const button = document.getElementById('wallet-connect');
  const status = document.getElementById('wallet-status');
  if (!button || !status) return;

  const eth = window.ethereum;

  function show(text) {
    status.textContent = text; // innerHTML は使わない
  }

  button.addEventListener('click', async () => {
    if (!eth) {
      show('ウォレットの拡張機能が見つかりません。');
      return;
    }
    try {
      const accounts = await eth.request({ method: 'eth_requestAccounts' });
      const chainId = await eth.request({ method: 'eth_chainId' });
      show('接続中: ' + accounts[0] + '(チェーンID ' + parseInt(chainId, 16) + ')');
    } catch (err) {
      if (err && err.code === 4001) {
        show('接続はキャンセルされました。');
      } else {
        show('接続できませんでした。');
      }
    }
  });

  if (eth && eth.on) {
    eth.on('accountsChanged', (accounts) => {
      show(accounts.length ? '接続中: ' + accounts[0] : '接続が解除されました。');
    });
    eth.on('chainChanged', () => window.location.reload());
  }
})();

eth_requestAccounts を呼ぶと、ウォレット側に接続の許可を求める画面が出ます。ユーザーが断るとコード 4001 のエラーが返るので、エラーとして騒がずに「キャンセルされました」と静かに表示するのが親切です。アカウントやチェーンは途中で切り替えられることがあるため、accountsChanged と chainChanged のイベントを受けて表示を更新します。

ここで取得したアドレスは、あくまで「ブラウザが申告した値」です。この時点では本人確認になっていないので、アドレスを根拠に会員限定コンテンツを開放するといった使い方はできません。

スクリプトはWordPressの仕組みで読み込む

上のJavaScriptは、テーマのテンプレートに <script> を直書きせず、wp_enqueue_script() で読み込みます。必要なページだけに限定すると、他のページの表示速度に影響しません。

<?php
// 子テーマの functions.php または自作プラグインに追加
add_action( 'wp_enqueue_scripts', function () {
	if ( ! is_page( 'wallet' ) ) { // 接続ボタンを置く固定ページのスラッグ
		return;
	}
	wp_enqueue_script(
		'my-wallet-connect',
		get_stylesheet_directory_uri() . '/js/wallet-connect.js',
		array(),
		'1.0.0',
		array(
			'in_footer' => true,
			'strategy'  => 'defer',
		)
	);
} );

第5引数に配列で strategy を渡す書き方はWordPress 6.3以降で使えます。ethers.js や viem をESM形式で読み込む場合は、WordPress 6.5以降の wp_enqueue_script_module() を使う方法があります。

外部ライブラリは、バージョンを固定し、できれば自サイトに置いて配信します。CDNのURLにバージョンを書かないと、知らない間に中身が変わる可能性があります。ウォレットを扱うページで読み込むスクリプトは、改ざんされたときの被害が大きいため、読み込み元を最小限にしてください。

署名ログインを実装する場合の考え方

「ウォレットでログイン」を実現するには、サーバーが発行した使い捨ての値(nonce)を含む文章にユーザーが署名し、サーバー側でその署名から得られるアドレスを検証します。メッセージの書式としては、ドメイン、アドレス、nonce、発行日時などを含めるSign-In with Ethereum(EIP-4361)が広く参照されています。

PHPで署名を検証するには楕円曲線暗号とハッシュの処理が必要で、自作するとミスが入り込みやすい部分です。保守されているライブラリやプラグインを選び、次の点が満たされているかを確認してください。

  • nonceはサーバーが発行し、1回使ったら無効にする。有効期限も設ける
  • 署名する文章に自サイトのドメインを含め、別サイト向けの署名を流用できないようにする
  • 検証に成功した後は、WordPressの通常のログインセッションに切り替え、権限は最小限のロールにする

署名要求とフィッシングのリスク

Web3連携でいちばん注意が必要なのは、サイト側の不具合よりも「悪意ある署名要求」です。ユーザーが内容をよく読まずに署名すると、トークンの使用許可(承認)を第三者に与えてしまい、資産を移されることがあります。

サイト運営者として、次の点を守ってください。

  • 秘密鍵やシードフレーズ(復元用の単語列)を入力させる画面を作らない。サイト上に「当サイトが秘密鍵やシードフレーズを尋ねることはありません」と明記する
  • サーバー側にウォレットの鍵を置いて自動で送金や署名をする仕組みは作らない
  • 署名を求めるときは、何のための署名か、資産の移動を伴うかを画面上で平易に説明する
  • 中身を読めない形式の署名(生データへの署名など)や、すべてのトークンの承認を求める要求は使わない
  • 接続先のコントラクトアドレスはコードに固定し、公式の発表と照合する

もう1つの大きなリスクは、WordPressそのものの乗っ取りです。管理画面に侵入されると、正規の接続ボタンを偽物に差し替えられ、訪問者に不正な署名を求めるスクリプトを配信されるおそれがあります。管理者の二段階認証、不要なプラグインの削除、更新の継続、ファイル改ざんの監視、Content-Security-Policyによるスクリプト読み込み元の制限を組み合わせて守ります。ドメインやDNSの管理アカウントも乗っ取りの対象になるため、同じように保護してください。

テストはテストネットで行う

開発中は、本番のチェーンではなくテストネットで動作を確かめます。Ethereumでは Sepolia などのテストネットが使われています(2026年10月現在。利用できるテストネットは変わることがあります)。ウォレット側でテストネットに切り替え、eth_chainId の値が想定したチェーンになっているかを画面で確認し、想定外のチェーンに接続されている場合は操作を進めない作りにしておくと安心です。

あわせて、ウォレット拡張がないブラウザ、スマートフォンのブラウザ、接続を断った場合、途中でアカウントを切り替えた場合の表示も確認しておきます。

法務・税務の確認

トークンの販売、交換、配布をサイトで扱う場合、資金決済や金融商品に関する法令、消費者保護、税務などの論点が出てきます。どの規制がかかるかは仕組みによって異なり、判断を誤ると影響が大きいため、事業として行う前に弁護士や税理士などの専門家に相談してください。

まとめ

  • 連携は「表示」「接続」「署名ログイン」「トランザクション」の4段階で考え、必要な段階までにとどめる
  • ウォレット接続はEIP-1193の request() とイベントで実装し、スクリプトは wp_enqueue_script() で必要なページだけに読み込む
  • 接続で得たアドレスは申告値にすぎない。本人確認が必要なら、nonceとドメインを含む署名を保守されたライブラリで検証する
  • 秘密鍵やシードフレーズはサーバーにもフォームにも置かない。署名要求の目的を画面で説明する
  • 管理画面の乗っ取りが最大のリスクになるため、WordPress本体のセキュリティ対策を合わせて行う

お気軽にご相談ください

お見積りへ お問い合わせへ
▲