Example output
Below is a sample NFT smart contract for your project using Solidity. The contract is based on the ERC-721 standard and implements the required features: creation and issuance of NFTs, ownership and transfer, and royalty control.
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC2981.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyNFT is ERC721URIStorage, IERC2981, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
uint256 private constant ROYALTY_PERCENT = 10;
mapping(uint256 => address) private _creators;
mapping(uint256 => uint256) private _royalties;
event RoyaltyUpdated(uint256 tokenId, uint256 royalty);
constructor() ERC721("MyNFT", "MNFT") {}
function mintNFT(address recipient, string memory tokenURI, uint256 royalty)
public onlyOwner
returns (uint256)
{
require(royalty <= 100, "Royalty must be between 0 and 100.");
_tokenIds.increment();
uint256 tokenId = _tokenIds.current();
_mint(recipient, tokenId);
_setTokenURI(tokenId, tokenURI);
_creators[tokenId] = recipient;
_royalties[tokenId] = royalty;
emit RoyaltyUpdated(tokenId, royalty);
return tokenId;
}
function royaltyInfo(uint256 tokenId, uint256 salePrice)
external
view
override
returns (address receiver, uint256 royaltyAmount)
{
receiver = _creators[tokenId];
royaltyAmount = (salePrice * _royalties[tokenId]) / 100;
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, IERC165)
returns (bool)
{
return
interfaceId == type(IERC2981).interfaceId ||
super.supportsInterface(interfaceId);
}
function setTokenURI(uint256 tokenId, string memory _tokenURI) public onlyOwner {
require(_exists(tokenId), "Token ID does not exist.");
_setTokenURI(tokenId, _tokenURI);
}
}
Deployment and interaction instructions:
Install Node.js and npm (https://www.npmjs.com/get-npm).
Install Truffle globally: npm install -g truffle.
Create a new directory for your project and navigate into it.
Run truffle init to set up a Truffle project.
Install the OpenZeppelin Contracts library: npm install @openzeppelin/contracts.
Save the provided smart contract as MyNFT.sol in the contracts directory.
In the truffle-config.js file, configure the desired Ethereum network and provide the necessary API keys and wallet mnemonic.
Compile the contract: truffle compile.
Deploy the contract: truffle migrate --network <network_name>.
Interact with the contract using Truffle Console: truffle console --network <network_name>.
To mint an NFT, call the mintNFT function with the desired recipient address, tokenURI, and royalty percentage.
Use MetaMask or other supported wallets to manage and transfer your NFTs.
Remember to thoroughly test your smart contract before deploying it to the mainnet. Here are some additional instructions to help you with testing and interaction:
Write tests for your contract using Truffle's testing framework. Create a new directory named test in your project, and write your test files inside it. Truffle supports both JavaScript and Solidity testing. For more information, refer to the Truffle documentation: https://www.trufflesuite.com/docs/truffle/testing/testing-your-contracts.
Run the tests using the truffle test command. Make sure all tests pass before deploying the contract to the mainnet.
Once you've deployed the contract to the Ethereum network, you can interact with it using popular Ethereum tools such as MetaMask, Etherscan, or any other Ethereum-compatible wallet. The contract address will be available in the deployment output.
To interact with your contract using MetaMask, you can add your contract as a custom token. To do this, go to MetaMask's "Assets" tab, click "Import Tokens," and then provide the contract address, token symbol (MNFT), and the number of decimals (0 for NFTs). MetaMask will then fetch the token details and allow you to manage and transfer your NFTs.
For an improved user experience and to facilitate the discovery of your NFTs, you can build a frontend web application that interacts with your smart contract. You can use popular web development frameworks such as React, Angular, or Vue.js, along with Ethereum libraries like ethers.js or Web3.js to interact with your contract.
If you plan on hosting your digital artwork or other unique digital assets on IPFS, you can use services like Pinata (https://pinata.cloud/) to store and manage your IPFS data. When minting NFTs, you can use the IPFS content identifier (CID) as the tokenURI to point to your digital asset.
Keep in mind that working with Ethereum requires a good understanding of its ecosystem, smart contracts, and best practices. Make sure to follow the latest Ethereum and Solidity documentation, and always stay up-to-date on security and optimization recommendations.