Solidity函数学习

简介: Solidity函数学习

  目录

函数

返回值(或称返回变量)

支持的返回参数和类型

可见性(Visibility)

状态可变性(mutability)

交易与调用

特殊函数

Getter 函数

接收以太币函数

Fallback函数

函数修饰器


今天给大家分享一下Solidity中的函数的学习

函数

Solidity中的函数为:

function function_name(<param_type> <param_name>) <visibility> <state mutability> [returns(<return_type>)]{ ... }

image.gif

它们可以在合约内部编写,也可以是自由函数(写在合约外)。

返回值(或称返回变量)

函数可以返回任意数量的值作为输出。有两种方法从函数返回变量:

1. 使用返回变量名:

function arithmetic(uint _a, uint _b) public pure
        returns (uint o_sum, uint o_product)
    {
        o_sum = _a + _b;
        o_product = _a * _b;
    }

image.gif

2. 直接在return语句中提供返回值:

function arithmetic(uint _a, uint _b) public pure
        returns (uint o_sum, uint o_product)
    {
        return (_a + _b, _a * _b);
    }

image.gif

使用第二种方法,你可以省略返回变量的名称,而仅指定其类型。

支持的返回参数和类型

为了调用智能合约函数,我们需要使用ABI规范来指定要调用的函数并对参数进行编码,这些参数将包含在交易的数据字段中并发送给以太坊网络来执行。

ABI编码也用于事件和返回类型,更多详细信息可以在中找到。

注意: (如果你使用的是Solidity版本:0.7.5才可以使用 v2 版本。对于低于0.7.5的版本,我们需要使用实验版本:pragma experimental ABIEncoderV2;)。

使用 Solidity 0.7.5 版本的示例。

// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.4;
pragma abicoder v2;
contract Test {
    struct S { uint a; uint[] b; T[] c; }
    struct T { uint x; uint y; }
    function f(S memory, T memory, uint) public pure {}
    function g() public pure returns (S memory, T memory, uint) {}
}

image.gif

可见性(Visibility)

