We want first class tokens on BCH! Part 4/N High level technical details

11 133
Avatar for bitcoincashautist
3 years ago
Topics: Bitcoin Cash, BCH

Hey all! We now have a high level doc outlining the requirements for enabling group token semantics. It's one and half A4 page, should be easy to read and enough to enable us to assess impact on scaling etc, ie start the talk at high level, and as everyone's understanding catches up can work our way down to design choices and implementation details, in a way we will together reinvent group tokens.

Meanwhile, Andrew is working on a full spec which you can find here. He already had some comments on the doc below, but the essence is good already. I need to read up more to implement those comments for this doc and it can be part of this reinvention process.

Btw, what does it mean 1st class? It means that they're enforced by node C++ (or any other programming language) code as opposed to being enforced by script (like Ethereum) or by users (like SLP). 1st class means that the logic is enforced by the same power that enforces BCH logic. There is no script that can allow creating BCH from nothing. Similarly, there is no script that can allow cheating group token rules.

Native Group Tokens High Level Requirements Overview

Script Requirements

OP_GROUP enables storage of data in a place preceding normal script. That's all that Script has to check. That data is given meaning in the consensus checking part. This data could be stored in a new transaction field all the same.

Grouped transaction output scripts MUST follow the following format (<> brackets indicate data pushes):

<Group ID> <quantity> OP_GROUP [normal script constraints],

Consensus Requirements

When verifying an individual transaction, perform the below in addition to normal processing.

For every input seen:

  • If they have the OP_GROUP opcode then:

    • Check whether fields are of valid size. Fail the transaction if not.

    • If it's a group token then add group balances to running sums.

    • If it's a group authority then OR group authorities to running flags.

  • Else do nothing.

For every output seen:

  • If they have the OP_GROUP opcode then:

    • Check whether fields are of valid size. Fail the transaction if not.

    • If it's a group token then add group balances to running sums.

    • If it's a group authority then OR group authorities to running flags.

  • Else do nothing.

Finally, check the validity of the transaction as a whole:

  • If an authority appears from nothing AND group genesis requirement is NOT met then fail the transaction.

  • Else check whether authority "balances" out i.e. only lower or equal authority can be found in the outputs flag. Fail the transaction if not met.

  • Check token balance taking into consideration authority found in the input and fail the transaction if criteria not met.

  • No authority: input group token balance == output group token balance

  • Mint authority: input group token balance <= output group token balance

  • Melt authority: input group token balance >= output group token balance

That's it. Whatever Native Group Token semantic details will designed, they will be implemented in one of these 3 places above. This high-level description should be sufficient to evaluate impact on scaling.

User Requirements

Users can decide whether to support the Native Group Token semantics or not. If it will not be supported, then NGT UTXOs will be unspendable by the user.

Non-supporting wallets should at least check for the presence of OP_GROUP and deal with them in a way that makes sense otherwise regular transactions created by the wallet could fail by accidentally including an OP_GROUP UTXO as input.

Assuming majority of wallets already match the UTXO script against know pantterns, this shouldn’t be an issue, as those will just ignore those UTXOs.

It is recommended that non-supporting wallets at least show them as non-spendable BCH balance because showing 0 would hide the fact that there's still something in there.

User Manual

Should the user choose to support NGTs then he should support, as a minimum:

  • Preservation of authority UTXOs i.e. if you use one as input, you must create one as change output.

  • Tracking wallet NGT balances which is as simple as summing UTXOs that belong to the wallet

  • Building ordinary NGT transactions, which are transactions containing OP_GROUP and respecting the consensus rules shown above

  • Melting NGT UTXOs

While advanced features won't be supported this way, at least the end user will be protected from accidentally giving up authority or unknowingly passing it on to other parties. If he doesn't want the tokens, end user can burn the tokens and claim the locked BCH.

Copyright

This document is placed in the public domain. Attribution neither required nor desired.

Credits

Andrew Stone

15
$ 5.81
$ 3.81 from @TheRandomRewarder
$ 2.00 from @tula_s
Avatar for bitcoincashautist
3 years ago
Topics: Bitcoin Cash, BCH

Comments

Thank you for this. This actually an additional learning for me.

$ 0.00
3 years ago

Very insightful and very educative

$ 0.00
3 years ago

Thanks!

$ 0.00
3 years ago

Preservation of authority UTXOs i.e. if you use one as input, you must create one as change output.

Tracking wallet NGT balances which is as simple as summing UTXOs that belong to the wallet

Building ordinary NGT transactions, which are transactions containing OP_GROUP and respecting the consensus rules shown above

$ 0.00
3 years ago

what is the rationale behind having a special melt authority? it seems wrong because:

  1. anyone should be able to melt their dead tokens
  2. you cannot prevent people from destroying tokens by sending them to 1bitcoineater anyway
  3. prevents paying miner fees the same simple way as with native bch tokens, thus forcing miners to run postage servers

is the reason to prevent accidental burning as was happening with slp? isnt there a better way to do that?

$ 0.00
3 years ago
  1. I generally agree, but. There are some interesting use-cases when you need to explicitly declare melt authority, and after asking Andrew, he confirmed functionality was the rationale and not error prevention.
  2. True. But burn is not the same as melt. You could send a grouped token to 1bitcoineater regardless of whatever authority but then you lose both the token and the BCH attached to it, and they will stay forever as zombies in the UTXO. Melting is different from such burn - it burns only the token (without the token taking UTXO space) and frees the BCH.
  3. It doesn't. Any token UTXO can contain more BCH than the dust minimum. So the bch becomes a postage stamp, and the token UTXO loses a bit of BCH with every TX. You can always recharge postage stamps, or not but then you have to include an additional BCH input to pay the fee.

