# 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: pub(に相当し、crate)内でのみ呼び出されるように契約メソッドを制限します。もう一つの方法は、契約のメソッドをinternalに設定することで、契約内に独立したimpl Contractコードブロックを定義することであり、そのimplementationは#[near_bindgen]によって装飾されていません。コールバック関数は、定義がpublic属性に設定されている必要がありますが、同時にコントラクト自身によってのみ呼び出されることを確認する必要があります。NEAR SDKは、#[private]マクロを提供して、この機能を実現します。注意すべきは、Rust言語ではデフォルトですべてがprivateであり、pub Traitのサブプロジェクトとpub EnumのEnum変数のみがデフォルトでpublicであるということです。! [](https://img-cdn.gateio.im/social/moments-ca94a7442872cab9f91f2842feb96bad)## 2. 特権関数のアクセス制御(ホワイトリストメカニズム)関数の可視性に加えて、契約の意味層面から完全なアクセス制御ホワイトリストメカニズムを構築する必要があります。契約の初期化、開始/停止、統一送金などの特権関数は、通常、契約の所有者(owner)のみが呼び出すことができます。これらの特権関数は、外部から呼び出されるためにpublic属性として設定する必要がありますが、同時にアクセス制御ルールを定義し、条件を満たすユーザーのみが完全に実行できることを保証する必要があります。Rustのスマートコントラクトでは、Solidityのmodifier機能に似たものを実現でき、カスタム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);}このトレイトを使用することで、コントラクト内の特権関数へのアクセス制御を実現でき、取引の呼び出し者がコントラクトのオーナーである必要があります。この原理に基づき、より複雑なモディファイアやトレイトをカスタマイズすることで、複数のユーザーや複数のホワイトリストを設定し、細かいグループアクセス制御を実現できます。! [](https://img-cdn.gateio.im/social/moments-4c9e1911156dc6134b40fab37dd6c539)## 3. その他のアクセス制御方法上記の方法に加えて、Rustスマートコントラクトには、契約呼び出しのタイミング制御、契約関数のマルチシグ呼び出しメカニズム、ガバナンス(DAO)の実装など、他のアクセス制御方法もあります。これらの内容は、本シリーズのスマートコントラクト育成日記の後続の記事で詳しく紹介されます。! [](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に設定することで、契約内に独立したimpl Contractコードブロックを定義することであり、そのimplementationは#[near_bindgen]によって装飾されていません。
コールバック関数は、定義がpublic属性に設定されている必要がありますが、同時にコントラクト自身によってのみ呼び出されることを確認する必要があります。NEAR SDKは、#[private]マクロを提供して、この機能を実現します。
注意すべきは、Rust言語ではデフォルトですべてがprivateであり、pub Traitのサブプロジェクトとpub EnumのEnum変数のみがデフォルトでpublicであるということです。
!
2. 特権関数のアクセス制御(ホワイトリストメカニズム)
関数の可視性に加えて、契約の意味層面から完全なアクセス制御ホワイトリストメカニズムを構築する必要があります。契約の初期化、開始/停止、統一送金などの特権関数は、通常、契約の所有者(owner)のみが呼び出すことができます。
これらの特権関数は、外部から呼び出されるためにpublic属性として設定する必要がありますが、同時にアクセス制御ルールを定義し、条件を満たすユーザーのみが完全に実行できることを保証する必要があります。
Rustのスマートコントラクトでは、Solidityのmodifier機能に似たものを実現でき、カスタム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); }
このトレイトを使用することで、コントラクト内の特権関数へのアクセス制御を実現でき、取引の呼び出し者がコントラクトのオーナーである必要があります。この原理に基づき、より複雑なモディファイアやトレイトをカスタマイズすることで、複数のユーザーや複数のホワイトリストを設定し、細かいグループアクセス制御を実現できます。
!
3. その他のアクセス制御方法
上記の方法に加えて、Rustスマートコントラクトには、契約呼び出しのタイミング制御、契約関数のマルチシグ呼び出しメカニズム、ガバナンス(DAO)の実装など、他のアクセス制御方法もあります。これらの内容は、本シリーズのスマートコントラクト育成日記の後続の記事で詳しく紹介されます。
!
!
!
!
!
!
!