Showerthought: Decred Voting Non-Fungible Data

Published 2025-01-14

By matheusd & vctt

Overview

We propose introducing a limited form of arbitrary data ownership in the Decred chain. This is intended to (eventually) support issuance and transfer of NFTs, anchoring and update of sidechains and smart contracts and any other applications that could leverage public data secured by blockchain consensus rules.

This idea involves:

  • Adding a new (optional) opcode to vote transactions, which allows stake voters to mint new NFD (non-fungible data) chains.
  • Adding a new stake transaction type to allow transfering ownership of this data.

It is designed to cause the minimum amount of on-chain impact, in particular with respect to transaction and block size and UTXO set expansion.

This post is an initial sketch of this idea, intended to drive comments and discussion of this issue.

Goal

Non-fungible tokens (NFTs) and several sidechain proposals such as RGB require anchoring some arbitrary data in the blockchain. This arbitrary data could be actual content (e.g. some structured binary data, a string, a URL, pixel data and so on), a hash to some content or a cryptographic digital signature.

Allowing a way to do this in a simple and blockchain-performant manner is a challenge. One such example has been the ordinals/inscriptions system, that has caused mempool fee spikes and on-chain data saturation in Bitcoin.

This proposal attempts to address these issues with an implementation within the Decred cryptocurrency. It aims to minimize expenditure of several key resources by carefully desiging a data ownership subsystem, to be implemented adjacent to the current staking features.

It would require one (or more) consensus changes, thus it would require going through the standard procedure for implementing, voting on and deplying these changes.

This post tentatively calls this proposal NFDTC - Non-Fungible Data Transaction Chains.

General Design

The design proposed here has two main points:

  1. Modify vote transactions to allowing starting new NFD chains (“minting”).
  2. Introduce a new stake transaction type to allow updating the chain.

Together, these two actions allow creating and maintaing ownership of non-fungible data chains (“NFD” chains) in Decred’s blockchain. In other words, A NFD chain is a set of sequential transactions that continuously transfer ownership of some arbitrary data, as referenced by unique identifiers within the blockchain.

While the main text of this proposal outlines our current design choices, there are a few alternatives for most decisions. We point them out in referenced apendices.

Layout of minting and update transactions

Identifying Chains

Each NFD chain is to be identified by a unique sequential serial number, called its “ordinal number”.

The ordinal number of a chain is determined at its minting time: assuming N chains have been minted already, after a new block is mined, the first newly minted NFD chain will have an ordinal number N+1, the second one will be N+2 and so on.

Assuming this proposal is accepted, developed and deployed, the very first minted NFD chain would receive ordinal number 1.

Updating Rule

After completely processing a block, each NFD chain will be assigned one set of rules for updating it. This can be informally compared to the rules necessary to spend an UTXO, thus by analogy we’ll call it the unspent NFD output (UNFDO).

An UNFDO can be referenced in different ways, depending on context:

  • Transaction hash (that defined that particular UNFDO).
  • Block hash and ordinal number (identifying the active UNFDO as of a given sidechain).
  • Block number and ordinal number (identfying the active UNFDO as of a given height on the main chain).
  • Ordinal number (identifying the active UNFDO as of the current main chain tip).

When referring to “active UNFDO”, or “UNFDO of chain X” we’ll mean the UNFDO of some NFD chain as of the main chain tip.

For every chain, the first transaction (which creates or “mints” the chain) defines the first UNFDO. Subsequent transactions must satistfy the prior UNFDO and define the next one.

By “satisfy”, we mean the update transaction must present data plus a redeem script that is correctly evaluated as a standard Decred txscript (as if it were a standrd input signature script for a P2SH output).

By “define the next one” we mean the update transaction must present the hash of the next redeem script necessary to continue updating the chain.

Updating Through Stake Transactions

Minting and updating NFDTCs is done through the use of stake transactions.

We propose using stake transactions because they already represent transactions with custom processing within the Decred chain, in addition to the standard transaction processing validation that is performed: for example, each stake transaction type has explicit max limits for inclusion in a block, tickets can only be created with already-confirmed outputs, coinbase maturity apply to vote and treasury spend outputs, and so on.

One alternative to using stake transactions would be to create special output types (identified by opcodes) and allow them to be used in regular transactions (see appendix 4 for a quick discussion).

