mirror of
https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line.git
synced 2025-06-08 16:36:32 +00:00
Update 7_2_Running_a_Bitcoin_Script.md
This commit is contained in:
parent
9cb0f6637e
commit
e9d9881f97
@ -10,19 +10,19 @@ A Bitcoin Script has three parts: it has a line of input; it has a stack for sto
|
|||||||
|
|
||||||
### Understand the Ordering
|
### Understand the Ordering
|
||||||
|
|
||||||
Bitcoin Scripts are run from left to right. That sounds easy enough, as it's the same way you read. However, this might be the most non-intuitive element of Bitcoin Script, because it means that functions don't look like you'd expect. Instead, _the operands go before the operator._
|
Bitcoin Scripts are run from left to right. That sounds easy enough, because it's the same way you read. However, it might actually be the most non-intuitive element of Bitcoin Script, because it means that functions don't look as you'd expect. Instead, _the operands go before the operator._
|
||||||
|
|
||||||
For example, if you were adding together "1" and "2", your Bitcoin Script for that would be `1 2 OP_ADD`, _not_ "1 + 2". Since we know that OP_ADD operator takes two inputs, we know that the two inputs before it are its operands. At least that's true at the most basical level of Scripting.
|
For example, if you were adding together "1" and "2", your Bitcoin Script for that would be `1 2 OP_ADD`, _not_ "1 + 2". Since we know that OP_ADD operator takes two inputs, we know that the two inputs before it are its operands. (At least that's true at the most basic level of Scripting.)
|
||||||
|
|
||||||
> **WARNING:** Technically, everything in Bitcoin Script is an opcode, thus it would be most appropriate to record the above example as `OP_1 OP_2 OP_ADD`. We leave the "OP" prefix off constants, but include it on all actual operators. Some writers prefer to also leave the "OP" prefix off operators, but we have opted not to.
|
> **WARNING:** Technically, everything in Bitcoin Script is an opcode, thus it would be most appropriate to record the above example as `OP_1 OP_2 OP_ADD`. We leave the "OP" prefix off constants, but include it on all actual operators. Some writers prefer to also leave the "OP" prefix off operators, but we have opted not to.
|
||||||
|
|
||||||
### Understand the Stack
|
### Understand the Stack
|
||||||
|
|
||||||
It's actually not quite correct to say that an operator applies to the inputs before it. Instead, an operator actually applies to the top inputs in Bitcoin's stack.
|
It's actually not quite correct to say that an operator applies to the inputs before it. Really, an operator applies to the top inputs in Bitcoin's stack.
|
||||||
|
|
||||||
_What is a stack?_ A stack is a LIFO (last-in-first-out) data structure. It has two access functions: push and pop. Push places a new object on top of the stack, pushing down everything below it. Pop removes the top object from the stack.
|
_What is a stack?_ A stack is a LIFO (last-in-first-out) data structure. It has two access functions: push and pop. Push places a new object on top of the stack, pushing down everything below it. Pop removes the top object from the stack.
|
||||||
|
|
||||||
Whenever Bitcoin Script encounters a constant, it's pushed onto the Stack. So the above example of `1 2 OP_ADD1` would actually look like this as it was processed:
|
Whenever Bitcoin Script encounters a constant, it pushes it on the stack. So the above example of `1 2 OP_ADD1` would actually look like this as it was processed:
|
||||||
```
|
```
|
||||||
Script: 1 2 OP_ADD
|
Script: 1 2 OP_ADD
|
||||||
Stack: [ ]
|
Stack: [ ]
|
||||||
@ -45,9 +45,9 @@ Script:
|
|||||||
Stack: [ 3 ]
|
Stack: [ 3 ]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Run a Simple Script
|
## Build Up Complexity
|
||||||
|
|
||||||
Here's an example of a more complex script. It shows how operators continue to interact with the stack, not just with the operands right before it:
|
More complex scripts are created by running more commands in order. They need to be carefully evaluated from left to right, so that you can understand the state of the stack as each new command is run. It will constantly change, as a result of previous operators:
|
||||||
```
|
```
|
||||||
Script: 3 2 OP_ADD 4 OP_SUB
|
Script: 3 2 OP_ADD 4 OP_SUB
|
||||||
Stack: [ ]
|
Stack: [ ]
|
||||||
@ -74,32 +74,33 @@ That's pretty much Bitcoin Scripting ... other than a few intricacies for how th
|
|||||||
|
|
||||||
### Understand scriptSig and scriptPubKey
|
### Understand scriptSig and scriptPubKey
|
||||||
|
|
||||||
As we've seen, every input for a Bitcoin transaction contains a `scriptSig` which is used to unlock the `scriptPubKey` for the associated UTXO. The easy way to think of this is that `scriptSig` is run, then the `scriptPubKey` is run.
|
As we've seen, every input for a Bitcoin transaction contains a `scriptSig` that is used to unlock the `scriptPubKey` for the associated UTXO. They are _effectively_ concatenated together, meaning that `scriptSig` and `scriptPubKey` are run together, in that order.
|
||||||
|
|
||||||
So, presume that a UTXO were locked with a `scriptPubKey` that read `OP_ADD 100 OP_EQUAL`, requiring as input two numbers that add up to a hundred, and presume that the `scriptSig` of `1 99` were run to unlock it. The two scripts would effectively be run in order as `1 99 OP_ADD 100 OP_EQUAL` and the following were occur:
|
So, presume that a UTXO were locked with a `scriptPubKey` that read `OP_ADD 99 OP_EQUAL`, requiring as input two numbers that add up to ninety-nine, and presume that the `scriptSig` of `1 98` were run to unlock it. The two scripts would effectively be run in order as `1 98 OP_ADD 99 OP_EQUAL`.
|
||||||
|
|
||||||
|
Evaulate the result:
|
||||||
```
|
```
|
||||||
Script: 1 99 OP_ADD 100 OP_EQUAL
|
Script: 1 98 OP_ADD 99 OP_EQUAL
|
||||||
Stack: []
|
Stack: []
|
||||||
|
|
||||||
Script: 99 OP_ADD 100 OP_EQUAL
|
Script: 98 OP_ADD 99 OP_EQUAL
|
||||||
Stack: [ 1 ]
|
Stack: [ 1 ]
|
||||||
|
|
||||||
Script: OP_ADD 100 OP_EQUAL
|
Script: OP_ADD 99 OP_EQUAL
|
||||||
Stack: [ 1 99 ]
|
Stack: [ 1 98 ]
|
||||||
|
|
||||||
Script: 100 OP_EQUAL
|
Script: 99 OP_EQUAL
|
||||||
Stack: [ 100 ]
|
Stack: [ 99 ]
|
||||||
|
|
||||||
Script: OP_EQUAL
|
Script: OP_EQUAL
|
||||||
Stack: [ 100 100 ]
|
Stack: [ 99 99 ]
|
||||||
|
|
||||||
Script:
|
Script:
|
||||||
Stack: [ TRUE ]
|
Stack: [ TRUE ]
|
||||||
```
|
```
|
||||||
This abstraction isn't quite accurate: for security reasons, the `scriptSig` is run, then the contents of the stack are transferred for the `scriptPubKey` to run, but it's accurate enough for understanding how the key of `scriptSig` fits into the lock of `scriptPubKey`.
|
This abstraction isn't quite accurate: for security reasons, the `scriptSig` is run, then the contents of the stack are transferred for the `scriptPubKey` to run, but it's accurate enough for understanding how the key of `scriptSig` fits into the lock of `scriptPubKey`.
|
||||||
|
|
||||||
> **WARNING** The above is a non-standard transaction type. It would not actually be accepted by nodes running Bitcoin Core with the standard settings. [8.1: Building a Bitcoin Script with P2SH.md](8_1_Building_a_Bitcoin_Script_with_P2SH.md) discusses how you actually _could_ use a Bitcoin Script like this, using the power of P2SH.
|
> **WARNING** The above is a non-standard transaction type. It would not actually be accepted by nodes running Bitcoin Core with the standard settings. [§8.1: Building a Bitcoin Script with P2SH](8_1_Building_a_Bitcoin_Script_with_P2SH.md) discusses how you actually _could_ use a Bitcoin Script like this, using the power of P2SH.
|
||||||
|
|
||||||
### Get the Results
|
### Get the Results
|
||||||
|
|
||||||
@ -108,8 +109,8 @@ Bitcoin will verify a transaction and allow the UTXO to be respent if two criter
|
|||||||
1. The execution did not get marked as invalid at any point, for example with a failed OP_VERIFY or the usage of a disabled opcode.
|
1. The execution did not get marked as invalid at any point, for example with a failed OP_VERIFY or the usage of a disabled opcode.
|
||||||
2. The top item in the stack at the end of execution is true (non-zero).
|
2. The top item in the stack at the end of execution is true (non-zero).
|
||||||
|
|
||||||
In the above example, the transaction would succeed because the stack has a `TRUE` at its top.
|
In the above example, the transaction would succeed because the stack has a `TRUE` at its top. But, it would be just as permissible to end with a full stack and the number `42` on top.
|
||||||
|
|
||||||
## Summary: Running a Bitcoin Script
|
## Summary: Running a Bitcoin Script
|
||||||
|
|
||||||
To process a Bitcoin Script, a `scriptSig` is run followed by the `scriptPubKey` that it's unlocking. These commands are run in order, from left to right, with constants being pushed onto a stack and operators popping elements off that stack, then pushing results back onto it. If the Script doesn't halt in the middle and if the item on top of the stack at the end is `TRUE`, then the UTXO is unlocked.
|
To process a Bitcoin Script, a `scriptSig` is run followed by the `scriptPubKey` that it's unlocking. These commands are run in order, from left to right, with constants being pushed onto a stack and operators popping elements off that stack, then pushing results back onto it. If the Script doesn't halt in the middle and if the item on top of the stack at the end is non-zero, then the UTXO is unlocked.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user