transactions – What’s a step-by-step method to insert knowledge in OP_RETURN?

0
29
transactions – What’s a step-by-step method to insert knowledge in OP_RETURN?


I wrote slightly demo program which places a snippet of information into an OP_RETURN script. It requires a bitcoin occasion that accepts RPC connections, although it might be carried out with out that. Yow will discover it on github right here. It has been examined, however solely on testnet. I will undergo the code and clarify what it is doing.

Begin

[...]
logging.basicConfig()
logging.getLogger("BitcoinRPC").setLevel(logging.DEBUG)

This makes logging extra verbose. It is useful as a result of it exhibits what RPC calls are being made.

Connect with bitcoind

rpc_user = "bitcoinrpc"
rpc_password = "87Y9A2gs25E9HDPGc9axqSqzxMR2MyTtrMkYc5KiZk2Z"

rpc = AuthServiceProxy("http://%s:%[email protected]:18332/" % (rpc_user, rpc_password))

Be aware that your password might be totally different, and that you just use port 8332 for mainnet as an alternative of port 18332.

Checklist unspent outputs

first_unspent = rpc.listunspent()[0]
txid = first_unspent['txid']
vout = first_unspent['vout']
input_amount = first_unspent['amount']
SATOSHI = Decimal("0.00000001")
change_amount = input_amount - Decimal("0.005") - SATOSHI

The - Decimal("0.005") half is in order that we pay a transaction price.

Create transaction

# Marker deal with we'll change
# Produces a sample that is straightforward to seek for
mainnet = 0
if mainnet:
    dummy_address = "1111111111111111111114oLvT2"
else:
    dummy_address = "mfWxJ45yp2SFn7UciZyNpvDKrzbhyfKrY8"

These are two totally different encodings of a Pay to Public Key Hash of all zeros. The highest one is the mainnet illustration, and the underside is the testnet illustration.

# My change deal with
change_address = "mhZuYnuMCZLjZKeDMnY48xsR5qkjq7bAr9"

Keep in mind, that is my change deal with. Should you do not change it, you will be sending cash to me.

tx = rpc.createrawtransaction([{"txid": txid, "vout": vout}], 
                              {change_address: change_amount, 
                               dummy_address: SATOSHI})

And now we have now an precise transaction. It would not comprise any of our personal knowledge although, so we’ll have to repair that.

Change dummy output with our personal output

# Sample to interchange
# Represents size of script, then OP_DUP OP_HASH160,
# then size of hash, then 20 bytes of zeros, OP_EQUALVERIFY OP_CHECKSIG
oldScriptPubKey = "1976a914000000000000000000000000000000000000000088ac"

This can be a little bit of a hack. As a substitute of making our personal output, we create a dummy output, then seek for the sample it makes and change it. There’s in all probability a greater approach to do that, however this appears best.

# Information to insert
knowledge = "Melons."
if len(knowledge) > 75:
    elevate Exception("Cannot comprise this a lot data-use OP_PUSHDATA1")

newScriptPubKey = "6a" + hexlify(chr(len(knowledge))) + hexlify(knowledge)

Subsequent we create the info we wish to put into the blockchain. I am utilizing the string Melons., however you would use something. (Above 40 bytes is nonstandard, although.) I lined most of this in my different reply.

This code will break if the info is longer than 75 bytes. Should you want it for greater than that, you would use OP_PUSHDATA1 as an alternative of the single-byte pushdata that I am utilizing right here.

#Append int of size to start out
newScriptPubKey = hexlify(chr(len(unhexlify(newScriptPubKey)))) + newScriptPubKey

This half is slightly totally different than my different reply, as a result of we have to embody the size of the scriptPubKey additionally. This code will break with knowledge longer than 251 bytes. If you would like it to work on knowledge longer than that, encode a varint appropriately.

if oldScriptPubKey not in tx:
    elevate Exception("One thing broke!")

Error checking for this very rickety technique.

tx = tx.change(oldScriptPubKey, newScriptPubKey)

Lastly, a string change swaps the brand new script for the outdated one.

Signal it

tx = rpc.signrawtransaction(tx)['hex']

Bitcoin handles the heaving lifting right here.

Broadcast it to the community.

rpc.sendrawtransaction(tx)

Finished! Now simply wait in your transaction to get right into a block.

I ran the code (output), and I produced a transaction, which you’ll see in Block Explorer right here. Should you copy the string subsequent to OP_RETURN, and paste it right into a Hex to ASCII converter, you get…

Melons.

Finished!

Different sources

I discovered this webpage useful whereas scripting this.

LEAVE A REPLY

Please enter your comment!
Please enter your name here