Skip to content

Instantly share code, notes, and snippets.

@ripper234
Created January 17, 2012 09:21
Show Gist options
  • Save ripper234/1625828 to your computer and use it in GitHub Desktop.
Save ripper234/1625828 to your computer and use it in GitHub Desktop.
How to decode messages stored in the Bitcoin blockchain with btcmsg
# directly from the web:
from protocol import read_msg
def get_msg_from_transaction(url):
import json
import urllib2
data = urllib2.urlopen(url)
j = json.load(data)
out=j['out']
values=[]
for v in out:
values.append(v['value'])
return read_msg(values)
def test():
message=get_msg_from_transaction('http://blockexplorer.com/tx/cc2fa5a40cdbaad70826040fe7fe4bec34ddfaefd358ca1e2a7957f1d5941738')
print message
test()
import binascii
# A fixed fee for any message (Satoshi) 0.005 BTC
FIXED_COSTS=500000
# Additional fee for each transaction value entry (Satoshi) 0.0005 BTC
VARIABLE_COSTS=50000
RESERVED_IDENTIFIER='00'
MD5SUM_IDENTIFIER='01'
ASCII_IDENTIFIER='02'
def write_msg(h,data_type):
output=[]
# First transaction value with costs (placeholder)
output.append('')
# Mark data type with 2 more decimal digits (100 options).
if data_type=='md5':
x=h
# Verify h is 32 hexadecimal chars long
if len(x) != 32:
print 'md5 must be exactly 32 chars long'
return ([],'')
for j in range(32):
if x[j]<'0' or x[j]>'f':
print 'md5 chars are only 0-9,a-f'
return ([],'')
# Split to groups with char length
# 2,4,4,...,4,2
s=[]
s.append(MD5SUM_IDENTIFIER+h[:2]) # Mark md5 msg with MD5SUM_IDENTIFIER
for i in range(7):
s.append(h[2+i*4:6+i*4])
s.append(h[30:33]+'00')
for t in s:
output.append('0.'+'%08d' % (int(t,16)))
if data_type=='ascii':
# Verify that it is an ascii string (limited with length)
x=binascii.hexlify(h)
# Split to groups with char length
# 2,4,4,...,4,2
s=[]
x=ASCII_IDENTIFIER+x # Mark ascii msg with header ASCII_IDENTIFIER
for i in range(len(x)/4):
s.append(x[i*4:(i+1)*4])
if h[(i+1)*4:] != '':
s.append(h[(i+1)*4:]+'00')
for t in s:
output.append('0.'+'%08d' % (int(t,16),))
# Update variable fee
output[0]=str((0.0+int(FIXED_COSTS)+len(output)*int(VARIABLE_COSTS))/10000000)
return (output,x)
def read_msg(h):
try:
# Ignore first entry (where the fee is stored)
h=h[1:]
except IndexError:
pass
s=''
for a in h:
tmp=a[3:]
tmp=int(tmp)
s+="%05d" % (tmp,)
l=[]
for i in range(len(h)):
l.append('%04x' % (int(s[i*5:(i+1)*5])))
try:
data_type = l[0][:2]
except IndexError:
print 'Error parsing list %s' % str(l)
return ''
if data_type == MD5SUM_IDENTIFIER: # md5
x=''
for t in l:
x+=t
return x[2:-2]
else:
if data_type == ASCII_IDENTIFIER: # ascii
x=''
for t in l:
x+=t
m=x[2:]
return binascii.unhexlify(m)
else:
print 'Unrecognized data type %s' % (data_type,)
def price(h):
p=0
for a in h:
p+=float(a)
return round(p,8)
BTCmsg Protocol v1 (2011-09-18)
===============================
Each message is represented by multiple payment which is calculated by
the following algorithm:
1. Two first chars for message type ('01' for md5, '02' for ascii).
2. Then the message in hex (python binascii.hexlify).
3. Split the long string to groups of 4 hex digits.
4. Each group of 4 hex (e.g. 2 ascii letters from the message) is
represented by a payment in satoshi (maximum 0xffff=65535).
5. The service fee (composed of a fixed part and a variable part times
the amount of small payments required, minus the transaction fee),
can be seen within the first transaction.
Enjoy!
Extra link to msgdump.tzg: http://dl.dropbox.com/u/464119/Bitcoin/btcmsg/msgdump.tgz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment