Previously, we released a UTXO-based token protocol, for both fungible and non-fungible tokens. Token rules such as issuance and transfer are enforced at layer 1 by miners. However, additional rules, such as token authentication, need to be enforced at layer 2, making it undesirable for users who want to validate everything themselves (e.g., SPV). We devise novel approaches to solve this issue so that all rules are validated at layer 1. To our best knowledge, it is the only solution that provides a holistic layer-1 token.
There are two ways to fabricate a token, as shown in the diagram above. Each box represents a transaction, with input on the left and output on the right. An arrow points from one transaction to the transaction it spends. Boxes of the same output color contain the same contract code.
- Replay attack: an attacker can reissue the same token.
- Man-in-the-middle attack: an attacker can start from a UTXO unrelated to a token in the middle and create an identical chain of token transactions from that point on. The attacker can simply copy the output of a transaction at row 1 and paste it into the output of a transaction in row 3 verbatim (the second tx in the diagram), since locking script is only evaluated when unlocked, but not evaluated when deployed. From then on, the transaction can be spent on and on, creating a parallel fake token chain.
In all three cases, transactions are accepted by miners since they pass layer-1 validations. The last transaction in the red circle of each case looks identical to each other. The only way to decide if it is a legitimate token A transaction is tracing all the way back to the issuance transaction. This can be done in two ways:
- The receiver does all the validation itself. This quickly becomes unscalable as the token transfer chain grows long.
- The receiver trusts some third party to validate. This undermines the trustless advantage of layer-1 tokens in the first place.
We come up with a solution to prevent both attacks.
To fend off replay attack, we embed a globally unique token ID inside each token UTXO algorithmically. In the token contract, transaction id (txid) of the issuance transaction is copied when the issuance UTXO is consumed and retained in all ensuing token UTXOs as token ID. Any reissued token will have a different txid and thus token ID, and will be detected trivially.
To prevent against man-in-the-middle attack when a transaction is received, we validate not only the parent transaction, but also its parent as well. When the counterfeit token UTXO (UTXO1) is spent into the a token UTXO (UTXO2), it passes validation at layer 1 since the token contract is not run at all (note that the locking script of a UTXO is only run when it is unlocked) and the transaction is accepted. However, when attempting to spend UTXO2 into UTXO3, UTXO1 will also be validated, in addition to UTXO2. The validation will fail since UTXO1 does not contain the same contract as in UTXO2 and UTXO3, and the transaction will be rejected as a result. Thus, it suffices to trace only ONE more step back when validating a token transaction (in case we receive UTXO2), instead of tracing all the way as before. This simplifies token implementation enormously.
A reference token contract is shown in its entirety below with comments inline. It validates not only the previous transaction, but the previous previous transaction as well.
It is generally deemed that UTXO-based Layer-1 token mandates backtracking transaction history till issuance. We present a breakthrough that only requires backtracking two steps. It eliminates the requirement of trusted third party, paving the way to wider Layer-1 token adoption. The same technique is applicable in other smart contracts to eliminate excessive backtracking of transaction history.
See some follow-up at “Back to Genesis” Simplest Explanation.