Як створити масштабовані dApps та смарт-контракти в Ethereum з State Channels крок за кроком. Частина 1

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

Вам не доведеться чекати майбутніх удосконалень блокчейна. Технологія тут залишається, і ви можете використовувати її для створення всіх видів dApps. Зараз державні канали в основному використовуються для ігор на основі блокчейна в Ethereum.

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

Що таке державні канали?

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

Їх називають "державними", оскільки кожна взаємодія повинна мати стан, який можна оновити. Подумайте про суму гри або банківський баланс.

Чому вони існують?

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

Що означає безкоштовні та швидкі транзакції.

Що нам потрібно для налаштування державного каналу?

  1. Принаймні 2 користувачі, які будуть взаємодіяти один з одним. Канал потрібно відкрити між двома або більше користувачами. Подібно до програми для чату.
  2. Розумний контракт з логікою державного каналу, який відкриє його і закриє.
  3. Якщо в грі буде використовуватися державний канал, для обох користувачів знадобиться депозит. Цей ескроу в ефірі буде зберігатися в смарт-контракті під час відкриття каналу.
  4. Додаток Javascript, який генерує підписані повідомлення, які будуть обмінюватися між мережами між мережами.
  5. Метамаска або подібний інструмент для підписання повідомлень. Підписання повідомлень не коштує газу, і вони виконуються миттєво. Обоє користувачів вимагають підписати повідомлення, щоб гарантувати, що саме вони генерують таку транзакцію.
  6. Електронною поштою або будь-якою зовнішньою програмою для обміну тими підписаними повідомленнями, щоб зробити це можливим.

Як вони працюють?

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

  1. У державному каналі між двома користувачами перший розгортає смарт-контракт, який "відкриє" канал.
  2. Другий виконує функцію розумного контракту "приєднатися" до цього державного каналу "
  3. Потім вони можуть розпочати обмін підписаними повідомленнями для програми. Обидва користувачі мають доступ до користувацького додатку javascript для генерування повідомлень з інформацією, яку вони роблять у смарт-контракті, але поза ланцюгом.
  4. Швидкість транзакцій залежить від того, наскільки швидко кожен користувач може створити та підписати ці повідомлення. Вони продовжують обмінюватися повідомленнями, граючи поза ланцюгами, поки не вирішать, що гра закінчена.
  5. Коли вони закінчать гру, будь-хто з них може перейти до розумного контракту та виконати функцію для його завершення, яка розпочне фазу «переговорів».
  6. У цій фазі обоє користувачів мають тайм-аут у 1 день для завантаження останніх 2-х повідомлень, які вони мають на смарт-контракт. Розумний контракт перевіряє останні повідомлення та вивільняє кошти на закінчення гри на основі цієї інформації. Кожне повідомлення містить результати попередніх взаємодій, тому безпечно просто перевіряти останні.

Як ви можете застосувати це в реальній ситуації?

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

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

Це індекс, за яким ми будемо слідувати, щоб створити таку децентралізовану програму:

  1. Створення візуального веб-програми. Це інтерфейс, як виглядатиме гра зовнішнім користувачам. Він буде використовуватися як носій для обміну підписаними повідомленнями для державних каналів.
  2. Створення функціональних можливостей, необхідних для підписання та шифрування повідомлень.
  3. Створення смарт-контракту.

1. Створення візуального веб-програми

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

У цьому випадку ми хочемо показати схожі речі для обох гравців. Гравець 1 побачить 6 граней кубиків як зображення, і йому доведеться вибрати, яке з них вийде, потім другий гравець, також повинен буде вибрати між цими обличчями, і він зможе побачити результат.

Тож рамка буде приблизно такою:

  1. Гравець 1 переходить у веб-додаток, натискає кнопку із написом «Почати нову гру», потім робить транзакцію з метамаскою для розгортання та налаштування смарт-контракту. Він отримує смарт-адресу контракту, яку він може надіслати іншому гравцеві для початку гри.
  2. Гравець 2 переходить у веб-додаток, натискає кнопку з написом "Приєднатись до існуючої гри" з адресою контракту, отриманою від гравця 1, потім він робить транзакцію з метамаскою, щоб налаштувати вже існуючу гру та надсилає ескроу.

