Back to Blog

Solanaエコシステムの保護 (3) — プログラムのアップグレード

2022年3月27日
5 min read

0. レビュー

1. 概要

前回のブログでは、invoke関数とinvoke_signed関数を介したクロスプログラム呼び出しの実装方法を紹介しました。本稿では、もう一つの基本的なトピックであるプログラムのアップグレードについて解説します。

2. アップグレード可能なプログラムのデプロイ

デフォルトでは、Solanaでデプロイされるすべてのプログラムは、アップグレード可能なBPFLoaderUpgradeableローダーでデプロイされます。これに加えて、Solanaはデプロイされたプログラムが変更不能であることを保証するために--finalオプションを提供しています。この場合、プログラムのデプロイにはBPFLoader2ローダーが使用されます。デプロイ後、プログラムはアップグレードできなくなります。

BPFLoaderUpgradeableローダープログラムは、プログラムアカウント、プログラムデータアカウント、バッファアカウントの3種類のアカウントを管理します。デプロイプロセスでは、まずバッファアカウントが作成されます。その後、Solana CLIはターゲットプログラムのバイトコードをロードし、それをバッファアカウントに書き込みます。最終的に、バッファアカウントに格納されたバイトコードはプログラムデータアカウントにコピーされます。

したがって、バッファアカウントはアップグレード可能なBPFローダーがデプロイプロセス中にバイトコードを一時的に格納するために使用され、プログラムデータアカウントはプログラムの実際のデータを格納し、プログラムアカウントは対応するプログラムデータアカウントを指すプロキシとして機能します。

以下に、プログラムをアップグレードする方法についてのいくつかのサンプルを示します。本稿で使用されているコードはすべてこちらで見ることができます。

2.1 コードレビュー (Rectangle_Area)

このサンプルコントラクトでは、width、height、areaの3つの属性を持つRectangleという名前の構造体を13行目から17行目に定義しています。また、Rectangleのarea()関数も定義しています。area()関数は、widthとheightを使用して長方形の面積を計算するためのものです。

process_instruction()関数では、まずunpack_u32()関数を使用して、命令データから長方形のwidthとheightを抽出します(45行目〜46行目)。51行目で、長方形のデータを格納するために使用されるアカウントが抽出されます。59行目で、try_from_slice_unchecked()関数がアカウントのデータをRectangle構造体の型でデシリアライズします。次に、データを構造体の対応するフィールドに割り当て、面積の値を計算します(61行目〜63行目)。最後のステップは、データをシリアライズしてデータアカウントに書き戻すことです。

デプロイされたプログラムは、以下のリンクで見ることができます。

https://explorer.solana.com/address/84mMqHRTQT6b2vfsD7XRxVKA3XMd7xoEXFdF6pLNw8y?cluster=testnet

2.2 トランザクションの送信

クライアント側では、まずデータ格納用のアカウントを作成するトランザクションを送信します。十分なサイズを確保するために、スペースサイズを1,024バイトに設定します。

次に、長方形の面積を計算し、データアカウントに格納するためのトランザクションを送信します。

トランザクションは以下のリンクで見ることができます。

https://explorer.solana.com/tx/4PybjXGRpuPKpak7FAz4BKMbcQCWmway69zAxtTnpFRuTTg7onyxW7agSe6ETx44iAGexbgnBUa8WdzdTTQSawJ3?cluster=testnet

3. アップグレード

ここで、プログラムに新しい関数を追加して、長方形の周囲長を計算できるようにしたいとします。

更新されたプロジェクトをコンパイルした後、以下のコマンドでオンチェーンのデプロイ済みプログラムをアップグレードします。

solana program deploy /path/to/program.so --program-id <PROGRAM_ID>

コントラクトは直接アップグレードでき、関連するトランザクションは以下で確認できます。

https://explorer.solana.com/tx/4Dm9v4zMiijKjQBhatx1D9xbV9PvMLdaonUWLaC2VwzkFvzdgorzbX5vsy4VQ7VxSUmqadftjiDzbyUmXgQchYmk?cluster=testnet

プログラムが正常にアップグレードされたことを確認するために、さらにトランザクションを送信します。結果は、関数が正常に機能していることを示しています。

関連するトランザクションは以下で見ることができます。

https://explorer.solana.com/tx/21c2G7kPVktAtdUFkH3QwGVi7orajRmy5PJo1UxX1mmAMU68eUkNuLzWYJRBaTzwGi5DxeocYjHfpWiU4hcSFtpQ?cluster=testnet

4. 再度アップグレード

