See how to generate a user state: 4. Epoch key proof.
Then use the user state to generate user state transition proofs.
const {
startTransitionProof,
processAttestationProofs,
finalTransitionProof,
} = await userState.genUserStateTransitionProofs()
const tx = await contract.startUserStateTransition(
startTransitionProof.publicSignals,
startTransitionProof.proof
)
Get the proof index of startTransitionProof
const proofIndexes: ethers.BigNumber[] = []
await tx.wait() // should wait until the transaction is confirmed
const proofHash = startTransitionProof.hash()
const proofIndex = await contract.getProofIndex(proofHash)
proofIndexes.push(proofIndex)
Submit all process attestations proofs and get the proof indexes.
for (let i = 0; i < processAttestationProofs.length; i++) {
const tx = await contract.processAttestations(
processAttestationProofs[i].publicSignals,
processAttestationProofs[i].proof
)
await tx.wait() // wait until the transaction is confirmed
const proofHash = processAttestationProofs[i].hash()
const proofIndex = await contract.getProofIndex(proofHash)
proofIndexes.push(proofIndex)
}
const tx = await contract.updateUserStateRoot(
finalTransitionProof.publicSignals,
finalTransitionProof.proof,
proofIndexes
)
It can be checked with either a Synchronizer
object or a UserState
object. See: 4. Epoch Key Proof.
Check if global state tree root exists in the current UniRep state
const fromEpoch = Number(finalTransitionProof.transitionFromEpoch)
const GSTRoot = finalTransitionProof.fromGlobalStateTree.toString()
const isGSTRootExisted = await userState.GSTRootExists(
GSTRoot,
fromEpoch
)
console.log(isGSTRootExisted) // false then the proof will be invalid
Check if epoch tree root matches the epoch
const fromEpoch = Number(finalTransitionProof.transitionFromEpoch)
const epochTreeRoot = finalTransitionProof.fromEpochTree.toString()
const isEpochTreeExisted = await userState.epochTreeRootExists(
epochTreeRoot,
fromEpoch
)
console.log(isEpochTreeExisted) // false then the proof will be invalid
Check epoch key nullifiers are not existed
const epkNullifiers = finalTransitionProof.epkNullifiers.map((i) => i.toString())
for (const nullifier of epkNullifiers) {
if (await userState.nullifierExist(nullifier)) {
return false // then the proof will be invalid
}
}