玩Solana 一文掌握Solana 核心概念

2024年,Solana異軍突起,TVL從年初的十億美元飆升至如今的近五十億美元,一躍成為第4大公鏈。

與Ethereum相比,Solana以更快的速度和更低廉的費用為用戶帶來了更優越的體驗。其基於POH的共識機制和非同步的交易執行模式為開發者提供了高吞吐量和低延遲的區塊鏈效能,成為各種去中心化應用的首選平台。

BlockSec 特別策劃了《玩轉 Solana》系列文章,涵蓋Solana 基本概念、查看和分析Solana 交易實用指南以及編寫Solana 智能合約教程等乾貨內容。

作為系列的第1期,本文將深入介紹Solana網路中的關鍵概念,包括其運作機制,帳戶模型與交易,為大家寫出正確且有效率的Solana合約打下基礎。

eBPF: Solana交易的執行基石

為了編寫和執行智能合約,區塊鏈往往需要一套程式語言和圖靈完備的運算環境。

熟悉Ethereum的朋友們應該知道,以太坊上的智能合約通常使用高級語言Solidity來編寫,而Solidity編譯產生的字節碼則運行在一個叫做以太坊虛擬機的環境中。

Solana並沒有選擇開發全新的虛擬環境和語言,而是充分利用了現有的優秀技術。原本用於拓展Linux核心功能的eBPF(extended Berkeley Packet Filter)虛擬機器被Solana選取並作為底層的執行環境。

那麼,eBPF 相對於EVM 有哪些優點呢?

相較於只支援解釋執行的EVM,eBPF能夠以即時編譯(JIT)模式直接將字節碼轉換成處理器可以直接執行的機器指令,從而更有效率地執行程式。

eBPF擁有一套高效率的指令集和成熟的基礎架構。開發者只需要使用Rust語言即可編寫智慧合約。 LLVM編譯框架提供了一個eBPF的後端,利用它可以直接將這些Rust語言所寫的程式編譯成可運行在eBPF虛擬機器上的字節碼。

Solana的帳戶模型

1. Solana帳戶結構

Solana上的資料以帳戶的形式儲存。如下圖所示,我們可將Solana中的所有資料視為一個龐大的鍵值對資料庫。資料庫的鍵是帳戶的位址,對於「錢包」帳戶(即由

Solana用戶透過公私鑰對直接控制的帳戶)而言,這個地址是使用Ed25519簽名系統產生的公鑰;而資料庫的值是該帳戶的具體信息,包含餘額和其它相關信息。

Solana使用名為AccountInfo的結構來描述一個帳戶,其組成如下圖所示。

Solana中的每個帳戶均包含四個欄位。這裡我們對其進行逐一解釋。

  • Data欄位儲存了該帳戶相關的資料。如果該帳戶為程式(即智慧合約),則它儲存的其實就是eBPF字節碼。否則,Data中資訊格式一般由帳戶建立者自行定義。

  • Executable欄位用於標識該帳戶是否為程式。需要注意的是,與以太坊不同,Solana中的程式是可以更新的。

  • Lamports欄位記錄了該帳戶Solana代幣的餘額。 Lamports其實是SOL Token的最小單位(1 SOL = 10億Lamports)。

  • Owner欄位指示了目前帳戶的擁有者。在Solana中,任何一個帳戶都有一個「Owner」。例如,所有「錢包」帳戶的擁有者都是System Program,這是Solana網路上的一個特殊帳戶,負責帳戶創建等功能。帳戶擁有者是唯一能夠修改帳戶資料和扣除Lamports餘額的人(但任何人都可以增加Lamports,即向帳戶執行轉帳功能)。

2. 預定義的Solana帳戶

Solana擁有一套稱作Native Programs的預先定義運行程序,它們被部署在固定的位址上。隨著Solana網路的升級,這些預先定義的程式也可能會被更新。我們可以將這些程式理解成Solana網路下提供特定功能的API和函式庫函數。

在Native Programs中,開發者經常需要與之互動的程式是System Program。 System Program為開發者提供了一些指令(Instructions),我們可以把每條指令理解成是一個獨立的方法。例如,開發者可使用CreateAccount指令來建立新的帳戶,或使用Transfer指令將Lamports轉帳到其它帳戶。

另外一個常見的Native Programs是BPF Loader程式。它是所有其它程式帳戶的擁有者,其負責部署、更新和執行特定的程序。當一個「錢包」帳戶需要更新它部署過的程式時,實際上就是透過委託BPF Loader程式來完成的,畢竟只有程式的擁有者才有直接權限修改資料。

除了Native Programs,Solana還提供了一組被稱為Sysvar的帳戶。它們為Solana上的程式提供了與當前Solana網路狀態相關的資訊和全局變量,例如當前的時鐘,最近的區塊哈希等。

3. 帳戶租金

在Solana鏈上,每個帳戶都需要保持一定數量的Lamports作為最低額度,這稱為租金。與現實生活中的租金概念不同,Solana上的租金是可以收回的。為了確保帳戶在鏈上的資料是可用的,帳戶需要持有相應數量的Lamports。租金的金額與帳戶在鏈上儲存空間的大小有關。

任何試圖將帳戶餘額扣減至低於租金金額的交易都會失敗,除非這筆交易直接將帳戶的餘額扣減至零。這種操作表明該帳戶的租金已被收回,在交易執行結束時,Solana會透過垃圾回收清空相應帳戶的儲存空間。

– ? 在瀏覽器中查看“Solana帳戶”

