Solidity v0.7.0の破壊的変更点
このセクションでは、Solidityバージョン0.7.0で導入された主な変更点と、変更の理由、影響を受けるコードの更新方法について説明します。 完全なリストは リリースチェンジログ を参照してください。
セマンティクスのサイレントな変更点
リテラルの非リテラル(
1 << xや2 ** 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_slotとx_offsetではなくx.slotとx.offsetでアクセスされます。
未使用または安全でない機能の削除
ストレージ外のマッピング
構造体や配列にマッピングが含まれている場合、その構造体と配列はストレージでのみ使用できるようになりました。 これまでは、マッピングのメンバーはメモリ内では無視されていたため、混乱してエラーが発生しやすい状況になっていました。
ストレージ内の構造体や配列にマッピングが含まれていると代入が動作しなくなるようになりました。 これまでは、マッピングはコピー操作中に自動的に無視されていましたが、これは誤解を招きやすく、エラーが発生しやすい状況になっていました。
関数とイベント
コンストラクタにはビジビリティ(
public/internal)は必要なくなりました。 コントラクトが作成されないようにするには、abstractマークを付けることができます。 これにより、コンストラクタのビジビリティの概念は廃止されました。
型チェッカー: ライブラリ関数の
virtualを禁止します。 ライブラリは継承できないので、ライブラリ関数は仮想関数であってはなりません。
同一の継承階層に同一名称、同一パラメータ型のイベントが複数存在することは認められません。
using A for Bは、記載されているコントラクトにのみ影響を与えます。 以前は、この効果は継承されていました。 現在では、この関数を利用するすべての派生コントラクトでusing文を繰り返さなければなりません。
式
符号付きの型によるシフトは禁止されています。 以前は、負の金額によるシフトは許可されていましたが、実行時にリバートされました。
finneyとszaboのデノミネーションは削除されています。 これらはほとんど使用されず、実際の金額を容易に確認できません。 代わりに、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: ...}()にしてください。nowをblock.timestampに変更してください。シフト演算子の右オペランドの型を符号なしに変更してください。例えば、
x >> (256 - y)をx >> uint(256 - y)に変更してください。必要に応じて、すべての派生コントラクトで
using A for B文を繰り返してください。すべてのコンストラクタから
publicキーワードを削除してください。すべてのコンストラクタから
internalキーワードを削除し、コントラクトにabstractを追加してください(まだ存在しない場合)。インラインアセンブリの
_slotと_offsetの接尾辞をそれぞれ.slotと.offsetに変更してください。