How to implement ERC721 batchBuy

I’m trying to implement a batchBuy function on 4.0 but I’m getting hit by scoping issues. More specifically, I’m in need to modify _balances and _owners but they are declared as private.

Here is a non-complete implementation:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.1;

import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";

//...

contract Abc is ERC721Upgradeable {

    //...

    function buyBatch(uint256[] memory tokenIds) public payable {
        require(msg.value >= COST * tokenIds.length, "not enough funds to cover the cost of each token");

        _balances[msg.sender] += tokenIds.length;

        for (uint i = 0; i < tokenIds.length; i++) {
            _beforeTokenTransfer(address(0), msg.sender, tokenIds[i]);

            _owners[tokenIds[i]] = msg.sender;

            emit Transfer(address(0), msg.sender, tokenIds[i]);
        }
    }
}

Also, I’m thinking that _balances[msg.sender] += tokenIds.length; could be moved inside the for loop, below _beforeTokenTransfer and change to _balances[msg.sender] += 1

I’m trying to keep the parent contract intact so I’m not sure if there is a way to do it.

1 Like

Hi @ExeciN, you should be using ERC721’s _mint or _safeMint functions.

1 Like

I’m trying to conserve gas usage.
This is why I don’t just call _mint inside the for loop.
For the same reason I’m also trying to get as many things outside of the for loop.

1 Like

Okay, I understand.

It’s not possible to access the owners mapping, this is by design and it won’t change.

My suggestion to conserve gas would be to first update to version 4.0 Beta, which has improved the gas efficiency of ERC721. (See announcement for details.)

However, you have to use _mint in the for loop. Take a look at the gas costs after upgrading to 4.0 Beta and see if you still consider that it needs optimization.

1 Like

This is already build on top of 4.0 beta hence the references to _balances and _owners.
In any case I see that the _owners mapping stays private so I guess my quest stops here.

Thanks for the inputs.

1 Like