Home

Atomic Transaction Format

This reference document explains how atomic transactions are serialised on Dijets Utility Chain - an instance of Ethereum Virtual Machine. The document uses the primitive serialisation format for packing and secp256k1 for cryptographic user identification.

Codec ID#

Some data is prepended with a codec ID (unt16) that denotes how the data should be deserialized. Right now, the only valid codec ID is 0 (0x00 0x00).

Inputs#

Inputs to Dijets Utility Chain Atomic Transactions are either an EVMInput from this chain or a TransferableInput (which contains a SECP256K1TransferInput) from another chain. The EVMInput will be used in ExportTx to spend funds from this chain, while the TransferableInput will be used to import atomic UTXOs from another chain.

EVM Input#

Input type that specifies an EVM account to deduct the funds from as part of an ExportTx.

What EVM Input Contains#

An EVM Input contains an address, amount, assetID, and nonce.

  • Address is the EVM address from which to transfer funds.
  • Amount is the amount of the asset to be transferred (specified in nDJT for DJT and the smallest denomination for all other assets).
  • AssetID is the ID of the asset to transfer.
  • Nonce is the nonce of the EVM account exporting funds.

Proto EVM Input Specification#


_10
message {
_10
bytes address = 1; // 20 bytes
_10
uint64 amount = 2; // 08 bytes
_10
bytes assetID = 3; // 32 bytes
_10
uint64 nonce = 4; // 08 bytes
_10
}

EVM Input Example#

Let's make an EVM Input:

  • Address: 0x8db97c7cece249c2b98bdc0226cc4c2a57bf52fc
  • Amount: 2000000
  • AssetID: 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
  • Nonce: 0

_22
[
_22
Address <- 0x8db97c7cece249c2b98bdc0226cc4c2a57bf52fc,
_22
Amount <- 0x00000000001e8480
_22
AssetID <- 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
_22
Nonce <- 0x0000000000000000
_22
]
_22
=
_22
[
_22
// address:
_22
0x8d, 0xb9, 0x7c, 0x7c, 0xec, 0xe2, 0x49, 0xc2,
_22
0xb9, 0x8b, 0xdc, 0x02, 0x26, 0xcc, 0x4c, 0x2a,
_22
0x57, 0xbf, 0x52, 0xfc,
_22
// amount:
_22
0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x84, 0x80,
_22
// assetID:
_22
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
_22
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
_22
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
_22
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
_22
// nonce:
_22
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
_22
]

Transferable Input#

Transferable Input wraps a SECP256K1TransferInput. Transferable inputs describe a specific UTXO with a provided transfer input.

What Transferable Input Contains#

A transferable input contains a TxID, UTXOIndex AssetID and an Input.

  • TxID is a 32-byte array that defines which transaction this input is consuming an output from.
  • UTXOIndex is an int that defines which utxo this input is consuming in the specified transaction.
  • AssetID is a 32-byte array that defines which asset this input references.
  • Input is a SECP256K1TransferInput, as defined below.

Proto Transferable Input Specification#


_10
message TransferableInput {
_10
bytes tx_id = 1; // 32 bytes
_10
uint32 utxo_index = 2; // 04 bytes
_10
bytes asset_id = 3; // 32 bytes
_10
Input input = 4; // size(input)
_10
}

Transferable Input Example#

Let's make a transferable input:

  • TxID: 0x6613a40dcdd8d22ea4aa99a4c84349056317cf550b6685e045e459954f258e59
  • UTXOIndex: 1
  • AssetID: 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
  • Input: "Example SECP256K1 Transfer Input from below"

