Atomic Transaction Format
This reference document explains how atomic transactions are serialised on Dijets Utility Chain - an instance of Ethereum Virtual Machine. The document uses the primitive serialisation format for packing and secp256k1 for cryptographic user identification.
Codec ID#
Some data is prepended with a codec ID (unt16) that denotes how the data should
be deserialized. Right now, the only valid codec ID is 0 (0x00 0x00).
Inputs#
Inputs to Dijets Utility Chain Atomic Transactions are either an EVMInput from this chain or
a TransferableInput (which contains a SECP256K1TransferInput) from another
chain. The EVMInput will be used in ExportTx to spend funds from this chain,
while the TransferableInput will be used to import atomic UTXOs from another
chain.
EVM Input#
Input type that specifies an EVM account to deduct the funds from as part of an ExportTx.
What EVM Input Contains#
An EVM Input contains an address, amount, assetID, and nonce.
Addressis the EVM address from which to transfer funds.Amountis the amount of the asset to be transferred (specified in nDJTX for DJTX and the smallest denomination for all other assets).AssetIDis the ID of the asset to transfer.Nonceis the nonce of the EVM account exporting funds.
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: 0x8db97c7cece249c2b98bdc0226cc4c2a57bf52fcAmount: 2000000AssetID: 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fNonce: 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.
TxIDis a 32-byte array that defines which transaction this input is consuming an output from.UTXOIndexis an int that defines which utxo this input is consuming in the specified transaction.AssetIDis a 32-byte array that defines which asset this input references.Inputis aSECP256K1TransferInput, as defined below.
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: 0x6613a40dcdd8d22ea4aa99a4c84349056317cf550b6685e045e459954f258e59UTXOIndex: 1AssetID: 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2dbInput: "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.
TypeIDis the ID for this input type. It is0x00000005.Amountis 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.AddressIndicesis 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: 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 DUC (Dijets Utility Chain) Atomic Transactions are either an EVMOutput to be added to
the balance of an address on this chain or a TransferableOutput (which
contains a SECP256K1TransferOutput) to be moved to another chain.
The EVM Output will be used in ImportTx to add funds to this chain, while the
TransferableOutput will be used to export atomic UTXOs to another chain.
EVM Output#
Output type specifying a state change to be applied to an EVM account as part of an ImportTx.
What EVM Output Contains#
An EVM Output contains an address, amount, and assetID.
Addressis the EVM address that will receive the funds.Amountis the amount of the asset to be transferred (specified in nDJTX for DJTX and the smallest denomination for all other assets).AssetIDis the ID of the asset to transfer.
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: 0x0eb5ccb85c29009b6060decb353a38ea3b52cd20Amount: 500000000000AssetID: 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.
AssetIDis a 32-byte array that defines which asset this output references.Outputis aSECP256K1TransferOutputas defined below.
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: 0xdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2dbOutput: "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.
TypeIDis the ID for this output type. It is0x00000007.Amountis a long that specifies the quantity of the asset that this output owns. Must be positive.Locktimeis a long that contains the Unix timestamp that this output can be spent after. The Unix timestamp is specific to the second.Thresholdis an int that names the number of unique signatures required to spend the output. Must be less than or equal to the length ofAddresses. IfAddressesis empty, must be 0.Addressesis a list of unique addresses that correspond to the private keys that can be used to spend this output.
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 Dijets Utility Chain to a different chain.
What ExportTx Contains#
An ExportTx contains an typeID, networkID, blockchainID, destinationChain, inputs, and exportedOutputs.
typeIDis an int that the type for an ExportTx. The typeID for an exportTx is 1.networkIDis an int that defines which Dijets network this transaction is meant to be issued to. This could refer to Mainnet, Dijets TestNet, etc. and is different than the EVM's network ID.blockchainIDis a 32-byte array that defines which blockchain this transaction was issued to.destinationChainis a 32-byte array that defines which blockchain this transaction exports funds to.inputsis an array of EVM Inputs to fund the ExportTx.exportedOutputsis an array of TransferableOutputs to be transferred todestinationChain.
ExportTx Example#
Let's make an EVM Output:
TypeID:1NetworkID:12345BlockchainID:0x91060eabfb5a571720109b5896e5ff00010a1cfe6b103d585e6ebf27b97a1735DestinationChain:0xd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bfInputs:"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 Dijets Utility Chain from another chain.
What ImportTx Contains#
An ImportTx contains an typeID, networkID, blockchainID,
destinationChain, importedInputs, and Outs.
typeIDis an int that the type for an ImportTx. The typeID for anImportTxis 0.networkIDis an int that defines which Dijets network this transaction is meant to be issued to. This could refer to Mainnet, Dijets TestNet, etc. and is different than the EVM's network ID.blockchainIDis a 32-byte array that defines which blockchain this transaction was issued to.sourceChainis a 32-byte array that defines which blockchain from which to import funds.importedInputsis an array of TransferableInputs to fund the ImportTx.Outsis an array of EVM Outputs to be imported to this chain.
ImportTx Example#
Let's make an ImportTx:
TypeID:0NetworkID:12345BlockchainID:0x91060eabfb5a571720109b5896e5ff00010a1cfe6b103d585e6ebf27b97a1735SourceChain:0xd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bfImportedInputs:"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#
TypeIDis the ID for this type. It is0x00000009.Signaturesis 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: 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.
CodecIDThe only current valid codec id is00 00.AtomicTxis an atomic transaction, as described above.Credentialsis an array of credentials. Each credential corresponds to the input at the same index in the AtomicTx
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 -
Credentials0x00000009000000010acccf47a820549a84428440e2421975138790e41be262f7197f3d93faa26cc8741060d743ffaf025782c8c86b862d2b9febebe7d352f0b4591afbd1a737f8a300
[ 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.
CodecIDThe only validCodecIDis00 00TxIDis a 32-byte transaction ID. Transaction IDs are calculated by taking sha256 of the bytes of the signed transaction.UTXOIndexis an int that specifies which output in the transaction specified byTxIDthat this utxo was created by.AssetIDis a 32-byte array that defines which asset this utxo references.Outputis the output object that created this utxo. The serialisation of Outputs was defined above.
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:0TxID:0xf966750f438867c3c9828ddcdbe660e21ccdbb36a9276958f011ba472f75d4e7UTXOIndex: 0 = 0x00000000AssetID:0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fOutput:"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, ]