Remix

在 Remix 上出現此錯誤“TypeError:函式中參數的數據位置必須是“memory”或“calldata”,但沒有給出。編制契約

  • July 28, 2022
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;

import "./Ownable.sol";
import "./Mtoken.sol";
import "./IERC20.sol";

contract MultiDrop is IERC20, Ownable {
MToken public mtok;
address private _owner;

event MultiERC20Transfer(
   address indexed _from,
   uint indexed _value,
   address _to,
   uint _amount,
   address mtok
);

constructor(MToken _mtok) {
   mtok = _mtok;
   _owner = msg.sender;
  
}

function multiERC20TransferTightlyPacked(
   address mtok, 
   bytes32[] _addressesAndAmounts
) public onlyOwner 
{
   for (uint i = 0; i < _addressesAndAmounts.length; i++) {
       address to = address(_addressesAndAmounts[i] >> 96);
       uint amount = uint(uint96(_addressesAndAmounts[i]));
       _safeERC20Transfer(mtok, to, amount);
       MultiERC20Transfer(msg.sender, msg.value, to, amount, mtok);
   }
}

function multiERC20Transfer( 
   address mtok,
   address[] _addresses,
   uint[] _amounts
) public onlyOwner 
{
   for (uint i = 0; i < _addresses.length; i++) {
       _safeERC20Transfer(mtok, _addresses[i], _amounts[i]);
       MultiERC20Transfer(
           msg.sender,
           msg.value,
           _addresses[i],
           _amounts[i],
           mtok
       );
   }
}
function _safeERC20Transfer(address mtok, address _to, uint _amount)
internal
{
   require(_to != 0);
   require(mtok.transferFrom(msg.sender, _to, _amount));
}

function mtokAvailable() public returns (uint256) {
return mtok.balanceOf(this);
}

function destroy() public onlyOwner {
uint256 balance = mtokAvailable();
require (balance > 0);
mtok.transfer(msg.sender, balance);
selfdestruct(msg.sender);
}   

}

解決方案應該是:

function multiERC20TransferTightlyPacked(
address mtok, 
bytes32[] memory _addressesAndAmounts
) public onlyOwner 

或者

function multiERC20TransferTightlyPacked(
address mtok, 
bytes32[] calldata _addressesAndAmounts
) public onlyOwner 

取決於您的案例!

在這兩個函式中,您在函式聲明中缺少帶有數組的數據位置:

function multiERC20TransferTightlyPacked(
   address mtok, 
   bytes32[] memory _addressesAndAmounts
)

OR

function multiERC20TransferTightlyPacked(
   address mtok, 
   bytes32[] calldata _addressesAndAmounts
)
function multiERC20Transfer( 
   address mtok,
   address[] memory _addresses,
   uint[] memory _amounts
)

OR

function multiERC20Transfer( 
   address mtok,
   address[] calldata _addresses,
   uint[] calldata _amounts
)

這些問答與您的問題無關,但對於您和其他將面臨此問題的人來說,它是相關的。我在我的文件中寫了這些。

問:哪些數據類型在聲明它們時需要數據位置?

Ans:數組、結構和映射在聲明它們時需要數據位置。但為什麼?因為這些在solidity中被稱為特殊類型的數據類型。

問:當solidity 只需要數組、結構和映射的數據位置時,為什麼我們要使用字元串的數據位置?

Ans: 因為字元串在內部是一個字元數組。

Q. 我們可以在函式參數中使用儲存數據位置嗎?如果不是那為什麼?

Ans: Solidity 知道這些函式參數是臨時的,不會儲存在任何地方。

引用自:https://ethereum.stackexchange.com/questions/132508