Dissecting Counterparty Transactions in Bitcoin

In this post in The Newbies thread, Sdouglas asks about where transaction data is stored in Bitcoin transactions today. This is a good topic for understanding so I'm making this thread to try to put what is now only in the code into words. Perhaps we can update the github documentation on the Counterparty protocol spec with this info or create another document there for those who want to see deeper into Counterparty.

Where in a Bitcoin transaction the additional Counterparty information is stored?

According to the protocol specification, additional data for Counterparty transactions can be stored as data after an OP_RETURN in a Bitcoin output or in another way. Currently, this data is stored in additional addresses in a mulit-signature transaction. Perhaps later it'll be stored via a hash pointing to a Distributed Hash Table but today, it's in a multisig output with 2 or more addresses.

Let's look at an example. I just looked through the recent transactions at blockscan.com and clicked on one that sent XCP from one address to another. The blockchain.info page for the transaction has a section at the bottom called Output Scripts. In that section was the following line:

OP_1 039513017d24f382623eb88e761258b3c4ba89f8751eae9ed19bfe52c19b32c900<br />1c434e545250525459000000000000000000000001000000057227138000000000 <br />OP_2 OP_CHECKMULTISIG

The string starting 0395 refers to the address of the sender. This allows them to get back the 0.00078 btc they sent by collecting it with a later transaction. The string that starts 1c434 is where the XCP data is stored. I guess it needs to say in there how much XCP is being sent.

Counterparty is coded in python and when I looked at the code, I found that data was packed using Python's struct.pack. Since decoding that might take a little figuring, I'm going to post this as a starting point and continue below.

Let me know if you have any questions.


[size=2][font=verdana]Just wanted to give this a bump.

I'd really like to understand where the 1c434e54250525490 string comes from

Is there some way you can go from [/font][/size][size=2][font=verdana]1c434e54250525490 to 'CNTRPRTY' and back again?

Many thanks

[quote author=sdouglas link=topic=490.msg3181#msg3181 date=1409088360]
[size=1em][font=verdana]Just wanted to give this a bump.

I'd really like to understand where the 1c434e54250525490 string comes from

Is there some way you can go from [/font][/size][size=1em][font=verdana]1c434e54250525490 to 'CNTRPRTY' and back again?

Many thanks

That hexadecimal is the UTF-8 (or ASCII) encoding of the string 'CNTRPTRY'.

Wonderful, thank you  :slight_smile:

I guess that the protocol was changed compared to August 2014.

When I sent XCP from one address to another, I got this output script below.

OP_1 03bbe265b3a367a1f5d91d65ec47ec54857861d370073d2058054190049e90da37 032cfc2c5b1fa2dc714b806cf01f8bf7d5aabc1eef7c8923fc8bf6275b84f22336 02f6c8f901926662f7bfb2cf3d8303b6830b135a2fb090be7c805c0f52e57e1ef5 OP_3 OP_CHECKMULTISIG 


According to the protocol document, all of the data is obfuscated by ARC4 encryption using the public key of the first sender as the encryption key.

I tried to get "1c434e545250525459..." string by using node.js but it did not work.

var rc4 = require('arc4');

var cipher = rc4('arc4', '17sdLuNtD7ZpFCVZ3Doz58fwxFF6i6CKk2');
var e = cipher.decodeString('02f6c8f901926662f7bfb2cf3d8303b6830b135a2fb090be7c805c0f52e57e1ef5');
console.log(e); // I got unreadable response 

Does the public key mean Bitcoin address of the sender?

@zono a bitcoin address is a hash of the public key.