media Image
深入探討 Solana - User
Back Icon Image

引言

Solana 區塊鏈的交易生命週期始於使用者與去中心化應用(DApp)的互動。DApp 作為 Web3 的門戶,將使用者的操作轉換為區塊鏈可理解的訊息。理解錢包如何管理公私鑰、簽署交易,DApp 如何組裝指令並發送交易,以及 Solana 如何儲存和管理狀態,是掌握 Solana 運作的核心。本篇將簡明介紹這些過程,幫助你了解 Solana 的交易流程。

提醒讀者:如果您尚未閱讀過或想先了解 Solana 的基本運作流程,建議先參考「由 Transaction 的生命週期看 Solana 的底層架構」 ,這將有助於您更好地理解本篇深入探討的技術細節。


1. 公私鑰系統與錢包運作 : Solana 的安全基石

在 Solana 區塊鏈中,錢包是用戶管理資產並與區塊鏈互動的關鍵工具,而公私鑰系統則是錢包運作的核心基礎。理解公私鑰的生成與管理,有助於掌握錢包如何保護資產並保障交易的安全性。

1.1 公私鑰生成與錢包管理

  • 公鑰:公鑰就像是銀行帳號,是用來接收資金的唯一識別符號。在 Solana 中,錢包應用使用 Ed25519 橢圓曲線數位簽章演算法來生成公鑰。生成後的公鑰會作為您的帳戶地址,通常以 Base58 編碼表示,例如:FDKJvWcJNe6wecbgDYDFPCfgs14aJnVsUfWQRYWLn4Tn。這個地址是公開的,任何人都可以通過這個地址向您發送資產。
  • 私鑰:私鑰則可以比作提款卡密碼,是保護您帳戶安全的核心工具。它由錢包生成並安全存儲在您的設備中,私鑰永遠不會離開您的控制範圍。只有擁有私鑰的人才能進行交易授權,意味著掌握私鑰的人擁有完全控制該帳戶的權限。
  • Keypair(密鑰對):密鑰對由公鑰和私鑰組成,前 32 字節是公鑰,後 32 字節是私鑰。就像銀行帳號和密碼的組合一樣,公鑰用於接收資產,私鑰用於保護和操作您的資產。錢包透過管理這對密鑰,讓使用者可以安全地查看並操作自己的帳戶,確保每筆交易的安全性和合法性。

在 Terminal 中,我們可以利用 solana-keygen 去生成密碼對,可由上方觀察到 json 檔中,共64字節,前 32 是公鑰,後 32 是私鑰。

1.2 錢包的運作流程

錢包應用在日常使用中,扮演著多重角色,包括生成密鑰、管理帳戶、簽署交易以及與 DApp 進行交互。以下是錢包的核心運作流程:

  • 密鑰管理:當使用者設置錢包時,應用會自動生成一對公私鑰並將其安全地存儲。私鑰被加密保護,並且通常會通過助記詞(mnemonic phrase)進行備份,這樣在用戶更換設備或重新安裝錢包時,可以通過助記詞恢復帳戶。
  • 帳戶查看與管理:錢包允許使用者查看他們的公鑰(即帳戶地址)和資產狀態。這些信息通常是錢包界面的核心部分,用戶可以隨時查看帳戶中的 SOL 代幣和其他資產的餘額。
  • 交易簽署與發送:當使用者在 DApp 中發起一筆交易時,交易數據會被傳遞到錢包中進行簽署。錢包使用私鑰對交易進行簽名,然後將簽名附加在交易數據上。這一步確保了交易的合法性和安全性,並防止未經授權的操作。簽署完成後,錢包會將簽署好的交易返回 DApp,然後通過 RPC(遠端程式呼叫)發送到 Solana 區塊鏈網路。

1.3 EVM v.s. Solana Address

  • EVM 公私鑰管理:在以太坊等 EVM 區塊鏈中,帳戶地址是通過將公鑰經過 Keccak-256 雜湊後的最後 20 字節生成的,這使得地址與公鑰之間沒有直接的雙向對應關係。這種設計雖然靈活,但增加了計算的複雜性。
  • Solana 的簡化設計:Solana 直接將公鑰用作帳戶地址,這不僅簡化了地址生成過程,還提高了交易處理效率。這樣的設計使得錢包操作更加直觀和高效,有利於減少開發者的工作量並提高用戶體驗。

2. Solana 帳戶系統:靈活與多樣化的數據管理

Solana 的帳戶系統具有高度的靈活性和多樣化,這使得它能夠支持更加複雜的應用程式邏輯。每個帳戶在 Solana 上都是一個數據結構,這些結構存儲了關於使用者與區塊鏈互動的所有狀態信息。

2.1 帳戶類型

