<p>For details of the specific byte structure of a block, see resources like the Bitcoin Wiki article on <a href="https://en.bitcoin.it/wiki/Block#Block_structure" rel="nofollow noreferrer">blocks</a>. For a transaction, see the article on <a href="https://en.bitcoin.it/wiki/Transaction#General_format_of_a_Bitcoin_transaction_.28inside_a_block.29" rel="nofollow noreferrer">transactions</a>.</p>

<p>The actual data storage happens within the transactions, within their intput and/or output <a href="https://en.bitcoin.it/wiki/Script" rel="nofollow noreferrer">scripts</a>. Theoretically, any script could be made including arbitrary data, but due to network standards, only certain types of scripts are allowed.</p>

<p>For an in-depth look at data storage techniques, see <a href="https://doi.org/10.5195/ledger.2018.101" rel="nofollow noreferrer">this paper</a>. (Full disclosure: I am one of the authors.)</p>

<p>Note, when I talk about pushing data to the stack:</p>

<ul>
<li><code>PUSHDATA(N)</code> (where <code>0 &lt;= N &lt;= 75</code>): Push the next N bytes onto the stack. The byte value for this is dec: <code>N</code></li>
<li><code>PUSHDATA1</code>: The next byte indicates the number of bytes after that to be pushed onto the stack. The byte value for this is dec: <code>76</code>, hex: <code>0x4c</code></li>
<li><code>PUSHDATA2</code>: The next two bytes indicate the number of bytes after that to be pushed onto the stack. The byte value for this is dec: <code>77</code>, hex: <code>0x4d</code></li>
</ul>

<p>Also, each chunk of data pushed with a PUSHDATA element cannot exceed 520 bytes, so bear in mind that any file will necessarily be broken up into chunks of 520 bytes or fewer.</p>

<p>Some ways of storing data include:</p>

