コンタクト
クラスと同様に、抽象、継承、および他のコントラクトによって呼び出される可能性があります。
典型的な使用:
- 新しい契約を作成します。
new MyContract(...)
- デプロイされたコントラクトを使用します。
MyContract($address)
視認性
視認性 | 似ている | に適用する | 外部からアクセス可能 | 下請契約にアクセス可能 |
---|---|---|---|---|
外部の | 関数 | √ | ||
公共 | 公共 | 関数 + 状態変数 | √ | √ |
内部 | 保護された | 関数 + 状態変数 | √ | |
プライベート | プライベート | 関数 + 状態変数 |
注: パブリック変数の場合、対応する getter が自動的に生成されます (詳細については、Ethers.js 非公式開発ガイド (続き)を参照してください)。
重要な要素
要素 | 例証する | 例 |
---|---|---|
状態変数 | チェーンに永久に保存され、ガスが必要です | uint data; |
関数 | read/write には 2 つのタイプがあり、write メソッドは Gas を消費する必要があり、コントラクトの内外に存在する可能性があります | function func() public {...} |
後退する() | 外部から直接呼び出すことはできません。リクエスト コントラクトに関数が存在しない場合に実行されます。 | fallback() external { ... } |
受け取る() | 外部から直接呼び出すことはできません。eth を受け取ったときに実行されます。 | receive() external payable {...} |
モディファイア | 関数呼び出しの前に実行される、再利用可能な宣言的制約。 | 宣言:modifier onlyOwner(){...} 使用:function func() public onlyOwner {...} |
イベント | チェーンの実行ログは、後で照会できます。 | emit Event1(data); |
構造 | カスタムタイプ | struct MyType { uint item1; bool item2; } |
エラー | カスタム例外 | 宣言:error MyError(unit reason); 使用:revert MyError(200); |
列挙する | 有限定数値の最良の選択 | enum State { Created, Locked, Inactive } |
ノート:
-
payable、eth を受け取る機能は追加する必要があります
-
ビューまたはピュア。関数がイーサリアムの状態を変更しないことを示します
-
フォールバックと受信機能
- どちらも関数名を持つことができないため、
function
キーワードはありません。 - 使用する必要があります
external
- フォールバック機能も有料化できますが、まずはレシーブ機能を利用することをお勧めします。
- payable fallback および receive 関数は最大 2300 ガスを消費する可能性があるため、ここでテストする必要があります。
- 通常のフォールバックにはこの制限はありません。ガスが十分にある限り、複雑な操作を実行できます。
- どちらも関数名を持つことができないため、
dapps でイベント ログとクエリ ログを使用する方法の詳細については、次を参照してください: Ethers.js 非公式開発ガイド (パート 2)
インターフェース
他の言語のインターフェースと同様に、次のことができます。
- 他のインターフェイスを継承する
- メソッド宣言のみ、他には何もない
- すべてのメソッドは外部です
図書館
契約に似ていますが、次の点が異なります。
- 状態変数を使用できません
- 継承できない、または継承される
- イースが受け取れない
- 独立して実行することはできず、他の契約によって参照される必要があります。
2 つの関係は似ています: コントラクト、実行可能ファイル、ライブラリ、ダイナミック リンク ライブラリ
データの種類
値型と参照型
似ている | |
---|---|
値のタイプ | bool、uint / int、アドレス、byte、enum |
参照タイプ | 配列(バイト/文字列など)、構造体、マッピング |
ノート:
-
バイト配列と文字列
keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2))
bytes bs = 'bytes';
string str = 'string';
byte1 b1 = 'a';
byte2 b2 = 256;
、256が半角サイズを超えています- 固定長バイト配列: byte1 ~ byte32
- 動的バイト データ: バイトと文字列。文字列は utf-8 でエンコードされます。
- Solidity は文字列比較の方法を提供しませんが、ハッシュ関数を使用して行うことができます。
-
配列
-
int[] age = [10, 20, 30, 40, 50];
-
int[] age = new int[](5);
-
int[5] age = [10, 20, 30, 40, 50];
-
固定長配列は new で初期化できません
-
動的配列は、新しい代入または初期代入を同時に使用できます
-
address
アドレスにはと の 2 種類があり、address payable
前者に比べて後者は伝達関数が多くなります。
ストレージの場所
似ている | 例 | |
---|---|---|
保管所 | コントラクト内の永続性、グローバル メモリ | 状態変数 |
メモリー | 関数のローカル メモリ、非永続的 | 関数入力 |
通話データ | 関数入力パラメーター、非永続 | 関数入力 |
スタック | EVM コール スタック |
関連するルール:
-
コピーを回避でき、変更できないため、calldata を優先します。
-
関数ローカル変数:
mapping (uint => address) storage localNames = names;
- ストレージの場合、外部状態変数を指す必要があります
- 値の型、メモリ
- 参照型、デフォルトはストレージですが、メモリとして指定できます。
- マッピング、ストレージ、常に外部状態変数を指します。次の例は、
names
コントラクトで定義された状態変数であり、その型もマッピングです。
-
割り当てルール
-
値の型、独立したコピーの作成
-
参照タイプ、コピー参照
-
storage と memory / calldata の間の割り当ては、常に独立したコピーを生成します。
-
メモリ変数間の代入
-
storage 値をローカル ストレージ変数に割り当て、参照をコピーします。
-
他のストレージ割り当てでは、常に独立したコピーが生成されます。
グローバル変数とメソッド
例証する | 例 | |
---|---|---|
イースユニット | ウェイ、ウェイ、エーテル | 1 gwei |
時間単位 | 秒、分、時間、日、週 | 1 minutes |
ブロック | ブロック オブジェクト | |
ブロックハッシュ() | 入力パラメーターが最新の 256 ブロックの 1 つである場合、それはそのハッシュになります。それ以外の場合は、0. | |
メッセージ | メッセージオブジェクト | |
TX | 送信オブジェクト | |
ガスレフト() | 残りガス | |
アビ | abi オブジェクト | |
住所 | アドレス オブジェクト | |
これ | アドレスに明示的に変換できる現在のコントラクト オブジェクト | address(this).balance |
タイプ() | タイプ情報 | |
addmod | (a + b) % k | |
マルモッド | (a * b) % k | |
ハッシュ関数 | keccak256、sha256、ripemd160 | |
エクカバー | 署名からアドレスを回復 |
详见:Units and Globally Available Variables — Solidity 0.8.18 ドキュメント
ノート:
-
tx.orgin と msg.sender の違い
- tx.orgin は tx を開始する最初のアカウントであり、その値は常に eoa です。
- msg.sender は、現在の関数の直接呼び出しアカウントであり、eoa またはコントラクト アドレスの場合があります。
-
ecrecover の最初のパラメーターが有効な eth メッセージ署名ハッシュであることを確認してください。これは、openzepplin の ecdsa ツール クラスを使用して行うことができます。
-
最初に使用され
address.transfer
、失敗するとtransfer
例外がスローされてsender
戻りますfalse
。 -
address の低レベル メソッド (call、delegatecall、staticcall、send、transfer) には 2 つの側面があります。
-
タイプや存在などの実行時チェックがないため、実行コストが低くなります。
-
したがって、安全ではありません。
-
アドレスでの call、delegatecall、および staticcall の使用は似ていますが、アプリケーション シナリオは異なります。
-
コール、コントラクトに適用
-
ライブラリに適用されるデリゲートコール
-
コントラクト読み取り専用メソッド、つまりビューまたは純粋なメソッドに適用されます。それ以外の場合は、例外がスローされます。
-
典型的な address.call 呼び出し:
bytes memory payload = abi.encodeWithSignature("register(string)", "MyName");
(bool success, bytes memory returnData) = address(nameReg).call(payload);
require(success);
- ガスを調整して eth を送信する必要がある場合は、次のようにします。
address(nameReg).call{gas: 1000000, value: 1 ether}(abi.encodeWithSignature("register(string)", "MyName"));
例外処理
例外の種類:
- ゼロ除算などのパニック、内部エラー。
- エラー、一般的な例外。
After the contract throws an exception, the state is roll back. 現在、次の 3 つの方法があります。
-
require(expression)、式が false の場合、例外がスローされ、未使用のガスが返されます
- 検証関数の入力パラメータに適しており、Error をスローします。
- 現在のバージョンの require は、カスタム エラー タイプでは使用できません。必要に応じて、「条件文 + 元に戻す」の組み合わせを使用してください。
-
assert(expression)、上記と同じですが、未使用のガスは返金されず、全額消費されます
-
内部状態の確認や Panic のスローに適しています。
-
revert()、エラーを直接スローするか、エラーをカスタマイズします。他の言語でのスローと同様です。
try...catch ステートメントの例:
try feed.getData(token) returns (uint v) {
return (v, true);
} catch Error(string memory /*reason*/) {
// require 导致
errorCount++;
return (0, false);
} catch Panic(uint /*errorCode*/) {
// assert 导致
errorCount++;
return (0, false);
} catch (bytes memory /*lowLevelData*/) {
// revert 导致
errorCount++;
return (0, false);
}