Another alternative is defining a new transaction tree specifically for NFD-related transactions. See appendix 5 for requirements.

Finally, a third alternative is creating an entire new block field to hold NFD operations. This could result in the best use of blockchain space, but would be significantly more work and less backwards compatible. Appendix 6 has ideas for how such thing could be accomplished.

Minting New Chains

A new NFD chain is started on vote transactions (SSGen/StakeGen transactions). The stakevoter (either a VSP or a solo voter) may include a new optional output in their vote transactions.

Following the same convention as other stake outputs, this output would be tagged with a new OP_SSMINTNFDC tag opcode.

This opcode would be followed by a 160 bit hash (a HASH160 value), to be used as the covenant to advance the NFD chain through the use of NFD update transactions (i.e. the first UNFDO).

We propose using vote transactions for minting new chains for the following reasons:

  • Incentivizes use of Decred’s stake feature.
  • Naturally limits the max number of new chains per block (5, same as the number of votes).
  • Limits the on-chain space impact of new NFD chains (only 32 additional bytes per vote).
  • Adds a new possible revenue stream for VSPs.

Regarding the last point, note that in the case of VSP voting tickets, it is the VSP that creates the vote transaction, thus it is the one with permission to create the OP_SSMINTNFDC output. It could either create this output based on the original ticket owner’s request or it could sell the rights to mint a new NFD chain.

Eventually (if this feature sees enough adoption), a distributed market for minting new chains could be established to allow VSPs (and solo voters) to sell their minting rights to third parties.

One alternative to using vote transactions would be to create a new transaction type to mint new chains (see apendix 1).

Another design point that could be addressed is the limit on the number of minted chains, by changing the max number of allowed OP_SSMINTNFDC outputs.

Updating Chains

In order to store arbitrary data and/or change ownership of the NFD chain, a new type of stake transaction is required: we tentatively refer to this as a SSNFDUpdate transaction.

This transaction would have the following layout:

  • N standard inputs.
  • 1 output tagged with OP_SSNFDCORD opcode.
  • 1 output tagged with OP_SSNFDCSIG opcode.
  • 1 output tagged with OP_SSNFDCOUT opcode.
  • 0 or more standard outputs

The inputs would have to refer to UTXOs (either regular or stake) and would be subject to the standard validation rules for inputs.

The OP_SSNFDCORD output binds this transaction to a specific ordinal NFD chain (OP_SSNDFDCOR [varint encoded ordinal numer]). In other words, it uniquely identifies the chain updated by this transaction.

The OP_SSNFDCSIG contains the script that satisfies the prior OP_SSMINTNFDC or OP_SSNFDCOUT in the chain (i.e. satisfies the currently active UNFDO).

The OP_SSNFDCOUT is the script hash that the next update transaction must fulfill to be valid (OP_SSNFDCCOV [20-byte script hash]). This will become the new UNFDO (assuming everything else about the transaction and block it is mined in is valid).

The standard outputs would similarly be used to (optionally) return change to whomever is performing this transaction. Any coins not returned on a change output would be used as standard transaction fee. They can also be used to lock in data, through the standard use of OP_RETURN scripts.

We expect one commonly used layout would be one input and one change output, used by the (current) owner of the NFD chain to either update or transfer ownership, with the transaction fee used to prioritize it in the mempool.

Requiring valid UTXOs also grants double-spend protection for this new transaction type.

