├── .gitignore ├── README.md ├── spec ├── 01-index.md ├── 04-send.md ├── asset-names.md ├── 06-issuance.md ├── 05-broadcast.md ├── 03-encoding.md └── 02-decoding.md ├── tools └── arc4decrypt.php └── examples ├── example-send.json └── example-broadcast.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.codekit 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # counterparty-spec 2 | 3 | A developer-level specification for the Counterparty protocol. 4 | 5 | 6 | ## Status 7 | 8 | This is a work in progress. At this point it is incomplete and may contain errors. 9 | 10 | 11 | ## Where to start 12 | 13 | Begin with the [index](spec/01-index.md) -------------------------------------------------------------------------------- /spec/01-index.md: -------------------------------------------------------------------------------- 1 | # A Specification for the Counterparty protocol 2 | 3 | This is a specification for the Counterparty protocol. 4 | 5 | ## Table of Contents 6 | 7 | - [Decoding Transactions](02-decoding.md) 8 | - [Encoding Transactions](03-encoding.md) 9 | 10 | - [Send Transactions](04-send.md) 11 | - [Broadcast Transactions](05-broadcast.md) 12 | - [Issuance Transactions](06-issuance.md) 13 | -------------------------------------------------------------------------------- /tools/arc4decrypt.php: -------------------------------------------------------------------------------- 1 | \n"; 11 | exit(1); 12 | } 13 | 14 | $decrypted_binary_data = arc4decrypt(hex2bin($txid), hex2bin($hexadecimal_data)); 15 | 16 | print "\n"; 17 | print "Deobfuscated:\n"; 18 | print bin2hex($decrypted_binary_data)."\n"; 19 | 20 | 21 | 22 | function arc4decrypt($arc4_decrypt_key, $encrypted_text) 23 | { 24 | $init_vector = ''; 25 | return mcrypt_decrypt(MCRYPT_ARCFOUR, $arc4_decrypt_key, $encrypted_text, MCRYPT_MODE_STREAM, $init_vector); 26 | } 27 | 28 | ?> -------------------------------------------------------------------------------- /spec/04-send.md: -------------------------------------------------------------------------------- 1 | # Send Transactions 2 | 3 | This describes the operation data for a send transaction. Please see [encoding](03-encoding.md) and [decoding](02-decoding.md) for an explanation of where the operation data fits into the full transaction data. 4 | 5 | ### The send transaction 6 | 7 | A send transaction contains 2 pieces of data. An asset name and a quantity. 8 | 9 | ``` 10 | 000000000004fadf|000000174876e800 11 | | | 12 | | └───── quantity (8 bytes) 13 | └────────────────── asset name (8 bytes) 14 | ``` 15 | 16 | 17 | The first 8 bytes contain an the asset id. This asset id is a 64 bit representation of the asset name. See [asset names](asset-names.md). 18 | 19 | And the next 8 bytes contain an unsigned integer with the quantity of the send. 20 | 21 | The total send transaction data length is 16 bytes. 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /spec/asset-names.md: -------------------------------------------------------------------------------- 1 | # Asset Names 2 | 3 | 4 | ### Decoding Asset Names 5 | 6 | An asset ID is a 64 bit number. 7 | 8 | There are 2 special asset IDs. Asset id `0` is BTC and asset id `1` is XCP. 9 | 10 | Asset IDs greater than 1 and less than 17576 (0x44A8) are invalid. 11 | 12 | To convert an asset ID into a name, repeatedly divide the asset ID by 26, round down and convert each remainder into a character until the result of the division is 0. The name is built from the last letter to the first letter. 13 | 14 | ``` 15 | Example of converting 000000000004fadf (326367) into a name 16 | 17 | ABCDEFGHIJKLMNOPQRSTUVWXYZ 18 | |||| |└── 25 19 | |||└───── 3 └─ 24 20 | ||└──── 2 21 | |└─── 1 22 | └── 0 23 | 24 | 326367 / 26 = 12552 remainder 15. 15 translates to P. The Asset is P. 25 | 12552 / 26 = 482 remainder 20. 20 translates to U. The Asset is UP. 26 | 482 / 26 = 18 remainder 14. 14 translates to O. The Asset is OUP. 27 | 18 / 26 = 0 remainder 18. 18 translates to S. The Asset is SOUP. 28 | ``` 29 | See [Javascript Example](https://gist.github.com/loon3/a714c7a85abe48d587bd) 30 | -------------------------------------------------------------------------------- /spec/06-issuance.md: -------------------------------------------------------------------------------- 1 | # Issuance 2 | 3 | This describes the operation data for an issuance transaction. Please see [encoding](03-encoding.md) and [decoding](02-decoding.md) for an explanation of where the operation data fits into the full transaction data. 4 | 5 | ``` 6 | 00000000d806c1d5|000080321c637440|01|00|00000000|00000000|29|43727970746f2d526577617264732050726f6772616d20687474703a2f2f6c7462636f696e2e636f6d 7 | | | | | | | | | 8 | | | | | | | | | 9 | | | | | | | | └─── Description 10 | | | | | | | └─── Length of the description (Note: This length byte is not present for descriptions that are 43 characters long or longer) 11 | | | | | | └─── call price (4 bytes) 12 | | | | | └─── call date (4 bytes) 13 | | | | └─── callable (1 byte) 14 | | | └─── divisible (1 byte) 15 | | └───── quantity (8 bytes) 16 | └────────────────── asset name (8 bytes) 17 | ``` 18 | 19 | The example above decodes to: 20 | 21 | ``` 22 | asset name 00000000d806c1d5 = LTBCOIN (see [asset names](asset-names.md)) 23 | quantity 00000000d806c1d5 = 1,409,527.13000000 24 | divisible 01 = true 25 | callable 00 = false 26 | call date 00000000 = none 27 | call price 00000000 = none 28 | Length of the description 29 = 41 29 | Description 2943727970746f2d526577617264732050726f6772616d20687474703a2f2f6c7462636f696e2e636f6d = Crypto-Rewards Program http://ltbcoin.com 30 | ``` 31 | 32 | 33 | -------------------------------------------------------------------------------- /spec/05-broadcast.md: -------------------------------------------------------------------------------- 1 | # Broadcasts 2 | 3 | 4 | 5 | ``` 6 | 7 | Raw example of decoding transaction cb90b267711165167a9ac82fa4ca1e561ae7d740b244bee98589523b04112241 8 | 9 | 10 | 11 | 12 | Decoded data from multisig output 13 | 14 | 2a|434e545250525459|0000001e|552161c8403e000000000000000000000d584350454c454354494f4e203100000000000000000000000000000000000000 15 | | | | | 16 | | | | └───── All of this is the transaction data (49 bytes) 17 | | | └─────────────── This is the transaction type identifier (4 bytes) 18 | | └───────────────────────────────── the string CNTRPRTY in hexadecimal (8 bytes) 19 | └─────────────────────────────────────────────── The length of the message (42?) (1 bytes) 20 | 21 | 22 | 23 | Transaction Data that makes up the broadcast 24 | 25 | 552161c8|403e000000000000|00000000|0d|584350454c454354494f4e203100000000000000000000000000000000000000 26 | | | | | | 27 | | | | | | 28 | | | | | | 29 | | | | | | 30 | | | | | | 31 | | | | | └─── Message text "XCPELECTION 1" (32 bytes) 32 | | | | └───────────── Length of the message. This is 13. (1 byte) 33 | | | └─────────────────────── Fee fraction information (4 bytes) 34 | | └────────────────────────────────────── Value Data as a floating point number. This is 30.0 (8 bytes) 35 | └────────────────────────────────────────────────────── Timestamp of 2015-04-05 11:24:40. (4 bytes) 36 | 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /examples/example-send.json: -------------------------------------------------------------------------------- 1 | { 2 | "locktime": 0, 3 | "txid": "e0082d1fc37172ccf0f5ebfc3cc54291e463384712f44f32ba4996c02045966f", 4 | "version": 1, 5 | "vin": [ 6 | { 7 | "scriptSig": { 8 | "asm": "3045022100a178c9accd7972cfe30a03c98ff5f684bdf0b144eb415f4a4b7fcff596283f720220267f68a6413093b97a42ed5c2f2811193c1bbdd07d668e3076f99751044c347a01 02f4aef682535628a7e0492b2b5db1aa312348c3095e0258e26b275b25b10290e6", 9 | "hex": "483045022100a178c9accd7972cfe30a03c98ff5f684bdf0b144eb415f4a4b7fcff596283f720220267f68a6413093b97a42ed5c2f2811193c1bbdd07d668e3076f99751044c347a012102f4aef682535628a7e0492b2b5db1aa312348c3095e0258e26b275b25b10290e6" 10 | }, 11 | "sequence": 4294967295, 12 | "txid": "8fd9f689f158a426867215dbdee58e9eab6c818097d4bf2bcf0bd1458f3c55ab", 13 | "vout": 2 14 | } 15 | ], 16 | "vout": [ 17 | { 18 | "n": 0, 19 | "scriptPubKey": { 20 | "addresses": [ 21 | "12pv1K6LTLPFYXcCwsaU7VWYRSX7BuiF28" 22 | ], 23 | "asm": "OP_DUP OP_HASH160 1407ec32be440f32fc70f4eea810acd98f32aa32 OP_EQUALVERIFY OP_CHECKSIG", 24 | "hex": "76a9141407ec32be440f32fc70f4eea810acd98f32aa3288ac", 25 | "reqSigs": 1, 26 | "type": "pubkeyhash" 27 | }, 28 | "value": 5.43e-05 29 | }, 30 | { 31 | "n": 1, 32 | "scriptPubKey": { 33 | "addresses": [ 34 | "17MPn1QXt1SLqKWy3NPmJQ7iT5dJKRhCU7", 35 | "12oEzNKh5TQpKDP1vfeTGnSjoxkboo1m5u", 36 | "1AuTJDwH6xNqxRLEjPB7m86dgmerYVQ5G1" 37 | ], 38 | "asm": "1 0276d539826e5ec10fed9ef597d5bfdac067d287fb7f06799c449971b9ddf9fec6 02af7efeb1f7cf0d5077ae7f7a59e2b643c5cd01fb55221bf76221d8c8ead92bf0 02f4aef682535628a7e0492b2b5db1aa312348c3095e0258e26b275b25b10290e6 3 OP_CHECKMULTISIG", 39 | "hex": "51210276d539826e5ec10fed9ef597d5bfdac067d287fb7f06799c449971b9ddf9fec62102af7efeb1f7cf0d5077ae7f7a59e2b643c5cd01fb55221bf76221d8c8ead92bf02102f4aef682535628a7e0492b2b5db1aa312348c3095e0258e26b275b25b10290e653ae", 40 | "reqSigs": 1, 41 | "type": "multisig" 42 | }, 43 | "value": 2.5e-05 44 | }, 45 | { 46 | "n": 2, 47 | "scriptPubKey": { 48 | "addresses": [ 49 | "1AuTJDwH6xNqxRLEjPB7m86dgmerYVQ5G1" 50 | ], 51 | "asm": "OP_DUP OP_HASH160 6ca4b6b20eac497e9ca94489c545a3372bdd2fa7 OP_EQUALVERIFY OP_CHECKSIG", 52 | "hex": "76a9146ca4b6b20eac497e9ca94489c545a3372bdd2fa788ac", 53 | "reqSigs": 1, 54 | "type": "pubkeyhash" 55 | }, 56 | "value": 0.0008634 57 | } 58 | ] 59 | } -------------------------------------------------------------------------------- /examples/example-broadcast.json: -------------------------------------------------------------------------------- 1 | { 2 | "status" : "success", 3 | "data" : { 4 | "network" : "BTC", 5 | "txid" : "cb90b267711165167a9ac82fa4ca1e561ae7d740b244bee98589523b04112241", 6 | "blockhash" : "000000000000000011a01872c6ee47dbe978dbf159ea44f0850c56fd1bbe599b", 7 | "block_no" : 350856, 8 | "confirmations" : 116, 9 | "time" : 1428251308, 10 | "version" : 1, 11 | "locktime" : 0, 12 | "sent_value" : "0.04870180", 13 | "fee" : "0.00010000", 14 | "inputs" : [ 15 | { 16 | "input_no" : 0, 17 | "address" : "1EcsAJ1LdZw3NyAzNWhgeYkh3ky2gqsAt5", 18 | "value" : "0.04870180", 19 | "received_from" : { 20 | "txid" : "0eb83afffb0a932cd26c3fef3a7d7e44b28fd72052c60894ca09ce0b143e6f19", 21 | "output_no" : 1 22 | }, 23 | "script_asm" : "304402207ff1951b0f11fbc7057ec1e5b411b0d571e4038bcf853a0cc03f3216704610ee022032cfce765285582ec9a5000c2e63ad8f37689ee85de425740e439fcf12b7cb1201 0304b91a4a3cba75b8fe2147d5ecc803111ba599c2e687d3e248d774b54bf0661d", 24 | "script_hex" : "47304402207ff1951b0f11fbc7057ec1e5b411b0d571e4038bcf853a0cc03f3216704610ee022032cfce765285582ec9a5000c2e63ad8f37689ee85de425740e439fcf12b7cb1201210304b91a4a3cba75b8fe2147d5ecc803111ba599c2e687d3e248d774b54bf0661d" 25 | } 26 | ], 27 | "outputs" : [ 28 | { 29 | "output_no" : 0, 30 | "address" : "13pkANCBZFiH38Nr4s7WdhAMabyhguxwXq", 31 | "value" : "0.00007800", 32 | "type" : "multisig", 33 | "req_sigs" : 1, 34 | "spent" : null, 35 | "script_asm" : "1 039dcd0f4d061e6e484bdbb55ad08bef330e227d4fff77161442741a31a247dc35 0297ebaa744b178d6dae2096142eb187530895d2b307b8c62af8969c5cc5f8a7fe 0304b91a4a3cba75b8fe2147d5ecc803111ba599c2e687d3e248d774b54bf0661d 3 OP_CHECKMULTISIG", 36 | "script_hex" : "5121039dcd0f4d061e6e484bdbb55ad08bef330e227d4fff77161442741a31a247dc35210297ebaa744b178d6dae2096142eb187530895d2b307b8c62af8969c5cc5f8a7fe210304b91a4a3cba75b8fe2147d5ecc803111ba599c2e687d3e248d774b54bf0661d53ae" 37 | }, 38 | { 39 | "output_no" : 1, 40 | "address" : "1EcsAJ1LdZw3NyAzNWhgeYkh3ky2gqsAt5", 41 | "value" : "0.04852380", 42 | "type" : "pubkeyhash", 43 | "req_sigs" : 1, 44 | "spent" : null, 45 | "script_asm" : "OP_DUP OP_HASH160 956210c4aec38eb7e4af31715a0d11d5936d85ed OP_EQUALVERIFY OP_CHECKSIG", 46 | "script_hex" : "76a914956210c4aec38eb7e4af31715a0d11d5936d85ed88ac" 47 | } 48 | ], 49 | "tx_hex" : "0100000001196f3e140bce09ca9408c65220d78fb2447e7d3aef3f6cd22c930afbff3ab80e010000006a47304402207ff1951b0f11fbc7057ec1e5b411b0d571e4038bcf853a0cc03f3216704610ee022032cfce765285582ec9a5000c2e63ad8f37689ee85de425740e439fcf12b7cb1201210304b91a4a3cba75b8fe2147d5ecc803111ba599c2e687d3e248d774b54bf0661dffffffff02781e000000000000695121039dcd0f4d061e6e484bdbb55ad08bef330e227d4fff77161442741a31a247dc35210297ebaa744b178d6dae2096142eb187530895d2b307b8c62af8969c5cc5f8a7fe210304b91a4a3cba75b8fe2147d5ecc803111ba599c2e687d3e248d774b54bf0661d53ae9c0a4a00000000001976a914956210c4aec38eb7e4af31715a0d11d5936d85ed88ac00000000" 50 | }, 51 | "code" : 200, 52 | "message" : "" 53 | } -------------------------------------------------------------------------------- /spec/03-encoding.md: -------------------------------------------------------------------------------- 1 | # Encoding a transaction 2 | 3 | ## Preface 4 | 5 | These instructions assume transaction data returned from the bitcoin core reference client as of version 0.9 6 | 7 | 8 | ## build the counterparty data 9 | 10 | Build the transaction specific data. Then encode the using one of the following methods 11 | 12 | 1. [OP_RETURN](#encoding-using-op_return) 13 | 2. [OP_CHECKSIG](#encoding-using-op_checksig) 14 | 3. [OP_CHECKMULTISIG](#encoding-using-op_checkmultisig) 15 | 16 | 17 | ### Encoding using OP_RETURN 18 | 19 | The data is encoded as an OP_RETURN script in the transaction. 20 | 21 | The OP_RETURN data begins with CNTRPRTY (8 bytes) and the remaining 72 bytes may be used for the transaction type and data. 22 | 23 | 24 | ``` 25 | 434e545250525459|00000000|000000000004fadf000000174876e800000000000000000000000000 26 | | | | 27 | | | └── All of this is the operation data (maximum 68 bytes) 28 | | └──────────────── This is the transaction type identifier (4 bytes) 29 | └───────────────────────────────── The string CNTRPRTY in hexadecimal (8 bytes) 30 | ``` 31 | 32 | EXAMPLE: 33 | https://chain.so/api/v2/tx/BTC/8a1d4c5308b7b47134b64fec8dfcb501b38d8ac57c2b7e8f1666a0536e36927e 34 | 35 | 36 | 37 | ### Encoding using OP_CHECKSIG 38 | 39 | (not written yet) 40 | 41 | 42 | ### Encoding using OP_CHECKMULTISIG 43 | 44 | If necesary, pad the operation specific data with zeros to make it 49 bytes long. 45 | 46 | The entire transaction data is 62 bytes long. Begin by assembling the length of the data, the string CNTRPRTY, a transaction type id and the padded transaction data. 47 | 48 | ``` 49 | 1c|434e545250525459|00000000|000000000004fadf000000174876e800000000000000000000000000000000000000000000000000000000000000000000 50 | | | | | 51 | | | | └── All of this is the operation data (49 bytes) 52 | | | └──────────────── This is the transaction type identifier (4 bytes) 53 | | └───────────────────────────────── The string CNTRPRTY in hexadecimal (8 bytes) 54 | └──────────────────────────────────────────── The length of the counterparty data (1 btye) 55 | ``` 56 | 57 | Now, obfuscate this data using ARC4 encoding. The key is the txid of the first transaction input for the new transaction you are building. 58 | 59 | Split the 62 bytes of data into 2 parts of 31 bytes each. 60 | 61 | For each 31 byte part, create a valid 33 byte public key. To create a public key, append `0x02` or `0x03` at the beginning and guess the last 2 bytes that make the checksum valid. 62 | 63 | ``` 64 | NOTE: This is not ARC4 Encoded - need to fix this example 65 | 02|000000000004fadf000000174876e80|FF 66 | | | | 67 | | | └── Randomly guessed checksum byte 68 | | └───────────────────────── 31 bytes of data 69 | └────────────────────────────────────────── Either 02 or 03 70 | ``` 71 | 72 | The last public key in the send transaction is the sender's public key. This allows the sender to reclaim the BTC dust used in the transaction at a later time. 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /spec/02-decoding.md: -------------------------------------------------------------------------------- 1 | # Decoding a transaction 2 | 3 | ## Preface 4 | 5 | These instructions assume transaction data returned from the bitcoin core reference client as of version 0.9 6 | 7 | 8 | ## Process vouts 9 | 10 | To decode a transaction, begin by iterating over each output (vout). When finished iterating over all the vouts, we will have 2 pieces of data: 11 | 12 | 1. A destination addresses or an array of destination addresses 13 | 2. Some binary data called `counterpartydata` 14 | 15 | For each vout, do the following: 16 | 17 | ### Step 1: Determine the type of output. 18 | 19 | Look at the last operator in the script stack of the output. This is found in `scriptPubKey.asm`. This must be one of: 20 | 21 | 1. [OP_RETURN](#decoding-op_return) 22 | 2. [OP_CHECKSIG](#decoding-op_checksig) 23 | 3. [OP_CHECKMULTISIG](#decoding-op_checkmultisig) 24 | 25 | ### Step 2: Interpret the data for this output 26 | 27 | Decode the data for this output. See [decoding data](#decoding-a-vout). 28 | 29 | The decoded data will either be a destination address or a `datachunk`. 30 | 31 | If the decoded data is a destination address, then add this destination address to `destinations`. 32 | 33 | If the decoded data is a `datachunk`, then append the `datachunk` to the `counterpartydata`. 34 | 35 | 36 | ## Decoding a vout 37 | 38 | The decoded data will either be a destination address or a `datachunk`. 39 | 40 | Begin by looking at the last operator in the script stack of the output. This is found in `scriptPubKey.asm`. Based on the type of operator, the data will be decoded in one of three ways. 41 | 42 | ### Decoding OP_RETURN 43 | 44 | An OP_RETURN transaction contains the counterparty transaction data entirely encoded in the 40 byte OP_RETURN transaction. 45 | 46 | To decode the data, do the following 47 | 48 | 1. Deobfuscate the OP_RETURN data using the ARC4 cipher. 49 | 2. Verify that the data chunk begins with CNTRPRTY 50 | 51 | The data chunk beginning with the 9th byte (after CNTRPRTY) is the decoded data. 52 | 53 | #### Example decoding OP_RETURN 54 | 55 | `this example is not written yet` 56 | 57 | 58 | ### Decoding OP_CHECKSIG 59 | 60 | not written yet 61 | 62 | 63 | ### Decoding OP_CHECKMULTISIG 64 | 65 | An OP_CHECKMULTISIG transaction contains either 2 or 3 pubkeys in its script. The first 1 or 2 pubkeys hold the encoded transaction data. The last pubkey is a destination pubkey and does not contain counterparty data. 66 | 67 | To decode the data, do the following 68 | 69 | 1. Make a combined data chunk. Combine the 1 or 2 data pubkeys by strippping the first and last bytes of each and appending them together as binary data. 70 | 2. Deobfuscate this combined data chunk using the ARC4 cipher. 71 | 3. Strip the first byte from the combined data chunk 72 | 4. Verify that combined data chunk, begins with CNTRPRTY 73 | 74 | The combined data chunk beginning with the 9th byte (after CNTRPRTY) is the decoded data. 75 | 76 | 77 | #### Example decoding OP_CHECKMULTISIG 78 | 79 | Given this hexadecimal representation of the script (ASM): 80 | 81 | ``` 82 | 1 83 | 0276d539826e5ec10fed9ef597d5bfdac067d287fb7f06799c449971b9ddf9fec6 84 | 02af7efeb1f7cf0d5077ae7f7a59e2b643c5cd01fb55221bf76221d8c8ead92bf0 85 | 02f4aef682535628a7e0492b2b5db1aa312348c3095e0258e26b275b25b10290e6 86 | 3 87 | OP_CHECKMULTISIG 88 | ``` 89 | 90 | We will do the following steps: 91 | 92 | 1) Make a combined data chunk 93 | 94 | Ignore the first and last bytes of each pubkey hash 95 | 96 | ``` 97 | 02|76d539826e5ec10fed9ef597d5bfdac067d287fb7f06799c449971b9ddf9fe|c6 98 | xx xx 99 | 100 | + 101 | 102 | 02|af7efeb1f7cf0d5077ae7f7a59e2b643c5cd01fb55221bf76221d8c8ead92b|f0 103 | xx xx 104 | ``` 105 | 106 | The combined data chunk is: 107 | 108 | ``` 109 | 76d539826e5ec10fed9ef597d5bfdac067d287fb7f06799c449971b9ddf9fe 110 | af7efeb1f7cf0d5077ae7f7a59e2b643c5cd01fb55221bf76221d8c8ead92b 111 | ``` 112 | 113 | 114 | 2) Deobfuscate with ARC4 115 | 116 | After deobfuscating, the data chunk is 117 | 118 | ``` 119 | 1c434e54525052545900000000000000000004fadf000000174876e8000000 120 | 00000000000000000000000000000000000000000000000000000000000000 121 | ``` 122 | 123 | 124 | 3) Strip the first byte from the combined data chunk 125 | and 126 | 4) Verify that combined data chunk, begins with CNTRPRTY 127 | 128 | ``` 129 | 1c|434e545250525459|00000000|000000000004fadf000000174876e800000000000000000000000000000000000000000000000000000000000000000000 130 | | | | | 131 | | | | └───── All of this is the transaction data (49 bytes) 132 | | | └─────────────── This is the transaction type identifier (4 bytes) 133 | | └───────────────────────────────── the string CNTRPRTY in hexadecimal (8 bytes) 134 | └─────────────────────────────────────────────── Ignore the first byte 135 | ``` 136 | 137 | 138 | 139 | ## Decoding counterpartydata 140 | 141 | After finished with the processing of the vouts, you will have the `destinations` and `counterpartydata`. 142 | 143 | The counterparty data looks like this 144 | 145 | ``` 146 | 434e545250525459|FFFFFFFF|xxxxxx... 147 | | | | 148 | | | └───── this data is different for each transaction type 149 | | └──────────────── the transaction type identifier (4 bytes) 150 | └──────────────────────────────── the string CNTRPRTY (8 bytes) 151 | ``` 152 | 153 | The first 8 bytes of the `counterpartydata` must be the string CNTRPRTY (Or `434e545250525459` in hexadecimal). 154 | 155 | The next 4 bytes of the contain a 4 byte integer representing the type of the transaction. The types of transactions and ID numbers are 156 | 157 | ID | Transaction type 158 | ---|----------------- 159 | 0 | [Send](#decoding-sends) 160 | 20 | Issuance 161 | 30 | Broadcast 162 | .. | (this list is incomplete) 163 | 164 | 165 | 166 | 167 | 168 | 169 | --------------------------------------------------------------------------------