<p>If you want to write OP_RETURNs to the blockchain without getting into the internals of how transactions are built, an easy way is to use our libraries for PHP and Python:</p>

<p><a href="https://github.com/coinspark/php-OP_RETURN" rel="noreferrer">https://github.com/coinspark/php-OP_RETURN</a></p>

<p><a href="https://github.com/coinspark/python-OP_RETURN" rel="noreferrer">https://github.com/coinspark/python-OP_RETURN</a></p>

<p>These support either sending individual transactions with one OP_RETURN attached, or else sending a batch of linked transactions to embed larger pieces of content. That content can then be retrieved from the blockchain using a single identifier.</p>

<p>Assuming you're using Bitcoin Core 0.11, you can change the value of <code>OP_RETURN_MAX_BYTES</code> to <code>80</code>, rather than <code>40</code> as it currently stands in the code.</p>

CC BY-SA 3.0
2015-09-21T05:44:27.203Z
2015-09-21T05:44:27.203Z
Gideon Greenspan
<p><strong><code>OP_RETURN</code> is a way to get arbitrary data into the blockchain with less burden to the network</strong></p>
<p>As a consequence, the data will also be present in less clients, as <code>OP_RETURN</code> data can be pruned out.</p>
<p>The goal of this answer is to explain what <a href="https://bitcoin.stackexchange.com/a/29555/21282">https://bitcoin.stackexchange.com/a/29555/21282</a> explained but with a bit more context for Bitcoin newbies.</p>
<p><strong>How a standard transaction looks like</strong></p>
<p>As seen in the JSON disassembly from <a href="https://bitcoin.stackexchange.com/a/29555/21282">https://bitcoin.stackexchange.com/a/29555/21282</a> each transaction has a list of outputs, and each output has a script.</p>
<p>The <a href="https://bitcoin.stackexchange.com/questions/5883/is-there-a-listing-of-strange-or-unusual-scripts-found-in-transactions/105392#105392">most common script by far</a> is <a href="https://en.bitcoin.it/wiki/Script#Standard_Transaction_to_Bitcoin_address_.28pay-to-pubkey-hash.29" rel="nofollow noreferrer">pay-to-pubkey-hash</a> which basically says:</p>
<blockquote>
<p>this output can be consumed by the person who controls the private key to this public key</p>
</blockquote>
<p>or in simpler terms &quot;pay X bitcoint to address Y&quot;.</p>
<p>That script has format:</p>
<pre><code>OP_DUP OP_HASH160 &lt;length-of-hash&gt; &lt;pubKeyHash&gt; OP_EQUALVERIFY OP_CHECKSIG
</code></pre>
<p>where pubKeyHash is 20 bytes and all other 5 fields are 1 byte.</p>
<p><strong>It is impossible to know if a standard transaction hash is an actual hash or arbitrary data</strong></p>
<p>Because <code>pubKeyHash</code> is a hash, it is impossible to know if that is the actual hash of something, or arbitrary data someone wants to encode into the blockchain.</p>
<p>The catch is: if you add arbitrary data there, you won't have a corresponding private key to claim back those funds. So what people do is to make transactions with the smallest amount possible that miners are willing to take for the verification work.</p>
<p>Now, every transaction in the blockchain takes as input a previous unspent output.</p>
<p>Therefore, embedding this data costs you a little, because that output is unspendable: it can never be used as an input of another transaction.</p>
<p>In order to verify if a transaction is valid, Bitcoin implementations have to keep around a full list of every unspent output ever created, known as the <a href="https://en.bitcoin.it/wiki/UTXO" rel="nofollow noreferrer">UTXO set</a>.</p>
<p>Spent outputs can be pruned to save space, but unspent ones can't.</p>
<p>Therefore, whenever you burn your fake pubkey hash output, you force every single implementation to keep that information around forever, since those funds can never be spent.</p>
<p><strong>How <code>OP_RETURN</code> solves that problem</strong></p>
<p>OP return is another type of script transaction different from the standard pay-to-pubkey-hash transaction.</p>
<p>As mentioned at: <a href="https://en.bitcoin.it/wiki/Script#Provably_Unspendable.2FPrunable_Outputs" rel="nofollow noreferrer">https://en.bitcoin.it/wiki/Script#Provably_Unspendable.2FPrunable_Outputs</a> the transaction has simply the form:</p>
<pre><code>OP_RETURN &lt;data&gt;
</code></pre>
<p><code>OP_RETURN</code> simply stops the script execution with a failure, making it impossible for anyone to use that output as the input of another transaction.</p>
<p>Therefore, when a bitcoin implementation sees that transaction, it can immediately decide that it is unspendable, unlike the pay-to-pubkey-hash transaction above, where it is impossible to make that decision. That's why this transaction is called &quot;provably unspendable&quot;.</p>
<p>So the miner can mine if for a mining fee, but then implementations immediately prune it from the UTXO set.</p>
<p>This allows the UTXO set to be smaller, thus making bitcoin more efficient to everyone.</p>
<p>But on the other hand, it also means that your embedded data will be present in less people's computers.</p>

