Brainstorming Interaction Between Group, PMv3, and Introspection

We have the 3 proposals moving forward on the standards track:

  1. Group enables native tokens, conceptually close to ERC-1155 but enforced with the C++ “contract” language. Scope has been reduced and now it’s just one baton UTXO per token for supply management and metadata updating operations. Pretty much SLP features with architectural flaws fixed but because it’s native and attached to BCH UTXOs we get DEX/CoinJoin almost out of the box and tokens get access to all interfaces BCH can access, including future ones.
  2. PMv3 gives us covenant and other goodies but for this topic covenant is the most relevant. The covenant also lets us implement CashTokens, conceptually close to ERC-20.
  3. Introspection gives us, well, introspection opcodes so Script contracts can easily be fed info from the outside, it’s like letting contracts load some variables from the outside, and those variables can be used to control the contract. Contract writers can code slots for user-provided variables, and users could plug those in by spending an input at the required index and with required features. I’m not a Script contract writer so I get lost here, but it’s not hard to imagine that introspection could enable a whole lot of interesting contracts.

Now, how could they all interact?

Here’s how I think it could work together:

1+2 saves covenant writers from having to implement tokens, and enables Group tokens to be locked inside a covenant BUT we can’t use the token amounts/IDs as conditions for the contract because Script has no way of accessing those, not without 3. that is.
1+2+3 gives contract writers full power, they can lock both BCH and some Group token inside a covenant, and then use other inputs/outputs to control their spending, and the covenant contract can be aware of tokenID/amount of the output it’s attached to.

Notes:

  • The current introspection CHIP doesn’t include Group introspection opcodes, but I guess we can talk about adding those as all proposals move forward.
  • Full scope of Andrew Stone’s Group Tokenization also included a covenant solution, but it looks like there’s no community interest in going with that so PMv3 would take that role.
1 Like

I see them being discussed, but none of these are “moving forward to activation”.

Should I remind why this language is highly controversial?

2 Likes

Thanks, edited the wording

Can you TL;DR what is the difference between PMv3 covenants and Last Will or Mecenas (via Electron Cash) covenants?

The concept of a covenant is this: a way to enforce that the Script on the new output will be the same as that on the prevout, and that by induction we can know that the whole chain of such TX-es is unbroken all the way back to the creation transaction.

I had to read up a little about both of your examples and it looks like they’re limited in that the change (or full inheritance) always has to be sent back to the same address, and they’re probably a special type of covenant which can be hacked with available opcodes, because it’s enough to look at the parent output to make that covenant possible.

For a more complex covenant currently you can’t look at the grandparent output from the Script (and actually looking would imply scaling problems), so the next output would have to carry it in order to prove that the historical chain is unbroken and so on and it would quickly grow in size, and PMv3 fixes this by carrying the compressed proof of what happened in the past so you can chain together multiple TX-es and the tip of it can prove the history with a single hash, which gets updated after every TX to include the new parent, and so on. This way you can “look” at the grandparent without actually looking. The previous TX was the one that did the looking and embedded the proof (HashedWitness) of what it had seen.

Just for info, the dropped Group covenant feature did it another way, by having tokens be covenanted from their genesis (or BCH with the “fence” feature), so consensus would directly enforce the sameness of the Script across all tokens belonging to that group (same tokenID), but without introspection opcodes it would be fairly limited and I’m not sure how breaking out of the covenant would be handled from within Script. I wanted to study this feature more but after community feedback made it clear there’s only interest in the “base” Group scope I gave up on that. I think this breaking-out of the covenant would require multiple “authority” UTXOs so with the reduced scope we lost a prerequisite to have covenant the Group way. Locking BCH in a Group covenant would require the “fence” feature too, which also got dropped… so yeah, I kind of see now why people thought the original scope was complex.

1 Like

A lot of years ago, in the time of Symbian Nokia smart phones, I got an app on one that was a “radio”. When I started it, to my surprise, I got the ability to use an FM-tuner interface and listen to the local radio broadcasts.

At first I figured that the smart guys at Nokia must have included an actual FM tumer in their phone. Because, that is how its done, no?

Turns out, I just underestimated the power of a generic computing device in combination with a simple analog-to-digital converter that any audio-recording device, like a phone, will have anyway. (wikipedia)

