Web3 реги и как они работают
December 6th, 2022

Всем привет!

В этой статье разберем принципы работы регистраций на веб3 сайтах.
В мире веб3 существует несколько способов authenticaton на странице

  1. Как у 1inch - веб приложение выступает чисто интерфейсом для работы с контрактом DEXa и ничего не хранит на серверах

  2. Как у opensea - веб приложение 50/50 на веб3, потому что некоторые моменты хранятся на серверах, а остальное в блокчене

  3. Как у Дегенскана - веб приложение с подключением кошелька, но вся работа с блокчейнами происходит на бэкэнде

Давайте разберёмся, как сделать authentication в каждом случае.
1. КАК У 1inch
Существует куча различный гайдов по тому, как добавить в свое приложение кнопку "connect wallet", поэтому не буду заострять внимание на этом. Просто в общих чертах опишу, как это работает.

ШАГ 1 - Создаем файл index.html, туда добавляем кнопку "connect wallet" и подключаем наш будущий файл script.js

ШАГ 2 - Делаем файл script.js, вешаем события на кнопки и используем чудесный API метамаска

Прелесть тут в том, что не нужно не нужно импортировать сторонние библиотеки.

А теперь подробнее.

window.ethereum - возвращает объект, если у пользователя установлено расширение метамаска, если его нет, то возвращается undefined.

await ethereum.request({ method: 'eth_requestAccounts' }); - тут мы асинхронно запрашиваем у пользователя кошельки, чтобы подключится к веб-приложению.

ethereum.selectedAddress - хранит массив подключенных адресов. Берем [0] элемент и получаем выбранный адрес, если он один, если много, то можем брать любой

Ура! Мы знаем адрес пользователя и можем делать запросы на отправление транзакций и т.п., а в метамаске теперь написано "подключено"

Теперь нам достаточно создать объект transactionParameters, куда передадим от кого (from), куда (to) и сколько эфира отправить (value)

await ethereum.request({method: 'eth_sendTransaction', params [transactionParameters]}); - делаем еще один request и отправляем транзакцию

При нажатии на кнопку send мы можем делать что угодно, я прикрутил отправку эфиров ortomich.eth

Вот тут документация метамаск апи: https://docs.metamask.io/guide/

Тут неповторимий Патрик делает это на протяжении 10 часов: https://www.youtube.com/watch?v=pdsYCkUWrgQ&t=1406s

Тут про window.ethereum - https://eips.ethereum.org/EIPS/eip-1193

                                                       2. КАК У OPENSEA

На всем известной площадке используются такие штуки как ПОДПИСИ

В чем основные плюсы сигнатур (аkа подписей)

  1. Бесплатно

  2. Никто не подделает твою подпись (если только угонит приватный ключ

Они собственно и придуманы, чтобы подтверждать различные действия на сайте от вашего лица, не платя за газ

Как же их использовать, чтобы зайти на сайт, где нужно не только делать свапы, а еще добавлять в избранное и т.п.?

Вся логика основано на том факте, что кроме самого пользователя, никто не сгенерит уникальную сигнатуру

ШАГ 0 - Инициализируем проект качаем модули

ШАГ 1 - Делаем html + подключаем axios и ethers, чтобы слать запросы на сервер и взаимодействовать с блокчейном

ШАГ 2 - Запускаем чудо-сервер на node.js + нам понадобиться бд чтоб хранить пользователей, mongoDB = 1 love ^_^ У них красивый сайт))))))

Тут стандартные node.js штучки, ну и соответвенно делаем путь /login, чтобы куда-то слать наши подписи

ШАГ 3 - Делаем файл userModel - это чисто для БД, чтобы понимала, что от нее хотят, короче просто поля для бд. По сути нам достаточно хранить только кошелек, чтобы идентифицировать пользователя, но я еще добавил роль, потому что могу x2

ШАГ 4 - Делаем файл authController, там будет лежать логика для autentification на сервере

В нем у нас будет две функции login и signatureVerify, нетрудно догадаться что они делают

Далее в signatureVerify берем подпись, и сообщение, а чудо метод recover возвращает исходный адрес, что с этой информацией делать дальше догадаться несложно.

const signer = await web3.eth.accounts.recover(message, sign);
if (signer != address) {
  res.status(400).json({
    msg: 'error',
    data: 'Wrong signature',
  });
}

Простой if сделает все сам. Если все хорошо, то переходим в функции login

В функции login мы точно знаем, что пользователь "владеет этим кошельком", и используя его адрес мы либо создаем новый аккаунт, либо входим в уже существующий

const address = req.body.address;
let user = await User.findOne({ address }); //ищем в бд
let dbMsg;
if (!user) {
  user = await User.create({ address: address });//создаем пользователя
  dbMsg = `new user ${address}`;
} else {
  dbMsg = `user exist`;//просто выводим
}

ШАГ 5 - Чтобы сделать модное сообщение для подписания как у опенси...

....просто генерируем случайную строку в hex формате

const genRanHex = (size) =>
  [...Array(size)]
    .map(() => Math.floor(Math.random() * 16).toString(16))
    .join('');
const nonce = genRanHex(32);
const message = `Welcome to OpenSea!\n\nClick to sign in and accept the OpenSea Terms of Service: https://opensea.io/tos\n\nThis request will not trigger a blockchain transaction or cost any gas fees.\n\nYour authentication status will reset after 24 hours.\n\nWallet address:\n${ethereum.selectedAddress}\n\nNonce:\n${nonce}`;

Зачем это нужно

Как можно в теории угнать логин? (Представим мир, где на опенси в подписи текст "1234", и с помощью подписи можно отправить все нфт любому человеку)

  1. Негодяи знают, что на опенси подпись "1234", и делают сайт с такой же подписью

  2. Вы каким-то образом туда заходите, и подписываете сообщение "1234"

  3. Негодяи теперь знают, ваш адрес и подпись сообщения "1234"

  4. Они идут на опенси и заходят под вашим логином

НО!

В реальном мире они максимум уберут лайки с нфт, так что бояться не стоит, но на всякий случай, если будете делать какой-то проект, то имейте это ввиду

Опенси раз в 24 часа просит вас подписать подобное сообщение, чтобы обновить данные и лишить хлеба негодяев

Тут доки ethers - https://docs.ethers.io/v5/

Тут можно поиграться с подписями - https://etherscan.io/verifiedSignatures#

Тут проект, который тоже использует подписи - https://snapshot.org/

Тут как работают сигнатуры - https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm

                                                  КАК У ДЕГЕНСКАНА

Тут основная логика в том, что не нужны особо взаимодействия с блокчейном, поэтому работает золотое правило web3 Если можно не использовать блокчейн, то мы им и не пользуемся Поэтому когда мы нажимаем "connect wallet" и подписываем сообщение, идет запрос на их сервер, где передается просто сигнатура

И получаем такой ответ, у меня нет подписки, поэтому тут false

Делаем вывод из этого, что когда вы делаете подпись, она отправляется на сервер, и там просто проверяется, нет ли у этого пользователя доступа к дегенскану или админке. Все просто и лаконично

Subscribe to Elez
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.
More from Elez

Skeleton

Skeleton

Skeleton