Введення в смарт-контракти

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

Традиційний договір vs. смарт-контракт

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

Введення в смарт-контракти

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

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

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

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

Визначення смарт-контракту

Взагалі сама термінологія була придумана дослідником Nick Szabo і вперше застосована в 1994 році, а задокументована була в 1997 році в статті, яка описує саму ідею смарт-контрактів.

Смарт-контракти мають на увазі, що виконується деяка автоматизація розподілу цінності, яка може залежати тільки від тих умов, які попередньо встановлені. У найпростішому варіанті це виглядає, як контракт із строго заданими умовами, який підписано певними сторонами.

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

Простий приклад - Escrow сервіс

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

Введення в смарт-контракти

Його можна реалізувати також із використанням Біткоїна, хоча зараз Біткоїн ще складно назвати повноцінною платформою для смарт-контрактів. Отже, ми маємо деякого покупця і маємо інтернет-магазин. Покупець хоче купити монітор у цьому магазині. У найпростішому випадку покупець оформляє та відправляє платіж, а інтернет-магазин приймає його, підтверджує, після чого відправляє товар. Однак у цій ситуації є необхідність великої довіри — покупець повинен на всю вартість монітора довіряти інтернет-магазину. Оскільки інтернет-магазин може мати низьку репутацію в очах покупця, існує ризик, що з якихось причин після прийому платежу магазин відмовить в обслуговуванні і не відправить товар покупцю. Тому покупець задається питанням (відповідно, і інтернет-магазин задається цим питанням), що можна в цьому випадку застосувати, щоб мінімізувати такі ризики і зробити надійнішими подібні угоди.

У випадку з Біткоїном можна надати можливість покупцю та продавцю незалежно один від одного вибрати медіатора. Є багато людей, які займаються вирішенням спірних питань. І наші учасники можуть вибрати із загального списку медіаторів того, якому одночасно довірятимуть. Разом вони створюють multisignature адресу 2 з 3, де є три ключі і необхідні два підписи будь-якими двома ключами, щоб витратити монети з цієї адреси. Один ключ належатиме покупцеві, другий — інтернет-магазину, а третій — медіатору. І на таку multisignature адресу покупець надішле суму, необхідну для оплати монітора. Тепер, коли продавець бачить, що гроші на деякий час заблоковані на multisignature адреса, яка залежить від нього, він сміливо може відправляти монітор поштою.

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

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

Медіатор зацікавлений у тому, щоб задовольнити одночасно і обурення покупця, та інтереси інтернет-магазину (далі буде зрозуміло чому). Він складає таку транзакцію, в якій монети з multisignature адреси будуть витрачатися в деякій пропорції між покупцем, інтернет-магазином та медіатором, оскільки він бере собі частину як винагороду за свою роботу. Припустимо, 90% усієї суми піде продавцю, 5% медіатору та 5% компенсації покупцю. Цю транзакцію медіатор підписує своїм ключем, але вона ще не може бути застосована, тому що для цього потрібні два підписи, а стоїть лише один. Таку транзакцію він надсилає і покупцю, і продавцю. Якщо хоча б один з них буде задоволений таким варіантом перерозподілу монет, то транзакція буде підписана і поширена в мережу. Для її валідації достатньо, щоб один із учасників угоди погодився з варіантом медіатора.

При цьому важливо спочатку вибрати медіатора так, щоб обидва учасники довіряли йому. У разі він діятиме незалежно від інтересів однієї чи іншої і об'єктивно оцінить ситуацію. Якщо ж медіатор не надає такий варіант розподілу монет, який задовольнить хоча б одного учасника, тоді домовившись разом, і покупець, і інтернет-магазин можуть переправити монети на нову multisignature адресу, поставивши свої два підписи. Нова multisignature адреса буде складена вже з іншим медіатором, який, можливо, буде більш компетентним у питанні і надасть найкращий варіант.

Приклад із гуртожитком та холодильником

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

Введення в смарт-контракти

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