<ul>
<li><p>Using the <em>coinbase</em> (or <em>generation</em>) transaction (if you're a miner) to store a small amount of arbitrary data in each block you mine. This data takes the place of the inputs that would normally appear in a transaction. The coinbase transaction allows up to 100 bytes of data; however, some of this must be used for special uses, such as the block height and extra nonce.</p></li>
<li><p>In outputs with <code>OP_RETURN</code>. Each transaction may have one <code>OP_RETURN</code> output. Such an output may have a value of zero (since otherwise you're burning money that can never be recovered). The script looks like <code>OP_RETURN &lt;up to 80 bytes of data&gt;</code>. <code>OP_RETURN</code> is byte value dec: <code>106</code>, hex: <code>0x6a</code>, and the data must begin with a PUSHDATA element.</p></li>
<li>In outputs that pay to an address, etc. that recipient address/key/etc. may be replaced with arbitrary data. In that case, take the regular script and replace the address/key/etc. with your data. This creates an output which you cannot spend but which must be tracked in the UTXO set, so it is not advisable to do. An example of this would be to take the P2PKH script <code>OP_DUP OP_HASH160 &lt;Public Key Hash&gt; OP_EQUALVERIFY OP_CHECKSIG</code> and replace the 20-byte public key hash with 20 bytes of other data. (Note that the hash is pushed onto the stack with a <code>PUSHDATA(20)</code> element. As bytes, this looks like: <code>0x 76 a9 14 [your 20 bytes of data] 88 ac</code>.) If you're replacing e.g., a public key, it may be detected that you're not using a real public key (if it doesn't start with <code>0x02</code>, <code>0x03</code>, or <code>0x04</code>, for instance), but a hash should be indistinguishable from arbitrary data.</li>
<li>In inputs, using P2SH scripts. Then the data may be stored in the redeem script itself or in the inputs to the redeem script. There are multiple ways to do this, but generally the arbitrary data will be included in a PUSHDATA element, which the redeem script will somehow operate on. One notable method involves the redeem script including <code>OP_HASH160 &lt;hash of the data to be included&gt; OP_EQUALVERIFY</code>, and the inputs to that script including the data to be stored. This method ensures that the data must be included for the script to return true. Another method is pushing data to the stack, then using <code>OP_DROP</code> or <code>OP_2DROP</code> to remove it from the stack. This is efficient, but it would be possible for an attacker to tamper with the data in a transaction malleability attack.</li>
<li>You could also store data in e.g., <a href="https://doi.org/10.1109/CW.2015.56" rel="nofollow noreferrer">the value field of your outputs</a>, but this is highly inefficient.</li>
</ul>

CC BY-SA 4.0
2019-02-08T23:56:44.637Z
Is it 80 bytes minus `op_return`, or is the size of that 1 or 2 bytes, bringing the effective size down to 79 or 78 bytes??
TLDR
CC BY-SA 4.0
2019-02-09T02:13:57.073Z
The maximum size for an OP_RETURN is actually 83 bytes by default. (This is a network "standard" and actual miners can choose for themselves what they will choose to mine.) This gives you effectively 80 bytes of data at most: 1 byte for `OP_RETURN`, 1 byte for `OP_PUSHDATA1`, 1 byte to indicate 80 bytes of data to be pushed, then 80 bytes of data. This is defined [here](https://github.com/bitcoin/bitcoin/blob/4cef8e05938e55d2d1bb3c36642aa294fb63b6e2/src/script/standard.h#L34).
Vecna
CC BY-SA 4.0
2019-02-08T19:36:30.273Z
2019-02-08T19:36:30.273Z
Vecna
<p>You can store arbitrary bytes in a Bitcoin transaction which are not validated but can be confirmed in the blockchain given sufficient fees.</p>

<p><code>op_return</code> is a Bitcoin script op_code used in output scripts and which, when executed on the script interpreter will return the script run as invalid, thereby rendering the output "unspendable".</p>

<p>Now, because the script-run is aborted, subsequent data in the same output script are never evaluated and can be arbitrary. A valid, confirmed Bitcoin transaction can contain unspendable outputs.</p>

<p>In theory an arbitrary size of data can be appended to <code>op_return</code> as long as the transaction is still valid (consensus), but node propagation policy usually limits this to 80-bytes. A miner could confirm larger data sizes of course.</p>

CC BY-SA 4.0
2019-02-08T08:58:33.583Z
2019-02-08T08:58:33.583Z
James C.
<p>At a block-to-block level, what is actually encoded at a <code>byte[]</code> level to encode a file stream?</p>

CC BY-SA 4.0
2019-02-08T03:09:37.860Z
Store files? That’s not a thing in Bitcoin.
Claris
CC BY-SA 4.0
2019-02-08T04:00:55.153Z
The coinbase transaction?
MCCCS
<block><op-return>
What Opcodes are used to store a file within Bitcoin?
TLDR
# What Opcodes are used to store a file within Bitcoin?

(Asked by: username_0 on 2019-02-08)

At a block-to-block level, what is actually encoded at a `byte[]` level to encode a file stream?

**Tags:** block, op-return

> **Comments:**
> **username_1**: Store files? That’s not a thing in Bitcoin.  
> **username_2**: The coinbase transaction?  

---

## 2 answers

### Answer by username_3 on 2019-02-08. Score: 3

For details of the specific byte structure of a block, see resources like the Bitcoin Wiki article on [blocks](https://en.bitcoin.it/wiki/Block#Block_structure). For a transaction, see the article on [transactions](https://en.bitcoin.it/wiki/Transaction#General_format_of_a_Bitcoin_transaction_.28inside_a_block.29).

The actual data storage happens within the transactions, within their intput and/or output [scripts](https://en.bitcoin.it/wiki/Script). Theoretically, any script could be made including arbitrary data, but due to network standards, only certain types of scripts are allowed.

For an in-depth look at data storage techniques, see [this paper](https://doi.org/10.5195/ledger.2018.101). (Full disclosure: I am one of the authors.)

Note, when I talk about pushing data to the stack:

* `PUSHDATA(N)` (where `0 <= N <= 75`): Push the next N bytes onto the stack. The byte value for this is dec: `N`
* `PUSHDATA1`: The next byte indicates the number of bytes after that to be pushed onto the stack. The byte value for this is dec: `76`, hex: `0x4c`
* `PUSHDATA2`: The next two bytes indicate the number of bytes after that to be pushed onto the stack. The byte value for this is dec: `77`, hex: `0x4d`

Also, each chunk of data pushed with a PUSHDATA element cannot exceed 520 bytes, so bear in mind that any file will necessarily be broken up into chunks of 520 bytes or fewer.

Some ways of storing data include:

* Using the *coinbase* (or *generation*) transaction (if you're a miner) to store a small amount of arbitrary data in each block you mine. This data takes the place of the inputs that would normally appear in a transaction. The coinbase transaction allows up to 100 bytes of data; however, some of this must be used for special uses, such as the block height and extra nonce.
* In outputs with `OP_RETURN`. Each transaction may have one `OP_RETURN` output. Such an output may have a value of zero (since otherwise you're burning money that can never be recovered). The script looks like `OP_RETURN` . `OP_RETURN` is byte value dec: `106`, hex: `0x6a`, and the data must begin with a PUSHDATA element.
* In outputs that pay to an address, etc. that recipient address/key/etc. may be replaced with arbitrary data. In that case, take the regular script and replace the address/key/etc. with your data. This creates an output which you cannot spend but which must be tracked in the UTXO set, so it is not advisable to do. An example of this would be to take the P2PKH script `OP_DUP OP_HASH160  OP_EQUALVERIFY OP_CHECKSIG` and replace the 20-byte public key hash with 20 bytes of other data. (Note that the hash is pushed onto the stack with a `PUSHDATA(20)` element. As bytes, this looks like: `0x 76 a9 14 [your 20 bytes of data] 88 ac`.) If you're replacing e.g., a public key, it may be detected that you're not using a real public key (if it doesn't start with `0x02`, `0x03`, or `0x04`, for instance), but a hash should be indistinguishable from arbitrary data.
* In inputs, using P2SH scripts. Then the data may be stored in the redeem script itself or in the inputs to the redeem script. There are multiple ways to do this, but generally the arbitrary data will be included in a PUSHDATA element, which the redeem script will somehow operate on. One notable method involves the redeem script including `OP_HASH160  OP_EQUALVERIFY`, and the inputs to that script including the data to be stored. This method ensures that the data must be included for the script to return true. Another method is pushing data to the stack, then using `OP_DROP` or `OP_2DROP` to remove it from the stack. This is efficient, but it would be possible for an attacker to tamper with the data in a transaction malleability attack.
* You could also store data in e.g., [the value field of your outputs](https://doi.org/10.1109/CW.2015.56), but this is highly inefficient.

> **Comments:**
> **username_0**: Is it 80 bytes minus `op_return`, or is the size of that 1 or 2 bytes, bringing the effective size down to 79 or 78 bytes??  
> **username_3**: The maximum size for an OP_RETURN is actually 83 bytes by default. (This is a network "standard" and actual miners can choose for themselves what they will choose to mine.) This gives you effectively 80 bytes of data at most: 1 byte for `OP_RETURN`, 1 byte for `OP_PUSHDATA1`, 1 byte to indicate 80 bytes of data to be pushed, then 80 bytes of data. This is defined [here](https://github.com/bitcoin/bitcoin/blob/4cef8e05938e55d2d1bb3c36642aa294fb63b6e2/src/script/standard.h#L34).  

---

### Answer by username_4 on 2019-02-08. Score: 2

You can store arbitrary bytes in a Bitcoin transaction which are not validated but can be confirmed in the blockchain given sufficient fees.

`op_return` is a Bitcoin script op\_code used in output scripts and which, when executed on the script interpreter will return the script run as invalid, thereby rendering the output "unspendable".

Now, because the script-run is aborted, subsequent data in the same output script are never evaluated and can be arbitrary. A valid, confirmed Bitcoin transaction can contain unspendable outputs.

In theory an arbitrary size of data can be appended to `op_return` as long as the transaction is still valid (consensus), but node propagation policy usually limits this to 80-bytes. A miner could confirm larger data sizes of course.


---