BCH is free to move in/out from the token UTXO, but it can't go below dust minimum. So even if some token was dead, if you had like 1000 UTXOs of it and weren't allowed to melt, you could combine them all into 1 token UTXO and 1 pure BCH UTXO, and recover the 999x dust minimum BCH into that pure BCH UTXO.

Unless the "fencing" functionality is enabled by the group genesis which disallows BCH from crossing the group boundary. But then there are also no tokens. Then the BCH is the token but not fungible with normal BCH anymore because it will be colored, forever. This behavior is determined at group creation and can't be changed later. This effectively burns BCH to create group-colored BCH, and this needs a pure BCH postage stamp in the inputs to be moved around, since BCH can't be extracted from the group.

to prevent accidental burning

This is kind of prevented already. Wallets who don't support OP_GROUP won't even see the tokens and won't be able to spend the token utxo they own. I thought it could happen because I misunderstood how wallets detect what they own.

$ 0.00
3 years ago

i dont get what the use case is supposed to be. Any link please?

Embedding stamps into tokens is an interesting idea, However it is not an alternative to simply paying fees to the miner directly in the token. I definitely wouldnt call this design 1st class. Also it seems like a potential user experience nightmare.

$ 0.00
3 years ago

Here's a functional description, there's lots of use cases: https://docs.google.com/document/d/1X-yrqBJNj6oGPku49krZqTMGNNEWnUJBRFjX7fJXvTs/edit

simply paying fees to the miner directly in the token

I don't think this is prevented by the group spec. It's prevented by existing rules, the 1 sat min. fee network rule: https://reference.cash/protocol/network/messages/feefilter.

A 0 BCH fee transaction is a valid transaction from consensus point of view. It's just that it can never reach the miner because nodes decided they don't want to pass around txes which are not likely to be mined.

Re. "1st class" I started with the title without thinking too much about what it meant because I got the idea from here: https://twitter.com/BitcoinUnlimit/status/1360297716757245956

Later I realized it's all about where the logical rules are enforced, not about our opinion of them. 1st class means C++ code in the node, so that no smart contract can ever touch the rules, but it can touch the token. 2nd class means script/smart contract token definition, so that script controls the logic of sum_in=sum_out. 3rd class would mean user enforcement, so that blockcahin only provides timestamping and storage while all the logic is implemented externally.

Also it seems like a potential user experience nightmare.

That is in the hands of wallet devs, what's under the hood doesn't matter for user experience. How is this simple: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol yet for ERC20 end users it is simple.

With group tokens, instead of all that code, all you have to do to create a token is create a BCH UTXO with easily crafted data in the OP_GROUP. Then create another TX using that one as input and creating the entire initial supply in 1 token utxo. Then, just use it. Done. With this you don't have melt/mint capability and the initial supply is fixed.

$ 0.00
3 years ago

It's just that it can never reach the miner

that is a soft limit. This is a hard limit "input group token balance == output group token balance". It should be >=, instead of ==.

i went through the spec, thanks, but i still dont get what the melt permission is supposed to achieve. Backing of tokens does not need it - what if i want my tokens to be backed by other token, not bch ? i need to make a contract for that anyway.

btw this again shows that the design of 2 balances per utxo stinks badly. Why not unlimited balances per utxo then? I want each of my USDM tokens to be backed by 0.4 USDT + 0.4 USDH + 0.001 BCH.

$ 0.00
3 years ago

Forgot to reply to this one sry. With melt, stablecoin supply could be more transparent because a melt op would indicate a redeem transaction assuming only the stablecoin issuer would keep the melt perms. Melt also plays well with the "fence" group setting which instead of making tokens makes colored BCH (token amount=0) which will be locked inside the fence and melt will allow you to exit the fence, with that setting, BCH can't freely move in&out of group outputs, it must have authority. This way some organization could freely move BCH between departments but only trusted employees could take it out and pay to someone external. Andrew mentioned some other uses in smart contracts but I haven't looked into that yet.

As for the other point, unlimited is not necessary. It's not exactly for the purpose of "backing" - the token doesn't get its value from the dust amount of BCH it carries, for example the stablecoin gets its value from the peg i.e. the promise it can be redeemed 1-to-1 for fiat. We require BCH "lockup" not because it will be "backed" by BCH but to keep the incentives in check without creating a more complex problem. This way, tokens are forced to "pay" for their existence in the UTXO elite real-estate, because of that little dust there will always be incentive to consolidate UTXO even if the token value goes to 0. Like this, any token op creates marginal demand for BCH through lockup and fees, and BCH value growth is correlated to PoW security we'll be getting from miners so it's quite important that we have a "main" coin IMO. If you want a coin really backed by some other tokens, I think we need some kind of contract that can spit out 0.4 USDT + 0.4 USDH + 0.001 BCH for every 1 USDM received. The 1 USDM would carry only dust BCH, and the contract could spit out 2 outputs with total matching those 3 balances. Through the atomic swap mechanism, group tokens alone allow for this trade to be done trustlessly but not entirely automatic as in powered by a smart contract because AFAIK the Script can't look around ie the data available to it is limited to the subject UTXO. The USDM issuer could publish half-transactions where anyone could fill in the missing USDT,USDH,BCH to make it valid and claim the USDM or the same in the opposite direction. Or they could run a server where users request partial TX-es.

$ 0.10
3 years ago

agreed

$ 0.00
3 years ago