_25
[
_25
TxID <- 0x6613a40dcdd8d22ea4aa99a4c84349056317cf550b6685e045e459954f258e59
_25
UTXOIndex <- 0x00000001
_25
AssetID <- 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
_25
Input <- 0x0000000500000000075bcd15000000020000000700000003
_25
]
_25
=
_25
[
_25
// txID:
_25
0x66, 0x13, 0xa4, 0x0d, 0xcd, 0xd8, 0xd2, 0x2e,
_25
0xa4, 0xaa, 0x99, 0xa4, 0xc8, 0x43, 0x49, 0x05,
_25
0x63, 0x17, 0xcf, 0x55, 0x0b, 0x66, 0x85, 0xe0,
_25
0x45, 0xe4, 0x59, 0x95, 0x4f, 0x25, 0x8e, 0x59,
_25
// utxoIndex:
_25
0x00, 0x00, 0x00, 0x01,
_25
// assetID:
_25
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
_25
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
_25
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
_25
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
_25
// input:
_25
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x74,
_25
0x6a, 0x52, 0x88, 0x00, 0x00, 0x00, 0x00, 0x01,
_25
0x00, 0x00, 0x00, 0x00,
_25
]

SECP256K1 Transfer Input#

A secp256k1 transfer input allows for spending an unspent secp256k1 transfer output.

What SECP256K1 Transfer Input Contains#

A secp256k1 transfer input contains an Amount and AddressIndices.

  • TypeID is the ID for this input type. It is 0x00000005.
  • Amount is a long that specifies the quantity that this input should be consuming from the UTXO. Must be positive. Must be equal to the amount specified in the UTXO.
  • AddressIndices is a list of unique ints that define the private keys that are being used to spend the UTXO. Each UTXO has an array of addresses that can spend the UTXO. Each int represents the index in this address array that will sign this transaction. The array must be sorted low to high.

Proto SECP256K1 Transfer Input Specification#


_10
message SECP256K1TransferInput {
_10
uint32 typeID = 1; // 04 bytes
_10
uint64 amount = 2; // 08 bytes
_10
repeated uint32 address_indices = 3; // 04 bytes + 04 bytes * len(address_indices)
_10
}

SECP256K1 Transfer Input Example#

Let's make a payment input with:

  • TypeId: 5
  • Amount: 500000000000
  • AddressIndices: [0]

_16
[
_16
TypeID <- 0x00000005
_16
Amount <- 500000000000 = 0x000000746a528800,
_16
AddressIndices <- [0x00000000]
_16
]
_16
=
_16
[
_16
// type id:
_16
0x00, 0x00, 0x00, 0x05,
_16
// amount:
_16
0x00, 0x00, 0x00, 0x74, 0x6a, 0x52, 0x88, 0x00,
_16
// length:
_16
0x00, 0x00, 0x00, 0x01,
_16
// sig[0]
_16
0x00, 0x00, 0x00, 0x00,
_16
]

Outputs#

Outputs to DUC (Dijets Utility Chain) Atomic Transactions are either an EVMOutput to be added to the balance of an address on this chain or a TransferableOutput (which contains a SECP256K1TransferOutput) to be moved to another chain.

The EVM Output will be used in ImportTx to add funds to this chain, while the TransferableOutput will be used to export atomic UTXOs to another chain.

EVM Output#

Output type specifying a state change to be applied to an EVM account as part of an ImportTx.

What EVM Output Contains#

An EVM Output contains an address, amount, and assetID.

  • Address is the EVM address that will receive the funds.
  • Amount is the amount of the asset to be transferred (specified in nDJT for DJT and the smallest denomination for all other assets).
  • AssetID is the ID of the asset to transfer.

Proto EVM Output Specification#


_10
message {
_10
bytes address = 1; // 20 bytes
_10
uint64 amount = 2; // 08 bytes
_10
bytes assetID = 3; // 32 bytes
_10
}

EVM Output Example#

Let's make an EVM Output:

  • Address: 0x0eb5ccb85c29009b6060decb353a38ea3b52cd20
  • Amount: 500000000000
  • AssetID: 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db

_19
[
_19
Address <- 0x0eb5ccb85c29009b6060decb353a38ea3b52cd20,
_19
Amount <- 0x000000746a528800
_19
AssetID <- 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
_19
]
_19
=
_19
[
_19
// address:
_19
0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e,
_19
0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89,
_19
0x43, 0xab, 0x08, 0x59,
_19
// amount:
_19
0x00, 0x00, 0x00, 0x74, 0x6a, 0x52, 0x88, 0x00,
_19
// assetID:
_19
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
_19
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
_19
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
_19
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
_19
]

Transferable Output#

Transferable outputs wrap a SECP256K1TransferOutput with an asset ID.

