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
に変更してください。