Solidityのmodifierとは?
執筆者 Frederik B
Solidityは、スマートコントラクトを実装するためのオブジェクト指向の高水準言語です。Solidityを学ぶ過程で、他の関数の挙動を修飾する特殊な関数であるmodifierに出会うことになります。
この記事では、Solidity modifierが何をするものか、modifierの種類、そして使い方について説明します。この記事を読み終える頃には、Solidity modifierを認識し、その使い方を理解できるようになります。
Solidity modifierは何をするものか
modifierは、他の関数の挙動を修飾するために使われる特殊なSolidity関数の一種です。 例えば、開発者は関数の実行を許可する前に、ある条件が満たされていることをチェックするためにmodifierを使うことができます。
modifierは関数と似ており、引数を取ることも戻り値の型を持つこともできます。また、modifierは連結することも可能で、1つの関数に複数のmodifierを付けることができます。
ただし、modifierはコントラクトのロジックのみを修飾でき、構造体を含むコントラクトのストレージを修飾することはできません。modifierを使うことで開発者が書く必要のあるボイラープレートコードの量を減らすことができ、Solidityコードの可読性を高めることができます。
Solidity関数に複数のmodifierを付けられるか
はい、開発者は1つのSolidity関数に複数のmodifierを使うことができます。 複数のmodifierはカンマで区切ります。複数のmodifierを使う際に重要な点は、modifierの順序が意味を持つということです。リストの最初のmodifierが最初に実行され、2番目のmodifierが2番目に適用され、以降も同様です。
例えば、ユーザーが認証済みかどうかをチェックするmodifierと、あるリソースを閲覧する権限があるかどうかをチェックするmodifierがある場合、これらのmodifierが適用される順序によって、ユーザーがそのリソースを閲覧できるかどうかが決まります。
Solidity modifierにはどのような種類があるか
Solidity modifierには、gate check、prerequisite、filter、reentrancy攻撃防止の4つの大きなカテゴリがあります。
1. Gate check
「gate check」は、関数の実行を許可する前に、ある条件が真であるかどうかをチェックするmodifierです。
例えば、ユーザーが自分のアカウントからお金を引き出すことを許可する関数があるとします。この関数が実行される前に、開発者はユーザーのアカウントに引き出しを行うのに十分な金額があるかどうかをチェックしたいかもしれません。このチェックはgate check modifierとみなされます。
gate checkのもう一つの例は、ユーザーがある特定のリソースを閲覧することを許可する前に、認証済みかどうかをチェックする関数です。
2. Prerequisite
「prerequisite」は、ある条件が真であるかをチェックするのではなく、関数が実行するための環境をセットアップするmodifierです。
例えば、Solidity開発者は、実行するために一定量のEtherを一緒に送る必要がある関数を使うことがあります。この場合、prerequisiteはEtherの残高をセットアップする関数ということになります。
3. Filter
「filter」は、ある条件が真であるかどうかをチェックし、真であれば関数の実行を許可するmodifierです。条件が真でない場合、関数は実行されません。
gate checkが条件が真であっても関数の実行を自動的に許可しないのに対し、filterは条件が真であれば関数の実行を許可します。
4. Reentrancy攻撃防止
reentrancy攻撃とは、悪意のある行為者が再帰呼び出しを通じて関数を悪用するために、その関数を複数回実行しようとする種類の攻撃です。
例えば、ユーザーが自分のアカウントからお金を引き出すことを許可する関数があるとします。reentrancy攻撃者は、実際に自分のアカウントに保有している以上の金額を引き出すために、その関数を複数回呼び出そうとするかもしれません。
reentrancy攻撃を防ぐために、その関数が再帰的に呼び出されているかどうかをチェックするmodifierを使うことができます。そうであれば、関数は実行されません。
requireとSolidity modifierの関係は何か
**requireはmodifierとしばしば同じ意味で使われます。どちらも、関数の実行を許可する前に、ある条件が真であるかをチェックすることができるためです。**指定された条件が真でない場合、コンパイラはエラーを出します。
例えば、次のステートメントはrequireキーワードを使い、オーナーのみが関数と対話できるようにしています。
requireとSolidity modifierには重要な違いがいくつかあります。
- modifierは(prerequisiteの場合のように)関数が実行するための環境をセットアップするために使うことができる
- _require_はある条件が真であるかをチェックするためにのみ使うことができる
- modifierはオーバーライドできる
- _require_はオーバーライドできない
SolidityとVyperでのmodifierの扱いの違いは何か
VyperはEthereumスマートコントラクト開発のためのPythonライクな言語で、セキュリティを高めるためにmodifierを使わないなどのトレードオフを行っています。代わりに、開発者は関数内でインラインのチェックやassertを使うことになっており、スマートコントラクトを修正する場合も、関数の一部として明示的に変更を行うことになっています。
Vyperがmodifierを使う機能を排除したことで、スマートコントラクトの監査可能性が向上します。読み手が関数の挙動を確認するために、頭の中でmodifierを関数の周りに配置し直す必要がなくなるためです。
modifierのオーバーライドとは何か
「virtual」というキーワードは、あるmodifierが派生コントラクトでオーバーライド可能であることを示すために使うことができます。例えば、「myModifier」というmodifierを持つ「Base Contract」というコントラクトがあるとします。また、「Base Contract」を継承する「Derived Contract」というコントラクトがあるとします。
「Base Contract」が「virtual」とマークされていれば、派生コントラクトでオーバーライドすることができます。これはライブラリの文脈でよく使われ、コントラクトがカスタマイズを可能にするために用いられます。
継承とmodifierはどのように関係するか
継承は、コントラクトの属性やプロパティを拡張することを可能にし、modifierの文脈では、継承によって新しいmodifierを追加したり、既存のmodifierをオーバーライドしたりすることができます。 これは前のセクションで説明した_virtual_というキーワードによって実現できます。
以下のシンプルな実装は、継承とmodifierがどのように連携するかを示しています。
この例では、コントラクトBはコントラクトAを継承しています。両方のコントラクトには「X」というmodifierがあります。ただし、コントラクトBでは、このmodifierが「override」とマークされており、コントラクトAのmodifierをオーバーライドすることを示しています。
Solidityでmodifierを使う方法
modifierを使うには、まずコントラクト内でmodifier関数を定義する必要があります。modifierは「_;」という特殊な記号を使い、modifierの条件が満たされた場合にのみ、この位置に関数本体が挿入されます。
以下のコントラクトは、modifierの使い方を示しています。
上記の例では、コントラクトには「onlyOwner」と「costs」という2つのmodifierがあります。
最初のmodifierは_msg.sender_がコントラクトのオーナーであることをチェックし、2番目のmodifierは_msg.value_がある価格以上であることをチェックします。
これらのmodifierはどちらも、コントラクト内の任意の関数で使うことができます。
Solidity modifierについてさらに学ぶ
modifierは、他の関数の挙動を修飾するために使われる関数です。modifierを使うことで、書く必要のあるボイラープレートコードの量を減らし、Solidityコードの可読性を高めることができます。
Solidity modifierについてさらに学び、Solidity開発者になる方法を知るには、Alchemy Universityの7週間のEthereum Developer Bootcampに申し込んでください。ChainShotチームによって元々作成されたこの無料のSolidityクラッシュコースは、Solidityを学ぶ最良の方法です。開発全般が初めての開発者であれば、Alchemy Universityの3週間のJavaScriptクラッシュコースは、Ethereum bootcampを始める前の前提知識として最適です。
関連する概要

ブロックチェーンで魔法を生み出す
Alchemyは、最も強力なweb3開発者向けプロダクトとツールを、豊富なリソース、コミュニティ、そして卓越したサポートと組み合わせて提供します。


