forked from bitcoinbook/bitcoinbook
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathch07_authorization-authentication.html
More file actions
2897 lines (2897 loc) · 132 KB
/
Copy pathch07_authorization-authentication.html
File metadata and controls
2897 lines (2897 loc) · 132 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.20">
<title>Authorization and Authentication</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment the following line when using as a custom stylesheet */
/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */
html{font-family:sans-serif;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
b,strong{font-weight:bold}
abbr{font-size:.9em}
abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
dfn{font-style:italic}
hr{height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type=checkbox],input[type=radio]{padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,::before,::after{box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.square{list-style-type:square}
ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details{margin-left:1.25rem}
details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}
details>summary::-webkit-details-marker{display:none}
details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
pre.pygments span.linenos{display:inline-block;margin-right:.75em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
li>p:empty:only-child::before{content:"";display:inline-block}
ul.checklist>li>p:first-child{margin-left:-1em}
ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]{border-bottom:1px dotted}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
</head>
<body class="article">
<div id="header">
</div>
<div id="content">
<div class="sect1">
<h2 id="c_authorization_authentication">Authorization and Authentication</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When you receive bitcoins, you have to decide who will have permission
to spend them, called <em>authorization</em>. You also have to decide how full
nodes will distinguish the authorized spenders from everyone else,
called <em>authentication</em>. Your authorization instructions and the
spender proof of authentication will be checked by thousands of
independent full nodes, which all need to come to the same conclusion
that a spend was authorized and authenticated in order for the transaction
containing it to be valid.</p>
</div>
<div class="paragraph">
<p>The original description of Bitcoin used a public key for authorization.
Alice paid Bob by putting his public key in the output of a transaction.
Authentication came from Bob in the form of a signature that committed to a
spending transaction, such as from Bob to Carol.</p>
</div>
<div class="paragraph">
<p>The actual version of Bitcoin that was originally released provided a
more flexible mechanism for both authorization and authentication.
Improvements since then have only increased that flexibility. In this
chapter, we’ll explore those features and see how they’re most commonly
used.</p>
</div>
<div class="sect2">
<h3 id="tx_script">Transaction Scripts and Script Language</h3>
<div class="paragraph">
<p>The original version of Bitcoin introduced a new
programming language called <em>Script</em>, a Forth-like stack-based
language. Both the script placed in an output and the legacy
input script used in a spending transaction are written in this scripting
language.</p>
</div>
<div class="paragraph">
<p>Script is a very simple language. It requires minimal processing and
cannot easily do many of the fancy things modern programming languages
can do.</p>
</div>
<div class="paragraph">
<p>When legacy transactions were the
most commonly used type of transaction, the majority of transactions processed
through the Bitcoin network had the form "Payment to Bob’s Bitcoin
address" and used a script called a pay to public key hash (P2PKH) script.
However, Bitcoin transactions are not limited to the "Payment to Bob’s
Bitcoin address" script. In fact, scripts can be written to express a
vast variety of complex conditions. In order to understand these more
complex scripts, we must first understand the basics of transaction
scripts and Script language.</p>
</div>
<div class="paragraph">
<p>In this section, we will demonstrate the basic components of the Bitcoin
transaction scripting language and show how it can be used to express
conditions for spending and how those conditions can be satisfied.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">Tip</div>
</td>
<td class="content">
<div class="paragraph">
<p>Bitcoin transaction validation is not based on
a static pattern but instead is achieved through the execution of a
scripting language. This language allows for a nearly infinite variety
of conditions to be expressed.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect3">
<h4 id="_turing_incompleteness">Turing Incompleteness</h4>
<div class="paragraph">
<p>The Bitcoin transaction script language
contains many operators, but is deliberately limited in one important
way—​there are no loops or complex flow control capabilities other than
conditional flow control. This ensures that the language is not <em>Turing
Complete</em>, meaning that scripts have limited complexity and predictable
execution times. Script is not a general-purpose language.
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.</p>
</div>
</div>
<div class="sect3">
<h4 id="_stateless_verification">Stateless Verification</h4>
<div class="paragraph">
<p>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. All the
information needed to execute a script is contained within the script
and the transaction executing the script. A
script will predictably execute the same way on any system. If your
system verified 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 an essential benefit of the Bitcoin
system.</p>
</div>
</div>
<div class="sect3">
<h4 id="tx_lock_unlock">Script Construction</h4>
<div class="paragraph">
<p>Bitcoin’s legacy transaction validation engine relies on two parts of scripts
to validate transactions: an output script and an input script.</p>
</div>
<div class="paragraph">
<p>An output script
specifies the conditions that must be met to spend the output in the
future, such as who is authorized to spend the output and how they will
be authenticated.</p>
</div>
<div class="paragraph">
<p>An input script is a script that satisfies the
conditions placed in an output script and allows the output
to be spent. Input scripts are part of every transaction input. Most
of the time in legacy transactions they contain a digital signature produced by the user’s
wallet from his or her private key, but not all input scripts
must contain signatures.</p>
</div>
<div class="paragraph">
<p>Every Bitcoin validating node will validate transactions by executing
the output and input scripts. As we saw in
<a href="#c_transactions">[c_transactions]</a>, each input contains an outpoint that refers to a
previous transaction output. The input also contains an input script. The
validation software will copy the input script, retrieve the UTXO
referenced by the input, and copy the output script from that UTXO. The
input and output scripts are then executed together. The input is
valid if the input script satisfies the output script’s conditions
(see <a href="#script_exec">Separate execution of output and input scripts</a>). All the inputs are validated independently as
part of the overall validation of the transaction.</p>
</div>
<div class="paragraph">
<p>Note that the preceding steps involve making copies of all data. The
original data in the previous output and current input is never changed.
In particular, the previous output is invariable and unaffected by
failed attempts to spend it. Only a valid transaction that correctly
satisfies the conditions of the output script results in the output being
considered as "spent."</p>
</div>
<div class="paragraph">
<p><a href="#input_and_output_scripts_legacy">Combining input and output scripts to evaluate a transaction script.</a> is an example of the output and
input scripts for the most common type of legacy Bitcoin transaction (a
payment to a public key hash), showing the combined script resulting
from the concatenation of the scripts prior to
validation.</p>
</div>
<div id="input_and_output_scripts_legacy" class="imageblock">
<div class="content">
<img src="images/mbc3_0701.png" alt="input_and_output_scripts">
</div>
<div class="title">Figure 1. Combining input and output scripts to evaluate a transaction script.</div>
</div>
<div class="sect4">
<h5 id="_the_script_execution_stack">The script execution stack</h5>
<div class="paragraph">
<p>Bitcoin’s scripting language is called a stack-based language because it
uses a data structure called a <em>stack</em>. A stack is a very simple data
structure that can be visualized as a stack of cards. A stack has two
base operations: push and pop. Push adds an item on top of the stack. Pop
removes the top item from the stack.</p>
</div>
<div class="paragraph">
<p>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 might 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.</p>
</div>
<div class="paragraph">
<p>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 0) if they are not equal. Bitcoin
transaction scripts usually contain a conditional operator so that they
can produce the TRUE result that signifies a valid transaction.</p>
</div>
</div>
<div class="sect4">
<h5 id="_a_simple_script">A simple script</h5>
<div class="paragraph">
<p>Now let’s apply what we’ve learned about scripts and stacks to some simple examples.</p>
</div>
<div class="paragraph">
<p>As we will see in <a href="#simplemath_script">Bitcoin’s script validation doing simple math.</a>, the script 2 3 OP_ADD 5 OP_EQUAL
demonstrates the arithmetic addition operator OP_ADD, adding two
numbers and putting the result on the stack, followed by the conditional
operator OP_EQUAL, which checks that the resulting sum is equal to
5. For brevity, the OP_ prefix may sometimes be omitted in examples
in this book. For more details on the available script operators and
functions, see <a href="https://oreil.ly/21vH9">Bitcoin Wiki’s script
page</a>.</p>
</div>
<div class="paragraph">
<p>Although most legacy output scripts refer to a public key hash (essentially, a
legacy Bitcoin address), thereby requiring proof of ownership to spend the
funds, the script does not have to be that complex. Any combination of
output and input scripts that results in a TRUE value is valid. The
simple arithmetic we used as an example of the scripting language is
also a valid script.</p>
</div>
<div class="paragraph">
<p>Use part of the arithmetic example script as the output script:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>3 OP_ADD 5 OP_EQUAL</pre>
</div>
</div>
<div class="paragraph">
<p>which can be satisfied by a transaction containing an input with the
input script:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>2</pre>
</div>
</div>
<div class="paragraph">
<p>The validation software combines the scripts:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>2 3 OP_ADD 5 OP_EQUAL</pre>
</div>
</div>
<div class="paragraph">
<p>As we see in <a href="#simplemath_script">Bitcoin’s script validation doing simple math.</a>, when
this script is executed, the result is OP_TRUE, making the transaction valid. Although this is a valid transaction
output script, note that the resulting UTXO can be spent by anyone with
the arithmetic skills
to know that the number 2 satisfies the script.</p>
</div>
<div id="simplemath_script" class="imageblock">
<div class="content">
<img src="images/mbc3_0702.png" alt="TxScriptSimpleMathExample">
</div>
<div class="title">Figure 2. Bitcoin’s script validation doing simple math.</div>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">Tip</div>
</td>
<td class="content">
<div class="paragraph">
<p>Transactions are valid if the
top result on the stack is TRUE, which is any
nonzero value.
Transactions are invalid if the top value on the stack is FALSE (the
value zero or an empty stack), the script
execution is halted explicitly by an operator (such as VERIFY,
OP_RETURN), or the script was not semantically valid (such as
containing an OP_IF statement that was not terminated by an OP_ENDIF
opcode). For details, see <a href="https://oreil.ly/J2DXt">Bitcoin
Wiki’s script page</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The following is a slightly more complex script, which calculates
2 + 7 – 3 + 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:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>2 7 OP_ADD 3 OP_SUB 1 OP_ADD 7 OP_EQUAL</pre>
</div>
</div>
<div class="paragraph">
<p>Try validating the preceding script yourself using pencil and paper.
When the script execution ends, you should be left with a TRUE value
on the stack.</p>
</div>
</div>
<div class="sect4">
<h5 id="script_exec">Separate execution of output and input scripts</h5>
<div class="paragraph">
<p>In the original Bitcoin
client, output and input scripts were concatenated and executed
in sequence. For security reasons, this was changed in 2010 because of
a vulnerability known as the 1 OP_RETURN bug. In the current
implementation, the scripts are executed separately with the stack
transferred between the two executions.</p>
</div>
<div class="paragraph">
<p>First, the input script is executed using the stack execution
engine. If the input script is executed without errors and has
no operations left over, the stack is copied and the
output script is executed. If the result of executing the output script
with the stack data copied from the input script is TRUE,
the input script has succeeded in resolving the conditions imposed
by the output script and, therefore, the input is a valid authorization
to spend the UTXO. If any result other than TRUE remains after
execution of the combined script, the input is invalid because it has
failed to satisfy the spending conditions placed on the output.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="p2pkh">Pay to Public Key Hash</h4>
<div class="paragraph">
<p>A pay to public key hash (P2PKH) script uses an output script that
contains a hash that commits to a public key. P2PKH is best known as
the basis for a legacy Bitcoin address. A P2PKH output can be spent by
presenting a public key that matches the hash commitment and a digital
signature created by the corresponding private key (see
<a href="#c_signatures">[c_signatures]</a>). Let’s look at an example of a P2PKH output script:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>OP_DUP OP_HASH160 <Key Hash> OP_EQUALVERIFY OP_CHECKSIG</pre>
</div>
</div>
<div class="paragraph less_space pagebreak-before">
<p>The Key Hash is the data that would be encoded into a legacy base58check
address. Most applications would show the <em>public key hash</em> in a script
using hexadecimal encoding and not the familiar Bitcoin
address base58check format that begins with <span class="keep-together">a "1."</span></p>
</div>
<div class="paragraph">
<p>The preceding output script can be satisfied with an input script
of the form:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><Signature> <Public Key></pre>
</div>
</div>
<div class="paragraph">
<p>The two scripts together would form the following combined validation
script:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><Sig> <Pubkey> OP_DUP OP_HASH160 <Hash> OP_EQUALVERIFY OP_CHECKSIG</pre>
</div>
</div>
<div class="paragraph">
<p>The result will be TRUE if the input script
has a valid signature from Bob’s private key that corresponds to
the public key hash set as an encumbrance.</p>
</div>
<div class="paragraph">
<p>Figures <a data-type="xref" href="#P2PubKHash1"
data-xrefstyle="select: labelnumber">#P2PubKHash1</a> and <a
data-type="xref" href="#P2PubKHash2" data-xrefstyle="select:
labelnumber">#P2PubKHash2</a> show (in two parts) a step-by-step
execution of the combined script, which will prove this is a valid
transaction.</p>
</div>
<div id="P2PubKHash1" class="imageblock">
<div class="content">
<img src="images/mbc3_0703.png" alt="Tx_Script_P2PubKeyHash_1">
</div>
<div class="title">Figure 3. Evaluating a script for a P2PKH transaction (part 1 of 2).</div>
</div>
<div id="P2PubKHash2" class="imageblock">
<div class="content">
<img src="images/mbc3_0704.png" alt="Tx_Script_P2PubKeyHash_2">
</div>
<div class="title">Figure 4. Evaluating a script for a P2PKH transaction (part 2 of 2).</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="multisig">Scripted Multisignatures</h3>
<div class="paragraph">
<p>Multisignature scripts set a condition where <em>k</em> public keys
are recorded in the script and at least <em>t</em> of those must provide
signatures to spend the funds, called <em>t</em>-of-<em>k</em>.
For example, a 2-of-3 multisignature is one
where three public keys are listed as potential signers and at least two
of those must be used to create signatures for a valid transaction to
spend the funds.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">Tip</div>
</td>
<td class="content">
<div class="paragraph">
<p>Some Bitcoin documentation, including earlier editions of this book,
uses the term "m-of-n" for a traditional multisignature. However, it’s hard
to tell "m" and "n" apart when they’re spoken, so we use the alternative
<em>t</em>-of-<em>k</em>. Both phrases refer to the same type of signature scheme.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The general form of an output script setting a <em>t</em>-of-<em>k</em> multisignature
condition is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>t <Public Key 1> <Public Key 2> ... <Public Key k> k OP_CHECKMULTISIG</pre>
</div>
</div>
<div class="paragraph">
<p>where <em>k</em> is the total number of listed public keys and <em>t</em> is the threshold
of required signatures to spend the output.</p>
</div>
<div class="paragraph">
<p>An output script setting a 2-of-3 multisignature condition looks like
this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>2 <Public Key A> <Public Key B> <Public Key C> 3 OP_CHECKMULTISIG</pre>
</div>
</div>
<div class="paragraph">
<p>The preceding output script can be satisfied with an input script
containing <span class="keep-together">signatures:</span></p>
</div>
<div class="listingblock">
<div class="content">
<pre><Signature B> <Signature C></pre>
</div>
</div>
<div class="paragraph">
<p>or any combination of two signatures from the private keys corresponding
to the three listed public keys.</p>
</div>
<div class="paragraph">
<p>The two scripts together would form the combined validation script:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><Sig B> <Sig C> 2 <Pubkey A> <Pubkey B> <Pubkey C> 3 OP_CHECKMULTISIG</pre>
</div>
</div>
<div class="paragraph">
<p>When executed, this combined script will evaluate to TRUE if
the input script has
two valid signatures from private keys that correspond to two of
the three public keys set as an encumbrance.</p>
</div>
<div class="paragraph">
<p>At this time, Bitcoin Core’s transaction relay policy limits multisignature output scripts to, at most, three
listed public keys, meaning you can do anything from a 1-of-1 to a
3-of-3 multisignature or any combination within that range.
You may want to check the IsStandard() function to see what is currently
accepted by the network. Note that the limit of three keys applies only to
standard (also known as "bare") multisignature scripts, not to
scripts wrapped in another structure like P2SH, P2WSH, or P2TR.
P2SH multisignature scripts are limited by both policy and consensus to
15 keys, allowing for up to a 15-of-15 multisignature. We will learn about
P2SH in <a href="#p2sh">Pay to Script Hash</a>. All other scripts are consensus limited to 20 keys
per OP_CHECKMULTISIG or OP_CHECKMULTISIGVERIFY opcode, although one
script may include multiple of those opcodes.</p>
</div>
<div class="sect3 less_space pagebreak-before">
<h4 id="multisig_bug">An Oddity in CHECKMULTISIG Execution</h4>
<div class="paragraph">
<p>There is an oddity in
OP_CHECKMULTISIG's execution that requires a slight workaround. When
OP_CHECKMULTISIG executes, it should consume <em>t</em> + <em>k</em> + 2 items on the stack as
parameters. However, due to the oddity, OP_CHECKMULTISIG will pop an extra
value or one value more than expected.</p>
</div>
<div class="paragraph">
<p>Let’s look at this in greater detail using the previous validation
example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><Sig B> <Sig C> 2 <Pubkey A> <Pubkey B> <Pubkey C> 3 OP_CHECKMULTISIG</pre>
</div>
</div>
<div class="paragraph">
<p>First, OP_CHECKMULTISIG pops the top item, which is <em>k</em> (in this example
"3"). Then it pops <em>k</em> items, which are the public keys that can sign;
in this example, public keys A, B, and C. Then, it pops one item, which
is <em>t</em>, the quorum (how many signatures are needed). Here <em>t</em> = 2. At this
point, OP_CHECKMULTISIG should pop the final <em>t</em> items, which are the
signatures, and see if they are valid. However, unfortunately, an oddity in
the implementation causes OP_CHECKMULTISIG to pop one more item (<em>t</em> + 1
total) than it should. The extra item is called the <em>dummy stack
element</em>, and it is disregarded when checking the
signatures so it has no direct effect on OP_CHECKMULTISIG itself.
However, the dummy element must be present because, if it isn’t present
when OP_CHECKMULTISIG attempts to pop on an empty stack, it will cause a
stack error and script failure (marking the transaction as invalid).
Because the dummy element is disregarded, it can be anything. It became the custom early on to use OP_0, which later became a
relay policy rule and eventually a consensus rule (with the enforcement of BIP147).</p>
</div>
<div class="paragraph">
<p>Because popping the dummy element is part of the consensus rules, it must now be
replicated forever. Therefore a script should look
like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>OP_0 <Sig B> <Sig C> 2 <Pubkey A> <Pubkey B> <Pubkey C> 3 OP_CHECKMULTISIG</pre>
</div>
</div>
<div class="paragraph">
<p>Thus the input script actually used in multisig is not:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><Signature B> <Signature C></pre>
</div>
</div>
<div class="paragraph">
<p>but instead it is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>OP_0 <Sig B> <Sig C></pre>
</div>
</div>
<div class="paragraph">
<p>Some people believe this oddity was a bug in the original code for
Bitcoin, but a plausible alternative explanation exists. Verifying
<em>t</em>-of-<em>k</em> signatures can require many more than <em>t</em> or <em>k</em> signature checking
operations. Let’s consider a simple example of 1-in-5, with the
following combined script:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><dummy> <Sig4> 1 <key0> <key1> <key2> <key3> <key4> 5 OP_CHECKMULTISIG</pre>
</div>
</div>
<div class="paragraph">
<p>The signature is checked first against key0, then key1, and then
the other keys before it is finally compared to its corresponding
key4. That means five signature checking operations need to be
performed even though there’s only one signature. One way to eliminate
this redundancy would have been to provide OP_CHECKMULTISIG a map
indicating which provided signature corresponds to which public key,
allowing the OP_CHECKMULTISIG operation to only perform exactly <em>t</em>
signature-checking operations. It’s possible that Bitcoin’s original
developer added the extra element (which we now call the dummy stack
element) in the original version of Bitcoin so they could add the
feature for allowing a map to be passed in a later soft fork. However,
that feature was never implemented, and the BIP147 update to the
consensus rules in 2017 makes it impossible to add that feature in the
future.</p>
</div>
<div class="paragraph">
<p>Only Bitcoin’s original developer could tell us whether the dummy stack
element was the result of a bug or a plan for a future upgrade. In this
book, we simply call it an oddity.</p>