Solidity is a popular programming language for writing smart contracts on the Ethereum blockchain. In Solidity, global variables play a crucial role in the functioning of smart contracts. These variables provide important information about the state and context of the blockchain, making it possible to create complex, decentralized applications. In this article, we will explore Solidity global variables, their different types, and their various uses.
What are Solidity Global Variables?
Global variables in Solidity are predefined variables that hold information about the current state of the Ethereum blockchain and the execution context of a smart contract. These variables are accessible from any part of a contract and are often used to access blockchain-specific data or manipulate the contract’s state. Understanding the types and uses of these global variables is essential for writing efficient and secure smart contracts.
The main variables we will be covering are: block
, msg
, and tx
.
Block
The block
is where the block—chain got its name. The blockchain works by creating new blocks and chaining them together linearly. Anytime a new block is created, it carries a set of transactions with it, those being invocations to smart contract functions. Those same functions can have access to their current carrier block, which grants them access to its information.
A block’s information includes details about its number in the blockchain, its mining difficulty, and a bunch of other stuff. The main attribute that we need to focus on however, is the block timestamp
.
The timestamp of a block indicates when this block has been mined. This is very important because it allows us to keep records of when a transaction has occurred. We can use those records to restrict interaction with a contract for a certain amount of time, or reward certain users based on timely dependent interactions with the contract.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
contract GlobalVariables {
uint256 constant MIN_TIME_BETWEEN_INTERACTIONS = 15 minutes;
uint256 lastInteraction;
function doSomeStuff() external {
require(
block.timestamp - lastInteraction > MIN_TIME_BETWEEN_INTERACTIONS,
"Not enough time has passed since last interaction"
);
lastInteraction = block.timestamp;
// do some stuff
}
}
Hint: The block.timesamp
is represented in seconds according to the UNIX timestamp. Solidity offers a set of numeric types such as minutes, hours, days… which are also represented in seconds (eg. 2 hours = 2 * 60 minutes * 60 seconds = 7200 seconds). These types are built into Solidity to ease time based comparisons such as the one in the example.
Msg
Similar to how a block
carries information about its attributes in the blockchain, a msg
carries information about a contract function call.
A msg
also has a few attributes, the most common of which are the sender
and value
.
The sender of a msg, as the name suggest, is the person or contract calling the function. The value on the other hand, contrary to what its name suggests, is not about the inputs being given to the function. The value is actually the amount of WEi sent to the contract, which is a currency in the Ethereum ecosystem that can be converted to Ether.
We can use the msg sender to keep track of certain users or contracts and their interactions with ours. And we can use the msg value to handle payments in our contract.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
contract GlobalVariables {
uint256 constant MIN_DONATION = 0.01 ether;
uint256 constant MAX_DONATION = 100 ether;
mapping(address => uint256) public donations;
function donate() external payable {
require(
msg.value >= MIN_DONATION,
"Donation must be at least 0.01 ether"
);
require(msg.value <= MAX_DONATION, "Donation can be at most 100 ether");
donations[msg.sender] += msg.value;
// do some stuff
}
}
Hint: Similar to time based units, Solidity offers currency based units to ease currency based computations.
Tx
The word tx
is a shorthand for the word transaction. You might be wondering what is the difference between a msg
and a tx
then. While the msg
carries data about the function call, the tx
carries data about the entire transaction chain. The only properties exposed by tx
are gasprice
and origin
.
To give an example: if a user calls contract A, which in turn calls contract B, the msg sender in contract B would be contract A, while the tx origin would be the user themselves.
The tx
is rarely a variable that you would use, and it’s generally a good practice to avoid it.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
contract GlobalVariables {
mapping(address => uint256) public donations;
//* good
function donate() external payable {
donations[msg.sender] += msg.value;
// do some stuff
}
//! bad
function donateFromOrigin() external payable {
donations[tx.origin] += msg.value;
// do some stuff
}
}
For a deeper understanding of how these global variables are effectively utilized within Solidity’s control structures, explore our comprehensive guide on control structures in Solidity.
All global variables
For a full list of Solidity global variables, you can reference the table below:
Name | Returns |
---|---|
blockhash(uint blockNumber) | Hash of the given block – only works for 256 most recent, excluding current, blocks |
block.coinbase | Current block miner’s address |
block.difficulty | Current block difficulty |
block.gaslimit | Current block gas limit |
block.number | Current block number |
block.timestamp | Current block timestamp as seconds since UNIX epoch |
gasleft() | Remaining gas |
msg.data | Complete calldata |
msg.sender | Sender of the message (current caller) |
msg.sig | First four bytes of the calldata (function identifier) |
msg.value | Number of wei sent with the message |
now | Current block timestamp |
tx.gasprice | Gas price of the transaction |
tx.origin | Sender of the transaction |
You can also find a more in depth explanation for every variable and its usage in the official Solidity documentation.
Don’t miss out our previous articles on Solidity Variables and Solidity Functions!
1. What is a global variable in Solidity?
- Global variables are special variables available in Solidity that provide information about the blockchain or the transaction itself. They can be used to retrieve data about the current block, transaction, or contract execution.
2. Can I get the miner’s address of the current block?
- Yes, you can access the miner’s address of the current block using
block.coinbase
.
3. How can I access the current block difficulty?
- The current block difficulty can be accessed via
block.difficulty
.
4. How to get the remaining gas in Solidity?
- You can get the remaining gas using the
gasleft()
function.
5. What does msg.sender
indicate in Solidity?
msg.sender
is a global variable that denotes the address of the caller of the current function.
6. How can we check the number of wei sent with a message?
- The number of wei sent with the current message can be verified via
msg.value.
7. Can I get the timestamp of the current block?
- Yes, the timestamp of the current block can be obtained using
block.timestamp
ornow
.
8. What is the purpose of msg.data
in Solidity?
msg.data
contains the complete calldata, which is the data passed in the call to the function in the contract.
9. What is tx.origin
in Solidity?
-
tx.origin
refers to the original entity that initiated the transaction. It could be different frommsg.sender
in case contracts are calling each other.
10. How to get the gas price of the transaction?
- The gas price of the transaction can be retrieved using
tx.gasprice
.