Units and Globally Available Variables¶
Ether Units¶
A literal number can take a suffix of wei
, finney
, szabo
or ether
to convert between the subdenominations of Ether, where Ether currency numbers without a postfix are assumed to be Wei, e.g. 2 ether == 2000 finney
evaluates to true
.
Time Units¶
Suffixes like seconds
, minutes
, hours
, days
, weeks
and
years
after literal numbers can be used to convert between 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
1 years == 365 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.
Catatan
The suffix years
has been deprecated due to the reasons above and cannot be used starting version 0.5.0.
These suffixes cannot be applied to variables. If you want to interpret some input variable in e.g. days, you can do it in the following way:
function f(uint start, uint daysAfter) public {
if (now >= start + daysAfter * 1 days) {
// ...
}
}
Special Variables and Functions¶
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.
Block and Transaction Properties¶
block.blockhash(uint blockNumber) returns (bytes32)
: hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced byblockhash(uint blockNumber)
.block.coinbase
(address
): current block miner's addressblock.difficulty
(uint
): current block difficultyblock.gaslimit
(uint
): current block gaslimitblock.number
(uint
): current block numberblock.timestamp
(uint
): current block timestamp as seconds since unix epochgasleft() returns (uint256)
: remaining gasmsg.data
(bytes
): complete calldatamsg.gas
(uint
): remaining gas - deprecated in version 0.4.21 and to be replaced bygasleft()
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 messagenow
(uint
): current block timestamp (alias forblock.timestamp
)tx.gasprice
(uint
): gas price of the transactiontx.origin
(address
): sender of the transaction (full call chain)
Catatan
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.
Catatan
Do not rely on block.timestamp
, now
and 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.
Catatan
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.
ABI Encoding Functions¶
abi.encode(...) returns (bytes)
: ABI-encodes the given argumentsabi.encodePacked(...) returns (bytes)
: Performs packed encoding of the given argumentsabi.encodeWithSelector(bytes4 selector, ...) returns (bytes)
: ABI-encodes the given arguments starting from the second and prepends the given four-byte selectorabi.encodeWithSignature(string signature, ...) returns (bytes)
: Equivalent toabi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)`
Catatan
These encoding functions can be used to craft data for function calls without actually
calling a 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 inputs types).
See the documentation about the ABI and the tightly packed encoding for details about the encoding.
Error Handling¶
assert(bool condition)
:- invalidates the transaction 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 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 reason)
:- abort execution and revert state changes, providing an explanatory string
Mathematical and Cryptographic Functions¶
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 at2**256
. Assert thatk != 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 at2**256
. Assert thatk != 0
starting from version 0.5.0. keccak256(bytes memory) returns (bytes32)
:- compute the Ethereum-SHA-3 (Keccak-256) hash of the input
sha256(bytes memory) returns (bytes32)
:- compute the SHA-256 hash of the input
sha3(bytes memory) returns (bytes32)
:- alias to
keccak256
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 (example usage)
It might be that you run into Out-of-Gas for sha256
, ripemd160
or ecrecover
on a private blockchain. The reason for this is that those are implemented as so-called precompiled contracts and these contracts only really exist after they received the first message (although their contract code is hardcoded). Messages to non-existing contracts are more expensive and thus the execution runs into an Out-of-Gas error. A workaround for this problem is to first send e.g. 1 Wei to each of the contracts before you use them in your actual contracts. This is not an issue on the official or test net.