Що нам варто блокчейн збудувати?

Вся історія людства — це безперервне позбавлення ланцюгів і створення нових, ще міцніших. (Анонімний автор)

Аналізуючи численні blockchain проекти (Bitshares, Hyperledger, Exonum, Ethereum, Bitcoin та ін.), я розумію, що з технічної точки зору всі вони побудовані за одними принципами. Блокчейни нагадують будинки, у яких при всій різноманітності конструкцій, декору та призначень є фундамент, стіни, дах, вікна, двері, які пов'язані один з одним певними способами. І якщо зрозуміти основні принципи проектування будівель, знати властивості матеріалів, що застосовуються, то можна визначити цільове призначення конкретного будинку. Нині з блокчейном виникла ситуація, що про нього чули, але мало хто розуміє архітектуру і принципи роботи. Тому виникає нерозуміння навіщо і як можна використовувати технології блокчейна.

У цій статті ми розберемо загальні для всіх блокчейнів властивості та принципи. Далі подивимося на завдання, які можна вирішувати за допомогою блокчейну і для закріплення матеріалу збудуємо маленький, але справжній блокчейн на своїй віртуальній ділянці!

Отже, давайте згадаємо які проблеми спочатку вирішив блокчейн.

Упевнений, що багато хто скаже про розподілену, децентралізовану, публічну та незмінну базу даних. Але навіщо це все було потрібне?

Я волію починати вивчення будь-якої технології з читання стандартів, тому що саме на них ґрунтуються всі статті та книги з досліджуваної теми. Але стандарти блокчейну в даний час відсутні, ISO створено тільки комітети для їхньої розробки. На даний момент у кожному публічному блокчейн проекті є свій документ White paper, який по суті є технічним завданням. Перший загальновідомий блокчейн проект – це мережа Bitcoin. Ідемо на офіційний сайт мережі та дивимося з чого все починалося.

Завдання блокчейна

Отже, завдання, яке вирішив блокчейн у мережі піонері Bitcoin – це здійснення довірчої передачі власності на цифрові активи (assets) у недовірчому середовищі без посередників. Наприклад, у мережі Bitcoin цифровий актив це цифрові монети bitcoin. І всі технічні рішення Bitcoin та інших блокчейнів зводяться до вирішення цього завдання.

Проблеми, які вирішує блокчейн

Припустимо, якась фінансова організація каже, що побудувала мережу по всьому світу, за допомогою якої можна переказувати гроші будь-якій людині. Чи ви повірите їй? Якщо ця організація Visa або MasterCard, швидше за все, повірите, а якщо, умовно кажучи, AnonymousWorldMoney, мабуть, ні. Чому ж? А тому, що ми чудово знаємо, як робляться розподілені системи приватними компаніями, з якими цілями, і до чого це може спричинити. Розглянемо докладніше проблеми таких систем, і як вони можуть бути вирішені із застосуванням технологій блокчейну.

Допустимо, в умовній AnonymousWorldMoney стоять сервери з базами даних, і добре, якщо їх буде дещо в різних дата-центрах. Коли відправник переказує гроші, реєструється транзакція, яка реплікується на всі сервери, і гроші доходять до одержувача.

Що нам варто блокчейн збудувати?

В ідеальному світі така схема чудово працює, у нашому ж виникають такі проблеми:

  1. Проблема ідентифікації учасників з одного боку та необхідність анонімності транзакцій з іншого. Тобто. треба переказати гроші конкретному одержувачу і так, щоб про цю транзакцію ніхто не знав, крім учасників угоди. Банки мають номери рахунків і банківських карток, прив'язаних до конкретної фізичної чи юридичної особи, а банківська таємниця захищає інформацію про транзакції. А хто гарантує, що умовна AnonymousWorldMoney не використовує персональні дані та інформацію про транзакції у своїх цілях?
  2. Як переконатись, що одержувач отримав саме ту суму, яку йому перевели? Умовно кажучи, відправник переказав $100, а одержувач отримав $10. Приходить відправник до офісу AnonymousWorldMoney зі своєю квитанцією, а клерк показує свою версію, де записано, що відправник переказав лише $10.
  3. Проблема недовірливого середовища, наприклад шахрайство, зване double-spending. Несумлінний учасник може витратити свій баланс кілька разів, поки платіж не реплікувався на всі сервери. CAP теорему, звичайно, ніхто не скасовував, і узгодженість зрештою буде досягнута, але хтось не отримає гроші за надані послуги чи товари. Тому, якщо немає повної довіри до платіжної організації чи учасників угод, треба будувати мережу, засновану не так на довірі, але в криптографії.
  4. Умовна AnonymousWorldMoney має кінцеве число серверів, які можуть стати недоступними ненавмисно або за злим наміром.
  5. AnonymousWorldMoney візьме свою відчутну комісію.
  6. Можливість керування. У процесі експлуатації Bitcoin з'ясувалося, що люди хочуть не лише перекладати один одному монети, але й перевіряти різні умови проходження транзакції, програмувати сценарії роботи, автоматично виконувати дії залежно від умов і т.д.