What Transferable Output Contains#

A transferable output contains an AssetID and an Output which is a SECP256K1TransferOutput.

  • AssetID is a 32-byte array that defines which asset this output references.
  • Output is a SECP256K1TransferOutput as defined below.

Proto Transferable Output Specification#


_10
message TransferableOutput {
_10
bytes asset_id = 1; // 32 bytes
_10
Output output = 2; // size(output)
_10
}

Transferable Output Example#

Let's make a transferable output:

  • AssetID: 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
  • Output: "Example SECP256K1 Transfer Output from below"

_23
[
_23
AssetID <- 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
_23
Output <- 0x000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859,
_23
]
_23
=
_23
[
_23
// assetID:
_23
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
_23
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
_23
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
_23
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
_23
// output:
_23
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
_23
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
_23
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
_23
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
_23
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
_23
0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00,
_23
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
_23
0x00, 0x00, 0x00, 0x01, 0x66, 0xf9, 0x0d, 0xb6,
_23
0x13, 0x7a, 0x78, 0xf7, 0x6b, 0x36, 0x93, 0xf7,
_23
0xf2, 0xbc, 0x50, 0x79, 0x56, 0xda, 0xe5, 0x63,
_23
]

SECP256K1 Transfer Output#

A secp256k1 transfer output allows for sending a quantity of an asset to a collection of addresses after a specified Unix time.

What SECP256K1 Transfer Output Contains#

A secp256k1 transfer output contains a TypeID, Amount, Locktime, Threshold, and Addresses.

  • TypeID is the ID for this output type. It is 0x00000007.
  • Amount is a long that specifies the quantity of the asset that this output owns. Must be positive.
  • Locktime is a long that contains the Unix timestamp that this output can be spent after. The Unix timestamp is specific to the second.
  • Threshold is an int that names the number of unique signatures required to spend the output. Must be less than or equal to the length of Addresses. If Addresses is empty, must be 0.
  • Addresses is a list of unique addresses that correspond to the private keys that can be used to spend this output.

Proto SECP256K1 Transfer Output Specification#


_10
message SECP256K1TransferOutput {
_10
uint32 typeID = 1; // 04 bytes
_10
uint64 amount = 2; // 08 bytes
_10
uint64 locktime = 3; // 08 bytes
_10
uint32 threshold = 4; // 04 bytes
_10
repeated bytes addresses = 5; // 04 bytes + 20 bytes * len(addresses)
_10
}

SECP256K1 Transfer Output Example#

Let's make a secp256k1 transfer output with:

  • TypeID: 7
  • Amount: 1000000
  • Locktime: 0
  • Threshold: 1
  • Addresses:
    • 0x66f90db6137a78f76b3693f7f2bc507956dae563

_26
[
_26
TypeID <- 0x00000007
_26
Amount <- 0x00000000000f4240
_26
Locktime <- 0x0000000000000000
_26
Threshold <- 0x00000001
_26
Addresses <- [
_26
0x66f90db6137a78f76b3693f7f2bc507956dae563
_26
]
_26
]
_26
=
_26
[
_26
// typeID:
_26
0x00, 0x00, 0x00, 0x07,
_26
// amount:
_26
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40,
_26
// locktime:
_26
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
_26
// threshold:
_26
0x00, 0x00, 0x00, 0x01,
_26
// number of addresses:
_26
0x00, 0x00, 0x00, 0x01,
_26
// addrs[0]:
_26
0x66, 0xf9, 0x0d, 0xb6, 0x13, 0x7a, 0x78, 0xf7,
_26
0x6b, 0x36, 0x93, 0xf7, 0xf2, 0xbc, 0x50, 0x79,
_26
0x56, 0xda, 0xe5, 0x63,
_26
]

Atomic Transactions#

Atomic Transactions are used to move funds between chains. There are two types ImportTx and ExportTx.

ExportTx#

ExportTx is a transaction to export funds from Dijets Utility Chain to a different chain.

What ExportTx Contains#

