Solidity 中的函数状态可变性

状态可变性是一个可靠的概念,它定义了函数的行为以及它们如何与存储在区块链上的数据进行交互。在本文中,我们将可以了解不同的状态可变性修饰符,以及如何在编写优化的智能合约时应用它们。

solidity 中两个主要的状态可变性修饰符是:

  • View
  • Pure

View功能

视图函数是只读函数,使用View关键字声明。它们不修改区块链的状态。这意味着使用view关键字声明的函数不能包含可能修改状态变量或存储在区块链上的数据的代码。

此外,View函数不能接收或发送以太币,只能调用其他view或pure函数。可能修改区块链状态的view函数将引发错误并导致编译失败。类似地,当编译器检测到一个只读取而不写入区块链的函数时,它会建议您将该函数的状态可变性设置为view。

合约A中的例子演示了viewResult函数如何从state读取数据(num1和num2),但不修改数据。

pragma solidity 0.8.10;
contract A {
// Declaring state variables
uint num1 = 5;
uint num2 = 10;
// View function to calculate product of 2 numbers
function viewResult() public view returns(uint product){
// Expression that reads state
product = num1 * num2;}}

输出:

product = 50

Pure函数?

将函数声明为pure函数可以限制该函数更改或与存储在区块链上的数据交互。标记为pure的函数既不从区块链读取也不向区块链写入。它们不能接收或发送以太币,不能使用msg或block,只能调用其他Pure函数。

如果你的合约中包含了一个不读取或修改状态的函数,编译器将发出警告信号,并建议指定状态可变性。可以忽略此警告,代码仍然可以编译。

下面合约B中的例子演示了addNum函数如何既不从state读取数据,也不向state写入数据。

pragma solidity 0.8.10;
contract B {
// Pure function that calculates sum of 2 numbers
function addNum(uint num1, uint num2) public pure
returns(uint sum){
// Expression that computes data passed in as parameters
// and does not read or modify state
sum = num1 + num2;
}
}

输出:

sum = 15

为什么要将函数标记为view或pure?

Gas 优化:Gas 消耗只在交易触发时生效,状态被修改时触发交易。标记为view或pure的函数不修改状态,因此不耗费gas,除非它们是从外部合约调用的。

其他函数状态可变性修饰符

除了View和Pure之外,功能状态的可变性还可以是payable或non-payable。

支付功能

使用关键字payable声明函数允许函数发送和接收以太币。试图通过未标记为可支付的函数发送或接收以太币将导致交易被拒绝。

因此,如果我们的智能合约需要通过该功能发送或接收以太坊,则必须将某个功能标记为payable功能。

下面的存款功能允许其他合约向合约 C发送以太币。

pragma solidity 0.8.10;
contract C {uint balance = 0;
// Payable function that allows other contracts
// to send ether to this contract.
function deposit () payable public{balance += msg.value;}
}

Non-payable函数

虽然non-payable不是当前Solidity中的关键字,但它是当函数没有明确定义为payable时假定的默认状态可变性修饰符。未明确定义为View或Pure的non-payable函数最适合于可能读取和修改状态变量的函数。non-payable功能的主要限制是它们不能接收或发送以太。

pragma solidity 0.8.10;
contract D {  uint count = 0;
// non-payable function that reads and modifies state.
function increment() public returns(uint){count += 1;return count;
}
}

上面合约D中的增量函数演示了non-payable函数如何通过访问声明的count变量从状态读取数据。它还演示了函数如何在每次调用增量函数时将count的值加1,从而潜在地修改状态。

Source:https://medium.com/coinmonks/function-state-mutability-in-solidity-acb850eedccc

关于

ChinaDeFi - ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。

Layer 2道友 - 欢迎对Layer 2感兴趣的区块链技术爱好者、研究分析人与Gavin(微信: chinadefi)联系,共同探讨Layer 2带来的落地机遇。敬请关注我们的微信公众号 “去中心化金融社区”

