Switch branches/tags
Nothing to show
Find file Copy path
5c3900e Aug 23, 2018
2 contributors

Users who have contributed to this file

@thephez @nmarley
90 lines (58 sloc) 7.37 KB
  DIP: 0002
  Title: Special Transactions
  Author: Samuel Westrich, Alexander Block, Andy Freer
  Comments-Summary: No comments yet.
  Status: Proposed
  Type: Standard
  Created: 2018-04-30
  License: MIT License

Table of Contents

  1. Abstract
  2. Motivation
  3. Special Transactions
  4. Serialization, hashing and signing
  5. Compatibility
  6. Copyright


This DIP adds a basis for new transaction types that will provide on-chain metadata to assist various consensus mechanisms. This will allow for a more native way to implement new features which don’t naturally fit into the current concept of transactions.


Currently, new features and consensus mechanisms have to be implemented on top of the restrictions imposed by the simple nature of transactions. Since classical transactions can only carry inputs and outputs, they are most useful for financial transactions (i.e. transfers of quantities of Dash between addresses on the distributed ledger). These inputs and outputs carry scripts and signatures which are used to authorize and validate the transaction.

To implement new on-chain features and consensus mechanisms which do not fit into this concept of financial transactions, it is often necessary to misuse the inputs/outputs and their corresponding scripts to add additional data and meaning to a transaction. For example, new opcodes would have to be introduced to mark a transaction as something special and add a payload. In other cases, OP_RETURN has been misused to store data on-chain.

This method of implementing new features results in some verification and consistency complications that can only be resolved with complicated, error-prone code. It also requires all parts of the ecosystem to reimplement the verification and consistency checks for each new feature.

Dash has so far avoided such extensions and misuse of the transaction format, but upcoming features would make this unavoidable. Instead of misusing the inputs/outputs of the transaction for every new feature or consensus mechanism, this DIP introduces a solution to provide a reusable framework for such extensions. This framework, called “Special Transactions”, updates and expands classical transactions with an additional type (a meaning) and an additional payload.

Special Transactions

This DIP increments the transaction version to 3 and splits the field into two 16-bit fields with the second field now becoming transaction type. A classical transaction will be of transaction type 0 to remain backwards compatible.

A non-zero type indicates a special transaction with an extra payload appended after the last of the classical transaction fields. The internal structure of the payload is specific to the special transaction type. A newly introduced special transaction type should clearly define the structure of the payload so that it can be safely serialized, deserialized and verified. The individual new special transaction types will be defined by new DIPs and are not subject to this DIP.

The inputs and outputs of special transactions usually have the same meaning as with classical transactions. Verification and processing of these does not change for most special transaction types. If exceptions are made to this rule, a new DIP describing the changes in detail and a deployment plan must be provided.

The new transaction format is defined as follows:

Bytes Name Data Type Description
2 version uint16_t Transaction version number; currently version 2. Programs creating transactions using newer consensus rules may use higher version numbers.
2 type uint16_t Type for a classical transaction will be 0. View transaction types for more information.
Varies tx_in count compactSize uint Number of inputs in this transaction.
Varies tx_in txIn Transaction inputs.
Varies tx_out count compactSize uint Number of outputs in this transaction.
Varies tx_out txOut Transaction outputs.
4 lock_time uint32_t A time (Unix epoch time) or block number.
1-9 extra_payload size compactSize uint Variable number of bytes of extra payload.
Varies extra_payload blob Extra payload will be appended based on the transaction type.

Serialization, hashing and signing

While implementing special transactions, implementors might choose to extend existing transaction classes by adding the payload fields to these classes. However, it is important to keep backwards compatibility when serializing, hashing or signing instances of these classes. This means that any classical transaction (type = 0, regardless of version) should NOT include these new fields while serializing, hashing or signing. A serialized classical transaction must always be identical to a transaction serialized by a program or library which does not support special transactions. The same applies to hashing and signing of classical transactions.

For special transactions, the extra_payload_size and extra_payload fields must be included when serialized, deserialized or hashed. All OP-Codes which perform any signing/verification (e.g. CHECKSIGVERIFY) must also include both fields when calculating the signed hash. This ensures that payloads can’t be modified after a transaction has been signed.


The introduction of special transactions will require the whole Dash ecosystem to perform a one-time mandatory update of all the software and libraries involved.

Software and libraries will have to be changed so that they can differentiate between classical transactions and special transactions. Deserialization of a classical transaction remains unchanged. Deserialization of a special transaction requires the software/library to at least implement skipping and ignoring the extra_payload field. Validation and processing of the inputs and outputs of a special transaction must remain identical to classical transactions.

A classical transaction can be identified by the 16-bit type field being 0. Please note that if the the 16-bit type field is 0, both 16-bit fields can also be interpreted as a single 32-bit field which would equal the value in the 16-bit version field. This is to allow some backwards compatibility for software/libraries which do not implement special transactions. However, this backwards compatibility is limited and will fail when special transactions are encountered.

A special transaction can be identified by the 16-bit version field being >= 3 and the 16-bit type field being non-zero.

The idea is to minimize the work necessary for future network wide upgrades. Only the initial introduction of special transactions will require more work. After that, the software and library implementers will determine if and when they want to implement newly introduced special transaction types. Clients that, for example, are only interested in following the financial ledger can completely ignore new special transactions as long as they correctly process the inputs and outputs of these special transactions. Only clients that are interested in Dash’s advanced features would need to selectively implement new special transaction types.


Copyright (c) 2018 Dash Core Team. Licensed under the MIT License