将多个 safeTransferFrom 调用捆绑到单个事务中

Bundle multiple safeTransferFrom calls into single transaction

是否有机会将多个 NFT 转账捆绑到单个交易中,以便用户只需确认一次?我正在尝试实现批量 NFT 传输功能

    for(let i = 0; i < nftCount; i++) {
      contract.methods.safeTransferFrom(from, to, userNFT[0][i]).send({ from: account });
    }

这很好用,但用户必须批准每笔转账,如果他试图转账 100 个 NFT,这会非常烦人且耗费 gas。

有没有更好的方法来一次完成批量传输?

假设收款合约不支持批量转账,您可以实现一个自定义合约,将它们批量合并到一个交易中。

pragma solidity ^0.8;

interface IERC721 {
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external;
}

contract BulkTransferer {
    IERC721 collection;

    constructor (address _collection) {
        collection = IERC721(_collection);
    }

    function bulkTransfer(address _from, address _to, uint256[] memory _tokenIds) external {
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            collection.safeTransferFrom(_from, _to, _tokenIds[i]);
        }
    }
}

因为 safeTransferFrom() 函数(在集合上)的调用者现在是你的 BulkTransferer 合约地址(而不是用户),用户需要 approve 你的合同在执行实际转移之前转移他们的代币。

通过多次执行 approve() 函数,每个令牌 ID 执行一次。或者一个不太安全的选择——通过执行 setApprovalForAll() 给予 BulkTransferer 合同地址批准转移 any 用户的代币。

如果你正在处理多个approve的NFT转账问题,那么我建议你可以看一下setApprovalForAll

https://docs.openzeppelin.com/contracts/4.x/api/token/erc721#IERC721-setApprovalForAll-address-bool-

该功能描述了您可以授权您信任的合约(可能是市场)代表您转让您拥有的所有 NFT 代币。因此,您无需对每个令牌都进行“批准”。