SimpleERC721Token using OpenZeppelin Contracts

SimpleERC721Token

Simple ERC721 Token using OpenZeppelin Contracts v3.0 beta release

I used Ownable whilst Access Controls for OpenZeppelin Contracts are redesigned.
A minter role with permission to mint, and an admin role to change the baseURI would be preferred and will change to this when access control is finished.

mint calls _setTokenURI it would be nice to do away with this all together by overriding tokenURI.

:warning: This sample has not been tested nor audited. Any solution should be appropriately tested and audited.

It can be deployed and interacted with using OpenZeppelin CLI 2.8: Release Candidate which now supports regular (non-upgradeable) deploys! :rocket:

SimpleERC721Token.sol

pragma solidity ^0.6.0;

import "@openzeppelin/contracts/token/ERC721/ERC721Full.sol";
import "@openzeppelin/contracts/ownership/Ownable.sol";
import "@openzeppelin/contracts/drafts/Strings.sol";
import "@openzeppelin/contracts/drafts/Counters.sol";

contract SimpleERC721Token is ERC721Full, Ownable {

    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor () public ERC721Full("Simple ERC721 Token", "SIM") {
        _setBaseURI("https://example.com/tokens/");
    }

    function setBaseURI(string memory baseURI) public onlyOwner {
        _setBaseURI(baseURI);
    }

    function mint(address to) public onlyOwner {
        _tokenIds.increment();

        uint256 newTokenId = _tokenIds.current();
        _mint(to, newTokenId);
        _setTokenURI(newTokenId, Strings.fromUint256(newTokenId));
    }
}

Deploy

$ npx oz deploy
✓ Compiled contracts with solc 0.6.3 (commit.8dda9521)
? Choose the kind of deployment regular
? Pick a network development
? Pick a contract to deploy SimpleERC721Token
✓ Deployed instance of SimpleERC721Token
0x21a59654176f2689d12E828B77a783072CD26680

Mint

$ npx oz send-tx
? Pick a network development
? Pick an instance SimpleERC721Token at 0x21a59654176f2689d12E828B77a783072CD26680
? Select which function mint(to: address)
? to: address: 0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0
✓ Transaction successful. Transaction hash: 0x6cb4119a1117473191aa8288dadf509be8dd474d537ab0cc0485b10efc61ad69
Events emitted:
 - Transfer(0x0000000000000000000000000000000000000000, 0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0, 1)

Get TokenURI

$ npx oz call
? Pick a network development
? Pick an instance SimpleERC721Token at 0x21a59654176f2689d12E828B77a783072CD26680
? Select which function tokenURI(tokenId: uint256)
? tokenId: uint256: 1
✓ Method 'tokenURI(uint256)' returned: https://example.com/tokens/1
https://example.com/tokens/1

If you want to experiment using Remix you can use the below code (only the imports have been changed).

:warning: Note: You should only use code published in an official release of OpenZeppelin Contracts. When importing via GitHub on Remix you can specify the release tag, (otherwise you will get the latest code in the master branch). The example below imports v3 Beta.

:warning: This sample has not been tested nor audited. Any solution should be appropriately tested and audited.

SimpleERC721Token.sol (GitHub imports for use on Remix)

pragma solidity ^0.6.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0-beta.0/contracts/token/ERC721/ERC721Full.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0-beta.0/contracts/ownership/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0-beta.0/contracts/drafts/Strings.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0-beta.0/contracts/drafts/Counters.sol";

contract SimpleERC721Token is ERC721Full, Ownable {

    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor () public ERC721Full("Simple ERC721 Token", "SIM") {
        _setBaseURI("https://example.com/tokens/");
    }

    function setBaseURI(string memory baseURI) public onlyOwner {
        _setBaseURI(baseURI);
    }

    function mint(address to) public onlyOwner {
        _tokenIds.increment();

        uint256 newTokenId = _tokenIds.current();
        _mint(to, newTokenId);
        _setTokenURI(newTokenId, Strings.fromUint256(newTokenId));
    }
}