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";
|
||||
|
||||
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 = () => {
|
|||
<div>
|
||||
<h2>Certificate Minter</h2>
|
||||
<label>
|
||||
Recipient Address:
|
||||
<input type="text" value={recipient} onChange={(e) => setRecipient(e.target.value)} style={{ color: 'black' }} />
|
||||
Certificate ID:
|
||||
<input type="text" value={certificateId} onChange={(e) => setCertificateId(e.target.value)} style={{ color: 'black' }} />
|
||||
</label>
|
||||
<br />
|
||||
<label>
|
||||
Name:
|
||||
<input type="text" value={userName} onChange={(e) => setUserName(e.target.value)} style={{ color: 'black' }}/>
|
||||
<input type="text" value={userName} onChange={(e) => setUserName(e.target.value)} style={{ color: 'black' }} />
|
||||
</label>
|
||||
<br />
|
||||
<label>
|
||||
Surname:
|
||||
<input type="text" value={surName} onChange={(e) => setSurName(e.target.value)} style={{ color: 'black' }}/>
|
||||
<input type="text" value={surName} onChange={(e) => setSurName(e.target.value)} style={{ color: 'black' }} />
|
||||
</label>
|
||||
<br />
|
||||
<label>
|
||||
Email:
|
||||
<input type="text" value={email} onChange={(e) => setEmail(e.target.value)} style={{ color: 'black' }}/>
|
||||
<input type="text" value={email} onChange={(e) => setEmail(e.target.value)} style={{ color: 'black' }} />
|
||||
</label>
|
||||
<br />
|
||||
<label>
|
||||
Company Name:
|
||||
<input type="text" value={companyName} onChange={(e) => setCompanyName(e.target.value)} style={{ color: 'black' }}/>
|
||||
<input type="text" value={companyName} onChange={(e) => setCompanyName(e.target.value)} style={{ color: 'black' }} />
|
||||
</label>
|
||||
<br />
|
||||
<button onClick={mintCertificate}>Mint Certificate</button>
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
22
nftCert.sol
22
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(
|
||||
|
|
|
|||
Loading…
Reference in New Issue