A-1 bytecode


この項目では、live V1 テストネットにデプロイされている CAW の各コントラクトの実行コードが、公開ソースをコンパイルした結果と一致するかを確かめます。エクスプローラの「検証済み」表示には頼りません――というより、これらの契約は Basescan 等で未検証です。だからこそ、自分の手元で同じものをコンパイルし、チェーン上のコードと突き合わせる。誰かの説明ではなく、再現できる証拠で語ります。

やさしく言うと

公開されている「レシピ」(ソースコード)と、実際に出てきた「料理」(チェーン上で動いているコード)が同じものか――それを確かめる項目です。私たちはレシピを取り寄せ、自分の手で同じ手順どおりに調理し(コンパイルし)、出来上がりを実際の料理とバイト単位で見比べました。

公開ソースsource

自分でコンパイル同じ手順で

チェーン上のコード= 完全一致

結果は バイト単位でぴたり一致。しかも参照アドレス(immutable)を伏せた「コード本体」だけでなく、末尾のメタデータ(ソースのハッシュ)まで含めて一致しました。つまり「動いているコード=公開されているソース」を、エクスプローラのバッジに頼らず自分のキッチンだけで確かめた、ということです。

このページは検証台帳A-1 項目の詳細記録です。

1. 主張(検証対象)

live V1 の各コントラクトの実行コード(runtime bytecode)が、公開リポジトリ GilgameshCaw/Caw のソースをコンパイルした結果と一致すること。ブロックエクスプローラのソース検証機能には依存せず(実際これらは未検証)、第三者が同じ手順で同じハッシュに到達できる、再現可能な形で証明します。

2. 検証方法

ビルド設定は、デプロイ当時の hardhat.config.js と、リポジトリにコミットされた solidity/package-lock.json(依存を版固定)に準拠します。

項目
solc 0.8.22
optimizer 有効・runs = 1
viaIR true
evmVersion paris
依存 OZ 4.9.6 / LayerZero oapp-v2 2.3.44 ほか(lock 固定)

手順は4つです。

1

ローカルでコンパイル

各コントラクトを上記設定でコンパイルし、deployedBytecodeimmutableReferences(immutable が置かれるバイト位置)を取得する。

2

canonical ハッシュを算出

immutable 領域(各32バイト)をゼロ化して、keccak256 を出す。

3

オンチェーンを同じ形に

実コードを取得し、同じ immutable 領域でゼロ化して keccak256 を出す。

4

突き合わせる

両者のハッシュが一致すれば、コードは公開ソースそのもの。今回はメタデータ込みの値(full)まで一致しました。

なぜ immutable 領域をゼロ化するのか。immutable 変数はデプロイ時に実行コードへ焼き込まれ、ソースには無い実値(例:LayerZero エンドポイントアドレス)が入ります。そのため生のバイトコードは必ず差が出る。コードそのものの同一性を見るには、この領域を両側で除外して比べる必要があります。なお evmVersionparis でした――既定の shanghai(PUSH0 命令あり)でビルドすると長さがズレ、paris でのみ長さ・メタデータまで完全一致したことから確定できます。

3. 判定

実プロトコル契約のコードを byte 完全一致で確認
デプロイ済み実行コードが、公開ソースのコンパイル結果と全契約で byte 完全一致(immutable をゼロ化、メタデータ込み)。コアは commit a26e0063、Marketplace のみ後発 d5dfc730。CAW token は外部の既存契約で対象外。

結果はこうなりました。

  • 一致 コアのプロトコル契約 12型(CawActions・CawProfileL2・CawActionsArchive・CawChallengeRelay・CawProfile・CawClientManager・Minter・Quoter・URI・BuyAndBurn・FontDataA/B)が、L1/L2/L2b の全インスタンスで byte 完全一致。ソースは commit a26e0063
  • 一致 CawProfileMarketplace は後発 commit d5dfc730(監査修正 H-15/H-17 等の後に増分再デプロイされた版)から byte 完全一致。デプロイは単一コミットではなく増分で、各契約は実デプロイ時のソースに対応します。
  • 対象外 CAW token(MintableCaw)は、deploy.js に「再デプロイしない既存契約」と明記された外部の既存トークンです。ソースツリーの一部ではないため、本項目のソース照合の対象外(=一致しないのが正しい)。本物の CAW は別途の既存 ERC20。

