mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
1671 文字
4 分
EOA向けのEVMウォレットログイン画面
2026-06-08
2026-06-09

以下は筆者の現時点での理解を表すものにすぎません

=====================

最近、主にフロントエンドのEOA walletログインの画面を作りました。blockChain開発に触れ始めた、とも言えるでしょうし、ちょうどEVMが実際にどのように操作されるのかにも触れたと言えます。

dreaifeHebi
/
web3WalletLogin
Waiting for api.github.com...
00K
0K
0K
Waiting...

image.png

1回のwallet login#

1回とは言っても、実際にウォレット側で確認が必要なインタラクションは2回あります——1回はページ側から開始されるウォレットアドレス取得の確認、もう1回はサーバー側が認証message/呼び出しドメイン/nonceなど、プロトコル構造に合ったもの(現在使っている構造はEIP-4361を模倣したものです。ただ、実際には個人的にはここはUI/追跡可能性の設計寄りで、実際にはnonceがリクエストの混同を防ぐことを保証できればよい気がします)などのmessageをウォレットに送って検証を要求するものです。

なぜ先にウォレットアドレスを取得してからでないと検証を開始できないのでしょうか?おそらく、ブラウザとウォレットの両方が本質的には信頼できないためです。もし中間のやり取りで直接与えられるデータがすべて信頼できないと考えるなら、ウォレットによって確認されたアドレスだけが信頼できるものとなり、その後で次のウォレット検証へ進める、ということになります。

このウォレットを制御しているのは私だ!#

あなたのウォレットアドレスは何ですか?#

ここでは実際には、ブラウザとウォレット間のインタラクションで、どのウォレットアドレスを選択してWebサイトに提供する権限を与えるかを確認するためのものです。

このプロジェクトでは実際にwagmiのconnectを使ってウォレットとのインタラクションをリクエストしています。

// wagmi config
export const wagmiConfig = createConfig({
...,
connectors: [injected({ shimDisconnect: true })],
...
});
// get wagmi injected connector
const injectedConnector = useMemo(
() => connectors.find((connector) => connector.id === "injected") ?? connectors[0],
[connectors]
);
// connect wallet
connect({ connector: injectedConnector });
// auto get wallet connect info
const { address, chainId, isConnected } = useAccount();

ここでもwagmiのuseAccountを通して、ウォレットで確認された後に更新される情報を自動的に取得しています。

では、あなたが言っているこのウォレットはあなたのものですか?#

この情報を認証してもらう必要があります#

認証すべきアドレスが分かったので、標準プロトコルSIWE(Sign-In with Ethereum)のログイン署名messageを準備できます。だいたい次のような形式のmessageです:

localhost:3000 wants you to sign in with your Ethereum account:
0xYourWalletAddress
Sign in to web3walletLogin with this wallet.
URI: http://localhost:3000
Version: 1
Chain ID: 1
Nonce: <server-issued nonce>
Issued At: <generated timestamp>

その後、このmessageに対してEIP-191の標準化を行い、他の署名や通常のトランザクションと区別できるようにします:

"\x19Ethereum Signed Message:\n" + len(message) + message

実装上は、wagmiのsignMessageAsyncを使ってウォレットへの実際の認証リクエストを行っています。

const { signMessageAsync, isPending: isSigning } = useSignMessage();
// make a siwe message
const siweMessage = new SiweMessage({
domain: window.location.host,
address,
statement: "Sign in to web3walletLogin with this wallet.",
uri: siteOrigin,
version: "1",
chainId,
nonce
});
const preparedMessage = siweMessage.prepareMessage();
// send sign request to wallet
const signature = await signMessageAsync({ message: preparedMessage });

これは私の秘密鍵だけが作成できる認証です#

このmessageがウォレットに届いて認証を要求するとき、ウォレットは自分の署名によって、以前提供したアドレスに対する制御権を検証できるようにする必要があります。このとき、ウォレットは自分の秘密鍵で先ほど送られてきた情報のhashを暗号化しつつ、この署名がウォレットアドレスとリクエストmessageだけを知っているWebサイトによって検証可能であることも保証する必要があります。ここで必要になるのは当然、一連の数学的変換によってこの検証方法の妥当性を保証することです。もちろん、ここではひとまずwagmiのアルゴリズムを使って返ってきたsignを検証しています(

// use the message (the client send) and sign(the wallet back)
const verifyResponse = await fetch("/api/auth/verify", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ message: preparedMessage, signature })
});
// sign message verify
const siwe = new SiweMessage(body.message);
const result = await siwe.verify({
signature: body.signature,
domain: expectedDomain,
nonce: siwe.nonce
});
// the fail result
if (!result.success) {
return NextResponse.json({ error: "invalid signature" }, { status: 401 });
}