帳戶在 Solana 中是持續保存數據的容器,類似於電腦上的文件,有不同形式:

  • 用戶帳戶 (User accounts):由私鑰控制,主要用於存儲 SOL 和其他代幣。例子:用戶可以通過這些帳戶進行交易和參與智能合約。
  • 數據帳戶 (Data accounts):保存 Program 的狀態數據,是智能合約運行的關鍵。例子:當用戶參與 DeFi 協議時,其狀態信息存儲於數據帳戶中。
  • 程式帳戶 (Program accounts):存儲可執行代碼,這些代碼在運行時只能更改其他帳戶,不會改變自身狀態。例子:智能合約的邏輯由這些帳戶管理,但合約本身不會自我修改。
  • 原生程式帳戶 (Native Program accounts):包含預部署的 Solana 核心功能,如 BPF 載入器和投票程式。例子:這些帳戶使得 Solana 能夠在不重新部署核心功能的情況下執行重要操作。

2.2 租金機制

Solana 的租金機制旨在減少帳戶狀態的膨脹。創建新帳戶時,必須保持最低 SOL 餘額,稱為“免租金”金額,以支付帳戶在驗證器內存中保持活躍的存儲成本。如果帳戶數據大小增加,最低餘額也會增加。當帳戶不再需要時,關閉帳戶可返還剩餘租金。

2.3 帳戶所有權

Solana 的所有權模型通過限制誰能修改帳戶數據來提升安全性。每個帳戶都有一個“所有者”,確保只有授權者才能更改帳戶數據。唯一例外是 Lamports 的轉移,無論帳戶所有權如何,增加帳戶的 Lamports 餘額是允許的。

2.4 狀態存儲

Solana 的 Program 是 唯讀 的可執行代碼,因此必須使用 PDA 來存儲狀態。PDA 是與特定 Program 關聯的特殊帳戶,其公鑰由參數與 Program ID 組合派生。PDA 存在於“橢圓曲線外”(因此沒有與其匹配的私鑰對),只有擁有 PDA 的 Program 可以生成簽名,這保證了只有該 Program 能修改 PDA 的狀態。


3. 交易與指令:Solana 的運作流程

在 Solana 區塊鏈中,交易(Transaction)和指令(Instruction)之間存在明確的層級關係。交易由一個或多個指令組成,每個指令都是對特定智能合約(Program)的請求。Solana 的交易是原子的,這意味著交易中的所有操作要麼全部成功執行,要麼完全失敗並回滾。這種設計確保了交易執行的精確性與高效性。

3.1 交易(Transaction)的結構

一筆 Solana 交易由以下四個關鍵部分組成:

  1. 帳戶地址列表(Account Addresses)
    • 設計原理:Solana 要求在交易前列出所有會讀取或寫入的帳戶地址,讓系統能提前分配資源並優化操作。
    • 挑戰與優勢:這對開發者來說可能具挑戰性,但能提高交易處理效率,並確保交易在多個處理器上平行化運行,提升網絡性能。
  2. 標頭(Header)
    • 功能描述:標頭包括對帳戶地址列表的引用,並指出哪些帳戶需要簽署交易,從而確保交易簽署與驗證過程的安全性與準確性。
    • 技術實現:標頭還包括簽名數量限制和其他安全性參數,這些參數確保即使在高並發環境中,交易也能快速且準確地被驗證。
  3. 最近區塊哈希(Recent Blockhash)
    • 防止重複與過期交易:每筆交易都必須包含一個最近的區塊哈希,這用於防止交易重複提交或過期無法執行。這個區塊哈希在 151 個區塊(約 1 分鐘)後過期,保證了交易的時效性。
    • 實際應用:RPC 節點通常每 2 秒重試一次,直到交易被最終確認或區塊哈希過期為止。這一機制有效防止了重複提交並阻止過期交易的執行。
  4. 指令(Instructions)
    • 核心操作:指令是交易的核心部分,每個指令代表一個具體操作,如轉帳、代幣鑄造、帳戶創建等。指令包含要執行的程式、所需的帳戶,以及執行指令所需的數據。
    • 多指令支持:Solana 允許一個交易中包含多個指令,這意味著可以通過單一交易完成多個操作,從而減少網路負載並提高處理效率。
    • 計算單位(Compute Units, CUs):每個指令的複雜度由計算單位來衡量。Solana 對每筆交易的總計算單位有上限,防止過於複雜的交易消耗過多資源。開發者需要謹慎設計交易,以確保其總計算單位不會超出網路限制。

3.2 示例代碼:組裝交易與指令

以下 TypeScript 代碼展示如何組裝一筆交易並將其發送到 Solana 區塊鏈:

import {
  Connection,
  PublicKey,
  Transaction,
  SystemProgram,
  sendAndConfirmTransaction
} from "@solana/web3.js";
import { useAnchorWallet, useConnection } from "@solana/wallet-adapter-react";

// 建立到 Solana 網路的連接
const { connection } = useConnection();
// 取得互動用戶的地址
const wallet = useAnchorWallet();
 
const provider = new AnchorProvider(connection, wallet, {});
setProvider(provider);

