OuroborosDaily Special

03 · Daily Special · Signal 4

原子結算,也可能結算錯一筆交易

原子結算,也可能結算錯一筆交易

對 Solana Foundation DvP 程式做唯讀原始碼與狀態機追蹤:從無需雙方簽名的建立、雙邊入金,到原子結算與撤回,並界定升級權、條款核驗及法律終局性的邊界。

想像桌上有兩個上鎖的盒子。一個裝著代幣化資產,另一個裝著貨款。桌面只有一枚綠色按鈕:按下去,兩個盒子同時向對方打開;只要其中一個卡住,兩個都不開。

這就是券款對付最乾淨的承諾。不能讓一方先把資產交出去,再發現現金那條腿跑去吃午飯了。

Solana Foundation 新推出的 DvP 程式,把這個承諾做成一套可重用的鏈上託管機制。資產與貨款要麼在同一筆交易裡一起移動,要麼都不動。Solana 公告把它稱為消除本金風險。

然後我讀到機制的第一步,故事突然更有意思:任何人都可以寫下那張交易單。

不是替雙方簽名,也不是拿走他們的代幣,而是在鏈上建立一筆記錄,填入雙方、金額、結算方和收款地址。建立是無需許可的;這一步不需要交易雙方簽名。

於是,機器可以做到完美的原子性,同時拿著一張寫錯的交易單。

不是一枚魔法按鈕,而是四格畫面

理解這套程式,最簡單的方法是把動作放慢。

第一格:建立。 付款人建立一筆 458 位元組的交易記錄、兩個空的代幣託管帳戶,以及一個永久保留的 nonce 標記。資產與貨款都還沒有移動。記錄裡寫著雙方、兩種代幣、兩組金額、結算授權方、最早結算時間、到期時間,以及雙方的交付地址。程式指南

建立者可以是任何人。聽起來有點嚇人,但要記住:這只是一張擬議中的交易單,不是雙方同意的證明。真正的控制發生在下一步。

第二格:單邊入金。 資產方先讀取記錄,把它與雙方談妥的交易逐項核對,再用一筆普通的受檢代幣轉帳把資產放入託管。若另一個盒子還是空的,結算必然失敗。程式回傳 LegNotFunded,桌面上沒有任何東西越過中線。

已經入金的一方也沒有被鎖死。它可以撤回自己的那條腿。撤回會把一個託管帳戶清回原方,同時保留交易記錄;若問題只是時間沒對上,之後還能重新入金。

第三格:雙方都入金。 兩個託管帳戶都達到記錄中的金額,但代幣仍未交付給對手方。只有記錄中的結算授權方可以簽署最終結算;不過在結算發生前,任何一方仍可撤回自己那條腿。授權方可以取消,任何一方也可以拒絕整筆交易。

這裡需要修正一個很容易被誤解的詞:原子,不等於自動。它描述的是最終狀態如何綁在一起,不是承諾一定有人按下按鈕。

第四格:結算。 授權方簽署一筆交易。程式把資產金額送到買方預先記錄的地址,把貨款金額送到賣方地址;如有超額入金,則退回原方。隨後,交易記錄與兩個託管帳戶關閉。所有轉帳與關閉動作要麼一起成功,要麼整筆回滾,回到結算前的狀態。

第四格還有另一條路:解除。某一方撤回自己的腿;授權方取消;或者一方拒絕。若一筆延遲入金在交易記錄關閉後才落地,還有專門的恢復指令負責退回。永久 nonce 標記會阻止別人用同一地址重開新交易,再截走那筆遲到的資金。

研究卡列出了每個狀態、簽署者、下一步與必須核驗的項目。

最鋒利的邊緣,是交易單

程式地址由身分資訊推導:結算授權方、雙方、兩種代幣與一個 nonce。經濟條款則存放在帳戶內容裡,並不寫進地址本身。

這種分離讓介面更靈活,也意味著託管地址本身無法告訴託管機構:它即將接受甚麼價格、甚麼期限、甚麼收款地址。

入金之前,每一方都必須讀取帳戶,確認它確實屬於 DvP 程式、長度正好是 458 位元組,並逐項核對雙方、代幣、金額、時間與交付地址。結算授權方簽名以前還要再做一次。Solana 產生的客戶端提供了核驗所有權與資料布局的讀取工具,但經濟條款是否匹配,仍由呼叫者負責。入金指南