CC BY-SA 4.0
2021-09-20T01:33:42.103Z
If I "add arbitrary data", won't it make the transaction invalid and not accepted in the blockchain? Or is it just the address of the recipient and instead of putting my own address I just put some arbitrary data?
Rony Tesler
CC BY-SA 4.0
2021-09-20T07:13:26.660Z
@RonyTesler you just put arbitrary data instead of an actual address you control. But since addresses look completely random in nature (they are public keys) it is impossible for peers to distinguish, so it has to be added to the chain. And because you don't have the private key, it is impossible for you (or anyone else) to claim funds later on.
Ciro Santilli OurBigBook.com
CC BY-SA 4.0
2021-01-14T09:05:50.047Z
2021-11-29T13:23:58.730Z
2021-11-29T13:23:58.730Z
Ciro Santilli OurBigBook.com
<p>In case you are here trying to convert OP_RETURN to readable values:</p>

<p><em>Note: This is javascript / typescript</em></p>

<pre><code>export default class OpReturnConverter {

    // Input -&gt; &lt;Buffer 35 33 36 39...&gt;
    // Output -&gt; 53696d706c6520616e737765722120f09f988a
    public static convertBufferToHex(buffer: Buffer) {
        const str = buffer.toString('hex')
        return Buffer.from(str, 'hex').toString()
    }

    // Input -&gt; 53696d706c6520616e737765722120f09f988a
    // Output -&gt; Simple answer! 
    public static convertHexToString(hex: string) {
        return Buffer.from(hex, 'hex').toString()
    }

    // Input -&gt; Simple answer! 
    // Output -&gt; &lt;Buffer 35 33 36 39...&gt;
    public static convertStringToBuffer(message: string) {
        const hexBuffer = Buffer.from(message).toString('hex')
        return Buffer.from(hexBuffer)
    }

}
</code></pre>

<hr>

<p><strong>Results</strong></p>

<pre><code>const string = 'Simple answer! '
console.log('Original -&gt;', string)

const buf = OpReturnConverter.convertStringToBuffer(string)
console.log('Buffer -&gt;', buf)

const hex = OpReturnConverter.convertBufferToHex(buf)
console.log('Hex -&gt;', hex)

const unhex = OpReturnConverter.convertHexToString(hex)
console.log('Unhex -&gt;', unhex)
</code></pre>

CC BY-SA 4.0
2020-04-05T00:45:19.180Z
2020-04-05T00:45:19.180Z
Michael
<p>Note: I went out and learned about how the <code>OP_RETURN</code> opcode works at the byte level in a bitcoin transaction. I’m writing it here so that others can learn quickly. First, a brief history of why we’re even talking about <code>OP_RETURN</code>.</p>

<p>Back in 2013 different players in the bitcoin ecosystem were trying to include bits of information into transactions so that they could take advantage of the irreversibility of the blockchain. Imagine for instance you wanted to write a contract and place it in an unchangeable location that at any future date one could go back to verify it existed. You can do this by using the blockchain. You add some bits to the transaction's scriptSig value that don't alter the end result of running that script, but allow you to store information like “I hereby declare to give asset A to address XYZ at time UNIX_TIMESTAMP”. There were even stranger ways people would add extra bits, like including it in the BTC value of an output. Some members of the community did not like this, as they saw these extra bits as polluting the blockchain. The extra bits were a network efficiency concern because more bits meant larger block chains and more of an onus on those who are running full nodes, and it was also a community consensus concern because they thought “we all implicitly agreed to store financial data in the blockchain, which is important to everyone, but we did not agree to store data like small text messages and invoice text”. </p>

