Introduction Smart Contract Variables
Contents
#EnterTheSmartContractSecuritySeries004
In this post, we will take a detailed look at variables in the Solidity programming language, which is used to develop smart contracts on the Ethereum blockchain. The variables used to store and manipulate data within smart contracts are categorized into Solidity’s three basic types: local, state, and global. A thorough understanding of these variable types is fundamental to writing effective and secure smart contracts.
Local Variables:
Local variables are defined within functions in Solidity and are only accessible within the scope of that function, and are deleted from memory after the function call completes. The use of local variables is ideal for storing temporary data in computational processes or storing intermediate results. They save on gas cost as they are not stored on the blockchain and are only used to store temporary values during function execution.
Features:
Lifespan:
Local variables are created when the function they are defined for is called and are destroyed when the function is finished executing.
Memory Management:
Solidity stores local variables in a memory region called “stack”. The stack has a limited storage space, so it may not be convenient to store very large data structures as local variables.
Gas Savings:
Since local variables are not written on the blockchain, their use reduces the cost of gas.
Usage Scenarios
Interim Calculations:
Used to store intermediate values during calculations within a function.
Loop Indexes:
Local variables such as loop counters are often used to control structures such as for loops.
Function Parameters:
Parameters passed to a function are technically local variables and are accessible within the scope of the function.
pragma solidity ^0.8.17;
contract ExampleContract {
function calculateSum(uint[] memory numbers) public pure returns (uint) {
uint sum = 0; // Local variable
for (uint i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
return sum; // sum returns the sum calculated here
}
}
In this example, sum and i are local variables. sum is used to calculate the sum and i is used as the index for the loop. When the function terminates, there is no trace of these variables and the transaction cost is low because they do not make any changes to the blockchain.
State Variables:
State variables are used to store persistent data for smart contracts in Solidity. These variables are stored in the contract’s storage on the blockchain and remain accessible for the lifetime of the contract. State variables are variables that describe the state of a smart contract and retain their values between functions and between transactions.
Properties:
Persistence:
Since state variables are stored on the blockchain, their values are retained even after the execution of the smart contract has ended.
Access Control:
State variables can be assigned different access tokens such as public, private, internal and external. These tokens control who can access the variables and how they can be viewed.
Cost:
When the value of the state variables is changed, this process incurs gas usage because data is written on the blockchain.
Usage Scenarios:
Contract Resource Management: For example, maintaining the balances of users of a smart contract.
Contract Settings:
Parameters that control contract behavior (e.g., minimum payment amount).
Authorization Control:
Storing authorization levels to be able to perform certain operations.
pragma solidity ^0.8.17;
contract Bank {
mapping(address => uint) public balances; // State variable
function deposit() public payable {
balances[msg.sender] += msg.value; // Balance update
}
function withdraw(uint amount) public {
require(balances[msg.sender] >= amount, “Insufficient balance”);
payable(msg.sender).transfer(amount);
balances[msg.sender] -= amount; // Balance decrease
}
}
In this example, balances is a state variable and holds the balance of each user. deposit and withdraw functions update this variable to increase or decrease the user’s balance. Since these transactions take place on the blockchain, the changes are persistent and require gas costs.
Conclusion:
State variables are critical for storing the persistent state of smart contracts in Solidity. When used correctly, they ensure data integrity between smart contracts’ functions and interactions between users. However, since every change is costly, it is important to optimize data storage and update processes.
Global Variables:
Global variables in Solidity provide important information about the blockchain network of smart contracts and transactions. These variables can be used in any function during smart contract execution and contain data specific to the contract’s operating context. Global variables make it easier for smart contracts to access transaction details and blockchain state, making them valuable for processing information such as timestamps, block information and transaction data.
Features:
Accessibility:
Global variables are accessible and readable from any function of the contract.
Information Provision:
They provide information about the transaction and blockchain properties, such as sending address, block number, gas price, etc.
Cost of Reading:
Reading global variables usually does not require gas cost (except for state variables).
Usage Scenarios:
Timecontrolled Transactions: to perform transactions at specific times using block.timestamp or to record events by adding a timestamp.
Access Control:
Ensure that only certain addresses can call functions using msg.sender.
Gas Optimization:
manage the gas usage of processes by checking the amount of gas left with the gasleft() function.
pragma solidity ^0.8.17;
contract Auction {
address public highestBidder;
uint public highestBid;
function bid() public payable {
require(msg.value > highestBid, “Your bid is too low.”);
require(block.timestamp < auctionEndTime, “The auction has ended.”);
if (highestBidder != address(0)) {
payable(highestBidder).transfer(highestBid); // Refund the previous highest bidder
}
highestBidder = msg.sender;
highestBid = msg.value;
}
function getRemainingTime() public view returns (uint) {
if (block.timestamp >= auctionEndTime) {
return 0;
} else {
return auctionEndTime – block.timestamp;
}
}
}
In this example, global variables such as msg.sender and block.timestamp are actively used. msg.sender determines the bidder’s address, while with block.timestamp we control the end time of the auction. These variables play a critical role during the execution of the contract and directly affect the functioning of the smart contract.
Conclusion:
Global variables allow smart contracts in Solidity to navigate the blockchain and the current transaction context. The correct use of these variables makes contracts more secure and efficient because they help the contract manage its functions and transactions with the right context. Being aware of the global variables in Solidity and using them effectively allows developers to make smart contracts more functional.
References
- Ethereum Foundation. (n.d.). Solidity Documentation. Retrieved from https://docs.soliditylang.org/en/v0.8.0/
- ConsenSys. (2021). Introduction to Smart Contracts. Retrieved from https://consensys.net/knowledge-base/ethereum-101/what-is-a-smart-contract/
- Remix Project. (n.d.). Remix – Ethereum IDE. Retrieved from https://remix.ethereum.org/
- Truffle Suite. (n.d.). Truffle Suite: Smart Contract Development. Retrieved from https://www.trufflesuite.com/
- Nomic Foundation. (n.d.). Hardhat: Ethereum Development Environment. Retrieved from https://hardhat.org/