CHIP 2021-02 Unforgeable Groups for Bitcoin Cash

I’m trying to understand this issue of multiple OP_GROUP instances. Is this picture correct?

opgroup

The blockchain would not even see those other instances until someone would post a redeem script, in which case there’s nothing special about OP_GROUP, it could be processed as if it was 2x OP_DROP or just ignored because it’d be cheaper, right? People can use the wide pallete of script to write whatever gibberish they want in the redeem script, so why go out of our way to give one opcode a special treatment there?

This code would recognize only 1 “prefix”, it wouldn’t allow multiple OP_GROUP to appear in the pubkey/output script as those would return TX_NONSTANDARD, right? So other OP_GROUPs could appear only in the signature/redeem script – and they can’t make much problems there, they even allow compressing a 2x pop operation.

If my understanding is correct, then Group Tokenization could be made to work by allowing this in the pubkey/output script: OP_PUSHDATA2 0x20 <arbitrary 32 bytes> OP_PUSHDATA2 0x08 <arbitrary 8 bytes> OP_DROP OP_DROP OP_HASH160 OP_DATA_X <redeem Script hash> OP_EQUAL and then the consensus code would set rules on that data and fail the tx if it doesn’t fit into group semantics. This would avoid a new opcode but it would be uglier.

PS isn’t VarInt sort of “double wrapping” the data? First you tell the push opcode how many bytes to expect, and then inside those bytes you again use a byte to tell the user how many bytes to expect. If we stored group data info directly into TX format, then varint would make sense. But since the push OP already provides a data size feature, why again introduce the size one more time into the data being pushed?

PPS

What do you mean by this, something new designed for what purpuose? Tokens can be sent to any existing address, we wouldn’t need a new format. We will need a standard (user/wallet layer) to present tokenIDs in human-readable format, link them to a ticker. There is word on that in the doc, Appendix C, but it is outside the scope of this CHIP. Maybe it’s for another CHIP to recommend a standard way to track token metadata across wallets.

To avoid the long discussions from becoming too long, I’ll open issues on the CHIP repo with the change requests.

Here is the first.

1 Like

Your question:

This question is very confusing because Andrew wrote this:

If nobody addresses a group-id, then why would Andrew write this? There is a consusion somewhere. Maybe you can spot the origins.

1 Like

Good idea, we can keep everything more tidy that way and anyone interested on the status of certain issues can visit the relevant threads. I’ll make a list here of all that were mentioned in the discussion above, thanks for creating those issues!

Rewriting technical part - done and closed. Todo: write about advanced features (subgroups, hold BCH, covenant) Done.

Include specification in the CHIP body - done and closed

Treatment of multiple OP_GROUP opcodes - discussion ongoing

Using VarInt for data values - discussion ongoing

Encoding of the quantity | flags variable - discussion ongoing

Limit the size of subgroup - discussion ongoing

1 Like

Yeah, let me know when the issues are fixed. :+1:

1 Like

Ok so here is some feedback. It would be REALLY NICE if it were possible to read the group data from a scriptOutput without having to really know anything about bitcoin script.

I’m thinking in particular making it as easy as possible for middleware that needs to process tx’s and extract out the group_id and quantity info from a UTXO. This means it would be nice if the special GROUP txo’s had a prefix byte, and the real script data that the interpreter in bitcoin interprets comes later. This way it’s as if we are “Extending” the scriptoutput field in bitcoin tx format and packing new data fields specific to group there.

Right now we have:

<groupid> <quantityorflags> OP_GROUP OP_DUP OP_HASH160 <pubkeyhash> OP_EQUALVERIFY OP_CHECKSIG

Would be nice if the BINARY data inside the scriptoutput field looked like this:

GROUP_PFX_BYTE <groupid> <quantityorflags> <EncapsulatedScriptData>

<EncapsulatedScriptData> then expands to the real script data you send to the script interpreter, which is just normal scriptOutput for that utxo:

OP_DUP OP_HASH160 <pubkeyhash> OP_EQUALVERIFY OP_CHECKSIG

  • When bitcoind sees GROUP_PFX_BYTE it knows that the real script data comes later in this txo – it reads the next fields of data as group information, then kicks off the interpreter on the <EncapsulatedScriptData>

  • When middleware that normally doesn’t really interpret scripts sees GROUP_PFX_BYTE it knows that the next 2 data fields are what it cares about: group_id and quantity. Everything later is script data blob that it can ignore.

This way GROUP lives on its own layer “outside” the bitcoin script data – and has nothing to do with bitcoin script. It makes it a little bit clearer to code that processes tx’s on the binary format level what to throw away, what to pay attention to, etc.