Як блокчейн вирішує ці проблеми

  1. Ідентифікація учасників здійснюється за допомогою пари ключів: приватного та відкритого, а алгоритм цифрового підпису однозначно ідентифікує відправника та одержувача, залишаючи їх особи анонімними.
  2. Транзакції збираються в блоки, обчислюється хеш блоку, який записується до наступного блоку. Така послідовність запису хешів у блоках і дала назву технології blockchain, і вона ж унеможливлює непомітну зміну/видалення блоків або окремих транзакцій з блоків. Таким чином, якщо транзакція потрапила до блокчейну, то можна бути впевненим, що її дані залишаться незмінними.
  3. Шахрайство double-spending запобігає шляхом досягнення консенсусу в мережі, які дані вважати вірними, а які відкидати. У мережі Bitcoin консенсус досягається підтвердженням виконання роботи PoW (Proof-of-Work).
  4. Надійність функціонування мережі досягається тим, що блокчейн є публічним, де кожен учасник може запустити свою ноду, отримати повну копію блокчейна і, більше того, самостійно почати перевіряти транзакції на правильність. Слід зазначити, що сучасні блокчейни дозволяють будувати як публічні (відкриті), а й приватні (закриті) блокчейни, і навіть використовувати комбіновані схеми.
  5. Повністю комісії в блокчейні не позбудеться, т.к. треба платити людям, які підтримують мережу, але в блокчейні необхідність комісії доводиться так переконливо, що не залишається сумнівів у її необхідності.
  6. Сучасні блокчейни мають можливість реалізовувати бізнес-логіку, яка в блокчейні називається Smart Contracts. Логіка смарт контрактів реалізуються різними мовами високого рівня.

Далі розглянемо ці рішення докладніше.

Архітектура блокчейна

Складові частини блокчейну

Кожен учасник може запустити свою ноду з повною копією блокчейну (full node). Повні ноди, які можуть записувати транзакції в блокчейн, називаються вузлами консенсусу (witness) чи майнерами (miner). Повні ноди, які тільки перевіряють правильність транзакцій, називаються вузлами аудиту (Audit). Легкі клієнти (light clients) не зберігають повних копій блокчейну, а взаємодіють із мережею, використовуючи повні ноди.
Більшість користувачів для транзакцій використовують саме легких клієнтів або web гаманці. Усі ноди пов'язані друг з одним. При такому наборі елементів архітектура мережі стає більш стійкою:

Що нам варто блокчейн збудувати?

Життєвий цикл транзакції

Подивимося на життєвий цикл транзакції і розберемо його частинами:

Що нам варто блокчейн збудувати?

Технології блокчейна

Зупинимося докладніше на технічних рішеннях та його зв'язках друг з одним.

ідентифікація

Кожна блокчейн транзакція має бути підписана цифровим підписом. Тому для здійснення транзакції кожен учасник повинен мати кілька ключів: private/public. Іноді кілька ключів називають гаманець (wallet), т.к. ключі однозначно пов'язані з унікальною цифровою адресою та балансом учасника. Насправді ключі та адреси – це просто рядки цифр у різних системах числення. Приклади ключів та адреси гаманця:

Private key: 0a78194a8a893b8baac7c09b6a4a4b4b161b2f80a126cbb79bde231a4567420f
Public key: 0579b478952214d7cddac32ac9dc522c821a4489bc10aac3a81b9d1cd7a92e57ba
Address: 0x3814JnJpGnt5tB2GD1qfKP709W3KbRdfb27V

