update smart contract and test UI
This commit is contained in:
parent
db0c6c3c33
commit
e1ccb79e6a
|
|
@ -4,7 +4,7 @@ import { ethers } from 'ethers';
|
||||||
import { abi, NFT_CONTRACT_ADDRESS } from "../constants/index";
|
import { abi, NFT_CONTRACT_ADDRESS } from "../constants/index";
|
||||||
|
|
||||||
const CertificateMinter = () => {
|
const CertificateMinter = () => {
|
||||||
const [recipient, setRecipient] = useState('');
|
const [certificateId, setCertificateId] = useState('');
|
||||||
const [userName, setUserName] = useState('');
|
const [userName, setUserName] = useState('');
|
||||||
const [surName, setSurName] = useState('');
|
const [surName, setSurName] = useState('');
|
||||||
const [email, setEmail] = useState('');
|
const [email, setEmail] = useState('');
|
||||||
|
|
@ -18,23 +18,28 @@ const CertificateMinter = () => {
|
||||||
const signer = provider.getSigner();
|
const signer = provider.getSigner();
|
||||||
const certificateContract = new ethers.Contract(NFT_CONTRACT_ADDRESS, abi, signer);
|
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!');
|
alert('Certificate minted successfully!');
|
||||||
} else {
|
} else {
|
||||||
alert('Please connect your wallet');
|
alert('Please connect your wallet');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error minting certificate:', error);
|
console.error('Error minting certificate:', error);
|
||||||
|
|
||||||
|
if (error.code === 4001) {
|
||||||
|
alert('Certificate already issued');
|
||||||
|
} else {
|
||||||
alert('Error minting certificate. Please check the console for details.');
|
alert('Error minting certificate. Please check the console for details.');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2>Certificate Minter</h2>
|
<h2>Certificate Minter</h2>
|
||||||
<label>
|
<label>
|
||||||
Recipient Address:
|
Certificate ID:
|
||||||
<input type="text" value={recipient} onChange={(e) => setRecipient(e.target.value)} style={{ color: 'black' }} />
|
<input type="text" value={certificateId} onChange={(e) => setCertificateId(e.target.value)} style={{ color: 'black' }} />
|
||||||
</label>
|
</label>
|
||||||
<br />
|
<br />
|
||||||
<label>
|
<label>
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,4 @@
|
||||||
export const abi = [
|
export const abi = [
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "to",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "tokenId",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "approve",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"inputs": [],
|
"inputs": [],
|
||||||
"stateMutability": "nonpayable",
|
"stateMutability": "nonpayable",
|
||||||
|
|
@ -125,39 +107,6 @@ export const abi = [
|
||||||
"name": "ERC721NonexistentToken",
|
"name": "ERC721NonexistentToken",
|
||||||
"type": "error"
|
"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": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -249,82 +198,6 @@ export const abi = [
|
||||||
"name": "OwnershipTransferred",
|
"name": "OwnershipTransferred",
|
||||||
"type": "event"
|
"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,
|
"anonymous": false,
|
||||||
"inputs": [
|
"inputs": [
|
||||||
|
|
@ -352,11 +225,6 @@ export const abi = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "from",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"internalType": "address",
|
"internalType": "address",
|
||||||
"name": "to",
|
"name": "to",
|
||||||
|
|
@ -368,20 +236,7 @@ export const abi = [
|
||||||
"type": "uint256"
|
"type": "uint256"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "transferFrom",
|
"name": "approve",
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "newOwner",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "transferOwnership",
|
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"stateMutability": "nonpayable",
|
"stateMutability": "nonpayable",
|
||||||
"type": "function"
|
"type": "function"
|
||||||
|
|
@ -482,6 +337,39 @@ export const abi = [
|
||||||
"stateMutability": "view",
|
"stateMutability": "view",
|
||||||
"type": "function"
|
"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": [],
|
"inputs": [],
|
||||||
"name": "name",
|
"name": "name",
|
||||||
|
|
@ -540,6 +428,82 @@ export const abi = [
|
||||||
"stateMutability": "view",
|
"stateMutability": "view",
|
||||||
"type": "function"
|
"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": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -590,8 +554,44 @@ export const abi = [
|
||||||
],
|
],
|
||||||
"stateMutability": "view",
|
"stateMutability": "view",
|
||||||
"type": "function"
|
"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 =
|
export const NFT_CONTRACT_ADDRESS =
|
||||||
"0x402F88e39B21390Ff962fb4bF1EE05f335E7dA3c";
|
"0xe7Bf32841a34C053aBcE967E0bE787F4164536d9";
|
||||||
|
|
|
||||||
22
nftCert.sol
22
nftCert.sol
|
|
@ -10,6 +10,9 @@ contract Certificate is ERC721, Ownable {
|
||||||
// Mapping to store additional information for each certificate
|
// Mapping to store additional information for each certificate
|
||||||
mapping(uint256 => CertificateInfo) private certificateInfoMapping;
|
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 {
|
struct CertificateInfo {
|
||||||
string userName;
|
string userName;
|
||||||
string surName;
|
string surName;
|
||||||
|
|
@ -20,18 +23,25 @@ contract Certificate is ERC721, Ownable {
|
||||||
constructor() ERC721("Certificate", "CERT") Ownable(msg.sender) {}
|
constructor() ERC721("Certificate", "CERT") Ownable(msg.sender) {}
|
||||||
|
|
||||||
function mintCertificate(
|
function mintCertificate(
|
||||||
address recipient,
|
uint256 certificateId,
|
||||||
string memory userName,
|
string memory userName,
|
||||||
string memory surName,
|
string memory surName,
|
||||||
string memory email,
|
string memory email,
|
||||||
string memory companyName
|
string memory companyName
|
||||||
) external onlyOwner {
|
) external {
|
||||||
uint256 tokenId = nextCertificateId;
|
// Check if the certificate with the given ID has already been issued
|
||||||
_safeMint(recipient, tokenId);
|
require(!issuedCertificates[userName][msg.sender], "Certificate already issued");
|
||||||
nextCertificateId++;
|
|
||||||
|
_safeMint(msg.sender, certificateId);
|
||||||
|
|
||||||
// Store additional information using a mapping
|
// 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(
|
function _storeCertificateInfo(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue