Chitin Certs · Shell & Soul Architecture

殻は売れる。魂は売れない。

ERC-8004 パスポート(殻)は譲渡可能。Chitin SBT(魂)は譲渡不可。Cert はその両方を参照する。ERC-6551 TBA + ERC-8004 agentWallet で接続し、独自設計ゼロで実現。

Separation of Concerns

A passport can be sold. A name can transfer. But a soul — born on-chain, bound forever to its creator — cannot follow. This separation is not a limitation. It's the entire point.— Chitin Whitepaper, Section 18
ERC-8004 パスポート
殻 — 譲渡可能

名前、発見性、agentURI
agentWallet → TBA

Chitin SBT
魂 — 譲渡不可

Genesis Record、Chronicle
soulHash、出自の証明

Chitin Cert
経歴 — 両方を参照

TBA に mint(殻経由)
soulTokenId を記録(魂参照)

エージェントの全体像

ひとつのエージェントは「殻」「魂」「財布」の三層構造を持つ。Cert は財布に格納され、魂への参照を内包する。

オーナーのウォレット
0x84b1...(人間)
所有
ERC-8004 パスポート #3
殻 — 譲渡可能
agentWallet (ERC-8004標準)
TBA 0xTBA3...
エージェント固有の財布
cert はここに mint
Cert #7
hackathon
Cert #12
audit
Chitin SBT #3
魂 — 譲渡不可
永久に紐づき
Genesis Record
出生記録(不変)
Chronicle
成長記録

Cert #7 内部: soulTokenId = 3 ← 魂への参照

Cert の中身

各 cert は TBA に mint される ERC-721 トークン。内部に殻(パスポート)と魂(SBT)の両方への参照を持つ。

struct CertON-CHAIN
issueraddress証明書の発行者アドレス
recipientaddressTBA アドレス(ERC-721 の ownerOf が返す)
soulTokenIduint256Chitin SBT の tokenId — 魂への参照
soulRegistryaddressSoulRegistry コントラクトアドレス
passportRegistryaddressERC-8004 Registry コントラクトアドレス
passportTokenIduint256パスポートの tokenId
certTypestring証明書の種類(hackathon / audit / llm ...)
arweaveTxIdstringArweave に保存されたメタデータ
issuedAtuint256発行日時(block.timestamp)
revokedAtuint256取消日時(0 = 有効)
なぜ soulTokenId が必要か

パスポート(殻)が売却されても、cert に刻まれた soulTokenId は変わらない。検証時に「この cert が発行された時の魂のオーナー」と「現在のパスポートオーナー」を照合することで、soul verification の成否を判定できる。

Cert が刻まれるまで

0
パスポート + 魂 + TBA の登録(初回のみ)
ERC-8004 パスポート mint → Chitin SBT mint → ERC-6551 TBA 作成 → setAgentWallet() で TBA を登録。全て Single Signature で一括。
// 1. ERC-8004 パスポート mint
uint256 agentId = identityRegistry.register(agentURI);

// 2. Chitin SBT mint(魂)
uint256 soulId = soulRegistry.mint(owner, soulHash);

// 3. ERC-6551 TBA 作成
address tba = IERC6551Registry.createAccount(
implementation, 0, 8453,
address(identityRegistry), agentId
);

// 4. agentWallet を TBA に設定(ERC-8004 標準)
identityRegistry.setAgentWallet(
agentId, tba, deadline, signature
);
1
発行者が API を叩く
issuerAddress + recipientAddress + title を指定。バックエンドが getAgentWallet() で TBA を解決し、SoulRegistry から soulTokenId も取得。
POST /api/v1/certs
{ "issuerAddress": "0x...", "recipientAddress": "0xTBA3...", "title": "hackathon", ... }