Для створення цифрового підпису в блокчейнах використовується алгоритм, що ґрунтується на еліптичних кривих: Elliptic Curve Digital Signature Algorithm (ECDSA). Для його роботи приватний ключ (256 бітне число), як правило, береться випадково. Число варіантів ключів становить 2 у ступені 256, тому можна говорити про практичну неможливість збігу значень приватних ключів.

Далі, публічний ключ виходить з приватного шляхом множення його значення на координати точки, що знаходиться на еліптичній кривій, у результаті виходять координати нової точки цієї ж кривої. Ця дія гарантує отримання пари ключів, придатних для цифрових підписів транзакцій. І нарешті адреса гаманця однозначно обчислюється з публічного ключа.

Є маса статей з подробицями криптографії, що використовується в блокчейні, наприклад: Bitcoin in a nutshell — Cryptography

Приватний ключ повинен бути строго секретним і зберігатися в безпеці. Публічний ключ відомий усім. При втраті приватного ключа доступ до активу (монет) відновити неможливо і гроші будуть втрачені назавжди. Тому завдання надійного зберігання приватних ключів є вкрай актуальним, т.к. це не банк, куди завжди можна прийти з паспортом та відновити рахунок. Існує ціла індустрія з виробництва, так званих, холодних криптогаманців, схожих на флешки:

Що нам варто блокчейн збудувати?

або можна використовувати надійніші способи, як приклад, вибивати значення приватного ключа на жетонах:

Що нам варто блокчейн збудувати?

Транзакції

Докладніше про структуру транзакції можна переглянути у статті Bitcoin in a nutshell - Transaction. Нам важливо розуміти, що кожна транзакція має принаймні такі дані:

From: 0x48C89c341C5960Ca2Bf3732D6D8a0F4f89Cc4368 - цифровой адрес отправителя
To: 0x367adb7894334678b90аfe7882a5b06f7fbc783a - цифровой адрес получателя
Value: 0.0001 - сумма транзакции
Transaction Hash: 0x617ede331e8a99f46a363b32b239542bb4006e4fa9a2727a6636ffe3eb095cef - хэш транзакции

Далі транзакція підписується приватним ключем і розсилається (див. подробиці роботи протоколу Bitcoin в nutshell-Protocol) всім нодам у блокчейні, які перевіряють транзакції на валідність. Алгоритм перевірки транзакції нетривіальний і включає два десятки кроків.

Блоки транзакцій

Перевіривши валідність транзакцій, ноди формують їх блоки. Крім транзакцій блок записується хеш попереднього блоку, число (лічильник Nonce), і відбувається обчислення хеша поточного блоку за алгоритмом SHA-256. Хеш повинен мати встановлені умови складності. Наприклад, у мережі Bitcoin складність хешу автоматично змінюється раз на 2 тижні залежно від потужності мережі так, щоб блок генерувався приблизно раз на 10 хвилин. Складність визначаться наступною умовою: знайдений хеш має бути меншим заздалегідь заданого числа. Якщо ця умова не виконується, то Nonce додається 1, і робота з обчислення хеша повторюється. Для підбору хешу використовують поле Nonce, т.к. це єдині дані у блоці, які можна змінити, решта мають залишатися незмінними. Правильний хеш повинен мати певну кількість нулів на початку, наприклад, один із реальних хешів:

000000000000000000000bf03212e7dd1176f52f816fa395fc9b93c44bc11f91

Успішне знаходження хеша є доказом виконаної роботи (Proof-of-Work, PoW) для мереж Bitcoin або Ethereum. Процес знаходження хешей називається майнінгом (mining), за аналогією до видобутку золота. Назву досить точно визначає суть процесу, т.к. відбувається простий перебір варіантів, і якщо хтось знайшов відповідний хеш, то це справді удача. Це як знайти справжній самородок золота в тоннах порожньої породи. Винагорода за блок зараз становить 12.5 BTC і якщо помножити на актуальний курс біткоїну $3900, то виходить більше за кілограм чистого золота. Є за що боротися!

