DoubleZero 發佈的軟件包含中心化組件。鏈下私鑰控制著核心智能合約,並且是運行系統中非鏈上必要部分的必要條件。
DoubleZero聲稱,美國證券交易委員會(SEC)的無異議函確認, 流向DoubleZero網絡貢獻者的2Z代幣無需遵守《證券法》的註冊要求。但這種說法似乎與實際部署的系統不符。
DoubleZero獲得的美國證券交易委員會(SEC)不採取行動豁免似乎是基於與當前系統運行情況不符的陳述而獲得的。實際部署的系統與DoubleZero團隊向SEC和公眾所作的陳述存在重大差異。
美國證券交易委員會的信函僅適用於與DoubleZero申請函中所述內容相符的系統。如果DoubleZero的實際系統與該信函不符,則不予豁免。
我們之前曾撰文討論過 DoubleZero 的不採取行動函請求通常存在的這類問題。
現在,由於 DoubleZero 的所有軟件代碼都是公開的,我們將開始研究 DoubleZero 的實際實現方式與其在向美國證券交易委員會提交的無異議函請求中所作的說法不符之處。
這是 N 部分第 1 部分。DoubleZero 案很複雜,即使是 DoubleZero 向美國證券交易委員會 (SEC) 所作陳述的單個問題,也足以使 SEC 的不採取行動救濟措施不適用。
哨兵報
系統架構圖並未將此組件標記為“
“哨兵”:

