NULL DATA
Storing data in bitcoin transactions.

NULL DATA is a standard locking script that you can use to store data on the blockchain.
WARNING: This locking script cannot be unlocked, so I wouldn’t use it as a lock for any amount of bitcoins.
How does it work?
The OP_RETURN
opcode immediately ends the execution of the script and marks it as invalid.1
Therefore, any output with a NULL DATA locking script on it is unspendable:

So what’s the use of the NULL DATA locking script?
You can use NULL DATA for data storage, because the standard script allows for a data push at the end.
So if you want to add some arbitrary data to a transaction; include an extra (empty) output, and place a NULL DATA locking script on it:
A transaction can only include one NULL DATA locking script for it to be considered a standard transaction (meaning that it will be relayed by nodes).
What data can you store in the NULL DATA script?
You can store up to 80 bytes2 of any data you want. But most people just encode text strings in to it. For example:
![]() |
6a0b68656c6c6f20776f726c64 |
OP_RETURN 68656c6c6f20776f726c64
|
NULL DATA |
---|---|---|---|
hex | opcodes | inline | stack |
How is that a text string?
Transaction data is typically represented in hexadecimal format, so it’s not always immediately obvious what the data is by looking at it.
But if it’s text, so you can read it by converting each byte from hexadecimal to its ASCII character code:
hexadecimal = 68656c6c6f20776f726c64
ascii = h e l l o w o r l d
ASCII Character Code Chart

Of course, you can store up to 80 bytes of any data you want (not just text in the form of ASCII character codes). You just need to know how to decode it to see what it is.
Where can you find NULL DATA scripts?
Anyone can use a NULL DATA script to add some arbitrary data to a transaction, so you can find them scattered around the blockchain.
Look for empty outputs when browsing the blockchain, as NULL DATA scripts are almost always placed on empty outputs (because the outputs are made unspendable by the lock).
Here are some examples of people using the script to store strings of text (hover over the data push
to see the ASCII text):
Example 1 - “hello world”
![]() |
6a0b68656c6c6f20776f726c64 |
OP_RETURN 68656c6c6f20776f726c64
|
NULL DATA |
---|---|---|---|
hex | opcodes | inline | stack |
Example 2 - “charley loves heidi”
![]() |
6a13636861726c6579206c6f766573206865696469 |
OP_RETURN 636861726c6579206c6f766573206865696469
|
NULL DATA |
---|---|---|---|
hex | opcodes | inline | stack |
Example 3 - “家族も友達もみんなが笑顔の毎日がほしい”
![]() |
6a39e5aeb6e6978fe38282e58f8be98194e38282e381bfe38293e381aae3818ce7ac91e9a194e381aee6af8ee697a5e3818ce381bbe38197e38184 |
OP_RETURN e5aeb6e6978fe38282e58f8be98194e38282e381bfe38293e381aae3818ce7ac91e9a194e381aee6af8ee697a5e3818ce381bbe38197e38184
|
NULL DATA |
---|---|---|---|
hex | opcodes | inline | stack |
Why was NULL DATA introduced as a standard script?
The NULL DATA locking script was introduced in Bitcoin 0.9.0
as a compromise to allow people to include arbitrary data inside transactions.
You see, before the NULL DATA script came about, people were adding data to transactions by using the existing standard locking scripts. For example, you could always use a P2PKH script and put your arbitrary data inside where the hashed public key
should go:
![]() |
76a91400000000006c6561726e6d6561626974636f696e88ac |
OP_DUP OP_HASH160 00000000006c6561726e6d6561626974636f696e OP_EQUALVERIFY OP_CHECKSIG
|
P2PKH |
---|---|---|---|
hex | opcodes | inline | stack |
However, the problem with this approach is that it looks like a standard locking script, so the output would be stored in the UTXO database, which is a waste of RAM as the output is effectively unspendable.
So this is where the NULL DATA comes in:
![]() |
6a0f6c6561726e6d6561626974636f696e |
OP_RETURN 6c6561726e6d6561626974636f696e
|
NULL DATA |
---|---|---|---|
hex | opcodes | inline | stack |
This script contains OP_RETURN
, which means it provably unspendable. Therefore, there is no need to store it in the UTXO database, which saves on precious RAM space.
Using the blockchain for data storage isn’t ideal, but you can’t stop people from doing it. Therefore, the NULL DATA script acts as a more reasonable alternative for data storage than previous methods.
On OP_RETURN: There was been some confusion and misunderstanding in the community, regarding the OP_RETURN feature in 0.9 and data in the blockchain. This change is not an endorsement of storing data in the blockchain. The OP_RETURN change creates a provably-prunable output, to avoid data storage schemes – some of which were already deployed – that were storing arbitrary data such as images as forever-unspendable TX outputs, bloating bitcoin’s UTXO database.
Bitcoin 0.9.0 Release Notes
Notes
OP_RETURN must be evaluated for a script to fail.
The presence of the OP_RETURN
opcode in a script does not automatically render the script invalid.
For example, in the script below the OP_RETURN
is in a branch that will never be evaluated, and so the script is valid:
OP_1 OP_IF OP_1 OP_ELSE OP_RETURN OP_ENDIF
|
You can see an example of this script in action (wrapped inside a P2SH) here.
Thanks to Vincenzo Iovino for pointing this out.