Skip to content

View and Pure Functions in Solidity

So far, we have mostly interacted and modified state variables from our Smart Contract. For example, when we write the owner, we modify a state variable. When we update the balance, we modify a state variable (balanceReceived).

For this, we needed to send a transaction. That works very transparently in Remix and also looks instantaneous and completely free of charge, but in reality it isn't. Modifying the State costs gas, is a concurrent operation that requires mining and doesn't return any values.

Reading values, on the other hand, is virtually free and doesn't require mining.

There are two types of reading functions:

  1. view: Accessing state variables
  2. pure: Not accessing state variables

View Function

Let's make our owner-variable private and instead add a simple getter function function

//SPDX-License-Identifier: MIT

pragma solidity 0.8.3;

contract FunctionsExample {

    mapping(address => uint) public balanceReceived;

    address payable owner;

    constructor() {
        owner = payable(msg.sender);
    }

    function getOwner() public view returns(address) {
        return owner;
    }

    function destroySmartContract() public {
        require(msg.sender == owner, "You are not the owner");
        selfdestruct(owner);
    }

    function receiveMoney() public payable {
        assert(balanceReceived[msg.sender] + msg.value >= balanceReceived[msg.sender]);
        balanceReceived[msg.sender] += msg.value;
    }

    function withdrawMoney(address payable _to, uint _amount) public {
        require(_amount <= balanceReceived[msg.sender], "not enough funds.");
        assert(balanceReceived[msg.sender] >= balanceReceived[msg.sender] - _amount);
        balanceReceived[msg.sender] -= _amount;
        _to.transfer(_amount);
    } 

    receive() external payable {
        receiveMoney();
    }
}

Let's give this a try: 1. Deploy the Smart Contract 2. click on "getOwner" 3. Observe the Transaction Log

You can observe that the deployment is a transaction, marked by the little green checkmark (1), while the reading operation is a call (2). In reality a transaction would need to get signed by a private key and mined by the network, while a reading operation does not need to get signed.

Pure Functions

So, view functions are reading functions - what are pure functions?

Pure functions are functions that are not accessing any state variables. They can call other pure functions, but not view functions.

Let's do a quick example:

//SPDX-License-Identifier: MIT

pragma solidity 0.8.3;

contract FunctionsExample {

    mapping(address => uint) public balanceReceived;

    address payable owner;

    constructor() {
        owner = payable(msg.sender);
    }

    function getOwner() public view returns(address) {
        return owner;
    }

    function convertWeiToEth(uint _amount) public pure returns(uint) {
        return _amount / 1 ether;
    }

    function destroySmartContract() public {
        require(msg.sender == owner, "You are not the owner");
        selfdestruct(owner);
    }

    function receiveMoney() public payable {
        assert(balanceReceived[msg.sender] + msg.value >= balanceReceived[msg.sender]);
        balanceReceived[msg.sender] += msg.value;
    }

    function withdrawMoney(address payable _to, uint _amount) public {
        require(_amount <= balanceReceived[msg.sender], "not enough funds.");
        assert(balanceReceived[msg.sender] >= balanceReceived[msg.sender] - _amount);
        balanceReceived[msg.sender] -= _amount;
        _to.transfer(_amount);
    } 

    receive() external payable {
        receiveMoney();
    }
}

Let's run it:

  1. Deploy a new Instance
  2. Run "convertWeiToEth" with 100
  3. Observe the Transaction log

Do you know why the returned amount is 0? Think about it for a moment, then look into the solution!

Why the amount is 0 solution

The amount is zero, because we return an integer. We divide 100 / 1000000000000000000 = 0.0000000000001. Integers in Solidity are cut off (not even rounded, or always rounded down).

If you enter 1000000000000000000 into the amount field, then the returned amount is 1 (1 Ether)

Alright, that's it, there's nothing much more to say about view and pure functions at this moment. On to the next lecture!