Після успішного знаходження хеша блок і сам знайдений хеш записуються блокчейн наступним блоком. Докладніше про структуру блоків можна переглянути у статті Bitcoin in nutshell-Blockchain, а нижче наведу спрощену схему:

Що нам варто блокчейн збудувати?

Блокчейн починається з блоку, який ще не має хеша попереднього блоку. Такий блок у блокчейні один і має власну назву Genesis block. В інших блоків однакова структура і вони відрізняються лише числом транзакцій. Реальні транзакції та блоки, що створюються в даний час в Bitcoin або Ethereum, можна дивитися в Блок Провідник.

Розмір блоків Bitcoin обмежений 1Мб і при мінімальному обсязі інформації в транзакції близько 200 байт, максимально в блоці може бути близько 6000 транзакцій. Звідси, до речі, і випливає продуктивність Bitcoin, з якої всі сміються: блок генерується приблизно раз на 10 хв * 60 сек = 600 сек, що дає формальну продуктивність близько 10 TPS. Хоча насправді це не продуктивність, а свідомо реалізований алгоритм роботи. У Ethereum для конкуренції просто зробили час створення блоку 15 сек. та продуктивність формально злетіла. Тому в блокчейнах, що використовують PoW як консенсус взагалі безглуздо порівнювати продуктивність, т.к. вона безпосередньо залежить від складності обчислення кеша, яку можна призначити будь-яку.

Форки

А що відбувається, якщо, наприклад, кілька вузлів знайшли хеші, що задовольняють умовам складності, але різні за значенням (іншими словами, дійшли різних консенсусів) і записали блоки в блокчейн? Давайте подивимося, як блокчейн захищається від цієї ситуації. У цьому випадку відбувається так званий форк ('вилка'), і блокчейн має дві версії ланцюжка:

Що нам варто блокчейн збудувати?

Що відбувається далі? Далі частина мережі починає працювати над блоком N+2 від одного ланцюжка, а частина від іншого:

Що нам варто блокчейн збудувати?

Якийсь із цих блоків буде знайдений раніше і відправлений до блокчейну і тоді за правилами блокчейн повинен буде переключитися на більш довгий ланцюжок і скасувати всі транзакції з альтернативного блоку:

Що нам варто блокчейн збудувати?

При цьому може скластися ситуація, коли транзакція учасника знаходилася тільки в одному з блоків форка, який і було скасовано. Тому, щоб бути впевненим, що потрібна транзакція записалася до блокчейну, є загальна рекомендація — перш ніж довіряти транзакції треба почекати, поки наступні кілька блоків не будуть додані до блокчейну. Рекомендації скільки блоків чекати для різних блокчейнів різняться. Наприклад, для мережі Bitcoin мінімум – це 2 блоки, максимум 6.

Така ж картина з форком блоків спостерігатиметься і за так званої атаки 51% — це коли група майнерів намагатиметься виростити альтернативну ланцюжок блоків, домагаючись скасування ланцюжка зі своїми шахрайськими транзакціями. Хоча нині замість шахрайства вигідніше витрачати свої потужності на чесний майнінг.

консенсус

Для запису блоку в блокчейн мережа має дійти консенсусу. Згадаймо, завдання досягнення консенсусу в комп'ютерних мережах зв'язку. Проблема формулюється як завдання візантійських генералів BFT (Візантійська відмовність). Опускаючи живописне опис проблем візантійської армії, завдання можна сформулювати так: як вузлам мережі дійти загального результату, якщо частина вузлів мережі можуть свідомо їх спотворювати. Існуючі алгоритми вирішення завдання BFT показують, що мережа може функціонувати правильно, якщо шахраїв менше 1/3. Чому в мережі Bitcoin не було застосовано консенсус BFT? Для чого потрібно було використовувати PoW? Є кілька причин:

  • BFT добре працює з невеликим фіксованим набором нод, а в публічному блокчейні число нод непередбачувано і, більше того, ноди можуть довільно вмикатися.
  • Необхідно мотивувати людей запускати блокчейн ноди. Для цього люди мають отримувати винагороду. У BFT формально нема за що отримувати винагороду, а ось за що йде винагорода в PoW всім зрозуміло на інтуїтивному рівні: за електрику, спожиту процесором у процесі знаходження хеша блоку.

