I have forked the pybitcointools library to return a properly formatted OP_RETURN
hex string, or insert the OP_RETURN
into a raw hex transaction.
My fork can be found here. The code is as follows:
from bitcoin.pyspecials import safe_hexlify, from_string_to_bytes, from_int_to_byte, from_string_to_bytes
def mk_opreturn(msg, rawtx=None, json=0):
def op_push(data):
import struct
if len(data) < 0x4c:
return from_int_to_byte(len(data)) + from_string_to_bytes(data)
elif len(data) < 0xff:
return from_int_to_byte(76) + struct.pack('<B', len(data)) + from_string_to_bytes(data)
elif len(data) < 0xffff:
return from_int_to_byte(77) + struct.pack('<H', len(data)) + from_string_to_bytes(data)
elif len(data) < 0xffffffff:
return from_int_to_byte(78) + struct.pack('<I', len(data)) + from_string_to_bytes(data)
else: raise Exception("Input data error. Rawtx must be hex chars" \
+ "0xffffffff > len(data) > 0")
orhex = safe_hexlify(b'\x6a' + op_push(msg))
orjson = {'script' : orhex, 'value' : 0}
if rawtx is not None:
try:
txo = deserialize(rawtx)
if not 'outs' in txo.keys(): raise Exception("OP_Return cannot be the sole output!")
txo['outs'].append(orjson)
newrawtx = serialize(txo)
return newrawtx
except:
raise Exception("Raw Tx Error!")
return orhex if not json else orjson
Note that the module name has been changed to btc
(from bitcoin
) in my fork.
To run this, you'll use os.chdir("c:/python/pybitcointools")
(or whatever directory it's been downloaded to. Then from bitcoin import *
. Now, let's use msg = 'The enemy of my enemy is my friend'
and rawtx = "01000000016e3cd2b24fcf49259db29888ec5fe6521070041cb8c7bb2017537046f9e00f2b0000000000ffffffff0168d61100000000001976a91469bbbb16301e40b9fb67130e1aa53a2281d60af088ac00000000"
.
mk_opreturn(msg, rawtx)
returns:
01000000016e3cd2b24fcf49259db29888ec5fe6521070041cb8c7bb2017537046f9e00f2b0000000000ffffffff0268d61100000000001976a91469bbbb16301e40b9fb67130e1aa53a2281d60af088ac0000000000000000246a2254686520656e656d79206f66206d7920656e656d79206973206d7920667269656e6400000000
This is the raw Tx with the OP_RETURN
properly inserted. Run the function without the rawtx
parameter and it returns the string 6a2254686520656e656d79206f66206d7920656e656d79206973206d7920667269656e64