返回部落格

保護 Solana 生態系統 (1) — Hello Solana

2022年3月9日
閱讀約 5 分鐘

1. 簡介

Solana 是一個高效能、無需許可的 Layer 1 區塊鏈系統,支援使用不同語言(如 Rust、C++ 和 C)開發程式(智能合約)。藉助 Tower BFT(拜占庭容錯)共識機制,它能夠每秒處理數千筆交易。Solana 的核心創新之一是歷史證明(Proof of History,簡稱 PoH),這是一種在網路中全域可用、無需許可的時間來源,其運作優先於共識機制。我們將在未來更詳細地討論 PoH。

2. 我們的使命

BlockSec 是一家區塊鏈安全公司,將「保護 DApp 生態系統」視為其使命。因此,我們不僅提供合約審計服務,還為整個社群提供關於如何編寫安全智能合約的建議。考慮到 Solana 的受歡迎程度、高效能以及優良的設計,本系列將專注於 Solana 上 Rust 智能合約的安全性。

3. Hello Solana

在我們從安全角度探討 Solana 智能合約之前,首先需要了解如何編寫、編譯和部署 Solana 智能合約。這裡我們以 Hello World 作為示範範例。

3.1 程式碼審查

在 Solana 中,智能合約被稱為程式 (program)。Hello World 程式旨在維護一個計數器,記錄目標帳戶(由程式擁有)被客戶端呼叫的次數,並將此數字作為輸出列印出來。

現在讓我們來瀏覽整個合約。

從第 1 行到第 9 行,透過 use 關鍵字顯式引入了許多函式庫。

在第 12 行,[derive(BorshSerialize, BorshDeserialize, Debug)] 被用於序列化和反序列化傳遞給 GreetingAccount 結構體的參數,該結構體定義在第 13 行到第 16 行之間。該結構體包含一個名為 counter 的公開成員,型別為 u32。隨後,如註釋所述,第 19 行導出了程式的入口點,即 process_instruction 函式。

process_instruction 函式接受三個參數(即 program_id、accounts 和 _instruction_data)。請注意,program_id 是已部署程式的公鑰(即地址),而 accounts 包含了用於問候的帳戶。_instruction_data 為空且未被使用。

若要了解更多關於 Solana 中的程式與帳戶資訊,請參閱 Solana 文件。

在第 27 行,列印了一條問候訊息。從第 30 行到第 33 行,程式會迭代帳戶並提取出指定的問候帳戶。之後,會檢查該帳戶的所有者,必須等於 program_id 以確保程式能夠寫入該帳戶。最後,透過 try_from_slice 提取 greeting_account,並將計數器加 1。

3.2 編譯程式

要編譯程式,我們需要使用以下指令安裝 Solana CLI。

sh -c "$(curl -sSfL https://release.solana.com/v1.9.9/install)"

為確認 Solana CLI 安裝成功,我們可以使用以下指令檢查版本。

solana --version

請注意,還需要安裝 Rust 和 NodeJS。

要編譯程式,我們可以使用以下指令。

cargo build-bpf --manifest-path=./src/program-rust/Cargo.toml --bpf-out-dir=dist/program

編譯後的程式將生成在 --bpf-out-dir 指定的目錄下,名稱為 helloworld.so。

3.3 部署合約

要在 Solana 上部署編譯好的程式,我們首先需要選擇一個叢集 (cluster)。Solana 有四種不同的叢集,分別是 mainnet、testnet、devnet 和 localnet。在本文中,我們僅於 devnet 部署編譯好的程式進行示範。

我們使用以下指令指定叢集。

solana config set --url https://api.devnet.solana.com

之後,我們需要為部署生成錢包。solana-keygen new --force 有助於生成錢包。更多資訊,請查看 Solana 文件。

由於新創建的帳戶沒有餘額來支付交易費用,我們透過以下指令空投 1 SOL。

solana airdrop 1 <YourPublicKey> --url https://api.devnet.solana.com

現在,我們準備好部署合約了。

solana program deploy dist/program/helloworld.so

使用者可以在 Devnet Explorer 查看程式與交易。在此演示中,您可以透過此連結找到已部署的程式。

3.4 發送交易

建議編寫腳本(稱為客戶端)來在 Solana 上發送交易。幸運的是,Solana 提供了 範例程式碼。要執行客戶端,我們首先需要安裝客戶端依賴庫。

