diff --git a/09_2_Running_a_Bitcoin_Script.md b/09_2_Running_a_Bitcoin_Script.md index f717cff..9967435 100644 --- a/09_2_Running_a_Bitcoin_Script.md +++ b/09_2_Running_a_Bitcoin_Script.md @@ -1,50 +1,9 @@ -# 7.2: Running a Bitcoin Script +# 9.2: Running a Bitcoin Script > :information_source: **NOTE:** This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning. Bitcoin Scripts may not initially seem that intuitive, but their execution is quite simple, using reverse Polish notation and a stack. -## Running Bitcoin Script code - -It is recommended that you run through the examples in a Bitcoin Script Debugger (`btcdeb`) to see the transformations happening -on the stack. This will require setting up C++ and a few other accessories on your machine, so choose if you want to add this additional material to your machine. - -### Installing btcdeb - -From some appropriate folder (e.g. `~/workspace`), clone the btcdeb project from Github and compile/install it. - -```Bash -$ sudo apt-get install git -$ git clone https://github.com/kallewoof/btcdeb.git -``` -Then, get C++ and other packages installed, so that you can get `btcdeb` running. -```Bash -$ sudo apt-get install autoconf libtool g++ pkg-config make -$ cd btcdeb -$ ./autogen.sh -$ ./configure -$ make -$ sudo make install -``` -After all of that, you should have a copy of `btcdeb`: -``` -$ which btcdeb -/usr/local/bin/btcdeb -``` -It is recommended that you all install readline, as this makes the debugger a lot easier to use by supporting history using up/down arrows, left-right movement, autocompletion using tab, etc. The package is usually called `libreadline-dev` (linux) or just `readline` (mac). -```Bash -$ sudo apt-get install libreadline-dev -``` - -### Bitcoin Script Debugging Primer - -`btcdeb` takes a script, as well as any number of stack entries, as startup arguments. If you start it up with no arguments, you simply get an interpreter -where you may issue `exec [opcode]` commands to perform actions directly. - -`btcc` takes script opcodes and data and outputs a Bitcoin Script in hexadecimal form. - -We will make use of both of these in the sections below. - ## Understand the Scripting Language A Bitcoin Script has three parts: it has a line of input; it has a stack for storage; and it has specific commands for execution. @@ -61,7 +20,7 @@ For example, if you were adding together "1" and "2", your Bitcoin Script for th 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. +> :book: ***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 pushes it on the stack. So the above example of `1 2 OP_ADD` would actually look like this as it was processed: ``` @@ -75,50 +34,13 @@ Script: OP_ADD Stack: [ 1 2 ] ``` _Note that in this and in following examples the top of the stack is to the right and the bottom is to the left._ - -Let's try this out: -```Bash -$ btcc OP_1 OP_2 OP_ADD -515293 -$ btcdeb '[OP_1 OP_2 OP_ADD]' # or: btcdeb 0x515293 -btcdeb -- type `btcdeb -h` for start up options -valid script -3 op script loaded. type `help` for usage information -script | stack ---------+-------- -1 | -2 | -OP_ADD | -#0001 1 -btcdeb> step - <> PUSH stack 01 -script | stack ---------+-------- -2 | 01 -OP_ADD | -#0002 2 -btcdeb> step - <> PUSH stack 02 -script | stack ---------+-------- -OP_ADD | 02 - | 01 -#0003 OP_ADD -btcdeb> step - <> POP stack - <> POP stack - <> PUSH stack 03 -script | stack ---------+-------- - | 03 -``` - -> `btcdeb` allows you to repeat the previous command by hitting enter. We will be doing this in subsequent examples, so don't be surprised about `btcdeb>` prompts with nothing as input. It is simply repeating the previous (often `step`) command. - + ### Understand the Opcodes When a Bitcoin Script encounters an operator, it evaluates it. Each operator pops zero or more elements off the stack as inputs, usually one or two. It then processes them in a specific way before pushing zero or more elements back on the stack, usually one or two. +> :book: ***What is an Opcode?*** Opcode stands for "operation code". It's typically associated with machine-language code, and is a simple function (or "operator"). + OP_ADD pops two items off the stack (here: 2 then 1), adds then together, and pushes the result back on the stack (here: 3). ``` Script: @@ -151,62 +73,6 @@ Running: 5 4 OP_SUB Stack: [ 1 ] ``` -Let's try this one too: -```Bash -$ btcdeb '[OP_3 OP_2 OP_ADD OP_4 OP_SUB]' -btcdeb -- type `btcdeb -h` for start up options -valid script -5 op script loaded. type `help` for usage information -script | stack ---------+-------- -3 | -2 | -OP_ADD | -4 | -OP_SUB | -#0001 3 -btcdeb> step - <> PUSH stack 03 -script | stack ---------+-------- -2 | 03 -OP_ADD | -4 | -OP_SUB | -#0002 2 -btcdeb> - <> PUSH stack 02 -script | stack ---------+-------- -OP_ADD | 02 -4 | 03 -OP_SUB | -#0003 OP_ADD -btcdeb> - <> POP stack - <> POP stack - <> PUSH stack 05 -script | stack ---------+-------- -4 | 05 -OP_SUB | -#0004 4 -btcdeb> - <> PUSH stack 04 -script | stack ---------+-------- -OP_SUB | 04 - | 05 -#0005 OP_SUB -btcdeb> - <> POP stack - <> POP stack - <> PUSH stack 01 -script | stack ---------+-------- - | 01 -``` - ## Understand the Usage of Bitcoin Script That's pretty much Bitcoin Scripting ... other than a few intricacies for how this scripting language interacts with Bitcoin itself. @@ -241,8 +107,7 @@ 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`. -> :warning: **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](08_1_Understanding_the_Foundation_of_P2SH.md -) discusses how you actually _could_ run a Bitcoin Script like this, using the power of P2SH. +> :warning: **WARNING** The above is a non-standard transaction type. It would not actually be accepted by nodes running Bitcoin Core with the standard settings. [§10.1: Building a Bitcoin Script with P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) discusses how you actually _could_ run a Bitcoin Script like this, using the power of P2SH. ### Get the Results @@ -259,5 +124,4 @@ To process a Bitcoin Script, a `scriptSig` is run followed by the `scriptPubKey` ## What's Next? -Continue "Introducing Bitcoin Scripts" with [§7.3: Scripting a P2PKH](07_3_Scripting_a_P2PKH.md). - +Continue "Introducing Bitcoin Scripts" with [§9.3: Testing a Bitcoin Script](09_3_Testing_a_Bitcoin_Script.md).