Тож давайте почнемо саме там. Давайте створимо поле посередині веб-програми за допомогою двох кнопок. Створіть папку під назвою кістки та файл всередині під назвою index.html. Ось код:

Ось так виглядають 2 кнопки за замовчуванням


    
        
         Гра в кубики ефіріума 
    
    <ніхто>
        
                                  
    

У цьому коді я щойно створив основну структуру HTML з дівом, що містить кнопки та заголовок. Зауважте, що в div є клас, який називається основний контент, який ми використаємо за мить.

Давайте зробимо це красивіше з деяким css. Створіть файл під назвою index.css із наступним кодом (його можна скопіювати та вставити):

Ось як це буде виглядати
корпус {
    сімейство шрифтів: sans-serif;
}
.main-content {
    маржа: авто;
    максимальна ширина: 500 пікселів;
    фоновий колір: whitesmoke;
    підкладка: 50px;
    межі-радіус: 10 пікселів;
    дисплей: сітка;
    сітка-шаблон-рядки: 1fr 1fr;
    сітка-шаблон-стовпці: 1fr 1fr;
    сітка-стовпчик-проміжок: 10px;
}
.основний вміст h1 {
    сітка-стовпчик: 1 / проліт 2;
}
. кнопка основного вмісту {
    межа: немає;
    колір: білий;
    фоновий колір: # 007dff;
    підкладка: 20px;
    межа-радіус: 5px;
    курсор: вказівник;
}
. кнопка основного вмісту: наведіть курсор {
    непрозорість: 0,8;
}
. кнопка основного вмісту: активна {
    непрозорість: 0,6;
}

Я додав h1 заголовок до html, щоб він виглядав краще, не забудьте оновити ваш HTML, додавши посилання на css:



    
        
        
         Гра в кубики ефіріума 
    
    <ніхто>
        
            

Кістки ефірума

                                  
    

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

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

Після натискання кнопки «Приєднатись до наявної гри» йому буде запропоновано адресу ескроу та контракту існуючої гри.

Ось як реагують дії кнопки:

Як додаток виглядає за допомогою простого JavaScript

Для цього я створив файл index.js з певною логікою javascript. Ось javascript, не забудьте ввести його руками, якщо ви хочете дізнатися це краще:

Дозвольте мені пояснити, що я там робив:

  • Спочатку я створив функцію під назвою start (), яка буде виконуватися негайно, щоб обернути вміст, щоб він був приємним і містився в одній великій функції.
  • Тоді я створив 2 слухачі подій, які активуються щоразу, коли натискаю кнопки «Пуск» або «Приєднання» у файлі html. Один для кнопки # нова гра та інший для кнопки # приєднатися до гри. Я використовую document.querySelector (), який є одним із найпотужніших способів вибрати що-небудь у вашому js-коді.
  • Всередині цих слухачів я показую або приховую поле діг кожного відповідного елемента. В основному вибір коробки з querySelector та видалення або додавання прихованого класу, який встановлено в css для відображення: немає; .

Тоді ми можемо з'єднати файл js з нашим modifie index.html:



    
        
        
         Гра в кубики ефіріума 
    
    <ніхто>
        
            

Кістки ефірума

                         
            
                

Скільки ескроу ви будете використовувати в ETH?

                             
            
                

Яка адреса смарт-контракту для існуючої гри?

                             
            
        
        
    

Я виділив жирними шматками доданого коду. Далі йде оновлений css для стилю нової інформації:

