mirror of
https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line.git
synced 2025-06-07 07:56:31 +00:00
Add btcdeb stuff to chapter 7
This commit is contained in:
parent
9f640da36d
commit
25c3717478
@ -4,6 +4,33 @@
|
||||
|
||||
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.
|
||||
|
||||
### Installing btcdeb
|
||||
|
||||
From some appropriate folder (e.g. `~/workspace`), clone the btcdeb project from Github and compile/install it. Note that it is recommended that you install readline, as this makes the debugger a lot easier to use (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
|
||||
$ git clone https://github.com/kallewoof/btcdeb.git
|
||||
$ cd btcdeb
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make install
|
||||
```
|
||||
|
||||
### 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.
|
||||
@ -35,6 +62,45 @@ 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 $(btcc OP_1 OP_2 OP_ADD) # or: btcdeb 515293
|
||||
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.
|
||||
@ -71,6 +137,62 @@ Running: 5 4 OP_SUB
|
||||
Stack: [ 1 ]
|
||||
```
|
||||
|
||||
Let's try this one too:
|
||||
```Bash
|
||||
$ btcdeb $(btcc 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.
|
||||
|
@ -67,6 +67,227 @@ Stack: [ True ]
|
||||
```
|
||||
The Script now ends and the transaction is allowed to respend the UTXO in question.
|
||||
|
||||
|
||||
## Running through a real example
|
||||
|
||||
If you have a scriptPubKey (the script) and a signature and pubkey (the result of running the sigScript of the input), you can debug these by doing
|
||||
|
||||
```Bash
|
||||
$ btcdeb <script> <signature> <pubkey>
|
||||
```
|
||||
|
||||
For example, transaction [4de699d05b416175ad7a119013563a0f436abe46c6a52f05bf59baca1b2aec41](https://www.smartbit.com.au/tx/4de699d05b416175ad7a119013563a0f436abe46c6a52f05bf59baca1b2aec41) in block 499033 has as its first output the script sig `483045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011012103b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42`.
|
||||
|
||||
The spent transaction output (txid [d0fcb7713582e7cda598d79b3ab084132f93db00e2ccde9bbd1d2660c55abe47](https://www.smartbit.com.au/tx/d0fcb7713582e7cda598d79b3ab084132f93db00e2ccde9bbd1d2660c55abe47) index 33) has as its script pub key `76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac`.
|
||||
|
||||
We can interpret this in two ways. Either put the two together into one big script:
|
||||
```Bash
|
||||
$ btcdeb 483045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011012103b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be4276a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac
|
||||
btcdeb -- type `btcdeb -h` for start up options
|
||||
valid script
|
||||
7 op script loaded. type `help` for usage information
|
||||
script | stack
|
||||
-------------------------------------------------------------------+--------
|
||||
3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a... |
|
||||
03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42 |
|
||||
OP_DUP |
|
||||
OP_HASH160 |
|
||||
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 |
|
||||
OP_EQUALVERIFY |
|
||||
OP_CHECKSIG |
|
||||
```
|
||||
Or we can interpret them one at a time, and use the script sig resulting stack as the input stack to the script pub key -- since we only really want the
|
||||
output, we can pipe the script to `btcdeb` and it will just print out the results (presuming the script executes cleanly):
|
||||
```Bash
|
||||
$ echo "483045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011012103b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42" | btcdeb
|
||||
3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c68501101
|
||||
03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
```
|
||||
We can then run the script pub key with these two stack entries as arguments:
|
||||
```Bash
|
||||
$ btcdeb 76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac \
|
||||
3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c68501101 \
|
||||
03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
btcdeb -- type `btcdeb -h` for start up options
|
||||
valid script
|
||||
5 op script loaded. type `help` for usage information
|
||||
script | stack
|
||||
-----------------------------------------+-------------------------------------------------------------------
|
||||
OP_DUP | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
OP_HASH160 | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
|
||||
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 |
|
||||
OP_EQUALVERIFY |
|
||||
OP_CHECKSIG |
|
||||
#0001 OP_DUP
|
||||
```
|
||||
We can also be fancy and run the results of the pipe call as argument to the second call,
|
||||
```Bash
|
||||
$ btcdeb 76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac $(echo "483045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011012103b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42" | btcdeb)
|
||||
btcdeb -- type `btcdeb -h` for start up options
|
||||
valid script
|
||||
5 op script loaded. type `help` for usage information
|
||||
script | stack
|
||||
-----------------------------------------+-------------------------------------------------------------------
|
||||
OP_DUP | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
OP_HASH160 | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
|
||||
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 |
|
||||
OP_EQUALVERIFY |
|
||||
OP_CHECKSIG |
|
||||
#0001 OP_DUP
|
||||
```
|
||||
|
||||
Either way we do it, we end up with the script on the left hand side and the stack on the right hand side.
|
||||
The top-most item in the stack is the top item, and things are "popped off" from top to bottom.
|
||||
The first item here is a public key and the second item is a signature.
|
||||
|
||||
We can check the stack directly using the `stack` command.
|
||||
```Bash
|
||||
btcdeb> stack
|
||||
<01> 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42 (top)
|
||||
<02> 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c68501101
|
||||
```
|
||||
We can also check the script we're running with `print`:
|
||||
```Bash
|
||||
btcdeb> print
|
||||
-> #0001 OP_DUP
|
||||
#0002 OP_HASH160
|
||||
#0003 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
|
||||
#0004 OP_EQUALVERIFY
|
||||
#0005 OP_CHECKSIG
|
||||
```
|
||||
The `->` arrow shows us the next instruction that is to be executed. If we run `step` we will perform the `OP_DUP` command:
|
||||
```Bash
|
||||
btcdeb> step
|
||||
<> PUSH stack 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
script | stack
|
||||
-----------------------------------------+-------------------------------------------------------------------
|
||||
OP_HASH160 | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
OP_EQUALVERIFY | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
|
||||
OP_CHECKSIG |
|
||||
#0002 OP_HASH160
|
||||
```
|
||||
Firstly, directly following the command are any PUSH or POP operations done to the stack, listed with some right-indentation and with a `<>` prefix.
|
||||
Here we see that `03b...` was pushed onto the stack. The right side shows us that the `03b...` that was there was duplicated and put on the
|
||||
stack again at the top.
|
||||
|
||||
We can keep stepping through the program and watch as it operates on the stack based on the left hand opcodes.
|
||||
```Bash
|
||||
btcdeb> step
|
||||
<> PUSH stack 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
script | stack
|
||||
-----------------------------------------+-------------------------------------------------------------------
|
||||
OP_HASH160 | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
OP_EQUALVERIFY | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
|
||||
OP_CHECKSIG |
|
||||
#0002 OP_HASH160
|
||||
btcdeb> step
|
||||
<> POP stack
|
||||
<> PUSH stack 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
|
||||
script | stack
|
||||
-----------------------------------------+-------------------------------------------------------------------
|
||||
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 | 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
|
||||
OP_EQUALVERIFY | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
OP_CHECKSIG | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
|
||||
#0003 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
|
||||
btcdeb>
|
||||
<> PUSH stack 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
|
||||
script | stack
|
||||
-----------------------------------------+-------------------------------------------------------------------
|
||||
OP_EQUALVERIFY | 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
|
||||
OP_CHECKSIG | 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
|
||||
| 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
| 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
|
||||
#0004 OP_EQUALVERIFY
|
||||
```
|
||||
In the second step above, the "opcode" was simply a chunk of data. Data is interpreted as a "push" operation of the data itself,
|
||||
which you can see is what happened here. The next operator is the `OP_EQUALVERIFY` which checks that the two top items are identical.
|
||||
Which you can observe that they are, so the operation should succeed. If the two were not identical, it should fail.
|
||||
|
||||
> *EXERCISE:* Pop off the top entry, and push some other random data on and step into the data. You should receive an error. Now pop your data off and push 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 back onto the stack and then try stepping again. It should now succeed. Use the `exec` command to perform operations on-the-fly.
|
||||
|
||||
If you `step` two more times, you will have an error. This is because `btcdeb` does not know enough to verify
|
||||
the signature of the transaction (specifically, it needs the transaction itself). We can pass that in to test the
|
||||
signature verification part as well by grabbing the transaction hex (note: not the txid, we need the entire hex
|
||||
of the transaction) and including it in the call to `btcdeb`.
|
||||
|
||||
We can get the hex of any transaction by appending `?format=hex` to the end of a transaction on
|
||||
blockchain.info. The transaction here is found at: https://blockchain.info/tx/4de699d05b416175ad7a119013563a0f436abe46c6a52f05bf59baca1b2aec41?format=hex
|
||||
|
||||
Restart btcdeb with `tx=`(hex):
|
||||
|
||||
```Bash
|
||||
$ ./btcdeb \
|
||||
tx=010000000247be5ac560261dbd9bdecce200db932f1384b03a9bd798a5cde7823571b7fcd0210000006b483045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011012103b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42ffffffffc6f5428a05fc20d1aa27c14e1e9bacb07f16d67895d2d48b97792167ad9c7cd1010000006a47304402201b0e1e9e3632740859c1f76dc002af546d28ecca10dbe96f5350fbc8daa3b279022017878fda5c2d47bb03d1554ed4637b554ec63b135df5387a4a32125cda6dd794012103e7cfd3c98952410dd14079e9160f91f968240da2603e25e4b3ef555fc7ed7d09ffffffff030066e9000000000017a9146c52f451a2bc85b815610fa5cd13127cb5c5a7c787c3df5307000000001976a914726d8c8926da39704d60dd401fa4026aa836068e88aca0950100000000001976a91475eac11f3cfda3e79c90469dac0ebaaaacde701488ac00000000 \
|
||||
76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac \
|
||||
3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c68501101 \
|
||||
03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
btcdeb -- type `./btcdeb -h` for start up options
|
||||
got transaction:
|
||||
CTransaction(hash=4de699d05b, ver=1, vin.size=2, vout.size=3, nLockTime=0)
|
||||
CTxIn(COutPoint(d0fcb77135, 33), scriptSig=483045022100c7d8e302908f)
|
||||
CTxIn(COutPoint(d17c9cad67, 1), scriptSig=47304402201b0e1e9e363274)
|
||||
CScriptWitness()
|
||||
CScriptWitness()
|
||||
CTxOut(nValue=0.15296000, scriptPubKey=a9146c52f451a2bc85b815610fa5cd)
|
||||
CTxOut(nValue=1.22937283, scriptPubKey=76a914726d8c8926da39704d60dd40)
|
||||
CTxOut(nValue=0.00103840, scriptPubKey=76a91475eac11f3cfda3e79c90469d)
|
||||
|
||||
valid script
|
||||
5 op script loaded. type `help` for usage information
|
||||
script | stack
|
||||
-----------------------------------------+-------------------------------------------------------------------
|
||||
OP_DUP | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
OP_HASH160 | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
|
||||
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 |
|
||||
OP_EQUALVERIFY |
|
||||
OP_CHECKSIG |
|
||||
#0001 OP_DUP
|
||||
btcdeb> step
|
||||
[...]
|
||||
々 step
|
||||
TransactionSignatureChecker::CheckSig(72 len sig, 33 len pubkey, sigversion=0)
|
||||
sig = 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c68501101
|
||||
pub key = 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
|
||||
script code = 76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac
|
||||
hash type = 01 (SIGHASH_ALL)
|
||||
SignatureHash(nIn=0, nHashType=01)
|
||||
- sigversion = SIGVERSION_BASE (non-segwit style)
|
||||
Serializing transaction
|
||||
<< txTo.nVersion (00000001)
|
||||
<< nInputs = 2 [compact]
|
||||
(serialize input 0)
|
||||
<< txTo.vin[nInput=0].prevout = COutPoint(d0fcb77135, 33)
|
||||
(SerializeScriptCode)
|
||||
<< scriptCode.size()=25 - nCodeSeparators=0
|
||||
<< script:76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac
|
||||
<< txTo.vin[nInput].nSequence = 4294967295 [0xffffffff]
|
||||
(serialize input 1)
|
||||
<< txTo.vin[nInput=1].prevout = COutPoint(d17c9cad67, 1)
|
||||
<< [empty script] (reason: nInput != nIn)
|
||||
<< txTo.vin[nInput].nSequence = 4294967295 [0xffffffff]
|
||||
<< nOutputs = 3 [compact]
|
||||
(serialize output 0)
|
||||
<< txTo.vout[nOutput] = CTxOut(nValue=0.15296000, scriptPubKey=a9146c52f451a2bc85b815610fa5cd)
|
||||
(serialize output 1)
|
||||
<< txTo.vout[nOutput] = CTxOut(nValue=1.22937283, scriptPubKey=76a914726d8c8926da39704d60dd40)
|
||||
(serialize output 2)
|
||||
<< txTo.vout[nOutput] = CTxOut(nValue=0.00103840, scriptPubKey=76a91475eac11f3cfda3e79c90469d)
|
||||
<< txTo.nLockTime = 0 [0x0]
|
||||
sighash = 8b2fc7c4b0ce353c524dbd1059f2fcb7355597555e5d840ad5506d9b473923fd
|
||||
pubkey.Verify(sig=3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011, sighash=8b2fc7c4b0ce353c524dbd1059f2fcb7355597555e5d840ad5506d9b473923fd):
|
||||
- secp256k1_ecdsa_verify() returned success
|
||||
result: success
|
||||
<> POP stack
|
||||
<> POP stack
|
||||
<> PUSH stack 01
|
||||
script | stack
|
||||
-----------------------------------------+-------------------------------------------------------------------
|
||||
| 01
|
||||
btcdeb>
|
||||
```
|
||||
|
||||
## Summary: Scripting a Pay to Public Key Hash
|
||||
|
||||
Sending to a P2PKH address was relatively easy when you were just using `bitcoin-cli`. Examining the Bitcoin Script underlying it lays bare the cryptographic functions that were implicit in funding that transaction: how the UTXO was unlocked with a signature and a public key.
|
||||
|
Loading…
x
Reference in New Issue
Block a user