In short – it irks me a little bit that code like Fulcrum that processes tx’s now has to worry about interpreting bitcoin script in order to extract out group_id info. Would have been easier had it been living outside bitcoin script, and had its own prefix byte to denote that fact, and so it’s just on its own layer of data encapsulation.

Not a huge deal – just a suggestion.

1 Like

I think that’s possible with the current scheme. Group consensus code looks at a particular OP_GROUP at a particular place in the script, and expects particularly formed pieces of data. If there’s no such pattern then it’s not a group output and is just an ordinary BCH output with whatever script, and that script may or may not include instances of OP_GROUP but they’re supposed to be benign as they don’t really do anything when processed by the Script machine itself.

Would you need to code in new features into code to recognize and deal with this prefix? My understanding is that OP_GROUP was intended as a kind of soft prefix which can also valid part of your EncapsulatedScriptData so you don’t need to touch Script and TX serialization other than implementing a simple opcode which does pretty much nothing when used in the “wrong” place.

Only when placed in the right place it becomes a “magical” opcode and activates the group consensus code so the special meaning to OP_GROUP is given by the self-contained group consensus code if and only if any output matches the “prefix” pattern i.e. it’s the first set of instructions in the script. If it doesn’t match the prefix pattern, it’s simply ignored by group code and processed by existing BCH code similarly to OP_DROP. As far as Script is concerned OP_GROUP just pops 2 elements instead of 1 and does nothing.

I hope I’m making sense, if I got something wrong @andrewstone can correct me. Anyway, I think we need to update the spec so this behavior is more obvious.

You wouldn’t need to touch tx serialization or anything in what I am suggesting. To code that doesn’t know any better, it just looks like a script it doesn’t understand.

This is the same situation you have now with what’s being proposed.

Only when placed in the right place it becomes a “magical” opcode and activates the group consensus code so the special meaning to OP_GROUP

Yes and I’m suggesting that magical place be as the first byte. And that there should be no mixing between script data and the token stuff. It just seems cleaner.

Putting the token data inside script is just kinda gnarly…

1 Like

Extracted summary:

A lot of work and research has gone into the technical specification of this CHIP. However, in its current form, GP does not think it is simple / minimal enough to be considered for acceptance into the network. Furthermore, important sections about costs, risks and alternatives are incomplete or have wrongfully been asserted as non-existent. GP would like to see a minimum viable change isolated from the current large scope, and then a deeper evaluation of costs, risks and alternatives.

3 Likes

A lot of work and research has gone into the technical specification of this CHIP.

Thank you for recognizing it. However, I don’t subscribe to the labor theory of value so that labor will have been meaningless if doesn’t achieve the desired outcome and impact which is to grow the ecosystem and BCH value, and with it my net worth as well :slight_smile: I’m not interested in participation trophies, I’m interested in 10x gains on BCH. While other proposals also increase the likelihood of a 10x, I felt that this one was neglected and has lots of potential so that’s where I’m putting my energy, it all adds up. The best way to predict the future is to make it happen.

However, in its current form, GP does not think it is simple / minimal enough to be considered for acceptance into the network.

Is there a broadly accepted simpleness / minimalism criteria for consensus layer changes? How do we quantify this requirement? Lines of code? Number of script ops required to perform token operations? If it’s a matter of opinion, then I simply disagree and will wait for other stakeholders to weigh in.

Furthermore, important sections about costs, risks and alternatives are incomplete or have wrongfully been asserted as non-existent.

Addressed below.

GP would like to see a minimum viable change isolated from the current large scope

Minimum viable change would be only the BATON, MINT, and MELT authorities. Even with only those, a lot can be done (tokens, atomic swaps, token CoinJoin/CashFusion), as demonstrated in the examples section.

However, covenants are really useful and would benefit from other Script opcodes as soon as they’re activated e.g. covenants would benefit from the introspection CHIP because it enables an entry into the covenant. Reducing the scope would mean we push that feature far away into the future. Why would we want to do that? The feature is cheap, enabled by a simple optional constraint on top of the above mentioned “base”.

How do we quantify “large”? If it’s a matter of opinion, then I simply disagree and will wait for other stakeholders to weigh in.

It is unclear what the author means with “The market demands smart cash but, with Ethereum, it got smart contracts disguised as cash”. What are the practical differences between smart cash and smart contracts disguised as cash?

Accepted, I’ll reword.

A strong statement such as “the market demands X” needs some actual backing.

How’s this: All Tokens | CoinMarketCap,