Крім PoW існує ще кілька консенсусів, які використовуються в сучасних блокчейнах, наприклад:

  • PoS (Proof-of-Stake) - у блокчейні Hyperledger
  • DPoS (Delegated Proof-of-Stake) - у блокчейні BitShares
  • Модифікації BFT: SBFT ( Simplified BFT ) та PBFT ( Practical BFT ), наприклад, у блокчейні Екзонум

Небагато зупинимося на консенсусі PoS, т.к. саме PoS та його різновиди набули найбільшого поширення в приватних блокчейнах. Чому саме у приватних? З одного боку, показники PoS краще проти PoW, т.к. для досягнення консенсусу потрібні менші обчислювальні ресурси, а отже, збільшується швидкість запису даних у блокчейн. Але з іншого боку, у PoS більше можливостей для шахрайства, тому для нейтралізації цього всі учасники блокчейну мають бути відомі.

Консенсус PoS заснований на виборі вузла, який може записати блок з транзакціями в блокчейн в залежності від кількості коштів на рахунку, вірніше, не на рахунку, а в заставі, тобто. чим у тебе більше коштів у заставі, тим більшою ймовірністю мережа вибере твій вузол для запису блоку. Запорука не повернеться, якщо блок виявиться невалідним. Таким чином реалізовано захист від шахрайства. Є такі варіації PoS:

  • Консенсус Delegated PoS (DPoS) поділяє учасників на тих, хто «голосує» і «валює». Утримувачі монет (учасники, що голосують) делегують своє право перевіряти і записувати транзакції в блокчейн іншим учасникам. Таким чином, валідатори виконують всю обчислювальну роботу і отримують за це винагороду, а наявність учасників гарантує чесність валідаторів, т.к. їх можна змінити будь-якої миті.
  • Консенсус LPoS (Leased Proof-of-Stake) дозволяє віддати свої кошти в оренду іншим вузлам, щоб вони мали більше шансів для перевірки блоків. Т.о. можна отримувати комісію за транзакції, при цьому не беручи участь у самій перевірці транзакцій та майнінгу блоків.

Існує ще ряд консенсусів, які поки не набули широкого поширення, тут просто перерахую для інформації, а огляд самих алгоритмів консенсусу можна подивитися, наприклад, у статті: Алгоритми Консенсусу у Блокчейні.

  • PoET (Proof-of-Elapsed Time)
  • PoC (Proof-of-Capacity)
  • PoB (Proof-of-Burn)
  • PoWeight (Proof-of-Weight)
  • PoA (Proof-of-Activity) - PoW + PoS
  • PoI (Proof-of-Importans)

Надійність та моделі розгортання блокчейнів

Публічний блокчейн

Стійкість громадськості або інша назва Блокчейн без дозволу досягається тим, що кожен може підключитися та переглянути інформацію або навіть підключити свій вузол, а довіра будується на консенсусі PoW.

Приватний блокчейн

приватний або Private Permissioned blockchain. У цих блокчейнах лише певна група учасників (організацій чи людей) має доступом до інформації. Такі блокчейни будують організації з збільшення загальної вигоди чи ефективності. Їх надійність забезпечується загальними цілями учасників та алгоритмами консенсусу PoS та BFT.

Блокчейн-консорціум

існують консорціум або Public Permissioned blockchain. Це такі блокчейни, до яких кожен може підключитися для перегляду, але додавати інформацію або підключити свій вузол учасник може лише з дозволу інших учасників. Такі блокчейни будують організації з підвищення довіри із боку замовників чи споживачів продукції чи суспільства загалом. Тут надійність також досягається присутністю довіри між учасниками та тими самими алгоритмами консенсусу PoS та BFT.

Спритні контракти

У блокчейни, реалізовані після Bitcoin, додана можливість виконання смарт-контрактів. По суті смарт-контракт - це транзакція, в якій розміщено програмний код для виконання. Смарт-контракти мережі Ethereum виконуються в EVM (Ethereum Virtual Machine). Для початку виконання смарт-контракту його треба явно запустити іншою транзакцією, або маємо виконатися передумови для виконання. Результати виконання смарт-контракту також запишуться до блокчейну. Отримання даних ззовні блокчейна можливе, але вкрай обмежене.

