5月29日 22:35

What are the differences between view, pure, and payable function modifiers in Solidity?

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)
solidity
contract 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)
solidity
contract 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.value to get transfer amount
  • Consumes Gas
solidity
contract 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

Featureviewpurepayable
Read state
Modify state
Receive ETH
Access msg.value
Gas consumption (external call)NoneNoneYes
Use casesData queriesPure calculationsFund operations

Combined Usage

Some modifiers can be combined:

solidity
contract 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

solidity
contract 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

  1. Prefer pure: If a function doesn't need to read state, using pure can save Gas
  2. Explicitly use view: For read-only operations, explicitly mark view to improve code readability
  3. Use payable carefully: Ensure payable functions have appropriate access controls and amount validation
  4. Avoid abuse: Don't misuse these modifiers for Gas optimization, which may lead to security issues
标签:Solidity