This file is meant to be the single source of truth for how we serialize transactions in Avalanche’s Platform Virtual Machine, aka the Platform Chain
or P-Chain
. This document uses the primitive serialization format for packing and secp256k1 for cryptographic user identification.
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 outputs wrap an output with an asset ID.
A transferable output contains an AssetID
and an Output
.
AssetID
is a 32-byte array that defines which asset this output references. The only validAssetID
is the AVAXAssetID
.Output
is an output, as defined below. For example, this can be a SECP256K1 transfer output.
+----------+----------+-------------------------+
| asset_id : [32]byte | 32 bytes |
+----------+----------+-------------------------+
| output : Output | size(output) bytes |
+----------+----------+-------------------------+
| 32 + size(output) bytes |
+-------------------------+
message TransferableOutput {
bytes asset_id = 1; // 32 bytes
Output output = 2; // size(output)
}
Let’s make a transferable output:
AssetID: 0x6870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a
Output: "Example SECP256K1 Transfer Output from below"
[
AssetID <- 0x6870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a,
Output <- 0x0000000700000000ee5be5c000000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715c,
]
=
[
// assetID:
0x68, 0x70, 0xb7, 0xd6, 0x6a, 0xc3, 0x25, 0x40,
0x31, 0x13, 0x79, 0xe5, 0xb5, 0xdb, 0xad, 0x28,
0xec, 0x7e, 0xb8, 0xdd, 0xbf, 0xc8, 0xf4, 0xd6,
0x72, 0x99, 0xeb, 0xb4, 0x84, 0x75, 0x90, 0x7a,
// output:
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
0xee, 0x5b, 0xe5, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0xda, 0x2b, 0xee, 0x01,
0xbe, 0x82, 0xec, 0xc0, 0x0c, 0x34, 0xf3, 0x61,
0xed, 0xa8, 0xeb, 0x30, 0xfb, 0x5a, 0x71, 0x5c,
]
Transferable inputs describe a specific UTXO with a provided transfer input.
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 the specified transaction.AssetID
is a 32-byte array that defines which asset this input references. The only validAssetID
is the AVAXAssetID
.Input
is a transferable input object.
+------------+----------+------------------------+
| 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 |
+------------------------+
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)
}
Let’s make a transferable input:
TxID
:0x0dfafbdf5c81f635c9257824ff21c8e3e6f7b632ac306e11446ee540d34711a15
UTXOIndex
:0
AssetID
:0x6870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a
Input
:"Example SECP256K1 Transfer Input from below"
[
TxID <- 0x0dfafbdf5c81f635c9257824ff21c8e3e6f7b632ac306e11446ee540d34711a15
UTXOIndex <- 0x00000001
AssetID <- 0x6870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a
Input <- 0x0000000500000000ee6b28000000000100000000
]
=
[
// txID:
0xdf, 0xaf, 0xbd, 0xf5, 0xc8, 0x1f, 0x63, 0x5c,
0x92, 0x57, 0x82, 0x4f, 0xf2, 0x1c, 0x8e, 0x3e,
0x6f, 0x7b, 0x63, 0x2a, 0xc3, 0x06, 0xe1, 0x14,
0x46, 0xee, 0x54, 0x0d, 0x34, 0x71, 0x1a, 0x15,
// utxoIndex:
0x00, 0x00, 0x00, 0x01,
// assetID:
0x68, 0x70, 0xb7, 0xd6, 0x6a, 0xc3, 0x25, 0x40,
0x31, 0x13, 0x79, 0xe5, 0xb5, 0xdb, 0xad, 0x28,
0xec, 0x7e, 0xb8, 0xdd, 0xbf, 0xc8, 0xf4, 0xd6,
0x72, 0x99, 0xeb, 0xb4, 0x84, 0x75, 0x90, 0x7a,
// input:
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
0xee, 0x6b, 0x28, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00
]
Outputs have two possible type: SECP256K1TransferOutput
, SECP256K1OutputOwners
.
A secp256k1 transfer output allows for sending a quantity of an asset to a collection of addresses after a specified unix time. The only valid asset is AVAX.
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.
+-----------+------------+--------------------------------+
| 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 |
+--------------------------------+
message SECP256K1TransferOutput {
uint32 type_id = 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)
}
Let’s make a secp256k1 transfer output with:
TypeID
: 7Amount
: 3999000000Locktime
: 0Threshold
: 1Addresses
:- 0xda2bee01be82ecc00c34f361eda8eb30fb5a715c
[
TypeID <- 0x00000007
Amount <- 0x00000000ee5be5c0
Locktime <- 0x0000000000000000
Threshold <- 0x00000001
Addresses <- [
0xda2bee01be82ecc00c34f361eda8eb30fb5a715c,
]
]
=
[
// type_id:
0x00, 0x00, 0x00, 0x07,
// amount:
0x00, 0x00, 0x00, 0x00, 0xee, 0x5b, 0xe5, 0xc0,
// locktime:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// threshold:
0x00, 0x00, 0x00, 0x01,
// number of addresses:
0x00, 0x00, 0x00, 0x01,
// addrs[0]:
0xda, 0x2b, 0xee, 0x01, 0xbe, 0x82, 0xec, 0xc0,
0x0c, 0x34, 0xf3, 0x61, 0xed, 0xa8, 0xeb, 0x30,
0xfb, 0x5a, 0x71, 0x5c,
]
A secp256k1 output owners output will recieve the staking rewards when the lock up period ends.
A secp256k1 output owners output contains a TypeID
, Locktime
, Threshold
, and Addresses
.
TypeID
is the ID for this output type. It is0x0000000b
.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.
+-----------+------------+--------------------------------+
| type_id : int | 4 bytes |
+-----------+------------+--------------------------------+
| locktime : long | 8 bytes |
+-----------+------------+--------------------------------+
| threshold : int | 4 bytes |
+-----------+------------+--------------------------------+
| addresses : [][20]byte | 4 + 20 * len(addresses) bytes |
+-----------+------------+--------------------------------+
| 20 + 20 * len(addresses) bytes |
+--------------------------------+
message SECP256K1OutputOwnersOutput {
uint32 type_id = 1; // 04 bytes
uint64 locktime = 2; // 08 bytes
uint32 threshold = 3; // 04 bytes
repeated bytes addresses = 4; // 04 bytes + 20 bytes * len(addresses)
}
Let’s make a secp256k1 output owners output with:
TypeID
: 11Locktime
: 0Threshold
: 1Addresses
:- 0xda2bee01be82ecc00c34f361eda8eb30fb5a715c
[
TypeID <- 0x0000000b
Locktime <- 0x0000000000000000
Threshold <- 0x00000001
Addresses <- [
0xda2bee01be82ecc00c34f361eda8eb30fb5a715c,
]
]
=
[
// type_id:
0x00, 0x00, 0x00, 0x0b,
// locktime:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// threshold:
0x00, 0x00, 0x00, 0x01,
// number of addresses:
0x00, 0x00, 0x00, 0x01,
// addrs[0]:
0xda, 0x2b, 0xee, 0x01, 0xbe, 0x82, 0xec, 0xc0,
0x0c, 0x34, 0xf3, 0x61, 0xed, 0xa8, 0xeb, 0x30,
0xfb, 0x5a, 0x71, 0x5c,
]
Inputs have one possible type: SECP256K1TransferInput
.
A secp256k1 transfer input allows for spending an unspent secp256k1 transfer output.
A secp256k1 transfer input contains an Amount
and AddressIndices
.
TypeID
is the ID for this output 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 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.
+-------------------------+-------------------------------------+
| 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 type_id = 1; // 04 bytes
uint64 amount = 2; // 08 bytes
repeated uint32 address_indices = 3; // 04 bytes + 4 bytes * len(address_indices)
}
Let’s make a payment input with:
TypeID
: 5Amount
: 4000000000AddressIndices
: [0]
[
TypeID <- 0x00000005
Amount <- 0x00000000ee6b2800,
AddressIndices <- [0x00000000]
]
=
[
// type_id:
0x00, 0x00, 0x00, 0x05,
// amount:
0x00, 0x00, 0x00, 0x00, 0xee, 0x6b, 0x28, 0x00,
// length:
0x00, 0x00, 0x00, 0x01,
// address_indices[0]
0x00, 0x00, 0x00, 0x00
]
Unsigned transactions contain the full content of a transaction with only the signatures missing. Unsigned transactions have six possible types: AddValidatorTx
, AddSubnetValidatorTx
, AddDelegatorTx
, CreateSubnetTx
, ImportTx
, and ExportTx
. They embed BaseTx
, which contains common fields and operations.
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.
+---------------+----------------------+-----------------------------------------+
| type_id : int | 4 bytes |
+---------------+----------------------+-----------------------------------------+
| network_id : int | 4 bytes |
+---------------+----------------------+-----------------------------------------+
| blockchain_id : [32]byte | 32 bytes |
+---------------+----------------------+-----------------------------------------+
| outputs : []TransferableOutput | 4 + size(outputs) bytes |
+---------------+----------------------+-----------------------------------------+
| inputs : []TransferableInput | 4 + size(inputs) bytes |
+---------------+----------------------+-----------------------------------------+
| memo : [256]byte | 4 + size(memo) bytes |
+---------------+----------------------+-----------------------------------------+
| 52 + size(outputs) + size(inputs) + size(memo) bytes |
+------------------------------------------------------+
message BaseTx {
uint32 type_id = 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)
}
Let’s make a base tx that uses the inputs and outputs from the previous examples:
TypeID
:0
NetworkID
:12345
BlockchainID
:0x000000000000000000000000000000000000000000000000000000000000000
Outputs
:"Example Transferable Output as defined above"
Inputs
:"Example Transferable Input as defined above"
[
TypeID <- 0x00000000
NetworkID <- 0x00003039
BlockchainID <- 0x000000000000000000000000000000000000000000000000000000000000000
Outputs <- [
0x6870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000700000000ee5be5c000000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715c
]
Inputs <- [
0xdfafbdf5c81f635c9257824ff21c8e3e6f7b632ac306e11446ee540d34711a15000000016870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000500000000ee6b28000000000100000000
]
]
=
[
// type_id:
0x00, 0x00, 0x00, 0x00,
// networkID:
0x00, 0x00, 0x30, 0x39,
// blockchainID:
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,
// number of outputs:
0x00, 0x00, 0x00, 0x01,
// transferable output:
0x68, 0x70, 0xb7, 0xd6, 0x6a, 0xc3, 0x25, 0x40,
0x31, 0x13, 0x79, 0xe5, 0xb5, 0xdb, 0xad, 0x28,
0xec, 0x7e, 0xb8, 0xdd, 0xbf, 0xc8, 0xf4, 0xd6,
0x72, 0x99, 0xeb, 0xb4, 0x84, 0x75, 0x90, 0x7a,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
0xee, 0x5b, 0xe5, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0xda, 0x2b, 0xee, 0x01,
0xbe, 0x82, 0xec, 0xc0, 0x0c, 0x34, 0xf3, 0x61,
0xed, 0xa8, 0xeb, 0x30, 0xfb, 0x5a, 0x71, 0x5c,
// number of inputs:
0x00, 0x00, 0x00, 0x01,
// transferable input:
0xdf, 0xaf, 0xbd, 0xf5, 0xc8, 0x1f, 0x63, 0x5c,
0x92, 0x57, 0x82, 0x4f, 0xf2, 0x1c, 0x8e, 0x3e,
0x6f, 0x7b, 0x63, 0x2a, 0xc3, 0x06, 0xe1, 0x14,
0x46, 0xee, 0x54, 0x0d, 0x34, 0x71, 0x1a, 0x15,
0x00, 0x00, 0x00, 0x01,
0x68, 0x70, 0xb7, 0xd6, 0x6a, 0xc3, 0x25, 0x40,
0x31, 0x13, 0x79, 0xe5, 0xb5, 0xdb, 0xad, 0x28,
0xec, 0x7e, 0xb8, 0xdd, 0xbf, 0xc8, 0xf4, 0xd6,
0x72, 0x99, 0xeb, 0xb4, 0x84, 0x75, 0x90, 0x7a,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
0xee, 0x6b, 0x28, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
// Memo length:
0x00, 0x00, 0x00, 0x00,
]
An unsigned add validator tx contains a BaseTx
, Validator
, Stake
, RewardsOwner
, and Shares
. The TypeID
for this type is 0x0000000c
.
BaseTx
Validator
Validator has aNodeID
,StartTime
,EndTime
, andWeight
NodeID
is 20 bytes which is the node ID of the validator.StartTime
is a long which is the Unix time when the validator starts validating.EndTime
is a long which is the Unix time when the validator stops validating.Weight
is a long which is the amount the validator stakes
Stake
Stake hasLockedOuts
LockedOuts
An array of Transferable Outputs that are locked for the duration of the staking period. At the end of the staking period, these outputs are refunded to their respective addresses.
RewardsOwner
ASECP256K1OutputOwners
Shares
10,000 times percentage of reward taken from delegators
+---------------+-----------------------+-----------------------------------------+
| base_tx : BaseTx | size(base_tx) bytes |
+---------------+-----------------------+-----------------------------------------+
| validator : Validator | 44 bytes |
+---------------+-----------------------+-----------------------------------------+
| stake : Stake | size(LockedOuts) bytes |
+---------------+-----------------------+-----------------------------------------+
| rewards_owner : SECP256K1OutputOwners | size(rewards_owner) bytes |
+---------------+-----------------------+-----------------------------------------+
| shares : Shares | 4 bytes |
+---------------+-----------------------+-----------------------------------------+
| 48 + size(stake) + size(rewards_owner) + size(base_tx) bytes |
+--------------------------------------------------------------+
message AddValidatorTx {
BaseTx base_tx = 1; // size(base_tx)
Validator validator = 2; // 44 bytes
Stake stake = 3; // size(LockedOuts)
SECP256K1OutputOwners rewards_owner = 4; // size(rewards_owner)
uint32 shares = 5; // 04 bytes
}
Let’s make an unsigned add validator tx that uses the inputs and outputs from the previous examples:
-
BaseTx
:"Example BaseTx as defined above with ID set to 0c"
-
Validator
Validator has aNodeID
,StartTime
,EndTime
, andWeight
NodeID
is 20 bytes which is the node ID of the validator.StartTime
is a long which is the Unix time when the validator starts validating.EndTime
is a long which is the Unix time when the validator stops validating.Weight
is a long which is the amount the validator stakes
-
Stake
:0x0000000139c33a499ce4c33a3b09cdd2cfa01ae70dbf2d18b2d7d168524440e55d55008800000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c
-
RewardsOwner
:0x0000000b00000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715c
-
Shares
:0x00000064
0x0000000b00000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715c
[
BaseTx <- 0x0000000c000030390000000000000000000000000000000000000000000000000000000000000006870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000700000000ee5be5c000000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715cdfafbdf5c81f635c9257824ff21c8e3e6f7b632ac306e11446ee540d34711a15000000016870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000500000000ee6b28000000000100000000
NodeID <- 0xe9094f73698002fd52c90819b457b9fbc866ab80
StarTime <- 0x000000005f21f31d
EndTime <- 0x000000005f497dc6
Weight <- 0x000000000000d431
Stake <- 0x0000000139c33a499ce4c33a3b09cdd2cfa01ae70dbf2d18b2d7d168524440e55d55008800000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c
RewardsOwner <- 0x0000000b00000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715c
Shares <- 0x00000064
]
=
[
// base tx:
0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x30, 0x39,
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,
0x00, 0x00, 0x00, 0x01, 0x68, 0x70, 0xb7, 0xd6,
0x6a, 0xc3, 0x25, 0x40, 0x31, 0x13, 0x79, 0xe5,
0xb5, 0xdb, 0xad, 0x28, 0xec, 0x7e, 0xb8, 0xdd,
0xbf, 0xc8, 0xf4, 0xd6,
0x72, 0x99, 0xeb, 0xb4, 0x84, 0x75, 0x90, 0x7a,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
0xee, 0x5b, 0xe5, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0xda, 0x2b, 0xee, 0x01,
0xbe, 0x82, 0xec, 0xc0, 0x0c, 0x34, 0xf3, 0x61,
0xed, 0xa8, 0xeb, 0x30, 0xfb, 0x5a, 0x71, 0x5c,
0x00, 0x00, 0x00, 0x01,
0xdf, 0xaf, 0xbd, 0xf5, 0xc8, 0x1f, 0x63, 0x5c,
0x92, 0x57, 0x82, 0x4f, 0xf2, 0x1c, 0x8e, 0x3e,
0x6f, 0x7b, 0x63, 0x2a, 0xc3, 0x06, 0xe1, 0x14,
0x46, 0xee, 0x54, 0x0d, 0x34, 0x71, 0x1a, 0x15,
0x00, 0x00, 0x00, 0x01,
0x68, 0x70, 0xb7, 0xd6, 0x6a, 0xc3, 0x25, 0x40,
0x31, 0x13, 0x79, 0xe5, 0xb5, 0xdb, 0xad, 0x28,
0xec, 0x7e, 0xb8, 0xdd, 0xbf, 0xc8, 0xf4, 0xd6,
0x72, 0x99, 0xeb, 0xb4, 0x84, 0x75, 0x90, 0x7a,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
0xee, 0x6b, 0x28, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
// Node ID
0xe9, 0x09, 0x4f, 0x73, 0x69, 0x80, 0x02, 0xfd,
0x52, 0xc9, 0x08, 0x19, 0xb4, 0x57, 0xb9, 0xfb,
0xc8, 0x66, 0xab, 0x80,
// StartTime
0x00, 0x00, 0x00, 0x00, 0x5f, 0x21, 0xf3, 0x1d,
// EndTime
0x00, 0x00, 0x00, 0x00, 0x5f, 0x49, 0x7d, 0xc6,
// Weight
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31,
// Stake
0x00, 0x00, 0x00, 0x01, 0x39, 0xc3, 0x3a, 0x49,
0x9c, 0xe4, 0xc3, 0x3a, 0x3b, 0x09, 0xcd, 0xd2,
0xcf, 0xa0, 0x1a, 0xe7, 0x0d, 0xbf, 0x2d, 0x18,
0xb2, 0xd7, 0xd1, 0x68, 0x52, 0x44, 0x40, 0xe5,
0x5d, 0x55, 0x00, 0x88, 0x00, 0x00, 0x00, 0x07,
0x00, 0x00, 0x01, 0xd1, 0xa9, 0x4a, 0x20, 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,
// RewardsOwner
0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0xda, 0x2b, 0xee, 0x01,
0xbe, 0x82, 0xec, 0xc0, 0x0c, 0x34, 0xf3, 0x61,
0xed, 0xa8, 0xeb, 0x30, 0xfb, 0x5a, 0x71, 0x5c,
// Shares
0x00, 0x00, 0x00, 0x64,
]
An unsigned add subnet validator tx contains a BaseTx
, Validator
, SubnetID
, and SubnetAuth
. The TypeID
for this type is 0x0000000d
.
BaseTx
Validator
Validator has aNodeID
,StartTime
,EndTime
, andWeight
NodeID
is 20 bytes which is the node ID of the validator.StartTime
is a long which is the Unix time when the validator starts validating.EndTime
is a long which is the Unix time when the validator stops validating.Weight
is a long which is the amount the validator stakes
SubnetID
a 32 byte subnet idSubnetAuth
containsSigIndices
and has a type id of0x0000000a
.SigIndices
is a list of unique ints that define the addresses signing the control signature to add a validator to a subnet. The array must be sorted low to high.
+---------------+----------------------+-----------------------------------------+
| base_tx : BaseTx | size(base_tx) bytes |
+---------------+----------------------+-----------------------------------------+
| validator : Validator | 44 bytes |
+---------------+----------------------+-----------------------------------------+
| subnet_id : [32]byte | 32 bytes |
+---------------+----------------------+-----------------------------------------+
| subnet_auth : SubnetAuth | 4 bytes + len(sig_indices) bytes |
+---------------+----------------------+-----------------------------------------+
| 80 + len(sig_indices) + size(base_tx) bytes |
+---------------------------------------------+
message AddSubnetValidatorTx {
BaseTx base_tx = 1; // size(base_tx)
Validator validator = 2; // size(validator)
SubnetID subnet_id = 3; // 32 bytes
SubnetAuth subnet_auth = 4; // 04 bytes + len(sig_indices)
}
Let’s make an unsigned add subnet validator tx that uses the inputs and outputs from the previous examples:
BaseTx
:"Example BaseTx as defined above with ID set to 0d"
NodeID
:0xe9094f73698002fd52c90819b457b9fbc866ab80
StarTime
:0x000000005f21f31d
EndTime
:0x000000005f497dc6
Weight
:0x000000000000d431
SubnetID
:0x58b1092871db85bc752742054e2e8be0adf8166ec1f0f0769f4779f14c71d7eb
SubnetAuth
:TypeID
:0x0000000a
SigIndices
:0x00000000
[
BaseTx <- 0x0000000d000030390000000000000000000000000000000000000000000000000000000000000006870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000700000000ee5be5c000000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715cdfafbdf5c81f635c9257824ff21c8e3e6f7b632ac306e11446ee540d34711a15000000016870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000500000000ee6b28000000000100000000
NodeID <- 0xe9094f73698002fd52c90819b457b9fbc866ab80
StarTime <- 0x000000005f21f31d
EndTime <- 0x000000005f497dc6
Weight <- 0x000000000000d431
SubnetID <- 0x58b1092871db85bc752742054e2e8be0adf8166ec1f0f0769f4779f14c71d7eb
SubnetAuth TypeID <- 0x0000000a
SubnetAuth <- 0x00000000
]
=
[
// base tx:
0x00, 0x00, 0x00, 0x0d,
0x00, 0x00, 0x30, 0x39,
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,
0x00, 0x00, 0x00, 0x01,
0x68, 0x70, 0xb7, 0xd6, 0x6a, 0xc3, 0x25, 0x40,
0x31, 0x13, 0x79, 0xe5, 0xb5, 0xdb, 0xad, 0x28,
0xec, 0x7e, 0xb8, 0xdd, 0xbf, 0xc8, 0xf4, 0xd6,
0x72, 0x99, 0xeb, 0xb4, 0x84, 0x75, 0x90, 0x7a,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
0xee, 0x5b, 0xe5, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0xda, 0x2b, 0xee, 0x01,
0xbe, 0x82, 0xec, 0xc0, 0x0c, 0x34, 0xf3, 0x61,
0xed, 0xa8, 0xeb, 0x30, 0xfb, 0x5a, 0x71, 0x5c,
0x00, 0x00, 0x00, 0x01,
0xdf, 0xaf, 0xbd, 0xf5, 0xc8, 0x1f, 0x63, 0x5c,
0x92, 0x57, 0x82, 0x4f, 0xf2, 0x1c, 0x8e, 0x3e,
0x6f, 0x7b, 0x63, 0x2a, 0xc3, 0x06, 0xe1, 0x14,
0x46, 0xee, 0x54, 0x0d, 0x34, 0x71, 0x1a, 0x15,
0x00, 0x00, 0x00, 0x01,
0x68, 0x70, 0xb7, 0xd6, 0x6a, 0xc3, 0x25, 0x40,
0x31, 0x13, 0x79, 0xe5, 0xb5, 0xdb, 0xad, 0x28,
0xec, 0x7e, 0xb8, 0xdd, 0xbf, 0xc8, 0xf4, 0xd6,
0x72, 0x99, 0xeb, 0xb4, 0x84, 0x75, 0x90, 0x7a,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
0xee, 0x6b, 0x28, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
// Node ID
0xe9, 0x09, 0x4f, 0x73, 0x69, 0x80, 0x02, 0xfd,
0x52, 0xc9, 0x08, 0x19, 0xb4, 0x57, 0xb9, 0xfb,
0xc8, 0x66, 0xab, 0x80,
// StartTime
0x00, 0x00, 0x00, 0x00, 0x5f, 0x21, 0xf3, 0x1d,
// EndTime
0x00, 0x00, 0x00, 0x00, 0x5f, 0x49, 0x7d, 0xc6,
// Weight
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31,
// SubnetID
0x58, 0xb1, 0x09, 0x28, 0x71, 0xdb, 0x85, 0xbc,
0x75, 0x27, 0x42, 0x05, 0x4e, 0x2e, 0x8b, 0xe0,
0xad, 0xf8, 0x16, 0x6e, 0xc1, 0xf0, 0xf0, 0x76,
0x9f, 0x47, 0x79, 0xf1, 0x4c, 0x71, 0xd7, 0xeb,
// SubnetAuth
// SubnetAuth TypeID
0x00, 0x00, 0x00, 0x0a,
// SigIndices length
0x00, 0x00, 0x00, 0x01,
// SigIndices
0x00, 0x00, 0x00, 0x00,
]
An unsigned add delegator tx contains a BaseTx
, Validator
, Stake
, and RewardsOwner
. The TypeID
for this type is 0x0000000e
.
BaseTx
Validator
Validator has aNodeID
,StartTime
,EndTime
, andWeight
NodeID
is 20 bytes which is the node ID of the delegatee.StartTime
is a long which is the Unix time when the delegator starts delegating.EndTime
is a long which is the Unix time when the delegator stops delegating (and staked AVAX is returned).Weight
is a long which is the amount the delegator stakes
Stake
Stake hasLockedOuts
LockedOuts
An array of Transferable Outputs that are locked for the duration of the staking period. At the end of the staking period, these outputs are refunded to their respective addresses.
RewardsOwner
AnSECP256K1OutputOwners
+---------------+-----------------------+-----------------------------------------+
| base_tx : BaseTx | size(base_tx) bytes |
+---------------+-----------------------+-----------------------------------------+
| validator : Validator | 44 bytes |
+---------------+-----------------------+-----------------------------------------+
| stake : Stake | size(LockedOuts) bytes |
+---------------+-----------------------+-----------------------------------------+
| rewards_owner : SECP256K1OutputOwners | size(rewards_owner) bytes |
+---------------+-----------------------+-----------------------------------------+
| 44 + size(stake) + size(rewards_owner) + size(base_tx) bytes |
+--------------------------------------------------------------+
message AddDelegatorTx {
BaseTx base_tx = 1; // size(base_tx)
Validator validator = 2; // 44 bytes
Stake stake = 3; // size(LockedOuts)
SECP256K1OutputOwners rewards_owner = 4; // size(rewards_owner)
}
Let’s make an unsigned add delegator tx that uses the inputs and outputs from the previous examples:
BaseTx
:"Example BaseTx as defined above with ID set to 0e"
NodeID
:0xe9094f73698002fd52c90819b457b9fbc866ab80
StarTime
:0x000000005f21f31d
EndTime
:0x000000005f497dc6
Weight
:0x000000000000d431
Stake
:0x0000000139c33a499ce4c33a3b09cdd2cfa01ae70dbf2d18b2d7d168524440e55d55008800000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c
RewardsOwner
:0x0000000b00000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715c
[
BaseTx <- 0x0000000e000030390000000000000000000000000000000000000000000000000000000000000006870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000700000000ee5be5c000000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715cdfafbdf5c81f635c9257824ff21c8e3e6f7b632ac306e11446ee540d34711a15000000016870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000500000000ee6b28000000000100000000
NodeID <- 0xe9094f73698002fd52c90819b457b9fbc866ab80
StarTime <- 0x000000005f21f31d
EndTime <- 0x000000005f497dc6
Weight <- 0x000000000000d431
Stake <- 0x0000000139c33a499ce4c33a3b09cdd2cfa01ae70dbf2d18b2d7d168524440e55d55008800000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c
RewardsOwner <- 0x0000000b00000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715c
]
=
[
// base tx:
0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x30, 0x39,
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,
0x00, 0x00, 0x00, 0x01,
0x68, 0x70, 0xb7, 0xd6, 0x6a, 0xc3, 0x25, 0x40,
0x31, 0x13, 0x79, 0xe5, 0xb5, 0xdb, 0xad, 0x28,
0xec, 0x7e, 0xb8, 0xdd, 0xbf, 0xc8, 0xf4, 0xd6,
0x72, 0x99, 0xeb, 0xb4, 0x84, 0x75, 0x90, 0x7a,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
0xee, 0x5b, 0xe5, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0xda, 0x2b, 0xee, 0x01,
0xbe, 0x82, 0xec, 0xc0, 0x0c, 0x34, 0xf3, 0x61,
0xed, 0xa8, 0xeb, 0x30, 0xfb, 0x5a, 0x71, 0x5c,
0x00, 0x00, 0x00, 0x01,
0xdf, 0xaf, 0xbd, 0xf5, 0xc8, 0x1f, 0x63, 0x5c,
0x92, 0x57, 0x82, 0x4f, 0xf2, 0x1c, 0x8e, 0x3e,
0x6f, 0x7b, 0x63, 0x2a, 0xc3, 0x06, 0xe1, 0x14,
0x46, 0xee, 0x54, 0x0d, 0x34, 0x71, 0x1a, 0x15,
0x00, 0x00, 0x00, 0x01,
0x68, 0x70, 0xb7, 0xd6, 0x6a, 0xc3, 0x25, 0x40,
0x31, 0x13, 0x79, 0xe5, 0xb5, 0xdb, 0xad, 0x28,
0xec, 0x7e, 0xb8, 0xdd, 0xbf, 0xc8, 0xf4, 0xd6,
0x72, 0x99, 0xeb, 0xb4, 0x84, 0x75, 0x90, 0x7a,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
0xee, 0x6b, 0x28, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
// Node ID
0xe9, 0x09, 0x4f, 0x73, 0x69, 0x80, 0x02, 0xfd,
0x52, 0xc9, 0x08, 0x19, 0xb4, 0x57, 0xb9, 0xfb,
0xc8, 0x66, 0xab, 0x80,
// StartTime
0x00, 0x00, 0x00, 0x00, 0x5f, 0x21, 0xf3, 0x1d,
// EndTime
0x00, 0x00, 0x00, 0x00, 0x5f, 0x49, 0x7d, 0xc6,
// Weight
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31,
// Stake
0x00, 0x00, 0x00, 0x01, 0x39, 0xc3, 0x3a, 0x49,
0x9c, 0xe4, 0xc3, 0x3a, 0x3b, 0x09, 0xcd, 0xd2,
0xcf, 0xa0, 0x1a, 0xe7, 0x0d, 0xbf, 0x2d, 0x18,
0xb2, 0xd7, 0xd1, 0x68, 0x52, 0x44, 0x40, 0xe5,
0x5d, 0x55, 0x00, 0x88, 0x00, 0x00, 0x00, 0x07,
0x00, 0x00, 0x01, 0xd1, 0xa9, 0x4a, 0x20, 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,
// RewardsOwner
0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0xda, 0x2b, 0xee, 0x01,
0xbe, 0x82, 0xec, 0xc0, 0x0c, 0x34, 0xf3, 0x61,
0xed, 0xa8, 0xeb, 0x30, 0xfb, 0x5a, 0x71, 0x5c,
]
An unsigned create subnet tx contains a BaseTx
, and RewardsOwner
. The TypeID
for this type is 0x00000010
.
BaseTx
RewardsOwner
ASECP256K1OutputOwners
+-----------------+-----------------------|---------------------------------+
| base_tx : BaseTx | size(base_tx) bytes |
+-----------------+-----------------------+--------------------------------+
| rewards_owner : SECP256K1OutputOwners | size(rewards_owner) bytes |
+-----------------+-----------------------+---------------------------------+
| size(rewards_owner) + size(base_tx) bytes |
+-------------------------------------------+
message CreateSubnetTx {
BaseTx base_tx = 1; // size(base_tx)
SECP256K1OutputOwners rewards_owner = 2; // size(rewards_owner)
}
Let’s make an unsigned create subnet tx that uses the inputs from the previous examples:
BaseTx
: “Example BaseTx as defined above but with TypeID set to 16”RewardsOwner
:TypeId
: 11Locktime
: 0Threshold
: 1Addresses
: [ 0xda2bee01be82ecc00c34f361eda8eb30fb5a715c ]
[
BaseTx <- 0x00000010000030390000000000000000000000000000000000000000000000000000000000000006870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000700000000ee5be5c000000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715cdfafbdf5c81f635c9257824ff21c8e3e6f7b632ac306e11446ee540d34711a15000000016870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000500000000ee6b28000000000100000000
RewardsOwner <-
TypeID <- 0x0000000b
Locktime <- 0x0000000000000000
Threshold <- 0x00000001
Addresses <- [
0xda2bee01be82ecc00c34f361eda8eb30fb5a715c,
]
]
=
[
// base tx:
0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x30, 0x39, 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, 0x00, 0x00, 0x00, 0x01,
0x39, 0xc3, 0x3a, 0x49, 0x9c, 0xe4, 0xc3, 0x3a,
0x3b, 0x09, 0xcd, 0xd2, 0xcf, 0xa0, 0x1a, 0xe7,
0x0d, 0xbf, 0x2d, 0x18, 0xb2, 0xd7, 0xd1, 0x68,
0x52, 0x44, 0x40, 0xe5, 0x5d, 0x55, 0x00, 0x88,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x12, 0x30,
0x9c, 0xd5, 0xfd, 0xc0, 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// RewardsOwner type id
0x00, 0x00, 0x00, 0x0b,
// locktime:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// threshold:
0x00, 0x00, 0x00, 0x01,
// number of addresses:
0x00, 0x00, 0x00, 0x01,
// addrs[0]:
0xda, 0x2b, 0xee, 0x01,
0xbe, 0x82, 0xec, 0xc0, 0x0c, 0x34, 0xf3, 0x61,
0xed, 0xa8, 0xeb, 0x30, 0xfb, 0x5a, 0x71, 0x5c
]
An unsigned import tx contains a BaseTx
, SourceChain
, and Ins
. The TypeID
for this type is 0x00000011
.
BaseTx
SourceChain
is a 32-byte source blockchain ID.Ins
is a variable length array of Transferable Inputs.
+-----------------+--------------|---------------------------------+
| base_tx : BaseTx | size(base_tx) bytes |
+-----------------+--------------+---------------------------------+
| source_chain : [32]byte | 32 bytes |
+-----------------+--------------+---------------------------------+
| ins : []TransferIn | 4 + size(ins) bytes |
+-----------------+--------------+---------------------------------+
| 36 + size(ins) + size(base_tx) bytes |
+--------------------------------------+
message ImportTx {
BaseTx base_tx = 1; // size(base_tx)
bytes source_chain = 2; // 32 bytes
repeated TransferIn ins = 3; // 4 bytes + size(ins)
}
Let’s make an unsigned import tx that uses the inputs from the previous examples:
BaseTx
: “Example BaseTx as defined above with TypeID set to 17”SourceChain
:Ins
: “Example SECP256K1 Transfer Input as defined above”
[
BaseTx <- 0x00000011000030390000000000000000000000000000000000000000000000000000000000000006870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000700000000ee5be5c000000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715cdfafbdf5c81f635c9257824ff21c8e3e6f7b632ac306e11446ee540d34711a15000000016870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000500000000ee6b28000000000100000000
SourceChain <- 0x787cd3243c002e9bf5bbbaea8a42a16c1a19cc105047c66996807cbf16acee10
Ins <- [
// input:
]
]
=
[
// base tx:
0x00, 0x00, 0x00, 0x11,
0x00, 0x00, 0x30, 0x39, 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, 0x00, 0x00, 0x00, 0x01,
0x39, 0xc3, 0x3a, 0x49, 0x9c, 0xe4, 0xc3, 0x3a,
0x3b, 0x09, 0xcd, 0xd2, 0xcf, 0xa0, 0x1a, 0xe7,
0x0d, 0xbf, 0x2d, 0x18, 0xb2, 0xd7, 0xd1, 0x68,
0x52, 0x44, 0x40, 0xe5, 0x5d, 0x55, 0x00, 0x88,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x12, 0x30,
0x9c, 0xd5, 0xfd, 0xc0, 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// sourceChain
0x78, 0x7c, 0xd3, 0x24, 0x3c, 0x00, 0x2e, 0x9b,
0xf5, 0xbb, 0xba, 0xea, 0x8a, 0x42, 0xa1, 0x6c,
0x1a, 0x19, 0xcc, 0x10, 0x50, 0x47, 0xc6, 0x69,
0x96, 0x80, 0x7c, 0xbf, 0x16, 0xac, 0xee, 0x10,
// 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,
0xee, 0x6b, 0x28, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
]
An unsigned export tx contains a BaseTx
, DestinationChain
, and Outs
. The TypeID
for this type is 0x00000012
.
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.
+-------------------+---------------+--------------------------------------+
| base_tx : BaseTx | size(base_tx) bytes |
+-------------------+---------------+--------------------------------------+
| destination_chain : [32]byte | 32 bytes |
+-------------------+---------------+--------------------------------------+
| outs : []TransferOut | 4 + size(outs) bytes |
+-------------------+---------------+--------------------------------------+
| 36 + size(outs) + size(base_tx) bytes |
+---------------------------------------+
message ExportTx {
BaseTx base_tx = 1; // size(base_tx)
bytes destination_chain = 2; // 32 bytes
repeated TransferOut outs = 3; // 4 bytes + size(outs)
}
Let’s make an unsigned export tx that uses the outputs from the previous examples:
BaseTx
: “Example BaseTx as defined above” withTypeID
set to 18DestinationChain
:0x0000000000000000000000000000000000000000000000000000000000000000
Outs
: “Example SECP256K1 Transfer Output as defined above”
[
BaseTx <- 0x00000012000030390000000000000000000000000000000000000000000000000000000000000006870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000700000000ee5be5c000000000000000000000000100000001da2bee01be82ecc00c34f361eda8eb30fb5a715cdfafbdf5c81f635c9257824ff21c8e3e6f7b632ac306e11446ee540d34711a15000000016870b7d66ac32540311379e5b5dbad28ec7eb8ddbfc8f4d67299ebb48475907a0000000500000000ee6b28000000000100000000
DestinationChain <- 0x0000000000000000000000000000000000000000000000000000000000000000
Outs <- [
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859,
]
]
=
[
// base tx:
0x00, 0x00, 0x00, 0x12
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,
]
Credentials have one possible types: SECP256K1Credential
. Each credential is paired with an Input or Operation. The order of the credentials match the order of the inputs or operations.
A secp256k1 credential contains a list of 65-byte recoverable signatures.
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.
+------------------------------+---------------------------------+
| type_id : int | 4 bytes |
+-----------------+------------+---------------------------------+
| signatures : [][65]byte | 4 + 65 * len(signatures) bytes |
+-----------------+------------+---------------------------------+
| 8 + 65 * len(signatures) bytes |
+---------------------------------+
message SECP256K1Credential {
uint32 TypeID = 1; // 4 bytes
repeated bytes signatures = 2; // 4 bytes + 65 bytes * len(signatures)
}
Let’s make a payment input with:
signatures
:0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1e1d1f202122232425262728292a2b2c2e2d2f303132333435363738393a3b3c3d3e3f00
0x404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5e5d5f606162636465666768696a6b6c6e6d6f707172737475767778797a7b7c7d7e7f00
[
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,
]
A signed transaction is an unsigned transaction with the addition of an array of credentials.
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.
+---------------------+--------------+------------------------------------------------+
| codec_id : uint16 | 2 bytes |
+---------------------+--------------+------------------------------------------------+
| unsigned_tx : UnsignedTx | size(unsigned_tx) bytes |
+---------------------+--------------+------------------------------------------------+
| credentials : []Credential | 4 + size(credentials) bytes |
+---------------------+--------------+------------------------------------------------+
| 6 + size(unsigned_tx) + len(credentials) bytes |
+------------------------------------------------+
message Tx {
uint32 codec_id = 1; // 2 bytes
UnsignedTx unsigned_tx = 2; // size(unsigned_tx)
repeated Credential credentials = 3; // 4 bytes + size(credentials)
}
Let’s make a signed transaction that uses the unsigned transaction and credential from the previous examples.
CodecID
:0
UnsignedTx
:0x0000000100000003ffffffffeeeeeeeeddddddddccccccccbbbbbbbbaaaaaaaa999999998888888800000001000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab085900000001f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd150000000200000003000000070000000400010203
Credentials
0x0000000900000002000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1e1d1f202122232425262728292a2b2c2e2d2f303132333435363738393a3b3c3d3e3f00404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5e5d5f606162636465666768696a6b6c6e6d6f707172737475767778797a7b7c7d7e7f00
[
CodecID <- 0x0000
UnsignedTx <- 0x0000000100000003ffffffffeeeeeeeeddddddddccccccccbbbbbbbbaaaaaaaa999999998888888800000001000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab085900000001f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd150000000200000003000000070000000400010203
Credentials <- [
0x0000000900000002000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1e1d1f202122232425262728292a2b2c2e2d2f303132333435363738393a3b3c3d3e3f00404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5e5d5f606162636465666768696a6b6c6e6d6f707172737475767778797a7b7c7d7e7f00,
]
]
=
[
// Codec ID
0x00, 0x00,
// unsigned transaction:
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
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, 0x03, 0x00, 0x00, 0x00, 0x07,
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,
A UTXO is a standalone representation of a transaction output.
A UTXO contains a CodecID
, TxID
, UTXOIndex
, and Output
.
CodecID
The only current valid codec id 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.
+--------------+----------+-------------------------+
| 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 |
+-------------------------+
message Utxo {
uint32 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)
}
Let’s make a UTXO from the signed transaction created above:
CodecID
:0
TxID
:0xf966750f438867c3c9828ddcdbe660e21ccdbb36a9276958f011ba472f75d4e7
UTXOIndex
: 0x00000000AssetID
:0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Output
:"Example SECP256K1 Transferable Output 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,
]
A StakeableLockIn is a staked and locked input. The StakeableLockIn can only fund StakeableLockOuts with the same address until its locktime has passed.
A StakeableLockIn contains a TypeID
, Locktime
and TransferableIn
.
TypeID
is the ID for this output type. It is0x00000015
.Locktime
is a long that contains the unix timestamp before which the input can be consumed only to stake. The unix timestamp is specific to the second.TransferableIn
is a transferable input object.
+-----------------+-------------------+--------------------------------+
| type_id : int | 4 bytes |
+-----------------+-------------------+--------------------------------+
| locktime : long | 8 bytes |
+-----------------+-------------------+--------------------------------+
| transferable_in : TransferableInput | size(transferable_in) |
+-----------------+-------------------+--------------------------------+
| 12 + size(transferable_in) bytes |
+----------------------------------+
message StakeableLockIn {
uint32 type_id = 1; // 04 bytes
uint64 locktime = 2; // 08 bytes
TransferableInput transferable_in = 3; // size(transferable_in)
}
Let’s make a StakeableLockIn with:
TypeID
: 21Locktime
: 54321TransferableIn
: “Example SECP256K1 Transfer Input as defined above”
[
TypeID <- 0x00000015
Locktime <- 0x000000000000d431
TransferableIn <- [
f1e1d1c1b1a191817161514131211101f0e0d0c0b0a09080706050403020100000000005000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0000000500000000075bcd150000000100000000,
]
]
=
[
// type_id:
0x00, 0x00, 0x00, 0x15,
// locktime:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31,
// transferable_in
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, 0x01,
0x00, 0x00, 0x00, 0x00,
]
A StakeableLockOut is an output that is locked until its locktime, but can be staked in the meantime.
A StakeableLockOut contains a TypeID
, Locktime
and TransferableOut
.
TypeID
is the ID for this output type. It is0x00000016
.Locktime
is a long that contains the unix timestamp before which the output can be consumed only to stake. The unix timestamp is specific to the second.transferableout
: “Example SECP256K1 Transfer Output as defined above”
+------------------+--------------------+--------------------------------+
| type_id : int | 4 bytes |
+------------------+--------------------+--------------------------------+
| locktime : long | 8 bytes |
+------------------+--------------------+--------------------------------+
| transferable_out : TransferableOutput | size(transferable_out) |
+------------------+--------------------+--------------------------------+
| 12 + size(transferable_out) bytes |
+-----------------------------------+
message StakeableLockOut {
uint32 type_id = 1; // 04 bytes
uint64 locktime = 2; // 08 bytes
TransferableOutput transferable_out = 3; // size(transferable_out)
}
Let’s make a stakeablelockout with:
TypeID
: 22Locktime
: 54321TransferableOutput
:"Example SECP256K1 Transfer Output from above"
[
TypeID <- 0x00000016
Locktime <- 0x000000000000d431
TransferableOutput <- 0x000000070000000000003039000000000000d431000000010000000251025c61fbcfc078f69334f834be6dd26d55a955c3344128e060128ede3523a24a461c8943ab0859,
]
=
[
// type_id:
0x00, 0x00, 0x00, 0x16,
// locktime:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31,
// transferable_out
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,
]