3個Aleo 開發者必知的核心概念

作為主網上線前的最後一次測試網,Aleo Testnet 3已經吸引了全球一眾開發者的目光。隨著三階段Phase 1的進行,開發者可以進行程序部署和轉賬,離網絡的完善又更近了一步。站在開發者的角度,本文會為大家簡單介紹關於 Aleo 程序開發的三大核心概念,來幫助開發者社區對Aleo有更進一步的了解。
基於零知識證明的編程語言
不管是Leo還是其編譯後的Aleo instructions都是Aleo公鏈的智能合約的一部分。就像其他公鏈的智能合約編程語言一樣like solidity,都是為鏈上交易以及鏈上應用開發提供便利性的工具。而Aleo公鏈不同的是在於,Aleo公鏈的智能合約編程語言是基於零知識證明技術zksnark實現的。通過將“智能合約的執行”打包成一個同態加密的多項式,通過驗證這個多項式的結果,來確定交易是否可信是否上鍊,這樣就可以做到真正的隱私計算、隱私交易。具體的操作過程如下圖所示。

這樣的好處不僅僅是提高了隱私性,這種鏈下執行加鏈下驗證的模式,給程序提供了無上限的運行時,同時鏈上節點只需要驗證Proof是否正確,驗證時間遠比執行時間短,所以可以大幅提高鏈的tps。同時因為不存在鏈上運行時的概念,所以也不需要考慮程序gas費過高的問題。
那麼對於我們開發者來說,知道這些有什麼用呢?這就要說它的缺點了,我們知道通過zksnark生成的多項式本質是程序約束的一種形式。所以我們的程序必須是確定性的,這樣程序的約束才能是確定性的,才能生成對應的多項式。所以很多傳統編程語言的功能很難實現,這也就是為什麼Aleo團隊不選擇實現圖靈完備的原因。所以作為開發者,我們需要了解這部分知識,對其有一個正確的期待。
還有一個缺點就是鏈下生成proof需要設備的性能比較強,所以低性能設備例如手機生成proof可能會非常慢。當然Aleo也有解決方案,那就是低性能設備可以通過委託Prover幫你生成證明,當然這樣就有一定的tradeoff,因為你的部分隱私會被用來換取便利性。在Aleo instructions中,可以通過finalize關鍵字實現部分程序鏈上執行的操作。
1 | // The function `mint_public` issues the specified token amount |
這裡默認你已經看了avm的doc。可以看到這裡主要實現了min_public函數,並且用finalize關鍵字重寫了mint_public。簡單來說用finalize關鍵字重寫的函數是鏈上執行的,而原函數則是鏈下執行的。原函數通過將輸入寄存在finalize類型的寄存器裡,之後在鏈上執行的時候會取出finalize寄存器的值進行對應finalize function的操作。這裡要注意finalize寄存器只能接受public的數據,所以意味著你的input是可能有隱私問題的,就像上面說的,這是一個tradeoff。
ZEXE模型
aleo的模型和以太坊以及比特幣不同,比特幣使用的是UTXO(Unspent Transaction Output)模型,而以太坊使用的是基於賬戶的模型。 aleo的zexe交易模型更像是比特幣。
zexe模型中有一個重要的概念就是record,record承載著智能合約的數據。在zexe模型中每個transaction至少對應一個record。

這裡的record就像UTXO模型一樣,每次交易消耗掉舊的records,生成新的records,而所有該用戶現存的records總和,即為該用戶所有資產的總餘額。就像現實中的紙幣一樣,不同的是record能夠承載別的數據。
每個record會包含4個parameter
- owner是該record所有者,也就是user的公鑰地址。
- gates是該record持有的aleo幣的數量
- data是存在該record的數據,屬於程序可自定義的map存儲區。開發者可以在這個值裡存儲自己定義的數據類型。
- nonce是隨機值,也就是防止雙花record的標識。
下面的代碼是Aleo instructions定義record的方式
1 | //aleo instruction define record |
這樣任何輸入輸出的records,都會在對應的data map區域新增對應的鍵值對map<ident,type>(如果已經存在則不新增)。利用這個功能我們能自己定義屬於自己的assets,去支持各種金融應用。
最近Aleo instructions還引入的新的關鍵字mapping。這個關鍵字是目前專門用於鏈上執行的,也就是只能用於前面所說的finalize關鍵字聲明的function裡面。
1 | mapping account: |
通過聲明mapping<key,value>,會在全節點的內存中開闢一個新的**公開的(public)全局的(global)**的data storage。開發者可以在鏈上存儲自己定義的鍵值對,這裡鍵值對必須是public的,並且對應的increment decrement的操作也只能是finalize類型的寄存器。目前對於mapping的使用場景還不清楚,還需要看後續的開發情況。
棧式虛擬機(Stack-based virtual machine)
眾所周知,虛擬機分為棧式虛擬機和寄存器虛擬機(register-based virtual machine)。知名的JVM和以太坊EVM都是棧式虛擬機,lua是寄存器虛擬機。目前Aleo的snarkvm實現的也是棧式虛擬機。
1 | pub struct Stack<N: Network> { |
上面的代碼就是snarkvm的棧幀數據結構。當snarkvm執行一段程序的對應function的時候,會先將該program初始化到新的棧幀裡,包括外部函數的使用(external_stack),所有function所需的registers(register_types,finalize_types),以及對應的pk,vk。每個棧幀都會有對應的寄存器數量,這個跟你寫完的program相關。加載完畢後,就按照棧的先進先出(first in first out)的原則,依次執行對應代碼和對應的外部函數引用。
就像是深度優先遍歷樹結構一樣,root節點的棧是我們初始程序,向下擴展的樹枝都是外部引用的程序棧。

以上就是關於 Aleo 開發階段的三個比較重要的核心概念,對於想要基於 Aleo開發隱私應用的開發者而言,這也是入門的基礎,希望本文可以給開發者社區帶來一些參考和啟發。