函数的可见性有四种:

    • Private(私有):限制性最强,函数只能在所定义的智能合约内部调用。
    • Internal(内部):可以在所定义智能合约内部调用该函数,也可以从继承合约中调用该函数。
    • External(外部):只能从智能合约外部调用。 (如果要从智能合约中调用它,则必须使用 this。)
    • Public(公开):可以从任何地方调用。 (最宽松)

    状态可变性(mutability)

      • view:用view声明的函数只能读取状态,而不能修改状态。
      • pure:用pure声明的函数既不能读取也不能修改状态。
      • payable:用payable声明的函数可以接受发送给合约的以太币,如果未指定,该函数将自动拒绝所有发送给它的以太币。
      contract SimpleStorage {
           uint256 private data;
           function getData() external view returns(uint256) {
               return data;
           }     function setData(uint256 _data) external {
              data = _data;
          }
      }

      image.gif

      交易与调用

      viewpure关键字定义的函数不会改变以太坊区块链的状态,这意味着当你调用这些函数时,你不会向区块链发送任何交易,因为交易被定义为从一个状态到另一个状态的状态栏变换。其仅仅是,你连接的节点通过检查其自己的区块链版本在本地执行函数代码,并将结果返回,而无需将任何交易广播到以太坊网络。

      特殊函数

      在本节中,我们将看到一些可以使用的特殊函数。

      Getter 函数

      定义为public的状态变量具有getter函数,该函数由编译器自动创建。该函数与变量具有相同的名称,并且具有外部可见性。

      contract C {
          uint public data;
          function x() public returns (uint) {
              data = 3; //  内部访问
              return this.data(); // 外部访问
          }
      }

      image.gif

      接收以太币函数

      合约最多可以具有一个receive函数。这个函数不能有参数,不能返回任何参数,并且必须具有receive可见性和 payable状态可变性。

      当向合约发送Ether且未指定调用任何函数(calldata 为空)时执行。这是在普通的以太坊转账上执行的函数(例如,通过.send().transfer()转账)。

      该函数声明如下:

      receive() external payable {
         ...
      }

      image.gif

      Fallback函数

      合约最多可以具有一个fallback函数(一般翻译为回退函数)。这个函数不能有参数,不能返回任何参数,并且必须具有external可见性。如果其他函数均不匹配给定的函数签名,或者根本没有提供任何数据并且没有receive函数,则在调用合约时执行该函数。

      你可以这样声明一个函数:

      fallback() external [payable]{
           ...
      }

      image.gif

      如果对一个没有实现receive函数或payable回退函数的合约转账,则合约将抛出异常,以太币会退还。

      可以在Remix中自行尝试一下,创建一个没有receivepayable fallback的合约,并向其中发送一些以太币。点击**Transact(交易)**后,你应该会看到一条类似以下的消息。

      image.gif编辑

      函数修饰器

      当你要在执行函数之前检查某些条件时,可以使用修饰器。例如,如果你要检查发件人是否是合约的所有者,则可以编写以下内容:

      function selectWinner() external {
          require(msg.sender == owner, "this function is restricted to the owner);
          ...}

      image.gif

      使用修饰器,我们可以分离该代码,以便我们可以将其与其他函数复用,我们只需要声明修饰器,如下所示:

      modifier onlyOwner(){
         require(msg.sender == owner, "this function is restricted to the owner);
        _; // will be replaced by the code of the function
      }

      image.gif

      然后将修饰器名称添加到函数中:

      function selectWinner() external onlyOwner {
          ...}

      image.gif

      通过在用空格分隔的列表中指定多个修饰器,可以将它们应用到一个函数,并按给出的顺序对其进行应用。

      目录
      相关文章
      |
      3月前
      |
      存储 区块链
      Solidity语言详解
      Solidity语言详解
      28 0
      |
      5月前
      |
      存储 安全 编译器
      Metamask项目方给Solidity程序员的16个安全建议
      文章是Metamask项目方Consensys在2020年发布的关于智能合约安全的博文,提供了16条Solidity程序员的安全建议,包括正确使用assert()、require()、revert()函数,避免使用tx.origin进行授权,注意整数除法舍入问题等,以帮助开发者提高智能合约的安全性。
      46 0
      |
      7月前
      |
      安全 算法 定位技术
      [Solidity][区块链安全入门]Solidity语言关于密码学知识的运用以及存在漏洞
      密码学在区块链中扮演关键角色,确保机密性、完整性、身份认证和不可否认性。对称密钥加密用于快速加密,但不支持不可否认性。非对称加密(如RSA)解决了这一问题,每个用户拥有公钥和私钥。散列函数(如SHA-1、SHA-2)用于数字签名,保证信息来源和完整性。同态加密允许在不解密情况下处理加密数据,增强隐私保护。零知识证明则能验证信息正确性而不泄露额外信息,如ZCash使用该技术隐藏交易详情。环签名技术(如在门罗币中)隐藏签名者身份。区块链隐私保护措施包括混币技术,旨在混淆交易路径。网络和应用层面上也存在隐私挑战,需要综合策略来防御。
      |
      6月前
      solidity 学习
      solidity 学习
      |
      Go 数据安全/隐私保护
      Solidity笔记-合约间的互相调用
      Solidity笔记-合约间的互相调用
      246 0
      |
      存储 编译器 区块链
      【一步步一起学DApp开发】(三)Solidity语言讲解 | 用Solidity编写智能合约 上
      【一步步一起学DApp开发】(三)Solidity语言讲解 | 用Solidity编写智能合约
      580 0
      |
      存储 JavaScript 前端开发
      【一步步一起学DApp开发】(三)Solidity语言讲解 | 用Solidity编写智能合约 下
      【一步步一起学DApp开发】(三)Solidity语言讲解 | 用Solidity编写智能合约
      258 0
      |
      Java 区块链
      【智能合约】Solidity 进阶编程 | 注意一下合约中的细节
      目录 1. 内置的全局变量 2. 错误处理 3. 访问函数 4. 创建合约 5. 合约继承 6. 修饰器modifier 最后
      259 0
      【智能合约】Solidity 进阶编程 | 注意一下合约中的细节
      |
      数据安全/隐私保护
      Solidity 文档--第三章:Solidity 编程实例
      Solidity 文档--第三章:Solidity 编程实例
      109 0
      |
      Ubuntu JavaScript 前端开发
      Solidity 文档--第二章:安装 Solidity
      Solidity 文档--第二章:安装 Solidity
      457 0

      热门文章

      最新文章