Вони можуть скористатися escrow сервісом, тобто вибрати медіатора, який проконтролює виконання угоди та вирішить спірні питання, якщо такі виникнуть. Тоді домовившись, вони складають смарт-контракт і прописують у ньому певні умови.

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

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

Класифікація смарт-контрактів

Для класифікації можна задавати різні групи критеріїв. Однак на даний момент розвитку технологій є актуальними чотири з них.

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

Їх також можна відрізняти за процесом завдання та виконання умов: вони можуть бути довільно програмовані, обмежені або встановлені, тобто строго типізовані. Коли на платформі смарт-контрактів існує лише 4 певні смарт-контракти, параметри до них можна задавати довільним чином. Відповідно, задавати їх набагато простіше: ми обираємо контракт зі списку та передаємо параметри.

За способом ініціювання існують автоматизовані смарт-контракти, тобто при настанні певних умов вони самовиконуються, а бувають такі контракти, в яких умови задані, але платформа автоматично не перевіряє їх виконання, для цього їх потрібно окремо ініціювати.

Крім того, смарт-контракти розрізняються за рівнем приватності. Вони можуть бути повністю відкриті, або частково, або повністю конфіденційні. Останнє означає, що сторонні спостерігачі не бачать умов смарт-контрактів. Проте тема приватності дуже велика і її краще розглянути окремо від поточної статті.

Нижче ми докладніше зупинимося на перших трьох критеріях, щоб внести більшу ясність у розуміння поточної теми.

Смарт-контракти щодо виконання

Введення в смарт-контракти

За середовищем виконання розрізняють централізовані та децентралізовані платформи смарт-контрактів. У разі централізованих цифрових контрактів використовується один сервіс, де існує лише один валідатор і може бути служба резервного копіювання та відновлення, яка також централізовано управляється. Є одна база даних, яка зберігає всю необхідну інформацію для завдання умов смарт-контракту та розподілу тієї цінності, яка враховується в цій базі даних сервісу. Такий централізований сервіс має клієнта, який певними запитами задає умови і користується такими контрактами. Через те, що платформа централізована, механізми аутентифікації можуть бути менш надійними, ніж криптовалютах.

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

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

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

Смарт-контракти щодо способу завдання та виконання умов

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

Вирізняють також довільні смарт-контракти, але не повні за Тьюрингом. Сюди можна віднести Біткоїн та Лайткоїн зі своїм скриптом. Мається на увазі, що можна в довільному порядку використовувати лише певні операції, але вже не можна написати цикли та власні алгоритми.

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

До довільних повних за Тьюрингом контрактів можна віднести платформу Ethereum та RootStock, яка ще перебуває на стадії розробки. Тому далі ми трохи детальніше зупинимося на платформі Ethereum смарт-контрактів.

Смарт-контракти щодо способу ініціації

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

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

Аккаунти в Ethereum

Типи облікових записів Ethereum

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

Обліковий запис користувача керується лише особистим ключем електронного підпису. Власник облікового запису генерує свою пару ключів для електронного підпису за алгоритмом ECDSA (Elliptic Curve Digital Signature Algorithm). Змінювати стан цього облікового запису можуть лише підписані цим ключем транзакції.

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

Як створюються облікові записи в Ethereum

У випадку з обліковим записом користувача, власник самостійно генерує пару ключів по ECDSA. Важливо відзначити, що Ethereum використовує для електронного підпису такий самий алгоритм і таку саму еліптичну криву, як і Bitcoin, але адреса обчислюється дещо іншим чином. Тут вже не застосовується результат подвійного хешування, як у Біткоїні, а передбачено одноразове хешування функцією Keccak на довжині 256 біт. Від отриманого значення відсікаються молодші біти, саме 160 молодших біт вихідного значення хеш-функції. У результаті ми отримуємо адресу Ethereum. Фактично він займає 20 байт.

Звернемо увагу, що ідентифікатор облікового запису в Ethereum кодується в hex без застосування контрольної суми, на відміну від Bitcoin та багатьох інших систем, де адреса кодується в систему числення на підставі 58 з додаванням контрольної суми. Це означає, що працювати з ідентифікаторами облікових записів в Ethereum потрібно обережно: навіть одна помилка в ідентифікаторі гарантовано призведе до втрати монет.

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

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