<p>To reach a middle ground in these opposing views, the core-developers made the opcode OP_RETURN a valid opcode to be used in a bitcoin transaction, which allows 80 arbitrary bytes to be used in an unspendable transaction. A good explanation of this can be found here:</p>

<pre><code>https://bitcoinfoundation.org/bitcoin/core-development-update-5/
</code></pre>

<p>Later in February 2014, the bytes count was reduced from 80 to 40 bytes. This change is documented in the link below. Note that in this pull discussion we learn that no more than one output with OP_RETURN can be included in a single transaction:</p>

<pre><code>https://github.com/bitcoin/bitcoin/pull/3737
</code></pre>

<p>Now that we’ve got the reason behind OP_RETURN down, let’s look at an example of OP_RETURN. I used chain.com’s API to find a transaction which has an OP_RETURN in its scriptSig. That tx’s hash is</p>

<pre><code>8bae12b5f4c088d940733dcd1455efc6a3a69cf9340e17a981286d3778615684 
</code></pre>

<p>Make sure you are connected to a fully-loaded bitcoind node, and run this command:</p>

<pre><code>$&gt; bitcoind getrawtransaction 8bae12b5f4c088d940733dcd1455efc6a3a69cf9340e17a981286d3778615684 1
</code></pre>

<p>which will give you this output:</p>

<pre><code>{
"hex" : "0100000001c858ba5f607d762fe5be1dfe97ddc121827895c2562c4348d69d02b91dbb408e010000008b4830450220446df4e6b875af246800c8c976de7cd6d7d95016c4a8f7bcdbba81679cbda242022100c1ccfacfeb5e83087894aa8d9e37b11f5c054a75d030d5bfd94d17c5bc953d4a0141045901f6367ea950a5665335065342b952c5d5d60607b3cdc6c69a03df1a6b915aa02eb5e07095a2548a98dcdd84d875c6a3e130bafadfd45e694a3474e71405a4ffffffff020000000000000000156a13636861726c6579206c6f766573206865696469400d0300000000001976a914b8268ce4d481413c4e848ff353cd16104291c45b88ac00000000",
"txid" : "8bae12b5f4c088d940733dcd1455efc6a3a69cf9340e17a981286d3778615684",
"version" : 1,
"locktime" : 0,
"vin" : [
    {
        "txid" : "8e40bb1db9029dd648432c56c295788221c1dd97fe1dbee52f767d605fba58c8",
        "vout" : 1,
        "scriptSig" : {
            "asm" : "30450220446df4e6b875af246800c8c976de7cd6d7d95016c4a8f7bcdbba81679cbda242022100c1ccfacfeb5e83087894aa8d9e37b11f5c054a75d030d5bfd94d17c5bc953d4a01 045901f6367ea950a5665335065342b952c5d5d60607b3cdc6c69a03df1a6b915aa02eb5e07095a2548a98dcdd84d875c6a3e130bafadfd45e694a3474e71405a4",
            "hex" : "4830450220446df4e6b875af246800c8c976de7cd6d7d95016c4a8f7bcdbba81679cbda242022100c1ccfacfeb5e83087894aa8d9e37b11f5c054a75d030d5bfd94d17c5bc953d4a0141045901f6367ea950a5665335065342b952c5d5d60607b3cdc6c69a03df1a6b915aa02eb5e07095a2548a98dcdd84d875c6a3e130bafadfd45e694a3474e71405a4"
        },
        "sequence" : 4294967295
    }
],
"vout" : [
    {
        "value" : 0.00000000,
        "n" : 0,
        "scriptPubKey" : {
            "asm" : "OP_RETURN 636861726c6579206c6f766573206865696469",
            "hex" : "6a13636861726c6579206c6f766573206865696469",
            "type" : "nulldata"
        }
    },
    {
        "value" : 0.00200000,
        "n" : 1,
        "scriptPubKey" : {
            "asm" : "OP_DUP OP_HASH160 b8268ce4d481413c4e848ff353cd16104291c45b OP_EQUALVERIFY OP_CHECKSIG",
            "hex" : "76a914b8268ce4d481413c4e848ff353cd16104291c45b88ac",
            "reqSigs" : 1,
            "type" : "pubkeyhash",
            "addresses" : [
                "1HnhWpkMHMjgt167kvgcPyurMmsCQ2WPgg"
            ]
        }
    }
],
"blockhash" : "000000000000000004c31376d7619bf0f0d65af6fb028d3b4a410ea39d22554c",
"confirmations" : 2655,
"time" : 1404107109,
"blocktime" : 1404107109
}
</code></pre>

