ERC-XXXX: Blob 認證訊息 (BAM)
類別: ERCs | 類型: 標準軌道 (Standards Track) | 狀態: 草案 (Draft)
作者: Vitalik Buterin (@vbuterin ), Skeletor Spaceman (@skeletor-spaceman )
摘要
本 ERC 定義了基於 EIP-4844 Blob 的去中心化認證訊息介面。核心註冊介面擴展了 ERC-BSS(Blob 空間分段),增加了解碼器指標(decoder pointer)和簽名註冊表指標(signature registry pointer):解碼器是一個鏈上的非受信合約,用於從負載(payload)中提取訊息;簽名註冊表是一個受信合約,用於驗證簽名。將解碼與驗證分離,可確保有缺陷或惡意的解碼器無法導致身份冒用——它只能產生錯誤的訊息,而這些訊息在受信註冊表的簽名驗證中會失敗。支援介面標準化了多方案金鑰管理(ECDSA、BLS、STARK 等)和鏈上訊息證明。
問題陳述
以太坊可以作為通用的認證訊息媒介。EIP-4844 Blob 每個提供 128 KiB 的數據可用性,其成本僅為 calldata 的一小部分。透過壓縮,單個 Blob 可容納數千條訊息——以 9 倍壓縮率計算,在目前的 Blob 吞吐量下,每天可實現 4.98 億條訊息。
目前尚無鏈上介面的標準。每個實作都定義了自己的:
批次註冊事件(索引器如何發現新的訊息批次)
訊息編碼(客戶端如何解碼批次負載)
金鑰管理合約(使用者如何註冊簽名金鑰)
證明機制(單個訊息如何在鏈上被證明)
現有標準並未解決此問題:
ERC-3722 (Poster):基於事件的極簡社交合約,不具備 Blob 感知能力,已停滯
ERC-7847 :基於 NFT 的社交媒體,未使用 Blob
Farcaster/Lens:特定於 L2,未標準化為 ERC
如果沒有共享介面,索引器無法追蹤跨實作的訊息提交,客戶端無法解碼來自其他協議的訊息,錢包無法跨應用程式管理簽名金鑰,智慧合約也無法對來自不同協議的認證訊息做出反應。
設計原則
任何人皆可讀取。 擁有以太坊節點並能存取 Blob 數據的客戶端,應能解碼來自任何合規實作的訊息。批次註冊事件包含一個解碼器地址,指向一個從負載中提取訊息的鏈上合約。私有編碼會產生中心化壓力;可發現的鏈上解碼器則能防止這種情況。
最小化捕獲。 沒有特權解碼器、註冊表或守門人。解碼器合約的部署是無需許可的。解碼器地址是每次提交的參數,而非全域常數。不同的實作使用不同的解碼器。沒有任何機制能阻止分叉解碼器合約並部署修改版本。
設計摘要
解碼器合約 (IERC_BAM_Decoder)
解碼器合約從負載中提取訊息和簽名數據。給定來自 Blob 分段或 calldata 批次的原始位元組,它會返回解碼後的訊息和原始簽名位元組。解碼器是非受信的:撒謊的解碼器會產生錯誤的訊息,其雜湊值在受信註冊表的驗證中會失敗。解碼器不負責驗證簽名。
interface IERC_BAM_Decoder { struct Message { address sender; uint64 nonce; bytes contents; } function decode(bytes calldata payload) external view returns (Message[] memory messages, bytes memory signatureData); }
decode 返回所有訊息(發送者 + nonce + 內容)和不透明的簽名位元組(例如:聚合的 BLS 簽名或串聯的 ECDSA 簽名)。客戶端隨後計算標準化的訊息雜湊,並針對受信註冊表進行驗證。這種分離意味著有缺陷的解碼器可能會導致偽陰性(拒絕有效訊息),但絕不會導致偽陽性(接受偽造訊息)。
v1 解碼器應使用簡單的編碼(ABI 編碼陣列、RLP 或 SSZ)。複雜的壓縮(基於字典、增量編碼)可以在後續的解碼器版本中引入。該介面與編碼無關;具有鏈上解壓功能的 v2 解碼器實作相同的函數。
核心註冊 (IERC_BAM_Core 擴展 IERC_BSS)
核心介面擴展了 ERC-BSS(Blob 空間分段)。registerBlobBatch 在一次調用中聲明 Blob 分段,並將批次與其解碼器和簽名註冊表一起註冊:
interface IERC_BAM_Core is IERC_BSS { event BlobBatchRegistered( bytes32 indexed versionedHash, address indexed submitter, address indexed decoder, address signatureRegistry ); event CalldataBatchRegistered( bytes32 indexed contentHash, address indexed submitter, address indexed decoder, address signatureRegistry ); function registerBlobBatch( uint256 blobIndex, uint16 startFE, uint16 endFE, bytes32 contentTag, address decoder, address signatureRegistry ) external returns (bytes32 versionedHash); function registerCalldataBatch( bytes calldata batchData, address decoder, address signatureRegistry ) external returns (bytes32 contentHash); }
registerBlobBatch 內部調用 declareBlobSegment(繼承自 IERC_BSS),為 BSS 索引器觸發 BlobSegmentDeclared 事件,然後為 BAM 索引器觸發帶有解碼器和簽名註冊表地址的 BlobBatchRegistered 事件。兩個事件,一次調用,分段與批次之間具有明確的關聯。
registerCalldataBatch 允許在沒有聚合器的情況下進行自我發布。使用相同的解碼器和簽名註冊表指標;無需分段聲明(calldata 沒有 Blob)。
簽名註冊表 (IERC_BAM_SignatureRegistry)
適用於 ECDSA、BLS、STARK 及未來方案的通用介面:
interface IERC_BAM_SignatureRegistry { event KeyRegistered(address indexed owner, bytes pubKey, uint256 index); function schemeId() external pure returns (uint8 id); function schemeName() external pure returns (string memory name); function register(bytes calldata pubKey, bytes calldata popProof) external returns (uint256 index); function getKey(address owner) external view returns (bytes memory pubKey); function isRegistered(address owner) external view returns (bool registered); function verify(bytes calldata pubKey, bytes32 messageHash, bytes calldata signature) external view returns (bool valid); function supportsAggregation() external pure returns (bool supported); function verifyAggregated( bytes[] calldata pubKeys, bytes32[] calldata messageHashes, bytes calldata aggregatedSignature ) external view returns (bool valid); }
此為簡略版;完整介面還包括 pubKeySize()、signatureSize() 和 verifyWithRegisteredKey()。每種簽名方案部署自己的註冊表。方案 ID:0x01=ECDSA, 0x02=BLS12-381 等。所有權證明(Proof of possession)可防止惡意金鑰攻擊。聚合支援是按方案選擇性開啟的。
訊息揭露 (IERC_BAM_Exposer)
用於在鏈上證明單個訊息的標準化事件:
interface IERC_BAM_Exposer { event MessageExposed( bytes32 indexed contentHash, bytes32 indexed messageId, address indexed author, address exposer ); function isExposed(bytes32 messageId) external view returns (bool exposed); }
expose() 函數本身不 進行標準化;它因證明類型(KZG、ZK、Merkle)和簽名方案而異。該事件是互操作性的介面:任何揭露器(exposer)無論機制如何,都會觸發 MessageExposed。
關鍵設計決策
BAM 擴展 BSS。 原始設計定義了沒有分段座標的 registerBlobBatch(blobIndex)。當與其他協議共享 Blob 時,調用者需要單獨的 BSS 調用。對兩個合約進行兩次調用會產生關聯問題:一個具有 N 個分段的共享 Blob 會產生 N 個 BlobSegmentDeclared 事件和一個 BlobBatchRegistered 事件,且都引用同一個 versioned hash。繼承 IERC_BSS 消除了歧義。一次調用,兩個事件,明確關聯。
信任分離:解碼器 vs 註冊表。 原始設計將解碼和驗證捆綁在單個「schema」合約中。如果客戶端信任一個惡意的 schema,任何人都可以冒充任何地址。解決方案:解碼器(非受信,多個)提取訊息;註冊表(受信,約 4 個)驗證簽名。撒謊的解碼器產生的錯誤雜湊將無法通過驗證——會產生偽陰性,但絕不會產生偽陽性。
鏈上解碼器發現。 傳統方法將解碼邏輯嵌入在鏈外客戶端中。如果協議更改其編碼,每個客戶端都需要更新。鏈上解碼器反轉了這一點:解碼器在鏈上、可審計,且可被任何合約或客戶端調用。解碼器地址在註冊事件中觸發,僅憑事件日誌即可發現。
無單例要求。 BAM 合約不需要共享單例部署。每個部署從其自己的地址觸發 BlobSegmentDeclared。以太坊事件主題是全域索引的;索引器根據主題雜湊而非合約地址進行過濾。
零存儲核心。 僅限事件,無 SSTORE。註冊成本約為 5,900 gas(分段驗證 + 兩次 LOG4 事件觸發),而使用存儲則需 25,000+ gas。在最便宜的 Blob 交易中,開銷低於 29%。
通用簽名註冊表。 所有方案共用一個介面。BLS12-381 是目前的主要案例(根據批次大小,簽名聚合可節省 79-94% 的認證開銷),但該介面無需修改即可支援後量子方案。
非標準化 expose 函數。 BLS+KZG 需要與 ECDSA+Merkle 或 STARK+ZK 不同的參數。事件提供了互操作性介面。
訊息 ID 慣例。 keccak256(author || nonce || contentHash):確定性的,不需要鏈上狀態,具備抗碰撞性。nonce 可防止同批次內的碰撞。
簽名域 (Signing domain)。 keccak256("ERC-BAM.v1" || chainId):防止跨鏈重放。曾考慮過 EIP-712 但被拒絕;認證訊息缺乏標準化的結構類型,且當訊息格式有意不指定時,EIP-712 的類型化數據模型會增加開銷卻無實質收益。
使用案例
基於 Blob 的去中心化 Twitter
聚合器收集使用者簽名的訊息,透過 v1 解碼器格式進行編碼,壓縮進 Blob 並提交至 L1。registerBlobBatch 觸發帶有解碼器和簽名註冊表地址的分段 + 批次事件。任何客戶端從事件中讀取這些資訊,獲取 Blob 數據,調用 decoder.decode(payload) 提取訊息和簽名數據,計算標準化訊息雜湊,並調用 registry.verifyAggregated(pubKeys, signedHashes, signatureData) 進行驗證。使用者透過簽名註冊表註冊 BLS 金鑰,以實現高效聚合(500+ 條訊息僅需一個簽名)。
鏈上治理觸發器
治理合約在執行提案前需要驗證特定訊息是否已發布。揭露器透過 KZG 點評估證明該訊息,並觸發 MessageExposed。治理合約調用 isExposed(messageId) 進行驗證。
跨實作互操作性
兩個訊息協議都實作了 IERC_BAM_Core。統一索引器追蹤兩者的 BlobBatchRegistered 事件,讀取各自的解碼器地址,並使用鏈上解碼器解碼來自兩個協議的訊息。兩個協議可以共享同一個受信註冊表。使用者只需註冊一次金鑰即可跨協議使用。
與 L2 Rollup 共享 Blob
Optimism 批次處理器將 field elements 0-1999 填入 Rollup 數據。訊息聚合器將 2000-4095 填入訊息。Rollup 在獨立的 BSS 合約上調用 bss.declareBlobSegment(0, 0, 2000, ...)。訊息聚合器在 BAM 合約上調用 core.registerBlobBatch(0, 2000, 4096, ...)。兩者都觸發 BlobSegmentDeclared(來自不同合約)。BAM 合約額外觸發帶有解碼器和簽名註冊表的 BlobBatchRegistered。索引器透過 versioned hash 和事件主題進行關聯。
自我發布備援
如果聚合器審查使用者,使用者可以透過 registerCalldataBatch 自行發布。雖然 gas 成本較高,但具備抗審查性。使用相同的解碼器和簽名註冊表指標;索引器的解碼方式完全相同。
本 ERC 不涵蓋的內容
訊息位元組佈局、批次格式、壓縮 :取決於具體解碼器。v1 解碼器使用簡單編碼;複雜壓縮是後續考慮的事項。
聚合器協議 :聚合器如何收集、排序和提交訊息屬於鏈外範疇。
費用拆分 :Blob gas 支付是應用層的事,而非協議層。
社交功能 :關注、按讚、個人資料、執行緒。屬於應用層;不包含在協議範圍內。
存檔 :超過約 18 天修剪窗口後的 Blob 數據保存是基礎設施問題。
expose() 函數 :因證明類型和方案而異。僅標準化事件。
與現有工作的關係
ERC-BSS (Blob 空間分段)。 ERC-BAM 透過 Solidity 介面繼承擴展了 ERC-BSS。BSS 聲明 Blob 的位置 (field element 範圍)。BAM 增加了內容 (認證訊息批次)和讀取方式 (解碼器合約)。BAM 合約即是 BSS 合約。獨立的 BSS 仍可用於非訊息類的使用案例。
ERC-3722 (Poster)。 哲學上一致:以太坊上的極簡社交媒體。Poster 是基於事件的,不具備 Blob 感知、金鑰管理或訊息證明功能。ERC-BAM 將此概念擴展到 Blob,並增加了簽名支援和解碼器發現。
ERC-7588 (Blob 交易元數據)。 正交關係。ERC-7588 描述 Blob 元數據。ERC-BAM 使用 Blob 存儲認證訊息數據。兩者可以共存。
ERC-7847 (社交媒體 NFT)。 不同的範式。ERC-7847 基於 NFT;ERC-BAM 基於事件且無代幣。
Farcaster / Lens。 特定於 L2 的協議,未標準化為 ERC。ERC-BAM 針對 L1 Blob 數據,儘管 calldata 和金鑰管理介面可在任何 EVM 鏈上運行。
參考實作
參考實作已部署在 Sepolia 測試網。現有合約早於解碼器/簽名註冊表分離和 BSS 擴展功能;它們在簽名註冊和揭露方面功能等效:
簽名註冊表 :BLSRegistry.sol(具備金鑰輪換、撤銷和聚合驗證功能的 BLS12-381)
揭露器 :BLSExposer.sol(具備鏈上驗證功能的 KZG + BLS 訊息揭露)
| 合約 | Sepolia 地址 |
| :--- | :--- |
| SocialBlobsCore | 0xAdd498490f0Ffc1ba15af01D6Bf6374518fE0969 |
| BLSRegistry | 0x2146758C8f24e9A0aFf98dF3Da54eef9f53BCFbf |
| BLSExposer | 0x0136454b435fE6cCa5F7b8A6a8cFB5B549afB717 |
ERC 介面(IERC_BAM_Core.sol, IERC_BAM_Decoder.sol, IERC_BAM_SignatureRegistry.sol, IERC_BAM_Exposer.sol)包含在 ERC PR 的 assets/ 目錄下。
徵求意見
尋求社群對以下方面的回饋:
信任分離。 我們將舊的「schema」拆分為非受信解碼器(提取訊息)和受信註冊表(驗證簽名)。撒謊的解碼器只能導致偽陰性(有效訊息被拒絕),絕不會導致偽陽性(身份冒用)。這種信任模型是否合理?是否有我們遺漏的邊際情況?
解碼器介面。 單個 decode(payload) → (messages, signatureData) 是否為正確的介面?解碼器是否也應返回元數據(例如:壓縮演算法、版本)?
BAM 擴展 BSS。 繼承模型(BAM 合約即 BSS 合約)對您的使用案例是否有意義?雙事件模式(BlobSegmentDeclared + BlobBatchRegistered)是否有任何摩擦?
標準化訊息雜湊。 我們標準化 messageHash = keccak256(sender || nonce || contents) 以便客戶端可以獨立於解碼器進行驗證。這是正確的公式嗎?是否應包含額外欄位?
v1 編碼。 對於 v1 解碼器,哪種編碼是正確的預設值:ABI 編碼陣列、RLP 還是 SSZ?哪些權衡最重要(gas 成本、工具支援、擴展性)?
訊息 ID 慣例。 keccak256(author || nonce || contentHash) 是正確的公式嗎?nonce 應該是強制性的,還是對於不需要批次內排序的協議是可選的?
揭露標準化。 僅標準化事件(而非函數)是否為正確的權衡?帶有不透明證明數據的基礎 expose(bytes calldata proof) 是否有用?
聚合模型。 簽名註冊表使聚合按方案選擇性開啟。聚合是否應該是一個單獨的介面,而不是基礎註冊表的一部分?
連結
完整 ERC 草案: 待定 (ERC PR 連結)
ERC-BSS (伴隨協議): 待定 (ERC PR 連結)
EIP-4844: 分片 Blob 交易
ERC-3722: Poster
ERC-7588: Blob 交易元數據
1 則貼文 - 1 位參與者
閱讀完整主題