26

Solidity 0.6.9 更新,calldata 有更多用武之地

 4 years ago
source link: https://learnblockchain.cn/article/1107
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Solidity 0.6.9 更新,calldata 可以用于内部函数。

回顾一下 solidity 中数据位置,即说明数据存储在哪里,solidity 有 3 个位置:

memory
storage
calldata

在 Solidity 中使用引用类型的时候,必须指定数据的位置, 关于数据位置,可以阅读登链社区 翻译的Solidity文档-引用类型

从 Solidity 0.6.9 版本开始,之前仅用于外部函数(external 修饰的函数)的calldata位置,现在可以在内部函数(internal修饰的函数 )使用了。

请注意,由于EVM不允许修改 calldata,因此无法在 calldata 变量中创建新值或将某些内容复制到 calldata变量。

以下是一段示例使用 calldata 的 代码:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.9;

contract C {
  address[] owners;
  function addOwners(address[] calldata _newOwners) public {
    // We pass _newOwners on as a calldata array.
    checkUnique(_newOwners);
    for (uint i = 0; i < _newOwners.length; i++)
      owners.push(_newOwners[i]);
  }
  
  /// 内部函数可以遍历 calldata 的数组,而不用再复制到内存了。
  
  function checkUnique(address[] calldata _newOwners) internal pure {
    for (uint i = 0; i < _newOwners.length; i++)
      for (uint j = i + 1; i < _newOwners.length; j++)
        require(_newOwners[i] != _newOwners[i]);
  }
}

使用 calldata 变量的好处是,它不用将 calldata 数据的副本保存到内存中,并确保不会修改数组或结构(calldata 位置是只读的),因此,如果可以的话,请尽量使用 calldata 作为数据位置

函数的返回值中其实也可以使用 calldata 数据位置,但是无法给其分配空间。

回顾一下 solidity 中数据位置,即说明数据存储在哪里,solidity 有 3 个位置:

memory
storage
calldata

在 Solidity 中使用引用类型的时候,必须指定数据的位置, 关于数据位置,可以阅读登链社区 翻译的Solidity文档-引用类型

从 Solidity 0.6.9 版本开始,之前仅用于外部函数(external 修饰的函数)的calldata位置,现在可以在内部函数(internal修饰的函数 )使用了。

请注意,由于EVM不允许修改 calldata,因此无法在 calldata 变量中创建新值或将某些内容复制到 calldata变量。

以下是一段示例使用 calldata 的 代码:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.9;

contract C {
  address[] owners;
  function addOwners(address[] calldata _newOwners) public {
    // We pass _newOwners on as a calldata array.
    checkUnique(_newOwners);
    for (uint i = 0; i < _newOwners.length; i++)
      owners.push(_newOwners[i]);
  }

  /// 内部函数可以遍历 calldata 的数组,而不用再复制到内存了。

  function checkUnique(address[] calldata _newOwners) internal pure {
    for (uint i = 0; i < _newOwners.length; i++)
      for (uint j = i + 1; i < _newOwners.length; j++)
        require(_newOwners[i] != _newOwners[i]);
  }
}

使用 calldata 变量的好处是,它不用将 calldata 数据的副本保存到内存中,并确保不会修改数组或结构(calldata 位置是只读的),因此,如果可以的话,请尽量使用 calldata 作为数据位置

函数的返回值中其实也可以使用 calldata 数据位置,但是无法给其分配空间。

本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 1秒前
  • 阅读 ( 2 )
  • 学分 ( 0 )
  • 分类:Solidity

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK