Solanaエコシステムをセキュアに保つ (1) — こんにちはSolana

Solanaエコシステムをセキュアに保つ (1) — こんにちはSolana

1. はじめに

Solanaは、Rust、C++、Cなどのさまざまな言語でプログラム(スマートコントラクト)を開発できる、高性能でパーミッションレスなレイヤー1ブロックチェーンシステムです。Tower BFT(Byzantine Fault Tolerant)の助けを借りて、毎秒数千トランザクションを処理できます。Solanaのコアイノベーションの1つはProof of History(PoH)であり、これはネットワーク上でコンセンサスより前に機能する、グローバルに利用可能でパーミッションレスな時間ソースです。PoHについては、後で詳しく説明します。

2. 私たちのミッション

BlockSecは、「DAppエコシステムの保護」をミッションとするブロックチェーンセキュリティ企業です。そのため、コントラクト監査サービスを提供するだけでなく、コミュニティ全体のために安全なスマートコントラクトの記述方法に関する提案も行っています。Solanaの人気、高性能、優れた設計を考慮して、このシリーズではSolana上のRustにおけるスマートコントラクトのセキュリティに焦点を当てます。

3. Hello Solana

セキュリティの観点からSolanaスマートコントラクトを議論する前に、まずSolanaスマートコントラクトの記述、コンパイル、デプロイ方法を知る必要があります。ここでは、Hello Worldを例として説明します。

3.1 コードレビュー

Solanaでは、スマートコントラクトはプログラムと呼ばれます。Hello Worldプログラムは、クライアントによって呼び出されたターゲットアカウント(プログラムが所有)の呼び出し回数を記録するカウンターを維持し、この番号を出力として表示することを目的としています。

それでは、コントラクト全体を見ていきましょう。

1行目から9行目では、useキーワードを使用して多くのライブラリを明示的にスコープに取り込みます。

12行目では、[derive(BorshSerialize, BorshDeserialize, Debug)]を使用して、13行目から16行目まで定義されている構造体GreetingAccountに渡されるパラメータをシリアライズおよびデシリアライズします。この構造体は、u32型の公開メンバーcounterを含みます。その後、コメントで示されているように、19行目はプログラムのエントリポイントであるprocess_instruction関数をエクスポートします。

process_instruction関数は、3つのパラメータ(program_idaccounts_instruction_data)を受け取ります。program_idはデプロイされたプログラムの公開鍵(つまりアドレス)であり、accountsには挨拶するアカウントが含まれます。_instruction_dataは空であり、使用されません。

Solanaのプログラムとアカウントの詳細については、Solanaドキュメントを参照してください。

27行目では、挨拶メッセージが表示されます。30行目から33行目では、アカウントが反復処理され、挨拶する特定のアカウントが抽出されます。その後、アカウントの所有者がチェックされ、プログラムがアカウントに書き込めることを保証するためにprogram_idと一致する必要があります。最後に、greeting_accounttry_from_sliceで抽出され、カウンターが1つ増やされます。

3.2 プログラムのコンパイル

プログラムをコンパイルするには、以下のコマンドでSolana CLIをインストールする必要があります。

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

Solana CLIが正常にインストールされたことを確認するには、以下のコマンドでバージョンを確認できます。

solana --version

RustNodeJSも必要であることに注意してください。

プログラムをコンパイルするには、次のコマンドを使用できます。

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

コンパイルされたプログラムは、--bpf-out-dirで指定されたディレクトリの下に、helloworld.soという名前で生成されます。

3.3 コントラクトのデプロイ

コンパイルされたプログラムをSolanaにデプロイするには、まずクラスターを選択する必要があります。Solanaには、mainnet、testnet、devnet、localnetの4つの異なるクラスターがあります。この投稿では、デモンストレーションのためにdevnetにのみコンパイルされたプログラムをデプロイします。

以下のコマンドを使用してクラスターを指定します。

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

その後、デプロイ用のウォレットを生成する必要があります。solana-keygen new --forceはウォレットの生成に役立ちます。詳細については、Solana Docを確認してください。

新しく作成されたアカウントにはトランザクション手数料を支払うための残高がないため、以下のコマンドで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関数が呼び出されてターゲットアカウントに挨拶します。トランザクションは1つの命令で構成されます。この命令は、1つのアカウントを含むkeysを受け取ります。アカウントの公開鍵(つまりgreetedPubkey)は、挨拶するターゲットアカウントです。このアカウントはストレージに使用され、署名者ではないことに注意してください。この場合、isSigner属性はfalseであり、isWritabletrueです。programIdgreetedPubkeyの所有者であり、デプロイされたコントラクトのアドレスでもあります。dataは空であり、このトランザクションでは使用されないことに注意してください。208行目では、sendAndConfirmTransaction関数が呼び出され、トランザクションがクラスターに送信されます。

トランザクションの詳細を**こちら**で表示できます。

4. 結論

この記事では、Solanaの背景を簡単に紹介し、サンプルプロジェクト(つまりHello World)を説明しました。Solanaでのプログラムのデプロイ方法と、クライアントを使用してオンチェーンプログラムと対話する方法を学びました。このシリーズでは、今後も記事を継続的に公開していく予定ですので、ぜひブログをフォローしてください。

このシリーズの他の記事を読む:

Sign up for the latest updates
Weekly Web3 Security Incident Roundup | Feb 9 – Feb 15, 2026

Weekly Web3 Security Incident Roundup | Feb 9 – Feb 15, 2026

During the week of February 9 to February 15, 2026, three blockchain security incidents were reported with total losses of ~$657K. All incidents occurred on the BNB Smart Chain and involved flawed business logic in DeFi token contracts. The primary causes included an unchecked balance withdrawal from an intermediary contract that allowed donation-based inflation of a liquidity addition targeted by a sandwich attack, a post-swap deflationary clawback that returned sold tokens to the caller while draining pool reserves to create a repeatable price-manipulation primitive, and a token transfer override that burned tokens directly from a Uniswap V2 pair's balance and force-synced reserves within the same transaction to artificially inflate the token price.

Top 10 "Awesome" Security Incidents in 2025

Top 10 "Awesome" Security Incidents in 2025

To help the community learn from what happened, BlockSec selected ten incidents that stood out most this year. These cases were chosen not only for the scale of loss, but also for the distinct techniques involved, the unexpected twists in execution, and the new or underexplored attack surfaces they revealed.

#10 Panoptic Incident: XOR Linearity Breaks the Position Fingerprint Scheme

#10 Panoptic Incident: XOR Linearity Breaks the Position Fingerprint Scheme

On August 29, 2025, Panoptic disclosed a Cantina bounty finding and confirmed that, with support from Cantina and Seal911, it executed a rescue operation on August 25 to secure roughly $400K in funds. The issue stemmed from a flaw in Panoptic’s position fingerprint calculation algorithm, which could have enabled incorrect position identification and downstream fund risk.