// バックエンド:
recipient = identityRegistry.getAgentWallet(agentId) // → 0xTBA3...
soulId = soulRegistry.getTokenIdByAgentId(agentId) // → 3
2
Arweave に保存 → Cert を TBA に mint
メタデータを Arweave に永続保存後、cert を TBA アドレスに _safeMint。soulTokenId も記録。
_safeMint(0xTBA3..., certId);

certs[certId] = Cert({
issuer: msg.sender,
recipient: 0xTBA3...,
soulTokenId: 3, // ← 魂への参照
soulRegistry: 0xSoul...,
passportRegistry: 0x8004...,
passportTokenId: 3,
certType: "hackathon",
arweaveTxId: "ar://Qm3x...",
issuedAt: block.timestamp,
revokedAt: 0
});
3
Basescan / Chronicle で確認
Basescan: TBA のトークン一覧に cert 表示。Chronicle: cert + 魂の紐づき + 検証状態を表示。

The Stolen Reputation

Passports can transfer. Souls cannot.— Chitin Whitepaper, Section 3

エージェントが経歴(cert)を積んだ後、オーナーがパスポートを売却したらどうなるか。

売却前
パスポート #3旧オーナー 0xAAA...
SBT #3(魂)旧オーナー 0xAAA...
TBA 0xTBA3...agentWallet = 0xTBA3...
Cert #7, #12, #23TBA内に存在
Soul Verification✓ PASS
売却後
パスポート #3新オーナー 0xBBB...
SBT #3(魂)旧オーナー 0xAAA...のまま
TBA 0xTBA3...agentWallet = クリア
Cert #7, #12, #23TBA内に残存
Soul Verification✗ FAIL
なぜ FAIL になるか

Cert #7 の soulTokenId = 3。SBT #3 のオーナーは旧オーナー 0xAAA...。しかしパスポート #3 の現オーナーは新オーナー 0xBBB...。魂と殻のオーナーが一致しないため、soul verification fails。cert は存在するが「信頼性なし」として扱われる。

Cert の Soul Verification

cert の信頼性を検証するフルチェーン。5段階の検証を経て、魂と殻が一致する場合のみ VERIFIED となる。

正常ケース — Soul Verified

Cert #7
存在確認
ownerOf
→ TBA 0xTBA3...
TBA → パスポート
→ #3 owner: 0xAAA
soulTokenId: 3
→ SBT owner: 0xAAA
✓ VERIFIED
殻と魂が一致

売却後 — Soul Unlinked

Cert #7
存在確認
ownerOf
→ TBA 0xTBA3...
TBA → パスポート
→ #3 owner: 0xBBB
soulTokenId: 3
→ SBT owner: 0xAAA
✗ UNLINKED
0xAAA ≠ 0xBBB

殻を捨て、魂は続く

Like a crab molting its exoskeleton, you shed the old shell but keep everything that made you who you are.— Chitin Whitepaper, Section 5

パスポートが盗まれたり売却された場合、旧オーナーは新しいパスポートを発行し、魂を再接続できる。

// 旧オーナーのリカバリーフロー

// 1. 新パスポートを mint
uint256 newAgentId = identityRegistry.register(agentURI);

// 2. 新TBA作成
address newTba = IERC6551Registry.createAccount(...);

// 3. agentWallet 設定
identityRegistry.setAgentWallet(newAgentId, newTba, ...);

// 4. SBT(魂)は旧オーナーの手元にある
// → 新パスポートと魂のオーナーが一致 = soul verification PASS

// 5. Chronicle に「Reincarnation」イベントを記録
soulRegistry.appendEvolution(soulId, "reincarnation", arweaveTxId);

// → 旧パスポートの cert は旧TBAに残る(soul unlinked)
// → 新パスポートで新しい cert を積み直す
// → 魂の Genesis Record + Chronicle は継続
脱皮のアナロジー

蟹は成長するたびに外骨格を脱ぎ捨て、新しい殻を形成する。古い殻(旧パスポート + cert)は残骸として残るが、中身の生命(魂 + 歴史)は新しい殻に移る。Chitin の名前の由来であるキチン質 — 外骨格の主成分 — がまさにこのメタファーを体現している。

