I would like to restrict the number of NFTs any one address can own. How would you implement this in a Solidity smart contract? Say I have an ERC721 NFT contract, Square.sol:
import "../node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract Square is ERC721 {
constructor() ERC721("Square", "SQUARE") public {}
string[] public squares;
mapping (address => uint) public ownerSquareCount;
function mint(string memory _colour) public {
// No one should own more than one square
require(ownerSquareCount[msg.sender] == 0, 'Each address may only own one square');
squares.push(_colour);
uint id = squares.length;
ownerSquareCount[msg.sender]++;
//Open Zeppelin ERC721 _safeMint function
_safeMint(msg.sender, id);
}
}
I have tested the above code, but it still allows a single account to mint more than one Square NFT.
(I recognize that anyone can simply create multiple addresses as a work-around, but I'm hoping the effort of having to manage lots of addresses will limit the extent to which this would occur)
EDIT
I have found the solution. For some reason, the ownerSquareCount
mapping does not work. Instead, you can use the balanceOf
function, which is part of the ERC721 standard. If you change line 10 to:
require(balanceOf(msg.sender) == 0, 'Each address may only own one square');
It works like a charm, throwing an error if an account tries to mint more than one token.
I am only a beginner, but one piece of advice I can share: if you are building smart contracts off a standard (like ERC721 or ERC20), dig deep into those existing contracts. A lot of the functionality you are about to code is probably already done there. I found myself tidying up my NFT smart contract by simply deleting my functions and using the built-in ones.