An ExportTx contains an typeID, networkID, blockchainID, destinationChain, inputs, and exportedOutputs.

  • typeID is an int that the type for an ExportTx. The typeID for an exportTx is 1.
  • networkID is an int that defines which Dijets network this transaction is meant to be issued to. This could refer to Mainnet, Dijets TestNet, etc. and is different than the EVM's network ID.
  • blockchainID is a 32-byte array that defines which blockchain this transaction was issued to.
  • destinationChain is a 32-byte array that defines which blockchain this transaction exports funds to.
  • inputs is an array of EVM Inputs to fund the ExportTx.
  • exportedOutputs is an array of TransferableOutputs to be transferred to destinationChain.

ExportTx Example#

Let's make an EVM Output:

  • TypeID: 1
  • NetworkID: 12345
  • BlockchainID: 0x91060eabfb5a571720109b5896e5ff00010a1cfe6b103d585e6ebf27b97a1735
  • DestinationChain: 0xd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf
  • Inputs:
    • "Example EVMInput as defined above"
  • Exportedoutputs:
    • "Example TransferableOutput as defined above"

_54
[
_54
TypeID <- 0x00000001
_54
NetworkID <- 0x00003039
_54
BlockchainID <- 0x91060eabfb5a571720109b5896e5ff00010a1cfe6b103d585e6ebf27b97a1735
_54
DestinationChain <- 0xd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf
_54
Inputs <- [
_54
0xc3344128e060128ede3523a24a461c8943ab08590000000000003039000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000000000001
_54
]
_54
ExportedOutputs <- [
_54
0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2dbdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700000000000f42400000000000000000000000010000000166f90db6137a78f76b3693f7f2bc507956dae563
_54
]
_54
]
_54
=
_54
[
_54
// typeID:
_54
0x00, 0x00, 0x00, 0x01,
_54
// networkID:
_54
0x00, 0x00, 0x00, 0x04,
_54
// blockchainID:
_54
0x91, 0x06, 0x0e, 0xab, 0xfb, 0x5a, 0x57, 0x17,
_54
0x20, 0x10, 0x9b, 0x58, 0x96, 0xe5, 0xff, 0x00,
_54
0x01, 0x0a, 0x1c, 0xfe, 0x6b, 0x10, 0x3d, 0x58,
_54
0x5e, 0x6e, 0xbf, 0x27, 0xb9, 0x7a, 0x17, 0x35,
_54
// destination_chain:
_54
0xd8, 0x91, 0xad, 0x56, 0x05, 0x6d, 0x9c, 0x01,
_54
0xf1, 0x8f, 0x43, 0xf5, 0x8b, 0x5c, 0x78, 0x4a,
_54
0xd0, 0x7a, 0x4a, 0x49, 0xcf, 0x3d, 0x1f, 0x11,
_54
0x62, 0x38, 0x04, 0xb5, 0xcb, 0xa2, 0xc6, 0xbf,
_54
// inputs[] count:
_54
0x00, 0x00, 0x00, 0x01,
_54
// inputs[0]
_54
0x8d, 0xb9, 0x7c, 0x7c, 0xec, 0xe2, 0x49, 0xc2,
_54
0xb9, 0x8b, 0xdc, 0x02, 0x26, 0xcc, 0x4c, 0x2a,
_54
0x57, 0xbf, 0x52, 0xfc, 0x00, 0x00, 0x00, 0x00,
_54
0x00, 0x1e, 0x84, 0x80, 0xdb, 0xcf, 0x89, 0x0f,
_54
0x77, 0xf4, 0x9b, 0x96, 0x85, 0x76, 0x48, 0xb7,
_54
0x2b, 0x77, 0xf9, 0xf8, 0x29, 0x37, 0xf2, 0x8a,
_54
0x68, 0x70, 0x4a, 0xf0, 0x5d, 0xa0, 0xdc, 0x12,
_54
0xba, 0x53, 0xf2, 0xdb, 0x00, 0x00, 0x00, 0x00,
_54
0x00, 0x00, 0x00, 0x00,
_54
// exportedOutputs[] count
_54
0x00, 0x00, 0x00, 0x01,
_54
// exportedOutputs[0]
_54
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
_54
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
_54
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
_54
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
_54
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
_54
0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00,
_54
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
_54
0x00, 0x00, 0x00, 0x01, 0x66, 0xf9, 0x0d, 0xb6,
_54
0x13, 0x7a, 0x78, 0xf7, 0x6b, 0x36, 0x93, 0xf7,
_54
0xf2, 0xbc, 0x50, 0x79, 0x56, 0xda, 0xe5, 0x63,
_54
]