Кожен смарт-контракт обов'язково містить конструктор (цього контракту). Він може бути пустим, а може мати вміст. Після того, як конструктор виконується, створюється ідентифікатор облікового запису смарт-контракту, використовуючи який, можна відправляти монети, викликати певні методи смарт-контракту і т.д.

Структура транзакції Ethereum

Щоб було зрозуміліше, ми розпочнемо розгляд структури транзакції Ethereum та прикладу коду смарт-контракту.

Введення в смарт-контракти

Транзакція Ethereum складається з кількох полів. Перше з них nonce — це певний порядковий номер транзакції щодо облікового запису, який її розповсюджує і є автором. Це потрібно для того, щоб відрізняти двійники транзакцій, тобто виключити випадок, коли та сама транзакція приймається двічі. Завдяки застосуванню ідентифікатора, кожна транзакція має унікальне хеш-значення.

Далі слідує таке поле, як ціна на газ. Тут зазначається ціна, за якою базова валюта Ethereum конвертується в gas, яким оплачується виконання смарт-контракту та виділення ресурсу віртуальної машини. Що це означає?

У Біткоїні комісії оплачуються безпосередньо базовою валютою — самим біткоїном. Це можливо завдяки простому механізму їх розрахунку: ми оплачуємо строго обсяг даних, що міститься в транзакції. В Ethereum ситуація складніша, тому що від обсягу даних транзакції відштовхуватися дуже складно. Тут транзакція ще може містити програмний код, який запускатиметься на віртуальній машині, а кожна операція віртуальної машини може мати різну складність. Існують також операції, які виділяють пам'ять змінних. Вони матимуть свою складність, від якої залежатиме оплата за кожну операцію.

Вартість кожної операції в еквіваленті gas буде константною. Він і запроваджується спеціально для того, щоб визначити константну вартість кожної операції. Залежно від навантаження на мережу зміняться gas price, тобто коефіцієнт, згідно з яким базова валюта конвертуватиметься в цю допоміжну одиницю для оплати комісії.

Є ще одна особливість транзакції в Ethereum: байт-код, який вона містить для виконання у віртуальній машині, буде виконуватися доти, доки він не завершиться з якимось результатом (успіх-неуспіх) або доки не закінчиться деяка кількість монет, виділена на оплату комісії. Саме щоб уникнути ситуації, коли з облікового запису відправника у разі якоїсь помилки витратилися всі монети на комісію (наприклад, якийсь вічний цикл запустився у віртуальній машині), існує таке поле — start gas (його часто називають gas limit) - воно визначає максимальний обсяг монет, які відправник готовий витратити на виконання певної транзакції.

Наступне поле називається адреса призначення. Сюди вписується адреса одержувача монет чи адресу конкретного смарт-контракту, способи якого будуть викликатися. Після нього слідує поле значення, куди вписується сума монет, що відправляються на destination address

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

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

Приклад коду смарт-контракту на Solidity

Давайте зараз розглянемо найпростіший смарт-контракт на прикладі.

contract Bank {
    address owner;
    mapping(address => uint) balances;
    
    function Bank() {
        owner = msg.sender;
    }

    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }

    function withdraw(uint amount) public {
        if (balances[msg.sender] >= amount) {
            balances[msg.sender] -= amount;
            msg.sender.transfer(amount);
        }
    }

    function getMyBalance() public view returns(uint) {
        return balances[msg.sender];
    }

    function kill() public {
        if (msg.sender == owner)
            selfdestruct(owner);
    }
}

Наведено вище спрощений вихідний код, який може утримувати монети користувачів і повертати їх на вимогу.

Отже, є смарт-контракт Bank, який виконує такі функції: він накопичує на своєму балансі монети, тобто при підтвердженні транзакції та розміщенні такого смарт-контракту створюється новий обліковий запис, який може містити на своєму балансі монети; він запам'ятовує користувачів та розподіл монет між ними; має кілька методів управління балансами, тобто є можливість поповнення, виведення та перевірки балансу користувача.