paired with the price appreciation of the “main” coins on whose blockchain those tokens exist.

If that is not sufficient, what kind of evidence would be satisfactory?

The noun/verb analogy is confusing and creates more questions than it answers.

Accepted, I’ll reword.

The only listed cost is “possible implementation errors”. At the very least this change will add complexity to potential future upgrades since future updates will need to account for both BCH and tokens.

This is vague so hard to address, let’s try and work it out.

Is BCH balance checking adding complexity to potential future upgrades? Token logic is in the same class as that. It just works, regardless of upgrades in other parts of the code.

Even if we only get what’s currently proposed in the CHIP and never ever upgrade it why would some future unrelated upgrades need to account for it?

Here are some changes that would NOT be affected by having group tokens:

  • Network rules, unless we choose to give special treatment to group UTXOs with regards to fee or dust limit requirements
  • Blocksize changes, unless we choose to have a separate cap for token TXes
  • Pruning
  • New opcodes
  • New SIGHASH
  • New signature types
  • UTXO commitments

and some that might be:

  • Changing numerical precision for BCH & tokens, and I suspect that BCH precision could be changed independently of tokens
  • Totally new state scheme e.g. utreexo
  • ?

There are likely other costs that are not mentioned / researched.

Another vague statement. What kind of costs are you expecting to find in some code performing simple arithmetic operations and a few IF statements? What kind of research are we looking for here?

It’s not clear which features are part of the current proposal.

All of the features in the CHIP. What’s described in technical description is also formalized in the specification. There’s a dedicated section for future upgrades, which is not part of the current proposal but for information only.

If all features are included, this is much more than a minimal viable proposal, and should be separated.

I did not see a convincing argument why we need to limit ourselves to a minimal viable proposal.

The authority system seems very complex.

Complex by what criteria? It’s no more complex than adding up balances, the only difference is that instead of summing up token amounts we’re summing the quantity field using a logical OR i.e. sum |= qty and then placing a few logical rules on that sum. I’m surprised by experienced developers classifying this as “complex”. On the outside, both token amount and token authority UTXOs are the same, and everything that works with BCH outputs work the same with both token amounts and authorities.

So these alternatives (e.g. CashTokens, SLP, SmartBCH) should still be evaluated.

Accepted, will add.

An evaluation of alternative versions of GROUP tokens could also be added.

Do you mean some historical proposals, or different scopes of the current one? The current authority system really made this “click” with me as an elegant solution. I didn’t look deeply into historical proposals but I understand that those had problems because they used a different way to perform management ops so I was not interested in that. What value would there be to entertain obsolete proposals? I actually got an opposing comment when I tried to explore an alternate design approach in the CHIP.

The evaluation of alternative rollout approaches is a good addition.

Thanks!

it does have serious implications on the core functioning of the network. So security considerations need to be further specified.

It’s vague, what kind of considerations are you looking for here? The network continues to function the same, but we could end up having lots of BCH dust UTXOs which would carry tokens, and with them economic value. We can even have lots of dust UTXOs now, but there’s no utility in having them other than to spam the network. It would cost only 5460 BCH (about $3m) to spam the network with 1b UTXOs. I understand that there are entities who’d like to see BCH fail, so why haven’t they attacked BCH in such a way? Maybe because they know it would be a futile attack because:

  • We can scale to more than 1T UTXOs and for 1T it becomes infeasible due to attack requiring about a quarter of BCH supply.
  • Miners can respond and quickly adjust the dust limit should there be evidence of such an attack
  • Withstanding such an attack would actually benefit holders because the attacker would have to purchase the BCH, and withstanding the attack would be good PR for BCH

If it will not be an attack but the aggregate market demand for tokens which ends up locking 5m BCH into 1T token UTXOs then I will be celebrating that on my yacht which I will have bought for 1 BCH.

Besides the workload increase for node developers, the only listed cost is that “BCH will get more adoption”.

What if it really is the only one? How hard do I have to try find others before giving up? We cannot invent problems to satisfy the expectation that there have to be problems. I don’t like complexity, that’s why this proposal appealed to me in the first place, because it so simple, cheap, and easy to reason about. Lots of potential impact at a low cost – yes please!

If you can think of any other costs then I’ll be happy to either dispute them or add them to the list if I fail to dispute them. Maybe this one should be turned to (-) for some stakeholders: “This functionality will enable competition from within our ecosystem.”

Please notice that I, as a stakeholder, have found several problems too which go unsolved.

There must be a big confusion about the general process. I wrote more on it here: A process towards acceptance of Bitcoin Cash Improvement Proposals.

