This README provides step-by-step instructions on how to deploy, verify, and interact with the FundNFT contract. The contract is based on the ERC1155 token standard and allows users to create funds, buy NFTs, and manage metadata.
This guide uses Foundry, a fast and flexible Ethereum development tool.
- Prerequisites
- Contract Overview
- Deploying the Contract
- Verifying the Contract
- Interacting with the Contract
- Contract Functions
- Events
- Testing the Contract
Before deploying the contract, ensure you have the following setup:
-
Foundry: Install Foundry by running:
curl -L https://foundry.paradigm.xyz | bash foundryup -
Metamask: A wallet to interact with the Ethereum network.
-
Infura or Alchemy API Key: For connecting to Ethereum networks like Rinkeby, Goerli, or Mainnet.
The FundNFT contract implements an ERC1155 token that allows the owner to create funds, mint NFTs for each fund, and let users purchase NFTs for 0.05 ETH. It also supports metadata management and withdrawals for the collected ETH.
- Create funds: The owner can create a new fund and mint a set number of NFTs.
- Buy NFTs: Users can purchase NFTs for 0.05 ETH.
- Metadata management: Allows changing the metadata URI for each fund.
- Withdraw funds: The contract owner can withdraw collected funds (ETH).
If you haven't already initialized a Foundry project, do so by running:
forge init fund-nft
cd fund-nftThis will create a project structure with the necessary files.
Install the OpenZeppelin contracts and other dependencies:
forge install OpenZeppelin/openzeppelin-contractsCreate the contract in the src directory as FundNFT.sol.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {ERC1155} from "lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol";
import {Strings} from "lib/openzeppelin-contracts/contracts/utils/Strings.sol";
import {IERC1155Receiver, IERC165} from "lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol";
// Contract implementation goes here...In the script directory, create a file called DeployFundNFT.s.sol with the following content:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {FundNFT} from "../src/FundNFT.sol";
import {Script} from "forge-std/Script";
contract DeployFundNFT is Script {
function run() public {
vm.startBroadcast();
string memory initialBaseURI = "https://mybaseuri.com/fund1/";
FundNFT fundNFT = new FundNFT(initialBaseURI);
console.log("FundNFT deployed to:", address(fundNFT));
vm.stopBroadcast();
}
}Use Foundry to deploy the contract. Run the following command:
forge script script/DeployFundNFT.s.sol --rpc-url <your_rpc_url> --private-key <your_private_key> --broadcastReplace <your_rpc_url> with the URL from your Infura or Alchemy account, and <your_private_key> with your wallet’s private key.
Once the contract is deployed, you can verify it on Etherscan (or any other block explorer). You need to use the forge-verify plugin:
-
Install the
forge-verifyplugin:forge install foundry-rs/forge-verify
-
Add your Etherscan API key to
foundry.toml:[profile] etherscan_api_key = "your_etherscan_api_key"
-
Verify the contract using the following command:
forge verify-contract <contract_address> src/FundNFT.sol:<FundNFT> --etherscan-api-key <your_etherscan_api_key>
You can interact with the deployed contract using the Foundry console. Start the console with:
forge console --rpc-url <your_rpc_url>Once connected, you can interact with your contract like this:
FundNFT fundNFT = FundNFT(<contract_address>);fundNFT.createFund(1000, "https://mybaseuri.com/fund2/");fundNFT.buyNFT(1, { value: 0.05 ether });fundNFT.withdrawFunds();fundNFT.setBaseURI(1, "https://newbaseuri.com/fund1/");(uint256 tokenId, uint256 totalSupply, uint256 availableSupply, string memory baseURI) = fundNFT.getFundDetails(1);- Purpose: Create a new fund with a specified number of NFTs and a base URI.
- Permissions: Only the owner can call this function.
- Purpose: Allows users to buy an NFT from a fund by sending 0.05 ETH.
- Permissions: Public, anyone can call this function.
- Purpose: Allows the owner to withdraw ETH collected from NFT sales.
- Permissions: Only the owner can call this function.
- Purpose: Set a new base URI for the fund's metadata.
- Permissions: Only the owner can call this function.
- Purpose: Constructs the metadata URL based on the fund ID and token ID.
- Permissions: Public, anyone can call this function.
- Emitted when: A new fund is created.
- Emitted when: An NFT is purchased.
You can write and run tests using Foundry.
Create a test in the test directory, for example, FundNFTTest.t.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {FundNFT} from "../src/FundNFT.sol";
import {Test} from "forge-std/Test";
contract FundNFTTest is Test {
FundNFT fundNFT;
function setUp() public {
fundNFT = new FundNFT("https://mybaseuri.com/");
}
function testCreateFund() public {
uint256 fundId = fundNFT.createFund(1000, "https://mybaseuri.com/fund1/");
assertEq(fundId, 1);
}
function testBuyNFT() public {
fundNFT.createFund(1000, "https://mybaseuri.com/fund1/");
fundNFT.buyNFT{value: 0.05 ether}(1);
}
function testWithdrawFunds() public {
fundNFT.createFund(1000, "https://mybaseuri.com/fund1/");
fundNFT.buyNFT{value: 0.05 ether}(1);
fundNFT.withdrawFunds();
}
}To run tests, execute:
forge testThis will compile and run the tests defined in the test directory.
This concludes the README for deploying, verifying, and interacting with the FundNFT contract using Foundry.