When I withdraw 10 clams, my client software generates a random ID: lkjsdfoiu
It then chooses a random blinding factor, which it keeps secret.
It then blinds the random ID using the blinding factor along with the server's 10-clam public minting key, producing (say): 897345jh
This random, and now blinded, ID is then sent to the OT server along with my withdrawal request.
Once the server verifies that it has successfully withdrawn 10 clams from my account, it uses its 10-clam private minting key to sign the blinded ID: 897345jh SIGNED: Server.
The server returns this to me. My client unblinds it using its secret blinding factor along with the server's 10-clam public minting key: lkjsdfoiu SIGNED: Server.
When you ask, "Ah-ha-ha, but how can the server's signature still verify, when the ID has changed from 897345jh back to lkjsdfoiu again?" (since it was unblinded) ==> The answer is, that is the whole point of blind signatures. They still work, even after they are unblinded. That is the whole magic of digital cash. (I encourage you to Google "homomorphic encryption" to learn more about the applications for this concept.)
At this point:
1. My client now has a random ID with a valid server signature on it.
2. The server has no idea what that ID is, since the ID was blinded when it was signed.
3. Therefore I and I alone am the only person who knows that ID.
4. When I give the token to Bob who redeems it at the server, the server can see that the token is good (since it has a valid signature.) The server also knows that it's worth 10 clams, since only the 10-clam public key can verify that signature. But the server has no idea where it came from.
Once the server redeems the token for Bob, it records the token's ID (lkjsdfoiu) in a spent token database. This way, if the token is ever redeemed twice, the server can see that it is no good, because it has already been used.
OT expires and rotates cash tokens and mints, in order to allow the server operator to erase its spent token database every few months. Otherwise, the server operator would be forced to store a growing database forever, which is not feasible for a server operator.