Solidity 中的函数状态可变性相关推荐

  1. Solidity 中 receive 函数 和 callback函数分析

    在使用transfer 和 send 方法的是后需要关注一下 receive方法和callback方法. receive 接收以太函数 一个合约最多有一个 receive 函数, 声明函数为: rec ...

  2. solidity 中的时间_Solidity官方文档中文版.pdf

    汇智网 H Solidity 官方文档中文版 导读 以太坊是什么? 以太坊是一个全新开放的区块链平台,它允许任何人在平台中建立和使用通过 区块链技术运行的去中心化应用.就像比特币一样,以太坊丌受任何人 ...

  3. 在 Solidity 中 ++i 为什么比 i++ 更省 Gas?

    前言 作为一个初学者,"在 Solidity 中 ++i 为什么比 i++ 更省 Gas?" 这个问题始终在每个寂静的深夜困扰着我.也曾在网上搜索过相关问题,但没有得到根本性的解答 ...

  4. Yul语言及对象说明——Solidity中文文档(9)

    写在前面:HiBlock区块链社区成立了翻译小组,翻译区块链相关的技术文档及资料,本文为Solidity文档翻译的第九部分<Yul语言及对象说明>,特发布出来邀请solidity爱好者.开 ...

  5. php foreach嵌套foreach,php中foreach怎么嵌套foreach PHP中foreach函数用法?

    foreach的使用方法小编不是很明确,分享达人指教一下.foreach (array_expressforeach($array as $key) { if(xxxx) { break; //bre ...

  6. react中纯函数_如何在纯React中创建电子邮件芯片

    react中纯函数 by Andreas Remdt 由Andreas Remdt 如何在纯React中创建电子邮件芯片 (How to create email chips in pure Reac ...

  7. 使用编译器——Solidity中文文档(8)

    写在前面:HiBlock区块链社区成立了翻译小组,翻译区块链相关的技术文档及资料,本文为Solidity文档翻译的第八部分<使用编译器>,特发布出来邀请solidity爱好者.开发者做公开 ...

  8. shell中的函数及脚本调试方法

    1.函数格式 目的:将一些相对对立的代码变成函数,提供可读性和重用性,避免重复编写相同代码. 函数格式: 函数关键字:function可以省略,可不带任何参数; 符号{表示函数体的开始(可在函数名后单 ...

  9. STM32中NVIC_SystemReset()函数的作用?什么时候用?

    STM32中NVIC_SystemReset()函数的作用?什么时候用? STM32软件复位有两种方式 (1)方式一:NVIC_SystemReset()函数用来复位STM32. 注意1:从SYSRE ...

  10. Linux系统中的函数

    Linux系统中的函数: 一.进程控制 fork 创建一个新进程 clone 按指定条件创建子进程 execve 运行可执行文件 exit 中止进程 _exit 立即中止当前进程 getdtables ...

最新文章

  1. 贝索斯:亚马逊正探讨人脸识别如何监管
  2. ie6 css :hover 和 select遮挡问题、和z-index失效问题
  3. 苏嵌第一天,shell中一些基础知识
  4. 线程池,远没你想象的那么简单
  5. Django框架——查询集QuerySet
  6. Go语言实例系列【 获得url实例】
  7. 我们是否应该保留同时多线程?
  8. angularjscheckbox全选_Vue Checkbox全选和选中的方法
  9. 进销存财务管理重要性
  10. python学习-02(数据类型、字符串、列表、元祖、字典)
  11. 身高预测_大部分都很准哦
  12. 编写吃c语言程序步骤,自己做的一个C语言小游戏——吃金子
  13. gabor滤波 matlab,图像处理 – 使用matlab应用Gabor方程创建Gabor滤波器
  14. 人脸识别、二维码电子签到,让会议会展入场更加智能!
  15. Hive on Hbase
  16. 服务器被攻击导致CPU100%的解决
  17. SQL server 数据库表的配置及其表的导入导出
  18. 【OpenCV学习】 《OpenCV3编程入门》--毛星云 01 邂逅OpenCV(OpenCV基本概念与基本架构) ROS系统上的运用(python实现)
  19. OpenLayers基础:在IIS中部署并启用CGI
  20. React+Egg.js实现全栈个人博客

热门文章

  1. 4k视频分辨率的码流_拍摄4K,30帧视频,多少码率合适?
  2. uniapp 标签打印 笔记
  3. 电脑计算机睡眠和休眠模式区别,电脑休眠和睡眠的区别?
  4. CF 592D(Super M-虚树直径)
  5. 市场、运营、销售什么区别?
  6. 就晚间宿舍熄灯时间调查
  7. 双引号后面要加句号吗_引号里应不应该用句号,双引号后的句号在前还是在后?...
  8. 文本自动生成研究进展与趋势之总结与展望
  9. 基于raspbian+motion的家庭监控网络
  10. 加性噪声(目前不理解)