I’m also seeing the same thing here where the group concept is a specialized solution for one type of tokens that require an extra component in the node. But when we look at the Script system there is ample opportunity to do tokens in a generic manner that don’t require the extra component. That don’t require the special-casing of one specific usecase.

This topic is opened to regard what makes sense in a world where these competing standars are developed, and that is awesome. That question is very important to answer.

My guess is that the goals of group can be answered by PMv3, and I emplore the group devs to consider this option and see if a joining of forces is the way forward.

1 Like

Bitcoin Cash is a specialized solution for one type of token and it worked quite well. All Group is really adding is the ability to create and manage the supply and metadata of these other tokens. They are reusing the base transfer function which works almost the same as it does for Bitcoin Cash. Same design paradigm.

But it does require it - the HashedWitness is the extra component. Re. “generic manner” - YAGNI. For exotic tokens/uses Group+PMv3HW would let you have those.

PMv3 is not a token solution by itself, it only enables a token solution to be coded with Script. Its main feature is covenant support through HashedWitness of which CashTokens are just one possible use. Because Script was not designed to build a whole token system, then even with the consensus change required (HashedWitness) the token solution is rather convoluted.

Why wasn’t Bitcoin originally implemented with the Script but the Bitcoin “covenant” is hard-coded by C++ instead? Because cash is the basic building block of a blockchain, everything blockchain does operates on some form of cash. Script operates on cash, it doesn’t create cash. Group is reusing the “transfer” interface of BCH whereas CashTokens have to re-implement it in Script and because of that it’s more limited.

Consider the atomic swap / DEX feature, this is what Jason said about it:

We get DEX pretty much out of the box with Group. Any BCH wallet dev. could build a basic DEX – required knowledge: BCH TX building principles, and basic accounting.

Why wasn’t BCH implemented with the Script but with the C++ “covenant”? Use the right tool for the job. Group does tokens, PMv3+Script does covenants.

A while ago you requested that Group demonstrates requirements on middlweare:

Solution: you poll a SPV server to give you the Genesis TX, any external metadata, and the SPV proof for that 1 genesis TX

Please add to the CHIP & spec all the new APIs, algorithms and indexers that are required to make this work.

It’s not been added yet but for anyone familiar with BCH UTXO model I believe it’s not hard to imagine what will be required, and with the baton (previously known as “authority outputs”) now locked to exactly one UTXO in existence for each distinct token, it only got simpler.

Why not ask the same kinds of question towards CashTokens? How does the user construct his transfer TX? How do we track token usage? How do we audit supply? How does the user know what he’s received? How do we build indexers? How do we track metadata? How much work is required to create all downstream software to have a smooth UX with CashTokens?

Just like a CPU with microcode is not an FM radio solution by itself, it “only” enables one with its code.

The question thus becomes: why spend money on an FM receiver if software can give you one already? Or, to drop the analogy, why add the Group special processing when plain script can do the same?

Make the question even more plain, to activate on Bitcoin Cash one of these two options:

  1. Group

  2. PMv3 + Introspection

Where nr 1 gives you one usecase, number 2 also gives that, but more. As I write just a few paragraphs above, why add Group when the PMv3 + Introspection can give you all that already?

I don’t think this got a real consideration and thus I’ll repeat it:

1 Like

one of these two

Why does it have to be one of the two, why not both? I want all 3.

Where nr 1 gives you one usecase, number 2 also gives that, but more.

It doesn’t give you that. It gives you more limited tokens, awkward to implement and use. I’d vote for 2. not for the tokens but for that “more”, and I’d vote for Group for the tokens.

Why did you ignore my points about APIs and middleware, judging from your past comments on Group I thought that was important to you?

joining of forces

For that we have to acknowledge the features and limitations of all 3 proposals. I did not open this thread to drop any one of them, but to see if they could be made to better fit together.

Maybe I missed something crucial, can you please explain what you mean with this?

“That” being the full-feature tokens, as in, having all features BCH has and being moved around and interacting with blockchain the same way BCH does. “Those” are best possible (value statement, you don’t have to agree but just to understand where I’m coming from) tokens, only thing better than that would be to drop the “dual” nature and have them really be equal to BCH but I’m not advocating for that because it would mess up incentives around BCH. So no, PMv3 doesn’t enable “that”. It enables some awkward tokens in which I’m not interested, and I don’t see other devs stading in line to build stuff based on CashTokens, whereas at least some people got excited about Group.

