即使我不拿任何 ether/matic,是否还需要 payable 关键字?

Is payble keyword neccessary even if I am not taking any ether/matic?

 function sendGift(uint256 _mintAmount,address recipient) public payable {
    uint256 supply = totalSupply();
    require(!paused);
    require(_mintAmount > 0);
    require(_mintAmount <= maxMintAmount);
    require(supply + _mintAmount<= availableSupplyForSale);
    //require(_amount >= cost * _mintAmount);
    require(coinToken.allowance(msg.sender,address(this))>=cost * _mintAmount);
      coinToken.transferFrom(msg.sender, address(this),cost * _mintAmount);
    if(supply<currentSupply){
    for (uint256 i = 1; i <= _mintAmount; i++) {
      _safeMint(recipient, supply + i);
    }
    }
    else{
         uint256[] memory tokenIds = walletOfOwner(address(this));
         for(uint256 i=1;i<=_mintAmount;i++)
        transferFrom(address(this),recipient,tokenIds[i]);
    }
  }

这里需要使用payable吗?合约不需要任何matic。它只接受自定义令牌作为付款。

(bool os, ) = payable(admin).call{value: address(this).balance}("");
    require(os);

此外,由于我没有使用任何 matic,作为所有者从合同中提取资产是否需要上述行?我有一种感觉,上面这行仅对提取 eth/polygon.

有用

我是区块链新手。请帮忙。

当您的函数接受原生代币(ETH、BNB、MATIC……取决于网络)时,函数的 payable 修饰符是必需的。

所以在这种情况下,您可以安全地将其从函数头中删除。

// removed `payable`
function sendGift(uint256 _mintAmount,address recipient) public {

low-level .call() 也不需要使用 payable 发送本地令牌。

payable(admin).call{value: address(this).balance}("");

但是,如果您使用 high-level .transfer(),那么您需要将 admin 变量类型 address 转换为它的扩展类型 address payable 使用类型转换功能。

// will not work as it's type `address`
admin.transfer(address(this).balance);
// need to cast type `address` to type `address payable`
payable(admin).transfer(address(this).balance);

为了从您的合约地址提取代​​币,您需要在代币合约上调用 transfer() 函数(在 ERC-20 标准中定义)。不要将它与 address payable 的原生 transfer() 函数混淆,这是两个不同的东西,只是名称相同。

interface IERC20 {
    function transfer(address, uint256) external returns (bool);
}

contract MyContract {
    function withdrawToken() {
        IERC20(tokenContractAddress).transfer(recipient, amount);
    }
}