在Remix中,我得到以下错误。
contracts/TestBench.sol:138:30:
TypeError: Data location must be "calldata" for parameter
in external function, but none was given.
function updateTokenName(string _name) external onlyOwner {
^----------^
该错误引用了下面的代码行(完整的智能合约附加在底部)。
function updateTokenName(string _name) external onlyOwner {
然后,在用如下行替换上述有问题的行之后:
function updateTokenName(string calldata _name) external onlyOwner {
我得到了一系列新的错误,看起来像这样。它们都引用了在我做出";"修复";通过添加CCD_ 1。
contracts/TestBench.sol:52:9:
DeclarationError: Undeclared identifier.
allowed[msg.sender][_spender] = _tokens; / ...
^-----^
错误引用的完整函数如下。
function approve(address _spender, uint256 _tokens) external {
allowed[msg.sender][_spender] = _tokens; // Allow spender to withdraw from msg.sender's account multiple times, up to the specified amount of tokens.
}
我做错了什么?我该如何修复这些错误?声明错误消息引用的标识符的正确方法是什么?
完整智能合约
pragma solidity ^0.5.0;
contract FractionalizedAssets {
address public owner; // contract creator
mapping (address => uint) public tokenBalanceOf; // map of address and token balance
constructor() public {
owner = msg.sender;
}
function mint(uint256 _amount, address _to) external onlyOwner {
require(_amount > 0);
tokenBalanceOf[_to] += _amount; // Increase the token balance for user's account by specified amount.
}
function transfer(address _from, address _to, uint256 _tokens) external { // Allow users to trade tokens between each other
require(tokenBalanceOf[_from] >=_tokens && _tokens > 0); // Ensure that sender has enough tokens to send
tokenBalanceOf[_from] -=_tokens; // Substract tokens from sender's account
tokenBalanceOf[_to] +=_tokens; // Add tokens to receiver's account
emit Transfer(_from,_to,_tokens); // Notify listeners about transfer event
}
event Transfer(address indexed from, address indexed to, uint256 value);
modifier onlyOwner() {
require( msg.sender == owner );
_;
}
function burn(uint256 _amount, address _from) external onlyOwner {
require(_amount > 0);
tokenBalanceOf[_from] -= _amount; // Decrease the token balance for user's account by specified amount.
}
function totalSupply() public view returns (uint256) {
return address(this).balance; // Return the total supply of tokens in circulation.
}
function balanceOf(address _owner) public view returns (uint256) {
return tokenBalanceOf[_owner]; // Return the token balance of specified address.
}
function transferFrom(address _from, address _to, uint256 _tokens) external {
require(_tokens > 0 && tokenBalanceOf[_from] >=_tokens); // Ensure that sender has enough tokens to send
tokenBalanceOf[_from] -=_tokens; // Substract tokens from sender's account
tokenBalanceOf[_to] +=_tokens; // Add tokens to receiver's account
emit Transfer(_from,_to,_tokens); // Notify listeners about transfer event
}
function approve(address _spender, uint256 _tokens) external {
allowed[msg.sender][_spender] = _tokens; // Allow spender to withdraw from msg.sender's account multiple times, up to the specified amount of tokens.
}
function allowance(address _owner, address _spender) public view returns (uint256) {
return allowed[_owner][_spender]; // Return the remaining number of tokens that spender is still allowed to withdraw from owner's account.
}
function transferFrom(address _from, address _to, uint256 _tokens) external {
require(_tokens > 0 && tokenBalanceOf[_from] >=_tokens && allowed[_from][msg.sender] >=_tokens); // Ensure that sender has enough tokens to send
tokenBalanceOf[_from] -= _tokens; // Substract tokens from sender's account
tokenBalanceOf[_to] += _tokens; // Add tokens to receiver's account
allowed[_from][msg.sender] -= _tokens; // Decrease the amount of remaining tokens spender is still allowed to withdraw from owner's account
emit Transfer(_from,_to,_tokens); // Notify listeners about transfer event
}
function increaseApproval(address _spender, uint256 _addedValue) external {
allowed[msg.sender][_spender] += _addedValue; // Increase the amount of tokens that spender is still allowed to withdraw from owner's account.
}
function decreaseApproval(address _spender, uint256 _subtractedValue) external {
allowed[msg.sender][_spender] -= _subtractedValue; // Decrease the amount of tokens that spender is still allowed to withdraw from owner's account.
}
function burnFrom(address _from, uint256 _tokens) external {
require(_tokens > 0 && tokenBalanceOf[_from] >=_tokens && allowed[_from][msg.sender] >=_tokens); // Ensure that sender has enough tokens to send
tokenBalanceOf[_from] -=_tokens; // Substract tokens from sender's account
allowed[_from][msg.sender]-=_tokens; // Decrease the amount of remaining tokens spender is still allowed to withdraw from owner's account
emit Burn(_from,_to,_tokens); // Notify listeners about transfer event
}
event Burn(address indexed from, address indexed to, uint256 value);
function burnAll(address _from) external onlyOwner {
uint256 balance = tokenBalanceOf[_from]; // Get the user's current token balance.
require(balance > 0); // Ensure that user has tokens to burn.
tokenBalanceOf[_from] = 0; // Set the user's token balance to zero.
emit Burn(_from, address(0), balance); // Notify listeners about transfer event.
}
function pause() external onlyOwner {
paused = true; // Set the contract to a paused state.
emit Pause(); // Notify listeners about transfer event.
}
function unpause() external onlyOwner {
paused = false; // Set the contract to an unpaused state.
}
event Pause();
function renounceOwnership() external onlyOwner {
emit OwnershipRenounced(owner); // Notify listeners about transfer event.
owner = address(0); // Set the contract's owner to zero.
}
event OwnershipRenounced(address indexed previousOwner);
function transferOwnership(address _newOwner) external onlyOwner {
require(_newOwner != address(0)); // Ensure that new owner is not zero.
emit OwnershipTransferred(owner, _newOwner); // Notify listeners about transfer event.
owner = _newOwner; // Set the contract's owner to the new owner.
}
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function reclaimEther() external onlyOwner {
owner.transfer(address(this).balance); // Transfer all ether in the contract to the owner's address.
emit ReclaimEther(); // Notify listeners about transfer event.
}
event ReclaimEther();
function destroy() external onlyOwner {
selfdestruct(owner); // Destroy the contract and transfer all ether in the contract to the owner's address.
emit Destroy(); // Notify listeners about transfer event.
}
event Destroy();
function updateOwner(address _newOwner) external onlyOwner {
require(_newOwner != address(0)); // Ensure that new owner is not zero.
emit OwnershipTransferred(owner, _newOwner); // Notify listeners about transfer event.
owner = _newOwner; // Set the contract's owner to the new owner.
}
function updateTokenName(string calldata _name) external onlyOwner {
tokenName = _name; // Update the name of the token.
emit TokenNameUpdated(_name); // Notify listeners about transfer event.
}
event TokenNameUpdated(string indexed newTokenName);
}
从这里开始
结构、数组或映射的所有变量的显式数据位置类型现在是强制性的。这也适用于函数参数和返回变量。例如,将uint[]x=m_x更改为uint[]存储x=m_x,并且函数f(uint[][]x)到函数f(uint[][]存储器x),其中存储器是数据位置并且可以由存储或相应地调用数据。请注意,外部功能需要数据位置为calldata的参数。
-
然后必须定义
allowed
映射和paused
存储变量:bool private paused; string tokenName; // address1 allows address2 uint amount token mapping(address=>mapping(address=>uint)) public allowed;
-
您两次定义了具有相同签名的
transferFrom
函数。您要么更改签名,要么必须删除其中一个函数。 -
burnFrom
内部发出Burn事件是错误的// _to is not defined emit Burn(_from,_to,_tokens)
-
由于此,
owner
类型需要更改
"发送";以及";转移";仅可用于"类型的对象;住址"应付";,而不是";地址";。
address payable public owner; // contract creator
// you do not need public
constructor() {
owner = payable(msg.sender);
}
function renounceOwnership() external onlyOwner {
emit OwnershipRenounced(owner); // Notify listeners about transfer event.
// owner type is set payable above
owner = payable(address(0)); // Set the contract's owner to zero.
}
// owner to payable in below two functions
function transferOwnership(address _newOwner) external onlyOwner {
require(_newOwner != address(0)); // Ensure that new owner is not zero.
emit OwnershipTransferred(owner, _newOwner); // Notify listeners about transfer event.
owner = payable(_newOwner); // Set the contract's owner to the new owner.
}
function updateOwner(address _newOwner) external onlyOwner {
require(_newOwner != address(0)); // Ensure that new owner is not zero.
emit OwnershipTransferred(owner, _newOwner); // Notify listeners about transfer event.
owner = payable(_newOwner); // Set the contract's owner to the new owner.
}
现在,您的应用程序已准备好在pragma solidity >=0.8.0 <0.9.0;
中编译