@Griffith I worked out an example of how you could create backed tokens even without the “fence” feature. It is possible as a consequence of locking the authority (aka baton) to exactly 1 UTXO in the “base” proposal. Maybe an easy SmartBCH bridge could be created this way, too! Including hash of the first prevout output in the tokenID preimage could allow a token authority to prove it was created by another token’s authority.
Token Group Script Covenant
The below example requires CHIP-2021-02: Native Introspection Opcodes.
It also assumes that introspection opcodes for reading Group annotation will be added:
all with variations for accessing different TX local outputs.
tokenID is generated by hashing a preimage consisting of parts of that token’s genesis transaction:
- Hash of first input’s prevout output;
- First input’s prevout TXID;
- First input’s prevout output index;
- Output index of the genesis output being generated.
- The genesis output being generated with tokenID left out;
Recall that consensus also enforces that:
- The genesis output must be of token authority type;
- When an authority output is spent, it can create any number of ordinary token outputs but only one authority output.
Because of consensus rules placed on token genesis and token authorities, it takes little to prove that a
pubKeyScript placed on a token authority is the same as the one set at genesis and that it couldn’t have been tampered with.
pubKeyScript only has to prove that it’s been tied to the token authority output since genesis, and such proof will be of fixed size.
OP_OUTPUTBYTECODE OP_INPUTINDEX OP_UTXOBYTECODE OP_EQUAL // I must be carried forward…
OP_OUTPUTTOKENQTY OP_NOT OP_AND // … to a token authority output…
OP_OUTPUTTOKENID OP_TOKENID OP_EQUAL OP_AND// … with the same tokenID as me.
OP_INPUTINDEX OP_UTXOBYTECODE OP_CAT OP_HASH256 // Also, my pubKeyScript…
OP_TOKENID OP_EQUAL OP_AND // … must be the same as set on my token’s genesis.
OP_SWAP<...>OP_AND // Any other conditions.
genDataHeader part of the signature is the
tokenID preimage with genesis
pubKeyScript left out, and the
outputIndex refers to the “change” output of the token authority being spent.
The size of the above covenant boilerplate code is given below:
6 Signature push opcodes (3+1+1+1)
25 Redeem script boilerplate code
63 Covenant proof part of signature, assuming NULL metadata.
Because token authorities can be created with or without capability to mint tokens, such covenanted output could be used as:
- As NFT with a BCH balance entirely controlled by the covenant;
- As a token authority with variable BCH balance.
When used as a NFT the covenant could serve as BCH vault, requiring arbitrary proofs to add or remove BCH.
When used with token minting and melting capability, the covenant could require BCH to be paid in/out of the covenant which would make tokens backed by BCH possible where such tokens would remain free P2PKH citizens.
Covenanted Ordinary Token Outputs
If the covenant is placed at token’s genesis then it is possible to envelop ordinary token outputs in the covenant by extending the code above to require indexes of a number of ordinary token outputs.
The covenant could then verify that it’s being passed on to them and tally up the balances in order to verify that outputs haven’t been omitted.
This would allow fanning out of covenanted outputs.
The above would work only with finite mint tokens.
For infinite mint the covenant would have to enforce that the total number of outputs in a transaction matches the number of provided indexes.
Supporting covenanted outputs merging would be achieved the same way, by requiring indexes of a number of inputs to be included in the balance calculation.
For example, this could be used to implement “colored” BCH where the covenant could enforce
tokenQty == satoshiAmount.
It could also allow any owner to burn the color and reclaim the BCH by coding the covenant so that it allows being spent to a token
OP_RETURN under some conditions.