実プロトコルのコントラクトは、エクスプローラ未検証であっても、自前のコンパイルだけで全件 byte 完全一致を確認しました。

4. receipt(公開証明)

誰でも再現できるよう、コンパイルで得た canonical keccak(immutable ゼロ化後の keccak256。メタデータ込み)を残します。同じ型は L1/L2/L2b で同じハッシュを共有します(同一ソース・同一設定のため)。

コントラクト チェーン ソース canonical keccak256
CawActions L1/L2/L2b a26e0063 0x050b3a9f200b3b75f4882445c9a6d8d147a37fecdb8d5f693c54d974f3931caf
CawProfileL2 L1/L2/L2b a26e0063 0xeef755f4f5762278d8bf682f9be75e8641bc824de647f7dee7d76fafb85a8e71
CawActionsArchive L2/L2b a26e0063 0xbfd02e0849825a47b5d8f33b1c340285f7af66aaf463d732b0d20bad18c935f1
CawChallengeRelay L2/L2b a26e0063 0xb6f20c1dcd4689f37a0b0a4d9e69c4c4d47336d5fd1d8168927a17eee3e4cdef
CawProfile L1 a26e0063 0x875d8d6165ae4e0388767362eb9b4424339465068227431e30318a4cc20f347c
CawClientManager L1 a26e0063 0x2939ac4da5aa89b0025a3b77e3c290dfae6df02c9d48888b3e9e02e9744ad71e
CawProfileMinter L1 a26e0063 0x3217e3d61c28d861492351d2a859d4704c655de9970d0916ee634fc3a480668e
CawProfileQuoter L1 a26e0063 0xbaf0af4f45d1125d67f4b58192a48f2a0cf1ef7bd9b9bf4cf54373d19d379e44
CawProfileMarketplace L1 d5dfc730 0x84642479dbb6dbd680e69118f0e0a5bf7ad2f87a8ff53bff452f8f72f87712d5
CawProfileURI L1 a26e0063 0x3c715a2d21bbc1e74726a3b151005ff3026ee0fc8a6ac47d975660105bac499b
CawBuyAndBurn L1 a26e0063 0xc6992111593c41bc646d6edc3da5190f7241fd227b5ac5e1079d7af1f58daaf3
CawFontDataA L1 a26e0063 0xb80eb0f102c1aef01852d6fdf4fac3a5ecda97f523936030a7b40e1a9c98a347
CawFontDataB L1 a26e0063 0x49ab78a2394dd9db9ca1061cd8f5ef17cc1f5e573379a7262742f11f3e5aadf4

再現は、実コードを取得して同じ immutable 領域をゼロ化し keccak256 を取るだけです。自分のノードと同じ ethers v6(node) 一発版(getCode→マスク→keccak256・貼り付け不要)を、下のツールの「コマンドで確認」にコピー安全な形で用意しています。出力が 0x050b3a9f…931caf と一致すれば OK。

▶ ブラウザでこの検証を再現する(別窓)

インストール不要。開いて「検証する」を押すだけで一致を確認できます。自動取得がブラウザ拡張等で弾かれる場合は、ツール内の「コードを貼って検証」へ(Chrome で出ないときは Edge かシークレットウィンドウでも) さらに対象アドレス・期待ハッシュ・オフセットを自分で編集でき、「1バイト改ざん」ボタンで実際に赤くなる(=常に合格ではない)ことや、生のバイトコード/返り値、開発者ツールの Network タブで実通信を直接確認できます。

5. 注記・限界

チェーン対応:L1 = Sepolia / L2 = Base Sepolia / L2b = Arbitrum Sepolia。

エクスプローラのソース検証について。 これらの契約は Basescan 等で「Verified」表示が付いていません。しかしコードの実体は、上記の byte 一致によって、エクスプローラの表示に依存せず独立に担保されています。むしろ「Verified バッジが無い」状況でこそ、自前のコンパイルによる独立再現が、ソースとオンチェーンを結ぶ唯一の橋渡しになります。
増分デプロイについて。 live V1 は一度きりの一括デプロイではなく、必要に応じた増分デプロイの結果です。コア契約は a26e0063 時点のソースのまま(アドレス不変=再デプロイされていない)で、Marketplace のみ後の d5dfc730(H-15/H-17 等の監査修正を反映)で独立に更新・再デプロイされていました。各契約のバイトコードを、それぞれの実デプロイ・コミットに対して照合しています。

