If you have been tinkering with Solidity, you might have used or came across the address
object in Solidity. Common use cases of this object includes reading address
balance, and sending tokens.
In this article, we will explore the different members of address
while referencing Solidity's docs.
1. Balance
The balance member provides access to read balance of address in Wei (1 Ether = 10^18 Wei).
function retrieveBalance() public view returns (uint256) {
//returns ETH balance of deployed contract in Wei
return address(this).balance;
}
function retrieveUserBalance(address user) public view returns (uint256) {
//returns ETH balance of user's address in Wei
return address(user).balance;
}
retrieveBalance()
function is an example of a gotcha that catches new Solidity devs off-guard. It is not unusual to assume that address(this).balance
would return the balance of our address. In reality, it is the balance of the smart contract itself that is read.
2. Code
The code
member allows us to query the deployed contract’s bytecode information.
function retrieveCode() public view returns (bytes memory) {
//returns EVM bytecode
return address(this).code;
}
function retrieveCodehash() public view returns (bytes32) {
//returns Keccak-256 hash of the EVM bytecode
return address(this).codehash;
}
retrieveCode()
queries the EVM bytecode and in this example, the output looks something like this “0x60806040…4300081a0033”.
This is useful for contract verification purposes. Here is an example of WETH’s deployed contract in Etherscan. Scroll below to see the Deployed Bytecode’s output.
retrieveCodehash()
simply provides the Keccak-256 hash of the output. It provides a more efficient way to verify the deployed contract as it is cheaper in terms of gas costs.
3. Transfer, Send & Call
• Transfer & Send
Typically invoked for sending Ether. Level Up has also put together a guide covering these members. The section below covers the output/responses when using these members.
function transferKeyword(uint256 ethAmount) public {
// NOT recommended for sending Ether
// Reverts with error if txn fails
payable(address(this)).transfer(ethAmount);
}
function sendKeyword(uint256 ethAmount) public returns (bool) {
// NOT recommended for sending Ether
// Reverts with bool: "false" if txn fails
return payable(address(this)).send(ethAmount);
}
transfer
and send
members are not recommended for sending Ether. Take note on the expected responses if you plan to use them.
In situations of failed transactions, transfer
reverts with an error while send
returns a boolean value of false
(but the transaction will be successful).
Note: send
updates state, but transfer
does not. Both members still consume gas regardless of the transaction status.
• Call
function callKeyword(uint256 ethAmount) public {
// RECOMMENDED method to send Ether
// Passing blanks ("") because the example below shows empty calldata
(bool sent, ) = address(this).call{value: ethAmount}("");
require(sent, "Failed to send Ether");
}
call
is recommended due to its flexibility for sending Ether. It also allows you to pass arguments if interacting with custom functions that require any parameters.
This concludes part 1. In the next part, we will cover other members of the address object such as staticcall
and delegatecall
. Stay tuned!
More Content
A guide on how to use Vyper, Ape & Web3.py to write, deploy & interact with smart contracts
This guide will show you how to use Noir on Scroll!
Reading Arrays, Structs and Nested Mappings from L1.
Learn smart contract development with Foundry, a blazingly fast framework for building and deploying smart contracts!
This precompile unlocks the Keystore and more, learn how to use it with examples.