Давайте пройдемося по кожному рядку вихідного коду. У цьому вся контракті є константні поля. Одне з них, з типом address, називається owner. Тут контракт запам'ятовує адресу користувача, який створив цей смарт-контракт. Далі, є динамічна структура, яка зберігає відповідності між адресами користувачів і балансами.

Після цього слідує метод Bank — він називається так само, як і контракт. Відповідно це його конструктор. Тут відбувається присвоєння змінної owner адреси того, хто розмістив цей смарт-контракт у мережі. Це єдине, що відбувається у цьому конструкторі. Тобто msg в даному випадку — це ті дані, які були передані віртуальній машині разом з транзакцією, що містить весь код цього контракту. Відповідно, msg.sender - це автор цієї транзакції, яка розміщує цей код. Він і буде власником смарт-контракту.

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

Наступний метод називається withdraw і він приймає один параметр - ту суму монет, яку хтось хоче вивести з цього банку. Тут іде перевірка, чи достатньо монет на балансі користувача, який викликає цей метод, щоб їх надіслати. Якщо їх достатньо, тоді сам смарт-контракт повертає таку кількість монет, що викликає.

Далі йде метод перевірки поточного балансу користувача. Той, хто викликає цей метод, використовуватиметься для отримання цього балансу в смарт-контракті. Варто зазначити, що модифікатор цього – view. Це означає, що сам метод ніяк не змінює змінні свого класу і він є лише методом читання. Окрема транзакція не створюється для виклику цього методу, комісія не сплачується, а всі обчислення виконуються локально, після чого користувач отримує результат.

Метод kill потрібен для того, щоб знищити стан смарт-контракту. І тут прописана додаткова перевірка, чи є власником цього контракту, що викликає цього методу. Якщо є, тоді контракт самознищується, а функція знищення приймає один параметр — ідентифікатор облікового запису, на який контракт відправить усі монети, що залишилися на його балансі. У цьому випадку монети, що залишилися, автоматично підуть на адресу власника контракту.

Як працює повний вузол мережі Ethereum?

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

Введення в смарт-контракти

Повний вузол мережі Ethereum як мінімум повинен мати чотири модулі.
Першим, як і для будь-якого децентралізованого протоколу, є P2P networking module — модуль мережного з'єднання та роботи з іншими вузлами, де обмін блоками, транзакціями, інформацією про інші вузли. Це традиційний компонент для всіх децентралізованих криптовалютів.

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

Третій модуль називається EVM (Ethereum virtual machine) — це віртуальна машина, яка приймає байт-код з Ethereum транзакції. Цей модуль приймає поточний стан певного облікового запису та виконує зміни його стану на базі отриманого байт-коду. Версія віртуальної машини на кожному з вузлів мережі має бути однаковою. Обчислення відбуваються на кожному з вузлів Ethereum абсолютно однакові, але вони відбуваються в асинхронному порядку: хтось раніше перевіряє і приймає цю транзакцію, тобто виконує весь код, що міститься в ній, а хтось пізніше. Відповідно, при створенні транзакції, вона поширюється в мережу, вузли її приймають і в момент верифікації так само, як у Біткоїні виконується Bitcoin Script, тут виконується байт-код віртуальної машини.

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

Міфи та обмеження смарт-контрактів

Що стосується обмежень, які існують для схожих на Ethereum платформ смарт-контрактів, можна навести такі:

  • code execution;
  • allocate memory;
  • blockchain data;
  • send payments;
  • create new contract;
  • call інші контракти.

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

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

Найпоширеніший міф полягає в тому, що смарт-контракти Ethereum можуть використовувати інформацію з будь-яких інтернет-ресурсів у своїх умовах. Правда полягає в тому, що віртуальна машина не може надіслати мережевий запит якомусь зовнішньому інформаційному ресурсу в інтернеті, тобто не можна написати такий смарт-контракт, який розподілятиме цінність між користувачами залежно від того, припустимо, яка погода на вулиці, або хто виграв у якомусь чемпіонаті, або на підставі того, яка ще подія сталася у зовнішньому світі, тому що інформації про ці події просто немає в базі даних самої платформи. Тобто у блокчейні нічого з цього приводу немає. Якщо воно там не з'явиться, то і віртуальна машина не може використовувати ці дані як тригери.

