Trust No One: WEB3.0原理主義者D氏の冒険
この物語を読む前に
この小説は、WEB3.0の技術や理念を分かりやすく伝えるために、あえて極端な設定で描いたフィクションです。
- 筆者は2023年半ばにDTPオペレータからエンジニアに転職し、1年間DApp開発に携わりました。そのときに得た知見を元に、この小説を書きました。
- 筆者は現在、WEB3.0から離れ、主にフロントエンド開発に携わっています。そのため、最新のトレンドは把握していません。
- 物語中のD氏は架空の人物であり、WEB3.0の「Trust No One」哲学を体現するために意図的に極端な性格設定にしています
- 基本的なアイデアは私が考案しましたが、文章構成や表現は生成AIの助けを借りています
この記事の技術情報について、完全な正確性は保証できません。あくまでWEB3.0の世界を理解するためのフィクションとして楽しんでいただければと思います。実際の開発やサービス利用の際は、必ず公式ドキュメントやソースコードを自分自身で確認してください(それこそがWEB3.0の理念でもあります)。
序章:信頼よりコードを
「Trust is good, code is better(信頼は良いが、コードはもっと良い)」
モニターの青白い光に照らされた顔に深い皺を刻みながら、D氏はこの言葉を何度も呟いた。彼の周りには、高性能サーバーが整然と並ぶ自宅のラックマウントから発せられる低い唸り声だけが響いていた。
私がD氏と出会ったのは、2023年のとある技術カンファレンスだった。当時、私はDTPオペレータからエンジニアに転職したばかりで、初めてSolidityに触れ、小規模なDApp(分散型アプリケーション)の開発に携わり始めたところだった。それまではコミックスの製版を担当しており、WEB3.0の世界観もまだよく理解していなかった私にとって、すべてが新鮮で挑戦的な経験だった。会場の片隅で、誰とも交流せず、ノートPCに向かって何かを必死に入力している彼の姿が妙に印象に残った。
「あなたは何をしているんですか?」と私が声をかけると、D氏は警戒心に満ちた目で私を一瞥した。
「このカンファレンスのWi-Fiは信用できない。自分のVPNを通して、発表者のGitHubリポジトリを全てクローンして検証している」
それが私たちの最初の会話だった。
D氏は40代半ばの元セキュリティエンジニア。5年前に大手テック企業をある「事件」をきっかけに退職し、それ以来、徹底的なWEB3.0原理主義者として生きている。彼の正体を知る人間は少なく、オンライン上では常に複数の偽名を使い分け、リアルの交流はほとんど持たない。
「中央集権的な権力に依存するシステムは、必ず腐敗する」
これが彼の信条だった。
あれから一年、私はWeb系の受託開発企業に転職し、WEB3.0の世界からは距離を置いている。しかし、D氏との奇妙な友情(彼がそう呼ぶことを許すなら)は続いていた。彼は時折、暗号化されたメッセージで連絡をよこし、私に「中央集権的な世界」の状況を尋ねてくる。
そして先週、彼から一通のメッセージが届いた。
新しいDAppを試してみることにした。
過程を記録する。
後世のために。
これは、WEB3.0の世界で生きる徹底的な原理主義者が、どのようにしてDAppと向き合うのか——その異常なまでに慎重で、時に滑稽にも見える行動の記録である。
D氏は今日も、自宅の防音室で、複数のモニターに囲まれながら呟く。
「Trust is good, code is better...」
彼の長い一日が始まろうとしていた。
D氏のモットー「Trust is good, code is better」
この言葉はWeb3やブロックチェーン技術の根底にある哲学を表現しています:
- 信頼よりも検証を重視する:人や組織を信頼するよりも、検証可能なコード(スマートコントラクト)に依拠する方が安全だという考え方
- 中央集権的な信頼から分散型の検証へ:従来のシステムでは中央機関(銀行や政府など)を信頼する必要がありましたが、ブロックチェーンではコードが透明で検証可能なため、誰かを盲目的に信頼する必要がなくなります
- 「Code is law」の思想:ブロックチェーン上では、プログラムされたコードがルールとなり、それが自動的に執行されます
D氏の極端な行動は、この哲学を体現したものなのです。
第1章:フロントエンドの精査
D氏は深呼吸をして、キーボードに指を走らせた。今日彼が挑むのは、話題の新しいDeFiプラットフォームだ。しかし、一般ユーザーのように単純にウェブサイトにアクセスしてウォレットを接続するなど、D氏には考えられない愚行だった。
「無謀すぎる。まるで見知らぬ人の車に飛び乗るようなものだ」
彼はまず、GitHubからソースコードを丁寧にクローンし、依存関係を含めた全てのパッケージの精査を始めた。「minifyされたコードなど信用できるか!」と憤りながら、難読化されたJavaScriptを一行一行解読していく。特に以下の点を徹底的にチェックしていた:
- JavaScriptのコードに悪意のある関数や不審なAPI呼び出しがないか
- サーバにクライアントの情報を勝手に送信するトラッキングコードが埋め込まれていないか
- どのコントラクトアドレスに対してどのようなリクエストを送り、どのようなレスポンスを受け取るのか(「未検証のコントラクトアドレスなど論外だ!」)
- UIに表示する情報は、RPCエンドポイントからの情報を不当に加工していないか(「表示価格の小数点以下を切り捨てているだけでも詐欺だ!」)
- ウォレット接続時に要求する権限は必要最小限か(「無限承認を求めるなど言語道断!」)
さらに、D氏はフロントエンドのホスティング方法にも厳しい目を向けた。「AWSやVercelなどの中央集権的なサービスでホストされているなど、WEB3.0の理念に反する!」と断じ、IPFSでホストされているDAppのみを高く評価する。
コードの精査が終わると、D氏は自らローカル環境でビルドし、本番環境と比較して「ビルド結果が一致しないなんて、何か裏があるに違いない」と疑心暗鬼になった。数日間の徹底的な調査の末、ようやくD氏はDAppの利用を検討する段階に進んだ。
第2章:ウォレットの選定
「メジャーだからという理由だけでMetaMaskを使うとでも?冗談じゃない」
D氏は鼻で笑いながら、ウォレット選定の作業に取り掛かった。DAppsを利用するには、ユーザ側でウォレットが必要になる。MetaMaskという分散型ウォレットがメジャーな選択肢だが、WEB3.0原理主義者のD氏が「メジャーだから」などという理由だけで納得してウォレットを導入するはずがない。
ウォレットは、秘密鍵という超重要なデータを扱う。もしも悪意のある又は脆弱性のあるウォレットを導入し、秘密鍵を盗まれてしまうと、すべての暗号資産が抜き取られてしまう。そのため、D氏はウォレット選定をかなりシビアに行った:
- オープンソースの分散型ウォレット(MetaMaskなど)のソースコードを確認する
- 問題ないことが確認できたら、ローカルPCでビルドする
「信頼できるのは、自分の目で確かめたコードだけだ」とD氏は呟きながら、深夜までコードを読み続けた。
第3章:フルノードの構築
「Infura?Alchemy?そんな中央集権的なサービスを信用できるか!」
D氏は一蹴し、自前のRPCエンドポイントを立てるためにフルノードを構築することにした。自宅のサーバーラックに設置した高性能マシンで、イーサリアムのフルノードを同期させ、数百GBのブロックチェーンデータを保持する。
「ブロックチェーンの全履歴を自分で検証できなければ、何を信じればいいというのか」
彼はまず、最新のGethクライアントのソースコードをGitHubからクローンし、コードを精査した後、自分でビルドした。
「バイナリをダウンロードするなど論外だ。自分でビルドしなければ何が含まれているか分からない」
D氏は専用の1TB NVMe SSDを用意し、ノードのデータディレクトリとして設定した。
geth --datadir /mnt/ethereum-node --syncmode "full" --http --http.api "eth,net,web3,txpool" --http.addr "127.0.0.1" --http.port 8545 --http.corsdomain "localhost" --ws --ws.api "eth,net,web3,txpool" --ws.addr "127.0.0.1" --ws.port 8546 --ws.origins "localhost"
「--http.addr "127.0.0.1"は重要だ。外部からのアクセスを許可するなど自殺行為に等しい」
彼はさらに、ファイアウォールを厳格に設定し、必要最小限のポートだけを開放した。
「同期モードはfullだ。archiveは必要ないが、lightなど論外だ。すべてのブロックヘッダーとブロックボディを自分で検証する」
同期が始まると、D氏はログを監視し続けた。
「現在のブロック高: 1,245,678...まだまだだ」
同期が完了するまでの数日間、D氏は忍耐強く待った。その間も、彼はノードの性能監視と最適化を怠らなかった。
「I/O待ちが多すぎる。ディスクのIOPSを上げる必要がある」
同期が完了すると、D氏は自作のスクリプトでノードの健全性をチェックした。
「ピア接続数: 25...十分だ。レイテンシ: 50ms...許容範囲内だ」
最後に、彼は自分のノードから取得したブロック情報と、複数の公開ノードから取得した情報を比較検証した。
「ブロックハッシュが一致している。これで信頼できるRPCエンドポイントの準備が整った」
彼にとって、これは単なる準備作業ではなく、WEB3.0の哲学そのものだった。
「自分で検証できないものを信じるな。これがWEB3.0の基本だ」
第4章:自前のIPFSノード構築
「他人のIPFSゲートウェイを信用するなど論外だ。データの完全性を自分で検証できなければ何の意味がある?」
D氏は、DAppのフロントエンドコードやNFTのメタデータがIPFSにホストされていることを確認した後、すぐに自前のIPFSノードの構築に取り掛かった。彼の自宅サーバーラックには、イーサリアムのフルノードの隣に、専用のIPFSノード用マシンが設置された。
「CIDハッシュが一致しなければ、それはデータが改ざんされた証拠だ」
D氏は、DAppが参照するすべてのIPFSコンテンツを自分のノードにピン留め(pin)し、永続的に保存することにした。彼は特に、NFTのメタデータやイメージファイルに注目していた。
「『オンチェーン』と謳っておきながら、実際はメタデータがオフチェーンというプロジェクトが多すぎる。そして、そのメタデータのホスティングが中央集権的なサーバーというのは言語道断だ」
彼は、自分のIPFSノードを通じてのみDAppのフロントエンドにアクセスし、公開ゲートウェイは一切使用しなかった。さらに、ENS(Ethereum Name Service)ドメインと組み合わせることで、常に最新バージョンのDAppにアクセスしつつも、その内容を自分で検証できる環境を整えた。
「データの永続性は自分で確保する。他人任せにするなど考えられない」
D氏のIPFSノードは24時間稼働し続け、彼が価値あると判断したコンテンツを世界中に分散配信していた。彼にとって、これはWEB3.0の理念に貢献する小さいながらも重要な一歩だった。
「分散化とは、自分自身が分散ネットワークの一部になることだ」
と、D氏は静かに呟いた。
第5章:スマートコントラクトの検証
フルノードの準備が整い、D氏はついにDAppが利用するスマートコントラクトのアドレスを特定した。Etherscanなどのブロックエクスプローラーでソースコードを確認する。
「Verifiedマークがないだと?論外だ」
幸い、このDAppのコントラクトはVerifiedされていた。しかし、D氏はそれだけでは満足しない。バイトコードと公開されたソースコードが一致するか自分でコンパイルして検証した。
「誰かの検証結果を信じるなんてありえない」とD氏は呟きながら、コンパイラのバージョンまで合わせて検証作業を行った。
D氏はソースコードを一行一行精査し始めた。特に以下の点に注意を払った:
「再入攻撃の脆弱性はないか...オーバーフロー対策は...アクセス制御は適切か...」
彼はOpenZeppelinのような信頼できるライブラリの使用を確認し、カスタム実装された部分には特に警戒心を持って臨んだ。
「オーナー権限で資金を引き出せる関数があるぞ...これは危険だ」
D氏は怪しい関数を発見するたびにメモを取り、リスク評価を行った。彼は特に、緊急時の資金引き出し機能(emergency withdraw)や、アップグレード可能なプロキシパターンの実装に細心の注意を払った。
「プロキシパターンか...実装を変更できるということは、いつでもバックドアを仕込める可能性がある」
数時間に及ぶコード監査の末、D氏はようやくこのスマートコントラクトが「許容できるリスク範囲」にあると判断した。
第6章:トランザクションの署名前に徹底検証
ついにDAppを使う準備が整った。D氏はキーボードに指を走らせ、DAppのインターフェースを操作し始めた。しかし、一般ユーザーのように単純に「Connect Wallet」ボタンをクリックするだけではない。彼はまず、ブラウザの開発者ツールを開き、ネットワークタブを監視状態にした。
「接続時にどのようなデータがやり取りされるか、まずは確認だ」
ウォレット接続のポップアップが表示されると、D氏は要求されている権限を一つ一つ精査した。
「アカウントへのアクセスのみか...チェーンIDの確認...hmm、これは許容範囲だ」
接続が完了すると、D氏はDAppのインターフェースに表示されている数値を自分のフルノードから取得したデータと照合し始めた。
「表示されているAPYが実際のコントラクトの値と一致しているか確認しなければ」
彼は自作のスクリプトを実行し、コントラクトから直接データを取得して比較した。数値が一致していることを確認すると、ようやく取引の準備に移った。
D氏がDAppの「Stake」ボタンをクリックすると、MetaMaskの署名リクエストが表示された。ここからが彼の真骨頂だった。
「まず、このコントラクトアドレスが正しいか確認する」
彼は別のモニターに表示された検証済みのコントラクトアドレスリストと照合した。
「次に、呼び出している関数を確認...これはapprove関数だ」
D氏の眉が寄った。
「approve関数?無限承認?そんな危険な権限、与えるわけがない!」
彼はMetaMaskのポップアップを閉じ、カスタムトランザクションを作成することにした。コマンドラインインターフェースを開き、ethers.jsのスクリプトを実行する。
「無限承認など論外だ。必要な分だけ承認する」
トランザクションのパラメータを設定する際、D氏はガス代にも細心の注意を払った。彼は別のターミナルウィンドウで現在のガス価格を確認するスクリプトを実行した。
「現在のベースフィーは12 Gwei、優先度手数料は0.5 Gwei...」
彼は計算機を叩き、最適なガス設定を算出した。
「急ぐ理由はない。ベースフィー+1 Gweiで十分だ」
カスタムガス設定を入力し、トランザクションの準備が整った。しかし、D氏はまだ署名ボタンを押さなかった。彼はトランザクションデータ(hex形式のデータフィールド)をコピーし、別のツールに貼り付けた。
「データフィールドをデコードして、本当に意図した操作だけが含まれているか確認する」
デコードツールは、16進数のデータを人間が読める形式に変換した。
Function: approve(address _spender, uint256 _value)
_spender: 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
_value: 100000000000000000000
「スペンダーアドレスが正しいステーキングコントラクトか確認...」
彼は再びアドレスリストと照合し、正しいことを確認した。
「値は100トークンで間違いない。これで安全だ」
ようやく署名ボタンを押す準備が整った。しかし、D氏はまだ一つの確認を行った。彼はEtherscanでこのコントラクトの最近のトランザクションを確認し、同様の操作が他のユーザーによって問題なく実行されているかを調べた。
「過去24時間のトランザクションに異常はなさそうだ」
すべての確認が完了し、D氏はようやく署名ボタンを押した。トランザクションがブロードキャストされると、彼は自分のフルノードのログを監視し、トランザクションが正しくメモリプールに入ったことを確認した。
「これで第一段階は完了だ。承認トランザクションがマイニングされるのを待ち、次にステーキング操作を行う」
D氏は、一般ユーザーが数秒で完了する操作に30分以上を費やしていた。彼の目には、何も考えずにConfirmボタンを押す一般ユーザーの姿が、目隠しをして崖から飛び降りるように見えた。
「検証なしの信頼は、WEB3.0の世界では自殺行為に等しい」
彼はモニターを見つめながら呟いた。承認トランザクションが確認されるのを待ちながら、D氏は次のステーキング操作のためのスクリプトを準備し始めた。彼の一日はまだ始まったばかりだった。
第7章:オフラインでの秘密鍵管理
D氏は主要な資産を管理するウォレットをコールドウォレット化し、インターネットに接続されていない専用PCで管理していた。DAppとの取引用には少額だけを入れた別ウォレットを使用し、取引後は即座に資金を引き上げる。
「ホットウォレットに大金を置くなんて自殺行為だ」
D氏は、オンラインPCでトランザクションの内容を準備し、それをQRコードに変換した。そのQRコードを、厳重に管理された金庫から取り出したエアギャップされたコンピュータのカメラで読み取り、保管されている秘密鍵を使ってトランザクションに署名した。署名済みのトランザクションは再びQRコードに変換され、オンラインPCのカメラで読み取られた後、D氏自身が運用するイーサリアムフルノードを通じてネットワークにブロードキャストされた。
「物理的な接続すら信用できない。電磁波漏洩すら考慮しなければ...」
D氏は時折、ファラデーケージ内でこの作業を行うこともあった。
第8章:プライバシー保護の徹底
D氏のDApp利用は、トランザクションの署名と送信で終わらなかった。彼にとって、ブロックチェーンの透明性は諸刃の剣だった。すべてのトランザクションが公開され、永続的に記録されるという特性は、プライバシーという観点では大きなリスクとなる。
「ブロックチェーンは透明すぎる。プライバシーは自分で守るしかない」
朝の光がカーテンの隙間から差し込む中、D氏は通常のブラウザを閉じ、別のマシンを起動した。そこには既にTorブラウザが準備されていた。
「IPアドレスの追跡は基本中の基本。それすら対策できないようでは話にならない」
彼はTorブラウザを起動し、複数のノードを経由して自分のIPアドレスを隠した状態でDAppにアクセスした。さらに、VPNを二重に使用するダブルVPN構成も施していた。
「フロントエンドのJavaScriptが何かを追跡していないか確認済みだが、念には念を入れる」
D氏は、DAppとのやり取りに使用するウォレットアドレスについても細心の注意を払っていた。彼のメインウォレットから直接トランザクションを送信することはなかった。代わりに、複雑なウォレット構造を構築していた。
「アドレス間の関連性を断ち切るためのミキシングは必須だ」
彼はコマンドラインインターフェースを開き、複数のウォレット間でトランザクションを経由させる自作のスクリプトを実行した。
const mixingPath = [wallet1, wallet2, wallet3, wallet4, targetWallet];
await executePrivacyEnhancedTransfer(token, amount, mixingPath);
「時間差を設けて、複数の中間ウォレットを経由させる。パターン分析による追跡を困難にする」
D氏のモニターには、複数のトランザクションが時間差で実行されていく様子が表示されていた。彼は各トランザクションの間に、ランダムな待機時間を設けていた。
「予測可能なパターンは追跡の手がかりになる」
さらに、D氏はTornado Cashのようなプライバシー強化ツールも利用していた。これにより、資金の出所を完全に隠蔽することが可能になる。
「法的に問題のない範囲でのプライバシー保護は、基本的人権だ」
彼はブロックチェーン分析ツールを使って、自分のトランザクションパスを追跡できるか自己検証も行った。満足のいく結果が得られると、小さくうなずいた。
「次は、メタデータの漏洩対策だ」
D氏はブラウザの設定を確認し、WebRTCを無効化し、JavaScriptを必要最小限に制限した。さらに、ブラウザのフィンガープリント対策も施していた。
「ブラウザフィンガープリントによる追跡も侮れない。キャンバスフィンガープリント、オーディオフィンガープリント、すべて対策する」
彼はDAppを使用する際、毎回異なるブラウザプロファイルを使用し、セッション終了後はすべての痕跡を消去した。
「デジタルフットプリントを最小限に抑える。これがWEB3.0時代の自己防衛だ」
トランザクションが完了すると、D氏は使用したウォレットの残高をすべて別のアドレスに移し、「使い捨てウォレット」として放棄した。
「同じウォレットを継続的に使用することは、行動パターンを晒すようなものだ」
彼はTorブラウザを閉じ、使用したマシンのRAMディスクをクリアした。物理メモリにすら痕跡を残さないという徹底ぶりだった。
「プライバシーは権利であり、責任でもある。自分で守らなければ誰も守ってくれない」
窓の外では、普通の人々が何も考えずにスマートフォンでDAppを使用している。D氏にとって、それは無防備に個人情報を晒しているように見えた。彼は静かにカーテンを閉め、次の作業に取り掛かった。
「Trust is good, code is better. But privacy is paramount.」
第9章:コミュニティの監視
D氏はDiscordやTelegramなどのコミュニティチャンネルを常に監視していたが、決して自分から発言することはなかった。
「情報は集めるが、自分の情報は出さない」
これが彼の鉄則だった。プロジェクトの開発者が匿名であることを高く評価し、KYC(本人確認)を要求するプロジェクトには一切関わらない。
エピローグ
このようにD氏のDApp利用は、一般ユーザーからすれば極端に見えるかもしれないが、WEB3.0の「Trust No One(誰も信用するな)」という哲学を体現している。実際のところ、こうした慎重さの一部は、WEB3.0の世界では決して無駄ではないのかもしれない。
私が最後にD氏から受け取ったメッセージはこうだった:
DAppの利用は完了した。
予想通り、ほとんどのユーザーは自分が何をしているのか理解していない。
だが、それが彼らの選択だ。
私は私の道を行く。
Trust is good, code is better.
WEB3.0の世界には、D氏のような原理主義者から、何も考えずにボタンを押すだけのユーザーまで、様々な人々が存在する。その多様性こそが、この新しいデジタルフロンティアの魅力なのかもしれない。