I built a decentralized app for creating NFTs and deployed it on Polygon Mumbai testnet. When I try to create a new token, the blockchain shows the transaction went through fine and I get a transaction ID, but the NFT never shows up in my MetaMask wallet.
Smart Contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract DigitalArtToken is ERC721, Ownable {
uint256 public constant TOTAL_SUPPLY = 50;
uint256 public constant TOKEN_PRICE = 0.02 ether;
uint256 public currentTokenId = 1;
constructor() ERC721("DigitalArtToken", "DAT") {}
function createToken() public payable {
require(currentTokenId <= TOTAL_SUPPLY, "All tokens have been minted");
require(msg.value >= TOKEN_PRICE, "Insufficient payment");
_safeMint(msg.sender, currentTokenId);
currentTokenId++;
}
function withdrawFunds() public onlyOwner {
uint256 contractBalance = address(this).balance;
payable(owner()).transfer(contractBalance);
}
}
Frontend Code:
import React, { useState, useEffect } from 'react';
import Web3 from 'web3';
import { Container, Button, Card } from 'react-bootstrap';
import DigitalArtToken from './contracts/DigitalArtToken.json';
import tokenImage from './assets/token.jpg';
function TokenMinter() {
const [web3Instance, setWeb3Instance] = useState(null);
const [tokenContract, setTokenContract] = useState(null);
const [userAddress, setUserAddress] = useState('');
const [ownedTokens, setOwnedTokens] = useState([]);
const [connectionError, setConnectionError] = useState('');
const initializeWeb3 = async () => {
try {
if (window.ethereum) {
const web3 = new Web3(window.ethereum);
await window.ethereum.request({ method: 'eth_requestAccounts' });
setWeb3Instance(web3);
const contract = new web3.eth.Contract(
DigitalArtToken.abi,
"0xA1B2C3D4E5F6789012345678901234567890ABCD"
);
setTokenContract(contract);
const accounts = await web3.eth.getAccounts();
setUserAddress(accounts[0]);
const balance = await contract.methods.balanceOf(accounts[0]).call();
setOwnedTokens(Array.from({length: parseInt(balance)}, (_, i) => i + 1));
} else {
setConnectionError('MetaMask is required!');
}
} catch (error) {
console.error(error);
setConnectionError('Connection failed!');
}
};
const purchaseToken = async () => {
try {
const transaction = await tokenContract.methods.createToken().send({
from: userAddress,
value: web3Instance.utils.toWei('0.02', 'ether'),
});
console.log('Transaction result:', transaction);
const newBalance = await tokenContract.methods.balanceOf(userAddress).call();
setOwnedTokens(Array.from({length: parseInt(newBalance)}, (_, i) => i + 1));
} catch (error) {
console.error('Minting failed:', error);
}
};
if (!web3Instance) {
return (
<div className="connection-screen">
<Button onClick={initializeWeb3}>Connect Wallet</Button>
{connectionError && <p className="error">{connectionError}</p>}
</div>
);
}
return (
<Container>
<h2>Digital Art Collection</h2>
<p>Connected: {userAddress}</p>
<div className="token-grid">
{[1,2,3,4,5].map((id) => (
<Card key={id} className="token-card">
<Card.Img src={tokenImage} alt={`Token ${id}`} />
<Card.Body>
<Card.Title>Art Token #{id}</Card.Title>
</Card.Body>
</Card>
))}
</div>
<div className="mint-section">
<Button variant="primary" onClick={purchaseToken}>
Mint New Token
</Button>
<p>Price: 0.02 MATIC</p>
<p>You own: {ownedTokens.length}/50 tokens</p>
</div>
</Container>
);
}
export default TokenMinter;
Any ideas what might be wrong?