peers メッシュの検証 — 改ざん可、ブラウザ内で完結Peer-mesh verification — tamperable, in your browser v2
3チェーン(Sepolia 40161 / Base Sepolia 40245 / Arbitrum Sepolia 40231)の 8 有向エッジの peers(eid) を読み、各エッジが正しい相手を往復で指すか照合します。
「わざと壊す」で全期待値を改変すると、到達済みエッジが実際に赤くなります=always-pass ではありません。Reads peers(eid) for 8 directed edges across 3 chains (Sepolia 40161 / Base Sepolia 40245 / Arbitrum Sepolia 40231) and checks that each edge points to the correct counterpart, in both directions.
Sanity-break tampers all expected values and the reached edges actually turn red — it is not always-pass.
方法A(おすすめ):下の「検証する」を押すだけ。8エッジの peers を自動取得し、往復照合まで完結します。「わざと壊す」で実際に赤くなることも確認できます。Method A (recommended): just press Verify. It fetches peers for all 8 edges and checks them round-trip in one step. Sanity-break confirms it really goes red.
方法B:コマンドで確認(自分のノードで完結・貼り付け不要)Method B: confirm via command (all on your own node, no paste)
自動取得(方法A)が拡張機能などで塞がれても、ノードで実行して出力を期待値と見比べるだけで確認できます。下の ethers と curl は同じことを別ツールでやる代替です(順番ではありません・どちらか一方で OK)。Even if auto-fetch (Method A) is blocked by an extension, you can run it on your node and compare the output against expectations. The ethers and curl commands below are two alternative ways to do the same thing (not sequential — either one is fine).
自動取得が弾かれる/一部チェーンが未到達のときは、下のコマンドで。返り値の下位20バイトが「指すべき相手」と一致すれば OK。If auto-fetch is blocked or a chain is unreachable, use the commands below. It is OK when the low 20 bytes of the return equal the intended counterpart.
ethers v6(自分のノードの client ディレクトリで実行・先頭の cd は自分のパスに置き換え)ethers v6 (run in your node’s client dir — replace the leading cd with your own path):
cd /var/www/あなたのドメインyour-domain/client node -e 'const {ethers}=require("ethers");const P={base:new ethers.JsonRpcProvider("https://base-sepolia-rpc.publicnode.com"),sep:new ethers.JsonRpcProvider("https://ethereum-sepolia-rpc.publicnode.com"),arb:new ethers.JsonRpcProvider("https://arbitrum-sepolia-rpc.publicnode.com")};const abi=["function peers(uint32) view returns (bytes32)"];const E=[["sep","0x9fcbb3d6880cD3293F1a731Fe6c958a6621a74bF",40245,"CawProfile_L1->ProfileL2_L2"],["base","0x0c3e245f3939B4D9f30e088988dD9D7C8F86b11d",40161,"ProfileL2_L2->CawProfile_L1"],["sep","0x9fcbb3d6880cD3293F1a731Fe6c958a6621a74bF",40231,"CawProfile_L1->ProfileL2_L2b"],["arb","0xbB9c2A3e8222d13f9E8469BB71cE62c3c2E82941",40161,"ProfileL2_L2b->CawProfile_L1"],["base","0x8195A9a8a97658672d5384e19a763804D6E16639",40231,"Relay_L2->Archive_L2b"],["arb","0x5bCbB34f51156D605331f9d6F76a44DEa1d279E5",40245,"Archive_L2b->Relay_L2"],["base","0x3b2A9ac4f274eE6E73CbAD198F80f455e70C3C05",40231,"Archive_L2->Relay_L2b"],["arb","0x454450aA713A99B06EE4aA05Ede5d80ca1bd3075",40245,"Relay_L2b->Archive_L2"]];(async()=>{for(const [c,a,eid,label] of E){const r=await new ethers.Contract(a,abi,P[c]).peers(eid);console.log(label,ethers.getAddress("0x"+r.slice(-40)));}})();'
・peers(uint32)=0xbb0b6a53。data = セレクタ + eid(32byte)。返り値 bytes32 の下位20バイトが相手アドレス。
・各エッジは読み出し元 OApp の在るチェーンで読みます。各チェーンとも Blockscout (GET) → publicnode → drpc を自動で試します。
・あるチェーンの公開 RPC が全滅した場合、そのエッジは「未到達(?)」として不一致(✗)と区別します。
・独立性:ソース可読・判定はアドレス一致比較のみ・RPC は CLI で自分のノードに差し替え可。「わざと壊す」で実際に赤くなります。peers(uint32)=0xbb0b6a53. data = selector + eid(32 bytes). The low 20 bytes of the returned bytes32 are the counterpart address.
Each edge is read on the chain where its source OApp lives. Each chain tries Blockscout (GET) → publicnode → drpc in order.
If every public RPC for a chain fails, that edge is shown as “unreachable(?)” and kept distinct from a mismatch (✗).
Independence: readable source, plain address-equality only, RPC swappable to your own node via CLI. Sanity-break actually turns it red.