Wednesday, February 19, 2025
HomeBitcointransactions - What's a step-by-step solution to insert knowledge in OP_RETURN?

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


I wrote just a little 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 applied with out that. You will discover it on github right here. It has been examined, however solely on testnet. I’ll 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 reveals 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))

Observe that your password will probably be completely different, and that you just use port 8332 for mainnet as a substitute of port 18332.

Record 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 payment.

Create transaction

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

These are two completely 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"

Bear in mind, that is my change deal with. When you do not change it, you may be sending cash to me.

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

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

Exchange 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"

It is 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 most likely a greater manner to do that, however this appears best.

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

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

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

This code will break if the info is longer than 75 bytes. When you want it for greater than that, you would use OP_PUSHDATA1 as a substitute 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 just a little completely 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’d like it to work on knowledge longer than that, encode a varint accurately.

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

Error checking for this very rickety methodology.

tx = tx.change(oldScriptPubKey, newScriptPubKey)

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

Signal it

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

Bitcoin handles the heaving lifting right here.

Broadcast it to the community.

rpc.sendrawtransaction(tx)

Performed! 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 be able to see in Block Explorer right here. When you copy the string subsequent to OP_RETURN, and paste it right into a Hex to ASCII converter, you get…

Melons.

Performed!

Different assets

I discovered this webpage useful whereas penning this.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments