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
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" } ]
Get proof of the wallet address you want to verifiy by calling the method
.getSBTData()
within the soulbound contract and store the output intoproof
andinputs
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];
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