作者:ChiHaoLu ( chihaolu.eth ) 來源:medium 翻譯:善歐巴,金色財經
本文主要介紹Aztec Layer2解決方案中Account Abstraction(AA)的發展及相關內容。我引用了大量Aztec的官方資源,包括官方文件、部落格和教學。請在文章末尾的參考文獻部分找到這些優秀的資源!
背景
由於與ZK-Rollups 中的其他Native AA 實作相比,Aztec 的複雜性有所增加,讀者可能會受益於擁有一定的背景,以便更好地理解本文。
-
熟悉智能合約錢包及其功能
-
熟悉EIP-4337
-
熟悉ZK-Rollups 中的本機帳戶抽象
-
UTXO基本概念
-
ZK-Rollups 的基本概念
-
零知識證明程序的基本概念
介紹
快速瀏覽Aztec
Aztec 是一個開源第2 層網絡,旨在為以太坊提供可擴展性和隱私保護。 Aztec 利用zkSNARK 證明透過ZK-Rollup 服務提供隱私保護和可擴充性。 Aztec 的使用者不需要任何受信任的第三方或額外的共識機制來存取隱私交易。
我們都知道,在傳統的ZK-Rollups 中,「ZK」並不一定意味著隱私;它意味著使用零知識證明(ZKP)來證明某些計算已在鏈下正確執行。然而,在Aztec 中,除了可擴展性之外,ZK-Rollup 中還實現了隱私性。深入研究一下,在過去,每筆交易的細節在鏈上都是公開可見的,但在Aztec,每筆交易的輸入和輸出都是加密的。這些交易透過ZKP進行驗證,以證明加密訊息是準確的並且源自明文。只有建構這些私人交易的用戶才知道實際的明文資訊。
即使是ZK-Rollup 中的重要角色,例如Sequencer 和Prover,也無法確定明文內容。有關交易的所有訊息,包括發送者、接收者、交易資料和轉移的價值,都是隱藏的。雖然只有用戶自己知道交易細節,但他們仍然可以相信交易的正確性。這種信心源於這樣一個事實:只有合法的交易才能產生有效的零知識證明來證明其準確性。
如何實現私密交易以及如何驗證它們的基本原則是一個很大的話題,超出了本文的範圍。簡單來說,我們需要的是一個「用於零知識證明驗證的附加層」來驗證ZKP 列表,每個ZKP 都驗證一個私人交易。這也是為什麼它們被稱為「ZK-ZK-Rollups」的原因。
什麼是Noir?
在Aztec 中,使用本機帳戶抽象,這表示外部擁有的帳戶(EOA) 和合約帳戶之間沒有區別。所有帳戶都是智能合約。因此,我們將簡要介紹Aztec 的合約開發生態系統,因為了解合約開發至關重要。但是,如果您不打算親自開發帳戶合約,那麼閱讀和理解本文並不需要您打開電腦並編寫合約。您只需要了解帳戶合約代碼中的邏輯。您可以自行決定探索該主題的深度!
Noir是一種用於編寫SNARK 程式的語言,類似於Circcom 和ZoKrates。它不僅允許您在電路創建後自動生成Solidity Verifier 合約,還可以用於編寫您自己的協議甚至區塊鏈。由於Noir 並不完全依賴Aztec(它不會編譯成特定的證明系統),因此只要為證明系統實現後端伺服器和智能合約接口,您就可以實現您的目標。
在Aztec,Noir 用於編寫智慧合約,其中變數(狀態)和函數可以受到隱私保護。
什麼是私人狀態和私人筆記
根據我們對公共區塊鏈的理解,通常所有狀態都是公共的。在Aztec語中,掌握私有狀態的概念以及如何管理它(新增、修改、刪除)至關重要。私有狀態被加密並由其持有者擁有。例如,如果我是合約的所有者,則該合約中的特定變數可以是加密和隱藏的私有狀態。只有我作為這個私有狀態的擁有者,才能解密密文以獲得明文。
私有狀態透過僅附加資料庫樹儲存。這樣做是因為直接更改狀態值可能會從事務圖中洩漏大量資訊。然而,該資料庫並未直接儲存私有狀態的值。相反,它以加密形式將它們記錄為私人筆記(例如,,x=0 -> x=1)addr=0x00 -> addr=0x01。所以,實際上,這些私有變數雖然看起來是變數,但實際上是由一堆不可變的私人票據組成的。這是變數的抽象概念。如果還不清楚,讓我們繼續前進。
當您需要刪除私有狀態時,您可以將與該私有狀態相關的無效符號新增至另一個無效符資料庫以使其無效。當您需要變更私有狀態時,請先將其無效,然後向其新增新的私有註解。
我們很快就會介紹無效器的概念。您可以將其視為將私人註釋連結到其無效符所需的密鑰。只有無效密鑰的所有者才能識別並使用與其關聯的私人註釋。
此時,精明的讀者可能已經注意到,這種結構非常類似於UTXO(未花費的交易輸出),我們可以遍歷UTXO 來確定私有狀態的當前狀態(儘管重要的是要記住是用戶簽署交易,而不是UTXO;我們稍後會解釋這一點)。
什麼是私人筆記?一個UTXO稱為Note,我們透過遍歷這個Note Tree來取得相關私有狀態的資訊。當我們想要改變私有狀態時,步驟如下:
-
使用者從筆記資料庫中檢索與該私有狀態相關的所有私有筆記。
-
使用者(實際上是使用者運行的Aztec 節點)在本地證明每個檢索到的註釋在此DB 樹中的存在。
-
使用者添加一個無效符號以防止其他人再次讀取同一片葉子。
-
使用者插入一個新的葉子(一個新的註釋)來更新這個私有狀態的值。
Aztec的AA 機制
什麼是協定層,什麼是應用層?
眾所周知,EIP-4337旨在將整個交易流程移至應用層,實現開放中繼系統,並透過智慧合約的可程式特性抽像出簽章(驗證機制)和支付模型。然而,對於Native Account Abstraction,無論是在StarkNet、zkSync 時代,或是本文重點的Aztec,都需要將某些元素蝕刻到Layer2 的協定中才能正常運作。例如,在Aztec 中,加密金鑰和無效金鑰需要在協定層級實現。
了解本機帳戶抽象化需要更深入地了解整個鏈的運作方式(假設它被稱為“本機”,AA 的執行邏輯自然連結到特定Layer2 的協議)。例如,在zkSync 時代,需要理解系統合約,在StarkNet 中,需要理解序列器如何運行,而在Aztec 中,理解這些「金鑰及其底層私有狀態」的作用至關重要。
帳戶入口點和驗證階段
在Aztec 中,與帳戶抽象的其他實作不同,沒有嚴格定義的函數名稱(函數簽章)作為帳戶合約的入口點(例如,validateUserOp在EIP-4337、validateTransactionzkSync Era 和__validate__StarkNet 中)。使用者可以自由選擇帳戶合約中的任意函數作為入口點,並發送帶有相關參數的交易。
使用者選擇的函數(我們稱之為entrypoint())必須是私有的(在使用者的私有執行環境中執行)。只能從帳戶合約所有者的客戶端(用戶的錢包)呼叫。當使用者的錢包entrypoint()在本地執行時,它同時產生零知識證明。該證明通知Aztec協定的驗證階段,鏈下執行已經發生並且已經成功。
驗證階段的限制
這也延伸到是否在驗證階段對可執行操作施加限制的問題。眾所周知,由於驗證交易沒有成本限制(本質上,驗證交易是呼叫函數view),攻擊者可以對記憶體池執行拒絕服務(DOS)攻擊,以破壞捆綁器(EIP-4337)或操作員/排序器(原生AA)。 EIP-4337 定義了禁止哪些操作碼以及如何限制儲存存取。 zkSync Era放寬了一些OpCode的使用,而StarkNet根本不允許外部合約呼叫。
由於Aztec 協定涉及用戶端對附加的零知識證明進行驗證,而不是實際呼叫驗證函數來確定結果為或,因此trueAztecfalse與其他協定不同,在驗證階段不會施加任何限制。帳戶內的合約entrypoint可以自由呼叫其他合約、存取任何儲存、執行任何計算。
互動流程
更詳細地說,在zkSync Era 和StarkNet 中,只有「帳戶合約」才能發起交易,因為協議調用指定函數作為入口點,施加了這種限制。然而,在Aztec 中,「所有合約」都可以發起交易,因為協定呼叫哪個函數作為入口點沒有限制。這意味著在Aztec 上,不再是使用者將交易傳送到特定角色(例如EIP-4337 中的EntryPoint 合約或Native AA 中的定序器/操作符),然後呼叫目標合約的固定互動流程。用戶可以透過錢包發送交易,直接讓目標合約完成相關交互,大大增強了靈活性。
如果您熟悉EIP-2938(AA 的另一種實作),您會發現Aztec 更類似於其中的多租戶方法。然而,這是一個更深層的話題,你可以自己探索。
Aztec 帳戶中的金鑰
在Aztec 中,每個帳戶通常有兩個主金鑰:簽章金鑰和隱私主金鑰。
簽署金鑰
簽署金鑰用於表示使用者對使用私鑰執行特定操作的授權。一個簡單的例子是使用者在帳戶合約中記錄從簽署金鑰派生的公鑰。然後,透過使用此簽名金鑰對交易或訊息進行簽名,可以在合約內恢復產生的簽名,以檢查其是否與合約中記錄的公鑰(也稱為所有者控制金鑰,以金鑰形式存儲)相匹配。 addressSolidity 錢包合約中的變數)。
關於數位簽章橢圓曲線演算法的選擇,由使用者決定。例如,以太坊使用secp256k1,而Aztec 提供了使用的範例schnorr。在帳戶合約中,該entrypoint()函數作為入口點(呼叫的來源),驗證邏輯(is_valid_impl())使用來檢查Schnorr 簽章是否與記錄的公鑰匹配std::schnorr::verify_signature(…) 。
簽章金鑰本質上和我們熟悉的智慧合約錢包中的擁有者控制金鑰相同,所以應該比較容易理解。事實上,簽署金鑰並不是絕對必要的。如果帳戶開發者實施了其他驗證機制,則帳戶可能沒有簽署金鑰。
隱私主密鑰
Aztec帳戶中的隱私主金鑰是不可轉讓的;每個Aztec 帳戶都綁定到一個隱私主金鑰。隱私主金鑰衍生出公用主金鑰,然後與合約代碼進行雜湊運算,產生帳戶合約的位址。
我們將使用者的account_address、partial_address、 和統稱public_master_key為帳戶的完整位址。在處理私有狀態時,使用者需要提供這三項訊息,以便任何人都可以驗證公鑰是否對應於預期的地址。
但是,如果它是一個不打算處理私有狀態並且缺少的應用程式(例如DeFi)public_master_key,您可以簡單地填寫該public_master_key欄位0以表示它不希望收到私人票據。
所以,儘管Aztec允許我們在帳戶合約中實現驗證機制甚至一些恢復機制來增強帳戶安全性,但與隱私主金鑰相關的機制卻被印在協定中並與地址綁定。因此,它不可互換。
這裡的意思是,該金鑰與以太坊中EOA(外部擁有帳戶)的私鑰一樣重要,使其成為帳戶的單點故障(SPoF)。如果用戶遺失或帳戶的隱私主金鑰被盜,毫無疑問該帳戶將無法恢復。
隱私主金鑰也使用類似BIP-32 的程序匯出加密金鑰和無效金鑰。使用者可以在不同的應用程式或操作中使用不同的加密金鑰和無效金鑰,以確保隱私和安全。
加密金鑰
加密金鑰的公鑰用於加密私人票據,而私鑰則用於解密它。例如,在代幣轉帳場景中,如果我(代幣發送者)想要將代幣轉帳給我的朋友(代幣接收者),我需要對私人票據進行加密(代幣的轉賬,涉及改變變量,本質上balance是使用我朋友的加密公鑰更改私有狀態變數UTXO)並發送它。
從局外人的角度來看,如果不知道令牌接收者的加密私鑰,他們就無法破解這個私人票據,也無法知道令牌接收者是誰。
無效符
每次使用私人註解時,都會產生從該私人註解派生的無效符(使用無效金鑰加密)。此機制用於防止雙花(避免其他人使用相同的方法確定紙幣的位置或兩次扣除資金),因為Aztec 協議會檢查無效符是否唯一。為了將該無效符與私人票據相匹配,需要無效私鑰對其進行解密,因此只有其所有者才能建立兩者之間的關係。
Aztec交易
描述Aztec 中交易的概念可能具有挑戰性,因為它很容易與UTXO(私人票據)混淆,而且EVM 和Aztec 中交易的執行模式完全不同。
在Aztec中,每筆交易都以零知識證明的形式廣播(顯然是出於隱私原因)。用戶必須在其節點(錢包應用程式或客戶端)本地執行計算,以產生與交易相對應的證明,而不是像我們過去那樣透過RPC API 簡單地將交易物件發送到礦工的記憶體池或任何第2層操作員。
交易哈希和隨機數
當使用者在本地建立交易時,有兩個重要要素:
-
寄件者地址:這代表處理交易的帳戶合約的地址。在這個帳戶合約裡面,有我們前面提到的入口點,它作為外部各方驗證這個行為(交易)是否得到帳戶所有者授權的驗證功能。
-
有效負載資料:這包括有關交易的信息,例如簽名、目標合約地址、價值、資料等。
在Aztec 的協議級別,每個有效交易的雜湊被用作防止相同交易被多次執行的手段。帳戶合約開發者可以決定帳戶合約中是否應該有nonce以及相關邏輯。例如,他們可以設定諸如確保交易中的nonce欄位嚴格增加或交易可以按任何順序處理等要求。
由於協議層面沒有嚴格的隨機數要求,Aztec 無法透過提交具有相同隨機數和更高Gas 費用的新交易來取消待處理的交易。
執行請求
如同前面所提到的,使用者可以根據不同情況指定帳戶合約中的任意函數作為入口點,而Aztec 中的操作並不是由一個簡單的交易物件來控制的。實際上,告訴合約帳戶做什麼的是一個稱為「執行請求」的物件。此物件代表使用者的行為,例如「使用0x1234以下參數呼叫合約上的傳輸函數」。
使用者在錢包本地發起交易,其中sender_address是帳戶合約的地址,包含payload呼叫目標合約中函數的相關編碼資料transfer(),以及帳戶合約可以驗證的簽章。錢包將這兩個元素轉換為執行請求。
然後,錢包將私人票據、加密金鑰或無效秘密輸入到本機虛擬機器以模擬此執行請求。模擬過程中會產生執行軌跡,交給證明者產生零知識證明。這個證明顯示這些計算(私有函數的執行)確實是由使用者在本地完成的。
透過這個過程,我們得到兩個資訊:proof和private_data(本次交易的私有內核電路的輸出)。然後錢包將包含這兩個資訊的交易對象發送到Aztec 的Sequencer mempool 並完成交易。
基於客戶端的ZKP 取代EVM 的類型執行環境
在Aztec 中,我們不會簡單地將所有資訊輸入到像EVM 這樣的圖靈機中來產生更新的狀態。相反,它依賴每個Dapp 內的電路來確定隱私資訊應如何運作。這意味著Dapp開發者需要有一種方法來證明合約變數的狀態。例如,讓我們考慮ERC-20 代幣合約中用戶的餘額。如果我們想要轉帳10 個DAI 代幣,合約可能有以下邏輯:
-
檢查發送者的餘額是否大於10 DAI(即> 10 DAI)。
-
如果發送者有足夠的餘額,則建立一個無效符來表示發送者的10 DAI 的銷毀(該無效符可以抵銷發送者對10 DAI 私人票據的佔有)。
-
為收件者建立新的私人註解。
-
廣播並加密包含10 DAI 傳輸的所有訊息。
從外人的角度來看,他們只能看到新的無效符和註釋出現,而且它們都是加密的。所以,每個人都知道發生了新的交易,但裡面到底發生了什麼事只有參與的參與者知道。
深入了解Aztec帳戶合約
錢包
Aztec 中的錢包是管理用戶與區塊鏈及其私人資料互動的重要組成部分。以下是Aztec 錢包必須處理的任務的摘要:
-
創建帳戶:錢包應該允許用戶創建新的帳戶合約,這本質上意味著在區塊鏈上部署新的帳戶合約。
-
私鑰管理:錢包負責管理使用者種子短語和私鑰,其中包括隱私主金鑰和簽署金鑰(取決於帳戶合約的設計)。這種管理還可以擴展到硬體錢包整合。
-
查看帳戶:使用者應該能夠查看他們的帳戶和相關狀態,包括餘額和其他私人狀態。這意味著錢包需要維護一個本地資料庫,其中包含所有與用戶相關的私人筆記。
-
與Dapp 互動:錢包需要促進使用者和Dapp 之間的互動。當使用者與Dapp 互動時,Dapp 可能會要求從使用者帳戶發送交易。
-
用戶同意: Dapp 可能需要用戶同意才能顯示某些合約狀態,例如代幣合約中的餘額。要公開這些狀態,錢包必須能夠接收用戶請求(因為公開餘額需要用戶金鑰同意)。
-
生成證明:要代表用戶發送交易,錢包必須能夠在本地生成證明。這涉及創建和處理交易有效性的零知識證明。
需要注意的一個關鍵點是,錢包需要掃描從創世區塊開始的所有區塊,使用用戶的金鑰來發現和解密相關的私人筆記,然後將其儲存在本地資料庫中以供將來使用。這對於促進使用者互動並確保私有狀態資料能夠有效管理至關重要。
您提到了Aztec 的另一個重要方面,即需要使用者廣播完整的位址。當錢包為目標交易的接收者建立加密票據時,它還需要能夠取得接收者的完整位址。這可以透過手動輸入或維護收件人地址的本機資料庫來實現。關於這方面的更多細節,可以參考Aztec官方文件。
帳戶合約
在Aztec 中,帳戶合約的主要任務是驗證簽名(確認交易是由帳戶所有者授權的,因此更廣泛的是授權,而不一定是「透過特定的數位簽章演算法進行驗證」)、管理Gas 消耗、並調用其他合約。
這是使用Schnorr 簽章演算法的Aztec 帳戶合約的官方範例。所有交易的入口點是entrypoint()函數(您可以自由選擇函數或名稱作為起點,但在本例中entrypoint()使用)。
當我們呼叫entrypoint()有附件的帳戶時payload,帳戶合約entrypoint()將呼叫Aztec AA 帳戶庫entrypoint()中的。
Aztec不需要我們的帳戶合約導入EntrypointPayload和Aztec AA帳戶庫;你可以自由設計自己的帳戶合約邏輯。
是context一個在中的每個函數中都可用的物件Aztec.nr。包含context應用程式執行所需的所有核心資訊。引自Aztec 官方文件。 – 背景是什麼
以上是Aztec AA帳戶庫的程式碼entrypoint()。它負責根據帳戶is_valid_impl合約上定義的驗證函數()來確定該操作是否得到帳戶所有者的授權,並透過進行必要的呼叫以實現交易所需的操作execute_calls。
這意味著,如果您想引用此Aztec AA 庫,並且您的帳戶合約沒有is_valid_impl使用相同的函數簽章實現,則此步驟將失敗。
另一個關鍵的實作細節是使用get_auth_witness()檢索signature. 您可以參考下面參考資料中的介紹來了解見證人的詳細工作原理。簡單來說,見證人就是「對使用者想要執行的操作的授權」。
身份驗證見證是一種在Aztec 上驗證操作的方案,因此使用者可以允許第三方(例如協定或其他使用者)代表他們執行操作。引自Aztec 官方文件。 — 認證見證人
之所以稱為“見證人”而不是簡單地稱為“簽名”,是因為帳戶合約的驗證方式並不一定涉及驗證簽名。
例如,假設有一個操作,將1000 個代幣從Alice 的帳戶轉移到DeFi 平台。在這種情況下,代幣合約需要查詢Alice的帳戶合約,看看她是否批准這個「行動」。此「操作」需要在Alice 的錢包(本地)中產生一個身份驗證見證,然後可以透過她的帳戶合約進行驗證。如果帳戶合約驗證成功,代幣合約就能知道這個「動作」已經被授權。
結論
截至目前,Aztec還沒有實現費用機制,他們的目標也是抽象化費用的支付。這意味著,要使一筆交易被視為有效,它必須證明它已經鎖定了足夠的資金來支付自己的費用。然而,它沒有具體說明這些資金必須來自哪裡,從而可以透過即時交換輕鬆實現付款或實物支付。