npm install 

安裝完成後,我們使用以下指令執行 main.ts 檔案中的 main 函式。

npm run start 

在 main 函式中,客戶端首先透過 establishConnection() 函式建立與指定叢集(即 Devnet)的連線,透過 establishPayer 檢查負責支付交易費用的付款人,並透過 checkProgram 驗證程式和問候帳戶是否存在。請注意,如果所需的帳戶不存在,將會透過發送交易來創建它。在我們的演示中,帳戶是在此交易中創建的。

當一切準備就緒,會呼叫 sayHello 函式來向目標帳戶發送問候。該交易包含一條指令。此指令接收包含一個帳戶的 keys。該帳戶的公鑰(即 greetedPubkey)是問候的目標帳戶。請注意,此帳戶用於儲存資料,並非簽名者。在這種情況下,isSigner 屬性為 false,而 isWritable 為 true。programId 是 greetedPubkey 的所有者,也是已部署合約的地址。請注意,data 為空,不會在此交易中使用。在第 208 行,呼叫了 sendAndConfirmTransaction 函式,交易隨即被發送至叢集。

您可以點擊 此處 查看詳細的交易內容。

4. 結論

在本文中,我們簡要介紹了 Solana 的背景,並瀏覽了範例專案(即 Hello World)。我們學習了如何部署 Solana 程式以及如何使用客戶端與鏈上程式互動。請持續關注我們的部落格,我們將會持續發佈該系列的更多文章。

閱讀本系列其他文章:

訂閱最新動態
Bitget 3.875億美元鏈下違規事件:超越金鑰與合約的範疇
Security Insights

Bitget 3.875億美元鏈下違規事件:超越金鑰與合約的範疇

2026年9月24日,攻擊者利用第三方安全產品漏洞,獲取內部憑證並偽造提款指令,導致約3.875億美元從Bitget部分營運錢包(涵蓋Ethereum、其他EVM網絡、XRP Ledger、Zcash及TRON)轉出;私鑰及冷錢包未受影響。本文深入梳理事件路徑與資金流向,分析快速轉換為原生資產及生態恢復應對,提出機構縱深防禦框架,並說明授權區塊鏈滲透測試如何驗證跨層假設。

約1130萬美元損失:Multicall Router、Nostra|BlockSec Weekly
Security Insights

約1130萬美元損失:Multicall Router、Nostra|BlockSec Weekly

本報告涵蓋2026/09/14至2026/09/20期間,探討以太坊與Starknet上兩起合計損失約1130萬美元的安全事件。較大一起中,多重呼叫路由器將自身位址接受為分派目標,導致巢狀呼叫以路由器自身已授權身分而非外部呼叫者身分進入Safe錢包的Gateway模組,約2900枚`aEthrsETH`被轉出至攻擊者建立的Uniswap v4池。在Starknet上,Nostra預言機整合僅要求最少一個聚合來源,當三個設定價格來源中僅兩個達成聚合時,操縱的薄池報價與正常報價平均後將`NSTR`估值約49.52美元,支撐約350萬美元以高估抵押品借貸。

损失約3.2億美元:Liquid Network與Symbiosis遭攻擊事件 | BlockSec
Security Insights

损失約3.2億美元:Liquid Network與Symbiosis遭攻擊事件 | BlockSec

本報告涵蓋2026/09/07至2026/09/13,探討兩起造成約3.2億美元損失的安全事件,包括前份報告未提及、發生於2026/09/06的Liquid Network漏洞事件。較大者為該Liquid Network漏洞:Elements中的rangeproof驗證快取藉由雜湊四個欄位(其中兩個長度可變)串接而成金鑰,且未標示欄位邊界,導致某輸出的驗證結果被錯誤套用至另一個未經檢驗證明的輸出,使攻擊者得以憑空創造4,000枚無擔保L-BTC,並將幾乎全數兌回比特幣。在橫跨BNB Smart Chain、Ethereum與Rootstock的Symbiosis跨鏈橋比特幣路徑中,讀取比特幣存款的鏈下程式碼從存款人可自行控制的欄位取得其身份,並在未檢查手續費是否為負值的情況下自存款中扣除,使330聰的存款鑄造出`46,116,860,184.27388234 syBTC`;其須賣出所經之資金池僅有11.26 syBTC,致使流動性提供者與用戶損失約9.97 BTC(約77萬美元)。