ImportTx#

ImportTx is a transaction to import funds to Dijets Utility Chain from another chain.

What ImportTx Contains#

An ImportTx contains an typeID, networkID, blockchainID, destinationChain, importedInputs, and Outs.

  • typeID is an int that the type for an ImportTx. The typeID for an ImportTx is 0.
  • networkID is an int that defines which Dijets network this transaction is meant to be issued to. This could refer to Mainnet, Dijets TestNet, etc. and is different than the EVM's network ID.
  • blockchainID is a 32-byte array that defines which blockchain this transaction was issued to.
  • sourceChain is a 32-byte array that defines which blockchain from which to import funds.
  • importedInputs is an array of TransferableInputs to fund the ImportTx.
  • Outs is an array of EVM Outputs to be imported to this chain.

ImportTx Example#

Let's make an ImportTx:

  • TypeID: 0
  • NetworkID: 12345
  • BlockchainID: 0x91060eabfb5a571720109b5896e5ff00010a1cfe6b103d585e6ebf27b97a1735
  • SourceChain: 0xd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf
  • ImportedInputs:
    • "Example TransferableInput as defined above"
  • Outs:
    • "Example EVMOutput as defined above"

_54
[
_54
TypeID <- 0x00000000
_54
NetworkID <- 0x00003039
_54
BlockchainID <- 0x91060eabfb5a571720109b5896e5ff00010a1cfe6b103d585e6ebf27b97a1735
_54
SourceChain <- 0xd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf
_54
ImportedInputs <- [
_54
0x6613a40dcdd8d22ea4aa99a4c84349056317cf550b6685e045e459954f258e5900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000746a5288000000000100000000
_54
]
_54
Outs <- [
_54
0x0eb5ccb85c29009b6060decb353a38ea3b52cd20000000746a528800dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
_54
]
_54
]
_54
=
_54
[
_54
// typeID:
_54
0x00, 0x00, 0x00, 0x00,
_54
// networkID:
_54
0x00, 0x00, 0x00, 0x04,
_54
// blockchainID:
_54
0x91, 0x06, 0x0e, 0xab, 0xfb, 0x5a, 0x57, 0x17,
_54
0x20, 0x10, 0x9b, 0x58, 0x96, 0xe5, 0xff, 0x00,
_54
0x01, 0x0a, 0x1c, 0xfe, 0x6b, 0x10, 0x3d, 0x58,
_54
0x5e, 0x6e, 0xbf, 0x27, 0xb9, 0x7a, 0x17, 0x35,
_54
// sourceChain:
_54
0xd8, 0x91, 0xad, 0x56, 0x05, 0x6d, 0x9c, 0x01,
_54
0xf1, 0x8f, 0x43, 0xf5, 0x8b, 0x5c, 0x78, 0x4a,
_54
0xd0, 0x7a, 0x4a, 0x49, 0xcf, 0x3d, 0x1f, 0x11,
_54
0x62, 0x38, 0x04, 0xb5, 0xcb, 0xa2, 0xc6, 0xbf,
_54
// importedInputs[] count:
_54
0x00, 0x00, 0x00, 0x01,
_54
// importedInputs[0]
_54
0x66, 0x13, 0xa4, 0x0d, 0xcd, 0xd8, 0xd2, 0x2e,
_54
0xa4, 0xaa, 0x99, 0xa4, 0xc8, 0x43, 0x49, 0x05,
_54
0x63, 0x17, 0xcf, 0x55, 0x0b, 0x66, 0x85, 0xe0,
_54
0x45, 0xe4, 0x59, 0x95, 0x4f, 0x25, 0x8e, 0x59,
_54
0x00, 0x00, 0x00, 0x01, 0xdb, 0xcf, 0x89, 0x0f,
_54
0x77, 0xf4, 0x9b, 0x96, 0x85, 0x76, 0x48, 0xb7,
_54
0x2b, 0x77, 0xf9, 0xf8, 0x29, 0x37, 0xf2, 0x8a,
_54
0x68, 0x70, 0x4a, 0xf0, 0x5d, 0xa0, 0xdc, 0x12,
_54
0xba, 0x53, 0xf2, 0xdb, 0x00, 0x00, 0x00, 0x05,
_54
0x00, 0x00, 0x00, 0x74, 0x6a, 0x52, 0x88, 0x00,
_54
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
_54
// outs[] count
_54
0x00, 0x00, 0x00, 0x01,
_54
// outs[0]
_54
0x0e, 0xb5, 0xcc, 0xb8, 0x5c, 0x29, 0x00, 0x9b,
_54
0x60, 0x60, 0xde, 0xcb, 0x35, 0x3a, 0x38, 0xea,
_54
0x3b, 0x52, 0xcd, 0x20, 0x00, 0x00, 0x00, 0x74,
_54
0x6a, 0x52, 0x88, 0x00, 0xdb, 0xcf, 0x89, 0x0f,
_54
0x77, 0xf4, 0x9b, 0x96, 0x85, 0x76, 0x48, 0xb7,
_54
0x2b, 0x77, 0xf9, 0xf8, 0x29, 0x37, 0xf2, 0x8a,
_54
0x68, 0x70, 0x4a, 0xf0, 0x5d, 0xa0, 0xdc, 0x12,
_54
0xba, 0x53, 0xf2, 0xdb,
_54
]

