Developing decentralized chat with Next.js [ukr]
Talk presentation
Developers often consider blockchain and Web3 to be complex and requiring new specific knowledge, languages, and concepts. However, it is possible to develop decentralized applications using a standard web developer toolkit. This presentation will explore the basic differences in developing Web3 applications, using the example of creating a decentralized chat application that interacts with blockchain and a distributed file system, using Next.js and a few small JS libraries. The nuances of working with Next.js will also be discussed, and the author will explain why they use it for most of their web applications.
Talk transcription
Так, всім привіт. Так, мене представили. Зразу переходимо до найважливішого. І мене дуже часто зустрічають, що блокчейн – це важко, потрібно знати якісь суперспецифічні мови, по типу солідіті, чи це потрібно занурюватися в Rust. І взагалі, можливо, потрібно знати якусь темну магію для того, щоб побудувати щось з блокчейном. Але я завжди відповідаю це, чи бачу інші розробники відповідають, що не знаю. Я побудував чат за 90 хвилин, за годинку, використовуючи чисто JavaScript. І після цього все закінчується. І сьогодні я хочу якраз пояснити, показати, що для того, щоб будувати, працювати з блокчейном, будувати якісь децентралізовані рішення, не потрібно знати якихось дуже суперспецифічних мов, матерій. А достатньо мати JavaScript і ще трішечки того, що ми сьогодні поговоримо. І почнемо.
Саме перше – це потрібно знати блокчейн-бесікс. Без них нікуди. Це як ми починаємо вчити front-end без кент і починаємо розбирати, що таке HTTP, умовно. Так саме тут. І сьогодні ми безтресенько про них пробіжимося і перейдемо далі до загальної концепції, як це – будувати децентралізований чат. І починаємо ми з того, що таке взагалі блокчейн. Дуже короткими словами – це децентралізована розподілена база даних, яка зберігає всі свої дані в ципочці блоків. І для того, щоб добавити нові дані в цю ципочку, має пройти певне голосування, знайдений певний консенсус з великою кількістю учасників мережі. А точніше 51 плюс учасник мережі має повигодити, що так, дійсно, ці дані, я вважаю, коректними, їх можна додати в блокчейн.
Цих степів якраз супер показують. Умовний еліс хоче відправити Бобу певні токени, якусь транзакцію виконати. Вона закручується, випадає в блок, цей блок розкидається на всіх учасників мережі. Вони підтверджують цю транзакцію, і після цього, як вони підтвердили, вона додається в нашу ципочку. І вже наступні учасники комунікації цієї мережі зможуть побачити цю транзакцію, що хтось комусь відправив кошти на своїх машинах, на своїх клієнтах. І приблизно внутрішній світ одного блоку виглядає приблизно так. Є номер блоку, є хеш конкретного блоку, є його parent. Ми можемо пройти всю ципочку, тобто це такий двонаправлений список, можна так навіть сказати, і ми можемо рухатися по цьому списку, дивитися, що відбувається.
І в ньому відбуваються якісь екстринзики, якісь дані, якісь функції виконуються. І ці функції, результатом функції є івенти, які кидаються при уразі успішного, неуспішного виконання і показують взагалі, які частини блокчейна були задіяні. І перше, коли виникає питання, як працювати з блокчейном, перше, що потрібно зробити, це підключитися до нього, це якийсь сервер. І структурка блокчейна, це трохи складніше, ніж просто сервер. Вона складається з декількох компонент, і основна частина цих компонент – це валідатори. Це валідатори або майнери, які ініціалізують нові блоки, вони їх продюсять, вони перевіряють, що дійсно всі дані, які попали в блокчейн, є коректні, ніхто їх не спробував підробити, всі знаходять консенсус і зберігають їх.
Є частина так званого архіву, який зберігає повну цепочку блоків, тобто повний ланцюжок, який архівом можна ітеруватися. Не всі блокчейни мають їх, але в більшості блокчейн, з яким ви будете працювати, це умовне Ethereum, це існує. І сама відома частина – RPC, ми це бачимо і в звичайному веб-2 світі бекендів, це просто сервіс, який об'єднує комунікацію між клієнтом, вами, користувачем, чи якоюсь додатком, і валідаторами, архівами, щоб через нього можна було відправляти дані якісь і отримувати їх з блокчейна.
І він зазвичай максимально оптимізований, він максимально легко, небагато важить і зберігає лише в собі останніх 200-300 блоків блокчейну, а не весь стейт, який назбирався за 5-10 років функціонування мережі. Тобто вони досить легкі. І перший спосіб комунікації – це використовуючи типічні, всім відомі нам протоколи, HTTP і TCP, огорнутий вебсокіт зазвичай, для того, щоб комунікувати з RPC-нодами. І якщо можна побачити, найпростіший спосіб – викликати курл, прост запит, в якому будується наш JSON-RPC, з якимось конкретним методом, і це вертає нам якийсь респонс. Але з'являється з часом питання, коли нам потрібні якісь параметризовані стейти, ми щось витягуємо параметризовано, і потрібно працювати з параметрами. Параметри в блокчейні дуже часто хешуються, адже блокчейн сам по собі використовує велику кількість криптографій і хешувань для того, щоб максимально оптимально і надійно зберігати ці дані.
І для найшвидшої дії, IPI блокчейна підтримує лише вже готові захешовані дані в тому вигляді, в якому він може просто звернутися до своєї бази і дати вам якийсь результат. І постає питання в тому, що, блін, це потрібно якось комунікувати, якось конвертити дані на фронтенді. І, звісно ж, жоден фронтендер не сильно хоче розбиратися в тому, як працюють хешування самого блокчейна. Тому було створено вже багато готових SDK, які роблять цю роботу за вас. І перша робота, яку SDK може робити за вас, це заврапувати сам запит, по типу, як ми робимо курл, чи як Axios робить з нашими звичайними HTTP-реквестами. Те саме, наприклад, ця бібліотека Polkadot API робить з нашим блокчейном. Ми підключаємося, чекаємо провайдера, ініціалізацію, і потім відправляємо реквести.
Але тут ми ще маємо хешувати дані самостійно. А потім ми використовуємо, беремо, переходимо на якусь більш високу бібліотеку, по типу, WebSuite.js – це найпопулярніша бібліотека в ефіріум світі, якщо хтось чув. Це другі по популярності блокчейн, які є відомі. І тут набагато все простіше. В нас вже є чіткі звичайні методи, які ми звикли бачити в JavaScript, в скрипті, в GetBalance, передаємо адресу, отримуємо в результаті бікнабер. До речі, цікавий аргумент, блокчейн не працює з слотами. Там дуже рідко можна зустріти числа з плаваючої точки, як в принципі і в банківських системах. Тому що плаваючі точки, вони дають нам похибку, і це неприпустимо, коли ми працюємо з якимись монетами, токенами, чи банківськими операціями. І з часом блокчейн все еволюціонує і ми доходимо до того, що з'являються максимально високорівнові бібліотеки, які дають нам можливість не мислити, як це під капотом працює, а використовувати блокчейн, як Twitter API чи Google API, де ми би скачали бібліотеку, дали вхідні дані, і витягуємо якісь ентиті, які нам потрібні в блокчейні. До речі, цей API ми будемо сьогодні використовувати саме для того, щоб витягувати пости в блокчейні, це є наші меседжі, нашого чату. Наступна частина, що ми робимо з блокчейном, це ключі.
Адже кожен блокчейн працює на асиметричному шифруванні, де ми маємо ключ-пару з публічного та приватного ключа, за допомогою якого ми відправляємо транзакції в блокчейн, з ним комунікуємо, достаємо дані з блокчейну, відправляємо і тому подібне. Тут трішечки потрібно розібратися в тому, що в нас взагалі за що відповідає. Публічний ключ – це наш ідентифікатор в мережі, це як, не знаю, юзер-айді, юзер-нейм в наших звичайних бекендах. Його можна безпечно передавати комусь, це фактично як номер вашої банківської карти, умовно, без всіх інших частинок. І за допомогою нього можна валідувати підпис, який генерується за допомогою нашого приватного ключа, який зберігається, в свою чергу, у вас на вашій стороні, ніхто, крім вас, його не повинен знати, а якщо хтось знає про нього, це вважайте, він знає всі дані вашої банківського рахунку, банківської карти і так далі.
І за допомогою приватного ключа ви підписуєте транзакцію, створюєте цей криптографічний proof of identity, і блокчейн, чи будь-який інший сервіс, може, за допомогою знаючи ваш публічний ключ, перевірити, що це дійсно ви поставили цей підпис. І тут є невеличка схемка. Найчастіше фронтенди комунікують з блокчейном і, використовуючи пабліки private key, двома способами. Перший – це за допомогою гаманця, це може бути метамаск в вашому браузерній екстенсіон, це може бути умовно леджер, флешечка якась, яка підключається до вашого девайсу.
Користувач заходить в аплікейшн, щось починає робити, хоче відправити транзакцію в блокчейн, фронтенд запитує підписання в валета, користувач проактивно погоджується, що так потрібно, я підписую, можливо вводить пароль в залежності від гаманця, і тепер ця підписана транзакція в фронтенд нам відправляється. Тобто фронтенд не знає нічого про ваші ключі, він просто питає в якогось все делегованого сервісу, який виконує це за нього.
А друга частина – це коли фронтенд знає ваш ключ, ви маєте тоді довіряти безумовно самому вашому фронтенду, адже ключ зберігається в local storage, в local db, може бути зашифрований, не зашифрований, це вже питання інше. Але суть в тому, що фронтенд без вашого, по факту, може вас не запитувати і підписувати дії за вас, так як він знає ваш правіткий, і може ним взаємодіяти з мережою майже без вашого відому, але зазвичай, якщо ви довіряєте, і цей аплікейшн не є якимось камом, він запитує ваші дії і комунікує з вами, що там відбувається з вашим ключем.
І коротко, як можна описати блокчейн зараз? Це не біткоін, в якому є взагалі тільки одна функція трансфера, і немає навіть можливості відкрити чітко конкретний блок, а лише пройти повністю цепочку і зберегти її в якомусь позгарсі. Зараз це ефіріум чи палькадот чи будь-які великі такі популярні блокчейни, які можна знайти в топ-10 часто, можна їх назвати таким блокчейном, що це лего, але він має комісію. Ця комісія – це основна особливість блокчейну, яка відрізняє його від якихось публічних API, які існують. В тому плані, що ви можете без проблем взаємодіяти з блокчейном, відправляти в нього будь-які дані, ніхто вам цього не може заборонити, він абсолютно публічний, ви можете зібрати свій конструктор лего, побудувати якусь свій аплікейшн.
Часто в блокчейнах є готові вже модулі, як, наприклад, ми сьогодні будемо розглядати блокчейн, в якому вже готові модулі для побудови будь-яких соціальних мереж. Маються пости, коментарі, підписки, юзернейми, профайли, реакції. Але для того, щоб записати щось в блокчейн, вам потрібно потратити комісію, заплатити щось частинкою свого токена, який має бути на вашому балансі, на вашого гаманця.
Або ж ви, як розробник аплікейшн, маєте якось вивернутися для того, щоб ваш користувач безкоштовно користувався, але ви сплачували цю комісію в блокчейн за кожну його дію. Це вже питання, яке ми, якраз, будемо розглядати. Але в загальному потрібно розуміти, що будь-яка транзакція в блокчейн – це певна комісія, яку ви сплачуєте. Це якби в банку кожна дія, яку ви там… Кожен переказ має комісію, наприклад. Ось це щось подібне, але для всіх задач, чи це буде переказ, чи це буде лайк, чи це буде коментар – немає різниці. І перш, ніж починати, ще перебіжемо трішечки з розуміння базових концепцій Next.js. І тут невеличкий дисклеймер, що я розглядаю стабільну версію Next.js, тому що зараз трішечки там розробляється бетка, яка зміни трохи структуру проекту, але основні концепції, які ми сьогодні проговоримо, залишаються тими самими, тому що це є основа на Next.js як такого.
І перше, про що я хочу поговорити – це рендери, типи рендерів, і в React, в Next.js їх цілих по факту чотири. Саме перший – це те, що ми і так добре знаємо, це client-side render, будь-який SPA, там React побудований через Create React App, має цей тип рендеру, де просто JavaScript бандл виправляється на frontend, повністю ініціалізує все, починає підгружати дані на frontend, рендерити під кожного користувача. І він, в принципі, працює, але люди звертаються до Next.js, в першу чергу, коли хочуть мати щось інше. Наприклад, потрібна швидша віддача якогось контенту на сторінці, чи потрібна SEO-оптимізація для того, щоб пошукуваки краще видавали контент для ваших сервісів.
Тоді приходить на допомогу SSR, Server-Side Render, який був задовго звинений до client-side, будь-яка сторінка, напевно, у 2090-х працювала через Server-Side Render, де якийсь PHP чи Java рендерувала вам еш-кімейль і відправляла його на frontend. І тут основна історія в тому, що якщо це динамічні якісь дані, які ви тягаєте з бази даних чи з блокчейну, як в нашому випадку, то кожен користувач запитує свої дані. Тобто під кожного користувача ми витягуємо конкретний масив даних, він може повторюватися, якщо ви відкриваєте одну ту саму сторінку якогось постачі, чату, але він підгружується для кожного окремо.
І так можна додавати кешування, але з кешуванням завжди є питання, коли його поновлювати і потрібно це починати менеджити, мислити, як ми будемо працювати з кешем. Тому Next.js пішов трішечки далі і досить недавно додавши так звану incremental static regeneration. Коли ми маємо статичний сайт, це як лендинг-пейдж через тільду зроблений чи через Webflow, який має повністю вже готові дані, які підгружені з блокчейну, вони підгружені раз, але він кожних 2, 3, 5, 10 секунд перепідгружає ці дані і зберігає в себе на бекенді готові статичні, і віддає фронту кожен кусочок вже готових даних. Це зменшує кількість, якщо у вас велика кількість користувачів, це зменшує кількість звернень до блокчейна, і блокчейн і бекенд сам це все валідує на своїй стороні. Це основна те, за що я особисто люблю Next.js, адже він дає можливість дуже легко це побудувати. Ми там переконаємося вже під час частинок з кодом розробки.
Друга частина – це добра задефайнена структура. Як і більшість фреймворків, таких високорівневих, він диктує свої правила, свою структуру, і якщо ви нею керуєтеся, він вас нагороджує своїми всіма плюшками, бенефітами. Перший – це динамічний роутінг. Коли вам не потрібно прописувати свої роути, придумувати їх, а по факту, як ви поклали дані в вашу папку Pages, такий роут вона має. Якщо це API слешт Create User, то по такому роуту ви можете до нього звертатись. Якщо там Space ID – це статичний, можна побудувати статичний, і буде звертатися ця сторіночка, наприклад.
І тут є ще одна класна штука, як Main Wrapper для всього аплікейшена, який врапає кожну частину коду, яка буде однакова для всіх-всіх сторінок вашого аплікейшена. Це можуть бути якісь там конфіги теми, Redux провайдер умовно, підключення якісь скрипти, і там хедер, що в душа забажає. І він буде рендеритись на кожній сторінці, він підгрузується по факту раз, коли ви відкрили сторінку, і коли ви бігаєте по сторінках, він не перепідгружається, а лише на клієнті рендериться лише та частина сторінки, яка змінюється. Це ще одна по факту класна особливість Next, що він дає оцей гібридний ререндер, коли ви маєте частину, прийняту з бекенду, частина на клієнті, і він сам розрулює, коли що потрібно обновляти.
Також недавно вони завезли з коробки оптимізацію картинок, досить недавно, півтори, напевно, роки назад. Дуже коротко, не хочу на цьому зупинятися. Всі проблеми, які ми маємо з картинками, по типу вона в нас важить 2 мегабайта, я її рендерюю як аватарку, мені потрібно якось зменшувати її розмір, в мене пригає лейаут, тому що картинка підгружається з часом, я не хочу підгружати картинку, поки я до неї не доскролив. Всі ці історії заврапує Next.js компонента images, яка з коробки йде, і це все вона робить через свій бекенд, робить свою магію, і ви вже не переймаєтесь про те, як мені оптимально, правильно працювати з картинками. Просто використовуєте там, де треба, які картинки вам потрібні.
І ще одне останнє частинка, подібне до App.js, мейн врапера, лейаути, які дають можливість використовувати частини коду, готові для багатьох сторінок, але вони не обов'язкові, мають бути на кожній сторінці. Наприклад, хедер і футер. Футер може бути тільки на хомпеджі, хедер може бути на двох сторінках, і якщо ми заходимо на хомпедж і переходимо на chain list page, хедер не буде знову ререндеритися, він буде залишатися тим, яким він був на першій сторінці, що дає нам перевагу в оптимізації швидкості рендеру. Це основні штуки, які я хотів розказати по фронтен-частині.
І ще є одна частина, за що я люблю App.js для невеличких педпроєктів, MVP-шок і подібних швидких, не суперважких штук – це опірувати. Це, по факту, свій бекенд всередині нашого Next.js аплікейшена. Він досить лімітований, але більшість задачок, які вам потрібно, він виконує. Вам потрібен Apollo сервер для GraphQL? Без питань. Потрібен якийсь rate limiter для API? Окей. Чи, можливо, вам потрібно працювати з куками, корсами? Це також все досить легко працюється. Я вже не говорю про базу даних, блокчейн і подібні речі. Це все дуже просто. Але якщо ви хочете вже якийсь виїзд складніший, там, мідлварів накидати, якісь у вас мають бути додаткові обробники подій і так далі, це вже буде трошечки важче. І можна будувати свій кастомний сервер для Next.js. Але я особисто, якщо я вже розумію, що мені потрібно щось складне, я беру Next.js і будую свій чистий окремий backend, з яким я вже просто підключаю Next.js-овську front-end частину і не знаю горя. І тепер переходимо до частини девелопменту. У нас сьогодні stack. Я взяв SVR для того, щоб кишувати запити, які ми будемо брати з блокчейну. TypeScript, тому що без нього мені… Бо працювати з блокчейною насправді трошки хардово, тому що він часто змінюється. Це штука, яка реально оновлюється. Додаються нові ті ж бібліотеки, часто-часто додають нові якісь типи, додають якісь конвертори і так далі. І без TypeScript досить важко підтримувати це особисто мені.
Tailwind для того, щоб не сильно запарюватися над CSS, який, коли мене представляли, сказали, що я не дуже люблю. Ну і Subsource SDK – це як SDK, верховий, high-level SDK для нашого якраз комунікації з блокчейном. Фулл репозиторій з кодом ви можете побачити по цьому скріншоті, або ж перейти за olehmelsubid, і це редірект на мій GitHub. Там в запінених перший є Decentralized Chat репозиторій. Ви можете його відкрити, форкнути, підняти. Там є врідві інструкції, яку ви можете потикати, щоб це все пощупати ручками в майбутньому.
І починаємо. Першим ділом, тут не буде прям лайфкодингу, ми пробіжимося по основних частинах коду, вони дуже маленькі. Я прибрав всю частину реактовську, більше концентруємося на частину комунікації з блокчейном. І перше, що нам потрібно зробити в чаті, це підключитися до самого нашого блокчейну. І в нас є функція create, і буде init, можливо, в іншій бібліотеці, чи просто в конструктор буде передаватися параметр. Але в загальному це передача трьох стрінгів, які під капотом отримують з'єднання.
І також тут ми бачимо таку штучку, як IPFS. Зустрічається, це не є частина блокчейна, це окрема файлова система, також децентралізована файлова система, яка будується на основі хешів, і кожен контент – це унікальний хеш, який зберігається в кучі нод, щось по типу торрента. І її часто блокчейни використовують для зберігання великого контенту, по типу картинка, відео, чи велика стаття, загружена в блокчейн, буде вартувати вам тисячі доларів. IPFS – це, як звичайна файлова система, буде вартувати долі центів, чи там цент, чи долари, якщо це якісь гіабайти даних. І води вже потребують часто авторизації, це просто на кійпейері ми вже не вийдемо. І зазвичай це звичайний там Basic, чи Bayer токен, чи там JVT, з звичайним хедером, який ми використовуємо часто для типічних backend сервісів. І підключилися, отримали API, написали там якесь його кешування, якщо потрібно, і далі нас ставить питання, як нам зафетчити наш блокчейн, зафетчити наші дані. І тут ми хочемо побачити щось типу такого, нашого чатику, в якому є дані з блокчейну, там ми їх якось зафетчимо. І тут постає питання.
Підключаємося до блокчейну, у нас є GetSocial API, в ньому витягуємо Substrate API, тут це низькорівневий API, так званий, тут, як я на початку показував, FinePost, це така вже врапнута система зверху, але для того, щоб достати, наприклад, ID-шники, нам потрібно доставати це через трошки більш низькорівневу частину бібліотеки. І ми підписуємося по Channel ID, пропередаємо колбек для нашої підписки, вертаються нам ID-шники, і тут трішечки в нас герязноти є, SN. Така проблема, що блокчейни оперують з своїми типами даних, якщо це ID-шники, зазвичай це U64, це може бути там I32, може бути ще щось. І в JavaScript досить важко їх розуміти, бібліотеки дають якісь там тип-варіанти конвертації часто, але ми не можемо чітко, нам тут по факту ручками потрібно прописувати, що ми там очікуємо.
Так, ми можемо додавати валідації, перевіряти, що дійсно типи сходяться і так далі, теж як з звичайним API, коли ми отримуємо JSON і точно не впевнені, що це за строки. Ось тут так само, якщо ми робимо там TrueToPermit, це по факту масив якихось стрінгів, і тут можна було б накидати валідацію, але ми це опускаємо. І відбувається мутація цього нашої бібліотеки SVR, але ми її саме тут не хочемо розглядати. Кому буде більш цікаво побачити код, я буду в Дискорді, зашарю вам скриншер, там буде трошки більше часу на це. І ми робимо звичайну підписку в UseEffect, в якій в нас є callback, є якась функція мутації, яка зверху приходить до нас, і ми слухаємо по факту блокчейн, кожен блок, якщо з'являється новий ID по цьому каналу, наш масив оновлюється, і ми його з нуля записуємо в наш кеш, по факту. Ну і, звісно, не треба забувати про Unsubscribe. Наступна частина, тобто, окей, ми підключилися, ми достали дані, а нам тепер потрібно логінитися. І, як ми на самому початку спілкувалися, два типи є варіанти логіну – з Wallet або з беріганням даних в базі даних.
Якщо це Wallet, то зазвичай в нас є бібліотека екстеншена, це може бути MetaMask, це може бути полька дотпл екстеншендап, який дає доступ, по факту, до всіх екстеншенів, які підтримують цей стандарт, які реалізовують цей стандарт. І тут в нас є WebTreeEnable, ми аненіціалізуємо, достаємо, інжектуємося до екстеншенів, перевіряємо, що їх дійсно, що їх не пусто, і тоді по аккаунт-гайді, який ми там зберігали, наприклад, в LocalStorage, намагаємося достати з Wallet наш інстанс, який буде потім підписувати наші транзакції, тому що ми підписуємо, кожна транзакція підписується, тобто Entity, яка підписує, це Signer. Ось також тут можна було би достати дані не по аккаунту, а витягнути всі і дати людині вибрати, з якого їй потрібно залогінитися. Також це працює саме через екстеншен. Друга частина – це коли ви самі генеруєте якийсь аккаунт, для користувача під капотом, і менеджуєте його, чи він вам дає свій сіт, свій приватний ключ, і ви ним вже оперуєте.
І для генерації теж є окремі так звані кейрінги, це ліби криптографічні, які дозволяють вам побудувати цю ключ-пару. Основна тут історія в тому, що ви генеруєте мнемоніку. Мнемоніка – це таке текстове представлення вашого приватного ключа, тому що приватний ключ – це, зазвичай, набір байтів. А для того, щоб зручніше його було запам'ятовувати, навіть на кусочок бумажки в банківську ячейку, чи якось виграювати десь, так часто зберігали біткоїни, зараз трошки, напевно, не той час, але також, то простіше працювати з текстовими словами англійського алфавиту, а не записувати хекс, де ви можете провтекати якийсь один байтик, щось зробити не так, і втратити весь свій приватний ключ.
Але слід не забувати, що блокчейн не знає, він не вміє там реклімітити, він знає, що є якийсь аккаунт, ви його зігнорували, і ви можете відправляти скільки завгодно даних, поки у вас не закінчуться кошти. І зазвичай, якщо ви хочете спонсорувати вашого користувача, тобто, що не він буде витрачати кошти, а ви, і ви керуєте цим, то цей анонімний користувач, для якого ви створили цю пневмоніку, він може бути будь-кем, це може бути якийсь зловмисник, чи спамер, що хоче просто там нашкодити вашій аплікаційні.
І якщо ви самі вже вирішуєте спонсорувати когось в блокчейні, тоді вам потрібно мати якийсь захист. Як мінімум, це має бути капча в коді вихідному, капча якраз піднята. Це може бути млрф верифікація, це може бути там діскорд, твіттер, не знаю, щоб вони підтвердили якоїсь своєї ідентиті, яку важче підробити, ніж просто новий блокчейн-ключ, який по факту генерується за декілька секунд вашого часу. І якщо ви вже перевірите своєго користувача, він згенерував ключ, ви знаєте його публічний чи навіть приватний ключ, вам потрібно його якось заспонсорувати.
І зазвичай блокчейни мають layer 2 так звані рішення, які дають можливість спонсорувати. Це може бути смарт-контракт, який спонсорує з вашого аккаунту. Це може бути якось тут у нас система енергії, яка по факту ви спалюєте певну кількість токенів на користь конкретного аккаунта вашого користувача, і він дає йому енергію. Таку по факту ігрову валюту, блокчейнову валюту, це не токен, який можна там продати, перевезти комусь, а як якісь алмазики в веб-грі, в які ви можете використовувати їх як внутрішній ресурс.
І все, це внутрішній ресурс, який користувач максимум може або використати, або не використати. І від нічого з цього вже нікому не буде, він на цьому не навариться, нічого не станеться. І ви його генеруєте цьому адресу, цьому користувачу, підписуєте своїм якимось сайнером на бекенді, наприклад, і обов'язково, щоб в кожній транзакції є така частина як нанс, адже в блокчейні все публічно, і підпис, який ми бачили, наприклад, тут, а ми тут його не бачили, підпис цієї транзакції, наприклад, CreatePost, він може бути однаковий, якщо там, ну ладно, не Create, а там Like. Якщо лайкаєш пост, тебе ID-шник посту той самий, ти той самий, і по факту криптографія тобі генерує однаковий підпис.
І для того, щоб цей однаковий підпис не можна було просто взяти і вдавати, що це ти якомусь зловмиснику, додається нанс, це криптографія, це не так блокчейнська криптографія, додається до кожної транзакції нанс, він інкрементний, і зберігається в блокчейні, що цей аккаунт вже виконав стільки дій. І коли твій нанс старий, коли хтось там транзакцію з нансом цим сформувався і не відправилося, чи хтось там знайшов і хоче її відправити, то блокчейн просто її відхилить, тому що нанс вже менший, ніж той, що в тебе зараз, і в тебе просто слешне. Це також один з ще частинок захистів, і його є така невеличка коварність, що його потрібно оновлювати.
Наприклад, тут ця бібліотека дає можливість нам оновлювати, автоматично резолвувати нанс, якщо поставити мінус один. Незавжди це відбувається так, і деякі інші бібліотеки, той саме Web3, коли відправляють транзакції, вам потрібно думати про нанс вашого аккаунту, його достати з блокчейну, вкласти в транзакцію. І найбільша проблемка, з'являється, коли вам потрібно багато транзакцій один за одним відправити.
Наприклад, коли ви відправляєте, ми любимо в мовному телеграмі відправляти меседжі не одним довгим лонгрідом, а по 10-15 маленьких меседжів. Я так не люблю, якщо за мною комунікуєте, не робіть такого, але так робиться, і в блокчейні, по факту, кожна ця транзакція – це новий нанс, і вам потрібно робити якусь на чергу, на стороні клієнта, який би сам інкрементив ці нанси, адже блокчейн має час блоку, і якщо ви написали 10 меседжів за 2 секунди, а блокчейн – 6 секунд чи 30 секунд, як в Ефіріума, то ваш нанс обновиться лише, коли цей блок закінчиться, коли блокчейн сам буде знати.
І вам потрібно якось на клієнті це самостійно вже зберігати. Але в нашому випадку, в той чад, який ми робимо, бібліотека вміє автоматично резолвувати це на своїй стороні. І останнє таке найбільш основне – це відправка меседжу. Ми меседж рендеримо, ми можемо залогінитися, розгологінитися, залогінитися з нового аккаунту, як бачимо тут інші аккаунти генеруються. Цей генерований аккаунт – це пустишка, по факту, я його можу генерувати безліч, він нічого себе поки не представляє, поки на нього не впали якісь токени. А токени в нас падають, коли ми починаємо відправляти якийсь один, відправляємо хоча б один меседж.У нас тут є, наприклад, можу ще показати те, що в нас... О, у нас тут, бачте, Капча. У нас Капча, яка відправляє цей меседж, він відправлений, і наш клієнт, який також підключений до цієї, це наш один клієнт, це також мій маленький код, він також підтягує цей меседж. І тепер ми хотіли би ще його відрендерити. У нас якраз трішечки часу. Тут все досить просто.
Також ми витягуємо для транзакції, як ми вже робили з енергією, генеруємо поста. По RAM сидимо, в нашій документації, найчастіше це документація. Ось тут можна, так, в нас є Space ID, Extension, Content, тут розписується, що це. Будь-який блокчейн має досить непогану документацію, бо без документації блокчейн, вважайте, мертвий, бо до нього ніхто не хоче будувати. Але в нас також тут є така сторона, знову ж таки, як IPFS, і в нього цей контент зберігається, як я казав, що ми зберігаємо меседж в IPFS, вертається нам IDшнік цього IPFS, це хеш, який потім передається. Ось тут такий в нас є врапер, передається в нашу транзакцію. І наша транзакція, по факту, має цей хеш блокчейновий, як окремий набір байтів.
І на цьому, по факту, транзакція вважається виконана, і вона відправляється, але якщо є фі. Тобто нам не потрібно забувати, що користувач, чи це ви, чи це ваш юзер, має мати фі, і вам її потрібно якось генерувати, чи спонсорувати. Останнє, ми відправили, все супер, але наш чат чомусь грузиться довго. Він з підгрузкою може крутитися, тому що він на клієнті достається. Давайте оптимізовувати його. І за що ми любимо NGS? Тому що ми пишемо функцію, яка, по факту, генерує цей... По факту, оптимізація наш SSR-рендеринг, бекендовий, виглядає приблизно так. У нас є функція, яка підгружає дані, ми передаємо це в бекендові пропси функції, і на фронтенді вже в апі цю пропсу достаємо і передаємо, тут ми передаємо наш конфіг, це, по факту, кишує ці дані. Це може бути пропса на конкретну сторінку. Це просто якийсь набір даних, який ви передаєте. І це наш сервер-сайт пропси, ми кожен раз їх підгружаємо для кожного клієнта. А це вже наші статичні пропси з ревалідацією в кожні 2 секунди. Різниця буквально в назві і в одній строчці коду. І це самим DexJS дуже класний, що він дає дуже швидко вам використовувати той варіант рендеру, який вам потрібний для цієї сторінки. Якщо вам потрібен динамічний рендер, не питання.
Якщо вам потрібно відобразити якусь сторінку швидко, без проблем. Якщо вам взагалі статична сторінка, то окей. Тобто ви підбираєте під кожну сторінку свій тип, і вам не потрібно реалізовувати 4 різних варіантів у себе, якомусь там SPI-додатку. Тому в таких кейсах, коли вам потрібно використовувати силу різних, найкраще, як на мене, використовувати DexJS. І тут ще така частинка є стосовно того, що передача даних різні бібліотеки, по-різному їх хочуть передавати. Якщо ви з бекенду передаєте просто до себе в компоненту, ви самі вирішуєте. Якщо це умовний редакс, чи я використовую SVR, він хоче якусь серіалізацію даних, для того, щоб їх потрібно перенести на бекенд, і з бекенду на фронтенд, і потім знову ж таки розпарсити, занести в стор якийсь, і для того, щоб клієнт міг нормально з ними комунікувати. То тут знову ж таки це як окремий пункт в документаціях зазвичай, про серіалізацію цих даних. Як ми використовуємо SVR, тут ми витягуємо дані з блокчейну, потім збираємо це в такий record, це функція з бібліотеки, яка будує по факту по ключу складному, зберігає наш об'єкт. І це все ми передаємо фолдбеком, і тут цей фолдбек передається в наш конфіг. По факту на цьому все. Знову ж таки код ви можете подивитися, якщо вам цікаво спілкуватися зі мною, можна знайти мене в телеграмі, ну і GitHub також є. І тепер я очікую якийсь питанічок, якщо вони є, задавайте.