実際の検算については?

それを見るには、EOAウォレットの署名で使われるsecp256k1曲線を見る必要があります。EOAウォレットにとっては、おおよそ次のようなものです:

  • EOA 秘密鍵:256-bit程度の乱数 d
  • 公開鍵:楕円曲線上の点 Q = d * G
  • アドレス:keccak256(publicKey) の後ろ20バイト
  • 署名:ECDSA over secp256k1

ただ、実は私もこの部分の実際の計算はあまり理解していません(。ただ、署名とmessage hashから得られる公開鍵Qから秘密鍵dへ逆算できないのは、要するに21282^{128}程度の計算量(secp256k1は256bit級の曲線)を要するQ=dGQ = d * G楕円曲線離散対数問題を解くことに相当するから、ということくらいは分かっています。

このように、最終的に返ってきたsign(r+s+vr + s + v)と自分が送ったmessage hashから公開鍵をrecoverし、その公開鍵から計算されたアドレスが、以前提供されたアドレスと一致する場合、このウォレットがそのアドレスに対する制御権を持っていることが証明されます。

結び#

blockChainの実開発の始まりとしては、だいたいこんな感じでしょう。正直、実際の秘密鍵署名と署名リカバリの実装を見ていると、昔acmを勉強していた頃の感覚が少しありました(

ただ、入口になるプロジェクトとしてはちょうどよく、自分のblockChainへの学習意欲を引き上げてくれた気がします。

共有

この記事が役に立ったときは、ぜひ他の人に共有してください!

EOA向けのEVMウォレットログイン画面
https://dreaife.tokyo/jp/posts/evm-wallet-login/
著者
dreaife
公開日
2026-06-08
ライセンス
CC BY-NC-SA 4.0

一部の情報は古い可能性があります

関連した投稿 スマート
1
EOAウォレットの署名検証とその関連内容について
WEB3 EOAウォレットの署名検証を、secp256k1、ECDSAのr/s/v、公開鍵復元、keccak-256によるアドレス計算から整理し、SIWEログインで秘密鍵を渡さず所有権を確認する仕組みを解説します。
2
ブロックチェーン入門
WEB3 ブロックチェーンは、時系列に連結されたブロックで構成される構造で、分散性、改ざん耐性、透明性、安全性といった中核的な特性を持ちます。仕組みとしては、取引の生成、検証、パッケージ化、チェーンへの追加が含まれます。暗号資産、サプライチェーン管理、金融サービスなどで活用されますが、拡張性、消費電力、ユーザー教育といった課題もあります。基盤となるロジックは分散台帳とコンセンサス機構に基づき、データの安全性と整合性を保証します。
3
トレード記録
WEB3 最近のトレード経験では比較的高い勝率を維持しており、特に2月3日のショートで大きな利益を得ました。判断ミスによって一部利益を失った場面はあったものの、全体としてはプラス収益です。現在の市場はレンジ相場で、短期的には二度目のテストが来る可能性があるため慎重な対応が必要です。トレード戦略は主にローソク足と出来高を基準とし、資金配分は80%を低レバの大局トレード、10%を高レバ高頻度トレード、残りをオンチェーン操作に充てています。感情的な売買を避けるため、判断が不明確なときはノーポジションを選び、キャッシュフローが安定してから高リスク運用を行うことを勧めています。
4
新時代の第一回選考
life この記事では、AIが急速に発展する中で、先進的なモデルを利用するコストが新たな社会的選別の重要な要因になることを考察しています。著者は、モデル利用料金の上昇によってデジタルデバイドが生じる可能性への不安を述べ、利用料金が現在の補助的な価格からより高い水準へ引き上げられた場合、一般ユーザーには負担が難しくなり、技術利用における階層分化が形成される可能性があると指摘しています。また、AIがセキュリティ、動画、音楽などの分野で多様に活用されていることを振り返り、AIがコーディングツールからより幅広い産業へ浸透しつつあることを強調しています。著者は個人的な視点から、限られた資本の中で時代の波をどのように模索しながら前進していくかを述べ、技術コストが一般利用に与える影響に注目するよう呼びかけています。キーワード:AIモデルコスト、デジタルデバイド、技術的選別、AI活用、時代への不安。
5
ブログ移行-Mizuki設定記録
infra notionNextからmizukiへの移行過程の記録、主な理由はnotionNextの制限です。mizukiを選んだ理由は、軽量で機能のバランスが良く、日記とプロジェクトの表示をサポートしているからです。設定プロセスは簡単で、内容はmdとtsファイルによって制御され、同時にbangumi APIとの接続も実現しています。CIを用いてNotionのコンテンツを同期する計画を立て、多言語対応を進め、画像リンクの有効期限切れの問題を解決しました。

目次