この項目(A-1)が扱うのは「実行コードの同一性」です。所有権の状態(A-2)、プロキシ構造(A-3)、所有権移転の履歴(A-4)、immutable 値の正当性(A-5)は、台帳の別項目で扱います。

説明を信じない。自分でコンパイルする。チェーンと突き合わせる。
証拠が出るまで、検証済みとは書かない。

This item checks whether the runtime code of each CAW contract deployed on the live V1 testnet matches the result of compiling the public source. We do not rely on an explorer’s “Verified” badge — in fact, these contracts are unverified on Basescan and the like. So we compile the same thing ourselves and diff it against the on-chain code. We speak with reproducible evidence, not with someone’s explanation.

In plain terms

Is the published “recipe” (the source code) the same as the “dish” actually served (the code running on-chain)? That is what this item checks. We took the recipe, cooked it ourselves with the exact same steps (compiled it), and compared the result with the real dish byte for byte.

public sourcesource

we compilesame steps

on-chain code= exact match

The result was an exact byte-for-byte match — and not only the “code body” with the reference addresses (immutables) masked, but the trailing metadata (a hash of the source) as well. So “the code that runs = the published source,” confirmed in our own kitchen without leaning on an explorer’s badge.

This page is the detailed record for item A-1 of the Verification Ledger.

1. Claim (what is verified)

That the runtime bytecode of each live V1 contract matches the result of compiling the source in the public repository GilgameshCaw/Caw. Without relying on any block-explorer source-verification feature (they are in fact unverified), we prove it reproducibly — anyone can follow the same steps and arrive at the same hash.

2. Method

The build settings follow the deploy-era hardhat.config.js and the solidity/package-lock.json committed to the repository (which pins dependency versions).

Setting Value
solc 0.8.22
optimizer enabled, runs = 1
viaIR true
evmVersion paris
dependencies OZ 4.9.6 / LayerZero oapp-v2 2.3.44, etc. (lock-pinned)

There are four steps.

1

Compile locally

Compile each contract with the settings above and obtain its deployedBytecode and immutableReferences (the byte offsets where immutables sit).

2

Compute the canonical hash

Zero out the immutable regions (32 bytes each) and take the keccak256 hash.

3

Normalize the on-chain code the same way

Take the live code, zero out the same immutable regions, and take its keccak256.

4

Diff them

If the two hashes match, the code is the public source itself. Here even the metadata-included value (full) matched.

Why zero out the immutable regions? Immutable variables are baked into the runtime code at deploy time, holding real values that do not exist in the source (e.g. the LayerZero endpoint address). So the raw bytecode will always differ. To compare the identity of the code itself, you must exclude these regions on both sides. The evmVersion was paris — building with the default shanghai (which uses the PUSH0 opcode) shifts the length; only paris reproduced the exact length and metadata, which pins the setting.

3. Verdict

Protocol code confirmed as a byte-for-byte match
Deployed runtime code is a byte-for-byte match with the compiled public source across every contract (immutables zeroed, metadata included). The core is from commit a26e0063, Marketplace alone from the later d5dfc730. The CAW token is a pre-existing external contract, out of scope.

The result was as follows.

  • match The 12 core protocol types (CawActions, CawProfileL2, CawActionsArchive, CawChallengeRelay, CawProfile, CawClientManager, Minter, Quoter, URI, BuyAndBurn, FontDataA/B) are a byte-for-byte match on every instance across L1/L2/L2b. Source: commit a26e0063.
  • match CawProfileMarketplace is a byte-for-byte match against the later commit d5dfc730 (the version redeployed after audit fixes H-15/H-17, etc.). The deployment is incremental, not a single commit — each contract corresponds to its actual deploy-time source.
  • out of scope The CAW token (MintableCaw) is a pre-existing external token, explicitly marked in deploy.js as a contract that is “not redeployed.” It is not part of the source tree, so it is outside this item’s source check (not matching is correct). The real CAW is a separate existing ERC20.

The real protocol contracts — even where the explorer shows them unverified — were confirmed as a byte-for-byte match using only our own compile.