// 定義帳戶和參數
const fromPubkey = wallet.publicKey;
const toPubkey = new PublicKey("RecipientPublicKeyHere");
const lamports = 1000000; // 1 SOL = 1e9 lamports

// 創建一個轉帳指令
const instruction = SystemProgram.transfer({
  fromPubkey,
  toPubkey,
  lamports,
});

// 組裝交易並添加指令 (可以在CUs未達上限時,持續添加 instruction)
const transaction = new Transaction().add(instruction);

// 設置最近區塊哈希
transaction.recentBlockhash = (await connection.getRecentBlockhash()).blockhash;

// 設置交易的簽名者
transaction.feePayer = fromPubkey;

// 簽署並發送交易
const transactionSignature = await connection.sendTransaction(transaction, [
  wallet.payer
]);

這段代碼展示了一筆簡單的轉帳交易,涵蓋了交易的組裝、簽署和發送的基本流程。

4. Solana 交易詳解:費用結構與交易執行

在理解了 Solana 的公私鑰系統、錢包管理、帳戶類別以及交易的打包和簽署過程後,接下來將深入探討交易的費用結構、執行過程以及可能出現的交易錯誤。

4.1. 交易的限制與費用結構

在 Solana 區塊鏈上,每筆交易的指令數量首先受到交易大小的限制,最大可達 1,232 字節。此外,交易中可引用的帳戶數量也有限制。交易的複雜度則受到計算單位 (CUs) 的限制,CUs 用來量化處理交易時所消耗的計算資源。

交易費用結構

SOL 的最小單位稱為 "lamport",相當於 1 SOL 的十億分之一,類似於比特幣中的 satoshi。執行交易的費用由兩部分組成:

  • 基本費用:每個簽名固定收取 5000 lamports,無論交易的複雜度如何,通常每筆交易只需一次簽名。
  • 優先費用:這是額外的費用,用於在區塊空間需求高時提高交易被驗證節點優先處理的可能性。優先費用以 micro-lamports(即 lamport 的百萬分之一)計算,按每個計算單位(CU)的價格來決定。

費用計算公式為:

交易總費用 = 優先費用 + 基本費用
優先費用 = 計算單位價格(micro-lamports)× CU limit

目前,所有交易相關費用的 50% 會被銷毀,永久性地將這部分 SOL 從流通中移除,其餘 50% 則分配給區塊生產者。未來的變更提案(SIMD 96)將允許 100% 的優先費用分配給區塊生產者,而基本費用保持不變。

4.2. 交易的執行過程

當使用者連接錢包後,應用程式 (Dapp) 可以讀取使用者的公鑰並開始構建交易。這個過程通常分為以下幾個步驟:

  • 交易消息構建 (Dapp):根據使用者的操作,如代幣交換或資產轉移,Dapp 會構建交易消息,設置包括交易對象的帳戶、公鑰、交易金額、滑點限制等參數。
  • 錢包簽署交易 (Dapp→Wallet):當交易消息準備就緒後,Dapp 會將其發送到使用者的錢包進行簽署。此時,錢包會彈出窗口讓使用者確認並簽署交易。簽署過程中,私鑰保持安全狀態,確保其不會離開錢包。
  • 交易提交與確認 (Wallet→Dapp→Node):簽署完成後,錢包將已簽署的交易返回給 Dapp。Dapp 隨後將交易提交給 RPC 提供者,RPC 作為中介,將交易轉發給 Solana 區塊鏈的驗證節點進行處理並等待確認。

4.3. 錯誤與故障分析

在 Solana 上,術語“交易失敗”容易引起誤解。這些交易會產生費用,並且已由運行時系統按照簽署者的意圖成功執行。所謂的“失敗”,往往是由於交易本身的邏輯要求而造成的結果。例如,如果交易超出了使用者設置的滑點限制,系統會自動使該交易“失敗”,以保護使用者的資產。

超過 80% 的“失敗”交易源於錯誤代碼 0x1771,即超出滑點限制的錯誤。值得注意的是,這些交易中有 95% 是由僅佔活躍 Solana 地址 0.1% 的自動化機器人提交的,這些機器人主要試圖利用時間敏感的價格套利機會。


Takeaways:

T1. 簡化的公私鑰系統

Solana 直接使用公鑰作為帳戶地址,簡化了地址生成過程,降低計算複雜性,並提升交易處理效率,這使得錢包管理和 DApp 開發更加便捷。

T2. 靈活的帳戶系統

Solana 支援多樣化的帳戶類型,適用於複雜的智能合約。透過租金機制管理鏈上資源,減少帳戶狀態膨脹。交易時提前指定參與帳戶,避免交易衝突,實現平行化處理,進一步提升網絡效能,為 Web3 應用提供更高效率。

T3. 合理的交易費用結構與計算單位限制

Solana 的交易費用由基本費和優先費組成,計算單位(CUs)限制確保資源消耗可控,使其在處理大量交易時保持穩定性能。

原文連結:深入探討 Solana - User