<p>Now, look at this transaction’s list of outputs, in particular the 1st one. By referencing <a href="https://en.bitcoin.it/wiki/Script" rel="noreferrer">the Bitcoin Wiki’s page on Script</a>, Bitcoin’s stack-based programming language, we can see here that the <code>OP_RETURN</code> opcode is represented by the hex value 0x6a. This first byte it followed by a byte which represents the length of the rest of the bytes in the scriptPubKey. In this case we see the hex value Ox13, which means there are 19 more bytes. These bytes comprise the arbitrary less-than-40 bytes you are allowed to send in a transaction marked by the <code>OP_RETURN</code> opcode. If you pop the message bytes into a UTF8 decoder, you’ll see that</p>

<pre><code>636861726c6579206c6f766573206865696469
</code></pre>

<p>becomes “charley loves heidi”. Aw! It’s almost like a digital version of a couple’s romantic heart tree carving. Now you understand at a byte level how <code>OP_RETURN</code> is supposed to work. You can write software now that searches for the <code>OP_RETURN</code> opcode in an output’s scriptPubKey, and use it to verify a contract or some other digital asset.</p>

CC BY-SA 3.0
2014-07-17T22:47:49.460Z
An important aspect of OP_RETURN is that outputs which use it in the standard way are provable unspendable. This means that nodes can immediately remove such outputs from their unspent outputs cache and potentially forget about them altogether (though Bitcoin Core doesn't do this yet). This makes OP_RETURN transactions *much* less expensive for the network than other ways of stuffing data into the block chain.
theymos
CC BY-SA 3.0
2015-02-02T10:34:11.427Z
FYI if anyone is looking to decode that message `636861726c6579206c6f766573206865696469` in php, it's the hex value so use `hex2bin()`
OACDesigns
CC BY-SA 3.0
2015-09-08T08:23:28.460Z
Why does this cost less to the network that just sending 1 satoshi to an arbitrary address that contains the 20 bytes of information itself ?
Nathan Parker
CC BY-SA 3.0
2016-10-20T15:39:55.313Z
@almel Nowadays the command to get the tx details is `bitcoin-cli` and not `bitcoind`.
thalisk
CC BY-SA 3.0
2015-09-16T23:43:53.220Z
@NathanParker Because with OP_RETURN, the node knows that the transaction output index is unspendable and can just ignore it. Whereas when sending 1 satoshi, the node will need to keep that unspent output in memory or in a database, waiting until someone spends it someday.
Nayuki
CC BY-SA 4.0
2018-07-24T19:56:45.663Z
In *NIX the `xxd` command can be used.  `echo 636861726c6579206c6f766573206865696469 | xxd -p -r` returns `charley loves heidi`
user207863
CC BY-SA 4.0
2018-08-24T08:42:34.320Z
How is it possible that [this famous transaction](https://bitcoinsays.com/d29c9c0e8e4d2a9790922af73f0b8d51f0bd4bb19940d9cf910ead8fbe85bc9b) contains more than 80 bytes?
robermann
CC BY-SA 4.0
2018-08-24T09:03:34.827Z
(it pushes 983 bytes)
robermann
CC BY-SA 4.0
2018-09-21T05:57:55.110Z
You say that "no more than one output with OP_RETURN can be included in a single transaction" and provide a pull request as a source for this. Where in this pull request discussion is this mentioned?
dionyziz
CC BY-SA 4.0
2019-03-12T11:43:15.023Z
For those wishing to decode the message using JavaScript, the one-liner in Node would be `Buffer.from('636861726c6579206c6f766573206865696469', 'hex').toString('utf8');`
thalisk
CC BY-SA 4.0
2019-03-12T11:45:06.803Z
According to the [Script wiki](https://en.bitcoin.it/wiki/Script): `it is usually considered non-standard (though valid) for a transaction to have more than one OP_RETURN output or an OP_RETURN output with more than one pushdata op`.
thalisk
CC BY-SA 4.0
2021-09-20T01:10:15.937Z
Why do the bytes I want to save in the blockchain have to come after the OP_RETURN and not before?
Rony Tesler
CC BY-SA 4.0
2021-09-20T01:13:38.350Z
@theymos So this is just a convention/consensus that makes these transaction burn the coins, or there are other technical reasons?
Rony Tesler
CC BY-SA 4.0
2021-09-20T01:17:10.680Z
@theymos https://twitter.com/lopp/status/947507679936774145?lang=en Here they say the coins are not burned.
Rony Tesler
CC BY-SA 4.0
2022-03-17T22:26:24.490Z
Can I include an `addresses` entry in `scriptPubKey` to indicate the recipient of the message?
William Entriken
CC BY-SA 4.0
2014-07-17T22:00:30.860Z
2020-06-15T00:44:31.570Z
2020-06-15T00:44:31.570Z
almel
<p>How is OP_RETURN used and why was it introduced in the first place?</p>

<transactions><protocol><script><op-return>
Explanation of what an OP_RETURN transaction looks like
almel
# Explanation of what an OP_RETURN transaction looks like

(Asked by: username_0 on 2014-07-17)

How is OP\_RETURN used and why was it introduced in the first place?

**Tags:** transactions, protocol, script, op-return


---

## 4 answers

### Answer by username_0 on 2014-07-17. Score: 98 | Accepted answer

Note: I went out and learned about how the `OP_RETURN` opcode works at the byte level in a bitcoin transaction. I’m writing it here so that others can learn quickly. First, a brief history of why we’re even talking about `OP_RETURN`.

Back in 2013 different players in the bitcoin ecosystem were trying to include bits of information into transactions so that they could take advantage of the irreversibility of the blockchain. Imagine for instance you wanted to write a contract and place it in an unchangeable location that at any future date one could go back to verify it existed. You can do this by using the blockchain. You add some bits to the transaction's scriptSig value that don't alter the end result of running that script, but allow you to store information like “I hereby declare to give asset A to address XYZ at time UNIX\_TIMESTAMP”. There were even stranger ways people would add extra bits, like including it in the BTC value of an output. Some members of the community did not like this, as they saw these extra bits as polluting the blockchain. The extra bits were a network efficiency concern because more bits meant larger block chains and more of an onus on those who are running full nodes, and it was also a community consensus concern because they thought “we all implicitly agreed to store financial data in the blockchain, which is important to everyone, but we did not agree to store data like small text messages and invoice text”.

To reach a middle ground in these opposing views, the core-developers made the opcode OP\_RETURN a valid opcode to be used in a bitcoin transaction, which allows 80 arbitrary bytes to be used in an unspendable transaction. A good explanation of this can be found here:

```
https://bitcoinfoundation.org/bitcoin/core-development-update-5/

```

Later in February 2014, the bytes count was reduced from 80 to 40 bytes. This change is documented in the link below. Note that in this pull discussion we learn that no more than one output with OP\_RETURN can be included in a single transaction:

```
https://github.com/bitcoin/bitcoin/pull/3737

```

Now that we’ve got the reason behind OP\_RETURN down, let’s look at an example of OP\_RETURN. I used chain.com’s API to find a transaction which has an OP\_RETURN in its scriptSig. That tx’s hash is

```
8bae12b5f4c088d940733dcd1455efc6a3a69cf9340e17a981286d3778615684 

```

Make sure you are connected to a fully-loaded bitcoind node, and run this command:

```
$> bitcoind getrawtransaction 8bae12b5f4c088d940733dcd1455efc6a3a69cf9340e17a981286d3778615684 1

```

which will give you this output:

```
{
"hex" : "0100000001c858ba5f607d762fe5be1dfe97ddc121827895c2562c4348d69d02b91dbb408e010000008b4830450220446df4e6b875af246800c8c976de7cd6d7d95016c4a8f7bcdbba81679cbda242022100c1ccfacfeb5e83087894aa8d9e37b11f5c054a75d030d5bfd94d17c5bc953d4a0141045901f6367ea950a5665335065342b952c5d5d60607b3cdc6c69a03df1a6b915aa02eb5e07095a2548a98dcdd84d875c6a3e130bafadfd45e694a3474e71405a4ffffffff020000000000000000156a13636861726c6579206c6f766573206865696469400d0300000000001976a914b8268ce4d481413c4e848ff353cd16104291c45b88ac00000000",
"txid" : "8bae12b5f4c088d940733dcd1455efc6a3a69cf9340e17a981286d3778615684",
"version" : 1,
"locktime" : 0,
"vin" : [
    {
        "txid" : "8e40bb1db9029dd648432c56c295788221c1dd97fe1dbee52f767d605fba58c8",
        "vout" : 1,
        "scriptSig" : {
            "asm" : "30450220446df4e6b875af246800c8c976de7cd6d7d95016c4a8f7bcdbba81679cbda242022100c1ccfacfeb5e83087894aa8d9e37b11f5c054a75d030d5bfd94d17c5bc953d4a01 045901f6367ea950a5665335065342b952c5d5d60607b3cdc6c69a03df1a6b915aa02eb5e07095a2548a98dcdd84d875c6a3e130bafadfd45e694a3474e71405a4",
            "hex" : "4830450220446df4e6b875af246800c8c976de7cd6d7d95016c4a8f7bcdbba81679cbda242022100c1ccfacfeb5e83087894aa8d9e37b11f5c054a75d030d5bfd94d17c5bc953d4a0141045901f6367ea950a5665335065342b952c5d5d60607b3cdc6c69a03df1a6b915aa02eb5e07095a2548a98dcdd84d875c6a3e130bafadfd45e694a3474e71405a4"
        },
        "sequence" : 4294967295
    }
],
"vout" : [
    {
        "value" : 0.00000000,
        "n" : 0,
        "scriptPubKey" : {
            "asm" : "OP_RETURN 636861726c6579206c6f766573206865696469",
            "hex" : "6a13636861726c6579206c6f766573206865696469",
            "type" : "nulldata"
        }
    },
    {
        "value" : 0.00200000,
        "n" : 1,
        "scriptPubKey" : {
            "asm" : "OP_DUP OP_HASH160 b8268ce4d481413c4e848ff353cd16104291c45b OP_EQUALVERIFY OP_CHECKSIG",
            "hex" : "76a914b8268ce4d481413c4e848ff353cd16104291c45b88ac",
            "reqSigs" : 1,
            "type" : "pubkeyhash",
            "addresses" : [
                "1HnhWpkMHMjgt167kvgcPyurMmsCQ2WPgg"
            ]
        }
    }
],
"blockhash" : "000000000000000004c31376d7619bf0f0d65af6fb028d3b4a410ea39d22554c",
"confirmations" : 2655,
"time" : 1404107109,
"blocktime" : 1404107109
}

```

Now, look at this transaction’s list of outputs, in particular the 1st one. By referencing [the Bitcoin Wiki’s page on Script](https://en.bitcoin.it/wiki/Script), Bitcoin’s stack-based programming language, we can see here that the `OP_RETURN` opcode is represented by the hex value 0x6a. This first byte it followed by a byte which represents the length of the rest of the bytes in the scriptPubKey. In this case we see the hex value Ox13, which means there are 19 more bytes. These bytes comprise the arbitrary less-than-40 bytes you are allowed to send in a transaction marked by the `OP_RETURN` opcode. If you pop the message bytes into a UTF8 decoder, you’ll see that

```
636861726c6579206c6f766573206865696469

```

becomes “charley loves heidi”. Aw! It’s almost like a digital version of a couple’s romantic heart tree carving. Now you understand at a byte level how `OP_RETURN` is supposed to work. You can write software now that searches for the `OP_RETURN` opcode in an output’s scriptPubKey, and use it to verify a contract or some other digital asset.

> **Comments:**
> **username_5**: An important aspect of OP_RETURN is that outputs which use it in the standard way are provable unspendable. This means that nodes can immediately remove such outputs from their unspent outputs cache and potentially forget about them altogether (though Bitcoin Core doesn't do this yet). This makes OP_RETURN transactions *much* less expensive for the network than other ways of stuffing data into the block chain.  
> **username_6**: FYI if anyone is looking to decode that message `636861726c6579206c6f766573206865696469` in php, it's the hex value so use `hex2bin()`  
> **username_7**: Why does this cost less to the network that just sending 1 satoshi to an arbitrary address that contains the 20 bytes of information itself ?  
> **username_9**: @username_7 Because with OP_RETURN, the node knows that the transaction output index is unspendable and can just ignore it. Whereas when sending 1 satoshi, the node will need to keep that unspent output in memory or in a database, waiting until someone spends it someday.  
> **username_8**: @username_0 Nowadays the command to get the tx details is `bitcoin-cli` and not `bitcoind`.  
> **username_10**: In *NIX the `xxd` command can be used.  `echo 636861726c6579206c6f766573206865696469 | xxd -p -r` returns `charley loves heidi`  
> **username_11**: How is it possible that [this famous transaction](https://bitcoinsays.com/d29c9c0e8e4d2a9790922af73f0b8d51f0bd4bb19940d9cf910ead8fbe85bc9b) contains more than 80 bytes?  
> **username_11**: (it pushes 983 bytes)  
> **username_12**: You say that "no more than one output with OP_RETURN can be included in a single transaction" and provide a pull request as a source for this. Where in this pull request discussion is this mentioned?  
> **username_8**: For those wishing to decode the message using JavaScript, the one-liner in Node would be `Buffer.from('636861726c6579206c6f766573206865696469', 'hex').toString('utf8');`  
> **username_8**: According to the [Script wiki](https://en.bitcoin.it/wiki/Script): `it is usually considered non-standard (though valid) for a transaction to have more than one OP_RETURN output or an OP_RETURN output with more than one pushdata op`.  
> **username_3**: Why do the bytes I want to save in the blockchain have to come after the OP_RETURN and not before?  
> **username_3**: @username_5 So this is just a convention/consensus that makes these transaction burn the coins, or there are other technical reasons?  
> **username_3**: @username_5 https://twitter.com/lopp/status/947507679936774145?lang=en Here they say the coins are not burned.  
> **username_13**: Can I include an `addresses` entry in `scriptPubKey` to indicate the recipient of the message?  

---

### Answer by username_1 on 2015-09-21. Score: 11

If you want to write OP\_RETURNs to the blockchain without getting into the internals of how transactions are built, an easy way is to use our libraries for PHP and Python:

<https://github.com/coinspark/php-OP_RETURN>

<https://github.com/coinspark/python-OP_RETURN>

These support either sending individual transactions with one OP\_RETURN attached, or else sending a batch of linked transactions to embed larger pieces of content. That content can then be retrieved from the blockchain using a single identifier.

Assuming you're using Bitcoin Core 0.11, you can change the value of `OP_RETURN_MAX_BYTES` to `80`, rather than `40` as it currently stands in the code.


---

### Answer by username_2 on 2021-01-14. Score: 4

**`OP_RETURN` is a way to get arbitrary data into the blockchain with less burden to the network**

As a consequence, the data will also be present in less clients, as `OP_RETURN` data can be pruned out.

The goal of this answer is to explain what <https://bitcoin.stackexchange.com/a/29555/21282> explained but with a bit more context for Bitcoin newbies.

**How a standard transaction looks like**

As seen in the JSON disassembly from <https://bitcoin.stackexchange.com/a/29555/21282> each transaction has a list of outputs, and each output has a script.

The [most common script by far](https://bitcoin.stackexchange.com/questions/5883/is-there-a-listing-of-strange-or-unusual-scripts-found-in-transactions/105392#105392) is [pay-to-pubkey-hash](https://en.bitcoin.it/wiki/Script#Standard_Transaction_to_Bitcoin_address_.28pay-to-pubkey-hash.29) which basically says:

> this output can be consumed by the person who controls the private key to this public key

or in simpler terms "pay X bitcoint to address Y".

That script has format:

```
OP_DUP OP_HASH160 <length-of-hash> <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

```

where pubKeyHash is 20 bytes and all other 5 fields are 1 byte.

**It is impossible to know if a standard transaction hash is an actual hash or arbitrary data**

Because `pubKeyHash` is a hash, it is impossible to know if that is the actual hash of something, or arbitrary data someone wants to encode into the blockchain.

The catch is: if you add arbitrary data there, you won't have a corresponding private key to claim back those funds. So what people do is to make transactions with the smallest amount possible that miners are willing to take for the verification work.

Now, every transaction in the blockchain takes as input a previous unspent output.

Therefore, embedding this data costs you a little, because that output is unspendable: it can never be used as an input of another transaction.

In order to verify if a transaction is valid, Bitcoin implementations have to keep around a full list of every unspent output ever created, known as the [UTXO set](https://en.bitcoin.it/wiki/UTXO).

Spent outputs can be pruned to save space, but unspent ones can't.

Therefore, whenever you burn your fake pubkey hash output, you force every single implementation to keep that information around forever, since those funds can never be spent.

**How `OP_RETURN` solves that problem**

OP return is another type of script transaction different from the standard pay-to-pubkey-hash transaction.

As mentioned at: <https://en.bitcoin.it/wiki/Script#Provably_Unspendable.2FPrunable_Outputs> the transaction has simply the form:

```
OP_RETURN <data>

```

`OP_RETURN` simply stops the script execution with a failure, making it impossible for anyone to use that output as the input of another transaction.

Therefore, when a bitcoin implementation sees that transaction, it can immediately decide that it is unspendable, unlike the pay-to-pubkey-hash transaction above, where it is impossible to make that decision. That's why this transaction is called "provably unspendable".

So the miner can mine if for a mining fee, but then implementations immediately prune it from the UTXO set.

This allows the UTXO set to be smaller, thus making bitcoin more efficient to everyone.

But on the other hand, it also means that your embedded data will be present in less people's computers.

> **Comments:**
> **username_3**: If I "add arbitrary data", won't it make the transaction invalid and not accepted in the blockchain? Or is it just the address of the recipient and instead of putting my own address I just put some arbitrary data?  
> **username_2**: @username_3 you just put arbitrary data instead of an actual address you control. But since addresses look completely random in nature (they are public keys) it is impossible for peers to distinguish, so it has to be added to the chain. And because you don't have the private key, it is impossible for you (or anyone else) to claim funds later on.  

---

### Answer by username_4 on 2020-04-05. Score: 0

In case you are here trying to convert OP\_RETURN to readable values:

*Note: This is javascript / typescript*

```
export default class OpReturnConverter {

    // Input -> <Buffer 35 33 36 39...>
    // Output -> 53696d706c6520616e737765722120f09f988a
    public static convertBufferToHex(buffer: Buffer) {
        const str = buffer.toString('hex')
        return Buffer.from(str, 'hex').toString()
    }

    // Input -> 53696d706c6520616e737765722120f09f988a
    // Output -> Simple answer! 
    public static convertHexToString(hex: string) {
        return Buffer.from(hex, 'hex').toString()
    }

    // Input -> Simple answer! 
    // Output -> <Buffer 35 33 36 39...>
    public static convertStringToBuffer(message: string) {
        const hexBuffer = Buffer.from(message).toString('hex')
        return Buffer.from(hexBuffer)
    }

}

```

---

**Results**

```
const string = 'Simple answer! '
console.log('Original ->', string)

const buf = OpReturnConverter.convertStringToBuffer(string)
console.log('Buffer ->', buf)

const hex = OpReturnConverter.convertBufferToHex(buf)
console.log('Hex ->', hex)

const unhex = OpReturnConverter.convertHexToString(hex)
console.log('Unhex ->', unhex)

```


---