Недоліки Ethereum

Давайте перерахуємо основні їх. Перший недолік полягає в тому, що існують деякі складності при проектуванні, розробці та тестуванні смарт-контрактів в Ethereum (Ethereum для написання смарт-контрактів використовується мова Solidity). Справді, практика показує, що дуже великий відсоток серед усіх помилок належить людському фактору. Це практично актуально і вже написаних смарт-контрактів Ethereum, які мають складність середню чи вище. Якщо для простих смарт-контрактів ймовірність помилки мала, то в складних смарт-контрактах дуже часто зустрічаються помилки, які призводять до розкрадання коштів, їх заморожування, знищення смарт-контрактів непередбачуваним чином і т. п. Вже багато таких випадків відомо.

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

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

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

Що стосується Ethereum, то було проведено дуже багато досліджень, отримано дуже великий практичний досвід: як позитивний, так і негативний, проте залишаються складності та вразливості, з якими належить ще якось боротися.

Отже, тематична частина статті завершена, перейдемо до питань, що виникають досить часто.

Часті питання

— Якщо всі сторони чинного смарт-контракту хочуть змінити умови, чи можуть вони скасувати цей смарт-контракт за допомогою мультипідпису, а потім створити новий смарт-контракт із оновленими умовами його виконання?

Тут відповідь буде двояка. Чому? Тому що з одного боку смарт-контракт один раз задається і він уже не має на увазі жодних змін, а з іншого боку він може мати заздалегідь прописану логіку, яка передбачає повну чи часткову зміну якихось умов. Тобто, якщо ви хочете щось змінити у своєму смарт-контракті, то ви заздалегідь повинні прописати умови, за якими ви можете оновити ці умови. Відповідно, тільки в такий запобіжний спосіб можна організувати оновлення контракту. Але і тут теж можна напоротися на неприємності: припуститися якоїсь помилки і отримати відповідну вразливість. Тому такі речі потрібно дуже детально та ретельно проектувати та тестувати.

— А якщо медіатор увійде у змову з однієї із сторін-учасників: escrow чи смарт-контракту? Чи обов'язковий медіатор у смарт-контракті?

Медіатор не є обов'язковим у смарт-контракті. Його може бути. Якщо у випадку escrow медіатор увійде в змову з однієї зі сторін, то так, ця схема різко втрачає всю свою цінність. Тому медіатори і вибираються таким чином, що їм довіряють одночасно всі сторони, залучені до цього процесу. Відповідно, ви просто не перекладатимете монети на multisignature адресу з тим медіатором, якому не довіряєте.

— Чи можна однією транзакцією Ethereum перевести багато різних токенів зі своєї адреси на цільові адреси, наприклад біржові адреси, де торгуються ці токени?

Це хороше питання і стосується моделі транзакцій Ethereum і її відмінності від моделі Bitcoin. І відмінність це кардинально. Якщо в моделі транзакції Ethereum ви просто переводите монети, то вони переводяться лише з однієї адреси на іншу, без здачі, просто конкретну суму, яку ви вказали. Інакше висловлюючись, це модель невитрачених виходів (UTXO), а модель саме акаунтів і відповідних балансів. Однією транзакцією відправити одразу кілька різних токенів теоретично можна, якщо написати хитрий смарт-контракт, але все одно доведеться зробити багато транзакцій, створити контракт, потім передати йому токени та монети, а потім викликати відповідний метод. Це вимагає зусиль та часу, відповідно, на практиці це так не працює і всі платежі в Ethereum здійснюються окремими транзакціями.

— Один із міфів про платформу Ethereum полягає в тому, що неможливо описати такі умови, які залежатимуть від даних зовнішнього інтернет-ресурсу, як бути тоді?

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

Даній темі присвячена одна з лекцій онлайн-курсу з Blockchain - “Введення в смарт-контракти".

Джерело: habr.com

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