# How to verify UBT root
**Goal**: Generate zk verified UBT root to use from PIR data source verification or light client verification.
Assume we have the followings
- zkEVM proof $evm\_proof_t$ which proves state transition for $block_t$. $mpt\_root_{t-1}$ to $mpt\_root_t$.
- UBT enabled node (modified Geth) which can generate witness for the state transition at block t: $ubt\_wit_{t-1}$
- UBT enabled light client (modified keeper) which can compute state transition for block t given: $block_t$, $ubt\_wit_{t-1}$, $ubt\_root_{t-1}$, returning new root $ubt\_root_t$
- Proof for the previous cycle for block t-1 $\pi_{t-1}$
And wants to produces proof $\pi_t$ which proves the new UBT root $ubt\_root_t$ is authentic.
## Proof construction
Input: $evm\_proof_t$, $block_t$, $mpt\_root_{t-1}$, $mpt\_root_t$, $ubt\_wit_{t-1}$, $ubt\_root_{t-1}$, $\pi_{t-1}$
Output: $ubt\_root_t$, $\pi_t$
Outside zkVM
- check $mpt\_root_{t-1}$ against blockchain
- check $mpt\_root_t$ against blockchain
Inside zkVM
- Verify $mpt\_root_{t-1}$ -> $mpt\_root_t$ transition with $evm\_proof_t$ and $block_t$.
- Verify $ubt\_root_{t-1}$ is the result of previous cycle using $\pi_{t-1}$
- Verify $ubt\_wit_{t-1}$'s inclusion against $ubt\_root_{t-1}$
- Verify $ubt\_root_{t-1}$ -> $ubt\_root_t$ with $ubt\_wit_{t-1}$, and $block_t$
**public input** (what does client has to input when verifying?)
$mpt\_root_{t-1}$, $mpt\_root_t$, $ubt\_root_{t-1}$
### TODOs
- Somehow get zkEVM proof, prev_MPT_root, next_MPT_root, block
- âś…Recursive verification using Ziren's verify proof syscall
- **UBT Node** to generate UBT_witness for block n
- **UBT keeper** to compute state transition using prev_UBT_root, UBT_witness, block(txns)
- Put together everything in zkVM guest program
---
Links
- [UBT](https://eips.ethereum.org/EIPS/eip-7864)
- [Keeper](https://github.com/ethereum/go-ethereum/tree/master/cmd/keeper)
*Sketch*