Credentials#

Credentials have one possible type: SECP256K1Credential. Each credential is paired with an Input. The order of the credentials match the order of the inputs.

SECP256K1 Credential#

A secp256k1 credential contains a list of 65-byte recoverable signatures.

What SECP256K1 Credential Contains#

  • TypeID is the ID for this type. It is 0x00000009.
  • Signatures is an array of 65-byte recoverable signatures. The order of the signatures must match the input's signature indices.

Proto SECP256K1 Credential Specification#


_10
message SECP256K1Credential {
_10
uint32 typeID = 1; // 4 bytes
_10
repeated bytes signatures = 2; // 4 bytes + 65 bytes * len(signatures)
_10
}

SECP256K1 Credential Example#

Let's make a payment input with:

  • TypeID: 9
  • signatures:
    • 0x0acccf47a820549a84428440e2421975138790e41be262f7197f3d93faa26cc8741060d743ffaf025782c8c86b862d2b9febebe7d352f0b4591afbd1a737f8a30010199dbf

_23
[
_23
TypeID <- 0x00000009
_23
Signatures <- [
_23
0x0acccf47a820549a84428440e2421975138790e41be262f7197f3d93faa26cc8741060d743ffaf025782c8c86b862d2b9febebe7d352f0b4591afbd1a737f8a30010199dbf,
_23
]
_23
]
_23
=
_23
[
_23
// Type ID
_23
0x00, 0x00, 0x00, 0x09,
_23
// length:
_23
0x00, 0x00, 0x00, 0x01,
_23
// sig[0]
_23
0x0a, 0xcc, 0xcf, 0x47, 0xa8, 0x20, 0x54, 0x9a,
_23
0x84, 0x42, 0x84, 0x40, 0xe2, 0x42, 0x19, 0x75,
_23
0x13, 0x87, 0x90, 0xe4, 0x1b, 0xe2, 0x62, 0xf7,
_23
0x19, 0x7f, 0x3d, 0x93, 0xfa, 0xa2, 0x6c, 0xc8,
_23
0x74, 0x10, 0x60, 0xd7, 0x43, 0xff, 0xaf, 0x02,
_23
0x57, 0x82, 0xc8, 0xc8, 0x6b, 0x86, 0x2d, 0x2b,
_23
0x9f, 0xeb, 0xeb, 0xe7, 0xd3, 0x52, 0xf0, 0xb4,
_23
0x59, 0x1a, 0xfb, 0xd1, 0xa7, 0x37, 0xf8, 0xa3,
_23
0x00, 0x10, 0x19, 0x9d, 0xbf,
_23
]

Signed Transaction#

A signed transaction contains an unsigned AtomicTx and credentials.

What Signed Transaction Contains#