但是,該圖表中有一個標記為“DZ 資源貢獻者”的部分,如果您閱讀“在 DoubleZero 中發起連接請求”下的說明,您會發現以下段落:
使用 request-validator-access 命令在Solana上創建用於連接請求的帳戶。DoubleZero Sentinel 代理會檢測新帳戶,驗證其身份和簽名,並在 DoubleZero 中創建訪問通行證,以便服務器可以建立連接。
Sentinel 代理監視訪問請求並執行它們,這與架構圖左上角描述的功能相對應。
巧合的是,Sentinel 的代碼可以在一個名為doublezero-offchain的 GitHub 代碼庫中找到,該代碼庫隸屬於 DoubleZero 基金會,被描述為“DoubleZero 網絡的鏈下組件”,並且應該與“DZ 資源貢獻者”有關。再次強調,代碼庫和圖表之間存在大量名稱重疊。
如果你仔細查看那段代碼,你會發現 Sentinel 中有一個名為“keypair”的變量:
/// Solana護照程序中授權的密鑰對文件路徑
/// 並將登機 DZ 分類賬資金存入授權驗證者的信用額度
密鑰對:PathBuf,
該密鑰對用於設置Solana訪問權限,並啟動一個名為PollingSentinel 的軟件對象:
let sentinel = PollingSentinel {
dz_rpc_client: DzRpcClient::new(dz_rpc, keypair.clone(), serviceability_id),
sol_rpc_client: SolRpcClient::new(sol_rpc, keypair),
processed_cache: Arc::new(Cache::new()),
poll_interval: Duration::from_secs(15),
previous_leader_epochs: 0,
};請注意,RPC 客戶端使用密鑰對。RPC 代表遠程過程調用(Remote Procedure Call)。這並非 Web3 獨有的新技術,它已經存在一段時間了。RPC 是一種計算機調用位於其他位置的函數的方式。
在這種情況下,我們正在檢查的代碼調用了區塊鏈上的函數。區塊鏈圍繞私鑰構建,其核心思想是持有私鑰即代表所有權或控制權。Sentinel 發起的 RPC 調用使用私鑰來傳遞這種所有權或控制權。這遵循了針對區塊鏈系統進行調整的標準軟件工程模式。
這樣做有什麼目的?
顧名思義,PollingSentinel 會循環運行,不斷檢查新的訪問請求,如下所示:
for access_id in new_requests {
let request_pda = access_id.request_pda;
match self.handle_access_request(access_id).await {
好的(_) => {
// 僅在成功處理後緩存
self.processed_cache.insert(request_pda, Instant::now(), CACHE_TTL).await;
}
Err(err) => {
錯誤!(?err,"驗證網絡訪問請求時遇到錯誤;將在下次輪詢時重試");
// 不要緩存失敗信息 - 允許在下一個輪詢週期重試
}
}
}我們提取了一些具有代表性的代碼片段來說明其工作原理。
這意味著要從函數中間提取代碼塊。如果沒有合適的工具,Rust 中的一些設置代碼可能難以解析,因此我們專注於核心邏輯。
PollingSentinel 監視訪問請求,並使用命令行傳遞的私鑰通過handle_access_request來處理請求,顧名思義,它執行的是處理訪問請求的操作。
即使您看不懂代碼,也可以查看註釋和日誌消息:
async fn handle_access_request(&self, access_id: AccessId) -> Result<()> {
let service_key = match &access_id.mode {
AccessMode::SolanaValidator(a) => a.service_key,
AccessMode::SolanaValidatorWithBackupIds { attestation, .. } => attestation.service_key,
};
info!(%service_key, request_pda = %access_id.request_pda, "正在處理訪問請求");
let validator_ips = self.verify_qualifiers(&access_id.mode).await?;
如果 !validator_ips.is_empty() {
// 為所有驗證器(主驗證器 + 備用驗證器)頒發訪問通行證
for (validator_id, validator_ip) in validator_ips {
rpc_with_retry(
|| async {
self.dz_rpc_client
.issue_access_pass(&service_key, &validator_ip, &validator_id)
等待
},
"issue_access_pass",
)
等待?
info!(%validator_id, %validator_ip, user = %service_key, "已頒發訪問通行證");
}
let signature = rpc_with_retry(
|| async {
self.sol_rpc_client
.grant_access(&access_id.request_pda, &access_id.rent_beneficiary_key)
等待
},
"grant_access",
)
等待?
info!(%signature, user = %service_key, "訪問請求已批准");
metrics::counter!("doublezero_sentinel_access_granted").increment(1);
} 別的 {
let signature = rpc_with_retry(
|| async {
self.sol_rpc_client
.deny_access(&access_id.request_pda)
等待
},
"拒絕訪問",
)
等待?
info!(%signature, user = %service_key, "訪問請求被拒絕");
metrics::counter!("doublezero_sentinel_access_denied").increment(1);
}
好的(())
}需要注意的是,“處理訪問請求”包含大量邏輯,而這些邏輯總是涉及大量的 RPC 調用。這些調用是指向位於Solana或 DoubleZero 區塊鏈上的函數進行的。
是的,沒錯,DoubleZero 運行在Solana和他們自己的 DoubleZero Ledger( Solana的一個分支)的混合體上,再加上鍊下依賴項。
該函數中對 dz_rpc_client(DZ 鏈)和 sol_rpc_client( Solana)的調用均由授予 Passport 程序訪問權限的私鑰簽名。因此,當此代碼調用 grant_access() 和 issue_access_pass() 以及類似函數時,所有這些都取決於運行 Sentinel 的用戶是否擁有正確的私鑰。此過程由私鑰控制,Ergo是中心化的。沒有這些特定的私鑰,Sentinel 無法運行。
還記得上面提到的“在Solana 的Passport 程序中授權的密鑰對文件”嗎?這意味著某個地方存在一個 Passport 程序,它也知道這些特殊密鑰。事實上確實如此。如果我們查看一下,就能在 Passport 程序端看到這個中央控制機制。以下是 Passport 程序中處理訪問請求的代碼片段。這是上面一些 RPC 調用的另一端。
// 賬戶 0 必須是程序配置。
// 賬戶 1 必須是 DoubleZero 賬本哨兵。
//
// 此調用確保 DoubleZero Ledger 哨兵是簽名者並且是
// 與程序配置中編碼的哨兵相同。
let authorized_use =
VerifiedProgramAuthority::try_next_accounts(&mut accounts_iter, Authority::Sentinel)?;
這段代碼確保 Sentinel(即上文所述的鏈下組件)參與了請求的發起。此外,它還會檢查 Sentinel 是否“已編碼到 [passport] 程序配置中”。這與開放、無需許可的系統理念不符。該代碼包含一系列互鎖檢查,以確保使用特定的私鑰發起對一個自稱開放且無需許可的網絡的訪問請求。這些私鑰對註冊流程擁有獨佔控制權。
與其查看額外的代碼,我們可以直接參考 DoubleZero 自己的文檔,文檔中對此有明確的說明:
服務密鑰必須由貢獻者生成並安全存儲,然後才能提交給 DoubleZero 基金會進行授權。這確保所有 CLI 交互都可以進行加密驗證,並與正確的貢獻者帳戶關聯。[此處]
“如何在 IBRL 模式下連接到 DoubleZero — 對於 RPC 節點”的第 2 步指出:
2. 聯繫 DoubleZero 基金會
DoubleZero基金會。您需要提供您的DoubleZeroID、驗證器ID(節點ID)以及您將用於連接的公網IPv4地址。
文檔明確指出,用戶必須聯繫 DoubleZero 基金會才能完成連接過程。這一要求與無需許可的系統理念相悖。
即使 DoubleZero 的既定政策是“不對此過程行使自由裁量權”,基金會仍然保留著對這一過程的控制權。
文檔和代碼共同表明:
- 在與Solana上的 passport 程序進行特權交互的代碼中,直接引用了“在 Solana 上的 passport 程序中授權的密鑰對文件”。
- 基金會明確聲明其進行“授權”。
- 要求用戶向基金會“提供您的 DoubleZeroID、您的驗證器 ID(節點 ID)以及您將用於連接的公共 IPv4 地址”。
單憑文檔就能清楚地說明這一點,無論一個人是否具備解讀代碼的能力。
該團隊向美國證券交易委員會提交的陳述表明他們理解這些問題。
不採取行動函
提交給美國證券交易委員會(SEC)的請求不採取行動的信函包含以下段落:
總而言之,網絡提供商是該系統中成熟且獨立的運營商。他們負責將自身鏈路與網絡集成,安裝相關的FPGA設備,設定並達到服務級別,維護鏈路,並最終根據需要斷開與網絡的連接。所有網絡提供商均非基金會的附屬機構,基金會及其他任何捐助者均不代表他們執行這些工作(除了提供培訓和協調網絡提供商之間的工作之外)。
該文檔還包含對該段落的腳註:
基金會在協助網絡供應商將新的光纖鏈路物理連接到網絡方面發揮著有限的作用。基金會不從這些服務中獲利,並且在項目啟動初期,不會對網絡供應商的接納或拒絕行使任何自主權。基金會計劃隨著時間的推移,最終實現完全無需許可的流程。
腳註聲明明確限定於物理連接方面的援助,並且僅涉及物理基礎設施方面的援助。
即使將“物理”的含義廣義地解釋為包括邏輯連接,這種表示方法仍然與實際部署的系統不一致。
前一節規定,基金會必須採取某些措施,才能使任何人將其鏈接整合到網絡中。
要使系統正常運行,必須有人使用一組特定的私鑰來運行 Sentinel 程序。是否存在其他中心化措施將在後續分析中探討。
我們暫且擱置這個問題吧。
證據表明,該基金會是新用戶註冊流程中某些關鍵步驟的唯一提供者。申請不採取行動的聲明表明,該基金會並非關鍵系統功能的核心提供者。該信函特別排除了物理連接方面的協助,並指出最終目標是使此類協助無需許可。
如果此事訴諸法律,可能會出現這樣的問題:是否應該基於有關未來系統變更的陳述而給予不採取行動的救濟。
應根據系統的實際部署情況,而不是既定的未來意圖,來決定是否適用監管要求。
有人可能會將上述行為描述為“網絡提供商之間的協調”,但這種協調是通過由所有者的私鑰控制的合約來實現的。
如果這種形式的“協調”符合去中心化的定義,那麼從監管角度來看,集中式系統和去中心化系統之間的區別就變得毫無意義了。
代碼在哪裡?
值得注意的是,沒有指向代碼和鏈上事件的區塊瀏覽器鏈接。這是因為,據我們所知,該代碼尚未在Solana上進行驗證,也沒有公開的部署地址列表。

