Dijets Virtual Machine - Transaction Format
This file is meant to be the single source of truth for how we serialize transactions in the Dijets Virtual Machine. This 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
).
Transferable Output#
Transferable outputs wrap an output with an asset ID.
What Transferable Output Contains#
A transferable output contains an AssetID
and an Output
.
AssetID
is a 32-byte array that defines which asset this output references.Output
is an output, as defined below. Outputs have four possible types:SECP256K1TransferOutput
,SECP256K1MintOutput
,NFTTransferOutput
andNFTMintOutput
.
Proto Transferable Output Specification#
message TransferableOutput { bytes asset_id = 1; // 32 bytes Output output = 2; // size(output) }
Transferable Output Example#
Let’s make a transferable output:
AssetID
:0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Output
:"Example SECP256K1 Transfer Output from below"
[ AssetID <- 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f Output <- 0x000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859, ] = [ // assetID: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, // output: 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
Transferable Input#
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. Transaction IDs are calculated by taking sha256 of the bytes of the signed transaction.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 an input, as defined below. This can currently only be a SECP256K1 transfer input
Proto Transferable Input Specification#
message TransferableInput { bytes tx_id = 1; // 32 bytes uint32 utxo_index = 2; // 04 bytes bytes asset_id = 3; // 32 bytes Input input = 4; // size(input) }
Transferable Input Example#
Let’s make a transferable input:
TxID
:0xf1e1d1c1b1a191817161514131211101f0e0d0c0b0a090807060504030201000
UTXOIndex
:5
AssetID
:0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Input
:"Example SECP256K1 Transfer Input from below"
[ TxID <- 0xf1e1d1c1b1a191817161514131211101f0e0d0c0b0a090807060504030201000 UTXOIndex <- 0x00000005 AssetID <- 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f Input <- 0x0000000500000000075bcd15000000020000000700000003 ] = [ // txID: 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x41, 0x31, 0x21, 0x11, 0x01, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, // utxoIndex: 0x00, 0x00, 0x00, 0x05, // assetID: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, // input: 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x07, 0x5b, 0xcd, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07 ]
Transferable Operation#
Transferable operations describe a set of UTXOs with a provided transfer operation. Only one Asset ID is able to be referenced per operation.
What Transferable Operation Contains#
A transferable operation contains an AssetID
, UTXOIDs
, and a TransferOp
.
AssetID
is a 32-byte array that defines which asset this operation changes.UTXOIDs
is an array of TxID-OutputIndex tuples. This array must be sorted in lexicographical order.TransferOp
is a transferable operation object.
Proto Transferable Operation Specs#
message UTXOID { bytes tx_id = 1; // 32 bytes uint32 utxo_index = 2; // 04 bytes } message TransferableOp { bytes asset_id = 1; // 32 bytes repeated UTXOID utxo_ids = 2; // 4 + 36 * len(utxo_ids) bytes TransferOp transfer_op = 3; // size(transfer_op) }
Transferable Operation Example#
Let’s make a transferable operation:
AssetID
:0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
UTXOIDs
:UTXOID
:TxID
:0xf1e1d1c1b1a191817161514131211101f0e0d0c0b0a090807060504030201000
UTXOIndex
:5
Op
:"Example Transfer Op from below"
[ AssetID <- 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f UTXOIDs <- [ { TxID:0xf1e1d1c1b1a191817161514131211101f0e0d0c0b0a090807060504030201000 UTXOIndex:5 } ] Op <- 0x0000000d0000000200000003000000070000303900000003431100000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859 ] = [ // assetID: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, // number of utxoIDs: 0x00, 0x00, 0x00, 0x01, // txID: 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x41, 0x31, 0x21, 0x11, 0x01, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, // utxoIndex: 0x00, 0x00, 0x00, 0x05, // op: 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x03, 0x43, 0x11, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
Outputs#
Outputs have four possible types:
SECP256K1TransferOutput
,
SECP256K1MintOutput
,
NFTTransferOutput
and
NFTMintOutput
.
SECP256K1 Mint Output#
A secp256k1 mint output is an output that is owned by a collection of addresses.
What SECP256K1 Mint Output Contains#
A secp256k1 Mint output contains a TypeID
, Locktime
, Threshold
, and Addresses
.
TypeID
is the ID for this output type. It is0x00000006
.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 ofAddresses
. IfAddresses
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. Addresses must be sorted lexicographically.
Proto SECP256K1 Mint Output Specification#
message SECP256K1MintOutput { uint32 typeID = 1; // 04 bytes uint64 locktime = 2; // 08 bytes uint32 threshold = 3; // 04 bytes repeated bytes addresses = 4; // 04 bytes + 20 bytes * len(addresses) }
SECP256K1 Mint Output Example#
Let’s make a SECP256K1 mint output with:
TypeID
:6
Locktime
:54321
Threshold
:1
Addresses
:0x51025c61fbcfc078f69334f834be6dd26d55a955
0xc3344128e060128ede3523a24a461c8943ab0859
[ TypeID <- 0x00000006 Locktime <- 0x000000000000d431 Threshold <- 0x00000001 Addresses <- [ 0x51025c61fbcfc078f69334f834be6dd26d55a955, 0xc3344128e060128ede3523a24a461c8943ab0859, ] ] = [ // typeID: 0x00, 0x00, 0x00, 0x06, // locktime: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, // threshold: 0x00, 0x00, 0x00, 0x01, // number of addresses: 0x00, 0x00, 0x00, 0x02, // addrs[0]: 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, // addrs[1]: 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
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 is0x00000007
.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 ofAddresses
. IfAddresses
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. Addresses must be sorted lexicographically.
Proto SECP256K1 Transfer Output Specification#
message SECP256K1TransferOutput { uint32 typeID = 1; // 04 bytes uint64 amount = 2; // 08 bytes uint64 locktime = 3; // 08 bytes uint32 threshold = 4; // 04 bytes repeated bytes addresses = 5; // 04 bytes + 20 bytes * len(addresses) }
SECP256K1 Transfer Output Example#
Let’s make a secp256k1 transfer output with:
TypeID
:7
Amount
:12345
Locktime
:54321
Threshold
:1
Addresses
:0x51025c61fbcfc078f69334f834be6dd26d55a955
0xc3344128e060128ede3523a24a461c8943ab0859
[ TypeID <- 0x00000007 Amount <- 0x0000000000003039 Locktime <- 0x000000000000d431 Threshold <- 0x00000001 Addresses <- [ 0x51025c61fbcfc078f69334f834be6dd26d55a955, 0xc3344128e060128ede3523a24a461c8943ab0859, ] ] = [ // typeID: 0x00, 0x00, 0x00, 0x07, // amount: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, // locktime: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, // threshold: 0x00, 0x00, 0x00, 0x01, // number of addresses: 0x00, 0x00, 0x00, 0x02, // addrs[0]: 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, // addrs[1]: 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
NFT Mint Output#
An NFT mint output is an NFT that is owned by a collection of addresses.
What NFT Mint Output Contains#
An NFT Mint output contains a TypeID
, GroupID
, Locktime
, Threshold
, and Addresses
.
TypeID
is the ID for this output type. It is0x0000000a
.GroupID
is an int that specifies the group this NFT is issued to.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 ofAddresses
. IfAddresses
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. Addresses must be sorted lexicographically.
Proto NFT Mint Output Specification#
message NFTMintOutput { uint32 typeID = 1; // 04 bytes uint32 group_id = 2; // 04 bytes uint64 locktime = 3; // 08 bytes uint32 threshold = 4; // 04 bytes repeated bytes addresses = 5; // 04 bytes + 20 bytes * len(addresses) }
NFT Mint Output Example#
Let’s make an NFT mint output with:
TypeID
:10
GroupID
:12345
Locktime
:54321
Threshold
:1
Addresses
:0x51025c61fbcfc078f69334f834be6dd26d55a955
0xc3344128e060128ede3523a24a461c8943ab0859
[ TypeID <- 0x0000000a GroupID <- 0x00003039 Locktime <- 0x000000000000d431 Threshold <- 0x00000001 Addresses <- [ 0x51025c61fbcfc078f69334f834be6dd26d55a955, 0xc3344128e060128ede3523a24a461c8943ab0859, ] ] = [ // TypeID 0x00, 0x00, 0x00, 0x0a, // groupID: 0x00, 0x00, 0x30, 0x39, // locktime: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, // threshold: 0x00, 0x00, 0x00, 0x01, // number of addresses: 0x00, 0x00, 0x00, 0x02, // addrs[0]: 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, // addrs[1]: 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
NFT Transfer Output#
An NFT transfer output is an NFT that is owned by a collection of addresses.
What NFT Transfer Output Contains#
An NFT transfer output contains a TypeID
, GroupID
, Payload
, Locktime
, Threshold
, and Addresses
.
TypeID
is the ID for this output type. It is0x0000000b
.GroupID
is an int that specifies the group this NFT was issued with.Payload
is an arbitrary string of bytes no long longer than 1024 bytes.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 ofAddresses
. IfAddresses
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. Addresses must be sorted lexicographically.
Proto NFT Transfer Output Specification#
message NFTTransferOutput { uint32 typeID = 1; // 04 bytes uint32 group_id = 2; // 04 bytes bytes payload = 3; // 04 bytes + len(payload) uint64 locktime = 4 // 08 bytes uint32 threshold = 5; // 04 bytes repeated bytes addresses = 6; // 04 bytes + 20 bytes * len(addresses) }
NFT Transfer Output Example#
Let’s make an NFT transfer output with:
TypeID
:11
GroupID
:12345
Payload
:NFT Payload
Locktime
:54321
Threshold
:1
Addresses
:0x51025c61fbcfc078f69334f834be6dd26d55a955
0xc3344128e060128ede3523a24a461c8943ab0859
[ TypeID <- 0x0000000b GroupID <- 0x00003039 Payload <- 0x4e4654205061796c6f6164 Locktime <- 0x000000000000d431 Threshold <- 0x00000001 Addresses <- [ 0x51025c61fbcfc078f69334f834be6dd26d55a955, 0xc3344128e060128ede3523a24a461c8943ab0859, ] ] = [ // TypeID: 0x00, 0x00, 0x00, 0x0b, // groupID: 0x00, 0x00, 0x30, 0x39, // length of payload: 0x00, 0x00, 0x00, 0x0b, // payload: 0x4e, 0x46, 0x54, 0x20, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, // locktime: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, // threshold: 0x00, 0x00, 0x00, 0x01, // number of addresses: 0x00, 0x00, 0x00, 0x02, // addrs[0]: 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, // addrs[1]: 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
Inputs#
Inputs have one possible type: SECP256K1TransferInput
.
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 is0x00000005
.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#
message SECP256K1TransferInput { uint32 typeID = 1; // 04 bytes uint64 amount = 2; // 08 bytes repeated uint32 address_indices = 3; // 04 bytes + 04 bytes * len(address_indices) }
SECP256K1 Transfer Input Example#
Let’s make a payment input with:
TypeId
:5
Amount
:123456789
AddressIndices
: [3
,7
]
[ TypeID <- 0x00000005 Amount <- 123456789 = 0x00000000075bcd15, AddressIndices <- [0x00000003, 0x00000007] ] = [ // type id: 0x00, 0x00, 0x00, 0x05, // amount: 0x00, 0x00, 0x00, 0x00, 0x07, 0x5b, 0xcd, 0x15, // length: 0x00, 0x00, 0x00, 0x02, // sig[0] 0x00, 0x00, 0x00, 0x03, // sig[1] 0x00, 0x00, 0x00, 0x07, ]
Operations#
Operations have three possible types: SECP256K1MintOperation
, NFTMintOp
, and NFTTransferOp
.
SECP256K1 Mint Operation#
A secp256k1 mint operation consumes a SECP256K1 mint output, creates a new mint output and sends a transfer output to a new set of owners.
What SECP256K1 Mint Operation Contains#
A secp256k1 Mint operation contains a TypeID
, AddressIndices
, MintOutput
, and TransferOutput
.
TypeID
is the ID for this output type. It is0x00000008
.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.MintOutput
is a SECP256K1 Mint output.TransferOutput
is a SECP256K1 Transfer output.
Proto SECP256K1 Mint Operation Specification#
message SECP256K1MintOperation { uint32 typeID = 1; // 4 bytes repeated uint32 address_indices = 2; // 04 bytes + 04 bytes * len(address_indices) MintOutput mint_output = 3; // size(mint_output TransferOutput transfer_output = 4; // size(transfer_output) }
SECP256K1 Mint Operation Example#
Let’s make a secp256k1 mint operation with:
TypeId
:8
AddressIndices
:0x00000003
0x00000007
MintOutput
:"Example SECP256K1 Mint Output from above"
TransferOutput
:"Example SECP256K1 Transfer Output from above"
[ TypeID <- 0x00000008 AddressIndices <- [0x00000003, 0x00000007] MintOutput <- 0x00000006000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c89 TransferOutput <- 0x000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859 ] = [ // typeID 0x00, 0x00, 0x00, 0x08, // number of address_indices: 0x00, 0x00, 0x00, 0x02, // address_indices[0]: 0x00, 0x00, 0x00, 0x03, // address_indices[1]: 0x00, 0x00, 0x00, 0x07, // mint output 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, // transfer output 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
NFT Mint Op#
An NFT mint operation consumes an NFT mint output and sends an unspent output to a new set of owners.
What NFT Mint Op Contains#
An NFT mint operation contains a TypeID
, AddressIndices
, GroupID
, Payload
, and Output
of addresses.
TypeID
is the ID for this operation type. It is0x0000000c
.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.GroupID
is an int that specifies the group this NFT is issued to.Payload
is an arbitrary string of bytes no longer than 1024 bytes.Output
is not aTransferableOutput
, but rather is a lock time, threshold, and an array of unique addresses that correspond to the private keys that can be used to spend this output. Addresses must be sorted lexicographically.
Proto NFT Mint Op Specification#
message NFTMintOp { uint32 typeID = 1; // 04 bytes repeated uint32 address_indices = 2; // 04 bytes + 04 bytes * len(address_indices) uint32 group_id = 3; // 04 bytes bytes payload = 4; // 04 bytes + len(payload) repeated bytes outputs = 5; // 04 bytes + size(outputs) }
NFT Mint Op Example#
Let’s make an NFT mint operation with:
TypeId
:12
AddressIndices
:0x00000003
0x00000007
GroupID
:12345
Payload
:0x431100
Locktime
:54321
Threshold
:1
Addresses
:0xc3344128e060128ede3523a24a461c8943ab0859
[ TypeID <- 0x0000000c AddressIndices <- [ 0x00000003, 0x00000007, ] GroupID <- 0x00003039 Payload <- 0x431100 Locktime <- 0x000000000000d431 Threshold <- 0x00000001 Addresses <- [ 0xc3344128e060128ede3523a24a461c8943ab0859 ] ] = [ // Type ID 0x00, 0x00, 0x00, 0x0c, // number of address indices: 0x00, 0x00, 0x00, 0x02, // address index 0: 0x00, 0x00, 0x00, 0x03, // address index 1: 0x00, 0x00, 0x00, 0x07, // groupID: 0x00, 0x00, 0x30, 0x39, // length of payload: 0x00, 0x00, 0x00, 0x03, // payload: 0x43, 0x11, 0x00, // number of outputs: 0x00, 0x00, 0x00, 0x01, // outputs[0] // locktime: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, // threshold: 0x00, 0x00, 0x00, 0x01, // number of addresses: 0x00, 0x00, 0x00, 0x01, // addrs[0]: 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
NFT Transfer Op#
An NFT transfer operation sends an unspent NFT transfer output to a new set of owners.
What NFT Transfer Op Contains#
An NFT transfer operation contains a TypeID
, AddressIndices
and an untyped NFTTransferOutput
.
TypeID
is the ID for this output type. It is0x0000000d
.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.NFTTransferOutput
is the output of this operation and must be an NFT Transfer Output. This output doesn’t have theTypeId
, because the type is known by the context of being in this operation.
Proto NFT Transfer Op Specification#
message NFTTransferOp { uint32 typeID = 1; // 04 bytes repeated uint32 address_indices = 2; // 04 bytes + 04 bytes * len(address_indices) uint32 group_id = 3; // 04 bytes bytes payload = 4; // 04 bytes + len(payload) uint64 locktime = 5; // 08 bytes uint32 threshold = 6; // 04 bytes repeated bytes addresses = 7; // 04 bytes + 20 bytes * len(addresses) }
NFT Transfer Op Example#
Let’s make an NFT transfer operation with:
TypeID
:13
AddressIndices
:0x00000007
0x00000003
GroupID
:12345
Payload
:0x431100
Locktime
:54321
Threshold
:1
Addresses
:0xc3344128e060128ede3523a24a461c8943ab0859
0x51025c61fbcfc078f69334f834be6dd26d55a955
[ TypeID <- 0x0000000d AddressIndices <- [ 0x00000007, 0x00000003, ] GroupID <- 0x00003039 Payload <- 0x431100 Locktime <- 0x000000000000d431 Threshold <- 00000001 Addresses <- [ 0x51025c61fbcfc078f69334f834be6dd26d55a955, 0xc3344128e060128ede3523a24a461c8943ab0859, ] ] = [ // Type ID 0x00, 0x00, 0x00, 0x0d, // number of address indices: 0x00, 0x00, 0x00, 0x02, // address index 0: 0x00, 0x00, 0x00, 0x07, // address index 1: 0x00, 0x00, 0x00, 0x03, // groupID: 0x00, 0x00, 0x30, 0x39, // length of payload: 0x00, 0x00, 0x00, 0x03, // payload: 0x43, 0x11, 0x00, // locktime: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, // threshold: 0x00, 0x00, 0x00, 0x01, // number of addresses: 0x00, 0x00, 0x00, 0x02, // addrs[0]: 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, // addrs[1]: 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
Initial State#
Initial state describes the initial state of an asset when it is created. It contains the ID of the feature extension that the asset uses, and a variable length array of outputs that denote the genesis UTXO set of the asset.
What Initial State Contains#
Initial state contains a FxID
and an array of Output
.
FxID
is an int that defines which feature extension this state is part of. For SECP256K1 assets, this is0x00000000
. For NFT assets, this is0x00000001
.Outputs
is a variable length array of outputs, as defined above.
Proto Initial State Specification#
message InitialState { uint32 fx_id = 1; // 04 bytes repeated Output outputs = 2; // 04 + size(outputs) bytes }
Initial State Example#
Let’s make an initial state:
FxID
:0x00000000
InitialState
:["Example SECP256K1 Transfer Output from above"]
[ FxID <- 0x00000000 InitialState <- [ 0x000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859, ] ] = [ // fxID: 0x00, 0x00, 0x00, 0x00, // num outputs: 0x00, 0x00, 0x00, 0x01, // output: 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
Credentials#
Credentials have two possible types: SECP256K1Credential
, and NFTCredential
.
Each credential is paired with an Input or Operation. The order of the
credentials match the order of the inputs or operations.
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 is0x00000009
.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#
message SECP256K1Credential { uint32 typeID = 1; // 4 bytes repeated bytes signatures = 2; // 4 bytes + 65 bytes * len(signatures) }
SECP256K1 Credential Example#
Let’s make a payment input with:
TypeID
:9
signatures
:0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1e1d1f202122232425262728292a2b2c2e2d2f303132333435363738393a3b3c3d3e3f00
0x404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5e5d5f606162636465666768696a6b6c6e6d6f707172737475767778797a7b7c7d7e7f00
[ TypeID <- 0x00000009 Signatures <- [ 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1e1d1f202122232425262728292a2b2c2e2d2f303132333435363738393a3b3c3d3e3f00, 0x404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5e5d5f606162636465666768696a6b6c6e6d6f707172737475767778797a7b7c7d7e7f00, ] ] = [ // Type ID 0x00, 0x00, 0x00, 0x09, // length: 0x00, 0x00, 0x00, 0x02, // sig[0] 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1d, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2e, 0x2d, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, // sig[1] 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5e, 0x5d, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6e, 0x6d, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x00, ]
NFT Credential#
An NFT credential is the same as an secp256k1
credential with a
different TypeID. The TypeID for an NFT credential is 0x0000000e
.
Unsigned Transactions#
Unsigned transactions contain the full content of a transaction with only the
signatures missing. Unsigned transactions have four possible types:
CreateAssetTx
,
OperationTx
,
ImportTx
,
and
ExportTx
.
They all embed
BaseTx
, which
contains common fields and operations.
Unsigned BaseTx#
What Base TX Contains#
A base TX contains a TypeID
, NetworkID
, BlockchainID
, Outputs
, Inputs
, and Memo
.
TypeID
is the ID for this type. It is0x00000000
.NetworkID
is an int that defines which network this transaction is meant to be issued to. This value is meant to support transaction routing and is not designed for replay attack prevention.BlockchainID
is a 32-byte array that defines which blockchain this transaction was issued to. This is used for replay attack prevention for transactions that could potentially be valid across network or blockchain.Outputs
is an array of transferable output objects. Outputs must be sorted lexicographically by their serialized representation. The total quantity of the assets created in these outputs must be less than or equal to the total quantity of each asset consumed in the inputs minus the transaction fee.Inputs
is an array of transferable input objects. Inputs must be sorted and unique. Inputs are sorted first lexicographically by theirTxID
and then by theUTXOIndex
from low to high. If there are inputs that have the sameTxID
andUTXOIndex
, then the transaction is invalid as this would result in a double spend.Memo
Memo field contains arbitrary bytes, up to 256 bytes.
Proto Base TX Specification#
message BaseTx { uint32 typeID = 1; // 04 bytes uint32 network_id = 2; // 04 bytes bytes blockchain_id = 3; // 32 bytes repeated Output outputs = 4; // 04 bytes + size(outs) repeated Input inputs = 5; // 04 bytes + size(ins) bytes memo = 6; // 04 bytes + size(memo) }
Base TX Example#
Let’s make an base TX that uses the inputs and outputs from the previous examples:
TypeID
:0
NetworkID
:4
BlockchainID
:0xffffffffeeeeeeeeddddddddcccccccbbbbbbbbaaaaaaaa9999999988888888
Outputs
:"Example Transferable Output as defined above"
Inputs
:"Example Transferable Input as defined above"
Memo
:0x00010203
[ TypeID <- 0x00000000 NetworkID <- 0x00000004 BlockchainID <- 0xffffffffeeeeeeeeddddddddcccccccbbbbbbbbaaaaaaaa9999999988888888 Outputs <- [ 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859 ] Inputs <- [ 0xf1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd15000000020000000700000003 ] Memo <- 0x00010203 ] = [ // typeID 0x00, 0x00, 0x00, 0x00, // networkID: 0x00, 0x00, 0x00, 0x04, // blockchainID: 0xff, 0xff, 0xff, 0xff, 0xee, 0xee, 0xee, 0xee, 0xdd, 0xdd, 0xdd, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc, 0xbb, 0xbb, 0xbb, 0xbb, 0xaa, 0xaa, 0xaa, 0xaa, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88, 0x88, // number of outputs: 0x00, 0x00, 0x00, 0x01, // transferable output: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, // number of inputs: 0x00, 0x00, 0x00, 0x01, // transferable input: 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x41, 0x31, 0x21, 0x11, 0x01, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x07, 0x5b, 0xcd, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, // Memo length: 0x00, 0x00, 0x00, 0x04, // Memo: 0x00, 0x01, 0x02, 0x03, ]
Unsigned CreateAssetTx#
What Unsigned Create Asset TX Contains#
An unsigned create asset TX contains a BaseTx
, Name
, Symbol
,
Denomination
, and InitialStates
. The TypeID
is 0x00000001
.
BaseTx
Name
is a human readable string that defines the name of the asset this transaction will create. The name is not guaranteed to be unique. The name must consist of only printable ASCII characters and must be no longer than 128 characters.Symbol
is a human readable string that defines the symbol of the asset this transaction will create. The symbol is not guaranteed to be unique. The symbol must consist of only printable ASCII characters and must be no longer than 4 characters.Denomination
is a byte that defines the divisibility of the asset this transaction will create. For example, the DJTX token is divisible into billionths. Therefore, the denomination of the DJTX token is 9. The denomination must be no more than 32.InitialStates
is a variable length array that defines the feature extensions this asset supports, and the initial state of those feature extensions.
Proto Unsigned Create Asset TX Specification#
message CreateAssetTx { BaseTx base_tx = 1; // size(base_tx) string name = 2; // 2 bytes + len(name) name symbol = 3; // 2 bytes + len(symbol) uint8 denomination = 4; // 1 bytes repeated InitialState initial_states = 5; // 4 bytes + size(initial_states) }
Unsigned Create Asset TX Example#
Let’s make an unsigned base TX that uses the inputs and outputs from the previous examples:
BaseTx
:"Example BaseTx as defined above with ID set to 1"
Name
:Volatility Index
Symbol
:VIX
Denomination
:2
InitialStates
:"Example Initial State as defined above"
[ BaseTx <- 0x0000000100000004ffffffffeeeeeeeeddddddddccccccccbbbbbbbbaaaaaaaa999999998888888800000001000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab085900000001f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd150000000200000007000000030000000400010203 Name <- 0x0010566f6c6174696c69747920496e646578 Symbol <- 0x0003564958 Denomination <- 0x02 InitialStates <- [ 0x0000000000000001000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859, ] ] = [ // base tx: 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xee, 0xee, 0xee, 0xee, 0xdd, 0xdd, 0xdd, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc, 0xbb, 0xbb, 0xbb, 0xbb, 0xaa, 0xaa, 0xaa, 0xaa, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, 0x00, 0x00, 0x00, 0x01, 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x41, 0x31, 0x21, 0x11, 0x01, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x07, 0x5b, 0xcd, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03 // name: 0x00, 0x10, 0x56, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x49, 0x6e, 0x64, 0x65, 0x78, // symbol length: 0x00, 0x03, // symbol: 0x56, 0x49, 0x58, // denomination: 0x02, // number of InitialStates: 0x00, 0x00, 0x00, 0x01, // InitialStates[0]: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
Unsigned OperationTx#
What Unsigned Operation TX Contains#
An unsigned operation TX contains a BaseTx
, and Ops
. The TypeID
for this type is 0x00000002
.
BaseTx
Ops
is a variable-length array of Transferable Operations.
Proto Unsigned Operation TX Specification#
message OperationTx { BaseTx base_tx = 1; // size(base_tx) repeated TransferOp ops = 2; // 4 bytes + size(ops) }
Unsigned Operation TX Example#
Let’s make an unsigned operation TX that uses the inputs and outputs from the previous examples:
BaseTx
:"Example BaseTx above" with TypeID set to 2
Ops
: ["Example Transferable Operation as defined above"
]
[ BaseTx <- 0x0000000200000004ffffffffeeeeeeeeddddddddccccccccbbbbbbbbaaaaaaaa999999998888888800000001000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab085900000001f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd150000000200000007000000030000000400010203 Ops <- [ 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f00000001f1e1d1c1b1a191817161514131211101f0e0d0c0b0a090807060504030201000000000050000000d0000000200000003000000070000303900000003431100000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859, ] ] = [ // base tx: 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xee, 0xee, 0xee, 0xee, 0xdd, 0xdd, 0xdd, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc, 0xbb, 0xbb, 0xbb, 0xbb, 0xaa, 0xaa, 0xaa, 0xaa, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, 0x00, 0x00, 0x00, 0x01, 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x41, 0x31, 0x21, 0x11, 0x01, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x07, 0x5b, 0xcd, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03 // number of operations: 0x00, 0x00, 0x00, 0x01, // transfer operation: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x01, 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x41, 0x31, 0x21, 0x11, 0x01, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x03, 0x43, 0x11, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
Unsigned ImportTx#
What Unsigned Import TX Contains#
An unsigned import TX contains a BaseTx
, SourceChain
and Ins
. * The TypeID
for this type is 0x00000003
.
BaseTx
SourceChain
is a 32-byte source blockchain ID.Ins
is a variable length array of Transferable Inputs.
Proto Unsigned Import TX Specification#
message ImportTx { BaseTx base_tx = 1; // size(base_tx) bytes source_chain = 2; // 32 bytes repeated TransferIn ins = 3; // 4 bytes + size(ins) }
Unsigned Import TX Example#
Let’s make an unsigned import TX that uses the inputs from the previous examples:
BaseTx
:"Example BaseTx as defined above"
, but withTypeID
set to3
SourceChain
:0x0000000000000000000000000000000000000000000000000000000000000000
Ins
:"Example SECP256K1 Transfer Input as defined above"
[ BaseTx <- 0x0000000300000004ffffffffeeeeeeeeddddddddccccccccbbbbbbbbaaaaaaaa999999998888888800000001000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab085900000001f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd150000000200000007000000030000000400010203 SourceChain <- 0x0000000000000000000000000000000000000000000000000000000000000000 Ins <- [ f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd15000000020000000300000007, ] ] = [ // base tx: 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xee, 0xee, 0xee, 0xee, 0xdd, 0xdd, 0xdd, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc, 0xbb, 0xbb, 0xbb, 0xbb, 0xaa, 0xaa, 0xaa, 0xaa, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, 0x00, 0x00, 0x00, 0x01, 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x41, 0x31, 0x21, 0x11, 0x01, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x07, 0x5b, 0xcd, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03 // source chain: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // input count: 0x00, 0x00, 0x00, 0x01, // txID: 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x41, 0x31, 0x21, 0x11, 0x01, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, // utxoIndex: 0x00, 0x00, 0x00, 0x05, // assetID: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, // input: 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x07, 0x5b, 0xcd, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, ]
Unsigned ExportTx#
What Unsigned Export TX Contains#
An unsigned export TX contains a BaseTx
, DestinationChain
, and Outs
. The
TypeID
for this type is 0x00000004
.
DestinationChain
is the 32 byte ID of the chain where the funds are being exported to.Outs
is a variable length array of Transferable Outputs.
Proto Unsigned Export TX Specification#
message ExportTx { BaseTx base_tx = 1; // size(base_tx) bytes destination_chain = 2; // 32 bytes repeated TransferOut outs = 3; // 4 bytes + size(outs) }
Unsigned Export TX Example#
Let’s make an unsigned export TX that uses the outputs from the previous examples:
BaseTx
:"Example BaseTx as defined above"
, but withTypeID
set to4
DestinationChain
:0x0000000000000000000000000000000000000000000000000000000000000000
Outs
:"Example SECP256K1 Transfer Output as defined above"
[ BaseTx <- 0x0000000400000004ffffffffeeeeeeeeddddddddccccccccbbbbbbbbaaaaaaaa999999998888888800000001000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab085900000001f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd150000000200000007000000030000000400010203 DestinationChain <- 0x0000000000000000000000000000000000000000000000000000000000000000 Outs <- [ 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859, ] ] = [ // base tx: 0x00, 0x00, 0x00, 0x04 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xee, 0xee, 0xee, 0xee, 0xdd, 0xdd, 0xdd, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc, 0xbb, 0xbb, 0xbb, 0xbb, 0xaa, 0xaa, 0xaa, 0xaa, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, 0x00, 0x00, 0x00, 0x01, 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x41, 0x31, 0x21, 0x11, 0x01, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x07, 0x5b, 0xcd, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03 // destination_chain: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // outs[] count: 0x00, 0x00, 0x00, 0x01, // assetID: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, // output: 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
Signed Transaction#
A signed transaction is an unsigned transaction with the addition of an array of credentials.
What Signed Transaction Contains#
A signed transaction contains a CodecID
, UnsignedTx
, and Credentials
.
CodecID
The only current valid codec id is00 00
.UnsignedTx
is an unsigned transaction, as described above.Credentials
is an array of credentials. Each credential will be paired with the input in the same index at this credential.
Proto Signed Transaction Specification#
message Tx { uint16 codec_id = 1; // 2 bytes UnsignedTx unsigned_tx = 2; // size(unsigned_tx) repeated Credential credentials = 3; // 4 bytes + size(credentials) }
Signed Transaction Example#
Let’s make a signed transaction that uses the unsigned transaction and credentials from the previous examples.
CodecID
:0
UnsignedTx
:0x0000000100000004ffffffffeeeeeeeeddddddddccccccccbbbbbbbbaaaaaaaa999999998888888800000001000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab085900000001f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd150000000200000007000000030000000400010203
Credentials
0x0000000900000002000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1e1d1f202122232425262728292a2b2c2e2d2f303132333435363738393a3b3c3d3e3f00404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5e5d5f606162636465666768696a6b6c6e6d6f707172737475767778797a7b7c7d7e7f00
[ CodecID <- 0x0000 UnsignedTx <- 0x0000000100000004ffffffffeeeeeeeeddddddddccccccccbbbbbbbbaaaaaaaa999999998888888800000001000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab085900000001f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd150000000200000007000000030000000400010203 Credentials <- [ 0x0000000900000002000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1e1d1f202122232425262728292a2b2c2e2d2f303132333435363738393a3b3c3d3e3f00404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5e5d5f606162636465666768696a6b6c6e6d6f707172737475767778797a7b7c7d7e7f00, ] ] = [ // Codec ID 0x00, 0x00, // unsigned transaction: 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xee, 0xee, 0xee, 0xee, 0xdd, 0xdd, 0xdd, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc, 0xbb, 0xbb, 0xbb, 0xbb, 0xaa, 0xaa, 0xaa, 0xaa, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, 0x00, 0x00, 0x00, 0x01, 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x41, 0x31, 0x21, 0x11, 0x01, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x07, 0x5b, 0xcd, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03 // number of credentials: 0x00, 0x00, 0x00, 0x01, // credential[0]: 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1d, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2e, 0x2d, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5e, 0x5d, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6e, 0x6d, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 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 validCodecID
is00 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 byTxID
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. Valid output types are SECP Mint Output, SECP Transfer Output, NFT Mint Output, NFT Transfer Output.
Proto UTXO Specification#
message Utxo { uint16 codec_id = 1; // 02 bytes bytes tx_id = 2; // 32 bytes uint32 output_index = 3; // 04 bytes bytes asset_id = 4; // 32 bytes Output output = 5; // size(output) }
UTXO Examples#
Let’s make a UTXO with a SECP Mint Output:
CodecID
:0
TxID
:0x47c92ed62d18e3cccda512f60a0d5b1e939b6ab73fb2d011e5e306e79bd0448f
UTXOIndex
:0
=0x00000001
AssetID
:0x47c92ed62d18e3cccda512f60a0d5b1e939b6ab73fb2d011e5e306e79bd0448f
Output
:0x00000006000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c6276aa2a
[ CodecID <- 0x0000 TxID <- 0x47c92ed62d18e3cccda512f60a0d5b1e939b6ab73fb2d011e5e306e79bd0448f UTXOIndex <- 0x00000001 AssetID <- 0x47c92ed62d18e3cccda512f60a0d5b1e939b6ab73fb2d011e5e306e79bd0448f Output <- 00000006000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c6276aa2a ] = [ // codecID: 0x00, 0x00, // txID: 0x47, 0xc9, 0x2e, 0xd6, 0x2d, 0x18, 0xe3, 0xcc, 0xcd, 0xa5, 0x12, 0xf6, 0x0a, 0x0d, 0x5b, 0x1e, 0x93, 0x9b, 0x6a, 0xb7, 0x3f, 0xb2, 0xd0, 0x11, 0xe5, 0xe3, 0x06, 0xe7, 0x9b, 0xd0, 0x44, 0x8f, // utxo index: 0x00, 0x00, 0x00, 0x01, // assetID: 0x47, 0xc9, 0x2e, 0xd6, 0x2d, 0x18, 0xe3, 0xcc, 0xcd, 0xa5, 0x12, 0xf6, 0x0a, 0x0d, 0x5b, 0x1e, 0x93, 0x9b, 0x6a, 0xb7, 0x3f, 0xb2, 0xd0, 0x11, 0xe5, 0xe3, 0x06, 0xe7, 0x9b, 0xd0, 0x44, 0x8f, // secp mint output: 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x62, 0x76, 0xaa, 0x2a, ]
Let’s make a UTXO with a SECP Transfer Output from the signed transaction created above:
CodecID
:0
TxID
:0xf966750f438867c3c9828ddcdbe660e21ccdbb36a9276958f011ba472f75d4e7
UTXOIndex
:0
=0x00000000
AssetID
:0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Output
:"Example SECP256K1 Transferable Output as defined above"
[ CodecID <- 0x0000 TxID <- 0xf966750f438867c3c9828ddcdbe660e21ccdbb36a9276958f011ba472f75d4e7 UTXOIndex <- 0x00000000 AssetID <- 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f Output <- 0x000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859 ] = [ // codecID: 0x00, 0x00, // txID: 0xf9, 0x66, 0x75, 0x0f, 0x43, 0x88, 0x67, 0xc3, 0xc9, 0x82, 0x8d, 0xdc, 0xdb, 0xe6, 0x60, 0xe2, 0x1c, 0xcd, 0xbb, 0x36, 0xa9, 0x27, 0x69, 0x58, 0xf0, 0x11, 0xba, 0x47, 0x2f, 0x75, 0xd4, 0xe7, // utxo index: 0x00, 0x00, 0x00, 0x00, // assetID: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, // secp transfer output: 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, ]
Let’s make a UTXO with an NFT Mint Output:
CodecID
:0
TxID
:0x03c686efe8d80c519f356929f6da945f7ff90378f0044bb0e1a5d6c1ad06bae7
UTXOIndex
:0
=0x00000001
AssetID
:0x03c686efe8d80c519f356929f6da945f7ff90378f0044bb0e1a5d6c1ad06bae7
Output
:0x0000000a00000000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c6276aa2a
[ CodecID <- 0x0000 TxID <- 0x03c686efe8d80c519f356929f6da945f7ff90378f0044bb0e1a5d6c1ad06bae7 UTXOIndex <- 0x00000001 AssetID <- 0x03c686efe8d80c519f356929f6da945f7ff90378f0044bb0e1a5d6c1ad06bae7 Output <- 0000000a00000000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c6276aa2a ] = [ // codecID: 0x00, 0x00, // txID: 0x03, 0xc6, 0x86, 0xef, 0xe8, 0xd8, 0x0c, 0x51, 0x9f, 0x35, 0x69, 0x29, 0xf6, 0xda, 0x94, 0x5f, 0x7f, 0xf9, 0x03, 0x78, 0xf0, 0x04, 0x4b, 0xb0, 0xe1, 0xa5, 0xd6, 0xc1, 0xad, 0x06, 0xba, 0xe7, // utxo index: 0x00, 0x00, 0x00, 0x01, // assetID: 0x03, 0xc6, 0x86, 0xef, 0xe8, 0xd8, 0x0c, 0x51, 0x9f, 0x35, 0x69, 0x29, 0xf6, 0xda, 0x94, 0x5f, 0x7f, 0xf9, 0x03, 0x78, 0xf0, 0x04, 0x4b, 0xb0, 0xe1, 0xa5, 0xd6, 0xc1, 0xad, 0x06, 0xba, 0xe7, // nft mint output: 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x62, 0x76, 0xaa, 0x2a, ]
Let’s make a UTXO with an NFT Transfer Output:
CodecID
:0
TxID
:0xa68f794a7de7bdfc5db7ba5b73654304731dd586bbf4a6d7b05be6e49de2f936
UTXOIndex
:0
=0x00000001
AssetID
:0x03c686efe8d80c519f356929f6da945f7ff90378f0044bb0e1a5d6c1ad06bae7
Output
:0x0000000b000000000000000b4e4654205061796c6f6164000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c6276aa2a
[ CodecID <- 0x0000 TxID <- 0xa68f794a7de7bdfc5db7ba5b73654304731dd586bbf4a6d7b05be6e49de2f936 UTXOIndex <- 0x00000001 AssetID <- 0x03c686efe8d80c519f356929f6da945f7ff90378f0044bb0e1a5d6c1ad06bae7 Output <- 0000000b000000000000000b4e4654205061796c6f6164000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c6276aa2a ] = [ // codecID: 0x00, 0x00, // txID: 0xa6, 0x8f, 0x79, 0x4a, 0x7d, 0xe7, 0xbd, 0xfc, 0x5d, 0xb7, 0xba, 0x5b, 0x73, 0x65, 0x43, 0x04, 0x73, 0x1d, 0xd5, 0x86, 0xbb, 0xf4, 0xa6, 0xd7, 0xb0, 0x5b, 0xe6, 0xe4, 0x9d, 0xe2, 0xf9, 0x36, // utxo index: 0x00, 0x00, 0x00, 0x01, // assetID: 0x03, 0xc6, 0x86, 0xef, 0xe8, 0xd8, 0x0c, 0x51, 0x9f, 0x35, 0x69, 0x29, 0xf6, 0xda, 0x94, 0x5f, 0x7f, 0xf9, 0x03, 0x78, 0xf0, 0x04, 0x4b, 0xb0, 0xe1, 0xa5, 0xd6, 0xc1, 0xad, 0x06, 0xba, 0xe7, // nft transfer output: 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x4e, 0x46, 0x54, 0x20, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x62, 0x76, 0xaa, 0x2a, ]
GenesisAsset#
An asset to be issued in an instance of the AVM's Genesis
What GenesisAsset Contains#
An instance of a GenesisAsset contains an Alias
, NetworkID
, BlockchainID
,
Outputs
, Inputs
, Memo
, Name
, Symbol
, Denomination
, and
InitialStates
.
Alias
is the alias for this asset.NetworkID
defines which network this transaction is meant to be issued to. This value is meant to support transaction routing and is not designed for replay attack prevention.BlockchainID
is the ID (32-byte array) that defines which blockchain this transaction was issued to. This is used for replay attack prevention for transactions that could potentially be valid across network or blockchain.Outputs
is an array of transferable output objects. Outputs must be sorted lexicographically by their serialized representation. The total quantity of the assets created in these outputs must be less than or equal to the total quantity of each asset consumed in the inputs minus the transaction fee.Inputs
is an array of transferable input objects. Inputs must be sorted and unique. Inputs are sorted first lexicographically by theirTxID
and then by theUTXOIndex
from low to high. If there are inputs that have the sameTxID
andUTXOIndex
, then the transaction is invalid as this would result in a double spend.Memo
is a memo field that contains arbitrary bytes, up to 256 bytes.Name
is a human readable string that defines the name of the asset this transaction will create. The name is not guaranteed to be unique. The name must consist of only printable ASCII characters and must be no longer than 128 characters.Symbol
is a human readable string that defines the symbol of the asset this transaction will create. The symbol is not guaranteed to be unique. The symbol must consist of only printable ASCII characters and must be no longer than 4 characters.Denomination
is a byte that defines the divisibility of the asset this transaction will create. For example, the DJTX token is divisible into billionths. Therefore, the denomination of the DJTX token is 9. The denomination must be no more than 32.InitialStates
is a variable length array that defines the feature extensions this asset supports, and the initial state of those feature extensions.
Proto GenesisAsset Specification#
message GenesisAsset { string alias = 1; // 2 bytes + len(alias) uint32 network_id = 2; // 04 bytes bytes blockchain_id = 3; // 32 bytes repeated Output outputs = 4; // 04 bytes + size(outputs) repeated Input inputs = 5; // 04 bytes + size(inputs) bytes memo = 6; // 04 bytes + size(memo) string name = 7; // 2 bytes + len(name) name symbol = 8; // 2 bytes + len(symbol) uint8 denomination = 9; // 1 bytes repeated InitialState initial_states = 10; // 4 bytes + size(initial_states) }
GenesisAsset Example#
Let’s make a GenesisAsset:
Alias
:asset1
NetworkID
:12345
BlockchainID
:0x0000000000000000000000000000000000000000000000000000000000000000
Outputs
: []Inputs
: []Memo
:2Zc54v4ek37TEwu4LiV3j41PUMRd6acDDU3ZCVSxE7X
Name
:asset1
Symbol
:MFCA
Denomination
:1
InitialStates
:"Example Initial State as defined above"
[ Alias <- 0x617373657431 NetworkID <- 0x00003039 BlockchainID <- 0x0000000000000000000000000000000000000000000000000000000000000000 Outputs <- [] Inputs <- [] Memo <- 0x66x726f6d20736e6f77666c616b6520746f206176616c616e636865 Name <- 0x617373657431 Symbol <- 0x66x726f6d20736e6f77666c616b6520746f206176616c616e636865 Denomination <- 0x66x726f6d20736e6f77666c616b6520746f206176616c616e636865 InitialStates <- [ 0x0000000000000001000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859 ] ] = [ // asset alias len: 0x00, 0x06, // asset alias: 0x61, 0x73, 0x73, 0x65, 0x74, 0x31, // network_id: 0x00, 0x00, 0x30, 0x39, // blockchain_id: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // output_len: 0x00, 0x00, 0x00, 0x00, // input_len: 0x00, 0x00, 0x00, 0x00, // memo_len: 0x00, 0x00, 0x00, 0x1b, // memo: 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x73, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, // asset_name_len: 0x00, 0x0f, // asset_name: 0x6d, 0x79, 0x46, 0x69, 0x78, 0x65, 0x64, 0x43, 0x61, 0x70, 0x41, 0x73, 0x73, 0x65, 0x74, // symbol_len: 0x00, 0x04, // symbol: 0x4d, 0x46, 0x43, 0x41, // denomination: 0x07, // number of InitialStates: 0x00, 0x00, 0x00, 0x01, // InitialStates[0]: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59, ]
Vertex#
A vertex is a collection of transactions. It's the DAG equivalent of a block in a linear blockchain.
What Vertex Contains#
A vertex contains a ChainID
, Height
, Epoch
, ParentIDs
,
TransactionCount
, TransactionSize
, Transactions
, and Restrictions
.
ChainID
is the ID of the chain this vertex exists on.Height
is the maximum height of a parent vertex plus 1.Epoch
is the epoch this vertex belongs to.ParentIDs
are the IDs of this vertex's parents.TransactionCount
is the total number of transactions in this vertex.TransactionSize
is the total size of the transactions in this vertex.Transactions
are the transactions in this vertex.Restrictions
are IDs of transactions that must be accepted in the same epoch as this vertex or an earlier one.
Proto Vertex Specification#
message AzimuthId { uint16 codec_id = 1; // 04 bytes bytes chain_id = 2; // 32 bytes uint64 height = 3; // 08 bytes uint32 epoch = 4; // 04 bytes repeated bytes parent_ids = 5; // 04 bytes + 32 bytes * count(parent_ids) uint32 tx_count = 5; // 04 bytes uint32 txs_size = 6; // 04 bytes repeated bytes transactions = 9; // 04 bytes + size(transactions) repeated bytes restrictions = 10; // 04 bytes + size(restrictions) }
AzimuthId Example#
Let’s make an AzimuthId:
CodecID
:0x0000
ChainID
:0xd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf
Height
:3
Epoch
:0
ParentIDs
: [0x73fa32c486fe9feeb392ee374530c6fe076b08a111fd58e974e7f903a52951d2
]Transactions
:[Example BaseTx as defined above]
Restrictions
: []
[ CodecID <- 0x0000 ChainID <- 0xd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf Height <- 0x0000000000000003 Epoch <- 0x00000000 ParentIDs <- [0x73fa32c486fe9feeb392ee374530c6fe076b08a111fd58e974e7f903a52951d2] Transactions <- [Example BaseTx defined above] Restrictions <- [] ] = [ // codec id 00 00 // chain id d8 91 ad 56 05 6d 9c 01 f1 8f 43 f5 8b 5c 78 4a d0 7a 4a 49 cf 3d 1f 11 62 38 04 b5 cb a2 c6 bf // height 00 00 00 00 00 00 00 03 // epoch 00 00 00 00 // num parent IDs 00 00 00 01 // parent id 1 73 fa 32 c4 86 fe 9f ee b3 92 ee 37 45 30 c6 fe 07 6b 08 a1 11 fd 58 e9 74 e7 f9 03 a5 29 51 d2 // num txs 00 00 00 01 // size of the transaction 00 00 01 7b // base tx from above [omitted for brevity] // num restrictions 00 00 00 00 ]