初心者のための Solidity チュートリアル: 15. 例外
この講義では、 Solidity で例外をスローする 3 つのメソッド、 error、require、およびassertを紹介し、 3 つのメソッドのガス消費量を比較します。
異常な
スマート コントラクトを作成するときにバグがよく発生しますが、Solidityの例外コマンドはバグのデバッグに役立ちます。
エラー
エラーは、 Solidity のバージョン 0.8.4 で追加された新しいコンテンツです。操作失敗の理由をユーザーに便利かつ効率的に (ガス節約) 説明できます。また、開発者がより適切にデバッグできるように、例外をスローしながらパラメータを運ぶこともできます。コントラクトの外で例外を定義できます。次に、TransferNotOwner例外を定義します。ユーザーがトークンの所有者ではないときに転送しようとすると、エラーがスローされます。
error TransferNotOwner(); // 自定义error
送金試行のアカウントアドレスを要求するパラメータを使用して例外を定義することもできます。
error TransferNotOwner(address sender); // 自定义的带参数的error
実行中は、error をrevert (ロールバック) コマンドとともに使用する必要があります。
function transferOwner1(uint256 tokenId, address newOwner) public {
if(_owners[tokenId] != msg.sender){
revert TransferNotOwner();
// revert TransferNotOwner(msg.sender);
}
_owners[tokenId] = newOwner;
}
トークンの所有者がイニシエーターであるかどうかをチェックするtransferOwner1()関数を定義しました。そうでない場合はTransferNotOwner例外がスローされ、そうであれば転送が行われます。
必要とする
requireコマンドは、 Solidity 0.8より前では例外をスローするための一般的な方法であり、多くの主流のコントラクトでは今でもこのコマンドが使用されています。うまく機能しますが、唯一の欠点は、例外を説明する文字列の長さがエラーコマンドよりも長くなるにつれてガスが増加することです。使用法: require(チェック条件, "例外の説明")、チェック条件が成立しない場合、例外がスローされます。requireコマンドを使用して、上記のtransferOwner関数を書き換えてみましょう。
function transferOwner2(uint256 tokenId, address newOwner) public {
require(_owners[tokenId] == msg.sender, "Transfer Not Owner");
_owners[tokenId] = newOwner;
}
主張する
通常、 assertコマンドは例外をスローする理由を説明できないため、プログラマがプログラムをデバッグするために使用します( requireよりも文字列が少ないため)。使い方は非常に簡単で、assert (チェック条件)とチェック条件が成立しない場合に例外をスローします。assertコマンドを使用して、上記のtransferOwner
関数を書き換えてみましょう。
function transferOwner3(uint256 tokenId, address newOwner) public {
assert(_owners[tokenId] == msg.sender);
_owners[tokenId] = newOwner;
}
リミックスで検証する
- 任意のuint256数値と 0 以外のアドレスを入力し、エラーメソッドであるtransferOwner1を呼び出します。コンソールは例外をスローし、カスタマイズされたTransferNotOwnerを表示します。
- 任意のuint256数値と 0 以外のアドレスを入力し、requireメソッドであるtransferOwner2を呼び出します。コンソールは例外をスローし、require内の文字列を出力します。
- 任意のuint256数値と 0 以外のアドレスを入力し、assertメソッドであるtransferOwner3を呼び出すと、コンソールは例外をスローするだけです。
3つの方法のガス比較
スローされた 3 つの例外のガス消費量を比較してみましょう。リミックス コンソールの [デバッグ] ボタンを使用すると、次のように各関数呼び出しのガス消費量を確認できます: (バージョン 0.8.17 を使用してコンパイル)
- エラーメソッドガス消費量:24457(パラメータ追加後のガス消費量:24660)
- 必要な方法ガス消費量:24755
- アサート方式のガス消費量:24473
errorメソッドがガスの消費量が最も少なく、次にassertメソッドが続き、requireメソッドが最も多くのガスを消費していることがわかります。したがって、error は例外をスローする理由をユーザーに通知するだけでなく、ガスを節約することもできます。(展開テスト時間が異なるため、各関数のガス消費量は異なりますが、比較結果は一貫していることに注意してください。)
注: Solidity 0.8.0 より前のバージョンでは、assert はパニック例外をスローします。これにより、残りのすべてのガスがスローされます。消費され、返却されません。詳細については、公式ドキュメントを参照してください。
要約する
この講義では、 Solidity で例外をスローする 3 つのメソッド、 error、require、およびassertを紹介し、 3 つのメソッドのガス消費量を比較します。結論: error は例外をスローする理由をユーザーに通知するだけでなく、ガスを節約することもできます。