変数のクリーンアップ
値が256ビットよりも短い場合、場合によっては残りのビットをクリーンアップする必要があります。 最終的に、EVM内のすべての値は256ビットのワードで保存されます。 したがって、値の型が256ビット未満である場合、残りのビットをクリーニングする必要があるケースがあります。 Solidityのコンパイラは、残りのビットに含まれる潜在的なゴミによって悪影響を受ける可能性のある演算の前に、このようなクリーニングを行うように設計されています。
例えば、値をメモリに書き込む前に、残りのビットをクリアする必要があります。 これは、メモリの内容がハッシュの計算に使用されたり、メッセージコールのデータとして送信されたりする可能性があるためです。 同様に、ストレージに値を格納する前に、残りのビットを消去する必要があります。 そうしないと、文字化けした値が観測される可能性があるからです。
なお、インラインアセンブリによるアクセスはそのような操作とはみなされません。 インラインアセンブリを使用して256ビットより短いSolidity変数にアクセスした場合、コンパイラは値が適切にクリーンアップされることを保証しません。
また、直後の演算に影響がない場合は、ビットのクリーニングは行いません。
例えば、 JUMPI
命令では0以外の値は true
とみなされるので、 JUMPI
の条件として使われる前のブーリアン値のクリーニングは行いません。
上記の設計原理に加えて、Solidityのコンパイラは、入力データがスタックに読み込まれる際に、入力データをクリーニングします。
次の表は、異なるタイプに適用されるクリーニングルールを説明するもので、 higher bits
は、タイプが256ビット未満の場合の残りのビットを指します。
型 |
有効な値 |
無効な値のクリーンアップ |
---|---|---|
n個のメンバーのenum |
0 から n-1 |
例外を投げる |
bool |
0 あるいは 1 |
1になる |
符号付き整数 |
higher bits set to the sign bit |
currently silently signextends to a valid value, i.e. all higher bits are set to the sign bit; may throw an exception in the future |
符号なし整数 |
上位ビットがゼロ |
currently silently masks to a valid value, i.e. all higher bits are set to zero; may throw an exception in the future |
有効な値と無効な値は、その型サイズに依存することに注意してください。
符号なし8ビット型である uint8
を考えてみると、次のような有効な値があります:
0000...0000 0000 0000
0000...0000 0000 0001
0000...0000 0000 0010
....
0000...0000 1111 1111
無効な値は、上位ビットが0に設定されます:
0101...1101 0010 1010 invalid value
0000...0000 0010 1010 cleaned value
符号付き8ビット型である int8
の場合、有効な値は次のとおりです:
Negative
1111...1111 1111 1111
1111...1111 1111 1110
....
1111...1111 1000 0000
Positive
0000...0000 0000 0000
0000...0000 0000 0001
0000...0000 0000 0010
....
0000...0000 1111 1111
コンパイラは符号ビットを signextend
します。
符号ビットは負の値を1、正の値を0とし、上位ビットを上書きします:
Negative
0010...1010 1111 1111 invalid value
1111...1111 1111 1111 cleaned value
Positive
1101...0101 0000 0100 invalid value
0000...0000 0000 0100 cleaned value