Units and Globally Available Variables
Units and Globally Available Variables
Ether Units
A literal number can take a suffix of wei
, finney
, szabo
or ether
to specify a subdenomination of Ether, where Ether numbers without a postfix are assumed to be Wei.
assert(1 wei == 1);
assert(1 szabo == 1e12);
assert(1 finney == 1e15);
assert(1 ether == 1e18);
The only effect of the subdenomination suffix is a multiplication by a power of ten.
Time Units
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.
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
blockhash(uint blockNumber) returns (bytes32)
: hash of the given block - only works for 256 most recent, excluding current, blocksblock.coinbase
(address payable
): 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 calldata
): complete calldatamsg.sender
(address payable
): 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 payable
): sender of the transaction (full call chain)
ABI Encoding and Decoding Functions
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 argumentsabi.encodePacked(...) returns (bytes memory)
: Performs packed encoding of the given argumentsabi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)
: ABI-encodes the given arguments starting from the second and prepends the given four-byte selectorabi.encodeWithSignature(string memory signature, ...) returns (bytes memory)
: Equivalent toabi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`
See the documentation about the ABI and the tightly packed encoding for details about the encoding.
Error Handling
See the dedicated section on assert and require for more details on error handling and when to use which function.assert(bool condition)
:causes an invalid opcode 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 changesrevert(string memory 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 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 inputsha256(bytes memory) returns (bytes32)
:compute the SHA-256 hash of the inputripemd160(bytes memory) returns (bytes20)
:compute RIPEMD-160 hash of the inputecrecover(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)
Members of Address Types
.balance
(uint256
):balance of the Address in Wei payable>.transfer(uint256 amount)
:send given amount of Wei to Address, reverts on failure, forwards 2300 gas stipend, not adjustable payable>.send(uint256 amount) returns (bool)
:send given amount of Wei to Address, returns false
on failure, forwards 2300 gas stipend, not adjustable.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.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.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.
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.
Last updated
Was this helpful?