Layout of components in a contract

@cameel Hi there. I took another look and got to realize two versions can both pass the compiling checks with no warnings or errors. The following snippet is the normal version, and a slightly modified version (due to an error that the view modifier is forgotten) below it also works fine. The normal version, as you mentioned, does not require gas, yet the modified version does require gas.

// SPDX-License-Identifier: MIT

pragma solidity 0.8.4;

contract Template {
    uint256 val;
    
    function setVal(uint256 val_) public {
        val = val_;
    }
    
    function getVal() public view returns(uint256) {
        return val;
    }
}

interface ITemplate {
    function setVal(uint256) external;
    function getVal() external view returns(uint256);
}

contract Test {
    
    function setVal(address addr, uint256 val_) public {
        ITemplate(addr).setVal(val_);
    }
    
    function getVal(address addr) public view returns(uint256) {
        return ITemplate(addr).getVal();
    }
}

The modified version having both views neglected in the interface and calling contract.

interface ITemplate {
    function setVal(uint256) external;
    function getVal() external returns(uint256);
}

contract Test {
    
    function setVal(address addr, uint256 val_) public {
        ITemplate(addr).setVal(val_);
    }
    
    function getVal(address addr) public returns(uint256) {
        return ITemplate(addr).getVal();
    }
}

This version would return an error message saying things like “declared as view, but (potentially) modifies the state, requires non-payable(default) or payable”, which seem to be irrelevant.

interface ITemplate {
    function setVal(uint256) external;
    function getVal() external returns(uint256);
}

contract Test {
    
    function setVal(address addr, uint256 val_) public {
        ITemplate(addr).setVal(val_);
    }
    
    function getVal(address addr) public view returns(uint256) {
        return ITemplate(addr).getVal();
    }
}