所有者(owner)状態の検証 — 3チェーン7つの Ownable、編集・改ざん可Owner-state verification — 7 Ownable across 3 chains, editable & tamperable v3
3チェーンの Ownable 契約 7件に owner()(eth_call 0x8da5cb5b)を読み、すべて同一のデプロイヤー EOA を返すか照合します。
期待値は編集でき、「わざと壊す」で実際に赤くなります=always-pass ではありません。Reads owner() (eth_call 0x8da5cb5b) on 7 Ownable contracts across 3 chains and checks whether they all return the same deployer EOA.
The expected value is editable; the sanity-break button actually turns it red — it is not always-pass.
方法A(おすすめ):下の「検証する」を押すだけ。3チェーンの owner() を自動取得し、すべて同一デプロイヤーかの照合まで完結します。「わざと壊す」で実際に赤くなることも確認できます。Method A (recommended): just press Verify. It fetches owner() across all 3 chains and judges whether they share one deployer — 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 the expected value. The ethers and curl commands below are two alternative ways to do the same thing (not sequential — either one is fine).
自動取得が拡張機能等でブロックされる/一部チェーンが未到達のときは、下のコマンドで直接確認できます。7件すべてが期待値(既定 0xF713…4a95)を返せば一致です。If auto-fetch is blocked or a chain is unreachable, confirm directly with the commands below. It is a match when all seven return the expected owner (default 0xF713…4a95).
ethers v6(自分のノードの client ディレクトリで実行・先頭の cd は自分のパスに置き換え・7件3チェーン)ethers v6 (run in your node’s client dir — replace the leading cd with your own path; all 7 across 3 chains):
cd /var/www/あなたのドメインyour-domain/client node -e 'const {ethers}=require("ethers");const base=new ethers.JsonRpcProvider("https://base-sepolia-rpc.publicnode.com");const sep=new ethers.JsonRpcProvider("https://ethereum-sepolia-rpc.publicnode.com");const arb=new ethers.JsonRpcProvider("https://arbitrum-sepolia-rpc.publicnode.com");const abi=["function owner() view returns (address)"];const C=[[base,"0x5674e4658b988Ed9337DD0CAa493C6aA908006af","CawActions@L2"],[base,"0x0c3e245f3939B4D9f30e088988dD9D7C8F86b11d","CawProfileL2@L2"],[base,"0x3b2A9ac4f274eE6E73CbAD198F80f455e70C3C05","CawActionsArchive@L2"],[base,"0x8195A9a8a97658672d5384e19a763804D6E16639","CawChallengeRelay@L2"],[sep,"0xD20bE35D2365C0f7DaF563A47b29eB5a165C2007","CawActions@L1"],[sep,"0x9CEffADC838a39D10a241d9A473844Ef0cB6274f","CawProfileURI@L1"],[arb,"0x287b249B58bF65411D4Da89dAdEF0e30496a0D4c","CawActions@L2b"]];(async()=>{for(const [p,a,name] of C){console.log(name.padEnd(22),await new ethers.Contract(a,abi,p).owner());}})();'
curl(依存ゼロ・1件例)curl (no deps, one example):
curl -s https://base-sepolia-rpc.publicnode.com -X POST -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x5674e4658b988Ed9337DD0CAa493C6aA908006af","data":"0x8da5cb5b"},"latest"]}'
curl の返り値は 32 バイト(左ゼロ詰め)。末尾 40 桁が owner です。L1/L2b は RPC を各チェーンのものに差し替えてください。The curl result is 32 bytes (left-zero-padded); the last 40 hex chars are the owner. For L1/L2b, swap in each chain’s RPC.
・検証する Ownable 契約7件:
Base Sepolia (L2) — CawActions 0x5674…06af, CawProfileL2 0x0c3e…b11d, CawActionsArchive 0x3b2A…3C05, CawChallengeRelay 0x8195…6639
Sepolia (L1) — CawActions 0xD20b…2007, CawProfileURI 0x9CEf…274f
Arbitrum Sepolia (L2b) — CawActions 0x287b…0D4c
・呼び出し:eth_call { to: 契約, data: 0x8da5cb5b }(= keccak256("owner()") の先頭4バイト)
・各チェーンとも Blockscout (GET) → publicnode → drpc を自動で試します。あるチェーンの公開 RPC が全滅した場合は「未到達(?)」と表示し、不一致(✗)と区別します。
・owner() を持たない群(ClientManager・Minter 等の ownerless 契約)は対象外です(そもそも owner() 関数を持ちません)。
・独立性:ソース可読・判定はアドレス一致比較のみ・RPC は CLI で自分のノードに差し替え可。期待値は編集でき、「わざと壊す」で実際に赤くなります。Ownable contracts checked (7):
Base Sepolia (L2) — CawActions 0x5674…06af, CawProfileL2 0x0c3e…b11d, CawActionsArchive 0x3b2A…3C05, CawChallengeRelay 0x8195…6639
Sepolia (L1) — CawActions 0xD20b…2007, CawProfileURI 0x9CEf…274f
Arbitrum Sepolia (L2b) — CawActions 0x287b…0D4c
Call: eth_call { to: contract, data: 0x8da5cb5b } (= the first 4 bytes of keccak256("owner()")).
Each chain tries Blockscout (GET) → publicnode → drpc in order. If every public RPC for a chain fails, it shows “unreachable(?)” — kept distinct from a mismatch (✗).
Ownerless contracts (ClientManager, Minter, etc.) are out of scope — they have no owner() function.
Independence: readable source, plain address-equality only, RPC swappable to your own node via CLI. The expected value is editable and the sanity-break button actually turns it red.