> For the complete documentation index, see [llms.txt](https://docs.autentica.io/whitepaper/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.autentica.io/whitepaper/blockchain/autentica-erc-721.md).

# Autentica ERC-721

Autentica Market (*AUTMKT*) is an ERC-721 smart contract that enables anyone to mint NFTs through our [Marketplace](https://www.autentica.market/). In addition to the ERC-721 standard, our smart contract also enables creators to receive royalties for each subsequent sale by implementing a proprietary solution which is described in the [IERC721Autentica](https://github.com/AutenticaCrypto/smart-contracts/blob/main/contracts/IERC721Autentica.sol) interface but also the [ERC-2981](https://eips.ethereum.org/EIPS/eip-2981) standard to ensure that creators are compensated for every sale, regardless of whether that sale occurs on the same platform where the NFT was originally created or on a different platform entirely that also supports that standard.

Minting NFTs can be a problem for many artists because of the technical aspects or because of the high costs associated to this process, and for this our Autentica Market (*AUTMKT*) smart contract enables creators that use our [Marketplace](https://www.autentica.market/) to have someone else cover the minting process and pay for the gas fees associated to it. What this means is that a creator can choose to have an investor to mint the NFT on his behalf and also cover the associated gas fees, while the the newly created NFT is owned by the creator. This solution is implemented on both the [Autentica Marketplace](https://www.autentica.market/) and the smart contract.

### Technical details

The smart contract inherits [OpenZeppelin Contracts](https://openzeppelin.com/contracts/)'s `Context`, `ERC721URIStorage`, `ERC721Enumerable`, and `AccessControl` abstract contracts and implements the `IERC2981` and `IERC721Autentica` interfaces.

#### Types

In order to support royalties and keep references to the investors that handled the NFT minting process on behalf of other creators we defined the following structure called `TokenDetails`

```
struct TokenDetails {
    /// Address of the wallet that created the token.
    address creator;
    /// Address of the wallet who paid for gas fees.
    address investor;
    /// The value ranges between 0 and 100 multiplied by (10 ** DECIMALS).
    uint256 royaltyFee;
    /// The value ranges between 0 and 100 multiplied by (10 ** DECIMALS).
    uint256 investorFee;
}
```

This structure enables us to determine who created the token, who minted it (the creator or an investor), the royalty fee, and if the royalty fee should be shared with an investor if the token was not minted by the creator.

#### Storage

The additional storage that this smart contracts uses on top of the `ERC721URIStorage`, `ERC721Enumerable` and `AccessControl` is the address of the NFT Marketplace smart contract which handles the trading part and a mapping from token ID to the `TokenDetails` structure which contains information like the creator and investor address, royalty fee and the investor fee.

#### Operations

**Minting**

The standard minting process is to invoke the `mint` function with `tokenId` which represents a unique identifier for the NFT, `uri` which represents the Uniform Resource Identifier that identifies the JSON file describing the NFT, and `royaltyFee` which represents the royalties that the creator will earn from subsequent sales expressed as a percentage.

```
/**
 * @dev Creates a token for `_msgSender()`. The creator of the token and the owner of it will
 * be assigned to `_msgSender()`.
 *
 * @param tokenId Token ID.
 * @param uri Token URI.
 * @param royaltyFee Royalty fee.
 *
 * See {ERC721-_mint}.
 *
 * Requirements:
 *
 * - The `royaltyFee` must be less than or equal to 100 * (10 ** DECIMALS), meaning 100%.
 */
function mint(uint256 tokenId, string memory uri, uint256 royaltyFee) external
```

### Investor Minting

If the creator is unable to mint the NFT due to the process's intricacy or the rising network gas fees, he/she can decide to mint the NFT through an investor. Prior to handing over the artwork to the *Investor*, he/she sets the `royaltyFee` that he/she wishes to earn from subsequent sales, as well as the `investorFee`, which represents the percentage that he/she gives to the *Investor* from his/hers proceeds each time the NFT is traded.

The investor then invokes the `investorMintingAndApproveMarketplace` function with the following parameters:

* `creator` which represents the address of the one that created the artwork
* `tokenId` which represents a unique identifier for the NFT
* `uri` which represents the Uniform Resource Identifier that identifies the JSON file describing the NFT
* `royaltyFee` which represents the royalties that the creator will earn from subsequent sales expressed as a percentage
* `investorFee` which represents a percentage from the creator's proceeds that is shared with the *Investor* each time the NFT is traded
* `v`, `r` and `s` that represents the ECDSA signature which verifies that the parameter values were chosen by the creator.

```
/**
 * Creates a token on behalf of a creator and approves the Autentica Marketplace smart contract.
 * The creator of the token and the owner of it will be assigned to `creator`
 * while the investor will be set to `_msgSender()`.
 *
 * @param creator Token creator and owner.
 * @param tokenId Token ID.
 * @param uri Token URI.
 * @param royaltyFee Royalty fee.
 * @param investorFee Investor fee.
 * @param v ECDSA `v` parameter.
 * @param r ECDSA `r` parameter.
 * @param s ECDSA `s` parameter.
 *
 * See {ERC721-_mint}.
 *
 * Requirements:
 *
 * - The `royaltyFee` must be less than or equal to 100 * (10 ** DECIMALS), meaning 100%.
 * - the `investorFee` must be less than or equal to 100 * (10 ** DECIMALS), meaning 100%.
 * - The investor can't be the creator.
 * - The ECDSA signature must be signed by someone with the admin or operator role.
 */
function investorMintingAndApproveMarketplace(
    address creator,
    uint256 tokenId,
    string memory uri,
    uint256 royaltyFee,
    uint256 investorFee,
    uint8 v,
    bytes32 r,
    bytes32 s
) external
```

### Source Code

The source code for the token can be found in the [AutenticaERC721.sol](https://github.com/AutenticaCrypto/smart-contracts/blob/main/contracts/AutenticaERC721.sol) file located in the `contracts` folder within our [smart-contracts](https://github.com/AutenticaCrypto/smart-contracts) repository.

### Deployments

<table><thead><tr><th width="330.38709677419354">Network</th><th>Address</th></tr></thead><tbody><tr><td>Ethereum</td><td><a href="https://etherscan.io/address/0x48a868dd45151800e306e83234c0eef55e5bc624">0x48a868dD45151800e306e83234c0EeF55E5BC624</a></td></tr><tr><td>Binance Smart Chain</td><td><a href="https://bscscan.com/address/0xf262a3b2a6973db844b6c82187d917e3b7a89170">0xf262a3b2a6973db844b6c82187d917e3b7a89170</a></td></tr><tr><td>Ethereum (Rinkeby)</td><td><a href="https://rinkeby.etherscan.io/address/0x7E7821ef6C1D635f4E7f9Bc0964207CB0F10F45f">0x7E7821ef6C1D635f4E7f9Bc0964207CB0F10F45f</a></td></tr><tr><td>Binance Smart Chain (testnet)</td><td><a href="https://testnet.bscscan.com/address/0x289a01be6A52B664D1C2EDEBB19F6C6419fb8229">0x289a01be6A52B664D1C2EDEBB19F6C6419fb8229</a></td></tr></tbody></table>
