CHIP 2021-01 Sighash_constrafirstin

SIGHASH_CONSTRA(IN)FIRSTIN(PUT) - A new sighash flag for efficient covenant spends

Burak Keceli - 01.30.2021 [DRAFT]


Currently interacting with covenants are inefficient and not scalable. In order to interact with a covenant (or calling a function) people must spend from the same covenant state, and this spend is limited to only one interaction per state. Multiple people trying to simultaneously spend from the same state results in unconfirmed transaction chain forks. SIGHASH_CONSTRAFIRSTIN aims to address this issue by allowing multiple participants to interact with the same covenant simultaneously.

How It Works:

SIGHASH_CONSTRAFIRSTIN signs the very first input in addition to input it is part of. It essentially agrees to participate in a transaction, as long as first input is constrained to an expected outpoint.


SIGHASH_CONSTRAFIRSTIN is not a sighash flag standalone, however it can work with three sighash constructions that exist today.


This construction signs the first input, the input that contains it, and the corresponding output. This says “I definitely want to move this much BCH to this output, but I don’t care about other outputs and any other input except first input in this transaction”.


This construction signs the first input, the one input it is part of, and all outputs. It’s essentially saying “I agree to participate in this transaction, as long as the following recipients receive these amounts. I don’t care about any additional inputs except the first input.”


This construction signs the one input it is in, and the first input. This is essentially saying “Any transaction including this input can spend this BCH as long as first input is expected outpoint”.


This proposal is licensed under a Creative Commons Attribution 4.0 International License


“This allows unordered inputs in order to allow non-serial / concurrent construction of a transaction.”

Is that a fair summary?

Hey @burak, thanks for working on this problem!

I’m definitely interested in solutions which allow for BCH covenants to avoid contention from multiple users trying to interact with “public” covenants at the same time.

I’m not sure if I understand the precise use case where this new signing serialization algorithm would be helpful, though – can you describe an example covenant where this would make a chain of transactions more efficient?

If the primary goal is just making it easier for multiple users to non-interactively join a covenant transaction, I’m struggling to imagine a scenario in which users could agree on the proper covenant output without also being able to work together to construct the rest of the transaction.

For the two classes of covenants I’m most interested in – CashTokens and two-way-bridged networks like BCH prediction markets – users update the covenant state one transaction at a time, and I think parallel updates would always require coordination (which must also be supported by the covenant design).

@emergent_reasons @bitjson A covenant can internally enforce a lock time interval for when it can be spent earliest (i.e in every 5 seconds). Within this duration people can independently construct their transactions whose first input spends from covenant state and other inputs are evaluated within the covenant context. These half-transactions can be relayed on a second layer and orchestrated by relaying nodes. Relayer nodes come up with a consensus on how to assemble transactions in a way that always result a common coinjoin throughput with CTOR input/output ordering. This 2l consensus is obviously not something set in stone, however whichever relayers result the longest and most profitable CPFP is preferred and mined by miners (this may require adjustments in first-seen first safe policy here). A BCH pre-consensus upgrade could also definitely help avoiding these unconfirmed chain forks. All can be done, however SIGHASH_CONSTRAFIRSTIN is the start.

As a next step for this: could you provide the code for an example covenant which demonstrates how the new algorithm is used? That would be very helpful in a more concrete analysis.



This may help to coordinate messages, but blocks are only finalized around every ~10 minutes, and unconfirmed transaction chains can easily be ignored by miners. Wouldn’t this coordination be equally effective on the second layer you’re describing? (And the lock time checking would just waste bytes in each covenant transaction?)

If this proposal is only useful with another relay and construction layer among nodes, said layer (and its interactions) needs to be fully described so people know the full benefit/cost of this proposal.

1 Like

There was some related discussion on Telegram, just wanted to mention here too:

The v0 CashTokens demo is actually a set of two interlocking covenants – the top-level, “corporation covenant” mints/redeems tokens (to demo how decentralized applications can do so). The bottom-level “token” covenant is held separately, and represents each actual “token UTXO”. Users can all move their tokens independently, without “checking in” to the corporation covenant, because the token covenant’s inductive proof prevents them from counterfeiting new tokens. So this parent-child covenant strategy is actually a great way to parallelize many thousands of simultaneous state updates to a covenant (and preventing contention in the top-level covenant).

This was actually my initial goal when I started working on the idea – I wanted some way for tokens to be issued such that they can be traded independently on secondary markets or DEXs, without requiring everyone in the world to fight over who gets to make the next top-level covenant transaction. And you can “branch” many times, so it’s even possible to have lower level covenants which further parallelize a system. (I expect this will be very important for large, liquid, synthetic asset markets.)

@burak if you or someone else is interested in driving this CHIP, would you consider creating a repository for it and adding more detail, for example as in this example template?

Hi all, as some of you outlined this proposal requires some level of coordination outside the mainnet. I’m now back to whiteboard trying to come up with solutions to the pain point of coordination and alternatives to proposed design. I’ll take this one step further when I eventually end up having an overall better design.