今回は、計算された周囲長をデータアカウントに格納したいと思います。この場合、Rectangle構造体にperimeterという属性を1つ追加します(18行目)。

データアカウントの構造体が以前のものと異なるため、まずデータアカウントからデータを読み取る必要があります。元の構造体(つまりOldRectangle)を使用して格納されたデータをデシリアライズします。その後、関連する属性を新しい構造体(つまりCurrentRectangle)に割り当て、新しい属性(つまりperimeter)を初期化します。

最後に、周囲長の値を計算し、それをupdate_accountに割り当ててからaccount_dataにシリアライズします。

アップグレードのためのトランザクションは以下で見ることができます。

https://explorer.solana.com/tx/5J3oKxZXtCi755gD7pMnVh48AFvmeVzRLPgJiyNn8JFeCKx1xpAfJtsi34zjyYKJmnMk8LtC3bcwfFSP7H2gtj5o?cluster=testnet

アップグレード後、solana account <DataAccount>コマンドでアカウントに格納されているデータをチェックできます。属性が最初の32バイトに格納されていることがわかります。アップグレードプロセス全体が完了しました。

5. 結論

この記事では、Solanaでプログラムをアップグレードする方法について説明しました。詳細なプロセスを説明するために、さまざまな例を使用しました。引き続き、Solanaに関する記事を投稿していく予定です。

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


BlockSecについて

BlockSecは、2021年に世界的に著名なセキュリティ専門家グループによって設立された、先駆的なブロックチェーンセキュリティ企業です。当社は、Web3の世界のセキュリティと使いやすさを向上させ、その大規模な普及を促進することに尽力しています。この目的のため、BlockSecはスマートコントラクトとEVMチェーンのセキュリティ監査サービス、セキュリティ開発と脅威のプロアクティブなブロックのためのPhalconプラットフォーム、資金追跡と調査のためのMetaSleuthプラットフォーム、そしてWeb3ビルダーが仮想通貨の世界を効率的にサーフィンするためのMetaSuites拡張機能を提供しています。

これまでに、MetaMask、Uniswap Foundation、Compound、Forta、PancakeSwapなど、300を超える著名なクライアントにサービスを提供し、Matrix Partners、Vitalbridge Capital、Fenbushi Capitalなどの著名な投資家から2回の資金調達で数千万米ドルを獲得しています。

公式ウェブサイト:https://blocksec.com/ 公式Twitterアカウント:https://twitter.com/BlockSecTeam

Sign up for the latest updates
約387万 USDの損失:Autheo NetworkとUNCXへのハッキング | BlockSecウィークリー
Security Insights

約387万 USDの損失:Autheo NetworkとUNCXへのハッキング | BlockSecウィークリー

この週次レポートでは、2026年10月12日–2026年10月18日に発生した3件のセキュリティインシデントを取り上げます。推定損失額の合計は約387万 USDです。Autheo Networkでは秘密鍵の侵害により約176万 USD、Qubic Walletでは脆弱なシード生成により約130万 USDの損失が発生しました。また、Ethereum、BNB Chain、Base、Robinhood Chain上のUNCX NetworkのSmart Token Vesting V2コントラクトでは、会計処理上の誤りにより約80.7万 USDの損失が発生しました。重点的に取り上げるUNCXの分析では、シェア総数の計算に欠陥があり、異なるトークン対シェア比率で作成されたベスティングのトランシェが混同された結果、共通プールからの過剰な引き出しが可能になった仕組みを説明します。

SEAL認証とは?暗号資産における運用セキュリティの保証
Security Insights

SEAL認証とは?暗号資産における運用セキュリティの保証

SEAL認証は、合意された範囲内で暗号資産分野の運用セキュリティについて独立した保証を提供します。その6つのモジュール、証拠資料の要件、認証の限界、BlockSecの評価プロセスを解説します。

約54万2,000ドルの損失:MakerDaoBotへの攻撃 | BlockSec週間ニュース
Security Insights

約54万2,000ドルの損失:MakerDaoBotへの攻撃 | BlockSec週間ニュース

本レポートは2026/10/05~10/11にEthereumで発生したセキュリティ事故1件を扱う。推定損失は約54.2万ドル。攻撃コントラクトは悪意あるアダプターを展開し、アクセス制御のないMakerDaoBot関数に渡して、ボット内部のMakerDAO残高への操作権限を付与させた。アダプターは旧ETH-Aオークション4件を決済し、ETH-A担保200単位をWETHに変換。攻撃コントラクトがWETHをETHに戻し、攻撃者へ200 ETHを送金した。