為了帶領大家更能理解相關概念,我們使用Solana提供的「Hello World」專案創建了一個程式帳戶,可以透過Solana的區塊鏈瀏覽器Solscan來查看以下帳戶?的相關資訊。

CJWhxB4qEWBv9eGYUkTN881bNDMDkLbzH1FmdwqLLhoe

如上圖所示,我們首先可以看到,該帳戶已被Solana瀏覽器標明為「Program」。在創建該帳戶時從發送者的餘額中扣除了一部分Lamports作為該帳戶的租金,故而我們可以看到其SOL Balance字段不為空。

其次,由於我們創建的是一個程序,其Executable字段為Yes。這裡可能有一個難以理解的地方,那就是讀者也許會發現Data欄位儲存的是一個位址而非eBPF程式。我們在前面提到過,Solana允許更新程序,而它實際上是透過一種「代理」模式來實現的。由於Solana並不允許直接修改程序帳戶,所以它創建了一個資料帳戶用來儲存eBPF程序,而在程序帳戶的Data欄位只儲存資料帳戶的位址。每當需要更新程式時,就只需修改資料帳戶中的Data欄位。我們用Solscan查看Executable Data欄位的帳戶可以發現它被標記為“Program Executable Data Account”,其Data欄位儲存了實際的程式:

回到上一張圖片,我們可以發現在More info中Owner欄位為BPF Loader,這與我們在上一節的描述是一致的。

在Overview中還有一個名為「Upgrade Authority」的字段,它的意義是什麼呢?

正如我們前面提到的,「錢包」帳戶是透過委託BPF Loader來更新程式的,而在更新之前,BPF Loader需要驗證委託者是否擁有更新的權限。由於程式帳戶的Owner欄位已經是BPF Loader,其本身已經沒有空間可以儲存該資訊了,因此Solana選擇把這個資訊儲存在資料帳戶的Data欄位中,而這個資訊其實就是部署程式的錢包位址,也就是這裡的「Upgrade Authority」。下圖展示了程式帳戶與資料帳戶之間的關係,可以看到資料帳戶的Data欄位由錢包位址和eBPF代碼兩部分資訊組成。

Solana的交易和指示

在Solana中,使用者同樣透過簽發交易(Transactions)來執行程式。其特別之處在於,Solana能夠並行執行這些交易,這也是其能夠提供閃電般交易速度的重要原因。接下來我們來看看Solana的交易是如何設計的。

一筆Solana交易由簽名和訊息主體組成。一筆交易可包含多個簽名。交易的訊息主體由四個部分組成,如下圖所示。

訊息的頭部資訊(Header)和帳戶地址數組(Compact array of account addresses)兩個欄位指定了交易涉及的所有帳戶以及帳戶在交易中的特徵:包括該帳戶是否提供了簽名以及執行過程中是否會被寫入。利用這些信息,Solana能夠驗證相應帳戶提供的簽名,並且能夠並行地執行那些不觸碰相同帳戶集合的交易。

最近的區塊哈希(Recent Blockhash)是交易的時間戳記。 Solana網路會確保交易來自於最近的150個區塊,否則交易會被認為過期而不會被執行。

指令陣列(Compact array of Instructions)是交易中最重要的部分,包含了一條或多條指令。一條指令其實是對某個程式提供的一段例程的呼叫。指令由三個欄位組成,如下圖所示:

第一個欄位Program ID Index指定了指令的接收者,也就是需要處理該指令的鏈上程式。它不會直接存放一個32位元組的位址,而是將該位址放在訊息主體中的帳戶位址陣列中。此欄位使用一個位元組的下標指明其在數組中的位置,實現了一種空間復用。

和第一個欄位類似,第二個欄位是由帳戶位址下標組成的陣列(Compact array of account address indexes),它指明了處理該指令涉及到的所有帳戶。

最後一個欄位是一段位元組數組,它是程式處理該指令所需的額外訊息,可以把它理解成函數的參數。

需要注意的是,Solana會依照順序處理交易中的所有指令,並確保交易的執行是原子性的。這意味著一筆交易中的指令要麼全部失敗,要麼全部成功執行,不會出現部分指令成功執行而部分失敗的情況。

– ? 在瀏覽器中查看“Solana交易”

我們使用另外一個Solana瀏覽器來查看前面創建程式帳戶的交易?。在Overview中能夠看到Solana交易的簽名、最近區塊哈希等資訊:
3uKQ85Lpsnwb5D6CgUntoMyJX3tSaeGb4pjUoMaMyNVqQNPp5PRG1kJEEEk3YNdWLYEMZGmoJ5Rowgon8hZzwL9D

而在Account Input中則列出了目前交易涉及到的所有帳戶以及相關帳戶在交易中的特徵。我們可以看到除了發送者、程式帳戶等地址外,兩個Native Programs和Sysvar帳戶也被包含進去了。

由於交易是一個簡單的程式建立交易,所以它只包含了兩個指令,第一個指令的接收者是System Program,負責建立程式帳戶;第二個指令的接受者則是BPF Loader,負責將實際部署的eBPF程式碼寫入到資料帳戶中,並將其位址寫入到程式帳戶的Data欄位。

總結

Solana上的智慧合約採用Rust語言開發,並在eBPF虛擬機器上運作。它遵循帳戶模型,鏈上的帳戶需要維持租金才能保證資料的可用性。交易由一條或多條指令組成,明確定義了依賴的所有帳戶,從而使得交易能夠被並行處理,提高了吞吐量並降低了回應延遲。這些特點共同促進了Solana的快速發展,使其成為備受青睞的區塊鏈平台之一。

Total
0
Shares
Related Posts