Units and Global Variables

Working with numbers, made easy!

Solidity provides a wide array of predefined units and variables that facilitate both logical and mathematical calculations. In this section we will go over some of the most commonly used ones.

Units

Solidity provides two types of units: ether units and time units.

Ether Units

Recall that the EVM denominates ether in terms of Wei (1 wei = 10**(-18) ether). Therefore, consider the following code that checks if an account has a balance of 1 ether:

if (account.balance == 10**18) {}

Having to specify an exact integer, especially for integers as large as 10**18, can lead to both bugs and legibility issues. Rather than specifying an exact value, we can utilize units.

if (account.balance == 1 ether) {}

In the code above, we are checking if the account has exactly 1 ether. Under the hood, we are still checking if the account has a balance of 10**18, but it is obvious that using units makes our code easier to read and less prone to bugs. Likewise, we can use units in state/local variables as well:

uint num = 1 ether;

Solidity provides us with the following ether units:

  • wei

  • gwei

  • ether

Time Units

The EVM (and computers in general) denominate time in terms of seconds. Dealing with seconds might be a headache for some and for this reason, Solidity provides us with time units. As an example, consider the following code:

function redeem() public {
        if (lastTimeCalled + 3600 < currentTime) {}
}

In the code above, we have a function which performs some logic if it has been more than a hour since the last time it was called; we check this by adding 3600 to lastTimeCalled. Again, denominating seconds explicitly introduces both legibility issues and the potential for bugs. Instead, we can use time units:

function redeem() public {
        if (lastTimeCalled + 1 hours < currentTime) {}
}

Listed below are the time units that Solidity provides:

  • seconds

  • minutes

  • hours

  • days

  • weeks

Again, note that all these units are denominated in terms of seconds.

Global Variables

As the name might suggest, global variables are values that are available at a global level. Listed below are some of the most commonly-used global variables:

  • block.gaslimit: the gas limit of the current block

  • block.number: the number of the current block

  • block.timestamp: the time at which the current block was published

  • msg.data: the data attached with the current message

  • msg.sender: the sender of the current message

  • msg.value: the amount of ether (denominated in wei) that was sent with the current message

  • tx.gasprice: the price per gas paid for the current transaction

  • tx.origin: the account that sent the current transaction

Transactions Vs Messages

Although transactions and messages might seem synonymous, there is a big difference between the two terms. Consider the following transaction:

I call contract A. Halfway through the execution of contract A, contract A calls contract B.

Transaction here refers to the entire execution context. In this scenario, tx.origin is my address (tx.origin is always the address of an EOA). Messages, meanwhile, refer to a specific execution environment. In the scenario above, there are two messages:

  • Message 1: consists of me as the sender and contract A as the recipient.

  • Message 2: consists of contract A as the sender and contract B as the recipient.

An easy way to think about messages is that a new message is created whenever the from/to values of the execution environment changes.

Resources

Solidity Docs: https://docs.soliditylang.org/en/v0.8.17/units-and-global-variables.html

Last updated