Solanaエコシステムをセキュアにする(6)―マルチシグ2

Solanaにおけるマルチシグの一般的な実装について解説。オンチェーンでのトランザクション署名、コードレビュー、デプロイの詳細を紹介します。

Solanaエコシステムをセキュアにする(6)―マルチシグ2

0. レビュー

1. 概要

前回の投稿では、マルチシグの実装について説明しました。しかし、その実装は、複数のユーザーからの署名をオフチェーンで同時に収集できることを前提としていました。本稿では、ユーザーが完全にオンチェーンで署名できる、より汎用的なマルチシグプログラムを紹介します。

2. テストプログラムの設計

マルチシグプログラムは、有効な署名者が提案者に個別に署名することを許可し、十分な署名が集まったら誰でも提案を実行できます。テストコードはすべてこちらで見ることができます。

3. コードレビュー

このプログラムでは、TransactionAccountTransactionという2つの構造体を追加しています。構造体TransactionAccountは、提案されたトランザクションで使用されるアカウント情報を記録するために設計されています。構造体Transactionは、提案の情報を記録するために使用されます。属性signersは、有効な署名の数を記録するために使用されることに注意してください。did_executeis_initializedは、実行と初期化が一度だけ行われることを保証します。

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

提案を送信するために、ユーザーは命令createTransaction()を呼び出すことができます。これには3つのアカウントが必要です。作成された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アカウントをconfigアカウントの管理者として設定します。関連するトランザクションを以下に示します。順序は createMultisig() (General-Multisig内) -> PriviligeOwnerプログラムのデプロイ -> 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()を呼び出します。ここでは4つのアカウント、つまりmultisigアカウントと3つの有効な署名者のアカウントを渡します。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によってトランザクションに自動的に署名できるようにします。引き続き、今後の投稿でさらに多くの情報をお伝えします。

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

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