# Rustスマートコントラクトアップグレード方案详解スマートコントラクト本質的にはプログラムであり、欠陥が存在することは避けられません。大量のテストと監査を経ても、脆弱性が現れる可能性があります。一度攻撃者に利用されると、ユーザーの資産に損失をもたらし、深刻な結果を引き起こす可能性があります。そのため、コントラクトのアップグレード可能性は非常に重要であり、主に脆弱性の修正や新機能の追加に使用されます。本記事では、Rustコントラクトの一般的なアップグレード方法について紹介します。## イーサリアム契約アップグレード案イーサリアムのスマートコントラクトは不変性を持ち、デプロイ後に変更することはできません。脆弱性を修正したり新機能を追加するための一般的な方法は、新しいコントラクトを再デプロイすることです。しかし、これによりコントラクトアドレスが変更され、そのコントラクトを使用するすべてのDAppを修正する必要があります。さらに、旧コントラクトにある状態データを移行する必要があり、作業量が多く、ミスが起こりやすいです。これを実現するために、通常はデータとロジックを分離したアーキテクチャを採用します: データはステートコントラクトに保存され、すべてのロジックは別のロジックコントラクトで実装されます。アップグレード時には、ロジックコントラクトのみを更新し、ステートデータを移行する必要はありません。具体的な実装では、代理コントラクト(Proxy Contract)を使用できます。代理コントラクトはデータを保存し、deleGatecallを通じてロジックコントラクトAを呼び出します。アップグレードする際は、新しいロジックコントラクトBをデプロイし、代理コントラクトがBを指すようにすればよいです。! [](https://img-cdn.gateio.im/social/moments-54db9c46be493cda1cd1968fc890b4d6)## NEARスマートコントラクトアップグレード案StatusMessageプロジェクトを例に挙げて、NEARコントラクトの一般的なアップグレード方法を紹介します。### 合約データ構造は変更されていません契約のロジックのみを変更し、データ構造の変更を伴わない場合、near deployを使用して新しいコードを再展開できます。既存のデータには引き続き正常にアクセスできます。### 合約データ構造が変更されました契約のデータ構造を変更した場合、直接再デプロイすると新旧のデータ構造が一致せず、データに正常にアクセスできなくなります。### Migrateメソッドを使用してアップグレードNEARは、コントラクトのアップグレードを支援するためにMigrateメソッドを提供します。新しいコントラクトにmigrateメソッドを追加します:さび#[private]#[init(ignore_state)]pub fn migrate() -> セルフ { old_stateさせてください: OldStatusMessage = env::state_read().expect('failed'); セルフ { タグライン: old_state.records, bios: LookupMap::new(b'b'.to_vec()), }}デプロイ時にmigrateメソッドを呼び出す:near デプロイ \ --wasmファイルターゲット/wasm32-unknown-unknown/release/status_message.wasm \ --initFunction 'migrate' \ --initArgs '{}' \ --accountId statusmessage.blocksec_upgrade.testnetこれにより、旧契約データを新しい構造に成功裏に移行できます。! [](https://img-cdn.gateio.im/social/moments-73f5e5195fa71f1f25f5d35ba1e8b8ec)## コントラクトのアップグレードに関する安全性の考慮1. アクセス制御: アップグレード関数はonly owner関数であるべきで、ownerのみが呼び出すことができます。2. ownerをDAOに設定し、提案と投票でスマートコントラクトを管理することを推奨します。3. マイグレーション関数の前に#[init(ignore_state)]を追加し、実行前に状態をロードしないようにします。4. 移行が完了したら、移行関数を削除し、一度だけ呼び出されることを確認してください。5. 新しいデータ構造は移行時に初期化を完了します。これらのアップグレードソリューションを合理的に使用することで、安全性を確保しつつ、スマートコントラクトを柔軟にアップグレードおよびメンテナンスすることができます。! [](https://img-cdn.gateio.im/social/moments-af3fe22c1999da5db0e2853b8a271276)
Rustスマートコントラクトアップグレード戦略:安全性と保守性の確保
Rustスマートコントラクトアップグレード方案详解
スマートコントラクト本質的にはプログラムであり、欠陥が存在することは避けられません。大量のテストと監査を経ても、脆弱性が現れる可能性があります。一度攻撃者に利用されると、ユーザーの資産に損失をもたらし、深刻な結果を引き起こす可能性があります。そのため、コントラクトのアップグレード可能性は非常に重要であり、主に脆弱性の修正や新機能の追加に使用されます。本記事では、Rustコントラクトの一般的なアップグレード方法について紹介します。
イーサリアム契約アップグレード案
イーサリアムのスマートコントラクトは不変性を持ち、デプロイ後に変更することはできません。脆弱性を修正したり新機能を追加するための一般的な方法は、新しいコントラクトを再デプロイすることです。しかし、これによりコントラクトアドレスが変更され、そのコントラクトを使用するすべてのDAppを修正する必要があります。さらに、旧コントラクトにある状態データを移行する必要があり、作業量が多く、ミスが起こりやすいです。
これを実現するために、通常はデータとロジックを分離したアーキテクチャを採用します: データはステートコントラクトに保存され、すべてのロジックは別のロジックコントラクトで実装されます。アップグレード時には、ロジックコントラクトのみを更新し、ステートデータを移行する必要はありません。
具体的な実装では、代理コントラクト(Proxy Contract)を使用できます。代理コントラクトはデータを保存し、deleGatecallを通じてロジックコントラクトAを呼び出します。アップグレードする際は、新しいロジックコントラクトBをデプロイし、代理コントラクトがBを指すようにすればよいです。
!
NEARスマートコントラクトアップグレード案
StatusMessageプロジェクトを例に挙げて、NEARコントラクトの一般的なアップグレード方法を紹介します。
合約データ構造は変更されていません
契約のロジックのみを変更し、データ構造の変更を伴わない場合、near deployを使用して新しいコードを再展開できます。既存のデータには引き続き正常にアクセスできます。
合約データ構造が変更されました
契約のデータ構造を変更した場合、直接再デプロイすると新旧のデータ構造が一致せず、データに正常にアクセスできなくなります。
Migrateメソッドを使用してアップグレード
NEARは、コントラクトのアップグレードを支援するためにMigrateメソッドを提供します。新しいコントラクトにmigrateメソッドを追加します:
さび #[private] #[init(ignore_state)] pub fn migrate() -> セルフ { old_stateさせてください: OldStatusMessage = env::state_read().expect('failed'); セルフ { タグライン: old_state.records, bios: LookupMap::new(b'b'.to_vec()), } }
デプロイ時にmigrateメソッドを呼び出す:
near デプロイ
--wasmファイルターゲット/wasm32-unknown-unknown/release/status_message.wasm
--initFunction 'migrate'
--initArgs '{}'
--accountId statusmessage.blocksec_upgrade.testnet
これにより、旧契約データを新しい構造に成功裏に移行できます。
!
コントラクトのアップグレードに関する安全性の考慮
アクセス制御: アップグレード関数はonly owner関数であるべきで、ownerのみが呼び出すことができます。
ownerをDAOに設定し、提案と投票でスマートコントラクトを管理することを推奨します。
マイグレーション関数の前に#[init(ignore_state)]を追加し、実行前に状態をロードしないようにします。
移行が完了したら、移行関数を削除し、一度だけ呼び出されることを確認してください。
新しいデータ構造は移行時に初期化を完了します。
これらのアップグレードソリューションを合理的に使用することで、安全性を確保しつつ、スマートコントラクトを柔軟にアップグレードおよびメンテナンスすることができます。
!