UTXO Specification

Abstract

This draft QIP defines the UTXO specification for Quai Network. The UTXO specification defines the data structures and algorithms used to represent the state of the UTXO set.

Motivation

We would like to encuroage the utilization of UTXOs on Quai Network in order to implement transactions that are lightweight, efficient, and secure. The implementation of UTXOs allows us to also implement the novel two token tokenomic design.

Specification

Header Definition

The header definition with the newly required utxoHash field is as follows:

// Header represents a block header in the Quai blockchain.
type Header struct {
	parentHash    []common.Hash   `json:"parentHash"           gencodec:"required"`
	uncleHash     common.Hash     `json:"sha3Uncles"           gencodec:"required"`
	coinbase      common.Address  `json:"miner"                gencodec:"required"`
	root          common.Hash     `json:"stateRoot"            gencodec:"required"`
	utxoHash      common.Hash     `json:"utxoHash"			   gencodex:"required"` // New
	txHash        common.Hash     `json:"transactionsRoot"     gencodec:"required"`
	etxHash       common.Hash     `json:"extTransactionsRoot"  gencodec:"required"`
	etxRollupHash common.Hash     `json:"extRollupRoot"        gencodec:"required"`
	manifestHash  []common.Hash   `json:"manifestHash"         gencodec:"required"`
	receiptHash   common.Hash     `json:"receiptsRoot"         gencodec:"required"`
	difficulty    *big.Int        `json:"difficulty"           gencodec:"required"`
	parentEntropy []*big.Int      `json:"parentEntropy"        gencodec:"required"`
	parentDeltaS  []*big.Int      `json:"parentDeltaS"         gencodec:"required"`
	number        []*big.Int      `json:"number"               gencodec:"required"`
	gasLimit      uint64          `json:"gasLimit"             gencodec:"required"`
	gasUsed       uint64          `json:"gasUsed"              gencodec:"required"`
	baseFee       *big.Int        `json:"baseFeePerGas"        gencodec:"required"`
	location      common.Location `json:"location"             gencodec:"required"`
	time          uint64          `json:"timestamp"            gencodec:"required"`
	extra         []byte          `json:"extraData"            gencodec:"required"`
	mixHash       common.Hash     `json:"mixHash"              gencodec:"required"`
	nonce         BlockNonce      `json:"nonce"`
}

Block Definition

The block definition with the newly required UTXO transactions is as follows:

// Block represents an entire block in the Quai blockchain.
type Block struct {
	header          *Header
	uncles          []*Header
	utxos           []*MsgUTXO
	transactions    Transactions
	extTransactions Transactions
	subManifest     BlockManifest

	// caches
	size       atomic.Value
	appendTime atomic.Value

	// These fields are used by package eth to track
	// inter-peer block relay.
	ReceivedAt   time.Time
	ReceivedFrom interface{}
}

UTXO Definition

UTXOs are defined by a MsgUTXO struct comprised of a Version, TxIn, TxOut, and LockTime.

// MsgUTXO implements the Message interface and represents a quai utxo message.
//
// Use the AddTxIn and AddTxOut functions to build up the list of transaction
// inputs and outputs.
type MsgUTXO struct {
	Version  uint32
	TxIn     []*TxIn
	TxOut    []*TxOut
	LockTime uint32
}


// TxIn defines a quai transaction input.
type TxIn struct {
	PreviousOutPoint OutPoint
	SignatureScript  []byte
	Witness          TxWitness
	Sequence         uint32
}

// TxOut defines a quai transaction output.
type TxOut struct {
	Value    uint64
	PkScript []byte
}

UtxoViewpoint Definition

UtxoViewpoint represents a view into the set of unspent transaction outputs from a specific point of view in the chain. For example, it could be for
the end of the main chain, some point in the history of the main chain, or down a side chain. When a new block is added to the blockchain, the UtxoViewpoint is updated based on the transactions within that block:

  1. Outputs from transactions in the block are added to the UTXO set (since they are new and unspent).
  2. Inputs in the block’s transactions reference and “spend” previous UTXOs, so those referenced UTXOs are removed from the set.

Following the successful processing of a block, the UtxoViewpoint is applied to the global UTXO set.

// The unspent outputs are needed by other transactions for things such as
// script validation and double spend prevention.
type UtxoViewpoint struct {
	entries  map[OutPoint]*UtxoEntry
	bestHash common.Hash
}

Merkle Trees

The merkle tree construction of the UTXO set is based on the root hash of the transaction array for each block. The UTXO set itself
is maintained by the progression / reorganization of the chain.

Considerations

  1. What signature scheme should be used for the UTXO transactions?
  2. What opcodes do we want to support, if any?
  3. What addresse scheme do we want to support?
  4. Do we want to support SegWit?
1 Like

Adding notes from @wizeguyy

  • Does it make sense to have Qu and Quai transactions in the same transaction list? If not, modify the MsgUTXO to be QuTransactions and Transaction to be QuaiTransactions.