корпус {
    сімейство шрифтів: sans-serif;
}
.hidden {
    дисплей: немає;
}
.main-content {
    маржа: авто;
    максимальна ширина: 500 пікселів;
    фоновий колір: whitesmoke;
    підкладка: 50px;
    межі-радіус: 10 пікселів;
    дисплей: сітка;
    grid-template-рядки: 1fr 80px auto;
    сітка-шаблон-стовпці: 1fr 1fr;
    сітка-стовпчик-проміжок: 10px;
}
.основний вміст h1 {
    сітка-стовпчик: 1 / проліт 2;
}
. кнопка основного вмісту {
    межа: немає;
    колір: білий;
    фоновий колір: # 007dff;
    підкладка: 20px;
    межа-радіус: 5px;
    курсор: вказівник;
}
. кнопка основного вмісту: наведіть курсор {
    непрозорість: 0,8;
}
. кнопка основного вмісту: активна {
    непрозорість: 0,6;
}
. кнопка основного вмісту: вимкнено {
    непрозорість: 0,5;
    колір фону: сірий;
    курсор: авто;
}
.mein-content введення {
    ширина: 100%;
    межі-радіус: 10 пікселів;
    підкладка: 10px;
    облямівка: 1px суцільний світловий колір;
}
.main-content div.new-game-setup, .main-content div.join-game-setup {
    сітка-стовпчик: 1 / проліт 2;
}
# кнопка - продовжити {
    сітка-стовпчик: 1 / проліт 2;
    margin-top: 20 пікселів;
}

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

2. Створення та підключення первинного смарт-контракту

Настав час створити базову версію смарт-контракту та з'єднати його зі своїм JavaScript за допомогою web3.js. На даний момент нам потрібні лише конструктор і деяка основна інформація. Запишіть цей код своїми руками у новий файл під назвою Dice.sol:

солідність прагми 0,4,25;
контрактні кубики {
    адресу громадського гравця1;
    адресу громадського гравця2;
    uint256 public player1Escrow;
    uint256 public player2Escrow;
    платник-платник ()
        вимагати (msg.value> 0);
        player1 = msg.sender;
        player1Escrow = msg.value;
    }
    функція setupPlayer2 () публічна платня {
        вимагати (msg.value> 0);
        player2 = msg.sender;
        player2Escrow = msg.value;
    }
}

Є 2 функції, конструктор для встановлення адреси та дескрипції першого гравця та функція setupPlayer2 () для настройки інформації другого гравця.

Ми хочемо розгорнути контракт і виконати конструктор із вказаним правилом msg.value, коли користувач натисне кнопку «Продовжити». Для цього нам доведеться реалізувати web3.js у нашому смарт-контракті. Оскільки це головний спосіб спілкування з блокчейном у браузері.

Отримайте web3.js у папці свого додатка звідси: https://github.com/ethereum/web3.js/blob/develop/dist/web3.js, який є офіційним оновленням коду розповсюдження.

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

Відкрийте сторінку, натисніть на

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

Ми використовуємо метамаску для розмови з blockchain. Однак це не працює, коли ви відкриєте файл index.html у своєму браузері, оскільки розширення file: // не підтримується для метамаски.

Тоді нам потрібно запустити локальний сервер, який обслуговуватиме файли в URL-адресі http: // localhost: 8080, оскільки метамаска не працює, коли ви відкриваєте файл index.html безпосередньо. Для цього відкрийте термінал і встановіть це:

npm i -g http-сервер

Потім у своїй папці проекту запустіть http-сервер, щоб запустити локальний сервер для вашого index.html:

http-сервер

Це буде обслуговувати файли на localhost: 8080, щоб ви могли отримати доступ до них та ввести web3 з метамаски.

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

Для розгортання нового контракту нам потрібен ABI, параметри конструктора та байт-код. Це вимоги до web3.js.

  1. Щоб створити ABI, перейдіть на remix.ethereum.org, вставте свій код у головний розділ та натисніть на ABI:

Це скопіює код ABI. Перейдіть у папку свого проекту та створіть файл під назвою ContraData.js, щоб вставити туди код зі змінною під назвою abi, як:

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

Кнопка копіювання байт-коду для вашого коду

І створіть іншу змінну всередині contractData.js, яку називають байт-кодом, з такою інформацією, як:

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

Імпортуйте цей файл JavaScript у ваш html перед файлом index.js для наявності змінних abi та bytecode:

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

Що я там робив:

  • Я додав ідентифікатор id до входів, де користувача запитують, скільки ефіру він хоче вкласти в дескриптор та адресу контракту, якщо він приєднається до вже існуючої гри.
  • Потім я додав імпорт javascript вище index.js, тому що ми хочемо, щоб абі та байт-код були доступні всередині index.js, оскільки його потрібно імпортувати спочатку.

Потім ми додаємо необхідну логіку, щоб ця кнопка працювала. Ми перевіримо, чи введена адреса контракту в HTML порожній чи ні.

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