A signed transaction contains a CodecID, AtomicTx, and Credentials.

  • CodecID The only current valid codec id is 00 00.
  • AtomicTx is an atomic transaction, as described above.
  • Credentials is an array of credentials. Each credential corresponds to the input at the same index in the AtomicTx

Proto Signed Transaction Specification#


_10
message Tx {
_10
uint16 codec_id = 1; // 2 bytes
_10
AtomicTx atomic_tx = 2; // size(atomic_tx)
_10
repeated Credential credentials = 3; // 4 bytes + size(credentials)
_10
}

Signed Transaction Example#

Let's make a signed transaction that uses the unsigned transaction and credential from the previous examples.

  • CodecID: 0

  • UnsignedTx: 0x000000000000303991060eabfb5a571720109b5896e5ff00010a1cfe6b103d585e6ebf27b97a1735d891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf000000016613a40dcdd8d22ea4aa99a4c84349056317cf550b6685e045e459954f258e5900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000746a5288000000000100000000000000010eb5ccb85c29009b6060decb353a38ea3b52cd20000000746a528800dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db

  • Credentials

    0x00000009000000010acccf47a820549a84428440e2421975138790e41be262f7197f3d93faa26cc8741060d743ffaf025782c8c86b862d2b9febebe7d352f0b4591afbd1a737f8a300


