Coreth Atomic Transaction Format
This page is meant to be the single source of truth for how we serialize atomic transactions in Coreth
. This document uses the primitive serialization 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 Coreth 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 nAVAX for AVAX 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.
Gantt EVM Input Specificationβ
+----------+----------+-------------------------+
| address : [20]byte | 20 bytes |
+----------+----------+-------------------------+
| amount : uint64 | 08 bytes |
+----------+----------+-------------------------+
| asset_id : [32]byte | 32 bytes |
+----------+----------+-------------------------+
| nonce : uint64 | 08 bytes |
+----------+----------+-------------------------+
| 68 bytes |
+-------------------------+
Proto EVM Input Specificationβ
message {
bytes address = 1; // 20 bytes
uint64 amount = 2; // 08 bytes
bytes assetID = 3; // 32 bytes
uint64 nonce = 4; // 08 bytes
}
EVM Input Exampleβ
Let's make an EVM Input:
Address: 0x8db97c7cece249c2b98bdc0226cc4c2a57bf52fc
Amount: 2000000
AssetID: 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Nonce: 0
[
Address <- 0x8db97c7cece249c2b98bdc0226cc4c2a57bf52fc,
Amount <- 0x00000000001e8480
AssetID <- 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
Nonce <- 0x0000000000000000
]
=
[
// address:
0x8d, 0xb9, 0x7c, 0x7c, 0xec, 0xe2, 0x49, 0xc2,
0xb9, 0x8b, 0xdc, 0x02, 0x26, 0xcc, 0x4c, 0x2a,
0x57, 0xbf, 0x52, 0xfc,
// amount:
0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x84, 0x80,
// assetID:
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
// nonce:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]
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 aSECP256K1TransferInput
, as defined below.
Gantt Transferable Input Specificationβ
+------------+----------+------------------------+
| tx_id : [32]byte | 32 bytes |
+------------+----------+------------------------+
| utxo_index : int | 04 bytes |
+------------+----------+------------------------+
| asset_id : [32]byte | 32 bytes |
+------------+----------+------------------------+
| input : Input | size(input) bytes |
+------------+----------+------------------------+
| 68 + size(input) bytes |
+------------------------+
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: 0x6613a40dcdd8d22ea4aa99a4c84349056317cf550b6685e045e459954f258e59
UTXOIndex: 1
AssetID: 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
Input: "Example SECP256K1 Transfer Input from below"
[
TxID <- 0x6613a40dcdd8d22ea4aa99a4c84349056317cf550b6685e045e459954f258e59
UTXOIndex <- 0x00000001
AssetID <- 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
Input <- 0x0000000500000000075bcd15000000020000000700000003
]
=
[
// txID:
0x66, 0x13, 0xa4, 0x0d, 0xcd, 0xd8, 0xd2, 0x2e,
0xa4, 0xaa, 0x99, 0xa4, 0xc8, 0x43, 0x49, 0x05,
0x63, 0x17, 0xcf, 0x55, 0x0b, 0x66, 0x85, 0xe0,
0x45, 0xe4, 0x59, 0x95, 0x4f, 0x25, 0x8e, 0x59,
// utxoIndex:
0x00, 0x00, 0x00, 0x01,
// assetID:
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
// input:
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x74,
0x6a, 0x52, 0x88, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
]
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.
Gantt SECP256K1 Transfer Input Specificationβ
+-------------------------+-------------------------------------+
| type_id : int | 4 bytes |
+-----------------+-------+-------------------------------------+
| amount : long | 8 bytes |
+-----------------+-------+-------------------------------------+
| address_indices : []int | 4 + 4 * len(address_indices) bytes |
+-----------------+-------+-------------------------------------+
| 16 + 4 * len(address_indices) bytes |
+-------------------------------------+
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
: 5Amount
: 500000000000AddressIndices
: [0]
[
TypeID <- 0x00000005
Amount <- 500000000000 = 0x000000746a528800,
AddressIndices <- [0x00000000]
]
=
[
// type id:
0x00, 0x00, 0x00, 0x05,
// amount:
0x00, 0x00, 0x00, 0x74, 0x6a, 0x52, 0x88, 0x00,
// length:
0x00, 0x00, 0x00, 0x01,
// sig[0]
0x00, 0x00, 0x00, 0x00,
]
Outputsβ
Outputs to Coreth Atomic Transactions are either an EVMOutput
to be added to the balance of an address on this chain or a TransferableOutput
(whcih 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 nAVAX for AVAX and the smallest denomination for all other assets).AssetID
is the ID of the asset to transfer.
Gantt EVM Output Specificationβ
+----------+----------+-------------------------+
| address : [20]byte | 20 bytes |
+----------+----------+-------------------------+
| amount : uin64 | 08 bytes |
+----------+----------+-------------------------+
| asset_id : [32]byte | 32 bytes |
+----------+----------+-------------------------+
| 60 bytes |
+-------------------------+
Proto EVM Output Specificationβ
message {
bytes address = 1; // 20 bytes
uint64 amount = 2; // 08 bytes
bytes assetID = 3; // 32 bytes
}
EVM Output Exampleβ
Let's make an EVM Output:
Address: 0x0eb5ccb85c29009b6060decb353a38ea3b52cd20
Amount: 500000000000
AssetID: 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
[
Address <- 0x0eb5ccb85c29009b6060decb353a38ea3b52cd20,
Amount <- 0x000000746a528800
AssetID <- 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
]
=
[
// address:
0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e,
0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89,
0x43, 0xab, 0x08, 0x59,
// amount:
0x00, 0x00, 0x00, 0x74, 0x6a, 0x52, 0x88, 0x00,
// assetID:
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
]
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 aSECP256K1TransferOutput
as defined below.
Gantt Transferable Output Specificationβ
+----------+----------+-------------------------+
| asset_id : [32]byte | 32 bytes |
+----------+----------+-------------------------+
| output : Output | size(output) bytes |
+----------+----------+-------------------------+
| 32 + size(output) bytes |
+-------------------------+
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: 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
Output: "Example SECP256K1 Transfer Output from below"
[
AssetID <- 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
Output <- 0x000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859,
]
=
[
// assetID:
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
// output:
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0x66, 0xf9, 0x0d, 0xb6,
0x13, 0x7a, 0x78, 0xf7, 0x6b, 0x36, 0x93, 0xf7,
0xf2, 0xbc, 0x50, 0x79, 0x56, 0xda, 0xe5, 0x63,
]
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.
Gantt SECP256K1 Transfer Output Specificationβ
+-----------+------------+--------------------------------+
| type_id : int | 4 bytes |
+-----------+------------+--------------------------------+
| amount : long | 8 bytes |
+-----------+------------+--------------------------------+
| locktime : long | 8 bytes |
+-----------+------------+--------------------------------+
| threshold : int | 4 bytes |
+-----------+------------+--------------------------------+
| addresses : [][20]byte | 4 + 20 * len(addresses) bytes |
+-----------+------------+--------------------------------+
| 28 + 20 * len(addresses) bytes |
+--------------------------------+
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
: 7Amount
: 1000000Locktime
: 0Threshold
: 1Addresses
:- 0x66f90db6137a78f76b3693f7f2bc507956dae563
[
TypeID <- 0x00000007
Amount <- 0x00000000000f4240
Locktime <- 0x0000000000000000
Threshold <- 0x00000001
Addresses <- [
0x66f90db6137a78f76b3693f7f2bc507956dae563
]
]
=
[
// typeID:
0x00, 0x00, 0x00, 0x07,
// amount:
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40,
// locktime:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// threshold:
0x00, 0x00, 0x00, 0x01,
// number of addresses:
0x00, 0x00, 0x00, 0x01,
// addrs[0]:
0x66, 0xf9, 0x0d, 0xb6, 0x13, 0x7a, 0x78, 0xf7,
0x6b, 0x36, 0x93, 0xf7, 0xf2, 0xbc, 0x50, 0x79,
0x56, 0xda, 0xe5, 0x63,
]
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 Coreth 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 Avalanche network this transaction is meant to be issued to. This could refer to mainnet, fuji, 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 todestinationChain
.
Gantt ExportTx Specificationβ
+---------------------+----------------------+-------------------------------------------------+
| typeID : int | 04 bytes |
+---------------------+----------------------+-------------------------------------------------+
| networkID : int | 04 bytes |
+---------------------+----------------------+-------------------------------------------------+
| blockchainID : [32]byte | 32 bytes |
+---------------------+----------------------+-------------------------------------------------+
| destinationChain : [32]byte | 32 bytes |
+---------------------+----------------------+-------------------------------------------------+
| inputs : []EvmInput | 4 + size(inputs) bytes |
+---------------------+----------------------+-------------------------------------------------+
| exportedOutputs : []TransferableOutput | 4 + size(exportedOutputs) bytes |
+----------+----------+----------------------+-------------------------------------------------+
| 80 + size(inputs) + size(exportedOutputs) bytes |
+-------------------------------------------------+
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"
[
TypeID <- 0x00000001
NetworkID <- 0x00003039
BlockchainID <- 0x91060eabfb5a571720109b5896e5ff00010a1cfe6b103d585e6ebf27b97a1735
DestinationChain <- 0xd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf
Inputs <- [
0xc3344128e060128ede3523a24a461c8943ab08590000000000003039000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000000000001
]
ExportedOutputs <- [
0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2dbdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700000000000f42400000000000000000000000010000000166f90db6137a78f76b3693f7f2bc507956dae563
]
]
=
[
// typeID:
0x00, 0x00, 0x00, 0x01,
// networkID:
0x00, 0x00, 0x00, 0x04,
// blockchainID:
0x91, 0x06, 0x0e, 0xab, 0xfb, 0x5a, 0x57, 0x17,
0x20, 0x10, 0x9b, 0x58, 0x96, 0xe5, 0xff, 0x00,
0x01, 0x0a, 0x1c, 0xfe, 0x6b, 0x10, 0x3d, 0x58,
0x5e, 0x6e, 0xbf, 0x27, 0xb9, 0x7a, 0x17, 0x35,
// destination_chain:
0xd8, 0x91, 0xad, 0x56, 0x05, 0x6d, 0x9c, 0x01,
0xf1, 0x8f, 0x43, 0xf5, 0x8b, 0x5c, 0x78, 0x4a,
0xd0, 0x7a, 0x4a, 0x49, 0xcf, 0x3d, 0x1f, 0x11,
0x62, 0x38, 0x04, 0xb5, 0xcb, 0xa2, 0xc6, 0xbf,
// inputs[] count:
0x00, 0x00, 0x00, 0x01,
// inputs[0]
0x8d, 0xb9, 0x7c, 0x7c, 0xec, 0xe2, 0x49, 0xc2,
0xb9, 0x8b, 0xdc, 0x02, 0x26, 0xcc, 0x4c, 0x2a,
0x57, 0xbf, 0x52, 0xfc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1e, 0x84, 0x80, 0xdb, 0xcf, 0x89, 0x0f,
0x77, 0xf4, 0x9b, 0x96, 0x85, 0x76, 0x48, 0xb7,
0x2b, 0x77, 0xf9, 0xf8, 0x29, 0x37, 0xf2, 0x8a,
0x68, 0x70, 0x4a, 0xf0, 0x5d, 0xa0, 0xdc, 0x12,
0xba, 0x53, 0xf2, 0xdb, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
// exportedOutputs[] count
0x00, 0x00, 0x00, 0x01,
// exportedOutputs[0]
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0x66, 0xf9, 0x0d, 0xb6,
0x13, 0x7a, 0x78, 0xf7, 0x6b, 0x36, 0x93, 0xf7,
0xf2, 0xbc, 0x50, 0x79, 0x56, 0xda, 0xe5, 0x63,
]
ImportTxβ
ImportTx is a transaction to import funds to Coreth 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 anImportTx
is 0.networkID
is an int that defines which Avalanche network this transaction is meant to be issued to. This could refer to mainnet, fuji, 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.
Gantt ImportTx Specificationβ
+---------------------+----------------------+-------------------------------------------------+
| typeID : int | 04 bytes |
+---------------------+----------------------+-------------------------------------------------+
| networkID : int | 04 bytes |
+---------------------+----------------------+-------------------------------------------------+
| blockchainID : [32]byte | 32 bytes |
+---------------------+----------------------+-------------------------------------------------+
| sourceChain : [32]byte | 32 bytes |
+---------------------+----------------------+-------------------------------------------------+
| importedInputs : []TransferableInput | 4 + size(importedInputs) bytes |
+---------------------+----------------------+-------------------------------------------------+
| outs : []EVMOutput | 4 + size(outs) bytes |
+----------+----------+----------------------+-------------------------------------------------+
| 80 + size(importedInputs) + size(outs) bytes |
+-------------------------------------------------+
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"
[
TypeID <- 0x00000000
NetworkID <- 0x00003039
BlockchainID <- 0x91060eabfb5a571720109b5896e5ff00010a1cfe6b103d585e6ebf27b97a1735
SourceChain <- 0xd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf
ImportedInputs <- [
0x6613a40dcdd8d22ea4aa99a4c84349056317cf550b6685e045e459954f258e5900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000746a5288000000000100000000
]
Outs <- [
0x0eb5ccb85c29009b6060decb353a38ea3b52cd20000000746a528800dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db
]
]
=
[
// typeID:
0x00, 0x00, 0x00, 0x00,
// networkID:
0x00, 0x00, 0x00, 0x04,
// blockchainID:
0x91, 0x06, 0x0e, 0xab, 0xfb, 0x5a, 0x57, 0x17,
0x20, 0x10, 0x9b, 0x58, 0x96, 0xe5, 0xff, 0x00,
0x01, 0x0a, 0x1c, 0xfe, 0x6b, 0x10, 0x3d, 0x58,
0x5e, 0x6e, 0xbf, 0x27, 0xb9, 0x7a, 0x17, 0x35,
// sourceChain:
0xd8, 0x91, 0xad, 0x56, 0x05, 0x6d, 0x9c, 0x01,
0xf1, 0x8f, 0x43, 0xf5, 0x8b, 0x5c, 0x78, 0x4a,
0xd0, 0x7a, 0x4a, 0x49, 0xcf, 0x3d, 0x1f, 0x11,
0x62, 0x38, 0x04, 0xb5, 0xcb, 0xa2, 0xc6, 0xbf,
// importedInputs[] count:
0x00, 0x00, 0x00, 0x01,
// importedInputs[0]
0x66, 0x13, 0xa4, 0x0d, 0xcd, 0xd8, 0xd2, 0x2e,
0xa4, 0xaa, 0x99, 0xa4, 0xc8, 0x43, 0x49, 0x05,
0x63, 0x17, 0xcf, 0x55, 0x0b, 0x66, 0x85, 0xe0,
0x45, 0xe4, 0x59, 0x95, 0x4f, 0x25, 0x8e, 0x59,
0x00, 0x00, 0x00, 0x01, 0xdb, 0xcf, 0x89, 0x0f,
0x77, 0xf4, 0x9b, 0x96, 0x85, 0x76, 0x48, 0xb7,
0x2b, 0x77, 0xf9, 0xf8, 0x29, 0x37, 0xf2, 0x8a,
0x68, 0x70, 0x4a, 0xf0, 0x5d, 0xa0, 0xdc, 0x12,
0xba, 0x53, 0xf2, 0xdb, 0x00, 0x00, 0x00, 0x05,
0x00, 0x00, 0x00, 0x74, 0x6a, 0x52, 0x88, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
// outs[] count
0x00, 0x00, 0x00, 0x01,
// outs[0]
0x0e, 0xb5, 0xcc, 0xb8, 0x5c, 0x29, 0x00, 0x9b,
0x60, 0x60, 0xde, 0xcb, 0x35, 0x3a, 0x38, 0xea,
0x3b, 0x52, 0xcd, 0x20, 0x00, 0x00, 0x00, 0x74,
0x6a, 0x52, 0x88, 0x00, 0xdb, 0xcf, 0x89, 0x0f,
0x77, 0xf4, 0x9b, 0x96, 0x85, 0x76, 0x48, 0xb7,
0x2b, 0x77, 0xf9, 0xf8, 0x29, 0x37, 0xf2, 0x8a,
0x68, 0x70, 0x4a, 0xf0, 0x5d, 0xa0, 0xdc, 0x12,
0xba, 0x53, 0xf2, 0xdb,
]
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 is0x00000009
.Signatures
is an array of 65-byte recoverable signatures. The order of the signatures must match the input's signature indices.
Gantt SECP256K1 Credential Specificationβ
+------------------------------+---------------------------------+
| type_id : int | 4 bytes |
+-----------------+------------+---------------------------------+
| signatures : [][65]byte | 4 + 65 * len(signatures) bytes |
+-----------------+------------+---------------------------------+
| 8 + 65 * len(signatures) bytes |
+---------------------------------+
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
: 9signatures
:0x0acccf47a820549a84428440e2421975138790e41be262f7197f3d93faa26cc8741060d743ffaf025782c8c86b862d2b9febebe7d352f0b4591afbd1a737f8a30010199dbf
[
TypeID <- 0x00000009
Signatures <- [
0x0acccf47a820549a84428440e2421975138790e41be262f7197f3d93faa26cc8741060d743ffaf025782c8c86b862d2b9febebe7d352f0b4591afbd1a737f8a30010199dbf,
]
]
=
[
// Type ID
0x00, 0x00, 0x00, 0x09,
// length:
0x00, 0x00, 0x00, 0x01,
// sig[0]
0x0a, 0xcc, 0xcf, 0x47, 0xa8, 0x20, 0x54, 0x9a,
0x84, 0x42, 0x84, 0x40, 0xe2, 0x42, 0x19, 0x75,
0x13, 0x87, 0x90, 0xe4, 0x1b, 0xe2, 0x62, 0xf7,
0x19, 0x7f, 0x3d, 0x93, 0xfa, 0xa2, 0x6c, 0xc8,
0x74, 0x10, 0x60, 0xd7, 0x43, 0xff, 0xaf, 0x02,
0x57, 0x82, 0xc8, 0xc8, 0x6b, 0x86, 0x2d, 0x2b,
0x9f, 0xeb, 0xeb, 0xe7, 0xd3, 0x52, 0xf0, 0xb4,
0x59, 0x1a, 0xfb, 0xd1, 0xa7, 0x37, 0xf8, 0xa3,
0x00, 0x10, 0x19, 0x9d, 0xbf,
]
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 is00 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
Gantt Signed Transaction Specificationβ
+---------------------+--------------+------------------------------------------------+
| codec_id : uint16 | 2 bytes |
+---------------------+--------------+------------------------------------------------+
| atomic_tx : AtomicTx | size(atomic_tx) bytes |
+---------------------+--------------+------------------------------------------------+
| credentials : []Credential | 4 + size(credentials) bytes |
+---------------------+--------------+------------------------------------------------+
| 6 + size(atomic_tx) + len(credentials) bytes |
+------------------------------------------------+
Proto Signed Transaction Specificationβ
message Tx {
uint16 codec_id = 1; // 2 bytes
AtomicTx atomic_tx = 2; // size(atomic_tx)
repeated Credential credentials = 3; // 4 bytes + size(credentials)
}
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
[
CodecID <- 0x0000
UnsignedAtomic Tx <- 0x0000000100000004ffffffffeeeeeeeeddddddddccccccccbbbbbbbbaaaaaaaa999999998888888800000001000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab085900000001f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd150000000200000007000000030000000400010203
Credentials <- [
0x00000009000000010acccf47a820549a84428440e2421975138790e41be262f7197f3d93faa26cc8741060d743ffaf025782c8c86b862d2b9febebe7d352f0b4591afbd1a737f8a300,
]
]
=
[
// Codec ID
0x00, 0x00,
// unsigned atomic transaction:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39,
0x91, 0x06, 0x0e, 0xab, 0xfb, 0x5a, 0x57, 0x17,
0x20, 0x10, 0x9b, 0x58, 0x96, 0xe5, 0xff, 0x00,
0x01, 0x0a, 0x1c, 0xfe, 0x6b, 0x10, 0x3d, 0x58,
0x5e, 0x6e, 0xbf, 0x27, 0xb9, 0x7a, 0x17, 0x35,
0xd8, 0x91, 0xad, 0x56, 0x05, 0x6d, 0x9c, 0x01,
0xf1, 0x8f, 0x43, 0xf5, 0x8b, 0x5c, 0x78, 0x4a,
0xd0, 0x7a, 0x4a, 0x49, 0xcf, 0x3d, 0x1f, 0x11,
0x62, 0x38, 0x04, 0xb5, 0xcb, 0xa2, 0xc6, 0xbf,
0x00, 0x00, 0x00, 0x01, 0x66, 0x13, 0xa4, 0x0d,
0xcd, 0xd8, 0xd2, 0x2e, 0xa4, 0xaa, 0x99, 0xa4,
0xc8, 0x43, 0x49, 0x05, 0x63, 0x17, 0xcf, 0x55,
0x0b, 0x66, 0x85, 0xe0, 0x45, 0xe4, 0x59, 0x95,
0x4f, 0x25, 0x8e, 0x59, 0x00, 0x00, 0x00, 0x01,
0xdb, 0xcf, 0x89, 0x0f, 0x77, 0xf4, 0x9b, 0x96,
0x85, 0x76, 0x48, 0xb7, 0x2b, 0x77, 0xf9, 0xf8,
0x29, 0x37, 0xf2, 0x8a, 0x68, 0x70, 0x4a, 0xf0,
0x5d, 0xa0, 0xdc, 0x12, 0xba, 0x53, 0xf2, 0xdb,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x74,
0x6a, 0x52, 0x88, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x0e, 0xb5, 0xcc, 0xb8, 0x5c, 0x29, 0x00, 0x9b,
0x60, 0x60, 0xde, 0xcb, 0x35, 0x3a, 0x38, 0xea,
0x3b, 0x52, 0xcd, 0x20, 0x00, 0x00, 0x00, 0x74,
0x6a, 0x52, 0x88, 0x00, 0xdb, 0xcf, 0x89, 0x0f,
0x77, 0xf4, 0x9b, 0x96, 0x85, 0x76, 0x48, 0xb7,
0x2b, 0x77, 0xf9, 0xf8, 0x29, 0x37, 0xf2, 0x8a,
0x68, 0x70, 0x4a, 0xf0, 0x5d, 0xa0, 0xdc, 0x12,
0xba, 0x53, 0xf2, 0xdb,
// number of credentials:
0x00, 0x00, 0x00, 0x01,
// credential[0]:
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01,
0x0a, 0xcc, 0xcf, 0x47, 0xa8, 0x20, 0x54, 0x9a,
0x84, 0x42, 0x84, 0x40, 0xe2, 0x42, 0x19, 0x75,
0x13, 0x87, 0x90, 0xe4, 0x1b, 0xe2, 0x62, 0xf7,
0x19, 0x7f, 0x3d, 0x93, 0xfa, 0xa2, 0x6c, 0xc8,
0x74, 0x10, 0x60, 0xd7, 0x43, 0xff, 0xaf, 0x02,
0x57, 0x82, 0xc8, 0xc8, 0x6b, 0x86, 0x2d, 0x2b,
0x9f, 0xeb, 0xeb, 0xe7, 0xd3, 0x52, 0xf0, 0xb4,
0x59, 0x1a, 0xfb, 0xd1, 0xa7, 0x37, 0xf8, 0xa3,
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 serialization of Outputs was defined above.
Gantt UTXO Specificationβ
+--------------+----------+-------------------------+
| codec_id : uint16 | 2 bytes |
+--------------+----------+-------------------------+
| tx_id : [32]byte | 32 bytes |
+--------------+----------+-------------------------+
| output_index : int | 4 bytes |
+--------------+----------+-------------------------+
| asset_id : [32]byte | 32 bytes |
+--------------+----------+-------------------------+
| output : Output | size(output) bytes |
+--------------+----------+-------------------------+
| 70 + size(output) bytes |
+-------------------------+
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 Exampleβ
Letβs make a UTXO from the signed transaction created above:
CodecID
:0
TxID
:0xf966750f438867c3c9828ddcdbe660e21ccdbb36a9276958f011ba472f75d4e7
UTXOIndex
: 0 = 0x00000000AssetID
:0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Output
:"Example EVMOutput as defined above"
[
CodecID <- 0x0000
TxID <- 0xf966750f438867c3c9828ddcdbe660e21ccdbb36a9276958f011ba472f75d4e7
UTXOIndex <- 0x00000000
AssetID <- 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Output <- 0x000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859
]
=
[
// Codec ID:
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,
// 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,
]