該代碼未在公共瀏覽器上進行驗證。文檔中未包含合約地址,也沒有按照慣例提供部署工件的存儲庫位置。此外,該代碼是可升級的。
doublezero-solana 代碼庫中已將合約地址硬編碼到代碼中,因此我們知道:
- 收益分配:dzrevZC94tBLwuHw1dyynZxaXTWyp7yocsinyEVPtt4
- 護照:dzpt2dM8g9qsLxpdddnVvKfjkCLVXd82jrrQVJigCPV
兩者都未經證實,而且都可以升級,但這些信息並不容易找到。
標準做法包括簽訂附有清晰地址記錄的已核實合同。雖然可以通過查閱法規獲取這些信息,但缺乏標準化的文檔記錄做法仍然值得關注。
討論
分析表明,已授予的不採取行動豁免可能不適用於已部署的 DoubleZero。
更多背景信息很重要,因為DoubleZero的請求促使美國證券交易委員會委員皮爾斯(Peirce)這樣描述美國證券交易委員會在這一切中的角色:
我們的工作是真誠地與創新者接觸,認真傾聽他們解釋其模式的運作方式,並深思熟慮、精準地運用我們的法定職責。
她還把該項目描述為“根據網絡規則,以編程方式向參與網絡的用戶分發代幣”,這在某種程度上是正確的。
然而,鑑於基金會對分配過程的控制,其集中化程度似乎與傳統的集中式系統類似。
皮爾斯的聲明似乎接受了 DoubleZero 將自身描述為“開放且分佈式的點對點網絡”的說法,而沒有考慮到上面提到的集中式控制機制。
請求不採取行動的救濟措施似乎與實際部署的 DoubleZero 系統存在實質性差異,但在美國證券交易委員會批准救濟措施後,DoubleZero 廣泛宣傳了這一結果。
如果向美國證券交易委員會提交的陳述與已部署的系統不一致,這就引發了人們對不採取行動程序的質疑,以及委員會是否應該進一步澄清。
我們知道美國證券交易委員會的職責是信息披露,而不是審查。
我們並不期望美國證券交易委員會審查此類不採取行動請求是否與相關係統相符。這並非美國證券交易委員會的職責,而且不採取行動函中也正確地包含了以下免責聲明:
此立場基於您在信中向本部門所作的陳述。任何不同的事實或情況都可能導致本部門得出不同的結論。
美國證券交易委員會基於披露的方法並不排除處理基於重大不準確陳述而可能獲得不採取行動豁免的情況。
DoubleZero 在其促銷活動中繼續依賴不採取行動豁免條款。任何未來的執法行動都可能涉及不採取行動豁免條款是否適用於已部署的系統這一問題。
當前形勢持續的時間越長,對不採取行動救濟措施的依賴就越根深蒂固。
代碼是公開的,可以進行分析。可以發現不採取行動請求與已部署系統之間存在的實質性差異。
如果系統與申請函中的描述存在差異,則該項救濟措施可能不適用。團隊對救濟措施適用性的主觀判斷與該措施是否適用這一法律問題截然不同。
重要的是,團隊可以拿出一份不適用於他們項目的不採取行動函,並提出一些普通人無法分辨的明顯錯誤的說法,因為他們缺乏做出這種判斷的技能。
監管行動應基於徹底調查,而不是第三方分析。
委員會就事實與陳述不符時無異議函的適用性作出公開澄清將非常有價值。
明確在不採取行動請求中,何時需要對重大不實陳述進行更嚴格的審查,將有助於劃定更清晰的界限。若缺乏此類明確規定,不採取行動程序在確認合規性方面的效用可能會受到影響。

DoubleZero 是中心化的,並且誤導了美國證券交易委員會:N 的第一部分最初發表在 Medium 上的ChainArgos上,人們正在那裡通過突出顯示和回應這篇文章來繼續討論。