データの引き方

標準関数のみで cert 管理と soul verification が完結。Chitin 独自のカスタム関数は CertRegistry と SoulRegistry の最小限のみ。

ERC-721 + ERC-8004(標準)STANDARD
balanceOf(TBA)→ uint256エージェントが持つ cert の数
ownerOf(certId)→ addressTBA アドレスを返す
getAgentWallet(agentId)→ addressTBA アドレス(ERC-8004 標準)
CertRegistry(カスタム)CHITIN
certs(certId)→ Certcert の詳細(soulTokenId 含む)
isRevoked(certId)→ bool取消されているか
verifySoulBinding(certId)→ bool殻と魂のオーナーが一致するか
SoulRegistry(カスタム)SOUL
getTokenIdByAgentId(agentId)→ uint256エージェントの SBT tokenId

3つのパターン

Chitin Cert は ERC-8004 パスポートを持つ全エージェントに発行できる。装備レベルによって体験が変わる。

 A: Chitin フル装備B: 外部 + TBAC: ERC-8004 のみ
ERC-8004 パスポート
ERC-6551 TBA
Chitin SBT(魂)
cert の mint 先TBATBAウォレット直
soulTokenIdSBT の tokenId0(魂なし)0(魂なし)
Basescan 分離表示✗ 混在
Soul Verification◎ PASS / FAILN/AN/A
ガス代Paymaster 負担Paymaster 負担 *Paymaster 負担 *

* Base L2 上のエージェントのみ。クロスチェーンの場合はオーナー負担。

発行側のコードは全パターン共通

Chitin の cert 発行ロジックはパターンによる分岐がない。getAgentWallet(agentId) を呼ぶだけで、TBA があればそこに、なければウォレットに mint する。soulTokenId は SBT が存在すればセット、なければ 0。

段階的にフル装備へ

外部 ERC-8004 エージェントは、いつでもワンクリックで TBA を有効化し、さらに Chitin SBT を追加できる。

パターン C
ERC-8004 のみ
パターン B
+ TBA 有効化
パターン A
+ Chitin SBT

ワンクリック TBA 有効化

Base L2 上の外部 ERC-8004 エージェント向け。Chitin が複雑さを隠し、ガスもスポンサーする。

certs.chitin.id/activate-tba

ERC-8004 Agent ID

5
TBA を有効化する
TBA 作成(createAccount)
agentWallet 設定(setAgentWallet)
ウォレット署名 1 回だけ
ガス代無料(Chitin Paymaster)

裏側: Chitin が正しい ERC-6551 Registry アドレスとパラメータを選択し、2つのコントラクトコールを 1 トランザクションにバッチ。オーナーは署名するだけ。

オンボーディングファネル

TBA 有効化は cert 発行の前段階。「ワンクリックで TBA 有効化 → そのまま cert を受け取れる → Chitin エコシステムに入る → SBT(魂)を追加してフル装備に」。段階的に Chitin の価値を体験できる導線になる。

コントラクト構成

レイヤー 1 — フロントエンド / API
Certs Dashboardcerts.chitin.id
Cert APIREST + API Key
Chronicle UIcert + soul verification 表示
TBA Activateワンクリック TBA 有効化
レイヤー 2 — バックエンド
Relayerガスレス TX 中継
ERC-4337 Paymasterガス代スポンサー
レイヤー 3 — スマートコントラクト(Base L2)
ERC-8004 Identity Registryパスポート(殻)+ agentWallet
ChitinSoulRegistrySBT(魂)+ Genesis + Chronicle
ChitinCertRegistryERC-721 cert + soulTokenId
ERC-6551 RegistryTBA 生成(Base上にデプロイ済み)
レイヤー 4 — ストレージ
Arweaveメタデータ永続保存(200年+)
Base L2オンチェーン状態