On Chain Verification

This on chain verification will verify the validity of the ZKP (Zero Knowledge Proof) curcuit and the underlying inputs that were used

JavaScript

  1. Define ABI for both verifier and 0xKYC soulbound contracts:

       
const verifierAbi = [{"inputs":[{"components":[{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct Pairing.G1Point","name":"a","type":"tuple"},{"components":[{"internalType":"uint256[2]","name":"X","type":"uint256[2]"},{"internalType":"uint256[2]","name":"Y","type":"uint256[2]"}],"internalType":"struct Pairing.G2Point","name":"b","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct Pairing.G1Point","name":"c","type":"tuple"}],"internalType":"struct ZkVerifier.Proof","name":"proof","type":"tuple"},{"internalType":"uint256[3]","name":"input","type":"uint256[3]"}],"name":"verifyTx","outputs":[{"internalType":"bool","name":"r","type":"bool"}],"stateMutability":"view","type":"function"}]
       
       
const soulboundAbi = [ { "inputs": [ { "internaltype": "string", "name": "name_", "type": "string" }, { "internaltype": "string", "name": "symbol_", "type": "string" } ], "statemutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": false, "internaltype": "address", "name": "_soul", "type": "address" } ], "name": "burn", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "internaltype": "address", "name": "_soul", "type": "address" } ], "name": "mint", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internaltype": "address", "name": "previousowner", "type": "address" }, { "indexed": true, "internaltype": "address", "name": "newowner", "type": "address" } ], "name": "ownershiptransferred", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "internaltype": "address", "name": "_soul", "type": "address" } ], "name": "update", "type": "event" }, { "inputs": [], "name": "_name", "outputs": [ { "internaltype": "string", "name": "", "type": "string" } ], "statemutability": "view", "type": "function" }, { "inputs": [], "name": "_symbol", "outputs": [ { "internaltype": "string", "name": "", "type": "string" } ], "statemutability": "view", "type": "function" }, { "inputs": [], "name": "_totalsbt", "outputs": [ { "internaltype": "uint256", "name": "", "type": "uint256" } ], "statemutability": "view", "type": "function" }, { "inputs": [ { "internaltype": "address", "name": "_soul", "type": "address" } ], "name": "burn", "outputs": [], "statemutability": "nonpayable", "type": "function" }, { "inputs": [ { "internaltype": "address", "name": "_soul", "type": "address" } ], "name": "getsbtdata", "outputs": [ { "internaltype": "uint256[2]", "name": "", "type": "uint256[2]" }, { "internaltype": "uint256[2][2]", "name": "", "type": "uint256[2][2]" }, { "internaltype": "uint256[2]", "name": "", "type": "uint256[2]" }, { "internaltype": "uint256[3]", "name": "", "type": "uint256[3]" } ], "statemutability": "view", "type": "function" }, { "inputs": [ { "internaltype": "address", "name": "_soul", "type": "address" } ], "name": "hassoul", "outputs": [ { "internaltype": "bool", "name": "", "type": "bool" } ], "statemutability": "view", "type": "function" }, { "inputs": [ { "internaltype": "uint256[2]", "name": "a", "type": "uint256[2]" }, { "internaltype": "uint256[2][2]", "name": "b", "type": "uint256[2][2]" }, { "internaltype": "uint256[2]", "name": "c", "type": "uint256[2]" }, { "internaltype": "uint256[3]", "name": "input", "type": "uint256[3]" }, { "internaltype": "address", "name": "to", "type": "address" } ], "name": "mint", "outputs": [], "statemutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "name", "outputs": [ { "internaltype": "string", "name": "", "type": "string" } ], "statemutability": "view", "type": "function" }, { "inputs": [], "name": "owner", "outputs": [ { "internaltype": "address", "name": "", "type": "address" } ], "statemutability": "view", "type": "function" }, { "inputs": [], "name": "renounceownership", "outputs": [], "statemutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "symbol", "outputs": [ { "internaltype": "string", "name": "", "type": "string" } ], "statemutability": "view", "type": "function" }, { "inputs": [], "name": "totalsbt", "outputs": [ { "internaltype": "uint256", "name": "", "type": "uint256" } ], "statemutability": "view", "type": "function" }, { "inputs": [ { "internaltype": "address", "name": "newowner", "type": "address" } ], "name": "transferownership", "outputs": [], "statemutability": "nonpayable", "type": "function" }, { "inputs": [ { "internaltype": "address", "name": "_soul", "type": "address" }, { "components": [ { "internaltype": "uint256[2]", "name": "a", "type": "uint256[2]" }, { "internaltype": "uint256[2][2]", "name": "b", "type": "uint256[2][2]" }, { "internaltype": "uint256[2]", "name": "c", "type": "uint256[2]" }, { "internaltype": "uint256[3]", "name": "input", "type": "uint256[3]" } ], "internaltype": "struct zksbt. Proof", "name": "_souldata", "type": "tuple" } ], "name": "updatesbt", "outputs": [ { "internaltype": "bool", "name": "", "type": "bool" } ], "statemutability": "nonpayable", "type": "function" }, { "inputs": [ { "internaltype": "address", "name": "_soul", "type": "address" }, { "internaltype": "address", "name": "verifieraddress", "type": "address" } ], "name": "validateattribute", "outputs": [ { "internaltype": "bool", "name": "", "type": "bool" } ], "statemutability": "view", "type": "function" } ]
   
  1. Get proof of the wallet address you want to verifiy by calling the method .getSBTData() within the soulbound contract and store the output into proof and inputs variables:

 const soulbound = new web3.eth.Contract(soulboundAbi, soulboundContractAddress);
 const verifier = new web3.eth.Contract(verifierAbi, verifierContractAddress);
 const sbtData = await soulbound.methods.getSBTData(walletAddress).call();
 const proof = [sbtData[0], sbtData[1], sbtData[2]];
 const inputs = sbtData[3];
  1. Finally call .verifyTx() from the verifier contract with this proof data to get the verification of the ZK:

const isVerified = await verifier.methods.verifyTx(proof, inputs).call();

Last updated