_54
[
_54
CodecID <- 0x0000
_54
UnsignedAtomic Tx <- 0x0000000100000004ffffffffeeeeeeeeddddddddccccccccbbbbbbbbaaaaaaaa999999998888888800000001000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab085900000001f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd150000000200000007000000030000000400010203
_54
Credentials <- [
_54
0x00000009000000010acccf47a820549a84428440e2421975138790e41be262f7197f3d93faa26cc8741060d743ffaf025782c8c86b862d2b9febebe7d352f0b4591afbd1a737f8a300,
_54
]
_54
]
_54
=
_54
[
_54
// Codec ID
_54
0x00, 0x00,
_54
// unsigned atomic transaction:
_54
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39,
_54
0x91, 0x06, 0x0e, 0xab, 0xfb, 0x5a, 0x57, 0x17,
_54
0x20, 0x10, 0x9b, 0x58, 0x96, 0xe5, 0xff, 0x00,
_54
0x01, 0x0a, 0x1c, 0xfe, 0x6b, 0x10, 0x3d, 0x58,
_54
0x5e, 0x6e, 0xbf, 0x27, 0xb9, 0x7a, 0x17, 0x35,
_54
0xd8, 0x91, 0xad, 0x56, 0x05, 0x6d, 0x9c, 0x01,
_54
0xf1, 0x8f, 0x43, 0xf5, 0x8b, 0x5c, 0x78, 0x4a,
_54
0xd0, 0x7a, 0x4a, 0x49, 0xcf, 0x3d, 0x1f, 0x11,
_54
0x62, 0x38, 0x04, 0xb5, 0xcb, 0xa2, 0xc6, 0xbf,
_54
0x00, 0x00, 0x00, 0x01, 0x66, 0x13, 0xa4, 0x0d,
_54
0xcd, 0xd8, 0xd2, 0x2e, 0xa4, 0xaa, 0x99, 0xa4,
_54
0xc8, 0x43, 0x49, 0x05, 0x63, 0x17, 0xcf, 0x55,
_54
0x0b, 0x66, 0x85, 0xe0, 0x45, 0xe4, 0x59, 0x95,
_54
0x4f, 0x25, 0x8e, 0x59, 0x00, 0x00, 0x00, 0x01,
_54
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
_54
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
_54
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
_54
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
_54
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x74,
_54
0x6a, 0x52, 0x88, 0x00, 0x00, 0x00, 0x00, 0x01,
_54
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
_54
0x0e, 0xb5, 0xcc, 0xb8, 0x5c, 0x29, 0x00, 0x9b,
_54
0x60, 0x60, 0xde, 0xcb, 0x35, 0x3a, 0x38, 0xea,
_54
0x3b, 0x52, 0xcd, 0x20, 0x00, 0x00, 0x00, 0x74,
_54
0x6a, 0x52, 0x88, 0x00, 0xdb, 0xcf, 0x89, 0x0f,
_54
0x77, 0xf4, 0x9b, 0x96, 0x85, 0x76, 0x48, 0xb7,
_54
0x2b, 0x77, 0xf9, 0xf8, 0x29, 0x37, 0xf2, 0x8a,
_54
0x68, 0x70, 0x4a, 0xf0, 0x5d, 0xa0, 0xdc, 0x12,
_54
0xba, 0x53, 0xf2, 0xdb,
_54
// number of credentials:
_54
0x00, 0x00, 0x00, 0x01,
_54
// credential[0]:
_54
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01,
_54
0x0a, 0xcc, 0xcf, 0x47, 0xa8, 0x20, 0x54, 0x9a,
_54
0x84, 0x42, 0x84, 0x40, 0xe2, 0x42, 0x19, 0x75,
_54
0x13, 0x87, 0x90, 0xe4, 0x1b, 0xe2, 0x62, 0xf7,
_54
0x19, 0x7f, 0x3d, 0x93, 0xfa, 0xa2, 0x6c, 0xc8,
_54
0x74, 0x10, 0x60, 0xd7, 0x43, 0xff, 0xaf, 0x02,
_54
0x57, 0x82, 0xc8, 0xc8, 0x6b, 0x86, 0x2d, 0x2b,
_54
0x9f, 0xeb, 0xeb, 0xe7, 0xd3, 0x52, 0xf0, 0xb4,
_54
0x59, 0x1a, 0xfb, 0xd1, 0xa7, 0x37, 0xf8, 0xa3,
_54
0x00,

UTXO#

A UTXO is a standalone representation of a transaction output.

What UTXO Contains#

A UTXO contains a CodecID, TxID, UTXOIndex, AssetID, and Output.

  • CodecID The only valid CodecID is 00 00
  • TxID is a 32-byte transaction ID. Transaction IDs are calculated by taking sha256 of the bytes of the signed transaction.
  • UTXOIndex is an int that specifies which output in the transaction specified by TxID that this utxo was created by.
  • AssetID is a 32-byte array that defines which asset this utxo references.
  • Output is the output object that created this utxo. The serialisation of Outputs was defined above.

Proto UTXO Specification#


_10
message Utxo {
_10
uint16 codec_id = 1; // 02 bytes
_10
bytes tx_id = 2; // 32 bytes
_10
uint32 output_index = 3; // 04 bytes
_10
bytes asset_id = 4; // 32 bytes
_10
Output output = 5; // size(output)
_10
}

UTXO Example#

Let’s make a UTXO from the signed transaction created above:

  • CodecID: 0
  • TxID: 0xf966750f438867c3c9828ddcdbe660e21ccdbb36a9276958f011ba472f75d4e7
  • UTXOIndex: 0 = 0x00000000
  • AssetID: 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
  • Output: "Example EVMOutput as defined above"

_34
[
_34
CodecID <- 0x0000
_34
TxID <- 0xf966750f438867c3c9828ddcdbe660e21ccdbb36a9276958f011ba472f75d4e7
_34
UTXOIndex <- 0x00000000
_34
AssetID <- 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
_34
Output <- 0x000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859
_34
]
_34
=
_34
[
_34
// Codec ID:
_34
0x00, 0x00,
_34
// txID:
_34
0xf9, 0x66, 0x75, 0x0f, 0x43, 0x88, 0x67, 0xc3,
_34
0xc9, 0x82, 0x8d, 0xdc, 0xdb, 0xe6, 0x60, 0xe2,
_34
0x1c, 0xcd, 0xbb, 0x36, 0xa9, 0x27, 0x69, 0x58,
_34
0xf0, 0x11, 0xba, 0x47, 0x2f, 0x75, 0xd4, 0xe7,
_34
// utxo index:
_34
0x00, 0x00, 0x00, 0x00,
_34
// assetID:
_34
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
_34
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
_34
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
_34
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
_34
// output:
_34
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
_34
0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00,
_34
0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01,
_34
0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, 0x03,
_34
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
_34
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
_34
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
_34
0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
_34
0x24, 0x25, 0x26, 0x27,
_34
]