本講義では、コントラクト権限制御(Ownable)の例を用いて、Solidity言語におけるコンストラクタ(constructor)と独自修飾子(modifier)を紹介します。
コンストラクタ
コンストラクターは、コントラクトごとに定義でき、コントラクトのデプロイ時に 1 回自動的に実行できる特別な関数です。これは、コントラクトの所有者アドレスの初期化など、コントラクトの一部のパラメーターを初期化するために使用できます。
address owner; // 定义owner变量
// 构造函数
constructor() {
owner = msg.sender; // 在部署合约的时候,将owner设置为部署者的地址
}
注⚠️: Solidityのバージョンが異なるコンストラクタの構文は統一されていません。Solidity 0.4.22以前では、コンストラクタはコンストラクタではなく、コントラクト名と同名の関数をコンストラクタとして使用していました。この古い書き方のため、開発者の記述漏れが発生しやすく(例:コントラクト名がParents、コンストラクタ名が親と記述されるなど)、コンストラクタが通常の関数になって抜け穴が発生することがありました。そのため、バージョン0.4では、 .22 以降では、新しいコンストラクターの書き方が採用されています。
コンストラクターを記述する古い方法のコード例:
pragma solidity =0.4.21;
contract Parents {
// 与合约名Parents同名的函数就是构造函数
function Parents () public {
}
}
デコレータ
モディファイアは、オブジェクト指向プログラミングのデコレータに似たソリッド性固有の構文であり、関数の特性を宣言し、コードの冗長性を削減します。アイアンマンのスマートアーマーのようなもので、これを装着したファンクションは特定の動作をするようになる。モディファイアの主な使用シナリオは、アドレス、変数、バランスなどの関数を実行する前にチェックすることです。
OnlyOwner という修飾子を定義してみましょう。
// 定义modifier
modifier onlyOwner {
require(msg.sender == owner); // 检查调用者是否为owner地址
_; // 如果是的话,继续运行函数主体;否则报错并revert交易
}
OnlyOwner 修飾子を持つ関数は、次の例のように、所有者アドレスによってのみ呼び出すことができます。
function changeOwner(address _newOwner) external onlyOwner{
owner = _newOwner; // 只有owner地址运行这个函数,并改变owner
}
changeOwner 関数を定義し、それを実行するとコントラクトの所有者を変更できますが、onlyOwner 修飾子の存在により、元の所有者のみがそれを呼び出すことができ、他の所有者はエラーを報告します。これは、スマート コントラクトのアクセス許可を制御する最も一般的に使用される方法でもあります。
OppenZepplin の所有可能な標準実装:
OppenZeppelin は堅牢性の標準化されたコード ベースを維持する組織であり、その Ownable 標準は次のように実装されています: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol
リミックスデモの例
Owner.sol を例に挙げます。
1. コードをコンパイルして Remix にデプロイします。
2. [所有者] ボタンをクリックして、現在の所有者変数を表示します。
3. 所有者アドレスのユーザーとしてchangeOwner関数を呼び出すと、トランザクションが成功します。
4. 非所有者アドレスを持つユーザーとしてchangeOwner関数を呼び出しますが、修飾子onlyOwnerのチェックステートメントが満たされないため、トランザクションは失敗します。
要約する
この講義では、Solidity のコンストラクターとモディファイアーを紹介し、コントラクトの権限を制御する Ownable コントラクトについて説明しました。