1 Like

ok, thanks for that. Good to see where you are coming from.

For clarity, a Script + Introspection solution actually has a better integration with the rest of the system since its part of the system. No glue needed, its included in the core fundamentals. Unlike group.

Maybe you have been looking at this in a very group-specific way and much like my software-defined-radio solution example above, its hard to grasp for most people. This is naturally a good improvement point.

2 Likes

That’s easy.

Because a dedicated, hardware FM receiver will use less power and provide greater efficiency (but less flexibility). It’s all about tradeoffs.

The same with Group tokens. They could be done using existing generic scripting subsystem, but such a solution, while more flexible, would be also much more complex, bloated and less efficient.

Since BCH blockchain aims to be efficient Cash system, Group seems like a logical solution, assuming it is done not in an overcomplicated way, of course.

1 Like

So Griffith proposed to add back Fencing and Subgroup features, and it got me thinking how would those interact here?

Recall that Andrew’s original proposal had them effectively be colored BCH, where only the mint/melt authorities could paint or clean the BCH to bring it in/out of the “fence” so tokenAmount field would be 0 for those.

Here’s something to ponder: consider interaction of this with Introspection and PMv3 CHIPs. We could have the authority UTXO be locked in some complex Script covenant contract, which would add/remove coloring depending on whatever author required to be put in the TX, but, we’d have the convenience advantage that so colored BCH would remain “free” citizens like BCH when it comes to being moved around because they’d be P2PKH and not P2SH UTXOs, so easier on the wallets and everything.

Is now a bad time to point out that the original OP_GROUP had a full covenant solution for tokens or fenced BCH already?
The proposed OP_GROUP scheme for covenants requires no new opcodes. The covenant script is set by the authority baton of the group and that makes all output scripts in the group match the covenant template. This is closer to an ETH contract than anything else currently proposed.

Never a bad time, but it got dropped because there was opposition to bundling tokens together with other features such as covenant, subgroups and fencing. My goal with the CHIP is to get at least “base” tokens in (tokens, and a single authority UTXO to manage supply and metadata).

Just the “base” can be extended using existing Script, given more power by Introspection (May 2022), and by PMv3 (May 2023) which is what I wanted to demonstrate here, so it’s worth having that “base” even if we never decide to go for other features Andrew had originally proposed.

As for upgrades, it will be easier to reason about those from the position of already having base tokens in and more people getting a grasp on how they work and interact with other blockchain features. Maybe we’ll realize that Script covenants are enough, or we’ll realize that we need something more like Group covenant, who knows?

If the community can agree to add more, great, if not, also great - we will at least have proper tokens and SLP can fade out. The less stuff there is in the proposal, the easier it is to defend against criticism, smaller “attack” surface.

My hope was for “base” to make it into May 2022 window, and having to argue about those extra features would have been a distraction, and it was and it took me some time to realize. It’s unfortunate that “base” won’t make it into May 2022, because then we could have a year to debate such upgrades.

Some more things about interaction which I only recently realized:

  • Group introduces its own “witness” with the tokenID, and it can be used to make fixed-size induction proofs by reconstructing the tokenID preimage, same how PMv3 induction proof reconstructs the TXID. I created an example Script of how this would work, which can found here. This approach isn’t possible with just the Group CHIP, it requires the Introspection CHIP expanded with Group annotation introspection opcodes.
  • PMv3 “witness” approach breaks stuff because it changes TXID computation. If we decide to bite the bullet and break TXID, then a space-time tradeoff is possible where we wouldn’t need to record the individual hashes of each input’s unlocking bytecode, it is enough to change the TXID preimage computation. Alternative to breaking TXID is to have the preimage data live as separate data structure but still be part of block merkle tree, approach described here.

So, there is some overlap between Group and PMv3. We could have both, or we could give up PMv3’s “detached proof” part and keep all other goodies, or we could give up Group but then we’d lose P2PKH tokens, or we could have Group but with the scheme that tokenID == genesisTXID which means some tradeoffs would be made. I think this “witness” facility is the main topic if we want to nicely integrate both Group and PMv3.