Tl;Dr: It is the responsibility of the proposal owner to convince the ecosystem.

2 Likes

Those are non-blocking and clearly defined and I believe we can successfully resolve those. Even though I may not always fully agree with you, I value your feedback and admire your positions on many other topics.

I’m hoping to convince more and more people, but there will always be some where it may be in their interest not to be convinced. Ecosystem is big and wide, and I hope it will become bigger and wider, and not one single entity represents it. If I fail to convince, giving up is also an option.

Meanwhile, something unexpected happened which blew my mind – a stakeholder of the “whale” class, Marc De Mesel, has signaled his support by giving this same response a $1k upvote.

As a developer and co-founder of Mint SLP https://mintslp.com/

I believe miner validated tokens is a smart step in the right direction! The Group Token proposal seems like a big improvement over SLP.

Thank you @andrewstone and others involved for working on and pushing this feature into BCH.

I hope the community can come together to support the Group Token proposal or something similar! You have my support for what it is worth!

2 Likes

Re. “Going back to the fact that the owner of Group is advertising it as “SLP2.0”, that means that we would lose a lot of features.”

I did not create nor change the name of that Telegram group to SLP2.0 so that’s not being fair. It was Paul Wasensteiner who made the initiative to rename it to SLP2.0 and nobody in that group (including you) seemed to mind at the time.

I then asked James Cramer about it to clarify and got the impression there was agreement forming around it so I just went along with it in casual talk.

The Group CHIP nowhere refers to it as SLP2.0, and it won’t ever because while GROUP enables a functionality, SLP can choose to use it or not use it, and some other token ecosystem could freely form around Group, but it is my impression that SLP folks want to use GROUP. Instead of speculation, it would be good to ask them?

Also, middleware development is permissionless, and once building blocks are available on the base layer, anyone will be free to use them as they see fit and build whatever they want with them. Group is an enabler, not a full-stack solution.

Oh, I misssed this copy of that reply (thats 4!).

As I wrote elsewhere, I’m not sure why you feel attacked as none of the points apply to you. I’m sorry you felt I was talking about you, I was not.

I was asked to provide some specific costs and risks so here is one.

As I understand it, any un-upgraded wallet that receives a GROUP utxo will be completely unaware of its special status, and would treat it as any other utxo on that address. Therefore when the wallet tries to spend it, the transaction will fail and the wallet will have no idea about how to deal with it.

It effectively means that all economic wallets must be upgraded in order to stay reliable. If not, BCH network will appear to the rest of the world to be unreliable and unsafe. Given that, the CHIP needs to address and commit to achieving that ecosystem-wide wallet upgrade.

Is anything above inaccurate?

3 Likes

It is my understanding that most wallets (maybe even all) simply filter UTXOs according to known patterns against the pubkey script TX field i.e. they’re whitelisting spendable patterns. A grouped pattern would not match, and would so not be included in the wallet’s local db of UTXOs belonging to the wallet. An unupgraded wallet would therefore NOT attempt to spend it because it wouldn’t even consider grouped UTXOs in building a transaction. I think it would be good to ask wallet devs for inputs here, but after talking with @cculianu I’m fairly confident of this.

1 Like

That sounds very optimistic. I don’t think it’s the case since until SLP there was no reason for wallets to do this besides p2pkh and p2sh. Or at best p2pkh, p2sh, p2sh-multisig. Electron is the most capable power-wallet that exists for BCH. It’s capabilities should not be considered representative.

2 Likes

Then I guess we should consider building a list of wallets and see how they deal with non-p2pkh and non-p2sh outputs. If consensus would allow it, what would happen if a miner would mine a 0xEE <gibberish> output? What if that <gibberish> contained a P2PKH template? Maybe some wallet implementation processing it from the back would think it’s just a P2PKH output and ignore the prefix? But then, couldn’t a miner even now prefix it with some currently-valid opcodes to make it unspendable and confuse such wallets?

To add some fresh context, in response to all the comments I’m reworking the CHIP to reduce the scope down to TRANSFER, GENESIS, MINT, MELT, and BATON features. The working branch is here. Merged. There I have already reduced the scope in both tech. description and the spec, those parts are like 90% done and I intend to add a flowchart if it will added a flowchart to clear some concepts and help with security analysis later. Also, Calin’s proposal is now implemented and it would help us close the following issues: layer mixing, number format for qty can now be VarInt (aka CompactSize), simplify parsing for non-VM aware code (could be relevant for HW), and the issue of multiple OP_GROUPs in script

2 Likes