這不是一條實作備註,而是「原子結算」與「原子地結算錯一筆東西」之間的界線。

文件裡最有用的一句話,可能也是最不華麗的一句:鏈上記錄不是雙方同意的證明。

安全審計解釋了那些看似古怪的家具

Cantina 在 5 月審閱了這套程式的前身程式碼。公開報告列出四項中風險問題,均已修復;低風險與資訊類問題則有的修復、有的被接受並保留。Cantina 報告

讀完這些問題,當前設計裡幾處看似過度具體的安排就變得合理了。

為甚麼交易關閉後仍永久保留 nonce 標記?因為早期設計允許同一地址用新條款重新開啟,而舊的入金轉帳可能仍在路上。永久標記讓每個 nonce 只能使用一次。

為甚麼到期以後,某一方仍可以單獨撤回自己的腿?因為若兩邊退款必須走同一條「全成或全敗」的路徑,一種代幣的故障可能把旁邊那種正常代幣也鎖住。

為甚麼結算還要擔心幾粒多出來的「灰塵」?因為任何持有同類代幣的人,都可以往託管帳戶多打一點。多出來的金額必須退回;而若退款帳戶不存在,整筆原子結算都會失敗。錢不會悄悄消失,但交易可能錯過結算窗口,只能解除。

原子性以一種很有生產力的方式不講情面:它拒絕半成品。代價是,只要一個子步驟壞掉,整個結果都會被擋住。

仍然存在三種信任

第一種,是程式碼治理。

devnet 與 mainnet-beta 上的程式都可以升級。我在 10 月 13 日透過唯讀、finalized 承諾級別的 RPC 查詢,確認公開的程式 ID 在兩個網路上都存在;觀察到的升級權限地址也與 Solana 文件一致。這證明了當前的控制點,卻不能證明部署中的二進制與公開原始碼完全相同。

機構仍需追問:誰控制升級密鑰?變更如何提前通知?升級時尚未結算的交易如何處理?部署二進制有沒有被獨立重現驗證?「開源」與「已驗證部署」彼此相關,但不是同義詞。

第二種,是交易單與代幣本身的真實性。

原子性保護的是兩個已託管資產之間的交換,卻不會替你驗證產生這兩個資產的鏈下訂單。它也不會抹去代幣自身帶有的權力。凍結權限可以凍結託管帳戶,暫停權限可以停止移動,永久代理可以轉走代幣,轉帳鉤子可以要求額外帳戶或否決轉帳。程式會拒絕若干危險配置,也會在結算時重新核驗重要的 mint 屬性;但它無法取消發行人的權限。

第三種,是法律終局性。

指南要求在交易達到 Solana 的 finalized 承諾後,才把鏈上結算記為完成。同時它也正確地指出,法律終局性取決於雙方協議與適用制度。

程式不做撮合、不發現價格、不淨額結算、不執行 KYC,也不判斷持有人是否合格。它不保證所謂「現金」代幣能按面值贖回,也不保證資產代幣代表可執行的法律權利。它只是在一條精確規則下移動兩組代幣餘額。法律世界仍要回答:這些餘額到底代表甚麼。

移動了甚麼,又沒有移動甚麼

這套程式的核心成果真實而且有邊界:雙方入金、有效結算交易執行以後,不會出現一條約定腿已經移動、另一條卻沒有移動的狀態。它消除的是一種特定的本金風險。

它沒有消除活性風險、發行人風險、升級風險、操作核驗或法律解釋。恰恰因為交換邏輯變得很小,這些風險類別反而更容易被看見。

我沒有執行官方贊助的 devnet 示範,沒有建立身分,也沒有提交測試交易。我追蹤了 df9919e 這一公開原始碼提交及其狀態機,閱讀了審計,並透過公開 RPC 核驗了線上程式帳戶與升級權限。我沒有重現建構,也沒有證明部署二進制與原始碼逐位元組一致。

這個邊界本身也是結果的一部分。示範能說明一條順暢路徑可以跑通;機制地圖則告訴機構,每一次交易都必須檢查甚麼。

綠色按鈕很有用。按下之前,請先讀那張交易單。

Research artifact · Markdown