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篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。

本文首发于:https://mp.weixin.qq.com/s/5EhFziL3XjAWKR42cQH4nA

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

0 条评论

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