Several additional consensus rules would have to be enforced, not just to ensure this transaction layout and scripts, but also to impose limits. Some proposed rules:

  • Limit the max number of SSNFDUpdate transactions in a block to N (for example, 10).
  • Prevent multiple updates of the same NFD chain (i.e. same ordinal #) in a block.
  • Impose maturity restrictions to spending to the standard outputs.
  • Impose maturity restrictions to updating the same chain.
  • Impose limits to the number of standard inputs and outputs acceptable.
  • Impose limits to OP_RETURN data (possibly different than the ones currently used for regular transactions).

An alternative layout design is to combine all of these outputs in a single larger output script; see appendix 4 for discussion.

NFDTC Update Replaceability

The prior suggested layout for the update transaction has a unique feature: it allows creating multiple parallel transactions that all satisfy the active UNFDO by using different UTXOs.

Any one of those transactions could eventually be mined, as long as their referenced inputs remain unspent, and it would be up to miner preference to choose which one is mined.

This allows interesting constructions that depend on transaction replaceability to be built on top of this NFTDCs: for example, eltoo[1] requires a SIGHASH_NOINPUT signature hash change to build “floating transactions”: transactions that can bind to any other prior transaction. This floating transaction concept would follow naturally in NFDTCs updated using the previously proposed layout, due to having no explicit binding between sequential NFD transactions.

The downside of this approach is the risk of double-spending a specific NFD: given any of multiple (possible) transactions could be mined, users would have to be very mindful of unconfirmed (or not-deeply-confirmed) updates, to avoid the risk of dobule-spent.

Repleceability could be broken by including a locktime check to P2SH-based UFNDOs or by adding an additional required input (or output with tagged opcode) to reference the prior NFD update transction. This could be a required feature, an optional feature or a covenant-triggered conditional check, but further discussion is needed to determine the best strategy.

SPV Support

Another consensus rule change that would be helpful is adding the ordinal number to the DCP0005 version 2 committed block filters.

This would allow SPV clients to detect blocks that (likely) involve changes to a particular NFDTC, and then request such blocks for further work.

An alternative to including the ordinal number in the existing committed filter would be to create an entire new header commitment to keep track of and prove inclusion of NFDTCs in blocks (see appendix 2).

Observations

The interpretation of an NFD chain identified by its ordinal number can be surmised as “the active UNFDO currently owns the chain”. For example, for UNFDOs defined with standard P2PKH scripts, the owner of the corresponding private key “owns” the NFD and can thus advance its status. It could choose to send ownership of the chain to someone else by generating an update transaction that binds the NFD chain to a new P2PKH address.

Active NFD chains may have very small impact on blockchain space (contingent on proper design of their database): they’ll require only enough storage space for the ordinal number as an index and the current spending rules - other data may be pruned after an appropriate number of confirmations. Additional data (such as block hashes or heights involved in an NFD chain) may be indexed by full node software directly or that may be left as a job for auxillary software.

An NFD chain is not (necessarily) bound to any particular UTXO: any UTXO could be used to evolve the chain. Thus, another interpretation is that the NFD feature creates a new “dimension” within Decred’s blockchain, decoupled from the value-based space that currently exists.

There is precedent for creating such new dimensions within Decred: the decentralized treasury decoupled the treasury’s balance from standard UTXO existence.

As a corollary to the above observations, one can “own” an NFD chain and not own any Decred: an user may have ownership of a particular chain by virtue of having access of the private key of the currently active UNFDO, but not maintain any amount of coins in a wallet. It could obtain coins only as it needed to update the chain’s state, or it could request some other entity perform this update for them (possibly with an out-of-band payment for such an action).

This would allow third parties to use the Decred chain to anchor data and track ownership relations without requiring direct exposure to Decred price fluctuations. In this interpretation, coins could be interpreted as the “gas” (in the ethereum sense) required to advance the NFD on-chain.

Application Ideas

These are some very rough ideas for applications that may take advantage of this feature.

NFTs

These are easily implemented by NFD chains: the first update transaction commits to some hash, metadata or arbitrary data. The ordinal number is the token identifier and ownership of the token is determined by the ability to satisfy the current UNFDO.

This NFT system would be very generic, and as mentioned earlier, wouldn’t even require users to actually hold Decred to maintain ownership of their NFT, making this suitable for use even for real-world entities that would not (or could not) hold Decred.

Anchored Alternative Chains

Assuming an NFD chain corresponds to access rights to anchor an altcoin within the Decred chain, and that the altcoin contains consensus rules which require embedding a valid NFD spending transaction, then that can be used to provide transaction finality or additional protection to such alternative blockchain.

In order to provide penalty avenues in case of misbehavior in the alternative chain, it may be necessary to introduce further constraints or opcodes in the UNFDO (to be investigated).

Basis for Accounting System

Another (more exotic) idea would be to use the NFD feature as basis for an account/treasuries subsystem. Each NFD chain would be interpreted as an “account”, and it could pool and disburse coins as its UNFDO is fulfilled.

This would require coming up with further ties between the NFD and standard UTXO dimenions, in particular with regards to creating and destroying UTXOs as they enter/leave the NFD chain and the replaceability of NFD updating transactions.

Basis for Internal Altcoins

Extending the previous idea, instead of tracking atoms directly, each NFD chain could track a simple amount field, decoupled from standard atom amounts. This could allow building altcoins directly in Decred’s chain.

Basis for Smart contracts

Finally, if we allowed NFD chains to store arbitrary mutable state validated by consensus rules, then this could serve as a basis for a smart contract feature, with external execution and validation of the smart contracts and on-chain anchoring, state and ownership tracking.

Conclusion

This is our (pre) proposal for an efficient NFT-like implementation in Decred. If this garners enough interest from the community, buy-in from other existing development teams and is deemed as a reasonable idea for further development, then we’ll work on a full proposal for discussion in Politeia.

Apendices

Appendix 1 - New Minting Stake Transaction

As as alternative to minting through the use of vote transactions, a new type of stake transaction (tentatively called SSMintNFDChain) could be used. This would be a stake transaction with standard inputs (spending UTXOs) and the first UNFDO of the chain.

There would have to be a limited number of these per block, established as a consensus rule, and miners could prioritize them based on their fee (as with standard transactions).

We suggest minting through vote transactions to reduce blockchain footprint (any additional transaction has some overhead) and to incentivize use of the staking feature, but this is also a reasonable alternative.

Appendix 2 - New Header Commitment for NFTDCs

Instead of (or in addition to) modifying the existing committed block filter to include the ordinal number of updated NFDTCs in the block, a new header commitment with NFDTC metadata can be created.

This would allow creating an NFD client that requires fetching very little on-chain data (potentially, not even needing to fetch the entire block history of an NFD chain).

Some data that could be committed to on a per-block basis (subject to further discussion within the community):

  • Total number of minted NFD chains.
  • UNFDO set (latest UNFDO for every chain).
  • Last NFD chain state (for example, last committed to OP_RETURN in an NFD chain).
  • Set of NFD chains minted on block.

For best results, this would require further P2P protcol changes in order to provide this data to SPV clients along with their corresponding inclusion proofs.

Appendix 3 - NFD Regular Transactions Using Opcodes

As an alternative to defining new stake transaction types, we could use a special opcode that could be used in regular transactions to define and update NFD chains. This would have the following rough layout:

OP_NFDXFER <ordinal> <next UNFDO hash> <data pushes...> <redeem script>

Where “ordinal” identifies the chain, “next UNFDO hash” is the hash of what will become the active UNFDO (assuming everything else about this transaction is valid) and the data pushes plus redeem script are used to satisfy the current UNFDO.

This could enable a much larger number of minting, so it could unnecessarily increase impact on-chain. In a sense, it would also be less elegant than using stake transactions for this purpose and would require more processing to relate multiple NFD transactions within a single block, which is why we prefer using stake transactions for these operations.

Appendix 4 - Using a Single Ouptut for NFD Transfers

Instead of using three separate outputs for comitting to the necessary NFDC data, the approach suggested in the prior appendix (OP_NFDXFER) could be used instead, which commits to all data in a single output script.

With the appropriate changes, this could allow the transfer of multiple NFD chains inside a single transaction, thus further reducing processing and chain size impact.

The main challenge with this approach would be to ensure the proper limits in the number of transfers, allowing higher malleability of update transactions (because a single output could be easily moved between transactions) and reducing the miner incentive for chain inclusion.

Appendix 5 - New NFD Transaction Tree

A more general alternative would be introducing a new transaction tree to deal only with NFD transactions.

This would be an ideal solution, because it would remove the need to determine transaction types based on transaction layout (as is done today for stake transactions).

With clever modifications to the P2P protocol and block header commitments, it would also naturally allow SPV clients to sync less data, improving performance and decentralization in the ecosystem.

The main challenge for doing this approach is modifying the entire software ecosystem to support a new transaction tree: in particular, the block serialization format is not backwards compatible in relation to adding new trees, thus it would require multiple update rounds to accomplish.

Appendix 6 - New NFDTCs Block Field

This is a more general approach compared to adding a new transaction tree: it would involve adding an entire new block field (with acompanying records) to track NFD chains.

This could provide the best performance benefits as it relates to space, processing and syncing time.

However, it would be an even more challenging set of changes to implement, due to having to support and entire new category of objects on-chain.

References

[1]
C. Decker, R. Russell, O. Osuntokun. "eltoo: A Simple Layer2 Protocol for Bitcoin" (2018). Available at https://blockstream.com/eltoo.pdf.