# 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