Перш ніж я покажу вам весь код, я хочу пояснити вам, як розгорнути контракт за допомогою web3.js. Це виглядає просто, але я застряг у деяких областях.

Отже, коли користувач натискає «Почати нову гру», він дає нам суму ескроу в ефірі та його адресу, ми можемо розгорнути новий контракт з цією функцією:

По суті, ви створюєте екземпляр контракту з abi і виконуєте метод .new () для цього контракту з байт-кодом.

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

Що означає, що цей зворотний дзвінок буде виконуватися 2 рази. Один, коли ви виконуєте створення контракту, і інший, коли адреса цього договору доступна.

Ви можете перевірити, коли адреса договору доступна, за допомогою простої заяви:

if (! result.address) {
    // Розпочато створення контракту
} else {
    // Контракт розгорнуто, і ви можете використовувати адресу з результатом адреси
}

Ось так ви розгортаєте контракт з web3.

Але що робити, якщо ви хочете отримати доступ до існуючого контракту на блокчейні?

Це саме те, що нам потрібно "приєднатися" до гри в кубики, щоб створити екземпляр контракту. Для цього нам потрібні лише ABI та адреса договору, байт-код не потрібен. Ось як це зробити в веб3:

Договір = web3.eth.contract (abi)
contractInstance = Contract.at (addressSelected)

Після цього ви можете виконувати функції цього договору так:

contractInstance.setupPlayer2 ({
  значення: web3.toWei (valueSelected),
  газ: 4e6
}, (помилка, результат) => {
    // Зробіть щось після виконання функції
})

Вам потрібні лише екземпляр, назва функції, параметри, якщо такі є, і функція зворотного виклику.

Тепер, коли ви зрозуміли, як розгортання та створення розумного контракту працюють на JavaScript, я покажу вам повний код програми:

Ігноруйте все вище, на що вам слід зосередитись, - це блок слухача "# кнопка - продовжити":

document.querySelector ('# кнопка-продовження'). addEventListener ()

Тому що вам потрібно дбати лише про те, що станеться, коли гравець 1 або гравець 2 натискають кнопку "Продовжити". Ось поділка:

  • Коли будь-який гравець натискає цю кнопку, слухач цієї події виконується
  • Всередині я отримую значення вхідних даних, щоб встановити ескроу та адресу розгорнутого контракту, якщо гравець приєднується до вже існуючої гри. Це змінні valueSelected та addressSelected.
  • Потім я створюю змінну настройки контракту з abi, яка буде потрібна обом гравцям.
  • Після цього я бачу, встановлена ​​чи ні адреса розгорнутого контракту. Якщо адреса порожня, це означає, що гравець натиснув "Почати нову гру", оскільки в такому випадку він не побачить введення адреси.
  • Що означає, що я розгортаю нову гру або розумний контракт для цього гравця з вибраним депозитом.
  • Цей перший гравець побачить адресу розгорнутого смарт-контракту. Йому доведеться поділитися цією адресою з іншим гравцем, щоб розпочати гру з кубиками, оскільки вам потрібні 2 гравці.
  • Якщо він вказав адресу, це означає, що він хоче приєднатися до існуючої гри. Це можна зробити, створивши екземпляр смарт-контракту, використовуючи його адресу, а потім виконавши функцію setupPlayer2 ().
  • Я використовую функцію setInterval, щоб перевіряти кожні 1 секунду, чи налаштування програвача 2 завершена чи не для початку гри.

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

Не пропустіть і будьте першим, хто прочитає його після завершення. Приєднуйтесь до мого ексклюзивного списку розсилки Ethereum Developers, щоб отримувати оновлення та інформацію безпосередньо від мене тут: http://eepurl.com/dDQ2yX

Частина 2 тепер доступна тут: https://medium.com/@merunasgrincalaitis/how-to-create-scalable-dapps-and-smart-contracts-in-ethereum-with-state-channels-step-by-step- 690f71a9bf2f

Якщо ви відчуваєте, що ви переповнені такою передовою інформацією, або ви просто новачок щодо солідності та Ethereum dapps, перегляньте мою книгу "Ethereum Developer: Learn Solidity from Scratch" тут https://merunas.io/