-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
for_use_ethereumbook_11oraclestxt_fr_CA.html
846 lines (826 loc) · 75.2 KB
/
for_use_ethereumbook_11oraclestxt_fr_CA.html
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
<!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.17">
<title>Oracles</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.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
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}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.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>: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,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="oracles_chap">Oracles</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Dans ce chapitre, nous discutons des <em>oracles</em>, qui sont des systèmes qui peuvent fournir des sources de données externes aux contrats intelligents Ethereum. Le terme « oracle » vient de la mythologie grecque, où il faisait référence à une personne en communication avec les dieux qui pouvait avoir des visions du futur. Dans le contexte des chaînes de blocs, un oracle est un système qui peut répondre à des questions externes à Ethereum. Idéalement, les oracles sont des systèmes <em>sans confiance</em>, ce qui signifie qu’ils n’ont pas besoin d’être fiables car ils fonctionnent selon des principes décentralisés.</p>
</div>
<div class="sect2">
<h3 id="why_oracles">Pourquoi les oracles sont nécessaires</h3>
<div class="paragraph">
<p>Un composant clé de la plate-forme Ethereum est la machine virtuelle Ethereum, avec sa capacité à exécuter des programmes et à mettre à jour l’état d’Ethereum, contraint par des règles de consensus, sur n’importe quel nœud du réseau décentralisé. Afin de maintenir le consensus, l’exécution d’EVM doit être totalement déterministe et basée uniquement sur le contexte partagé de l’état Ethereum et des transactions signées. Cela a deux conséquences particulièrement importantes : la première est qu’il ne peut y avoir de source intrinsèque d’aléatoire avec laquelle l’EVM et les contrats intelligents peuvent fonctionner ; la seconde est que les données extrinsèques ne peuvent être introduites que comme données utiles d’une transaction.</p>
</div>
<div class="paragraph">
<p>Déballons ces deux conséquences plus loin. Pour comprendre l’interdiction d’une véritable fonction aléatoire dans l’EVM pour fournir un caractère aléatoire aux contrats intelligents, considérez l’effet sur les tentatives de parvenir à un consensus après l’exécution d’une telle fonction : le nœud A exécuterait la commande et stockerait <code>3</code> au nom du contrat intelligent dans son stockage, tandis que le nœud B, exécutant le même contrat intelligent, stockerait <code>7</code> à la place. Ainsi, les nœuds A et B arriveraient à des conclusions différentes sur ce que devrait être l’état résultant, bien qu’ils aient exécuté exactement le même code dans le même contexte. En effet, il se pourrait qu’un état résultant différent soit atteint à chaque fois que le contrat intelligent est évalué. En tant que tel, il n’y aurait aucun moyen pour le réseau, avec sa multitude de nœuds fonctionnant indépendamment dans le monde, de parvenir à un consensus décentralisé sur ce que devrait être l’état résultant. En pratique, cela deviendrait bien pire que cet exemple très rapidement, car les effets d’entraînement, y compris les transferts d’ether, s’accumuleraient de façon exponentielle.</p>
</div>
<div class="paragraph">
<p>Notez que les fonctions pseudo-aléatoires, telles que les fonctions de hachage cryptographiquement sécurisées (qui sont déterministes et peuvent donc faire, et font en effet, partie de l’EVM), ne suffisent pas pour de nombreuses applications. Prenez un jeu de hasard qui simule des lancers de pièces pour résoudre les paiements de pari, qui doivent randomiser pile ou face – un mineur peut obtenir un avantage en jouant au jeu et en n’incluant ses transactions que dans les blocs pour lesquels il gagnera. Alors comment contourner ce problème ? Eh bien, tous les nœuds peuvent s’entendre sur le contenu des transactions signées, de sorte que les informations extrinsèques, y compris les sources aléatoires, les informations sur les prix, les prévisions météorologiques, etc., peuvent être introduites en tant que partie des données des transactions envoyées au réseau. Cependant, ces données ne sont tout simplement pas fiables, car elles proviennent de sources invérifiables. En tant que tel, nous venons de reporter le problème. Nous utilisons des oracles pour tenter de résoudre ces problèmes, dont nous parlerons en détail dans la suite de ce chapitre.</p>
</div>
</div>
<div class="sect2">
<h3 id="oracle_use_cases">Cas d’utilisation Oracle et exemples</h3>
<div class="paragraph">
<p>Les oracles, idéalement, fournissent un moyen sans confiance (ou du moins presque sans confiance) d’obtenir des informations extrinsèques (c’est-à-dire "du monde réel" ou hors chaîne), tels que les résultats des matchs de football, le prix de l’or ou des nombres vraiment aléatoires, sur la plate-forme Ethereum pour les contrats intelligents à utiliser. Ils peuvent également être utilisés pour relayer directement les données en toute sécurité vers les interfaces DApp. Les oracles peuvent donc être considérés comme un mécanisme permettant de combler le fossé entre le monde hors chaîne et les contrats intelligents. Permettre aux contrats intelligents d’appliquer des relations contractuelles basées sur des événements et des données du monde réel élargit considérablement leur portée. Cependant, cela peut également introduire des risques externes pour le modèle de sécurité d’Ethereum. Considérez un contrat « testamentaire intelligent » qui distribue les actifs lorsqu’une personne décède. C’est quelque chose de fréquemment discuté dans l’espace des contrats intelligents, et met en évidence les risques d’un oracle de confiance. Si le montant de l’héritage contrôlé par un tel contrat est suffisamment élevé, l’incitation à pirater l’oracle et à déclencher la distribution des actifs <em>avant</em> le décès du propriétaire est très élevée.</p>
</div>
<div class="paragraph">
<p>Notez que certains oracles fournissent des données propres à une source de données privée spécifique, telles que des certificats universitaires ou des identifiants gouvernementaux. La source de ces données, comme une université ou un département gouvernemental, est entièrement fiable et la vérité des données est subjective (la vérité n’est déterminée qu’en faisant appel à l’autorité de la source). De telles données ne peuvent donc pas être fournies sans confiance, c’est-à-dire sans faire confiance à une source, car il n’y a pas de vérité objective vérifiable de manière indépendante. En tant que tels, nous incluons ces sources de données dans notre définition de ce qui compte comme des "oracles", car elles fournissent également un pont de données pour les contrats intelligents. Les données qu’ils fournissent prennent généralement la forme d’attestations, telles que des passeports ou des certificats de réussite. Les attestations deviendront une grande partie du succès des plates-formes de chaîne de blocs à l’avenir, en particulier en ce qui concerne les problèmes connexes de vérification de l’identité ou de la réputation, il est donc important d’explorer comment elles peuvent être servies par les plates-formes de chaîne de blocs.</p>
</div>
<div class="paragraph">
<p>Voici d’autres exemples de données pouvant être fournies par les oracles :</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Nombres aléatoires/entropie provenant de sources physiques telles que les processus quantiques/thermiques : par exemple, pour sélectionner équitablement un gagnant dans un contrat intelligent de loterie</p>
</li>
<li>
<p>Déclencheurs paramétriques indexés sur les aléas naturels : par exemple, déclenchement de contrats intelligents d’obligation catastrophe, tels que les mesures à l’échelle de Richter pour une obligation tremblement de terre</p>
</li>
<li>
<p>Données de taux de change : par exemple, pour un rattachement précis des cryptomonnaies à la monnaie fiduciaire</p>
</li>
<li>
<p>Données sur les marchés des capitaux : par exemple, prix des paniers d’actifs/titres symboliques</p>
</li>
<li>
<p>Données de référence de tests de performance : par exemple, intégration des taux d’intérêt dans les dérivés financiers intelligents</p>
</li>
<li>
<p>Données statiques/pseudostatiques : identifiants de sécurité, codes pays, codes devises, etc.</p>
</li>
<li>
<p>Données de temps et d’intervalle : pour les déclencheurs d’événements fondés sur des mesures de temps précises</p>
</li>
<li>
<p>Données météorologiques : par exemple, calculs de primes d’assurance basés sur les prévisions météorologiques</p>
</li>
<li>
<p>Événements politiques : pour la résolution du marché de prédiction</p>
</li>
<li>
<p>Événements sportifs : pour la résolution du marché de la prédiction et les contrats de sports fantastiques</p>
</li>
<li>
<p>Données de géolocalisation : par exemple, telles qu’elles sont utilisées dans le suivi de la chaîne d’approvisionnement</p>
</li>
<li>
<p>Vérification des dommages : pour les contrats d’assurance</p>
</li>
<li>
<p>Événements survenant sur d’autres chaînes de blocs : fonctions d’interopérabilité</p>
</li>
<li>
<p>Prix du marché de l’ether : par exemple, oracles pour le prix du gaz en fiat</p>
</li>
<li>
<p>Statistiques de vol : par exemple, telles qu’elles sont utilisées par les groupes et les clubs pour la mise en commun des billets d’avion</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Dans les sections suivantes, nous examinerons certaines des façons dont les oracles peuvent être implémentés, y compris les modèles d’oracle de base, les oracles de calcul, les oracles décentralisés et les implémentations de client oracle dans Solidity.</p>
</div>
</div>
<div class="sect2">
<h3 id="oracle_design_patterns">Modèles de conception Oracle</h3>
<div class="paragraph">
<p>Tous les oracles fournissent quelques fonctions clés, par définition. Ceux-ci incluent la capacité de :</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Recueillir des données à partir d’une source hors chaîne.</p>
</li>
<li>
<p>Transférez les données en chaîne avec un message signé.</p>
</li>
<li>
<p>Rendre les données disponibles en les plaçant dans le stockage d’un contrat intelligent.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Une fois que les données sont disponibles dans le stockage d’un contrat intelligent, elles peuvent être consultées par d’autres contrats intelligents via des appels de message qui invoquent une fonction "retrieve" (récupérer) du contrat intelligent de l’oracle ; il est également accessible directement aux nœuds Ethereum ou aux clients activés par le réseau en "recherchant" le stockage de l’oracle.</p>
</div>
<div class="paragraph">
<p>Les trois principales façons de configurer un oracle peuvent être classées comme <em>request–response</em> (requête-réponse), <span class="keep-together"><em>publish-subscribe</em></span> (publication-abonnement) et <em>immediate-read</em> (immédiat-lecture).</p>
</div>
<div class="paragraph">
<p> En commençant par le plus simple, les oracles à lecture immédiate sont ceux qui fournissent des données qui ne sont nécessaires que pour une décision immédiate, comme "Quelle est l’adresse de <em>ethereumbook.info</em>?" ou "Cette personne a-t-elle plus de 18 ans ?" Ceux qui souhaitent interroger ce type de données ont tendance à le faire sur une base « juste à temps » ; la recherche est effectuée lorsque l’information est nécessaire et peut-être plus jamais après. Des exemples de tels oracles incluent ceux qui contiennent des données sur ou émises par des organisations, telles que des certificats académiques, des codes de numérotation, des adhésions institutionnelles, des identifiants d’aéroport, des identifiants auto-souverains, etc. Ce type d’oracle stocke les données une fois dans son stockage contractuel, d’où tout un autre contrat intelligent peut le rechercher à l’aide d’un appel de demande au contrat oracle. Il peut être mis à jour. Les données dans le stockage de l’oracle sont également disponibles pour une recherche directe par des applications compatibles avec la chaîne de blocs (c’est-à-dire, Ethereum <span class="keep-together">connecté au client</span>) sans avoir à passer par la palabre et à encourir les coûts de gaz liés à l’émission d’une transaction. Un magasin voulant vérifier l’âge d’un client souhaitant acheter de l’alcool pourrait utiliser un oracle de cette manière. Ce type d’oracle est attrayant pour une organisation ou une entreprise qui pourrait autrement avoir à exécuter et à entretenir des serveurs pour répondre à de telles demandes de données. Notez que les données stockées par l’oracle ne sont probablement pas les données brutes que l’oracle sert, par exemple, pour des raisons d’efficacité ou de confidentialité. Une université peut mettre en place un oracle pour les certificats de réussite scolaire des anciens étudiants. Cependant, stocker tous les détails des certificats (qui pourraient s’étendre sur des pages de cours suivis et de notes obtenues) serait excessif. Au lieu de cela, un hachage du certificat est suffisant. De même, un gouvernement pourrait souhaiter mettre les identifiants des citoyens sur la plate-forme Ethereum, où il est clair que les détails inclus doivent rester confidentiels. Encore une fois, hacher les données (plus soigneusement, dans les arbres Merkle avec des sels) et ne stocker que le hachage racine dans le stockage du contrat intelligent serait un moyen efficace d’organiser un tel service.</p>
</div>
<div class="paragraph">
<p>La configuration suivante est <em>publication-abonnement</em> (<em>publish–subscribe</em>), où un oracle qui fournit effectivement un service de diffusion pour les données qui devraient changer de valeurs (peut-être à la fois régulièrement et fréquemment) est soit interrogé par un contrat intelligent sur la chaîne, soit surveillé par un processus hors chaîne pour les mises à jour. Cette catégorie a un modèle similaire aux flux RSS, WebSub, etc., où l’oracle est mis à jour avec de nouvelles informations et un indicateur signale que de nouvelles données sont disponibles pour ceux qui se considèrent comme "abonnés". Les parties intéressées doivent soit interroger l’oracle pour vérifier si les dernières informations ont changé, soit écouter les mises à jour des contrats oracle et agir lorsqu’elles se produisent. Les exemples incluent les flux de prix, les informations météorologiques, les statistiques économiques ou sociales, les données de trafic, etc. Le sondage est très inefficace dans le monde des serveurs Web, mais pas dans le contexte pair à pair des plateformes en chaîne de blocs : les clients Ethereum doivent suivre avec tous les changements d’état, y compris les changements de stockage de contrat, de sorte que l’interrogation des changements de données est un appel local à un client synchronisé. Les journaux d’événements Ethereum permettent aux applications de rechercher particulièrement, et ce facilement, les mises à jour d’un oracle, et donc ce modèle peut même être considéré à certains égards comme un service "push" (d’envoi). Cependant, si l’interrogation est effectuée à partir d’un contrat intelligent, ce qui peut être nécessaire pour certaines applications décentralisées (par exemple, lorsque les incitations à l’activation ne sont pas possibles), des dépenses importantes en gaz peuvent être engagées.</p>
</div>
<div class="paragraph">
<p>La catégorie <em>request–response</em> (<em>requête-réponse</em>) est la plus compliquée : c’est lorsque la quantité de données est trop grande pour être stocké dans un contrat intelligent et les utilisateurs ne devraient avoir besoin que d’une petite partie de l’ensemble de données globale à la fois. C’est également un modèle applicable pour les entreprises de fournisseurs de données. Concrètement, un tel oracle pourrait être mis en œuvre comme un système de contrats intelligents en chaîne et une infrastructure hors chaîne utilisée pour surveiller les demandes et récupérer et renvoyer des données. Une demande de données à partir d’une application décentralisée serait généralement un processus asynchrone impliquant un certain nombre d’étapes. Dans ce modèle, premièrement, un EOA traite avec une application décentralisée, ce qui entraîne une interaction avec une fonction définie dans le contrat intelligent de l’oracle. Cette fonction initie la demande à l’oracle, avec les arguments associés détaillant les données demandées en plus d’informations supplémentaires pouvant inclure des fonctions de rappel et des paramètres de planification. Une fois cette transaction validée, la requête oracle peut être observée comme un événement EVM émis par le contrat oracle, ou comme un changement d’état ; les arguments peuvent être récupérés et utilisés pour effectuer la requête réelle de la source de données hors chaîne. L’oracle peut également exiger un paiement pour le traitement de la demande, c’est à dire le paiement du gaz pour le rappel et les autorisations d’accès aux données demandées. Enfin, les données résultantes sont signées par le propriétaire de l’oracle, attestant de la validité des données à un moment donné, et livrées dans une transaction à l’application décentralisée qui a fait la demande, soit directement, soit via le contrat de l’oracle. En fonction des paramètres de planification, l’oracle peut diffuser d’autres transactions mettant à jour les données à intervalles régulières (par exemple, des informations de tarification en fin de journée).</p>
</div>
<div class="paragraph">
<p>Les étapes d’un oracle de requête-réponse peuvent être résumées comme suit :</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Recevez une requête d’un DApp.</p>
</li>
<li>
<p>Analysez la requête.</p>
</li>
<li>
<p>Vérifiez que les autorisations de paiement et d’accès aux données sont fournies.</p>
</li>
<li>
<p>Récupérez les données pertinentes d’une source hors chaîne (et cryptez-les si nécessaire).</p>
</li>
<li>
<p>Signez la ou les transactions avec les données incluses.</p>
</li>
<li>
<p>Diffusez la ou les transactions sur le réseau.</p>
</li>
<li>
<p>Planifiez toutes les autres transactions nécessaires, telles que les notifications, etc.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Une gamme d’autres régimes sont également possibles; par exemple, les données peuvent être demandées et renvoyées directement par un EOA, supprimant ainsi le besoin d’un contrat intelligent d’oracle. De même, la demande et la réponse pourraient être faites vers et depuis un capteur matériel compatible avec l’Internet des objets. Par conséquent, les oracles peuvent être humains, logiciels ou matériels.</p>
</div>
<div class="paragraph">
<p>Le modèle requête-réponse décrit ici est couramment observé dans les architectures client-serveur. Bien qu’il s’agisse d’un modèle de messagerie utile qui permet aux applications d’avoir une conversation bidirectionnelle, il est peut-être inapproprié dans certaines conditions. Par exemple, une obligation intelligente nécessitant un taux d’intérêt auprès d’un oracle pourrait devoir demander les données quotidiennement selon un modèle demande-réponse afin de s’assurer que le taux est toujours correct. Étant donné que les taux d’intérêt changent rarement, un modèle de publication-abonnement peut être plus approprié ici, en particulier si l’on tient compte de la bande passante limitée d’Ethereum.</p>
</div>
<div class="paragraph">
<p>La publication-abonnement est un modèle dans lequel les éditeurs (dans ce contexte, les oracles) n’envoient pas de messages directement aux destinataires, mais classent plutôt les messages publiés dans des classes distinctes. Les abonnés peuvent exprimer leur intérêt pour une ou plusieurs classes et récupérer uniquement les messages qui les intéressent. Dans un tel modèle, un oracle pourrait écrire le taux d’intérêt dans sa propre mémoire interne à chaque fois qu’il change. Plusieurs DApps abonnés peuvent simplement le lire à partir du contrat oracle, réduisant ainsi l’impact sur la bande passante du réseau tout en minimisant les coûts de stockage.</p>
</div>
<div class="paragraph">
<p>Dans un modèle de diffusion ou de multidiffusion, un oracle publierait tous les messages sur un canal et les contrats d’abonnement écouteraient le canal sous une variété de modes d’abonnement. Par exemple, un oracle peut publier des messages sur un canal de taux de change de cryptomonnaie. Un contrat intelligent d’abonnement pourrait demander le contenu complet de la chaîne s’il avait besoin de la série chronologique pour, par exemple, un calcul de moyenne mobile ; un autre peut n’exiger que le dernier taux pour un calcul du prix au comptant. Un modèle de diffusion est approprié lorsque l’oracle n’a pas besoin de connaître l’identité du <span class="keep-together">contrat</span> d’abonnement.</p>
</div>
</div>
<div class="sect2">
<h3 id="data_authentication_sec">Authentification des données</h3>
<div class="paragraph">
<p>Si nous supposons que la source de les données interrogées par une DApp font à la fois autorité et sont dignes de confiance (une hypothèse non négligeable), une question reste en suspens : étant donné que l’oracle et le mécanisme de requête-réponse peuvent être exploités par des entités distinctes, comment pouvons-nous faire confiance à ce mécanisme ? Il existe une réelle possibilité que les données soient altérées en transit, il est donc essentiel que les méthodes hors chaîne soient en mesure d’attester de l’intégrité des données renvoyées. Deux approches courantes de l’authentification des données sont les <em>preuves d’authenticité</em> et les <em>environnements d’exécution de confiance</em> (TEE).</p>
</div>
<div class="paragraph">
<p>Les preuves d’authenticité sont des garanties cryptographiques que les données n’ont pas été falsifiées. Basées sur une variété de techniques d’attestation (par exemple, des preuves signées numériquement), elles transfèrent efficacement la confiance du support de données vers l’attestateur (c’est-à-dire le fournisseur de l’attestation). En vérifiant la preuve d’authenticité en chaîne, les contrats intelligents sont en mesure de vérifier l’intégrité des données avant de les exploiter. <a href="http://www.oraclize.it/">Oraclize</a> est un exemple de service oracle exploitant une variété de preuves d’authenticité. Une de ces preuves qui est actuellement disponible pour les requêtes de données à partir du réseau principal Ethereum est la preuve TLSNotary. Les preuves TLSNotary permettent à un client de fournir la preuve à un tiers que le trafic Web HTTPS s’est produit entre le client et un serveur. Bien que HTTPS soit lui-même sécurisé, il ne prend pas en charge la signature des données. Par conséquent, les preuves TLSNotary reposent sur les signatures TLSNotary (via PageSigner). Les preuves TLSNotary s’appuient sur le protocole Transport Layer Security (TLS), permettant à la clé principale TLS, qui signe les données après leur accès, d’être répartie entre trois parties : le serveur (l’oracle), un audité (Oraclize) et un Auditeur. Oraclize utilise une instance de machine virtuelle Amazon Web Services (AWS) comme auditeur, qui peut être vérifiée comme n’ayant pas été modifiée depuis l’instanciation. Cette instance AWS stocke le secret TLSNotary, lui permettant de fournir des preuves d’honnêteté. Bien qu’elle offre des garanties plus élevées contre la falsification des données qu’un simple mécanisme de requête-réponse, cette approche nécessite l’hypothèse qu’Amazon lui-même ne falsifiera pas l’instance de VM.</p>
</div>
<div class="paragraph">
<p><a href="http://www.town-crier.org/">Town Crier</a> est un système oracle de flux de données authentifié basé sur l’approche TEE ; ces méthodes utilisent des enclaves sécurisées basées sur le matériel pour garantir l’intégrité des données. Town Crier utilise Intel Software Guard eXtensions (SGX) pour s’assurer que les réponses des requêtes HTTPS peuvent être vérifiées comme authentiques . SGX offre des garanties d’intégrité, garantissant que les applications s’exécutant dans une enclave sont protégées par le CPU contre toute altération par tout autre processus. Il assure également la confidentialité, garantissant que l’état d’une application est opaque pour les autres processus lors de son exécution dans l’enclave. Et enfin, SGX permet l’attestation, en générant une preuve signée numériquement qu’une application, identifiée de manière sécurisée par un hachage de sa version, s’exécute réellement dans une enclave. En vérifiant cette signature numérique, il est possible pour une application décentralisée de prouver qu’une instance Town Crier fonctionne en toute sécurité dans une enclave SGX. Ceci, à son tour, prouve que l’instance n’a pas été falsifiée et que les données émises par Town Crier sont donc authentiques. La propriété de confidentialité permet en outre à Town Crier de gérer des données privées en autorisant le chiffrement des requêtes de données à l’aide de la clé publique de l’instance Town Crier. L’utilisation du mécanisme de requête-réponse d’un oracle dans une enclave telle que SGX nous permet de penser qu’il s’exécute en toute sécurité sur du matériel tiers de confiance, garantissant que les données demandées sont renvoyées sans altération (en supposant que nous faisons confiance à Intel/SGX).</p>
</div>
</div>
<div class="sect2">
<h3 id="computation_oracles_sec">Oracles de calcul</h3>
<div class="paragraph">
<p>Jusqu’à présent, nous n’avons discuté des oracles que dans le contexte de la demande et de la livraison de données. Cependant, les oracles peuvent également être utilisés pour effectuer des calculs arbitraires, une fonction qui peut être particulièrement utile compte tenu de la limite de gaz de bloc inhérente à Ethereum et des coûts de calcul relativement élevés. Plutôt que de simplement relayer les résultats d’une requête, les oracles de calcul peuvent être utilisés pour effectuer des calculs sur un ensemble d’entrées et renvoyer un résultat calculé qu’il aurait peut-être été impossible de calculer en chaîne. Par exemple, on peut utiliser un oracle pour effectuer un calcul de régression intensif afin d’estimer le rendement d’un contrat obligataire.</p>
</div>
<div class="paragraph">
<p>Si vous êtes prêt à faire confiance à un service centralisé mais auditable, vous pouvez revenir à Oraclize. Ils fournissent un service qui permet aux applications décentralisées de demander la sortie d’un calcul effectué dans une machine virtuelle AWS en bac à sable. L’instance AWS crée un conteneur exécutable à partir d’un fichier Dockerfile configuré par l’utilisateur, compressé dans une archive qui est téléchargée sur le système de fichiers décentralisé (IPFS ; voir <a href="#data_storage_sec">[data_storage_sec]</a>). Sur demande, Oraclize récupère cette archive à l’aide de son hachage, puis initialise et exécute le conteneur Docker sur AWS, en transmettant tous les arguments fournis à l’application en tant que variables d’environnement. L’application conteneurisée effectue le calcul, soumis à une contrainte de temps, et écrit le résultat sur la sortie standard, où il peut être récupéré par Oraclize et renvoyé à l’application décentralisée. Oraclize propose actuellement ce service sur une instance AWS t2.micro auditable, donc si le calcul a une valeur non triviale, il est possible de vérifier que le bon conteneur Docker a été exécuté. Néanmoins, ce n’est pas une solution véritablement décentralisée.</p>
</div>
<div class="paragraph">
<p>Le concept de "cryptlet" en tant que norme pour les vérités d’oracle vérifiables a été formalisé dans le cadre plus large de l’ESC Framework de Microsoft. Les cryptlets s’exécutent dans une capsule chiffrée qui fait abstraction de l’infrastructure, telle que les Entrées/Sorties, et auquel le CryptoDelegate est attaché afin que les messages entrants et sortants soient signés, validés et prouvés automatiquement. Les cryptlets prennent en charge les transactions distribuées afin que la logique de contrat puisse prendre en charge des transactions complexes à plusieurs étapes, à plusieurs chaînes de blocs et de systèmes externes de manière ACID. Cela permet aux développeurs de créer des résolutions portables, isolées et privées de la vérité à utiliser dans les contrats intelligents. Les cryptlets suivent le format indiqué ici :</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-solidity" data-lang="solidity">public class SampleContractCryptlet : Cryptlet
{
public SampleContractCryptlet(Guid id, Guid bindingId, string name,
string address, IContainerServices hostContainer, bool contract)
: base(id, bindingId, name, address, hostContainer, contract)
{
MessageApi = new CryptletMessageApi(GetType().FullName,
new SampleContractConstructor())</code></pre>
</div>
</div>
<div class="paragraph">
<p>Pour une solution plus décentralisée, nous pouvons nous tourner vers <a href="https://truebit.io/">TrueBit</a>, qui offre une solution de calcul hors chaîne évolutive et vérifiable. Ils utilisent un système de solveurs et de vérificateurs qui sont incités à effectuer des calculs et à vérifier ces calculs, respectivement. Si une solution est contestée, un processus de vérification itératif sur des sous-ensembles du calcul est effectué en chaîne, une sorte de « jeu de vérification ». Le jeu se déroule à travers une série de tours, chacun vérifiant de manière récursive un sous-ensemble de plus en plus petit du calcul. Le jeu atteint finalement un tour final, où le défi est suffisamment trivial pour que les juges - les mineurs d’Ethereum - puissent rendre une décision finale sur la question de savoir si le défi a été relevé, en chaîne. En effet, TrueBit est une implémentation d’un marché de calcul, permettant aux applications décentralisées de payer pour un calcul vérifiable à effectuer en dehors du réseau, mais s’appuyant sur Ethereum pour faire respecter les règles du jeu de vérification. En théorie, cela permet aux contrats intelligents sans confiance d’effectuer en toute sécurité n’importe quelle tâche de calcul.</p>
</div>
<div class="paragraph">
<p>Un large éventail d’applications existe pour des systèmes comme TrueBit, allant de l’apprentissage automatique à la vérification de la preuve de travail. Un exemple de ce dernier est le pont Doge-Ethereum, qui utilise TrueBit pour vérifier la preuve de travail de Dogecoin (Scrypt), qui est une fonction gourmande en mémoire et en calcul qui ne peut pas être calculée dans la limite de gaz du bloc Ethereum. En effectuant cette vérification sur TrueBit, il a été possible de vérifier en toute sécurité les transactions Dogecoin dans un contrat intelligent sur le testnet Rinkeby d’Ethereum.</p>
</div>
</div>
<div class="sect2">
<h3 id="decentralized_orackes_sec">Oracles décentralisés</h3>
<div class="paragraph">
<p>Alors que les données centralisées ou les oracles de calcul suffisent pour de nombreuses applications, ils représentent des points de défaillance uniques dans le réseau Ethereum. Un certain nombre de schémas ont été proposés autour de l’idée d’oracles décentralisés comme moyen d’assurer la disponibilité des données et la création d’un réseau de fournisseurs de données individuels avec un système d’agrégation de données en chaîne.</p>
</div>
<div class="paragraph">
<p><a href="https://www.smartcontract.com/link">ChainLink</a> a proposé un réseau oracle décentralisé composé de trois contrats intelligents clés : un contrat de réputation, un contrat de correspondance des commandes et un contrat d’agrégation — et un registre hors chaîne des fournisseurs de données. Le contrat de réputation est utilisé pour suivre les performances des fournisseurs de données. Les scores du contrat de réputation sont utilisés pour remplir le registre hors chaîne. Le contrat d’appariement des commandes sélectionne les offres des oracles à l’aide du contrat de réputation. Il finalise ensuite un accord de niveau de service, qui inclut les paramètres de requête et le nombre d’oracles requis. Cela signifie que l’acheteur n’a pas besoin de traiter directement avec les oracles individuels. Le contrat d’agrégation collecte les réponses (soumises à l’aide d’un schéma de validation-révélation) de plusieurs oracles, calcule le résultat collectif final de la requête et réinjecte finalement les résultats dans le contrat de réputation.</p>
</div>
<div class="paragraph">
<p>L’un des principaux défis d’une telle approche décentralisée est la formulation de la fonction d’agrégation. ChainLink propose de calculer une réponse pondérée, permettant de rapporter un score de validité pour chaque réponse oracle. La détection d’un score «invalide» ici n’est pas triviale, car elle repose sur la prémisse que les points de données aberrants, mesurés par les écarts par rapport aux réponses fournies par les pairs, sont incorrects. Le calcul d’un score de validité basé sur l’emplacement d’une réponse oracle parmi une distribution de réponses risque de pénaliser les réponses correctes par rapport aux réponses moyennes. Par conséquent, ChainLink propose un ensemble standard de contrats d’agrégation, mais permet également de spécifier des contrats d’agrégation personnalisés.</p>
</div>
<div class="paragraph">
<p>Une idée connexe est le protocole SchellingCoin. Ici, plusieurs participants rapportent des valeurs et la médiane est considérée comme la « bonne » réponse. Les déclarants sont tenus de fournir un acompte qui est redistribué en faveur de valeurs plus proches de la médiane, incitant ainsi à déclarer des valeurs similaires aux autres. Une valeur commune, également connue sous le nom de point de Schelling, que les répondants pourraient considérer comme la cible naturelle et évidente autour de laquelle se coordonner devrait être proche de la valeur réelle.</p>
</div>
<div class="paragraph">
<p>Jason Teutsch de TrueBit a récemment proposé une nouvelle conception pour un oracle décentralisé de disponibilité des données hors chaîne. Cette conception s’appuie sur une chaîne de blocs de preuve de travail dédiée qui est capable de signaler correctement si les données enregistrées sont disponibles ou non à une époque donnée. Les mineurs tentent de télécharger, stocker et propager toutes les données actuellement enregistrées, garantissant ainsi que les données sont disponibles localement. Bien qu’un tel système soit coûteux dans le sens où chaque nœud de minage stocke et propage toutes les données enregistrées, le système permet de réutiliser le stockage en libérant les données après la fin de la période d’enregistrement.</p>
</div>
</div>
<div class="sect2">
<h3 id="oracle_client_interfaces_in_solidity_sec">Interfaces clients Oracle en Solidity</h3>
<div class="paragraph">
<p><a href="#using_oraclize_to_update_the_eth_usd">Utilisation d’Oraclize pour mettre à jour le taux de change ETH/USD à partir d’une source externe</a> est un exemple Solidity démontrant comment Oraclize peut être utilisé pour interroger en continu le prix ETH/USD à partir d’une API et stocker le résultat de manière utilisable.</p>
</div>
<div id="using_oraclize_to_update_the_eth_usd" class="exampleblock">
<div class="title">Example 1. Utilisation d’Oraclize pour mettre à jour le taux de change ETH/USD à partir d’une source externe</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-solidity" data-lang="solidity">/*
Défileur de prix ETH/USD tirant parti de l'API CryptoCompare
Ce contrat garde en mémoire un prix ETH/USD mis à jour,
qui est mis à jour toutes les 10 minutes.
*/
pragma solidity ^0.4.1;
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
/*
"oraclize_" prepended methods indicate inheritance from "usingOraclize"
*/
contract EthUsdPriceTicker is usingOraclize {
uint public ethUsd;
event newOraclizeQuery(string description);
event newCallbackResult(string result);
function EthUsdPriceTicker() payable {
// signale la génération et le stockage de la preuve TLSN sur IPFS
oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
// demande de requête
queryTicker();
}
function __callback(bytes32 _queryId, string _result, bytes _proof) public {
if (msg.sender != oraclize_cbAddress()) throw;
newCallbackResult(_result);
/*
* Analyse la chaîne de résultat en un entier non signé pour une utilisation en chaîne.
* Utilise l'assistant "parseInt" hérité de "usingOraclize", permettant
* un résultat de chaîne tel que "123.45" à convertir en uint 12345.
*/
ethUsd = parseInt(_result, 2);
// appelé depuis le rappel puisque nous interrogeons le prix
queryTicker();
}
function queryTicker() external payable {
if (oraclize_getPrice("URL") > this.balance) {
newOraclizeQuery("Oraclize query was NOT sent, please add some ETH
to cover for the query fee");
} else {
newOraclizeQuery("Oraclize query was sent, standing by for the
answer...");
// les paramètres de la requête sont (délai en secondes, type de source de données,
// argument de source de données)
// spécifie JSONPath, pour récupérer une partie spécifique du résultat de l'API JSON
oraclize_query(60 * 10, "URL",
"json(https://min-api.cryptocompare.com/data/price?\
fsym=ETH&tsyms=USD,EUR,GBP).USD");
}
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Pour s’intégrer à Oraclize, le contrat EthUsdPriceTicker doit être un enfant de <span class="keep-together"><code>usingOraclize</code></span> ; le contrat usingOraclize est défini dans le fichier <em>oraclizeAPI</em>. La demande de données est effectuée à l’aide de la fonction <code>oraclize_query</code>, qui est héritée du contrat <code>usingOraclize</code>. Il s’agit d’une fonction surchargée qui attend au moins deux arguments :</p>
</div>
<div class="ulist">
<ul>
<li>
<p>La source de données prise en charge à utiliser, telle que URL, WolframAlpha, IPFS ou calculation</p>
</li>
<li>
<p>L’argument de la source de données donnée, qui peut inclure l’utilisation d’assistants d’analyse JSON ou XML</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>La requête de prix est effectuée dans la fonction <code>queryTicker</code>. Afin d’effectuer la requête, Oraclize exige le paiement d’une somme modique en ether, couvrant le coût du gaz pour traiter le résultat et le transmettre à la fonction __callback et un supplément d’accompagnement pour le service. Ce montant dépend de la source de données et, le cas échéant, du type de preuve d’authenticité requis. Une fois les données récupérées, la fonction __callback est appelée par un compte contrôlé par Oraclize autorisé à effectuer le rappel ; il transmet la valeur de réponse et un argument queryId unique, qui, par exemple, peut être utilisé pour gérer et suivre plusieurs rappels en attente d’Oraclize.</p>
</div>
<div class="paragraph">
<p>Le fournisseur de données financières Thomson Reuters fournit également un service oracle pour Ethereum, appelé BlockOne IQ, permettant de demander des données de marché et de référence par des contrats intelligents exécutés sur des réseaux privés ou autorisés. <a href="#contract_calling_the_blockone_iq_service_for_market_data">Contrat faisant appel au service BlockOne IQ pour les données de marché</a> montre l’interface pour l’oracle, et un contrat client qui fera la demande.</p>
</div>
<div id="contract_calling_the_blockone_iq_service_for_market_data" class="exampleblock">
<div class="title">Example 2. Contrat faisant appel au service BlockOne IQ pour les données de marché</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-solidity" data-lang="solidity">pragma solidity ^0.4.11;
contract Oracle {
uint256 public divisor;
function initRequest(
uint256 queryType, function(uint256) external onSuccess,
function(uint256
) external onFailure) public returns (uint256 id);
function addArgumentToRequestUint(uint256 id, bytes32 name, uint256 arg) public;
function addArgumentToRequestString(uint256 id, bytes32 name, bytes32 arg)
public;
function executeRequest(uint256 id) public;
function getResponseUint(uint256 id, bytes32 name) public constant
returns(uint256);
function getResponseString(uint256 id, bytes32 name) public constant
returns(bytes32);
function getResponseError(uint256 id) public constant returns(bytes32);
function deleteResponse(uint256 id) public constant;
}
contract OracleB1IQClient {
Oracle private oracle;
event LogError(bytes32 description);
function OracleB1IQClient(address addr) external payable {
oracle = Oracle(addr);
getIntraday("IBM", now);
}
function getIntraday(bytes32 ric, uint256 timestamp) public {
uint256 id = oracle.initRequest(0, this.handleSuccess, this.handleFailure);
oracle.addArgumentToRequestString(id, "symbol", ric);
oracle.addArgumentToRequestUint(id, "timestamp", timestamp);
oracle.executeRequest(id);
}
function handleSuccess(uint256 id) public {
assert(msg.sender == address(oracle));
bytes32 ric = oracle.getResponseString(id, "symbol");
uint256 open = oracle.getResponseUint(id, "open");
uint256 high = oracle.getResponseUint(id, "high");
uint256 low = oracle.getResponseUint(id, "low");
uint256 close = oracle.getResponseUint(id, "close");
uint256 bid = oracle.getResponseUint(id, "bid");
uint256 ask = oracle.getResponseUint(id, "ask");
uint256 timestamp = oracle.getResponseUint(id, "timestamp");
oracle.deleteResponse(id);
// Faire quelque chose avec les données de prix
}
function handleFailure(uint256 id) public {
assert(msg.sender == address(oracle));
bytes32 error = oracle.getResponseError(id);
oracle.deleteResponse(id);
emit LogError(error);
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>La demande de données est initiée à l’aide de la fonction <code>initRequest</code>, qui permet de spécifier le type de requête (dans cet exemple, une demande de prix infrajournalier), en plus de deux fonctions de rappel.
Cela renvoie un identifiant uint256 qui peut ensuite être utilisé pour fournir des arguments supplémentaires. La fonction addArgumentToRequestString permet de spécifier le Reuters Instrument Code (RIC), ici pour le stock IBM, et <span class="keep-together"><code>addArgumentToRequestUint</code></span> permet de spécifier l’horodatage. Maintenant, passer un alias pour block.timestamp récupérera le prix actuel pour IBM. La requête est alors exécutée par la fonction <code>executeRequest</code>. Une fois la requête traitée, le contrat oracle appellera la fonction callback onSuccess avec l’identifiant de la requête, permettant de récupérer les données résultantes ; en cas d’échec de la récupération, le rappel <span class="keep-together"><code>onFailure</code></span> renverra un code d’erreur à la place. Les champs disponibles qui peuvent être récupérés en cas de succès incluent les prix <code>open</code>, high, <code>low</code>, close (OHLC) et bid/ask.</p>
</div>
</div>
<div class="sect2">
<h3 id="_conclusion">Conclusion</h3>
<div class="paragraph">
<p>Comme vous pouvez le constater, les oracles fournissent un service crucial aux contrats intelligents : ils apportent des faits externes à l’exécution du contrat. Avec cela, bien sûr, les oracles présentent également un risque important - s’ils sont des sources fiables et peuvent être compromis, ils peuvent entraîner une exécution compromise des contrats intelligents qu’ils alimentent.</p>
</div>
<div class="paragraph">
<p>Généralement, lorsque vous envisagez l’utilisation d’un oracle, faites très attention au <em>modèle de confiance</em>. Si vous supposez que l’oracle est digne de confiance, vous risquez de compromettre la sécurité de votre contrat intelligent en l’exposant à des entrées potentiellement fausses. Cela dit, les oracles peuvent être très utiles si les hypothèses de sécurité sont soigneusement prises en compte.</p>
</div>
<div class="paragraph">
<p>Les oracles décentralisés peuvent résoudre certains de ces problèmes et proposer des contrats intelligents Ethereum sans confiance en données externes. Choisissez avec soin et vous pourrez commencer à explorer le pont entre Ethereum et le "monde réel" qu’offrent les oracles.</p>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2022-05-15 08:26:48 -0400
</div>
</div>
</body>
</html>