Note that the two “witness” approaches are not the exactly the same but they can both prove unforgeability of persistent contracts through a fixed-size inductive proof. The main distinction is that the tokenID preimage doesn’t contain input unlocking bytecode, so proving that some input was spent in a specific way is not possible by reconstructing the tokenID, but it is still possible by reconstructing the TXID and such proof won’t grow linearly because we don’t use the TXID facility for the inductive proof.

Another thing to ponder is the TX format. Group uses the PFX_GROUP approach in order not to require a new TX format, but if we will be going with both PMv3 and Group, then we might as well have fields for the Group annotation. Using the referencing “trick” found in PMv3’s “detached signature” scheme we could have the inputs be part of tokenID preimage, too! “Detached proof” then becomes tokenID and can be optionally attached to utxo’s in which case Group consensus is activated. This is something to be worked out.

Had a little brainstorming session with imaginary_username, here are the notes:

Summary of Spec Talk Held on 2022-02-01

Debaters: imaginary_username and bitcoincashautist
Spectators: freetrader, griffith, emergent_reasons
Main Topics:
    - Unforgeable Groups CHIP scope
    - Evaluation of carried commitment (Group) and detached proof (PMv3) features
    - Detached proofs roll-out

Unforgeable Groups CHIP Scope

Discussed version: v4.3-905cac9e

It was demonstrated that “satoshi tokens” and “NFT” group types (also referred to as “super-contracts”) can be implemented using the “native tokens” group with a Script covenant set at group genesis.
To avoid premature optimization trap, the CHIP owner expressed agreement with removing the two while leaving the option to reintroduce them at a later upgrade should a need be demonstrated.
The dropped group types wouldn’t have enabled new features but would only optimize features enabled by the “native tokens” group type.

Evaluation of Carried Commitments (Group) and Detached Proofs (PMv3) Features

Both carried commitments (introduced in Unforgeable Groups CHIP) and detached proofs (introduced in PMv3 CHIP) can solve the problem of proving ancestry with a fixed-size proof, without requiring nodes to access non-local transaction data.
Either feature would enable a class of contracts currently not possible on Bitcoin Cash blockchain.
Group CHIP is non-breaking as it is, and it was assumed that the “detached proofs” would be rolled out in a non-breaking way, which is not how it’s currently proposed in PMv3 CHIP.
With solutions relying on either feature, the required data to complete the proof is brought into local context by the spender and proofs are then made by local Script validation.
Effect of either approach to nodes was confirmed to be irrelevant because the cost to blockchain is the same in terms of “big O”.

The discussion was focused around end-users and application developers.

imaginary_username presented a succinct summary:

Carried commitment

  • fixed for a given token set; clever way around taking anything out of txid, by making the proof immutable.

  • compact (because it doesn’t need to be blown up when not used in a given tx) and “surgical” (because when not blown up the tx can completely ignore the commitment, no need to do any maneuvering to propagate it)… as long as you expect almost all of your usecases to meet the following:

    • the covenant is applied to the token group only. Minimal permissionless joins/exits - those will require batons - they are essentially minting/destruction events.
    • you do not intend to mutate the genesis covenant very much. mutation will require that you either somehow adapt your script outside the commitment to your new requirements, or do some complex “lock this token to get a new superset token” kind of maneuver.
    • you do not intend to propagate entities that span many existing tokens permissionlessly. you’ll probably need to pull some lock-and-superset maneuver as the previous point.

Detached/inductive proof

  • token or coin agnostic; literally a way to take proof out of txid (by committing the hash).
  • needs to be propagated for every tx involving an entity as long as it exists, script also needs to account for all scenarios it may be involved in (you can’t “turn it off” by just ignoring it), so less compact.
  • can be stacked with a given token much better, as it’s an entirely independent facility from tokens. tokens enter and exit inductive covenant facilities just as easily as bch.
  • born to be mutated, as long as the propagation script allows for it.

Note: “tokens” here refer to Group’s “native tokens” and their interaction with PMv3’s “detached proof” feature. Group tokens would be free P2PKH outputs so could be locked into P2SH same way as free BCH.

