Solidity v0.7.0の破壊的変更点

このセクションでは、Solidityバージョン0.7.0で導入された主な変更点と、変更の理由、影響を受けるコードの更新方法について説明します。 完全なリストは リリースチェンジログ を参照してください。

セマンティクスのサイレントな変更点

  • リテラルの非リテラル( 1 << x2 ** x など)による指数化やシフトは、常に uint256 型(非負のリテラル用)または int256 型(負のリテラル用)を使用して演算を行います。 これまでは、シフト量/指数の型で演算を行っていたため、誤解を招く恐れがありました。

シンタックスの変更点

  • 外部関数やコントラクト作成コールで、Etherやガスが新しい構文で指定されるようになりました。 x.f{gas: 10000, value: 2 ether}(arg1, arg2) です。 従来の構文( x.f.gas(10000).value(2 ether)(arg1, arg2) )ではエラーになります。

  • グローバル変数 now は非推奨であり、代わりに block.timestamp を使用すべきです。 now という単一の識別子は、グローバル変数としては一般的すぎて、トランザクション処理中に変化するような印象を与える可能性がありますが、 block.timestamp は単なるブロックのプロパティであるという事実を正しく反映しています。

  • 変数に関するNatSpecコメントは、パブリックな状態の変数に対してのみ許可され、ローカルまたは内部の変数に対しては許可されません。

  • トークン gwei は、現在のキーワード(例えば 2 gwei を数字で指定するために使用)であり、識別子としては使用できません。

  • 文字列リテラルには、印刷可能なASCII文字のみを含めることができるようになり、16進数( \xff )やユニコードエスケープ( \u20ac )などの様々なエスケープシーケンスも含まれています。

  • Unicode文字列リテラルがサポートされ、有効なUTF-8シーケンスに対応できるようになりました。 これらは unicode という接頭語で識別されます: unicode"Hello 😃"

  • ステートミュータビリティ: 継承の際に、関数のステートミュータビリティを制限できるようになりました。 デフォルトのステートミュータビリティを持つ関数は、 pure および view 関数でオーバーライドでき、 view 関数は pure 関数でオーバーライドできます。 同時に、パブリックな状態変数は view とみなされ、定数であれば pure ともみなされます。

インラインアセンブリ

  • インラインアセンブリのユーザー定義関数および変数名に . を使用できないようにしました。 SolidityをYul-onlyモードで使用している場合も有効です。

  • ストレージポインタ変数 x のスロットとオフセットは、 x_slotx_offset ではなく x.slotx.offset でアクセスされます。

未使用または安全でない機能の削除

ストレージ外のマッピング

  • 構造体や配列にマッピングが含まれている場合、その構造体と配列はストレージでのみ使用できるようになりました。 これまでは、マッピングのメンバーはメモリ内では無視されていたため、混乱してエラーが発生しやすい状況になっていました。

  • ストレージ内の構造体や配列にマッピングが含まれていると代入が動作しなくなるようになりました。 これまでは、マッピングはコピー操作中に自動的に無視されていましたが、これは誤解を招きやすく、エラーが発生しやすい状況になっていました。

関数とイベント

  • コンストラクタにはビジビリティ( public / internal )は必要なくなりました。 コントラクトが作成されないようにするには、 abstract マークを付けることができます。 これにより、コンストラクタのビジビリティの概念は廃止されました。

  • 型チェッカー: ライブラリ関数の virtual を禁止します。 ライブラリは継承できないので、ライブラリ関数は仮想関数であってはなりません。

  • 同一の継承階層に同一名称、同一パラメータ型のイベントが複数存在することは認められません。

  • using A for B は、記載されているコントラクトにのみ影響を与えます。 以前は、この効果は継承されていました。 現在では、この関数を利用するすべての派生コントラクトで using 文を繰り返さなければなりません。

  • 符号付きの型によるシフトは禁止されています。 以前は、負の金額によるシフトは許可されていましたが、実行時にリバートされました。

  • finneyszabo のデノミネーションは削除されています。 これらはほとんど使用されず、実際の金額を容易に確認できません。 代わりに、 1e20 や非常に一般的な gwei のような明確な値を使用できます。

宣言

  • キーワード var が使用できなくなりました。 以前は、このキーワードは解析されますが、型エラーが発生し、どの型を使用すべきかの提案がありました。 現在は、パーサーエラーとなります。

インターフェースの変更点

  • JSON AST: 16進文字列リテラルを kind: "hexString" でマークするようになりました。

  • JSON AST: 値が null のメンバーをJSON出力から削除しました。

  • NatSpec: コンストラクタと関数に一貫したユーザードキュメントを出力するようにしました。

コードのアップデート方法

このセクションでは、変更のたびに先行コードを更新する方法を詳しく説明しています。

  • x.f.value(...)()x.f{value: ...}() に変更してください。同様に (new C).value(...)()new C{value: ...}() に、 x.f.gas(...).value(...)()x.f{gas: ..., value: ...}() にしてください。

  • nowblock.timestamp に変更してください。

  • シフト演算子の右オペランドの型を符号なしに変更してください。例えば、 x >> (256 - y)x >> uint(256 - y) に変更してください。

  • 必要に応じて、すべての派生コントラクトで using A for B 文を繰り返してください。

  • すべてのコンストラクタから public キーワードを削除してください。

  • すべてのコンストラクタから internal キーワードを削除し、コントラクトに abstract を追加してください(まだ存在しない場合)。

  • インラインアセンブリの _slot_offset の接尾辞をそれぞれ .slot.offset に変更してください。