1
0
mirror of https://github.com/bitcoinbook/bitcoinbook synced 2024-11-26 09:58:22 +00:00

pay-to-public-key, op_return, p2sh draft, opcode tables

This commit is contained in:
Andreas M. Antonopoulos 2014-06-24 12:01:40 -04:00
parent 4272b825f8
commit fb702a133a

View File

@ -1,8 +1,6 @@
[[ch5]]
== Chapter 5 - Transactions
*DRAFT: DO NOT SUBMIT ISSUES OR PULL REQUEST YET, DRAFT IN PROGRESS AND FREQUENTLY MODIFIED*
[[ch5_intro]]
=== Introduction
@ -212,14 +210,15 @@ Bitcoin's scripting language is called a stack-based language because it uses a
The scripting language executes the script by processing each item from left to right. Numbers (data constants) are pushed onto the stack. Operators push or pop one or more parameters from the stack, act on them, and may push a result onto the stack. For example, OP_ADD will pop two items from the stack, add them and push the resulting sum onto the stack. In the following example, an addition operator _OP_ADD_ is demonstrated, adding two numbers and putting the result on the stack:
{diagram - 2 3 OP_ADD}
{remove op_ from above?}
Here's a more complex script, to calculate ((2 + 3) * 2) + 1. Notice that when the script contains several operators in a row, the stack allows the results of one operator to be acted upon by the next operator:
{diagram - 2 3 OP_ADD 2 OP_MUL 1 OP_ADD}
Conditional operators evaluate a condition producing a boolean result of TRUE or FALSE. For example, OP_EQUAL pops two items from the stack and pushes TRUE if they are equal or FALSE if they are not. Bitcoin transaction scripts usually contain a conditional operator, so that they can produce the result TRUE that signifies a valid transaction.
Conditional operators evaluate a condition producing a boolean result of TRUE or FALSE. For example, OP_EQUAL pops two items from the stack and pushes TRUE (TRUE is represented by the number 1) if they are equal or FALSE (represented by zero) if they are not equal. Bitcoin transaction scripts usually contain a conditional operator, so that they can produce the result TRUE that signifies a valid transaction.
While most locking scripts refer to a bitcoin address or public key, thereby requiring proof of ownership to spend the funds, the script does not have to be that complex. Any combination of locking and unlocking scripts that results in a TRUE value is valid.
While most locking scripts refer to a bitcoin address or public key, thereby requiring proof of ownership to spend the funds, the script does not have to be that complex. Any combination of locking and unlocking scripts that results in a TRUE value is valid.
In a bitcoin transaction, the locking script could be as simple as:
----
@ -238,17 +237,22 @@ The validation software combines the locking and unlocking scripts and the resul
When this script is executed, the result is OP_TRUE, making the transaction valid.
[TIP]
====
Transactions are valid if the top result on the stack is TRUE (1), but also if the stack is empty after script execution. Transactions are invalid if the top value on the stack is FALSE (0) or if script execution is halted explicitly by an operator, such as OP_VERIFY, OP_RETURN or a conditional terminator such as OP_ENDIF. See <<tx_script_ops>> for details.
====
{non zero is TRUE?}
==== Turing Incompleteness
The bitcoin transaction script language contains many operators but is deliberately limited in one important way - there are no loops or other flow control capabilities. This ensures that the language is not Turing Complete, meaning that scripts have limited complexity and predictable execution times. This ensures that the language cannot be used to create an infinite loop or other form of "logic bomb" that could be embedded in a transaction in a way that causes a Denial-of-Service attack against the bitcoin network. Remember, every transaction is validated by every full node on the bitcoin network. A limited language prevents the transaction validation mechanism from being used as a vulnerability.
The bitcoin transaction script language contains many operators but is deliberately limited in one important way - there are no loops or other flow control capabilities. This ensures that the language is not Turing Complete, meaning that scripts have limited complexity and predictable execution times. These limitations ensure that the language cannot be used to create an infinite loop or other form of "logic bomb" that could be embedded in a transaction in a way that causes a Denial-of-Service attack against the bitcoin network. Remember, every transaction is validated by every full node on the bitcoin network. A limited language prevents the transaction validation mechanism from being used as a vulnerability.
==== Stateless Verification
The bitcoin transaction script language is stateless, in that there is no state prior to execution of the script, or state saved after execution of the script. Therefore, all the information needed to execute a script is contained within the script. A script will predictably execute the same way on any system. If your system verifies a script you can be sure that every other system in the bitcoin network will also verify the script, meaning that a valid transaction is valid for everyone and everyone knows this.
The bitcoin transaction script language is stateless, in that there is no state prior to execution of the script, or state saved after execution of the script. Therefore, all the information needed to execute a script is contained within the script. A script will predictably execute the same way on any system. If your system verifies a script you can be sure that every other system in the bitcoin network will also verify the script, meaning that a valid transaction is valid for everyone and everyone knows this. This predictability of outcomes is a key benefit of the bitcoin system.
=== Standard Transactions
In the first few years of bitcoin's development, the developers introduced some limitations in the types of scripts that could be processed by the reference client. The limitation is encoded in a function called +isStandard()+ which defines five types of "standard" transactions. These limitations are temporary and may be lifted by the time you read this. Until then, the five standard types of transaction scripts are the only ones that will be accepted by the reference client and most miners who run the reference client. While it is possible to create a non-standard transaction containing a script that is not part of the standard types, you must find a miner who does not follow these limitations, to mine that transaction into a block.
In the first few years of bitcoin's development, the developers introduced some limitations in the types of scripts that could be processed by the reference client. These limitations are encoded in a function called +isStandard()+ which defines five types of "standard" transactions. These limitations are temporary and may be lifted by the time you read this. Until then, the five standard types of transaction scripts are the only ones that will be accepted by the reference client and most miners who run the reference client. While it is possible to create a non-standard transaction containing a script that is not one of the standard types, you must find a miner who does not follow these limitations, to mine that transaction into a block.
Check the source code of the bitcoin core client (the reference implementation) to see what is currently allowed as a valid transaction script.
@ -275,10 +279,10 @@ The locking script above can be satisfied with an unlocking script of the form:
The two scripts together would form the combined validation script below:
----
<Cafe Signature> <Cafe Public Key> OP_DUP OP_HASH160 <Cafe Public Key Hash> OP_EQUAL OP_CHECKSIGVERIFY
<Cafe Signature> <Cafe Public Key> OP_DUP OP_HASH160 <Cafe Public Key Hash> OP_EQUAL OP_CHECKSIG
----
When executed, this combined script will evaluate to TRUE, if and only if the unlocking script matches the conditions set by the locking script, that is if the unlocking script has a valid signature from the Cafe's private key which corresponds to the public key hash set as an encumbrance.
When executed, this combined script will evaluate to TRUE if, and only if, the unlocking script matches the conditions set by the locking script. In other words, the result will be TRUE if the unlocking script has a valid signature from the Cafe's private key which corresponds to the public key hash set as an encumbrance.
Here's a step-by-step execution of the combined script, which will prove this is a valid transaction:
@ -290,53 +294,262 @@ image::images/Tx_Script_P2PubKeyHash_1.png["Tx_Script_P2PubKeyHash_1"]
.Evaluating a script for a Pay-to-Public-Key-Hash transaction (Part 2 of 2)
image::images/Tx_Script_P2PubKeyHash_2.png["Tx_Script_P2PubKeyHash_2"]
==== Simple Pubkey
==== Pay-to-Public-Key
Pay-to-Public-Key is a simpler form of a bitcoin payment than Pay-to-Public-Key-Hash. With this script form, the public key itself is stored in the locking script, rather than a public-key-hash as with P2PKH above, which is much shorter. The disadvantage of this form of locking script is that it consumes more space in the blockchain to store these types of payments, because a public key is 264 or 520 bits long (depending on whether it is compressed), whereas a public key hash is only 160 bits long. For legacy compatibility, Pay-to-Public-Key is used in all coinbase generation transactions, the transactions that pay the reward to the miners.
A Pay-to-Public-Key locking script looks like this:
----
<Public Key A> OP_CHECKSIG
----
The corresponding unlocking script that must be presented to unlock this type of output is a simple signature, like this:
----
<Signature from Private Key A>
----
The combined script, which is validated by the transaction validation software is:
----
<Signature from Private Key A> <Public Key A> OP_CHECKSIG
----
The script above is a simple invocation of the CHECKSIG operator which validates the signature as belonging to the correct key and returns TRUE on the stack.
==== Mutli-Signature
Multi-signature scripts set a condition where N public keys are recorded in the script and at least M of those must provide signatures to release the encumbrance, also known as an M-of-N scheme where N is the total number of keys and M is the threshold of signatures required for validation. For example, a 2-of-3 multi-signature is one where 3 public keys are listed as potential signers and at least 2 of those must be used to create signatures for a valid transaction to spend the funds. At this time, standard multi-signature scripts are limited to at most 15 listed public keys, meaning you can do anything from a 1-of-1 to a 15-of-15 multi-signature or any combination within that range. The limitation to 15 listed keys may be lifted by the time of publication of this book, so check the +isStandard()+ function to see what is currently accepted by the network.
Multi-signature scripts set a condition where N public keys are recorded in the script and at least M of those must provide signatures to release the encumbrance. This is also known as an M-of-N scheme, where N is the total number of keys and M is the threshold of signatures required for validation. For example, a 2-of-3 multi-signature is one where 3 public keys are listed as potential signers and at least 2 of those must be used to create signatures for a valid transaction to spend the funds. At this time, standard multi-signature scripts are limited to at most 15 listed public keys, meaning you can do anything from a 1-of-1 to a 15-of-15 multi-signature or any combination within that range. The limitation to 15 listed keys may be lifted by the time of publication of this book, so check the +isStandard()+ function to see what is currently accepted by the network.
The general form of a locking script setting an M-of-N multi-signature condition is:
----
M <Public Key 1> <Public Key 2> ... <Public Key N> N OP_CHECKMULTISIGVERIFY
M <Public Key 1> <Public Key 2> ... <Public Key N> N OP_CHECKMULTISIG
----
where N is the total number of listed public keys and M is the threshold of required signatures to spend the output.
A locking script setting a 2-of-3 multi-signature condition looks like this:
----
2 <Public Key A> <Public Key B> <Public Key C> 3 OP_CHECKMULTISIGVERIFY
2 <Public Key A> <Public Key B> <Public Key C> 3 OP_CHECKMULTISIG
----
The locking script above can be satisfied with an unlocking script of the form:
----
<Signature from Private Key B> <Signature from Private Key C>
OP_0 <Signature from Private Key B> <Signature from Private Key C> <Public Key B> <Public Key C>
----
or any combination of two signatures from the private keys corresponding to the three listed public keys.
_Note: The prefix OP_0 is required because of a bug in the original implementation of CHECKMULTISIG where one item too many is popped off the stack. It is ignored by CHECKMULTISIG and is simply a placeholder._
The two scripts together would form the combined validation script below:
----
<Signature from Private Key B> <Signature from Private Key C> 2 <Public Key A> <Public Key B> <Public Key C> 3 OP_CHECKMULTISIGVERIFY
OP_0 <Signature from Private Key B> <Signature from Private Key C> <Public Key B> <Public Key C>
2 <Public Key A> <Public Key B> <Public Key C> 3 OP_CHECKMULTISIG
----
When executed, this combined script will evaluate to TRUE, if and only if the unlocking script matches the conditions set by the locking script, that is if the unlocking script has a valid signatures from the two private keys which correspond to two of the three public keys set as an encumbrance.
When executed, this combined script will evaluate to TRUE if, and only if, the unlocking script matches the conditions set by the locking script, that is if the unlocking script has a valid signatures from the two private keys which correspond to two of the three public keys set as an encumbrance.
==== Data Output (OP_RETURN)
Bitcoin's distributed and timestamped ledger, the blockchain, has potential uses far beyond payments. Many developers have tried to use the transaction scripting language to take advantage of the security and resilience of the system for applications such as digital notary services, stock certificates, and smart contracts. Early attempts to use bitcoin's script language for these purposes involved creating transaction outputs that recorded data on the blockchain, for example to record a digital fingerprint of a file in such a way that anyone could establish proof-of-existence of that file on a specific date by reference to that transaction.
The use of bitcoin's blockchain to store data unrelated to bitcoin payments is a controversial subject. Many developers consider such use abusive and want to discourage it. Others view it as a demonstration of the powerful capabilities of blockchain technology and want to encourage such experimentation. Those who object to the inclusion of non-payment data argue that it causes "blockchain bloat", burdening those running full bitcoin nodes with carrying the cost of disk storage for data that the blockchain was not intended to carry. Moreover, such transactions create UTXO that cannot be spent, using the destination bitcoin address as a free-form 20-byte field. Since the address is used for data, it doesn't correspond to a private key and the resulting UTXO can _never_ be spent, it's a fake payment. This practice causes the size of the in-memory UTXO set to increase and these transactions which can never be spent are therefore never removed, forcing bitcoin nodes to carry these forever in RAM which is far more expensive.
In version 0.9 of the bitcoin core client, a compromise was reached, with the introduction of the OP_RETURN operator. OP_RETURN allows developers to add 40 bytes of non-payment data to a transaction output. However, unlike the use of "fake" UTXO, the OP_RETURN operator creates an explicitly _provably un-spendable_ output, which does not need to be stored in the UTXO set. OP_RETURN outputs are recorded on the blockchain, so they consume disk space and contribute to the increase in the blockchain's size, but they are not stored in the UTXO set and therefore do not bloat the UTXO memory pool and burden full nodes with the cost of more expensive RAM.
OP_RETURN scripts look like this:
----
OP_RETURN <data>
----
where the data portion is limited to 40 bytes and most often represents a hash, such as the output from the SHA256 algorithm (32 bytes). Many applications put a prefix in front of the data to help identify the application. For example, the proofofexistence.com digital notarization service uses the 8-byte prefix "DOCPROOF" which is ASCII encoded as 44f4350524f4f46 in hexadecimal.
Keep in mind that there is no "unlocking script" that corresponds to OP_RETURN, that can be used to "spend" an OP_RETURN output. The whole point of OP_RETURN is that you can't spend the money locked in that output and therefore it does not need to be held in the UTXO set as potentially spendable - OP_RETURN is _provably un-spendable_. OP_RETURN is usually an output with a zero bitcoin amount, since any bitcoin assigned to such an output is effectively lost forever. If an OP_RETURN is encountered by the script validation software it results immediately in halting the execution of the validation script and marking the transaction as invalid. Thus, if you accidentally reference an OP_RETURN output as an input in a transaction, that transaction is invalid.
{how are these transactions structured? can a single transaction have two outputs - 1 as p2pkh and one as op_return? wouldn't i need that to pay the transaction fee? is this something most wallets can implement?}
==== Pay to Script Hash (P2SH)
Pay-to-Script-Hash (P2SH) was introduced in the winter of 2012 as a powerful new type of transaction that greatly simplified the use of complex transaction scripts. {simplified? didn't it introduce? could you use scripts before p2sh?}.
* Complex scripts replaced by shorter fingerprint in the output
* Scripts can be coded as an address, so the sender and the sender's wallet don't need complex engineering to implement
* Moves the burden of constructing the script to the recipient not the sender
* Moves the burden in data storage for the long script from the output (which is in UTXO set) to the input
* Moves the burden in data storage for the long script from the present (payment) to the future (spend)
* Sender pays the fee and shorter output means less fee for the sender, shifts the cost of a complex transaction to the spender (recipient)
{why was it introduced? how is this related to "multi-sig", how else can it be used? }
===== Redeem Script and isStandard Validation
=== Non-Standard Transactions
=== Scripts and Signatures
==== Elliptic Curve Digital Signature Algorithm
===== Signing with the Private Key
===== Validating a Digital Signature
==== Types of Signature Hashes
[[tx_script_ops]]
=== Transaction Script Language Operators, Constants and Symbols
[[tx_script_ops_table_pushdata]]
.Push Value onto Stack
[options="header"]
|=======
| Symbol | Value (hex) | Description
| OP_0 or OP_FALSE | 0x00 | An empty array is pushed on to the stack
| 1-75 | 0x01-0x4b | Push the next N bytes onto the stack, where N is 1 to 75 bytes
| OP_PUSHDATA1 | 0x4c | The next script byte contains N, push the following N bytes onto the stack
| OP_PUSHDATA2 | 0x4d | The next two script bytes contain N, push the following N bytes onto the stack
| OP_PUSHDATA4 | 0x4e | The next four script bytes contain N, push the following N bytes onto the stack
| OP_1NEGATE | 0x4f | Push the value "-1" onto the stack
| OP_RESERVED | 0x50 | Halt - Invalid transaction unless found in an unexecuted OP_IF clause
| OP_1 or OP_TRUE| 0x51 | Push the value "1" onto the stack
| OP_2 to OP_16 | 0x52 to 0x60 | For OP_N, push the value "N" onto the stack. eg. OP_2 pushes "2"
|=======
[[tx_script_ops_table_control]]
.Conditional Flow Control
[options="header"]
|=======
| Symbol | Value (hex) | Description
| OP_NOP | 0x61 | Do nothing
| OP_VER | 0x62 | Halt - Invalid transaction unless found in an unexecuted OP_IF clause
| OP_IF | 0x63 | Execute the statements following if top of stack is not 0
| OP_NOTIF | 0x64 | Execute the statements following if top of stack is 0
| OP_VERIF | 0x65 | Halt - Invalid transaction
| OP_VERNOTIF | 0x66 | Halt - Invalid transaction
| OP_ELSE | 0x67 | Execute only if the previous statements were not executed
| OP_ENDIF | 0x68 | Ends the OP_IF, OP_NOTIF, OP_ELSE block
| OP_VERIFY | 0x69 | Check the top of the stack, Halt and Invalidate transaction if not TRUE
| OP_RETURN | 0x6a | Halt and invalidate transaction
|=======
[[tx_script_ops_table_control]]
.Stack Operations
[options="header"]
|=======
| Symbol | Value (hex) | Description
| OP_TOALTSTACK | 0x6b | Pop top item from stack and push to alternative stack
| OP_FROMALTSTACK | 0x6c | Pop top item from alternative stack and push to stack
| OP_2DROP | 0x6d | Pop top two stack items
| OP_2DUP | 0x6e | Duplicate top two stack items
| OP_3DUP | 0x6f | Duplicate top three stack items
| OP_2OVER | 0x70 | Copies the third and fourth items in the stack to the top
| OP_2ROT | 0x71 | Moves the fifth and sixth items in the stack to the top
| OP_2SWAP | 0x72 | Swap the two top pairs of items in the stack
| OP_IFDUP | 0x73 | Duplicate the top item in the stack if it is not 0
| OP_DEPTH | 0x74 | Count the items on the stack and push the resulting count
| OP_DROP | 0x75 | Pop the top item in the stack
| OP_DUP | 0x76 | Duplicate the top item in the stack
| OP_NIP | 0x77 | Pop the second item in the stack
| OP_OVER | 0x78 | Copy the second item in the stack and push it on to the top
| OP_PICK | 0x79 | Pop value N from top, then copy the Nth item to the top of the stack
| OP_ROLL | 0x7a | Pop value N from top, then move the Nth item to the top of the stack
| OP_ROT | 0x7b | Rotate the top three items in the stack
| OP_SWAP | 0x7c | Swap the top three items in the stack
| OP_TUCK | 0x7d | Copy the top item and insert it between the top and second item.
|=======
[[tx_script_ops_table_control]]
.String Splice Operations
[options="header"]
|=======
| Symbol | Value (hex) | Description
| _OP_CAT_ | 0x7e | Disabled (Concatenates top two items)
| _OP_SUBSTR_ | 0x7f | Disabled (Returns substring)
| _OP_LEFT_ | 0x80 | Disabled (Returns left substring)
| _OP_RIGHT_ | 0x81 | Disabled (Returns right substring)
| OP_SIZE | 0x82 | Calculate string length of top item and push the result
|=======
[[tx_script_ops_table_control]]
.Binary Arithmetic and Conditionals
[options="header"]
|=======
| Symbol | Value (hex) | Description
| _OP_INVERT_ | 0x83 | Disabled (Flip the bits of the top item)
| _OP_AND_ | 0x84 | Disabled (Boolean AND of two top items)
| _OP_OR_ | 0x85 | Disabled (Boolean OR of two top items)
| _OP_XOR_ | 0x86 | Disabled (Boolean XOR of two top items)
| OP_EQUAL | 0x87 | Push TRUE (1) if top two items are exactly equal, push FALSE (0) otherwise
| OP_EQUALVERIFY | 0x88 | Same as OP_EQUAL, but run OP_VERIFY after to halt if not TRUE
| OP_RESERVED1 | 0x89 | Halt - Invalid transaction unless found in an unexecuted OP_IF clause
| OP_RESERVED2 | 0x8a | Halt - Invalid transaction unless found in an unexecuted OP_IF clause
|=======
[[tx_script_ops_table_control]]
.Numeric Operators
[options="header"]
|=======
| Symbol | Value (hex) | Description
| OP_1ADD | 0x8b | Add 1 to the top item
| OP_1SUB | 0x8c | Subtract 1 from the top item
| _OP_2MUL_ | 0x8d | Disabled (Multiply top item by 2)
| _OP_2DIV_ | 0x8e | Disabled (Divide top item by 2)
| OP_NEGATE | 0x8f | Flip the sign of top item
| OP_ABS | 0x90 | Change the sign of the top item to positive
| OP_NOT | 0x91 | If top item is 0 or 1 boolean flip it, otherwise return 0
| OP_0NOTEQUAL | 0x92 | If top item is 0 return 0, otherwise return 1
| OP_ADD | 0x93 | Pop top two items, add them and push result
| OP_SUB | 0x94 | Pop top two items, subtract first form second, push result
| OP_MUL | 0x95 | Disabled (Multiply top two items)
| OP_DIV | 0x96 | Disabled (Divide second item by first item)
| OP_MOD | 0x97 | Disabled (Remainder divide second item by first item)
| OP_LSHIFT | 0x98 | Disabled (Shift second item left by first item number of bits)
| OP_RSHIFT | 0x99 | Disabled (Shift second item right by first item number of bits)
| OP_BOOLAND | 0x9a | Boolean AND of top two items
| OP_BOOLOR | 0x9b | Boolean OR of top two items
| OP_NUMEQUAL | 0x9c | Return TRUE if top two items are equal numbers
| OP_NUMEQUALVERIFY | 0x9d | Same as NUMEQUAL, then OP_VERIFY to halt if not TRUE
| OP_NUMNOTEQUAL | 0x9e | Return TRUE if top two items are not equal numbers
| OP_LESSTHAN | 0x9f | Return TRUE if second item is less than top item
| OP_GREATERTHAN | 0xa0 | Return TRUE if second item is greater than top item
| OP_LESSTHANOREQUAL | 0xa1 | Return TRUE if second item is less than or equal to top item
| OP_GREATERTHANOREQUAL | 0xa2 | Return TRUE if second item is great than or equal to top item
| OP_MIN | 0xa3 | Return the smaller of the two top items
| OP_MAX | 0xa4 | Return the larger of the two top items
| OP_WITHIN | 0xa5 | Return TRUE if the third item is between the second item (or equal) and first item
|=======
[[tx_script_ops_table_control]]
.Cryptographic and Hashing Operations
[options="header"]
|=======
| Symbol | Value (hex) | Description
| OP_RIPEMD160 | 0xa6 | Return RIPEMD160 hash of top item
| OP_SHA1 | 0xa7 | Return SHA1 hash of top item
| OP_SHA256 | 0xa8 | Return SHA256 hash of top item
| OP_HASH160 | 0xa9 | Return RIPEMD160(SHA256(x)) hash of top item
| OP_HASH256 | 0xaa | Return SHA256(SHA256(x)) hash of top item
| OP_CODESEPARATOR | 0xab | Mark the beginning of signature-checked data
| OP_CHECKSIG | 0xac | Pop a public key and signature and validate the signature for the transaction's hashed data, return TRUE if matching
| OP_CHECKSIGVERIFY | 0xad | Same as CHECKSIG, then OP_VEIRFY to halt if not TRUE
| OP_CHECKMULTISIG | 0xae | Run CHECKSIG for each pair of signature and public key provided. All must match. Bug in implementation pops an extra value, prefix with OP_NOP as workaround
| OP_CHECKMULTISIGVERIFY | 0xaf | Same as CHECKMULTISIG, then OP_VERIFY to halt if not TRUE
|=======
[[tx_script_ops_table_control]]
.Non-Operators
[options="header"]
|=======
| Symbol | Value (hex) | Description
| OP_NOP1-OP_NOP10 | 0xb0-0xb9 | Does nothing, ignored.
|=======
[[tx_script_ops_table_control]]
.Reserved OP codes for internal use by the parser
[options="header"]
|=======
| Symbol | Value (hex) | Description
| OP_SMALLDATA | 0xf9 | Represents small data field
| OP_SMALLINTEGER | 0xfa | Represents small integer data field
| OP_PUBKEYS | 0xfb | Represents public key fields
| OP_PUBKEYHASH | 0xfd | Represents a public key hash field
| OP_PUBKEY | 0xfe | Represents a public key field
| OP_INVALIDOPCODE | 0xff | Represents any OP code not currently assigned
|=======
=== Transaction Malleability