函数类型

  1. solidity中函数的形式:
  2. 到底什么是Pure和View?
  • 代码
    1. 1. pure v.s view
    2. 2. internal v.s. external
    3. 3. payable
  • solidity中函数的形式:

        function <function name> (<parameter types>) {internal|external|public|private} [pure|view|payable] [returns (<return types>)]
    
    1. function:声明函数时的固定用法,想写函数,就要以function关键字开头。

    2. <function name>:函数名

    3. (<parameter types>):函数的参数,也就是要输入到函数的变量类型和名字。

    4. {internal|external|public|private}:函数可见性说明符,一共4种。没标明函数类型的,默认internal

      • public: 内部外部均可见。(也可用于修饰状态变量,public变量会自动生成 getter函数,用于查询数值).

      • private: 只能从本合约内部访问,继承的合约也不能用(也可用于修饰状态变量)。

      • external: 只能从合约外部访问(但是可以用this.f()来调用,f是函数名)

      • internal: 只能从合约内部访问,继承的合约可以用(也可用于修饰状态变量)。

    5. [pure|view|payable]:决定函数权限/功能的关键字。payable(可支付的)很好理解,带着它的函数,运行的时候可以给合约转入ETHpureview的介绍见下一节。

    6. [returns ()]:函数返回的变量类型和名称。

    到底什么是PureView

    pureview关键字的函数是不改/写链上状态的,因此用户直接调用他们是不需要付gas的(合约中非pure/view函数调用它们则会改写链上状态,需要付gas)。

    1. 包含pure关键字的函数,不能读取也不能写入存储在链上的状态变量。

    2. 包含view关键字的函数,能读取但也不能写入状态变量。

    3. 不写pure也不写view,函数既可以读取也可以写入状态变量。

    在以太坊中,以下语句被视为修改链上状态:

    写入状态变量。

    释放事件。

    创建其他合同。

    使用selfdestruct.

    通过调用发送以太币。

    调用任何未标记view或pure的函数。

    使用低级调用(low-level calls)。

    使用包含某些操作码的内联汇编。

    以下被认为是从状态中读取:

    1. 读取状态变量。
    2. 访问 this.balance 或者 <address>.balance
    3. 访问 blocktxmsg 中任意成员 (除 msg.sigmsg.data 之外)。
    4. 调用任何未标记为 pure 的函数。
    5. 使用包含某些操作码的内联汇编。

    代码

    1. pure v.s view

    // SPDX-License-Identifier: MIT
    
    //声明solidity版本 这行代码意思是源文件将不允许小于 0.8.4 版本或大于等于 0.9.0 版本的编译器编译
    pragma solidity ^0.8.4; 
    
    contract HelloWeb3{
        
        uint256 public number = 5;
        
        //定义add函数 external是可以从合约外部调用此函数 
    
        function add() external{
            number = number + 1;
        }
        //pure 不能读取也不能写入存储在链上的状态变量number
        //那pure函数能做些什么?举个例子,你可以给函数传递一个参数 _number,然后让他返回 _number+1。
        function addPure(uint256 _number) external pure returns(uint256 new_number){
            new_number = _number+1;
        }
        //view 能读取,但不能够改写状态变量number
        //可以稍微改写下方程,让他不改写number,而是返回一个新的变量。
        function addView() external view returns(uint256 new_number) {
            new_number = number + 1;
        }
    }
    

    2. internal v.s. external

    // SPDX-License-Identifier: MIT
    
    //声明solidity版本 这行代码意思是源文件将不允许小于 0.8.4 版本或大于等于 0.9.0 版本的编译器编译
    pragma solidity ^0.8.4; 
    
    contract Web3{
    
        uint256 public number = 5;
    
         // internal: 内部
        function minus() internal {
            number = number - 1;
        }
    
        // 合约内的函数可以调用内部函数
        function minusCall() external {
            minus();
        }
    }
    

    3. payable

    // SPDX-License-Identifier: MIT
    
    //声明solidity版本 这行代码意思是源文件将不允许小于 0.8.4 版本或大于等于 0.9.0 版本的编译器编译
    pragma solidity ^0.8.4; 
    
    contract HelloWeb3{
    
        // payable: 递钱,能给合约支付eth的函数
        function minusPayable() external payable returns(uint256 balance) {
            balance = address(this).balance;
        }
    }
    

    this关键字可以让我们引用合约地址

    img

    我们可以在返回的信息中看到,合约的余额是1 ETH。

    img

    Example: 3-2.png


    转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。