いまさらSolidity - Units and Globally Available Variables

# はじめに

基本は大事ということで、Solidityを使う機会が増えてきたので、単位とグローバルに利用可能な変数（Units and Globally Available Variables）のドキュメントを[Google翻訳](https://translate.google.co.jp/)や[DeepL翻訳](https://www.deepl.com/translator)を使用して翻訳してみます。

https://docs.soliditylang.org/en/v0.8.18/units-and-global-variables.html


## 単位とグローバルに利用可能な変数（Units and Globally Available Variables）

### Ether単位（Ether Units）

<details><summary>原文</summary><div>

A literal number can take a suffix of wei, gwei or ether to specify a subdenomination of Ether, where Ether numbers without a postfix are assumed to be Wei.

```solidity
assert(1 wei == 1);
assert(1 gwei == 1e9);
assert(1 ether == 1e18);
```

The only effect of the subdenomination suffix is a multiplication by a power of ten.

:::note
Note
The denominations finney and szabo have been removed in version 0.7.0.
:::

</div></details>

リテラル番号は、wei、gwei、etherの接尾辞を付けてEtherの下位呼称を指定することができ、接尾辞のないEther番号はWeiとみなされます。

```solidity
assert(1 wei == 1);
assert(1 gwei == 1e9);
assert(1 ether == 1e18);
```

サブデノミネーションサフィックス（副 種類 接尾）による効果は、10の累乗のみです。

:::note
Note
種類 finney と szabo はバージョン 0.7.0 で削除されました。
:::

### 時間単位（Time Units）

<details><summary>原文</summary><div>

Suffixes like `seconds`, `minutes`, `hours`, `days` and `weeks` after literal numbers can be used to specify units of time where seconds are the base unit and units are considered naively in the following way:

- `1 == 1 seconds`
- `1 minutes == 60 seconds`
- `1 hours == 60 minutes`
- `1 days == 24 hours`
- `1 weeks == 7 days`

Take care if you perform calendar calculations using these units, because not every year equals 365 days and not even every day has 24 hours because of leap seconds. Due to the fact that leap seconds cannot be predicted, an exact calendar library has to be updated by an external oracle.

:::note
Note
The suffix `years` has been removed in version 0.5.0 due to the reasons above.
:::

These suffixes cannot be applied to variables. For example, if you want to interpret a function parameter in days, you can in the following way:

```solidity
function f(uint start, uint daysAfter) public {
    if (block.timestamp >= start + daysAfter * 1 days) {
      // ...
    }
}
```

</div></details>

`seconds`、`minutes`、`hours`、`days`、`weeks`といった数字の後につけるサフィックスは、秒を基本単位とした時間の単位を指定するために用いることができ、単位は次のように単純に考えることができます。

- `1 == 1 seconds`
- `1 minutes == 60 seconds`
- `1 hours == 60 minutes`
- `1 days == 24 hours`
- `1 weeks == 7 days`

この単位を使って暦の計算を行う場合、1年＝365日とは限らず、うるう秒の関係で1日＝24時間とも限らないので、注意が必要です。
うるう秒は予測できないため、正確なカレンダーライブラリは外部のオラクルによって更新されなければなりません。

:::note
Note
上記の理由により、バージョン0.5.0ではサフィックス `years` が削除されました。
:::

これらのサフィックスは変数には適用できません。
例えば、関数のパラメータを日単位で解釈したい場合は、以下のようになります。

```solidity
function f(uint start, uint daysAfter) public {
    if (block.timestamp >= start + daysAfter * 1 days) {
      // ...
    }
}
```

## 特殊変数と関数（Special Variables and Functions）

<details><summary>原文</summary><div>

There are special variables and functions which always exist in the global namespace and are mainly used to provide information about the blockchain or are general-use utility functions.

</div></details>

グローバルな名前空間に常に存在し、主にブロックチェーンに関する情報を提供したり、汎用的なユーティリティ関数として使用される特殊変数や関数があります。

# ブロックとトランザクションのプロパティ（Block and Transaction Properties）

<details><summary>原文</summary><div>

- `blockhash(uint blockNumber) returns (bytes32)`: hash of the given block when `blocknumber` is one of the 256 most recent blocks; otherwise returns zero
- `block.basefee` (`uint`): current block’s base fee (EIP-3198 and EIP-1559)
- `block.chainid` (`uint`): current chain id
- `block.coinbase` (`address payable`): current block miner’s address
- `block.difficulty` (`uint`): current block difficulty (`EVM < Paris`). For other EVM versions it behaves as a deprecated alias for `block.prevrandao` (EIP-4399)
- `block.gaslimit` (`uint`): current block gaslimit
- `block.number` (`uint`): current block number
- `block.prevrandao` (`uint`): random number provided by the beacon chain (`EVM >= Paris`)
- `block.timestamp` (`uint`): current block timestamp as seconds since unix epoch
- `gasleft() returns (uint256)`: remaining gas
- `msg.data` (`bytes calldata`): complete calldata
- `msg.sender` (`address`): sender of the message (current call)
- `msg.sig` (`bytes4`): first four bytes of the calldata (i.e. function identifier)
- `msg.value` (`uint`): number of wei sent with the message
- `tx.gasprice` (`uint`): gas price of the transaction
- `tx.origin` (`address`): sender of the transaction (full call chain)

:::note
Note
The values of all members of `msg`, including `msg.sender` and `msg.value` can change for every external function call. This includes calls to library functions.
:::

:::note
Note
When contracts are evaluated off-chain rather than in context of a transaction included in a block, you should not assume that `block.*` and `tx.*` refer to values from any specific block or transaction. These values are provided by the EVM implementation that executes the contract and can be arbitrary.
:::

:::note
Note
Do not rely on `block.timestamp` or `blockhash` as a source of randomness, unless you know what you are doing.

Both the timestamp and the block hash can be influenced by miners to some degree. Bad actors in the mining community can for example run a casino payout function on a chosen hash and just retry a different hash if they did not receive any money.

The current block timestamp must be strictly larger than the timestamp of the last block, but the only guarantee is that it will be somewhere between the timestamps of two consecutive blocks in the canonical chain.
:::

:::note
Note
The block hashes are not available for all blocks for scalability reasons. You can only access the hashes of the most recent 256 blocks, all other values will be zero.
:::

:::note
Note
The function `blockhash` was previously known as `block.blockhash`, which was deprecated in version 0.4.22 and removed in version 0.5.0.
:::

:::note
Note
The function `gasleft` was previously known as `msg.gas`, which was deprecated in version 0.4.21 and removed in version 0.5.0.
:::

:::note
Note
In version 0.7.0, the alias `now` (for `block.timestamp`) was removed.
:::

</div></details>

- `blockhash(uint blockNumber) returns (bytes32)`: `blocknumber` が最新の 256 ブロックのうちの 1 つである場合、与えられたブロックのハッシュを返します。 それ以外の場合はゼロを返します。
- `block.basefee` (`uint`): 現行ブロックの基本料金。（EIP-3198、EIP-1559）
- `block.chainid` (`uint`): 現在のチェーンID
- `block.coinbase` (`address payable`): 現在のブロックマイナーのアドレス
- `block.difficulty` (`uint`): 現在のブロックの難易度 (`EVM < Paris`). 他の EVM バージョンでは、 `block.prevrandao` の非推奨のエイリアスとして動作します。 (EIP-4399)
- `block.gaslimit` (`uint`): 現在のブロックガスリミット（gaslimit）
- `block.number` (`uint`): 現在のブロック番号
- `block.prevrandao` (`uint`): ビーコンチェーンから提供された乱数 (`EVM >= Paris`)
- `block.timestamp` (`uint`): 現在のブロックのタイムスタンプ (UNIXエポックからの秒数)
- `gasleft() returns (uint256)`: 残ガス
- `msg.data` (`bytes calldata`): 完全な calldata
- `msg.sender` (`address`): 送信者 (現在の通話)
- `msg.sig` (`bytes4`): calldataの最初の4バイト。（すなわち関数識別子）
- `msg.value` (`uint`): メッセージとともに送信されたweiの数
- `tx.gasprice` (`uint`): 取引きgas価格
- `tx.origin` (`address`): トランザクションの送信者 (コールチェーン全体)

:::note
Note
`msg.sender` と `msg.value` を含む `msg` のすべてのメンバの値は、外部関数を呼び出すたびに変更することができます。これには、ライブラリ関数の呼び出しも含まれます。
:::

:::note
Note
コントラクトがブロックに含まれるトランザクションのコンテキストではなく、オフチェーンで評価される場合、 `block.*` と `tx.*` が特定のブロックやトランザクションの値を参照していると仮定してはいけません。
これらの値は、コントラクトを実行する EVM 実装によって提供され、任意の値とすることができます。
:::

:::note
Note
自分が何をしているのか分からない限り、ランダム性の源として `block.timestamp` や `blockhash` に依存しないでください。

タイムスタンプもブロックハッシュも、ある程度は採掘者の影響を受ける可能性があります。
マイニングコミュニティの悪者は、例えば、選択したハッシュでカジノのペイアウト機能を実行し、お金を受け取らなかった場合、別のハッシュを再試行することができます。

現在のブロックのタイムスタンプは、最後のブロックのタイムスタンプよりも厳密に大きくなければならないが、唯一の保証は、正規のチェーンにおける連続した2つのブロックのタイムスタンプの間のどこかにあることです。
:::

:::note
Note
ブロックハッシュはスケーラビリティの観点から全てのブロックに対して利用できるわけではありません。
直近の256ブロックのハッシュにのみアクセスでき、それ以外の値はすべて0になります。
:::

:::note
Note
関数 `blockhash` は以前は `block.blockhash` として知られていましたが、バージョン 0.4.22 で非推奨となり、バージョン 0.5.0 で削除されました。
:::

:::note
Note
関数 `gasleft` は以前は `msg.gas` として知られていましたが、バージョン 0.4.21 で非推奨となり、バージョン 0.5.0 で削除されました。
:::

:::note
Note
バージョン 0.7.0 で、(`block.timestamp` の)エイリアス `now` が削除されました。
:::

### ABIエンコード・デコード関数（ABI Encoding and Decoding Functions）

<details><summary>原文</summary><div>

- `abi.decode(bytes memory encodedData, (...)) returns (...)`: ABI-decodes the given data, while the types are given in parentheses as second argument. Example: `(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))`
- `abi.encode(...) returns (bytes memory)`: ABI-encodes the given arguments
- `abi.encodePacked(...) returns (bytes memory)`: Performs packed encoding of the given arguments. Note that packed encoding can be ambiguous!
- `abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)`: ABI-encodes the given arguments starting from the second and prepends the given four-byte selector
- `abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)`: Equivalent to `abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`
- `abi.encodeCall(function functionPointer, (...)) returns (bytes memory)`: ABI-encodes a call to `functionPointer` with the arguments found in the tuple. Performs a full type-check, ensuring the types match the function signature. Result equals `abi.encodeWithSelector(functionPointer.selector, (...))`

:::note
Note
These encoding functions can be used to craft data for external function calls without actually calling an external function. 
Furthermore, `keccak256(abi.encodePacked(a, b))` is a way to compute the hash of structured data (although be aware that it is possible to craft a “hash collision” using different function parameter types).
:::

See the documentation about the ABI and the tightly packed encoding for details about the encoding.

</div></details>

- `abi.decode(bytes memory encodedData, (...)) returns (...)`: 与えられたデータを ABIデコードします、型は第2引数の括弧の中に与えられます。例：`(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))`
- `abi.encode(...) returns (bytes memory)`: 与えられた引数をABIエンコードします。
- `abi.encodePacked(...) returns (bytes memory)`: 与えられた引数に対して、packed エンコードを行います。packed エンコーディングは曖昧な場合があることに注意しましょう!
- `abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)`: 与えられた引数を2番目から順にABIエンコードし、与えられた4バイトのセレクタを前置します。
- `abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)`: Equivalent to `abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`
- `abi.encodeCall(function functionPointer, (...)) returns (bytes memory)`: タプルで見つかった引数で `functionPointer` を呼び出すことを ABI エンコードします。完全な型チェックを行い、型が関数のシグネチャと一致することを確認する。結果は `abi.encodeWithSelector(functionPointer.selector, (...))` と等しくなります。

:::note
Note
これらのエンコーディング関数は、実際に外部関数を呼び出すことなく、外部関数 呼び出し用のデータを細工するために使用することができます。
さらに、 `keccak256(abi.encodePacked(a, b))` は構造化データのハッシュを計算する方法です（ただし、異なる関数パラメータタイプを使用して「ハッシュの衝突」を工作することが可能であることに注意してください）。
:::

エンコーディングの詳細については、ABIと密閉型エンコーディングに関するドキュメントを参照してください。

### bytesのメンバ（Members of bytes）

<details><summary>原文</summary><div>

- `bytes.concat(...) returns (bytes memory)`: Concatenates variable number of bytes and bytes1, …, bytes32 arguments to one byte array

</div></details>

- `bytes.concat(...) returns (bytes memory)`: 可変長のバイト数と引数bytes1, ..., bytes32を1バイトの配列に連結します。

### stringのメンバ（Members of string）

<details><summary>原文</summary><div>

- `string.concat(...) returns (string memory)`: Concatenates variable number of string arguments to one string array

</div></details>

- `string.concat(...) returns (string memory)`: 可変個数の文字列引数を1つの文字列配列に連結します。

## エラー処理（Error Handling）

<details><summary>原文</summary><div>

See the dedicated section on assert and require for more details on error handling and when to use which function.

- `assert(bool condition)`
    causes a Panic error and thus state change reversion if the condition is not met - to be used for internal errors.

- `require(bool condition)`
    reverts if the condition is not met - to be used for errors in inputs or external components.

- `require(bool condition, string memory message)`
    reverts if the condition is not met - to be used for errors in inputs or external components. Also provides an error message.

- `revert()`
    abort execution and revert state changes

- `revert(string memory reason)`
    abort execution and revert state changes, providing an explanatory string

</div></details>

エラー処理の詳細と、どの関数をいつ使うかについては、assertとrequireの専用セクションをご覧ください。

- `assert(bool condition)`
    条件を満たさない場合、パニックエラーとなり、状態変化を戻す - 内部エラーに使用されます。

- `require(bool condition)`
    条件を満たさない場合、元に戻す - 入力や外部コンポーネントのエラーに使用されます。

- `require(bool condition, string memory message)`
    条件を満たさない場合、元に戻す - 入力や外部コンポーネントのエラーに使用されます。また、エラーメッセージも表示されます。

- `revert()`
    実行を中止し、状態の変化を元に戻します。

- `revert(string memory reason)`
    実行を中止し、状態変化を元に戻す、説明文字列を提供します。

### 数学的・暗号学的関数（Mathematical and Cryptographic Functions）

<details><summary>原文</summary><div>

- `addmod(uint x, uint y, uint k) returns (uint)`
    compute `(x + y) % k` where the addition is performed with arbitrary precision and does not wrap around at `2**256`. Assert that `k != 0` starting from version 0.5.0.

- `mulmod(uint x, uint y, uint k) returns (uint)`
    compute `(x * y) % k` where the multiplication is performed with arbitrary precision and does not wrap around at `2**256`. Assert that `k != 0` starting from version 0.5.0.

- `keccak256(bytes memory) returns (bytes32)`
    compute the Keccak-256 hash of the input

:::note
Note
There used to be an alias for keccak256 called sha3, which was removed in version 0.5.0.
:::

- `sha256(bytes memory) returns (bytes32)`
    compute the SHA-256 hash of the input

- `ripemd160(bytes memory) returns (bytes20)`
    compute RIPEMD-160 hash of the input

- `ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)`
    recover the address associated with the public key from elliptic curve signature or return zero on error. The function parameters correspond to ECDSA values of the signature:

    - `r` = first 32 bytes of signature
    - `s` = second 32 bytes of signature
    - `v` = final 1 byte of signature

    `ecrecover` returns an `address`, and not an `address payable`. See address payable for conversion, in case you need to transfer funds to the recovered address.

    For further details, read example usage.

:::note warn
Warning
If you use `ecrecover`, be aware that a valid signature can be turned into a different valid signature without requiring knowledge of the corresponding private key. In the Homestead hard fork, this issue was fixed for _transaction_ signatures (see EIP-2), but the ecrecover function remained unchanged.

This is usually not a problem unless you require signatures to be unique or use them to identify items. OpenZeppelin have a ECDSA helper library that you can use as a wrapper for `ecrecover` without this issue.
:::

:::note
Note
When running `sha256`, `ripemd160` or `ecrecover` on a private blockchain, you might encounter Out-of-Gas. This is because these functions are implemented as “precompiled contracts” and only really exist after they receive the first message (although their contract code is hardcoded). Messages to non-existing contracts are more expensive and thus the execution might run into an Out-of-Gas error. A workaround for this problem is to first send Wei (1 for example) to each of the contracts before you use them in your actual contracts. This is not an issue on the main or test net.
:::

</div></details>

- `addmod(uint x, uint y, uint k) returns (uint)`
    `(x + y) % k` を計算します。ここで、加算は任意の精度で行われ、 `2**256` で折り返されることはありません。バージョン 0.5.0 からは `k != 0` であることを仮定しています。

- `mulmod(uint x, uint y, uint k) returns (uint)`
    `(x * y) % k` を計算します。ここで、乗算は任意の精度で実行され、`2**256`で折り返されることはありません。バージョン 0.5.0 からは `k != 0` であることを仮定しています。

- `keccak256(bytes memory) returns (bytes32)`
    入力のKeccak-256ハッシュを計算します。

:::note
Note
以前は、keccak256の別名としてsha3というものがありましたが、バージョン0.5.0で削除されました。
:::

- `sha256(bytes memory) returns (bytes32)`
    入力のSHA-256ハッシュを計算します。

- `ripemd160(bytes memory) returns (bytes20)`
    入力のRIPEMD-160ハッシュを計算します。

- `ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)`
    楕円曲線署名から公開鍵に関連付けられたアドレスを復元するか、エラー時に0を返します。この関数のパラメータは、署名のECDSA値に対応します。

    - `r` = 署名の最初の32バイト
    - `s` = 署名の2番目の32バイト
    - `v` = 署名の最後の1バイト

    `ecrecover` は `address` を返しますが、 `address payable` は返しません。回収されたaddressに資金を振り込む必要がある場合に備えて、変換用の address payable を参照してください。

    詳しくは、使用例をご覧ください。

:::note warn
Warning
`ecrecover`を使用する場合、有効な署名は対応する秘密鍵の知識がなくても、別の有効な署名に変わる可能性があることに注意してください。Homesteadハードフォークでは、この問題は \_transaction\_ signatures で修正されたが (EIP-2 参照)、ecrecover 関数はそのままです。

これは、署名が一意であることを要求したり、アイテムを識別するために使用したりしない限り、通常は問題ではありません。OpenZeppelinにはECDSAヘルパーライブラリがあり、この問題なしに `ecrecover` のラッパーとして使用することができます。
:::

:::note
Note
プライベートブロックチェーンで `sha256`、`ripemd160` または `ecrecover` を実行すると、Out-of-Gas に遭遇することがあります。
これは、これらの関数が「プリコンパイルされたコントラクト」として実装されており、最初のメッセージを受信した後でのみ実際に存在するからです。（ただし、コントラクトコードはハードコーディングされています）
存在しないコントラクトへのメッセージはより高価であるため、実行時にOut-of-Gasエラーに遭遇する可能性があります。
この問題を回避するには、実際のコントラクトで使用する前に、まずWei（例えば1）を各コントラクトに送信することです。
これは、メインネットやテストネットでは問題ありません。
:::

## アドレス型のメンバ（Members of Address Types）

<details><summary>原文</summary><div>

- `<address>.balance` (`uint256`)
    balance of the Address in Wei

- `<address>.code` (`bytes memory`)
code at the Address (can be empty)

- `<address>.codehash` (`bytes32`)
    the codehash of the Address

- `<address payable>.transfer`(`uint256 amount`)
    send given amount of Wei to Address, reverts on failure, forwards 2300 gas stipend, not adjustable

- `<address payable>.send(uint256 amount) returns (bool)`
    send given amount of Wei to Address, returns false on failure, forwards 2300 gas stipend, not adjustable

- `<address>.call(bytes memory) returns (bool, bytes memory)`
    issue low-level `CALL` with the given payload, returns success condition and return data, forwards all available gas, adjustable

- `<address>.delegatecall(bytes memory) returns (bool, bytes memory)`
    issue low-level `DELEGATECALL` with the given payload, returns success condition and return data, forwards all available gas, adjustable

- `<address>.staticcall(bytes memory) returns (bool, bytes memory)`
    issue low-level `STATICCALL` with the given payload, returns success condition and return data, forwards all available gas, adjustable

For more information, see the section on Address.

:::note warn
Warning
You should avoid using `.call()` whenever possible when executing another contract function as it bypasses type checking, function existence check, and argument packing.
:::

:::note warn
Warning
There are some dangers in using `send`: The transfer fails if the call stack depth is at 1024 (this can always be forced by the caller) and it also fails if the recipient runs out of gas.
So in order to make safe Ether transfers, always check the return value of `send`, use `transfer` or even better: Use a pattern where the recipient withdraws the money.
:::

:::note warn
Warning
Due to the fact that the EVM considers a call to a non-existing contract to always succeed, Solidity includes an extra check using the `extcodesize` opcode when performing external calls.
This ensures that the contract that is about to be called either actually exists (it contains code) or an exception is raised.

The low-level calls which operate on addresses rather than contract instances (i.e. `.call()`, `.delegatecall()`, `.staticcall()`, `.send()` and `.transfer()`) do not include this check, which makes them cheaper in terms of gas but also less safe.
:::

:::note
Note
Prior to version 0.5.0, Solidity allowed address members to be accessed by a contract instance, for example `this.balance`.
This is now forbidden and an explicit conversion to address must be done: `address(this).balance`.
:::

:::note
Note
If state variables are accessed via a low-level delegatecall, the storage layout of the two contracts must align in order for the called contract to correctly access the storage variables of the calling contract by name.
This is of course not the case if storage pointers are passed as function arguments as in the case for the high-level libraries.
:::

:::note
Note
Prior to version 0.5.0, `.call`, `.delegatecall` and `.staticcall` only returned the success condition and not the return data.
:::

:::note
Note
Prior to version 0.5.0, there was a member called `callcode` with similar but slightly different semantics than `delegatecall`.
:::

</div></details>

- `<address>.balance` (`uint256`)
    Wei単位のAddress残高

- `<address>.code` (`bytes memory`)
    Addressのコード (空にすることができます)

- `<address>.codehash` (`bytes32`)
    Addressのコードハッシュ

- `<address payable>.transfer`(`uint256 amount`)
    指定された量の Wei を Address に送信、失敗した場合は元に戻します、2300 ガスの給付金を転送します。調整はできません。

- `<address payable>.send(uint256 amount) returns (bool)`
    指定された量の Wei を Address に送信し、失敗した場合は false を返します、2300 ガスの給付金を転送します。調整はできません。

- `<address>.call(bytes memory) returns (bool, bytes memory)`
    与えられたペイロードで低レベルの `CALL` を発行し、成功条件と戻りデータを返し、利用可能なすべてのgasを転送します。調整可能です。

- `<address>.delegatecall(bytes memory) returns (bool, bytes memory)`
    与えられたペイロードで低レベルの `DELEGATECALL` を発行し、成功条件と戻りデータを返し、利用可能なすべてのgasを転送します。調整可能です。

- `<address>.staticcall(bytes memory) returns (bool, bytes memory)`
    与えられたペイロードで低レベルの `STATICCALL` を発行し、成功条件と戻りデータを返し、利用可能なすべてのgasを転送します。調整可能です。

詳しくは、Address の項をご覧ください。

:::note warn
Warning
型チェック、関数の存在チェック、引数のパッキングをバイパスしてしまうので、他のコントラクト関数を実行する際には、できる限り `.call()` を使用しないようにすべきです。
:::

:::note warn
Warning
`send` を使用する際にはいくつかの危険性があります。呼び出しスタックの深さが 1024 になっていると転送に失敗します (これは呼び出し側で常に強制することができます) し、受信側がgas欠になると転送に失敗します。
したがって、安全に Ether を転送するためには、常に `send` の戻り値を確認し、 `transfer` を使用するか、より良い方法を探してください。受信者がお金を引き出すパターンを使用します。
:::

:::note warn
Warning
Solidity では外部呼び出しの際に `extcodesize` オペコードを使用した特別なチェックを行います。
これにより、呼び出されようとしているコントラクトが実際に存在する (コードを含む) か、例外が発生するかが確認されます。

コントラクトインスタンスではなくアドレスを操作する低レベルコール (`.call()`, `.delegatecall()`, `.staticcall()`, `.send()`, `.transfer()`) には、このチェックがありません。これはガスの点では安価ですが、安全性も低くなっています。
:::

:::note
Note
バージョン 0.5.0 以前の Solidity では、コントラクト インスタンス (例: `this.balance`) によってアドレス メンバーにアクセスすることが可能でした。
これは現在では禁止されており、アドレスへの明示的な変換を行う必要があります。アドレスへの明示的な変換が必要です。： `address(this).balance`
:::

:::note
Note
低レベルのデリゲートコールで状態変数にアクセスする場合、呼び出されたコントラクトが呼び出したコントラクトの記憶変数に名前で正しくアクセスできるように、2つのコントラクトの記憶レイアウトを一致させる必要があります。
もちろん、高レベルライブラリのように、ストレージポインタが関数の引数として渡される場合は、この限りではありません。
:::

:::note
Note
バージョン 0.5.0 より前の `.call`, `.delegatecall`, `.staticcall` は成功条件のみを返し、戻り値のデータは返しませんでした。
:::

:::note
Note
バージョン 0.5.0 より前のバージョンでは、 `delegatecall` と似ているが少し異なるセマンティクスを持つ `callcode` という名前のメンバが存在しました。
:::

### コントラクト関連（Contract Related）

<details><summary>原文</summary><div>

- `this` (current contract’s type)
    the current contract, explicitly convertible to Address

- `selfdestruct(address payable recipient)`
    Destroy the current contract, sending its funds to the given Address and end execution. Note that selfdestruct has some peculiarities inherited from the EVM:

    - the receiving contract’s receive function is not executed.
    - the contract is only really destroyed at the end of the transaction and `revert` s might “undo” the destruction.

Furthermore, all functions of the current contract are callable directly including the current function.

:::note warn
Warning
From version 0.8.18 and up, the use of `selfdestruct` in both Solidity and Yul will trigger a deprecation warning, since the `SELFDESTRUCT` opcode will eventually undergo breaking changes in behaviour as stated in EIP-6049.
:::

:::note
Note
Prior to version 0.5.0, there was a function called `suicide` with the same semantics as `selfdestruct`.
:::

</div></details>

- `this` (現コントラクトの型)
    現コントラクトでは、明示的にアドレスに変換されます。

- `selfdestruct(address payable recipient)`
    現コントラクトを破棄し、その資金を与えられたアドレスに送り、実行を終了します。自爆には、EVMから継承されたいくつかの特殊性があることに注意してください。

    - 受信コントラクトの受信機能は実行されません。
    - コントラクトはトランザクションの終了時にのみ本当に破棄され、`revert`はその破棄を「元に戻す」かもしれません。

さらに、現在のコントラクトのすべての関数は、現在の関数を含めて直接呼び出すことができます。

:::note warn
Warning
バージョン 0.8.18 以降では、Solidity と Yul の両方で `selfdestruct` を使用すると、非推奨の警告がトリガーされます。これは、EIP-6049 に記載されているように、 `SELFDESTRUCT` オプコードの動作が最終的に破壊的変更を受けるためです。
:::

:::note
Note
バージョン 0.5.0 より前のバージョンでは、 `selfdestruct` と同じセマンティクスを持つ `suicide` という関数がありました。
:::

### 型情報（Type Information）

<details><summary>原文</summary><div>

The expression `type(X)` can be used to retrieve information about the type `X`.
Currently, there is limited support for this feature (`X` can be either a contract or an integer type) but it might be expanded in the future.

The following properties are available for a contract type `C`:

- `type(C).name`
    The name of the contract.

- `type(C).creationCode`
    Memory byte array that contains the creation bytecode of the contract. This can be used in inline assembly to build custom creation routines, especially by using the `create2` opcode.
    This property can not be accessed in the contract itself or any derived contract.
    It causes the bytecode to be included in the bytecode of the call site and thus circular references like that are not possible.

- `type(C).runtimeCode`
    Memory byte array that contains the runtime bytecode of the contract.
    This is the code that is usually deployed by the constructor of `C`. If `C` has a constructor that uses inline assembly, this might be different from the actually deployed bytecode. Also note that libraries modify their runtime bytecode at time of deployment to guard against regular calls.
    The same restrictions as with `.creationCode` also apply for this property.

In addition to the properties above, the following properties are available for an interface type `I`:

- `type(I).interfaceId:`
    A `bytes4` value containing the EIP-165 interface identifier of the given interface `I`.
    This identifier is defined as the `XOR` of all function selectors defined within the interface itself - excluding all inherited functions.

The following properties are available for an integer type `T`:

- `type(T).min`
    The smallest value representable by type `T`.

- `type(T).max`
    The largest value representable by type `T`.

</div></details>

`type(X)` 式は、型 `X` に関する情報を取得するために使用できます。
現在のところ、この機能のサポートは限られていますが (`X` はコントラクト型でも整数型でもよい)、将来的には拡張されるかもしれません。

コントラクト型 `C` では、以下のプロパティが利用可能です。

- `type(C).name`
    コントラクトの名称です。

- `type(C).creationCode`
    コントラクトの作成バイトコードを含むメモリバイト配列です。
    これはインラインアセンブリで、特に `create2` オペコードを使用して、カスタムの作成ルーチンを構築するために使用することができます。
    このプロパティはコントラクト自身や派生コントラクトからはアクセスすることができません。
    これは、バイトコードが呼び出し元のバイトコードに含まれるため、循環参照は不可能です。

- `type(C).runtimeCode`
    コントラクトのランタイムバイトコードを格納したメモリバイト配列です。
    これは、通常 `C` のコンストラクタによって展開されるコードです。
もし `C` がインラインアセンブリを使用するコンストラクタを持っているなら、これは実際にデプロイされるバイトコードとは異なるかもしれません。
    また、ライブラリは通常の呼び出しから保護するために、デプロイ時にランタイムバイトコードを変更することに注意してください。
    このプロパティには、 `.creationCode` と同じ制限が適用されます。

インターフェースタイプ `I` では、上記のプロパティに加えて、以下のプロパティが利用可能です。

- `type(I).interfaceId:`
    指定されたインターフェイス `I` の EIP-165 インターフェイス識別子を含む `bytes4` 値です。
     この識別子は、継承されたすべての関数を除く、インターフェイス自体内で定義されたすべての関数セレクターの `XOR` として定義されます。

整数型 `T` に対して、以下のプロパティを設定できます。

- `type(T).min`
    型 `T` で表現可能な最小の値です。

- `type(T).max`
    型 `T` で表現できる最大の値です。

## 予約キーワード（Reserved Keywords）

<details><summary>原文</summary><div>

These keywords are reserved in Solidity.
They might become part of the syntax in the future:

`after`, `alias`, `apply`, `auto`, `byte`, `case`, `copyof`, `default`, `define`, `final`, `implements`, `in`, `inline`, `let`, `macro`, `match`, `mutable`, `null`, `of`, `partial`, `promise`, `reference`, `relocatable`, `sealed`, `sizeof`, `static`, `supports`, `switch`, `typedef`, `typeof`, `var`.

</div></details>

これらのキーワードは Solidity で予約されています。
これらは将来的に構文の一部になる可能性があります。

`after`, `alias`, `apply`, `auto`, `byte`, `case`, `copyof`, `default`, `define`, `final`, `implements`, `in`, `inline`, `let`, `macro`, `match`, `mutable`, `null`, `of`, `partial`, `promise`, `reference`, `relocatable`, `sealed`, `sizeof`, `static`, `supports`, `switch`, `typedef`, `typeof`, `var`

# さいごに

`addmod`や`mulmod`が使えるので、暗号系の計算もSolidityで実装できそうです。
（いままでは、uint256を超える計算ができないと思っていた・・・）
まあ、gas代が沢山かかりそうではありますが・・・

そして、`ecrecover`を使うなら、OpenZeppelinのヘルパーを使えと・・・
EIP-2を見てみると、スモール`s`を採用するということらしいです。

> 2. All transaction signatures whose s-value is greater than `secp256k1n/2` are now considered invalid. The ECDSA recover precompiled contract remains unchanged and will keep accepting high s-values; this is useful e.g. if a contract recovers old Bitcoin signatures.

> 2. s 値が `secp256k1n/2` より大きいすべてのトランザクション署名は、無効と見なされるようになりました。 ECDSA のプリコンパイル済みコントラクトは変更されず、高い S 値を受け入れ続けます。 これは便利です。 コントラクトが古いビットコイン署名を回復した場合。

https://eips.ethereum.org/EIPS/eip-2#specification