Яку логіку можна реалізувати за допомогою смарт-контракту? Насправді не так багато, наприклад перевірка умов за даними з блокчейну, зміна власників цифрових активів залежно від цих умов, запис даних у постійне сховище всередині блокчейну. Реалізується логіка спеціальною мовою високого рівня Solidity.

Класичним прикладом функціональності, яку реалізують з використанням смарт-контрактів, - це випуск токенів для проведення ICO. Наприклад, мною було реалізовано смарт-контракт на випуск скромних 500 000 000 AlexToken. за посилання в Etherscan перебувають

вихідний код смарт-контракту на мові Solidity

pragma solidity ^0.4.23;
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
**/
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
if (a == 0) {
return 0;
}
c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
**/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
// uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return a / b;
}
/**
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
**/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
**/
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
assert(c >= a);
return c;
}
}
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
**/
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender account.
**/
constructor() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
**/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
**/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
/**
* @title ERC20Basic interface
* @dev Basic ERC20 interface
**/
contract ERC20Basic {
function totalSupply() public view returns (uint256);
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
**/
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) public view returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/**
* @title Basic token
* @dev Basic version of StandardToken, with no allowances.
**/
contract BasicToken is ERC20Basic {
using SafeMath for uint256;
mapping(address => uint256) balances;
uint256 totalSupply_;
/**
* @dev total number of tokens in existence
**/
function totalSupply() public view returns (uint256) {
return totalSupply_;
}
/**
* @dev transfer token for a specified address
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
**/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
emit Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
**/
function balanceOf(address _owner) public view returns (uint256) {
return balances[_owner];
}
}
contract StandardToken is ERC20, BasicToken {
mapping (address => mapping (address => uint256)) internal allowed;
/**
* @dev Transfer tokens from one address to another
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
**/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
*
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
**/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param _owner address The address which owns the funds.
* @param _spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
**/
function allowance(address _owner, address _spender) public view returns (uint256) {
return allowed[_owner][_spender];
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
*
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _addedValue The amount of tokens to increase the allowance by.
**/
function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
*
* approve should be called when allowed[_spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _subtractedValue The amount of tokens to decrease the allowance by.
**/
function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
uint oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
}
/**
* @title Configurable
* @dev Configurable varriables of the contract
**/
contract Configurable {
uint256 public constant cap = 1000000000*10**18;
uint256 public constant basePrice = 100*10**18; // tokens per 1 ether
uint256 public tokensSold = 0;
uint256 public constant tokenReserve = 500000000*10**18;
uint256 public remainingTokens = 0;
}
/**
* @title CrowdsaleToken 
* @dev Contract to preform crowd sale with token
**/
contract CrowdsaleToken is StandardToken, Configurable, Ownable {
/**
* @dev enum of current crowd sale state
**/
enum Stages {
none,
icoStart, 
icoEnd
}
Stages currentStage;
/**
* @dev constructor of CrowdsaleToken
**/
constructor() public {
currentStage = Stages.none;
balances[owner] = balances[owner].add(tokenReserve);
totalSupply_ = totalSupply_.add(tokenReserve);
remainingTokens = cap;
emit Transfer(address(this), owner, tokenReserve);
}
/**
* @dev fallback function to send ether to for Crowd sale
**/
function () public payable {
require(currentStage == Stages.icoStart);
require(msg.value > 0);
require(remainingTokens > 0);
uint256 weiAmount = msg.value; // Calculate tokens to sell
uint256 tokens = weiAmount.mul(basePrice).div(1 ether);
uint256 returnWei = 0;
if(tokensSold.add(tokens) > cap){
uint256 newTokens = cap.sub(tokensSold);
uint256 newWei = newTokens.div(basePrice).mul(1 ether);
returnWei = weiAmount.sub(newWei);
weiAmount = newWei;
tokens = newTokens;
}
tokensSold = tokensSold.add(tokens); // Increment raised amount
remainingTokens = cap.sub(tokensSold);
if(returnWei > 0){
msg.sender.transfer(returnWei);
emit Transfer(address(this), msg.sender, returnWei);
}
balances[msg.sender] = balances[msg.sender].add(tokens);
emit Transfer(address(this), msg.sender, tokens);
totalSupply_ = totalSupply_.add(tokens);
owner.transfer(weiAmount);// Send money to owner
}
/**
* @dev startIco starts the public ICO
**/
function startIco() public onlyOwner {
require(currentStage != Stages.icoEnd);
currentStage = Stages.icoStart;
}
/**
* @dev endIco closes down the ICO 
**/
function endIco() internal {
currentStage = Stages.icoEnd;
// Transfer any remaining tokens
if(remainingTokens > 0)
balances[owner] = balances[owner].add(remainingTokens);
// transfer any remaining ETH balance in the contract to the owner
owner.transfer(address(this).balance); 
}
/**
* @dev finalizeIco closes down the ICO and sets needed varriables
**/
function finalizeIco() public onlyOwner {
require(currentStage != Stages.icoEnd);
endIco();
}
}
/**
* @title LavevelToken 
* @dev Contract to create the Lavevel Token
**/
contract AlexToken is CrowdsaleToken {
string public constant name = "AlexToken";
string public constant symbol = "ALT";
uint32 public constant decimals = 18;
}

та бінарне уявлення, як його бачить мережа

60806040526000600355600060045533600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600560146101000a81548160ff021916908360028111156200006f57fe5b0217905550620001036b019d971e4fe8401e74000000600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546200024a6401000000000262000b1d179091906401000000009004565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550620001986b019d971e4fe8401e740000006001546200024a6401000000000262000b1d179091906401000000009004565b6001819055506b033b2e3c9fd0803ce8000000600481905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6b019d971e4fe8401e740000006040518082815260200191505060405180910390a362000267565b600081830190508281101515156200025e57fe5b80905092915050565b611cb880620002776000396000f300608060405260043610610112576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146104c7578063095ea7b31461055757806318160ddd146105bc57806323b872dd146105e7578063313ce5671461066c578063355274ea146106a3578063518ab2a8146106ce57806366188463146106f957806370a082311461075e57806389311e6f146107b55780638da5cb5b146107cc578063903a3ef61461082357806395d89b411461083a578063a9059cbb146108ca578063bf5839031461092f578063c7876ea41461095a578063cbcb317114610985578063d73dd623146109b0578063dd62ed3e14610a15578063f2fde38b14610a8c575b60008060008060006001600281111561012757fe5b600560149054906101000a900460ff16600281111561014257fe5b14151561014e57600080fd5b60003411151561015d57600080fd5b600060045411151561016e57600080fd5b3494506101a7670de0b6b3a764000061019968056bc75e2d6310000088610acf90919063ffffffff16565b610b0790919063ffffffff16565b9350600092506b033b2e3c9fd0803ce80000006101cf85600354610b1d90919063ffffffff16565b111561024c576101f66003546b033b2e3c9fd0803ce8000000610b3990919063ffffffff16565b915061022e670de0b6b3a764000061022068056bc75e2d6310000085610b0790919063ffffffff16565b610acf90919063ffffffff16565b90506102438186610b3990919063ffffffff16565b92508094508193505b61026184600354610b1d90919063ffffffff16565b6003819055506102886003546b033b2e3c9fd0803ce8000000610b3990919063ffffffff16565b6004819055506000831115610344573373ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f193505050501580156102dd573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a35b610395846000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef866040518082815260200191505060405180910390a361045184600154610b1d90919063ffffffff16565b600181905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc869081150290604051600060405180830381858888f193505050501580156104bf573d6000803e3d6000fd5b505050505050005b3480156104d357600080fd5b506104dc610b52565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561051c578082015181840152602081019050610501565b50505050905090810190601f1680156105495780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561056357600080fd5b506105a2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b8b565b604051808215151515815260200191505060405180910390f35b3480156105c857600080fd5b506105d1610c7d565b6040518082815260200191505060405180910390f35b3480156105f357600080fd5b50610652600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c87565b604051808215151515815260200191505060405180910390f35b34801561067857600080fd5b50610681611041565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b3480156106af57600080fd5b506106b8611046565b6040518082815260200191505060405180910390f35b3480156106da57600080fd5b506106e3611056565b6040518082815260200191505060405180910390f35b34801561070557600080fd5b50610744600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061105c565b604051808215151515815260200191505060405180910390f35b34801561076a57600080fd5b5061079f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506112ed565b6040518082815260200191505060405180910390f35b3480156107c157600080fd5b506107ca611335565b005b3480156107d857600080fd5b506107e16113eb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561082f57600080fd5b50610838611411565b005b34801561084657600080fd5b5061084f6114ab565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561088f578082015181840152602081019050610874565b50505050905090810190601f1680156108bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108d657600080fd5b50610915600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506114e4565b604051808215151515815260200191505060405180910390f35b34801561093b57600080fd5b50610944611703565b6040518082815260200191505060405180910390f35b34801561096657600080fd5b5061096f611709565b6040518082815260200191505060405180910390f35b34801561099157600080fd5b5061099a611716565b6040518082815260200191505060405180910390f35b3480156109bc57600080fd5b506109fb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611726565b604051808215151515815260200191505060405180910390f35b348015610a2157600080fd5b50610a76600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611922565b6040518082815260200191505060405180910390f35b348015610a9857600080fd5b50610acd600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119a9565b005b600080831415610ae25760009050610b01565b8183029050818382811515610af357fe5b04141515610afd57fe5b8090505b92915050565b60008183811515610b1457fe5b04905092915050565b60008183019050828110151515610b3057fe5b80905092915050565b6000828211151515610b4757fe5b818303905092915050565b6040805190810160405280600981526020017f416c6578546f6b656e000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600154905090565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151515610cc457600080fd5b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610d1157600080fd5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610d9c57600080fd5b610ded826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b3990919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610e80826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f5182600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b3990919063ffffffff16565b600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b6b033b2e3c9fd0803ce800000081565b60035481565b600080600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508083111561116d576000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611201565b6111808382610b3990919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a3600191505092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561139157600080fd5b60028081111561139d57fe5b600560149054906101000a900460ff1660028111156113b857fe5b141515156113c557600080fd5b6001600560146101000a81548160ff021916908360028111156113e457fe5b0217905550565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561146d57600080fd5b60028081111561147957fe5b600560149054906101000a900460ff16600281111561149457fe5b141515156114a157600080fd5b6114a9611b01565b565b6040805190810160405280600381526020017f414c54000000000000000000000000000000000000000000000000000000000081525081565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561152157600080fd5b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561156e57600080fd5b6115bf826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b3990919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611652826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b60045481565b68056bc75e2d6310000081565b6b019d971e4fe8401e7400000081565b60006117b782600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a0557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611a4157600080fd5b8073ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6002600560146101000a81548160ff02191690836002811115611b2057fe5b021790555060006004541115611c0a57611ba5600454600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015611c89573d6000803e3d6000fd5b505600a165627a7a723058205bbef016cc7699572f944871cb6f05e69915ada3a92a1d9f03a3fb434aac0c2b0029

Більше подробиць про смарт-контракти можна дізнатися у статті: Що таке смарт-контракти у Ethereum.

Висновок

Ми перерахували технології, на яких побудовані сучасні блокчейни і як вони пов'язані один з одним. Тепер давайте сформулюємо, які завдання можна вирішити за допомогою блокчейну, а рішення яких буде, у кращому разі, неефективним. Отже, використання блокчейну не обов'язково, якщо:

  • Транзакції відбуваються у довірчому середовищі;
  • Наявність комісії посередників не погіршує життя учасників;
  • У учасників немає власності, яку можна подати у вигляді цифрових активів;
  • Немає розподіленості у цифрових активах, тобто. цінністю володіє чи постачає лише один учасник.

Яке майбутнє чекає на блокчейн? Зараз можна лише припускати можливі шляхи розвитку блокчейн технологій:

  • Блокчейн стане такою ж звичайною технологією баз даних, як, наприклад, SQL або NoSQL для вирішення певного кола завдань;
  • Блокчейн стане широко поширеним протоколом як HTTP для Інтернету;
  • Блокчейн стане основою для нової фінансової та політичної системи планети!

Ми ж у наступній частині подивимося які зараз існують блокчейни і для чого вони застосовуються у різних індустріях.

Це лише початок!

Джерело: habr.com

Додати коментар або відгук