# U1.1
## Reputation
Reputation now consists of only `posRep` and `negRep`. `graffiti` and `signUp` are removed.
The removal of `graffiti` is a result of removing the hashchains from the epoch tree. We can't determine the order in which attestations were received between epoch keys, and thus which `graffiti` is the latest one.
Most uses of `graffiti` can be built outside of the Unirep protocol. e.g. a user claims a username using an epoch key. When the user wants to use the username they prove ownership of the old epoch key.
## Attesters
Each attester is a semaphore group. A user does not sign up globally with Unirep, they sign up with each attester.
Attesters have their own epochs, and each epoch has a `stateTree` and an `epochTree`.
Attesters may set their own `epochLength`.
## State tree
The state tree is an incremental merkle tree with leaves `H(idNullifier, attesterId, epoch, posRep, negRep)`, where `idNullifier` is a user secret. These entries are used to prove the amount of starting rep in the current epoch.
## Epoch tree
The epoch tree is a sparse merkle tree. Each leaf index is an epoch key and each leaf is the balance received in the current epoch, stored as `H(posRep, negRep)`. An attestation updates the summed value in the leaf.
e.g. if my epoch key is `10294` and I have `posRep: 10` and `negRep: 1` my leaf is `H(10, 1)`. If I receive an attestation with `negRep: 2` my new leaf is `H(10, 3)`.
Only the root of this tree is stored onchain. This tree is replaced every epoch.
## Epoch key
Epoch keys are calculated as `H(idNullifier, attesterId, epoch, nonce)`. Epoch keys are unique between attesters during the same epoch.
e.g. A member of attester A and attester B will have different epoch keys for attester A epoch 1 and attester B epoch 1.
## Attestations
When an attestation is made a ZK proof must be included that outputs the new epoch tree root and leaf. This attestation should sum the previous balance of the leaf and the new attestation.
## User state transition
User state transitions happen per-attester. Because epoch tree leaves are no longer hashchains the logic is much more simple. Each epoch key needs a merkle inclusion proof, then the balance is added to a final sum. The new state tree leaf is calculated using this sum.
The time complexity of a state transition in UnirepV1 is `O(N)`, in UnirepV2 it is **`O(1)`**.
## Spending rep
In UnirepV1 we can only spend reputation using nullifiers. This means if I want to spend 1000 rep I have to generate 1000 nullifiers in ZK and put each onchain.
UnirepV1 also has lag when rep is given. If I receive 10 rep in epoch 1 I cannot prove I have this rep until epoch 2.
UnirepV2 solves both of these problems by making the user state transition smaller. In a single ZK proof we can prove the start balance (the state tree leaf) and the balance of each epoch key (which contains the latest attestations).
Let's examine the flow of two spend operations. Assume a user Alice has a start balance of `posRep: 50, negRep: 0` and has not spent anything in this epoch.
- Alice spends 10 rep from epoch key `444`
- The attester takes this proof and creates an attestation of `negRep: 10` to epoch key `444`
- Alice wants to spend another 10 rep
- Alice proves the start balance from state tree of `posRep: 50, negRep: 0`
- Alice proves her epoch key balances, all are 0, except for epoch key `444` which has `negRep: 10`
- Alice sums all values and proves she has `posRep: 50, negRep: 10`
A spend operation performs a state transition to calculate the latest balance. The structural change to the epoch tree makes this operation light enough to be possible.