diff --git a/components/CertificateMinter.js b/components/CertificateMinter.js
index 5db8afa..8bf1285 100644
--- a/components/CertificateMinter.js
+++ b/components/CertificateMinter.js
@@ -4,7 +4,7 @@ import { ethers } from 'ethers';
import { abi, NFT_CONTRACT_ADDRESS } from "../constants/index";
const CertificateMinter = () => {
- const [recipient, setRecipient] = useState('');
+ const [certificateId, setCertificateId] = useState('');
const [userName, setUserName] = useState('');
const [surName, setSurName] = useState('');
const [email, setEmail] = useState('');
@@ -18,14 +18,19 @@ const CertificateMinter = () => {
const signer = provider.getSigner();
const certificateContract = new ethers.Contract(NFT_CONTRACT_ADDRESS, abi, signer);
- await certificateContract.mintCertificate(recipient, userName, surName, email, companyName);
+ await certificateContract.mintCertificate(certificateId, userName, surName, email, companyName);
alert('Certificate minted successfully!');
} else {
alert('Please connect your wallet');
}
} catch (error) {
console.error('Error minting certificate:', error);
- alert('Error minting certificate. Please check the console for details.');
+
+ if (error.code === 4001) {
+ alert('Certificate already issued');
+ } else {
+ alert('Error minting certificate. Please check the console for details.');
+ }
}
};
@@ -33,28 +38,28 @@ const CertificateMinter = () => {
Certificate Minter
diff --git a/constants/index.js b/constants/index.js
index a426048..d72f84a 100644
--- a/constants/index.js
+++ b/constants/index.js
@@ -1,22 +1,4 @@
export const abi = [
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "approve",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
{
"inputs": [],
"stateMutability": "nonpayable",
@@ -125,39 +107,6 @@ export const abi = [
"name": "ERC721NonexistentToken",
"type": "error"
},
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "recipient",
- "type": "address"
- },
- {
- "internalType": "string",
- "name": "userName",
- "type": "string"
- },
- {
- "internalType": "string",
- "name": "surName",
- "type": "string"
- },
- {
- "internalType": "string",
- "name": "email",
- "type": "string"
- },
- {
- "internalType": "string",
- "name": "companyName",
- "type": "string"
- }
- ],
- "name": "mintCertificate",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
{
"inputs": [
{
@@ -249,82 +198,6 @@ export const abi = [
"name": "OwnershipTransferred",
"type": "event"
},
- {
- "inputs": [],
- "name": "renounceOwnership",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "safeTransferFrom",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- },
- {
- "internalType": "bytes",
- "name": "data",
- "type": "bytes"
- }
- ],
- "name": "safeTransferFrom",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "operator",
- "type": "address"
- },
- {
- "internalType": "bool",
- "name": "approved",
- "type": "bool"
- }
- ],
- "name": "setApprovalForAll",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
{
"anonymous": false,
"inputs": [
@@ -352,11 +225,6 @@ export const abi = [
},
{
"inputs": [
- {
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
{
"internalType": "address",
"name": "to",
@@ -368,20 +236,7 @@ export const abi = [
"type": "uint256"
}
],
- "name": "transferFrom",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "newOwner",
- "type": "address"
- }
- ],
- "name": "transferOwnership",
+ "name": "approve",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
@@ -482,6 +337,39 @@ export const abi = [
"stateMutability": "view",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "certificateId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "userName",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "surName",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "email",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "companyName",
+ "type": "string"
+ }
+ ],
+ "name": "mintCertificate",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
{
"inputs": [],
"name": "name",
@@ -540,6 +428,82 @@ export const abi = [
"stateMutability": "view",
"type": "function"
},
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "safeTransferFrom",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "safeTransferFrom",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "operator",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "approved",
+ "type": "bool"
+ }
+ ],
+ "name": "setApprovalForAll",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -590,8 +554,44 @@ export const abi = [
],
"stateMutability": "view",
"type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
}
];
export const NFT_CONTRACT_ADDRESS =
- "0x402F88e39B21390Ff962fb4bF1EE05f335E7dA3c";
+ "0xe7Bf32841a34C053aBcE967E0bE787F4164536d9";
diff --git a/nftCert.sol b/nftCert.sol
index 72c8090..283d88b 100644
--- a/nftCert.sol
+++ b/nftCert.sol
@@ -10,6 +10,9 @@ contract Certificate is ERC721, Ownable {
// Mapping to store additional information for each certificate
mapping(uint256 => CertificateInfo) private certificateInfoMapping;
+ // Mapping to check if a certificate with a given name and wallet address has been issued
+ mapping(string => mapping(address => bool)) private issuedCertificates;
+
struct CertificateInfo {
string userName;
string surName;
@@ -20,18 +23,25 @@ contract Certificate is ERC721, Ownable {
constructor() ERC721("Certificate", "CERT") Ownable(msg.sender) {}
function mintCertificate(
- address recipient,
+ uint256 certificateId,
string memory userName,
string memory surName,
string memory email,
string memory companyName
- ) external onlyOwner {
- uint256 tokenId = nextCertificateId;
- _safeMint(recipient, tokenId);
- nextCertificateId++;
+ ) external {
+ // Check if the certificate with the given ID has already been issued
+ require(!issuedCertificates[userName][msg.sender], "Certificate already issued");
+
+ _safeMint(msg.sender, certificateId);
// Store additional information using a mapping
- _storeCertificateInfo(tokenId, userName, surName, email, companyName);
+ _storeCertificateInfo(certificateId, userName, surName, email, companyName);
+
+ // Mark the certificate as issued
+ issuedCertificates[userName][msg.sender] = true;
+
+ // Update the nextCertificateId only if the mint is successful
+ nextCertificateId = certificateId + 1;
}
function _storeCertificateInfo(