forked from ethereum/wiki
/
Russian White Paper
1190 lines (617 loc) · 124 KB
/
Russian White Paper
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
[Russian] White Paper - Манифест проекта Эфириум. [Ссылка на англоязычный оригинал.](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-White-Paper)
# Обозначения и ответы на вопрос "куда я попал"
Биткойн - (здесь с битновостей ).
BTC - стандартное обозначение для валюты биткойн.
Слова "узел", "нод" и "нода" (от англ. *"node"* - узел) в этом тексте обозначают абсолютно одно и то же.
# Платформа следующего поколения для смарт-контрактов и децентрализованных приложений
КОгда Сатоши Накамото впервые запустил блокчейн Биткойна в январе 2009-го, на самом деле он одновременно запустил также две радикальные и совершенно не тестировавшиеся
до того момента концепции. Первая - это "биткойн", децентрализованная peer-to-peer криптовалюта that maintains a value without any backing, внутренней стоимости или
центрального эмитента. Вплоть до текущего момента "биткойн" в качестве единицы валюты получил некоторое внимание публики - как в политическом аспекте как валюта без
центрального банка, так и как валюта с большой волатильностью. Однако также есть другая, не менее важная, часть эксперимента Сатоши: концепция блокчейна, основанного
на Proof-of-Work, который используется как инструмент публичной договорённости о порядке транзакций. Bitcoin as an application can be described as a first-to-file
system: Если один пользователь имеет 50 BTC, и одновременно пересылает 50 BTC пользователям A и B, то только транзакция, подтверждённая первой, пройдёт. Нет никакого
способа узнать, какая из двух транзакций была произведена раньше, и именно это десятилетиями ставило в тупик развитие децентрализованных цифровых валют. Блокчейн
Сатоши был первым заслуживающим доверия децентрализованным решением. Сейчас внимание сообщества переключается на эту другую часть биткойн-технологии - на то, каким
образом идея блокчейна может быть использована для чего-то, помимо денег.
Commonly cited applications include using on-blockchain digital assets to represent custom currencies and financial instruments ("colored coins"), the ownership of an
underlying physical device ("smart property"), не заменяемые активы, такие, как доменные имена ("Неймкойн"), а также более продвинутые приложения, такие как
децентрализованные биржи, финансовые деривативы, peer-to-peer азартные игры и интегрированные в блокчейн системы индентификации и репутации. Другая важная область,
лежащая в интересах - "смарт-контракты" - системы, которые автоматически переводят денежные активы заказчику в соответствии с произвольными заранее оговоренными
правилами. К примеру, контракт может иметь форму "A может забрать вплоть до X единиц валюты в день, B - до Y единиц валюты в день, A и B по договорённости могут
забрать всё, и A может отключить возможность B забирать валюту". Логичным расширением этой идеи являются <hyperref>децентрализованные автономные организации<hyperref>
(ДАО) - смарт-контракты на большой срок, которые определяют правила работы такой организации. Идея Эфириума - предоставить блокчейн со встроенным полностью
самостоятельным Тьюринг-полным языком программирования, который может быть использован для создания "контрактов" that can be used to encode arbitrary state transition
functions, позволяя пользователям создавать любую из описанных выше систем,- равно как и такие, которые человечество ещё не смогло вообразить - просто записывая логику
работы такой системы в несколько строчек кода.
# Оглавление
# Введение в биткойн и существующие концепции
## История
Концепция децентрализованной цифровой валюты, а также альтернативных приложений, таких как реестры собственности, витала в воздухе десятилетиями. Анонимные протоколы
"электронного кэша" 80-х и 90-х, по большей части опиравшиеся на cryptographic primitive known as Chaumian blinding, предлагали валюту высокой степени приватности, но
не получили никакого распространения, поскольку принципиально зависели от централизованного посредника. Представленная в 1998 Вей Даем концепция [b-money]
(http://www.weidai.com/bmoney.txt) стала первым предложением как ввести идею создания денег посредством решения вычислительных задач, так и децентрализованного
консенсуса между участниками. Однако его предложение было скудным на детали того, как конкретно можно было бы реализовать децентрализованный консенсус. В 2005 Хал
Финни предложил концепцию "reusable proofs of work", которая использует идеи b-money и вычислительно сложных Hashcash загадок Адама Бэка для концепции криптовалюты - к
сожалению, его идея также включала в себя посредника, которому пользователи должны были доверять.
Because currency is a first-to-file application, где порядок следования транзакций часто критически важен, в децентрализованной валюте должно быть реализовано
децентрализованное соглашение между участниками. Главный дорожный камень, на который натыкались все протоколы валют до Биткойна is the fact that, while there had been
plenty of research on creating secure Byzantine-fault-tolerant multiparty consensus systems for many years, all of the protocols described were solving only half of
the problem. The protocols assumed that all participants in the system were known, and produced security margins of the form "if N parties participate, then the system
can tolerate up to N/4 malicious actors". The problem is, however, that in an anonymous setting such security margins are vulnerable to sybil attacks, where a single
attacker creates thousands of simulated nodes on a server or botnet and uses these nodes to unilaterally secure a majority share.
Инновация, внедрённая Сатоши - комбинирование простого протокола децентрализованного соглашения, основанного на узлах, соединяющих транзакции в "блоки" каждые 10
минут, и концепции proof-of-work, с помощью которой узлы и имеют право объединять транзакции в блоки. Так как влияние каждого узла пропорционально его вычислительной
мощности, организовать вычислительную мощность больше, чем мощность всей сети, сложнее, чем просто симулировать миллион узлов. Несмотря на грубую простоту блокчейна
Биткойн, он доказал свою работоспособность, и стал колыбелью более чем 200 криптовалют, выпущенных на основе его кода за 5 лет работы системы.
## Биткойн как система изменения состояний
С технической точки зрения, бухгалтерская книга Биткойна - система изменения состояний. "Состояние" здесь - это владение некоторым числом Биткойнов, а "функция
изменения состояния" - функция, по состоянию и транзакции возвращающая новое состояние. В стандартной банковской системе, для примера, состояние - это выписка о
балансе, транзакция - это запрос о переводе $X от A к B, и функция изменения состояния уменьшает значение на счёте A на $X и увеличивает значение на счёте B на $X.
Если на счёте A меньшая сумма, чем $X, функция изменения состояния возвращает ошибку. Следовательно, можно формально описать
```
APPLY(S,TX) -> S' or ERROR
```
В банковской системе, описанной выше
```
APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 }
```
Но:
```
APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR
```
"Состояние" какого-то адреса в системе Биткойн - это количество BTC на нём (технически, "непотраченные результаты входящих транзакций", НРВТ), при этом каждому НРВТ
соответствует количество пересланных денег и владелец (адресат). Владелец - это просто номер кошелька, 20-байтовый адрес, называемый *публичным ключом* (я насчитал 34
байта, WTF?). У каждой транзакции есть один или больше входов - при этом каждый вход содержит отсылку к соответствующим ему НРВТ и криптографическую подпись, сделанную
приватным ключом владельца; выходов тоже может быть один или несколько, и каждый выход содержит новую НРВТ.
Принцип работы функции изменения состояния `APPLY(S,TX) -> S'` может быть таким:
1. Для каждого входа в `TX`:
* Если ему соответствует НРВТ, находящееся не в `S`, вернуть ошибку.
* Если предоставленная криптографическая подпись не совпадает с подписью владельца НРВТ, вернуть ошибку.
2. Если сумма всех денег на входе меньше, чем сумма всех денег на выходе, вернуть ошибку.
3. Вернуть `S`, у которого "ушедшие в транзакцию" НРВТ (НРВТ, отправленные "на вход транзакции"), удалены, и к которому добавлены все НРВТ, полученные "на выходе из
транзакции".
Первая часть первого пункта не позволяет отправителям тратить монеты, которыми они не обладают; вторая часть не позволяет тратить монеты других людей. Второй шаг нужен
понятно зачем (в ядерной физике, кстати, тоже реакция не происходит, если в системе отсчёта, связанной с центром масс, сумма масс покоя частиц на входе меньше суммы
масс покоя частиц на выходе). Напоследок разберём простенький пример. Пусть Алиса хочет переслать 11.7 BTC Бобу. Для этого сначала Алиса должна найти набор НРВТ,
обладание которыми она может подтвердить и сумма средств которых равна как минимум 11.7 BTC. В большинстве ситуаций Алисе не удастся найти у себя несколько НРВТ, сумма
средств на которых в точности бы равнялась 11.7 BTC; вместо этого ей, например, пересылали 6, 4 и 2 BTC, и наименьшее число, которое она может собрать из имеющихся у
неё НРВТ равно 6+4+2=12. Затем она создаёт транзакцию с тремя входами и двумя выходами. Первым выходом будет адрес Боба, куда отправится 11.7 BTC, вторым - один из
кошельков Алисы, куда отправится 0.3 BTC "сдачи".
## Майнинг
<картинка>
Если бы речь шла о работе (??) посредством доверительного централизованного сервиса, эту систему было бы легко внедрить. Однако, поскольку мы разрабатываем
децентрализованную валюту, необходимо скомбинировать систему транзакций с системой децентрализованного соглашения, при котором соглашение о порядке транзакций у
каждого пользователя сети одно и то же. В системе Биткойн это достигается путём объединения транзакций в "блоки". Протокол Биткойн-сети устроен так, что производит
примерно один блок в десять минут, и каждый блок содержит точное время нахождения, nonce, хэш предыдущего блока (чтобы была связь с ним) и список всех транзакций,
который произошли с момента генерации предыдущего блока. Так и возникает блокчейн (букв. перев. "цепочка блоков") . Блокчейн неизменен и лишь постоянно растёт;
блокчейн хранит в себе историю всех транзакций и совершенно децнетрализован.
Алгоритм проверки валидности блока в этой системе таков:
1. Проверить, существует ли и валиден ли предыдущий блок.
2. Проверить, что таймштамп рассматриваемого блока больше, чем таймштамп предыдущего (принцип причинности), но не более, чем на 2 часа.
3. Проверить proof-of-work рассматриваемого блока.
4. Пусть `S[0]` - состояние в конце предыдущего блока.
5. Пусть `TX` - список транзакций блока, а всего этих транзакций `n`. Для всех `i` из набора `0..n-1`, зададим `S[i+1] = APPLY(S[i],TX[i])`. Если любая такая apply-
процедура выдаёт ошибку, выйти из цикла и выдать ошибку.
6. Код выполнен успешно, и `S[n]` - состояние после обсчёта транзакций этого блока.
Заметим, что состояние (счёта) не включено в блок ни в коей мере; узлы, занимающиеся валидацией, должны для этого знать состояние счёта каждого из входов транзакций в
блоке, и единственный способ сделать это - пройти весь путь по блокчейну с самого начала. Порядок, в котором майнер включает транзакции в блок, имеет значение: если в
данном блоке есть две транзакции A и B, такие, что B тратит средства (НРВТ), предоставленные A, то угадайте, дети, в каком порядке эти транзакции должны идти, чтобы
всё получилось?..
Нетривиальная часть валидации блока --- так называемая концепция "proof of work": условие того, что SHA256-хэш каждого блока как 256-битное число должно быть меньше
динамической величины, связанной с так называемой "сложностью", и равной на момент написать этих строк примерно 2^192. Сделано это для того, чтобы сделать нахождение
блоков вычислительно сложным, thereby preventing sybil attackers from remaking the entire blockchain in their favor. Поскольку SHA256 - это алгоритм шифрования
совершенно непредсказуемой псевдослучайной функцией, единственный способ найти блок - простой перебор значений nonce, т.е. простой перебор вычисляющихся по ним (а
также по ) хэшей. При текущем длине этого числа в 2^192 это, в среднем, 2^64 попытки; сложность перенастраивается каждые 2016 блоков так, чтобы в среднем каждый новый
блок обнаруживался примерно раз в 10 минут. Нашедшему блоку майнеру выплачивается вознаграждение, в данный момент равное 25 BTC. Дополнительно, если сумма на входе
больше, чем сумма на выходе ("комиссия"), майнер, нашедший блок, соответствующий этой транзакции, забирает её себе.
Для лучшего понимания майнинга проверим устойчивости блокчейн-системы при атаке. Поскольку криптография, лежащая в основе Биткойн (SHA-256 алгоритм) на данный момент
является защищённой (в частности, активно используется банками), целью злоумышленника будет часть системы, напрямую не связанная с шифрованием - порядок транзакций.
Стратегия предполагаемого злоумышленника могла бы быть такой:
1. Переслать продавцу 100 BTC за некоторый продукт (лучше всего, цифровой продукт быстрого получения)
2. Дождаться получения продукта
3. Произвести другую транзакцию, переслав 100 BTC на другой свой адрес
4. Попытаться убедить систему, что транзакция самому себе была произведена первой
Как только произошёл шаг (1), спустя несколько минут некоторый майнер включит эту транзакцию в блок - например, блок 270000. После того, как пройдёт примерно час, ещё
примерно пять блоков будут добавлены к сети, и каждый из этих блоков своей отсылкой к предыдущему будет также отсылать к транзакции (1), таким образом подтверждая её.
В этот момент продавец решит, что оплата завершена, и перешлёт продукт; поскольку мы рассматриваем случай цифрового продукта, доставка моментальна. Далее злоумышленник
создаёт другую транзакцию, пересылая 100 BTC себе. Если злоумышленник произведёт её как обычно, транзакция не произойдёт; майнеры заметят, что miners will attempt to
run APPLY(S,TX) and notice that TX consumes a UTXO which is no longer in the state. Вместо этого злоумышленник мог бы создать форк блокчейна, начиная майнить другую
версию блока 270000, отмечающую как предыдущий блок 269999, но с новой транзакцией вместо предыдущей. Поскольку информация в этом блоке другая, это предполагает
переделывание proof-of-work. Новая версия блока 270000 имеет другой хэш, и блоки 270001-270005 отсылают не к ней. Правило, имплементированное в биткойн-протокол,
таково: форк с самым длинным блокчейном считается истинным, и "честные" майнеры будут работать с блокчейном длиной 270005, а злоумышленник будет в одиночку работать
над своим. Злоумышленник имеет шанс сделать свой блокчейн самым длинным, только если его вычислительные мощности больше суммарной вычислительной мощности всей
остальной сети (так называемая "атака 51%").
## Деревья Мёркла
*Слева: лишь малое число нодов в дереве Меркль необходимо для доказательства валидности ветви*
*Справа: любая попытка изменить любую часть дерева Мёркла приведёт к несогласованности в цепочке.*
Важным масштабируемым свойством Биткойна является то, что блок размещается в многоуровневой структуре информации. Хэш блока - это на самом деле хэш заголовка, ~200
байтовый кусок информации, включающий в себя timestamp, nonce, хэш предыдущего блока и хэш структуры под названием дерево Мёркла, которое и хранит всю информацию о
транзакциях в этом блоке. Дерево Мёркла - бинарное дерево, составленное 1) из узлов с большим количеством листьев внизу, которые и содержат всю информацию 2) из узлов
"в середине", каждый из которых является хэшем двух своих детей 3) "верхушка дерева", также являющаяся хэшем своих двух своих детей. Смысл дерева Мёркла - сделать так,
чтобы информация в блоке была представлена по частям: нод может загрузить только заголовок блока из некоторого источника, а также малую часть дерева из другого
источника, и быть уверенным, что вся информация корректна. Причина, почему это работает, в том, что хэши вычисляются вверх: если злоумышленник попытается "подсунуть"
фейковую транзакцию вниз дерева Мёркла, все узлы "ближе к верхушке", с которыми он связан, также изменят свои хэши, и хэш заголовка блока тоже изменится, что приведёт
к тому, что протокол зарегистрирует его как совершенно другой блок (с практически наверняка невалидным proof-of-work).
Дерево Мёркла, как сейчас кажется, действительно необходимо для жизнеспособности системы. На апрель 2014 года полный нод Биткойн-сети (полным нодом называется нод,
который хранит всю копию блокчейна у себя на диске), занимает 15 Гб дискового пространства и растёт примерно на 1 Гб в месяц. На данный момент хранить полную копию
блокчейна могут позволить себе владельцы ПК (но не владельцы смартфонов), и в будущем, по-видимому, только бизнесы и отдельно взятые фанаты будут хранить полные ноды.
Протокол "упрощённой верификации платежей" (УВП) разрешает существование также "лёгких нод", которые загружают лишь заголовок блока, проверяют proof-of-work заголовков
блока, и затем загружают ветки лишь с необходимыми держателю такой ноды транзакциями. Это позволяет держателям "лёгких нод" безопасно определить статус любой Биткойн-
транзакции, а также собственный текущий баланс, скачав крайне малую часть всего блокчейна.
## Альтернативные приложения блокчейна
Идея применения блокчейн-технологии к остальным концепциям также имеет долгую историю. В 2005 году Ник Сзабо изложил концепцию ["secure property titles with owner
authority"](http://szabo.best.vwh.net/securetitle.html), a document describing how "new advances in replicated database technology" will allow for a blockchain-based
system for storing a registry of who owns what land, creating an elaborate framework including concepts such as homesteading, adverse possession and Georgian land tax.
Однако, к сожалению, никакой эффективной replicated database system на тот момент не было, и протокол не имел практического применения. С 2009, однако, с развитием
системы децентрализованного соглашения Биткойн число альтернатив ему стало быстро увеличиваться (благо исходный код Биткойн-протокола открыт).
* Неймкойн ([Namecoin](http://namecoin.info/)) - созданная в 2010 децентрализованная система регистрации DNS-серверов. В децентрализованных протоколах Tor, Bitcoin и
BitMessage единственный вид идентификации пользователей - присваивание идентификатора в виде псевдослучайного хеша вида `1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy`. Было бы
здорово иметь аккаунт с именем (идентификатором) наподобие "george". Проблема здесь, очевидно, в том, что если какой-то пользователь может создать аккаунт "george", то
кто-то другой также сможет зарегистрировать аккаунт с тем же именем. Единственное решение здесь - "first-to-file paradigm", где тот, кто раньше зарегистрировал
пользователя "george", того и тапки - ровно такое решение используется в биткойн-протоколе. Неймкойн - первый и самый успешный пример системы регистрации доменных имён
с такой идеей.
* [Цветные монеты](https://docs.google.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) - протокол, позволяющий людям создавать свои собственные
криптовалюты - or, in the important trivial case of a currency with one unit, digital tokens, on the Bitcoin blockchain. В протоколе цветных монет выпуск новой валюты
происходит
* Метакойны - их идея в том, чтобы иметь протокол, действующий поверх биткойн-сети, использующий биткойн-транзакции для хранения метакойн-транзакций, но имеющий другую
функцию изменения состояния, <code>APPLY'</code>. Поскольку метакойн-протокол не может защитить невалидные метакойн-транзакции от появления в биткойн-блокчейне,
добавляется такое правило: если <code>APPLY' (S, TX)</code> возвращает ошибку, <code>APPLY' (S, TX) = S</code>. Это даёт лёгкий механизм создания произвольного
криптовалютного протокола "малой кровью", т.к. сложности майнинга и создания децентрализованной сети "уводятся" в биткойн-часть протокола.
Таким образом, есть два способа достижения децентрализованного соглашения: построить независимую сеть, или же построить протокол поверх сети Биткойн. Первый подход,
при всей его успешности в приложениях вроде Namecoin, трудно внедрить; each individual implementation needs to bootstrap an independent blockchain, а также создать и
протестировать весь необходимый код. Additionally, we predict that the set of applications for decentralized consensus technology will follow a power law distribution
where the vast majority of applications would be too small to warrant their own blockchain, and we note that there exist large classes of decentralized applications,
particularly decentralized autonomous organizations, that need to interact with each other.
Основанный на Биткойне подход, с другой стороны, имеет такой недостаток: он не наследует упрощённую систему верификации платежей (СВП) в биткойн. СВП работает,
поскольку глубина биткойн-блокчейна - способ подтверждения валидности. Основанные на биткойне мета-протоколы, с другой стороны, cannot force the blockchain not to
include transactions that are not valid within the context of their own protocols. Следовательно, внедрение полностью защищённого СПВ мета-протокола потребовало бы
пробегать биткойн-блокчейн вплоть до начала для определения валидности транзакций. На данный момент все "лёгкие" имплементации основанного на Биткойне мета-протокола
полагаются на "сервер, которому участники сети доверяют", при том что одна из главных причин возникновения криптовалют - избавиться от необходимости кому-либо
доверять.
## Написание сценариев (скриптов)
Даже в отсутствие каких-либо расширений протокол Биткойна поддерживает примитивную версию "смарт-контрактов". Владение НРВТ в Биткойн можно подтверждать не только
публичным ключом, но и скриптом, написанным на простом основанном на стеке языке программирования. В последнем случае транзакция, тратящая НРВТ, должна предоставить
данные, которые удовлетворят такой скрипт. Действительно, даже стандартный способ с публичным ключом - по сути, тот же скрипт: "на входе" этот скрипт берёт цифровую
подпись эллиптической кривой в качестве параметра, сверяет её с транзакцией и адресом, владеющим НРВТ, и возвращает 1 в случае успеха и 0 в случае неуспеха. Возможны
более замысловатые скрипты. К примеру, возможен скрипт, согласно которому для валидации необходимо 2 из 3 приватных ключей (так называемая мультиподпись). (Это может
быть полезно для корпоративных аккаунтов, аккаунтов безопасного хранения и некоторых ситуаций с участием эскроу). Скрипты также могут быть использованы для
автоматических выплат за решения вычислительных проблем; можно даже создать скрипт, говорящий что-то вроде "эта биткойн-НРВТ Ваша, если Вы можете предоставить
доказательство того, что переслали столько-то Догекойнов мне" - и это уже почти децентрализованная биржа криптовалют, не правда ли?
Однако встроенный в Биткойн язык сценариев имеет ряд серьёзных ограничений:
* Отсутствие Тьюринг-полноты - этот язык позволяет реализовать далеко не все виды вычислений. В частности, запрещены все петли (циклы). Это сделано для того, чтобы
избежать бесконечных циклов во время верификации транзакций; теоретически это преодолимое препятствие для авторов скриптов, поскольку любой цикл может быть симулирован
достаточно большим количеством `if`'ов - но это, конечно, приводит к "раздутию" такого скрипта. К примеру, для того, чтобы прописать альтернативу алгоритму цифровой
подписи эллиптической кривой, по-видимому, придётся вручную прописать 256 повторяющихся операций умножения.
* Отсутствие возможности задавать сумму транзакции - не существует способа проводить прозрачные операции с финансами с помощью НРВТ-скрипта. Для примера рассмотрим
хеджирующий контракт, в который A и B закладывают эквивалент $1000 в биткойнах, и спустя 30 дней скрипт пересылает стороне A эквивалент $1000 в биткойнах, а остальное
пересылает стороне B.
* Отсутствие промежуточных состояний - возможны только НРВТ. Нет никакой возможности написать контракт из нескольких стадий, который мог бы содержать в себе переход к
некоторому промежуточному состоянию. Биткойн-сценарии не приспособлены для контрактов с опциями, децентрализованных обменников и двустадийных криптопротоколов
(необходимых для безопасности вычислительных премий). Сказанное означает, что НРВТ могут быть использованы только для простых моментально исполняющихся контрактов, но
никак не для более замысловатых контрактов с опциями и промежуточными стадиями и состояниями. По этой же причине трудно внедрить мета-протоколы. Этот пункт в сочетании
с предыдущих приводит также к тому, что на языке сценариев Биткойн задать предел суммы, которую можно забрать с обменника, не получится.
* Блокчейн-слепота - НРВТ не видит информацию из блокчейна (такую, как nonce и предыдущий хэш). Это сильно ограничивает возможные приложения в азартных играх и
некоторых других категориях, лишая язык сценариев естественного источника случайных чисел.
Можно выделить три подхода к разработке современных приложений поверх криптовалюты: создать новый блокчейн, использовать язык сценариев поверх Биткойн, и создать
мета-протокол поверх Биткойн. Создание нового блокчейна приводит к неограниченной свободе творчества, но за это придётся заплатить but at the cost of development time
and bootstrapping effort. Язык сценариев Биткойн прост в использовании и стандартизации, но крайне ограничен в возможностях. Мета-протоколы также просты, но страдают
от ошибок в масштабируемости. Разрабатывая Эфириум, мы надеемся создать наиболее общий фреймворк, включающий в себя плюсы всех трёх парадигм.
# Эфириум
Цель Эфириума - соединить и улучшить концепции скриптинга, альткойнов и мета-протоколов, и позволить всем желающим создавать произвольные децентрализованные
приложения, обладающие одновременно свойствами масштабируемости, стандартизации, полноты, лёгкости разработки и совместимости. Эфириум добивается этого построением
платформы: блокчейна со встроенным Тьюринг-полным языком программирования, позволяющим любому желающему писать смарт-контракты и децентрализованные приложения, где
каждый сможет создавать собственные произвольные правила владения, транзакций и функций изменения состояния. Реализация идеи известной криптовалюты Неймкойн (Namecoin)
на этом языке занимает две строки кода, а такие протоколы, как валюты и системы репутации можно реализовать менее чем в двадцать строк. Смарт-контракты,
криптографические "коробки", содержащие значение и открывающиеся только при определённых условиях, также могут быть построены поверх платформы Эфириум, причём со
значительно большей мощностью, нежели Биткойн-скриптинг, по причине Тьюринг-полноты языка, value-awareness, blockchain-awareness and state.
## Эфириум-аккаунты
В Эфириум состояние сделано из аккаунтов; каждый аккаунт оснащён 20-байтовым адресом и функции перехода - переводы валюты или информации между аккаунтами. Эфириум-
аккаунт содержит четыре поля:
* nonce, счётчик, используемый для того, чтобы каждая транзакция произошла ровно один раз
* баланс аккаунта
* код контракта, связанного с аккаунтом (если контракт есть)
* хранилище контракта (пустое по умолчанию)
"Эфир" - главное внутреннее "крипто-топливо" Эфириума, и используется как валюта, в которой происходят транзакции. Возможны два способа ведения аккаунтов: аккаунт,
контролируемый владельцем (его приватным ключом), и аккаунт, контролируемый кодом встроенного контракта. Первый способ - это ровно то, что было в системе Биткойн:
аккаунт, единственной опцией которого является пересылка денег (создание исходящей транзакции). При втором способе каждый раз, когда аккаунт получает входящее
сообщение, активируется код контракта, allowing it to read and write to internal storage and send other messages or create contracts in turn.
## Сообщения и транзакции
Сообщения в Эфириум - это нечто, напоминающее транзакции в Биткойн, но с тремя существенными отличиями. Во-первых, сообщение в Эфириум может быть создано либо внешним
источником, либо контрактом, в то время как Биткойн-транзакция может быть вызвана лишь источником. Во-вторых, есть явный способ хранить информацию в этих сообщениях.
В-третьих, получатель эфириум-сообщения, если это контракт-аккаунт, имеет возможность "ответить" автору на него; что означает, что Эфириум-сообщения также включают в
себя концепцию функций.
Термин "транзакция" используется в Эфириуме как ссылка на подписанный пакет данных, который хранит сообщение, готовое к посылке с другого аккаунта автора. Транзакции
содержат получателя, электронную подпись автора, количество пересылаемого эфира и информации, а также два значения под названием `STARTGAS` и `GASPRICE`. Для того,
чтобы предотвратить экспоненциальное раздутие и бесконечные циклы в коде, каждой транзакции устанавливается предел количества вычислительных шагов в коде. `STARTGAS` -
это именно такой предел, а `GASPRICE` - сумма, которая платится майнеру за каждый вычислительный шаг. Если при выполнении транзакции "газ заканчивается", все изменения
состояний обращаются (кроме выплат майнерам), и если выполнение транзакции прерывается при остающемся газе, остающееся количество пересылается обратно выславшемую.
## Функция изменения состояния в Эфириум
Эфириум-функция изменения состояния `APPLY(S,TX) -> S'` может быть определена так:
1. Проверить корректность сумм транзакции, валидность подписи, а также что nonce совпадает с nonce отправителя. Вернуть ошибку, если что-то не так.
2. Вычислить комиссию по формуле `STARTGAS * GASPRICE` и определить адрес отправителя по подписи. Вычесть значение комиссии из баланса отправителя и увеличить его
nonce. Если баланс отправителя меньше значения взимаемой комиссии, вернуть ошибку.
3. Задать `GAS = STARTGAS`, и снимать определённое количество газа за каждый байт транзакции.
4. Переслать сумму транзакции с аккаунта отправителя на аккаунт получателя. Если аккаунта получателя не существует, создать его. Если аккаунт получателя - контракт,
запустить код контракта (тут, естественно, два исхода - либо контракт будет вычислен до конца, либо во время вычисления закончится газ).
5. Если по какой-то причине денежный перевод не удался (у отправителя не было суммы перевода, или при выполнении контракта закончился газ), откатить все изменения,
кроме выплаты комиссий майнеру.
6. В случае успешного выполнения контракта вернуть оставшийся газ отправителю, and send the fees paid for gas consumed to the miner.
Рассмотрим пример. Пусть код контракта таков:
```
if !contract.storage[msg.data[0]]:
contract.storage[msg.data[0]] = msg.data[1]
```
Заметим, что в реальности контракт пишется на низкоуровневом языке ("ЭВМ-код"); этот пример написан для ясности на Serpent, нашем высокоуровневом языке, и может быть
скомпилирован до "ЭВМ-кода". Предположим, что хранилище контракта пусто, и в результате транзакции пересылаются 10 единиц эфира, контракт обеспечен 2000 единицами
газа, ether gasprice = 0.001, и дополнительно пересылается информация `[2, 'CHARLIE']`. Функция изменения состояния в этом случае будет действовать так:
1. Проверить валидность транзакции и корректность её суммы.
2. Проверить, что у отправителя есть как минимум 2000*0.001 = 2 единицы эфира. После успешной проверки вычесть 2 единицы эфира из аккаунта отправителя.
3. Присвоить переменной `GAS` значение 2000; в предположении, что транзакция занимает 170 байтов и комиссия за байт равна 5, вычтем 850; таким образом, останется 1150
единиц газа.
4. Вычесть 10 единиц эфира из аккаунта отправителя и добавить их к аккаунту контракта.
5. Запустить выполнение кода. В нашем примере это совсем просто: код проверяет, есть ли в хранилище информация по адресу `2`, замечает, что её там нет и прописывает
туда значение `CHARLIE`. Предположим, это занимает 187 единиц газа, и газа остаётся 1150 - 187 = 963.
6. Вернуть 963*0.001 = 0.963 единиц эфира отправителю.
И это всё. Если аккаунт, на который производится пересылка, не содержит контракта, шаги с контрактом, очевидно, надо пропустить, и всё ещё проще: комиссия будет равна
попросту `GASPRICE`, умноженной на количество байтов в транзакции, и информация, пересланная при транзакции, не будет играть никакой роли. Дополнительно, заметим, что
инициированные контрактом сообщения могут задавать gas limit порождаемым им подвычислениям; и если при таком подвычислении газ заканчивается, откат (к предыдущему
состоянию) происходит к моменту вызова сообщения. Таким образом, подобно транзакциям, контракты могут задавать строгие лимиты на количество шагов в каждом порождаемом
собой подвычислении.
## Выполнение кода
Код контрактов Эфириум написан на низкоуровневом stack-based bytecode языке, который мы назвали "Код Эфириум-виртуальной машины" или "ЭВМ-код". :) Код состоит из
последовательности байтов, и каждый байт представляет какую-то операцию. В общем случае, выполнение кода - это бесконечный цикл, состоящий из выполнения операции в
текущей строке и последующего увеличения номера строки на 1; прерваться этот процесс может при достижении конца кода, или ошибке в коде, или выполнении инструкций
`STOP` или `RETURN` в коде. Операции могут обращаться к трём типам мест для хранения информации:
* **Стек**, last-in-first-out хранилище, куда можно записывать и откуда можно извлекать значения
* **Память**, байтовый массив произвольного размера
* Привязанное к контракту долговременное **хранилище** ключей и значений. В отличие от стека и памяти, которые очищаются после выполнения кода, хранилище используется
для долговременного хранения параметров.
Код также имеет доступ к денежной сумме, отправителю и информации входящего сообщения, а также информации в заголовке блока, и код также может вернуть набор байтов на
выходе.
Принцип выполнения нашего "ЭВМ-кода" на удивление прост. Выполнение происходит так: вся информация о состоянии вычисления содержится в наборе `(block_state,
transaction, message, code, memory, stack, pc, gas)`, где `block_state` содержит информацию обо всех аккаунтах, включая балансы и состояния хранилищ. При каждом раунде
выполнения выполняется следующая инструкция: берётся `pc`-ый байт `code`, и действие каждой инструкции на этот набор определяется по-разному. Для примера, `ADD`
достаёт два элемента из стека и возвращает туда их сумму, после чего уменьшает `gas` на 1 и увеличивает `pc` на 1; а, скажем, `SSTORE` берёт верхние два элемента стека
и вставляет второй элемент в хранилище контракта at the index specified by the first item. Хотя существует масса способов оптимизировать Эфириум посредством just-in-
time compilation, простейшая реализация Эфириума занимает всего лишь пару сотен строк кода.
## Блокчейн и майнинг
Блокчейн Эфириума во многом похож на блокчейн Биткойна, но не во всём. :) Главная разница, пожалуй - в том, что блокчейн Эфириума содержит и копию списка транзакций, и
текущее состояние каждого из пользователей. Помимо этого, номер блока и его сложность также размещаются в блоке. Валидация блоков в Эфириум происходит так:
1. Проверяется существование и валидность предыдущего блока.
2. Проверяются таймштампы: именно, что блок создан позже, чем предыдущий, но не более чем на 15 минут
3. Проверяется, что номер блока, его сложность, transaction root, uncle root and gas limit (various low-level Ethereum-specific concepts) валидны.
4. Проверяется, что proof-of-work блока валиден.
5. Пусть `S[0]` обозначает `STATE_ROOT` предыдущего блока.
6. Пусть `TX` - список транзакций в блоке, а транзакций `n`. Для всех `0... n-1` положим `S[i+1] = APPLY(S[i],TX[i])`. Если некоторые приложения возвращают ошибку, или
если количество газа, уничтоженное в блоке, превышает `GASLIMIT`, возвращается ошибка.
7. Пусть `S_FINAL` обозначает `S[n]` с добавлением выплаты за блок майнеру.
8. Проверяется, совпадает ли `S_FINAL` со `STATE_ROOT`. Если да, блок валиден; в противном случае - нет.
Этот подход может показаться неэффективным на первый взгляд, поскольку он предполагает полного состояния и всех блоков, но в реальности эффективность должна быть
сравнима с эффективностью Биткойна. И вот почему. Состояния хранятся в древовидной структуре, и после нахождения нового блока (т.е. после новых транзакций) лишь малая
часть дерева должна быть изменена. Поэтому информация can be stored once and referenced twice using pointers (ie. hashes of subtrees). Для этого используется
специальный тип дерева - "дерево Патрисия", включающий модификацию дерева Мёркль, позволяющую вставлять и удалять ноды (а не просто изменять). Дополнительно, т.к. вся
информация о состояниях содержится в последнем блоке, нет необходимости хранить всю историю блокчейна - если бы это удалось встроить в Биткойн, каждая полная нода
занимала бы в 10-20 раз меньше места на жёстком диске.
# Приложения
Обобщая, можно сказать, что возможны три типа приложений в Эфириум. Первая категория - финансовые приложения, предоставляющие пользователям более мощные способы
управления контрактами и заключения контрактов на свои активы. Такими активами могли бы быть подвалюты, финансовые деривативы, контракты хеджирования, сберегательные
кошельки, завещания, и в конечном счёте даже некоторые виды контрактов трудоустройства. Вторая категория - полуфинансовые приложения, с участием, помимо денег, также
немонетарных материальных благ; хорошим примером могли бы быть самоисполняемые награды за решения вычислительных проблем. Третья категория приложений - нефинансовые
приложения, такие как онлайн-голосование и децентрализованное управление.
## Система жетонов
Системы жетонов на блокчейне имеют самые разные приложения - от подвалют, представляющих активы (такие как доллар или золото to company stocks), токены, представляющие
samrt property, безопасных неподделываемых купонов, и даже систем жетонов без привязки к какой-либо стоимости, used as point systems for incentivization. Системы
жетонов на удивление просто встраиваются в Эфириум. Дело в том, что и валюта, и система жетонов с необходимостью являются базой данных с одной операцией - отнять X
единиц от состояния счёта A и прибавить X единиц к состоянию счёта B, со следующими пререквизитами: 1) A имеет как минимум X единиц перед началом транзакции 2)
транзакция подтверждена стороной A. Всё, что нужно для реализации системы жетонов - реализовать эту логику в контракте.
Простейший код, осуществляющий систему жетонов в Serpent, выглядит так:
```
from = msg.sender
to = msg.data[0]
value = msg.data[1]
if contract.storage[from] >= value:
contract.storage[from] = contract.storage[from] - value
contract.storage[to] = contract.storage[to] + value
```
Это буквально функция изменения состояния обычной банковской системы (уже описанная в этом документе чуть выше). Необходимо, конечно, в начало добавить ещё несколько
строк кода, описывающего шаг изначального распределения валюты и ещё несколько специальных случаев - в идеале, неплохо бы также встроить функцию, позволяющую другим
контрактам запрашивать информацию о балансе произвольного адреса. Но это, в общем-то, и всё. Теоретически, основанные на Эфириум системы жетонов, ведущие себя как
подвалюты, могут включать другую важную опцию, которой нет в метакойнах: возможность платить комиссии напрямую в такой подвалюте. Как это может быть реализовано: в
контракт включается опция "возместить заранее указанную сумму, потраченную на комиссии". Пользователи, таким образом, должны будут "активировать" свои контракты
некоторым количеством эфира, однако, как только эфир передан контракту, его можно будет использовать многократно, т.к. контракт будет возмещать его каждый раз.
## Финансовые деривативы и валюты
Финансовые деривативы - наиболее распространённое приложение смарт-контрактов, и одно из простейших с точки зрения написания кода. Главная сложность написания
финансовых контрактов - в том, что большинство из них предполагают отсылку к ценнику по отношению к ; к примеру, крайне желательным приложением был бы смарт-контракт,
хеджирующий риски волатильности эфира (или другой криптовалюты) по отношению к доллару США, но для работы такой контракт должен знать курс ETH/USD. Простейший способ
реализовать это - посредством контракта на "поток информации" от условного NASDAQ.
Теперь, когда у нас есть этот ключевой ингредиент, хеджирующий контракт мог бы выглядеть так:
1. Дождаться, пока А "вложит в контракт" 1000 эфира.
2. Дождаться, пока B "вложит в контракт" 1000 эфира.
3. Записать стоимость 1000 эфира в долларах США - пусть это $x.
4. Спустя 30 дней, разрешить A или B "реактивировать" контракт: переслать эфира текущей стоимостью $x стороне А, и остальное - стороне B.
Такой контракт может иметь значительный потенциал в криптокоммерции. Одной из главных проблем криптовалют остаётся их волатильность - вряд ли кому-то из физических лиц
и продавцов могла бы понравиться перспектива потерять 23% своих сбережений за день. К текущему моменту главным решением являются issuer-backed активы; идея тут в том,
что выпускающее лицо создаёт подвалюту,
На практике же, однако, эмитентам доверять не приходится, и в некоторых случаях банковская инфраструктура недостаточно развита (слишком враждебна) к таким сервисам.
Финансовые деривативы предоставляют альтернативу. Здесь вместо описанной в предыдущем абзаце схемы с лицом-эмитентом, децентрализованный рынок спекулянтов играет эту
роль. В отличие от эмитентов, speculators have no option to default on their side of the bargain because the hedging contract holds their funds in escrow. Заметим, что
этот подход всё же не полностью децентрализован, поскольку нуждается во внешнем источнике, поставляющем информацию о курсе ETH/USD. Но даже он гораздо лучше подхода с
эмитентов в смысле также уменьшения инфраструктуры (в отличие от эмитента денег, эмиссия информации о курсе валюты не требует лицензий и является просто формой свободы
слова) и уменьшения возможности мошенничества.
## Системы индентификации и репутации
Первая альтернативная криптовалюта, <href>Namecoin</href>, пыталась использовать биткойн-подобный блокчейн для системы регистрации имён, где пользователи могут
регистрировать свои имена в публичной базе данных среди остальной информации. Наиболее обсуждаемый пример того, зачем это могло бы быть нужно - DNS-система,
отображающая доменная имена наподобие "namecoin.info" в IP-адрес. Другие примеры - email-аутентификация и потенциально более продвинутые системы репутации. Вот пример
простого контракта, который осуществляет Неймкойн-подобную систему регистрации имён в Эфириум:
```
if !contract.storage[tx.data[0]]:
contract.storage[tx.data[0]] = tx.data[1]
```
Этот контракт крайне прост; всё, что в нём говорится - ... Каждый может зарегистрировать имя и присвоить ему некоторое значение, и эту "регистрацию" никакая сторона
отменить не сможет, она уже в блокчейне. Более сложный контракт регистрации имени will also have a "function clause" allowing other contracts to query it, as well as a
mechanism for the "owner" (ie. the first registerer) of a name to change the data or transfer ownership. Более того, каждый сможет добавлять репутационную и сеть-
доверия функциональность поверх.
## Децентрализованное хранение файлов
В последние годы произошёл всплеск популярных стартапов, связанных с хранением файлов онлайн. Самым заметным из них является Dropbox. Однако в данный момент рынок
хранения файлов сравнительно неэффективен; беглый взгляд на различные существующие решения, в частности, на . Контракты Эфириум могут породить бум в экосистеме
децентрализованного хранения файлов, где отдельные пользователи могут зарабатывать небольшие суммы денег сдачей в аренду собственных жёстких дисков, и неиспользуемое
пространство будет приводить лишь к снижению стоимости хранения файлов.
Ключевым здесь является то, что мы назвали "децентрализованный Dropbox-контракт". Кратко опишем то, как он работает.
У этого протокола есть такая важная фича: несмотря на то, что кажется, что владельцу файла приходится полагаться на большое количество случайных узлов, которые хранят
его файл, риск может быть сведён практически до нуля предварительным разбиением на кусочки под названием "secret sharing". Контракты отслеживают то, хранят ли ноды
нужные куски. Если по контракту доли выплачиваются, это и является доказательством того, что рассматриваемый узел действительно хранит часть файла.
## Децентрализованные автономные организации
Идея децентрализованных автономных организаций (ДАО) - это виртуальная организация, с каким-то количеством членов или держателей акций,. Члены могут коллективно
решать, как организация должна распределять свои деньги. Методы распределения могут быть самые разные: от зарплат и премий до много более экзотических механизмов
наподобие внутренней валюты. Звучит похоже на обычные организации, но правоприменение здесь происходит только посредством блокчейн-технологии. К настоящему моменту
дискуссии вокруг ДАО велись вокруг "капиталистической" модели "децентрализованной автономной корпорации" (ДАК) с получающими дивиденды владельцами акций и торгующимися
акциями; альтернатива, которую, возможно, следовало бы назвать "децентрализованной автономное сообщество", такова: все члены имеют одинаковое право голоса и 67% членов
должны согласиться с добавлением/исключением члена для вынесения решения. Требование того, чтобы один человек имел только одно членство.
Обсудим то, как бы мог выглядеть код децентрализованной автономной организации. Первое, что приходит в голову - код, умеющий самоизменяться, если 2/3 членов дали
согласие на некоторое изменение. Although code is theoretically immutable, one can easily get around this and have de-facto mutability by having chunks of the code in
separate contracts, and having the address of which contracts to call stored in the modifiable storage. При простой реализации ДАО-контракта будет три типа транзакций,
отличающихся информацией транзакции:
\begin{itemize}
\end{itemize}
Такой контракт будет иметь пункт для каждой.
Альтернативная модель - децентрализованная корпорация, где любой аккаунт может иметь ноль или больше акций, и 2/3 акций необходимы для вынесения решения. Полный
"позвоночник" организации включал бы в себя функционал управления активами, возможность сделать предложение покупки/продажи акций, и возможность принимать предложения
(предпочтительно with an order-matching mechanism inside the contract). Delegation would also exist Liquid Democracy-style, generalizing the concept of a "board of
directors".
## Дальнейшие приложения
1. Сберегательные кошельки. Предположим, Алиса хочет сохранить свои сбережения, но опасается того, что потеряет или кто-либо украдёт её приватный ключ. Она заключает
контракт с Бобом (который заменяет банк), обеспеченный эфиром Алисы. Контракт может быть такого вида:
* В одиночку Алиса может забрать не более 1% средств в день.
* В одиночку Боб может забрать не более 1% средств в день, но Алиса имеет право наложить вето на этот пункт.
* Алиса и Боб по договорённости могут забрать любую часть средств.
Обычно 1% в день - это более чем достаточно для Алисы, и если Алиса захочет забрать больше, по договорённости с Бобом она сможет воспользоваться третьим пунктом. Если
приватный ключ Алисы будет украден, она обратится к Бобу за перемещением средств на новый контракт. Если она потеряет свой приватный ключ, Боб получит все средства в
конце концов. Если Боб окажется подозрительным лицом, она сможет отменить пункт, позволяющий ему забирать средства.
2. Страхование урожая. Каждый может создать контракт по управлению финансовыми деривативами, но использующий сведения о погоде, а не о цене актива, в качестве исходных
данных. Если краснодарский фермер покупает дериватив, выплаты по которому производятся обратно пропорционально осадкам в его регионе, тогда и в случае засухи фермер не
будет страдать, и в случае достаточного количества дождей, очевидно, тоже.
3. Децентрализованный поток информации.
4. Смарт-эскроу с мультиподписью. Биткойн позволяет заключать транзакционные контракты с мультиподписью, где, к примеру, три из пяти ключей могут расходовать средства.
Эфириум позволяет более замысловатые контракты - для примера, "4 из 5 могут потратить все средства, 3 из 5 могут тратить до 10% в день, 2 из 5 могут тратить до 0.5% в
день". В дополнение к сказнному, мультиподпись Эфириума асинхронна - две стороны могут поставить свою подпись в разное время, и последняя из них автоматически
произведёт транзакцию.
5. Облачные вычисления.
6. Peer-to-peer азартные игры. Любое количество протоколов peer-to-peer азартных игр, such as Frank Stajano and Richard Clayton's Cyberdice, может быть включено в
блокчейн Эфириума. Простейший такой протокол - контракт на разницу с хешем следующего блока, и могут быть созданы более продвинутые протоколы сервисов азартных игр с
практически нулевыми комиссиями, при этом в таких азартных играх нет никакой возможности жульничества.
7. Рынки предсказаний.
8. Децентрализованные рынки на основе блокчейна, в основании которых лежат описанные нами в соответствующем разделе системы идентификации и репутации.
# Размышления и разное
## Реализация modified GHOST
The ["Greedy Heavist Observed Subtree" (GHOST)](http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf) protocol - инновация, впервые введённая Йонатан
Сомполински и Авив Зохар в декабре 2013. Мотивация GHOST: блокчейны с быстрым временем подтверждения транзакции в данный момент страдают от недостаточной безопасности
ввиду большого количества "прокисших" блоков. Поясним, что имеется в виду. Так как блокам нужно сколько-то времени для того, чтобы распространиться по сети, если
майнер А находит блок, а затем майнер B находит другой блок с таким же порядковым номером до того, как к нему распространится информация о находке майнера A, блок
майнера B остаётся ненужным, не войдёт в блокчейн, и вычисления майнера B никак не помогут сообществу. Такие блоки мы и будем называть "прокисшими" (англ. термин -
stale). Этот эффект заметно усиливает тенденцию к централизации: если майнер A - это майнинг-пул, суммарная мощность которого составляет 30% мощности всей сети, а у
майнера (майнинг-пула) B эта цифра составляет 10% мощности всей сети, A будет иметь риск найти "ненужный" блок 70% времени (т.к. лишь в 30% случаев A будет находить
последний блок), а B, соответственно, будет иметь риск найти "ненужный" блок 90% времени. Таким образом, если интервал между блоками достаточно короткий, "ненужных"
блоков будет много и они будут заметно влиять на майнинг, и майнер B в нашем примере будет многократно проигрывать майнеру A даже не только за счёт меньшей мощности,
но также и из-за того, что будет находить гораздо больше "ненужных" блоков. Майнеры будут переходить на крупные пулы, и всё это приведёт к тому, что блокчейны с малым
временем генерации блока будут майниться на 1-2 крупных пулах, которые будут полностью контролировать майнинг, после чего [атака 51%](линк) неизбежна.
Сомполински и Зохар описали GHOST, который решает первую из этих проблем включением "прокисших" блоков в вычисление, определяющее самый длинный (с точки зрения
количества proof-of-work) отросток блокчейна. Для того, чтобы решить проблему централизации, мы выходим за рамки GHOST-протокола и вводим выплаты за "прокисшие" блоки:
"прокисший" блок получает 87.5% от того, что бы получил, если б был принят в блокчейн,
Это было сделано по нескольким причинам. Во-первых, полная версия протокола GHOST сильно бы усложнила вычисление того, какие дяди данного блока валидны. Во-вторых,
полная версия GHOST при предлагаемой Эфириум системе компенсации за "прокисшие" блоки приводит к отсутствию стимула майнить главную цепь блокчейна; как известно ....,
а не цепь возможного злоумышленника. Кроме того, одноуровневый GHOST приносит 80% пользы от полного GHOST-протокола, и процент прокисших блоков в нём при block time
(среднего времени нахождения нового блока) 40 секунд таков же, как у Лайткойна (как известно, block time Лайткойна - 2.5 минуты). Однако мы будем чуть более
консервативны при выборе block time и положим его равным 60 секунд (как у Праймкойна), поскольку верификация некоторых блоков занимает чуть больше обычного.
## Комиссии
Поскольку любую транзакцию, помещённую отправителем в блокчейн, кто-то должен добавить в блок и проверить, должен быть некоторый регуляторный механизм (комиссии) во
избежание злоупотреблений. Подход, используемый в Биткойн - комиссия устанавливается отправителем и может быть какой угодно, в том числе равной нулю (но когда награды
за нахождение блока станут крайне низкими, основную долю заработка майнера будут составлять именно комиссии, и транзакции с меньшими комиссиями будут включаться в
блокчейн в последнюю очередь, что приведёт к тому, что какие-то комиссии люди всё-таки будут платить, устанавливая тем самым динамическую сумму предполагаемой
комиссии). Это свойство Биткойн-протокола вызвало широкое одобрение Биткойн-сообщества как "рыночное", позволяющее спросу и предложению на услуги майнеров определять
цену. Проблема такого подхода в том, что проведение транзакций - это не рынок; пусть это и привлекательно - представлять проведение транзакций как рынок майнинг-услуг.
В реальности же каждая транзакция, включённая майнером в блок, должна быть проведена каждым узлом сети, так что практически вся часть "стоимости проведения транзакции"
осуществляется людьми, не получающими от неё никакой прибыли. Hence, tragedy-of-the-commons problems are very likely to occur.
Однако этот недостаток рыночного механизма при некотором упрощении магически исчезает. Аргумент тут такой. Предположим, что:
1. Пусть транзакция состоит из `k` операций и предлагает комиссию в `kR` майнеру, который включит её в блокчейн, где `R` задаётся отправителем, а `k` и `R` более-менее
известны майнеру заранее.
2. Себестоимость проведения операций для каждого нода равна `C` (т.е. все ноды одинаково эффективны)
3. Обозначим число майнящих нод за `N`, и пусть вычислительные мощности всех одинаковы (т.е. равны `1/N` от полного хэшрэйта сети).
4. Нет полных нод, которые не заняты в майнинге.
Майнер захочет провести только те транзакции, комиссия за которые превысит себестоимость проведения транзакций. Таким образом, ожидаемая награда здесь - `kR/N`, т.к.
вероятность нахождения блока с рассматриваемой транзакцией (да какого угодно блока) в нашей модели равна `1/N`. (Окей, более точно - матожидание награды равно `kR/N`.)
Себестоимость же проведения транзакции равна просто `kC`. Таким образом, майнеры будут включать такие транзакции в блок, для которых `kR/N > kC`, или `R > NC`. Ещё раз
подчеркнём, что `R` - устанавливаемая отправителем комиссия за каждую операцию транзакции, а `NC` - себестоимость проведения операции для всей сети.
Однако наша модель всё же не очень похожа на реальность. И вот почему:
1. Себестоимость проведения транзакций для майнера, нашедшего блок и включившего её в него, всё-таки выше, чем себестоимость для всех остальных нод, которые занимаются
её верификацией. Дело в том, что время, необходимое на верификацию, замедляет распространение блока в сети, что увеличивает вероятность того, что блок станет
"прокисшим" и не принесёт никакой прибыли.
2. Существуют полные ноды, которые не занимаются майнингом.
3. Вычислительные мощности майнеров распределены крайне неравномерно, и тенденция здесь, увы, в сторону дальнейшего увеличения "коэффициента Джини".
4. Спекулянты, боящиеся конкуренции политики и разного рода фанатики, стремясь нанести вред сети, вполне могут создать замысловатые контракты, себестоимость которых
для них самих будет гораздо ниже, чем себестоимость для верифицирующих (=почти всех остальных) нод.
По причине (1) майнерам выгоднее включать в блок поменьше транзакций, причина (2) увеличивает `NC`; так что эти два эффекта хотя бы частично компенсируют друг друга.
Пункты (3) и (4) являются известной проблемой; для того, чтобы пофиксить её, мы вводим плавающий лимит: ни один блок не может иметь больше операций, чем
`BLK_LIMIT_FACTOR` умножить на долгосрочное экспоненциально изменяющееся среднее значение. Более детально, `blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) +
floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR)`. `BLK_LIMIT_FACTOR` и `EMA_FACTOR` - константы, которые пока что предлагается положить равными 65536 и 1.5
соответственно, но эти значения, скорее всего, изменятся после более глубокого анализа.
## Вычисление и Тьюринг-полнота
An important note is that the Ethereum virtual machine is Turing-complete; это означает, что ЭВМ-код может реализовать любое мыслимое вычисление, включая бесконечные
циклы. ЭВМ-код допускает два способа написать бесконечный цикл. Во-первых, можно использовать инструкцию `JUMP` (или `JUMPI`, которая выполняет `JUMP` при выполнении
некоторого условия), которая позволяет вернуться в одну из предыдущих строк кода. Во-вторых, контракты могут обращаться к другим контрактам, что потенциально может
привести к рекурсии. Это, естественно, проблема: могут ли недобросовестные пользователи выключить майнеров и полные ноды, вводя их в бесконечный цикл? В computer
science это известно как <wiki>проблема остановки</wiki>: Тьюринг в своё время доказал, что не существует общего алгоритма, который позволял бы определить, закончится
ли когда-либо выполнение той или иной программы.
Как описано в разделе "Изменение состояния", наше решение - в том, чтобы задать максимально допустимое число шагов в вычислении, и если в вычислении больше шагов,
вычисление прерывается, произведённые изменения откатываются, но комиссии за него автором контракта уплачиваются. С сообщениями та же история. Чтобы пояснить причины
такого решения, рассмотрим следующие примеры:
* Злоумышленник создаёт контракт с бесконечным циклом, и затем пересылает транзакцию, активирующую этот контракт, майнеру. Майнер, проводя транзакцию, попадает в
бесконечный цикл, и в какой-то момент его газ заканчивается. Выполнение контракта на этом останавливается, но транзакция, активировавшая этот контракт, остаётся
валидной и майнер радостно взимает со злоумышленника комиссию за каждый вычислительный шаг.
* Злоумышленник создаёт цикл такой длины, чтобы за время, которое майнер будет вычислять его до конца, было найдено ещё несколько блоков, и майнер не мог включить
транзакцию в следующий блок, чтобы потребовать комиссию. Однако злоумышленник должен будет задать значение переменной `STARTGAS`, ограничивающей количество
вычислительных шагов, так что майнер заранее будет знать, какой контракт может содержать сумасшедшее количество вычислительных шагов.
* Злоумышленник видит контракт наподобие `send(A,contract.storage[A]); contract.storage[A] = 0`, и пересылает транзакцию с количеством газа, достаточным только для
выполнения первого шага, но не для второго (в данном примере - забирая деньги, но не давая балансу уменьшиться). Автор контракта не должен волноваться о возможности
таких атак, ведь если вычисление прерывается, произведённые изменения откатываются.
* Финансовый контракт берёт среднее от, скажем, девяти частных источников информации (для минимизации риска). Злоумышленник берёт один из этих потоков (который
модифицируемый с помощью variable-address-call mechanism described in the section on DAOs), and converts it to run an infinite loop, thereby attempting to force any
attempts to claim funds from the financial contract to run out of gas. Для защиты от подобного можно просто указать gas limit сообщения.
Альтернатива Тьюринг-полноты языка - Тьюринг-неполнота, где нет инструкций `JUMP` и `JUMPI`, и только одна копия каждого контракта может существовать в стеке в каждый
момент времени. В такой ситуации описанная система комиссий и паранойя по поводу возможности рекурсии теряют актуальность, поскольку в отсутствие возможности устроить
бесконечный цикл стоимость выполнения контракта будет ограничена сверху его размером. Дополнительно, Тьюринг-неполнота - не то чтобы такое уж сильное ограничение; из
всех рассмотренных нами контрактов пока что только один содержал "петлю" (инструкцию типа `JUMP`), и даже этой петли можно было избежать (оохх), 26 раз повторив одну
строчку. Возникает вопрос - есть ли какая-то серьёзная необходимость вводить в Эфириум Тьюринг-полный язык, если он причиняет нам столько проблем? Оказывается, что
Тьюринг-неполнота языка не приводит к решению всех этих проблем. Рассмотрим такой набор контрактов:
```
C0: call(C1); call(C1);
C1: call(C2); call(C2);
C2: call(C3); call(C3);
...
C49: call(C50); call(C50);
C50: (run one step of a program and record the change in storage)```
```
Перешлём транзакцию адресату A. Тогда для 51 транзакции наш контракт занимает 2^50 вычислительных шагов. Майнеры могли бы предугадывать такие логические бомбы,
устанавливая максимальное число вычислительных шагов для каждого контракта и вычисляя их в том числе когда в теле одного контракта выполняется другой контракт
Другая проблема здесь в том, что поле "адресат сообщения" - переменная, так что в общем случае, видимо, нельзя предсказать, какие другие контракты будет вызывать
данный контракт. Так что в итоге имеем нечто поистине удивительное: Тьюринг-полный язык на удивление прост в использовании; отсутствие Тьюринг-полноты языка не
приводит к тому, что возможность атаки бесконечным циклом на сеть отпадает сама; механизм защиты от бесконечного цикла в случае Тюринг-неполного языка такой же, как в
случае Тьюринг-полного. Поэтому почему бы не позволить себе радость пользоваться Тьюринг-полным языком? (:
## Валюта и выпуск
Сеть Эфириум включает в себя свою собственную встроенную валюту *эфир*, введённую с двумя целями: 1) предоставить по-настоящему ликвидную валюту для обмена цифровыми
активами 2) предоставить механизм оплаты стоимости транзакций. Для удобства и во избежание будущих споров и дискуссий (как это сейчас происходит с Биткойном при
обсуждениях названий для миллибиткойна, микробиткойна и мельчайшей частички Биткойна) номиналы валют предлагается обозначить:
* 1: wei
* 10^3: lovelace
* 10^6: babbage
* 10^9: shannon
* 10^12: szabo
* 10^15: finney
* 10^18: ether
Это расширенная версия долларов/центов, рублей/копеек, биткойн/сатоши. Мы ожидаем, что "ether" будет использоваться для обычных транзакций, "finney" - для
микротранзакций, "szabo" и "wei" - для технических дискуссий о протоколе; оставшиеся номиналы могут понадобиться позже и не должны быть пока что включены в стандартный
Эфириум-клиент.
Модель выпуска может быть следующей:
* Эфир будет выставлен на продажу по цене 1000-2000 единиц эфира за 1 BTC; на вырученные деньги будет профинансирована проделанная и дальнейшая разработка Эфириума,
как это имело место с Мастеркойн и NXT. Для первых покупателей будут действовать скидки. Биткойны, полученные с продажи, будут полностью использоваться для выплаты
зарплат и премий разработчикам, а также инвестированы в различные коммерческие и некоммерческие проекты в экосистеме Эфириум.
* 30% от полного количества проданного эфира будет оставлено организации, чтобы поощрить ранних участников, выплатить ETH-расходы перед первым блоком и в качестве
долгосрочного резерва. Это количество распределено в соответствии с законом экспоненциального затухания; каждый месяц до 5.6% оставшегося фонда может быть распределено