4. Receipt (public proof)

So anyone can reproduce it, we leave the canonical keccak from compiling (keccak256 after immutable zeroing, metadata included). The same type shares the same hash across L1/L2/L2b (same source, same settings).

Contract Chain Source canonical keccak256
CawActions L1/L2/L2b a26e0063 0x050b3a9f200b3b75f4882445c9a6d8d147a37fecdb8d5f693c54d974f3931caf
CawProfileL2 L1/L2/L2b a26e0063 0xeef755f4f5762278d8bf682f9be75e8641bc824de647f7dee7d76fafb85a8e71
CawActionsArchive L2/L2b a26e0063 0xbfd02e0849825a47b5d8f33b1c340285f7af66aaf463d732b0d20bad18c935f1
CawChallengeRelay L2/L2b a26e0063 0xb6f20c1dcd4689f37a0b0a4d9e69c4c4d47336d5fd1d8168927a17eee3e4cdef
CawProfile L1 a26e0063 0x875d8d6165ae4e0388767362eb9b4424339465068227431e30318a4cc20f347c
CawClientManager L1 a26e0063 0x2939ac4da5aa89b0025a3b77e3c290dfae6df02c9d48888b3e9e02e9744ad71e
CawProfileMinter L1 a26e0063 0x3217e3d61c28d861492351d2a859d4704c655de9970d0916ee634fc3a480668e
CawProfileQuoter L1 a26e0063 0xbaf0af4f45d1125d67f4b58192a48f2a0cf1ef7bd9b9bf4cf54373d19d379e44
CawProfileMarketplace L1 d5dfc730 0x84642479dbb6dbd680e69118f0e0a5bf7ad2f87a8ff53bff452f8f72f87712d5
CawProfileURI L1 a26e0063 0x3c715a2d21bbc1e74726a3b151005ff3026ee0fc8a6ac47d975660105bac499b
CawBuyAndBurn L1 a26e0063 0xc6992111593c41bc646d6edc3da5190f7241fd227b5ac5e1079d7af1f58daaf3
CawFontDataA L1 a26e0063 0xb80eb0f102c1aef01852d6fdf4fac3a5ecda97f523936030a7b40e1a9c98a347
CawFontDataB L1 a26e0063 0x49ab78a2394dd9db9ca1061cd8f5ef17cc1f5e573379a7262742f11f3e5aadf4

Reproduction: fetch the live code, zero out the same immutable regions, and take keccak256. The same ethers v6 (node) one-liner (getCode → mask → keccak256, no paste) is provided copy-safe under “CLI” in the tool below; the printed hash should equal 0x050b3a9f…931caf.

▶ Reproduce this check in your browser (new tab)

No install needed. Just open it and click “Verify”. If auto-fetch is blocked by a browser extension, use “Paste code” inside the tool (or try Edge / an incognito window). You can also edit the target / expected-hash / offsets, hit “Tamper 1 byte” to watch it actually turn red (not always-pass), and inspect the raw bytecode and the real traffic in the DevTools Network tab.

5. Notes & limits

Chain mapping: L1 = Sepolia / L2 = Base Sepolia / L2b = Arbitrum Sepolia.

On explorer source verification. These contracts do not carry a “Verified” display on Basescan and the like. Yet the substance of the code is secured independently by the byte-for-byte match above, without depending on the explorer. If anything, it is precisely when no Verified badge exists that an independent reproduction from source becomes the only bridge between the source and the on-chain code.
On the incremental deployment. The live V1 is the result of incremental deploys, not a single monolithic one. The core contracts are still from the a26e0063 source (their addresses are unchanged — i.e. not redeployed), while only the Marketplace was independently updated and redeployed at the later d5dfc730 (reflecting audit fixes such as H-15/H-17). We reconcile each contract’s bytecode against its actual deploy commit.

What this item (A-1) covers is the identity of the runtime code. Ownership state (A-2), proxy structure (A-3), ownership-transfer history (A-4), and the legitimacy of the immutable values (A-5) are handled in other items of the ledger.

Don’t trust the explanation. Compile it yourself. Diff it against the chain.
Until the evidence is in, we don’t write “verified.”
Copyright ©  CAW JAPAN.com All Rights Reserved.
PAGE TOP
夜の薔薇園へ