0. レビュー
- Solanaエコシステムの保護 (1) — Hello Solana
- Solanaエコシステムの保護 (2) — プログラム間の呼び出し
- Solanaエコシステムの保護 (3) — プログラムのアップグレード
- Solanaエコシステムの保護 (4) — アカウント検証
- Solanaエコシステムの保護 (5) — マルチシグ
1. 概要
前回の投稿では、マルチシグの実装について説明しました。しかし、その実装は、複数のユーザーからの署名をオフチェーンで同時に収集できることを前提としていました。本稿では、ユーザーが完全にオンチェーンで署名できる、より一般的なマルチシグプログラムを紹介します。
2. テストプログラムの設計
マルチシグプログラムは、有効な署名者が提案者に個別に署名することを許可し、十分な署名が集まったと承認されたら、誰でも提案を実行できます。テストコードはすべてこちらで見つけることができます。
3. コードレビュー
このプログラムでは、TransactionAccountとTransactionという2つの構造体が追加されています。構造体TransactionAccountは、提案されたトランザクションで使用されるアカウント情報を記録するために設計されています。構造体Transactionは、提案の情報を記録するために使用されます。属性signersは、有効な署名の数を記録するために使用されることに注意してください。did_executeとis_initializedは、実行と初期化が一度だけ行われることを保証します。

プログラムは5つの異なる命令を提供します。命令AllocatePDAは、一意のPDAアカウントを作成し、それをmultisigアカウントとして使用することを目的としています。これは、すべての有効な署名者の情報を記録します。命令InitializeMultisigでは、命令を実行するために必要な署名の数と、有効な署名者の公開鍵の配列を設定します。命令CreateTransactionは、提案を作成するために使用され、署名者は命令approveを介して提案を承認できます。承認の数がmultisigで設定されたしきい値に達すると、命令ExecuteTransactionを呼び出してトランザクションを実行できます。

提案を送信するために、ユーザーは命令createTransaction()を呼び出すことができます。これは3つのアカウントを受け取ります。1つは作成されたtransactionアカウントで、残りの2つはターゲットトランザクションによって使用されます。悪意のあるユーザーによるアカウントの再初期化を防ぐために、属性is_initializedをチェックします(161〜163行目)。その後、構造体TransactionAccountを指定されたデータで初期化し、データアカウントにシリアライズします(188行目)。

関数Approve()では、まずTransactionアカウントとmultisigアカウントがプログラムによって所有されているかを確認します。他のプログラムから作成されたアカウントは、チェックがない場合、悪意のあるユーザーによって使用される可能性があることに注意してください。次に、署名者の公開鍵をmultisigアカウントに格納されているキーと照合します。一致した場合、署名は検証され、対応する値がtrueに変更されます。

命令ExecuteTransaction()では、有効な署名の数を数えます。署名の数がしきい値に達しない場合、プログラムはロールバックされます。

その後、ターゲットのInstructionを指定された属性で初期化し、関数invoke_signed()を介してターゲットプログラムの命令を呼び出します。提案が繰り返し実行されるのを防ぐために、属性did_executeをtrueに設定します。

プログラムをテストネットにデプロイしました。以下のリンクで見つけることができます。
https://explorer.solana.com/address/CPzn7ptnJntjUB4NGKqQGRai8NFLNwFaspmJ7nEGbMHe?cluster=testnet
4. トランザクションの送信
デプロイ後、まずmultisigアカウントを作成し、configアカウントを初期化する際にmultisigアカウントを管理者として設定します。関連するトランザクションを以下に示します。順序は、createMultisig()(General-Multisig内)-> PrivilegeOwnerプログラムのデプロイ -> Allocate()(PrivligeOwner内)-> InitializeConfig()(PrivligeOwner内)です。
https://explorer.solana.com/tx/2vXHmwbCsARstx8wi4eLACbrb6PuZZMktsqU8VnJLp64fvrpaE62QSTn5QLczzxnTvxRLWMSR3dKLGYXZasGMn69?cluster=testnet
https://explorer.solana.com/tx/2EMq9y6HNnXq1n2XsqrBkJd8RGL27PCj5T4JyJ71ZoA3ipUggT6dF6S6uDv4TtxGGKk8BmiAJHS7BFRgZqWjkWVb?cluster=testnet
https://explorer.solana.com/tx/3UhXKsTubUiPqRtLyNYskxvbyrTKHsbeptxuAfJQ348AU4b8gQET2HAMaqxwud6Wo3MKTYHWBneqa9z2WhCpwV6t?cluster=testnet
https://explorer.solana.com/tx/5NA7Yw23uRf48Q3BYM21dtS7gD9YMECij43ZaRLMPe7svt3bsv2TPWwbCRP5akDmttjLEHWZtpqrZrVLNr9QLyJY?cluster=testnet
次に、命令InitializeMultisig()を呼び出します。ここでは、multisigアカウントと3つの有効な署名者のアカウントの4つを渡します。mの値を2に設定します。これは、3人の署名者のうち2人の署名があれば、特権関数を実行できることを意味します。

関数CreateTransaction()では、作成されたTransactionアカウント、ターゲットプログラム(PrivilegeOwner)の公開鍵、およびconfigアカウントの公開鍵を渡します(306〜307行目)。さらに、_dataを3に設定する必要があります。これは、PrivilegeOwnerプログラムの命令unlock()に対応します。

最初のテストでは、1人の署名者のみが作成された提案を承認します。この場合、収集された署名が限られているため、ExecuteTransaction()は失敗します。コンソールには次の出力が表示されます。

別の署名者が作成された提案を承認し、ExecuteTransaction()を呼び出します。合計署名数がしきい値に達したため、提案は正常に実行されます。
https://explorer.solana.com/tx/55Qy93RxybsT7c5v9AFgN8Dt1h3AVJfbsosLbstYVB6paY1wmau5sdtLfGpfryXnZTsBNRauvwLSmAu2nABFxVCe?cluster=testnet
https://explorer.solana.com/tx/4XF4MUhL4oftkDt4sn7NoREmGqcDMVP6HGypvJQMtiAbBKiCuy4B98vhQKtvm4mPv7SprrDDVsiwgb6pNwgJcTwz?cluster=testnet
4. まとめ
本稿では、Solanaにおけるマルチシグの一般的な実装を紹介しました。この実装はPDAの機能を利用しており、有効な署名の数が要件を満たすと、プログラムが自動的にトランザクションにPDAで署名できるようになります。引き続き、今後の投稿でさらに詳しく説明していきます。
このシリーズの他の記事を読む:
- Solanaエコシステムの保護 (1) — Hello Solana
- Solanaエコシステムの保護 (2) — プログラム間の呼び出し
- Solanaエコシステムの保護 (3) — プログラムのアップグレード
- Solanaエコシステムの保護 (4) — アカウント検証
- Solanaエコシステムの保護 (5) — マルチシグ
- Solanaエコシステムの保護 (7) — 型の混同
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



