Solidity:TypeError:函数声明为视图,但此表达式修改了状态,因此需要不可支付(默认)或应付
Posted
技术标签:
【中文标题】Solidity:TypeError:函数声明为视图,但此表达式修改了状态,因此需要不可支付(默认)或应付【英文标题】:Solidity: TypeError: Function declared as view, but this expression modifies the state and thus requires non-payable (the default) or payable 【发布时间】:2021-07-31 16:01:41 【问题描述】:我一直在尝试创建一个智能合约/代币,将其部署在币安智能链测试网上。我遵循了一些文档并从这个开始。我正在研究这个功能问题。函数被声明为只读。这是源代码
该函数正在更改所有者地址的状态,还有什么选项可以将其声明为只读
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.2;
//import "Context.sol";
//import "IBEP20.sol";
//import "SafeMath.sol";
//import "Ownable.sol";
contract SampleTaken
mapping(address => uint) public balances;
uint public totalSupply = 1000000 * 10 ** 18;
string public name ="Sample Token";
string public symbol ="KJA";
uint public decimals = 18;
/** Events aailable for the Contract**/
event Transfer(address indexed _from, address indexed _to, uint256 _value);
constructor()
balances[msg.sender] = totalSupply;
function balanceOf(address _ownerAddress) public view returns (uint)
return balances[_ownerAddress];
function transfer(address _toAddress, uint _noOfTokens) public view returns (bool)
require(balanceOf(msg.sender) >= _noOfTokens, "Total balance is less than the number of Tokens asked for !!!");
balances[_toAddress] +=_noOfTokens;
balances[msg.sender] -= _noOfTokens;
emit Transfer(msg.sender,_toAddress, _noOfTokens);
return true;
function transferFrom(address _from, address _to, uint _value) public returns (bool)
require(balanceOf(_from) >= _value, "Balance is less than the number of Tokens asked for !!!");
// require(allowance[_from][msg.sender] >= _value, "Allowance too low");
balances[_to] += _value;
balances[_from] -= _value;
emit Transfer (_from, _to, _value);
return true;
非常感谢任何帮助。
问候
【问题讨论】:
【参考方案1】:从函数声明中删除view
或pure
关键字,只保留public returns
改变
function transfer(address _toAddress, uint _noOfTokens) public view returns (bool)
到
function transfer(address _toAddress, uint _noOfTokens) public returns (bool)
改变方法:
function transfer(address _toAddress, uint _noOfTokens) public returns (bool)
require(balanceOf(msg.sender) >= _noOfTokens, "Total balance is less than the number of Tokens asked for !!!");
balances[_toAddress] +=_noOfTokens;
balances[msg.sender] -= _noOfTokens;
emit Transfer(msg.sender,_toAddress, _noOfTokens);
return true;
【讨论】:
【参考方案2】:您的transfer()
函数被声明为view
函数。
函数可以声明为视图,在这种情况下它们承诺不会修改状态。
来源:Solidity docs
但是这些行(在transfer()
函数内)修改了状态:
balances[_toAddress] +=_noOfTokens;
balances[msg.sender] -= _noOfTokens;
emit Transfer(msg.sender,_toAddress, _noOfTokens);
如果您希望您的函数修改状态,它不能是 view
(也不能是 pure
)函数 - 您需要删除 view
修饰符:
function transfer(address _toAddress, uint _noOfTokens) public returns (bool)
【讨论】:
谢谢彼得。通过文档,看起来在这种情况下不能使用 View。但是,根据我的理解,将函数声明为视图会使它们无法从合同外部访问,从而保护了函数。我的理解不正确吗?谢谢 @user3161840 “视图使它们无法从合约外部访问” - 这是不正确的......如果您想限制哪些地址可以执行该功能,您可以使用ownable 方法。 OpenZeppelin 实现仅针对一个地址(存储在_owner
属性中)进行验证,但您也可以针对多个地址(存储在数组或映射中)进行验证...如果您不希望任何其他合约或用户执行函数,需要标记为private
或internal
。以上是关于Solidity:TypeError:函数声明为视图,但此表达式修改了状态,因此需要不可支付(默认)或应付的主要内容,如果未能解决你的问题,请参考以下文章