Back to Blog

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

March 9, 2022

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
Drift Protocol Incident: Multisig Governance Compromise via Durable Nonce Exploitation
Security Insights

Drift Protocol Incident: Multisig Governance Compromise via Durable Nonce Exploitation

On April 1, 2026 (UTC), Drift Protocol on Solana suffered a $285.3M loss after an attacker exploited Solana's durable nonce mechanism to delay the execution of phished multisig approvals, ultimately transferring administrative control of the protocol's 2-of-5 Squads governance with zero timelock. With full admin privileges, the attacker created a malicious collateral market (CVT), inflated its oracle price, relaxed withdrawal protections, and drained USDC, JLP, SOL, cbBTC, and other assets through 31 rapid withdrawals in approximately 12 minutes. This incident highlights how durable nonce-based delayed execution can decouple signer intent from on-chain execution, bypassing the temporal assumptions that multisig security implicitly relies on.

Weekly Web3 Security Incident Roundup | Mar 23 – Mar 29, 2026
Security Insights

Weekly Web3 Security Incident Roundup | Mar 23 – Mar 29, 2026

This BlockSec weekly security report covers eight DeFi attack incidents detected between March 23 and March 29, 2026, across Ethereum and BNB Chain, with total estimated losses of approximately $1.53M. Incidents include a $679K flawed burn mechanism exploit on the BCE token, a $512K spot-price manipulation attack on Cyrus Finance's PancakeSwap V3 liquidity withdrawal, a $133.5K flash-loan-driven referral reward manipulation on a TUR staking contract, and multiple integer overflow, reentrancy, and accounting error vulnerabilities in DeFi protocols. The report provides detailed vulnerability analysis and attack transaction breakdowns for each incident.

Newsletter -  March 2026
Security Insights

Newsletter - March 2026

In March 2026, the DeFi ecosystem experienced three major security incidents. Resolv Protocol lost ~$80M due to compromised privileged infrastructure keys, BitcoinReserveOffering suffered ~$2.7M from a double-minting logic flaw, and Venus Protocol incurred ~$2.15M following a donation attack combined with market manipulation.