At first it seemed there’s feature overlap, and bitcoincashautist argued that Group’s carried commitment could functionally replace PMv3’s detached proofs feature by emulating it through successive group genesis operations.
Through some high-level examples it was demonstrated that it probably could, but it would burden application developers with additional complexity.

Quoting imaginary_username, the high-level example discussed was:

for example, i have my kitty-tokens. it’s created without frills, the groupId simply refers to a bog-standard genesis tx, p2pkh, all that. I want some of those kitty-tokens to enter an inductive contract (say, a kittyDAO, a kittyDAO2…) after the fact. how do i do that? or can my holders not do it without my baton approval?

Through discussion, a key difference revealed itself, quoting bitcoincashautist:

Both must compare some 2 contract steps, but group way compares N and N+1, while detached proof compares N and N-1. That is the key distinction, because only N and N+1 are easily accessible through introspection, N-1 requires embedding the parent and proving it through the prevout’s TXID or some other input’s prevout groupID if you made a disposable commitment in N-1

imaginary_username:

well it’s two different philosophies: it’s extremely easy for things to enter a covenant in the detached proof setup, and rightly so - “if it carries the right stuff and has the right spending condition, who cares where it came from?” is the question. we can restrict that one step further, but yes it is more complex to do that versus the groupID case. in exchange, well, the groupID case is more difficult to enter permissionlessly. which is the more important thing to people - entering a facility permissionlessly, or entering in a restricted way?

Later it was noted that the group way could also simply require payment to a P2SH address to enter the covenant, and the covenant itself could then require a group genesis.
This doesn’t remove complexity but allows it to be moved away from the end user.

It was agreed that both have merits, and an evaluation by a wider audience on picking either or both is worth conducting.
This is because:

  • Superiority of the method depends on the problem being solved, so having both would make the blockchain overall more efficient, assuming the most efficient method would be used when adequate.
    Having both would give more tools to application developers enabling them to reduce complexity of their solutions, and, through more compact transactions, reduce TX fees and UX complexity for their users.
  • Synergy is possible, the carried commitment can commit to a bunch of prevout TXIDs to preserve them or carry them forward, even if all outputs from those TXID are later spent.
    Later, it is possible to unpack the groupID to reveal TXIDs and use any of them to construct required proofs.
  • In order to make P2PKH tokens possible, we require a Genesis operation and the “carry” aspect of groupID anyway.
  • Having the groupID commit to the whole genesis TX instead of just the minimal source of entropy (one genesis transaction’s prevout and genesis output index) gives more “bang for the buck” and the “buck” (cost) is less than a single signature verification per genesis output, while benefits can be perpetually enjoyed by application developers and their users.

With all these said, having both increases complexity and can be a maintenance and robustness burden that node implementations are unwilling to bear, so we are looking for wider input on how to balance these aspects.

Detached Proofs Roll-out

The conversation moved on to discuss how exactly to roll out detached proofs without breaking the TX format which is seen as a no-go.

It was agreed that the least-invasive way is to change the TXID function so that it compresses input unlocking script field into a hash of itself.
The hash would never be recorded anywhere, it would be computed on-the-fly by upgraded software.
Inputs MUST opt-in to be compressed either through some opcode or a bool PFX on the inputs, otherwise existing Script contracts that rely on reconstructing TXID would break.
Problem would be that non-upgraded software obtaining a “raw” TX wouldn’t compute the correct TXID anymore and would find the TX invalid.

Solution would be to upgrade node APIs so that the rawtransaction call returns the TX with compressed inputs, while a new API endpoint would be used by upgraded software, quoting imaginary_username:

something like that, or op_hashedproof w/e
and then when applications ask for rawtransaction, give them the tx with hash but not the detached proof, so legacy apps won’t freak out
and newer apps who do want the detached proof can get it via a new command like rawtransactionproof

Appendix - Impact on Discussed CHIPs

  • Detached Proofs can be extracted to a standalone CHIP from PMv3 CHIP, or PMv3 CHIP itself can be updated accordingly.
    This would enable inputs to opt-in for having themselves compressed on-the-fly and would enable the “N-1” proving method in a non-breaking way.
  • Unforgeable Groups (CHIP) will enable native P2PKH tokens and the “N+1” proving method.
    The “NFT” and “satoshi tokens” group types will be dropped.