# Rust スマートコントラクト養成日記(7)契約安全の権限管理この記事では、Rustスマートコントラクトにおける権限管理に関する内容を2つの視点から紹介します:1. コントラクトのメソッド(関数)へのアクセス/呼び出しの可視性2. 特権関数のアクセス制御/権限と責任の分担## 1. コントラクト関数(メソッド)の可視性スマートコントラクトを作成する際に、契約関数の可視性を指定することで、関数の呼び出し権限を制御し、契約内の重要な部分が意図せずアクセスまたは操作されるのを防ぐことができます。Bancor Network取引所を例に挙げると、この取引所は2020年6月18日に、スマートコントラクトの主要関数のアクセス制御権限設定の誤りにより資産の安全性に関する事件が発生しました。このスマートコントラクトはSolidity言語で記述されており、契約関数の可視性はpublic/externalとprivate/internalの2種類に分かれています。前者は契約関数が外部の呼び出し者によって呼び出されることを許可し、契約インターフェースの一部と見なされます。Bancor Networkは、あるセキュリティの脆弱性を修正する際に、契約の一部の重要な送金関数をpublic属性に設定してしまい、誰でも契約の外部からこれらの関数を呼び出して送金操作を行えるようになりました。この重要な脆弱性により、ユーザーの59万ドルの資産が深刻なリスクにさらされています。! [](https://img-cdn.gateio.im/social/moments-6967d12c897f0589b734fb88bc385e7c)Rustスマートコントラクトにおいても、契約関数の可視性制御を重視する必要があります。NEAR SDKが定義した#[near_bindgen]マクロは、Rustスマートコントラクト関数を修飾するために使用でき、以下のような異なる可視属性があります:- pub fn: このメソッドはpublicであり、コントラクトインターフェースの一部であり、外部から呼び出すことができます。- fn: pubが明示されていない場合、コントラクト外部から直接呼び出すことはできず、コントラクト内部からのみ呼び出すことができます。- pub(crate) fn: メソッドをcrate内部の範囲内で呼び出すように制限します。別の方法として、契約のメソッドをinternalに設定するのは、契約の中に#[near_bindgen]で修飾されていない独立したimpl Contractのコードブロックを定義することです。! [](https://img-cdn.gateio.im/social/moments-ca94a7442872cab9f91f2842feb96bad)(Callbacks)関数について、定義時にpublicプロパティとして設定する必要があり、function callによって呼び出すことができるようにする必要があります。また、コールバック関数が他者によって随意に呼び出されないようにする必要があり、呼び出し元はコントラクト自身でなければなりません。NEAR SDKは、この機能を実現するために#[private]マクロを提供しています。注意が必要なのは、Rust言語ではデフォルトですべての内容がprivateであり、pub Traitのサブプロジェクトとpub EnumのEnum変数のみがデフォルトでpublicであるということです。! [](https://img-cdn.gateio.im/social/moments-4c9e1911156dc6134b40fab37dd6c539)## 2. 特権関数のアクセス制御(ホワイトリストメカニズム)関数の可視性に加えて、契約の意味的なレベルから完全なアクセスコントロールホワイトリストメカニズムを確立する必要があります。特定の特権関数(、例えば契約の初期化、開始/停止、統一転送など)は、契約の所有者(によってのみ呼び出すことができ、これらの関数は通常「only owner」関数と呼ばれます。これらの重要な関数は外部から呼び出すためにpublic属性に設定する必要がありますが、アクセス制御ルールを定義することができ、該当するルールを満たす場合にのみ完全に実行されます。例えば、次のようなカスタムTraitを実装できます:さびpub トレイト Ownable { fn assert_owner)&self( { assert_eq!)env::p redecessor_account_id((, self.get_ owner)(); } fn get_owner)&self( -> AccountId; fn set_owner)&mut自己、所有者:AccountId(;}このtraitを利用することで、コントラクト内の特権関数へのアクセス制御を実現でき、呼び出し者はコントラクトのownerである必要があります。この原理に基づき、より複雑なmodifierやtraitをカスタマイズすることで、複数のユーザーや複数のホワイトリストを設定し、精密なグループアクセス制御を実現できます。! [])https://img-cdn.gateio.im/social/moments-b465966b93b04b1f687c676e62c39bc2(! [])https://img-cdn.gateio.im/social/moments-6211a037604bd45f9d638f6f0a7ce5c2(! [])https://img-cdn.gateio.im/social/moments-7f9b5788662e38094194172212155bb5(! [])https://img-cdn.gateio.im/social/moments-2c64fb18a6182ccc014ef4c949213e7e(! [])https://img-cdn.gateio.im/social/moments-5b7fd87c1bbe1b57c40c5349716f6d7c(! [])https://img-cdn.gateio.im/social/moments-5c3bdf877fa7e468268992229d94bebc(! [])https://img-cdn.gateio.im/social/moments-54c0aed04624592c740791245f01325a(
Rustスマートコントラクト安全:権限管理とアクセス管理の詳細解説
Rust スマートコントラクト養成日記(7)契約安全の権限管理
この記事では、Rustスマートコントラクトにおける権限管理に関する内容を2つの視点から紹介します:
1. コントラクト関数(メソッド)の可視性
スマートコントラクトを作成する際に、契約関数の可視性を指定することで、関数の呼び出し権限を制御し、契約内の重要な部分が意図せずアクセスまたは操作されるのを防ぐことができます。
Bancor Network取引所を例に挙げると、この取引所は2020年6月18日に、スマートコントラクトの主要関数のアクセス制御権限設定の誤りにより資産の安全性に関する事件が発生しました。このスマートコントラクトはSolidity言語で記述されており、契約関数の可視性はpublic/externalとprivate/internalの2種類に分かれています。前者は契約関数が外部の呼び出し者によって呼び出されることを許可し、契約インターフェースの一部と見なされます。
Bancor Networkは、あるセキュリティの脆弱性を修正する際に、契約の一部の重要な送金関数をpublic属性に設定してしまい、誰でも契約の外部からこれらの関数を呼び出して送金操作を行えるようになりました。この重要な脆弱性により、ユーザーの59万ドルの資産が深刻なリスクにさらされています。
!
Rustスマートコントラクトにおいても、契約関数の可視性制御を重視する必要があります。NEAR SDKが定義した#[near_bindgen]マクロは、Rustスマートコントラクト関数を修飾するために使用でき、以下のような異なる可視属性があります:
別の方法として、契約のメソッドをinternalに設定するのは、契約の中に#[near_bindgen]で修飾されていない独立したimpl Contractのコードブロックを定義することです。
!
(Callbacks)関数について、定義時にpublicプロパティとして設定する必要があり、function callによって呼び出すことができるようにする必要があります。また、コールバック関数が他者によって随意に呼び出されないようにする必要があり、呼び出し元はコントラクト自身でなければなりません。NEAR SDKは、この機能を実現するために#[private]マクロを提供しています。
注意が必要なのは、Rust言語ではデフォルトですべての内容がprivateであり、pub Traitのサブプロジェクトとpub EnumのEnum変数のみがデフォルトでpublicであるということです。
!
2. 特権関数のアクセス制御(ホワイトリストメカニズム)
関数の可視性に加えて、契約の意味的なレベルから完全なアクセスコントロールホワイトリストメカニズムを確立する必要があります。特定の特権関数(、例えば契約の初期化、開始/停止、統一転送など)は、契約の所有者(によってのみ呼び出すことができ、これらの関数は通常「only owner」関数と呼ばれます。
これらの重要な関数は外部から呼び出すためにpublic属性に設定する必要がありますが、アクセス制御ルールを定義することができ、該当するルールを満たす場合にのみ完全に実行されます。例えば、次のようなカスタムTraitを実装できます:
さび pub トレイト Ownable { fn assert_owner)&self( { assert_eq!)env::p redecessor_account_id((, self.get_ owner)(); } fn get_owner)&self( -> AccountId; fn set_owner)&mut自己、所有者:AccountId(; }
このtraitを利用することで、コントラクト内の特権関数へのアクセス制御を実現でき、呼び出し者はコントラクトのownerである必要があります。この原理に基づき、より複雑なmodifierやtraitをカスタマイズすることで、複数のユーザーや複数のホワイトリストを設定し、精密なグループアクセス制御を実現できます。
! [])https://img-cdn.gateio.im/webp-social/moments-b465966b93b04b1f687c676e62c39bc2.webp(
! [])https://img-cdn.gateio.im/webp-social/moments-6211a037604bd45f9d638f6f0a7ce5c2.webp(
! [])https://img-cdn.gateio.im/webp-social/moments-7f9b5788662e38094194172212155bb5.webp(
! [])https://img-cdn.gateio.im/webp-social/moments-2c64fb18a6182ccc014ef4c949213e7e.webp(
! [])https://img-cdn.gateio.im/webp-social/moments-5b7fd87c1bbe1b57c40c5349716f6d7c.webp(
! [])https://img-cdn.gateio.im/webp-social/moments-5c3bdf877fa7e468268992229d94bebc.webp(
! [])https://img-cdn.gateio.im/webp-social/moments-54c0aed04624592c740791245f01325a.webp(