In Solidity, view, pure, and payable are three important function modifiers that define the behavioral characteristics and constraints of functions.
1. View Modifier
Definition: Declares that the function will not modify the contract's state variables but can read the state.
Characteristics:
- Can read state variables (storage)
- Cannot modify state variables
- Cannot send ETH
- Does not consume Gas (when called externally)
soliditycontract ViewExample { uint256 public storedData = 100; // view function can read state function getData() public view returns (uint256) { return storedData; // read state variable } // Error: view function cannot modify state function setData(uint256 _data) public view { // storedData = _data; // compilation error! } }
2. Pure Modifier
Definition: Declares that the function neither reads nor modifies contract state, relying only on input parameters.
Characteristics:
- Cannot read state variables
- Cannot modify state variables
- Cannot access global variables like
msg.sender,msg.value - Does not consume Gas (when called externally)
soliditycontract PureExample { uint256 public constant VALUE = 100; // pure function only depends on input parameters function add(uint256 a, uint256 b) public pure returns (uint256) { return a + b; } // pure function can read constants function getConstant() public pure returns (uint256) { return VALUE; // constants don't count as state reads } // Error: pure function cannot read state variables function getData() public pure returns (uint256) { // return storedData; // compilation error! } }
3. Payable Modifier
Definition: Allows the function to receive ETH (Ether).
Characteristics:
- Can receive ETH transfers
- Can read and modify state (default behavior)
- Can access
msg.valueto get transfer amount - Consumes Gas
soliditycontract PayableExample { mapping(address => uint256) public balances; // payable function can receive ETH function deposit() public payable { require(msg.value > 0, "Must send ETH"); balances[msg.sender] += msg.value; } // query contract balance function getBalance() public view returns (uint256) { return address(this).balance; } // withdraw ETH function withdraw(uint256 amount) public { require(balances[msg.sender] >= amount, "Insufficient balance"); balances[msg.sender] -= amount; payable(msg.sender).transfer(amount); } }
Modifier Comparison Table
| Feature | view | pure | payable |
|---|---|---|---|
| Read state | ✅ | ❌ | ✅ |
| Modify state | ❌ | ❌ | ✅ |
| Receive ETH | ❌ | ❌ | ✅ |
| Access msg.value | ❌ | ❌ | ✅ |
| Gas consumption (external call) | None | None | Yes |
| Use cases | Data queries | Pure calculations | Fund operations |
Combined Usage
Some modifiers can be combined:
soliditycontract CombinedExample { // payable + view cannot be combined because view doesn't consume Gas while payable needs to handle transfers // can define ETH receiving functions receive() external payable {} fallback() external payable {} // calculation functions use pure function calculateFee(uint256 amount) public pure returns (uint256) { return amount * 5 / 100; // 5% fee } // query functions use view function getContractBalance() public view returns (uint256) { return address(this).balance; } }
Practical Application Example
soliditycontract Bank { mapping(address => uint256) private balances; uint256 public totalDeposits; // payable: receive deposits function deposit() public payable { balances[msg.sender] += msg.value; totalDeposits += msg.value; } // view: query balance function getBalance(address user) public view returns (uint256) { return balances[user]; } // pure: calculate interest function calculateInterest(uint256 principal, uint256 rate) public pure returns (uint256) { return principal * rate / 100; } // payable + other operations function withdraw() public payable { uint256 amount = balances[msg.sender]; require(amount > 0, "No balance"); balances[msg.sender] = 0; totalDeposits -= amount; payable(msg.sender).transfer(amount); } }
Best Practices
- Prefer pure: If a function doesn't need to read state, using pure can save Gas
- Explicitly use view: For read-only operations, explicitly mark view to improve code readability
- Use payable carefully: Ensure payable functions have appropriate access controls and amount validation
- Avoid abuse: Don't misuse these modifiers for Gas optimization, which may lead to security issues