Оглавление
Данная методичка предназначена, в первую очередь, для крипто энтузиастов, которые хотят научиться разбираться в том крипто мире, в котором они находятся, но при этом не обладают глубокими знаниями о протоколах, внутреннем устройстве блокчейнов и т.д.
Поэтому в данной работе многие понятия сознательно сокращены (впрочем без потери их адекватности и применимости) для лучшего усвоения материала без излишних технических подробностей.
Основы мира defi
Смарт-контракты
- Смарт-контракт это программный код, который выполняется на нодах блокчейна, а результат выполнения (если это прописано в программе) сохраняется в блокчейне в специальном хранилище. Назовем данные, сохраняемые в блокчейне – персистент данными.
- Код смарт-контракта после заливки в блокчейн дополнительно заливается сверху слоем эпоксидки, чтобы предотвратить любое случайное или намеренное изменение кода.
- Функции смарт контракта могут быть вызваны извне (с кошелька пользователя или из другого контракта) и делятся на две большие группы:
– Не меняющие состояние персистент данных (только чтение из блокчейна)
– Меняющие состояние персистент данных
Вызов функций первой группы не стоит газа и денег и не уходит дальше ближайшей ноды, к которой мы подцеплены (пример: Balance Of, TotalSupply, Allowance). В BSC scan эти функции перечислены во вкладке “READ”
Вызов функций второй группы превращается в полноценную транзакцию, которая майнится, включается в блок и результат которой записывается в блокчейн. (пример: Approve, Transfer, TransferFrom). В BSC scan эти функции перечислены во вкладке “WRITE”
Блокчейны состояния
- Etherium и блокчейны, построенные на его основе (Polygon/matic, BSC, и т.д.), относятся к блокчейнам состояния.
- Каждый адрес хранит в блокчейне значение своего баланса в нативной монете блокчейна (ETH, BNB, MATIC)
- Каждый смарт-контракт хранит в блокчейне значения своих персистент переменных
- На текущий момент времени (Блок Х) состояние блокчейна описывается балансом всех существующих адресов в сети и текущими значениями персистент переменных всех смарт-контрактов в блокчейне.
Аккаунты
- Сид-фраза (12 слов) которую вы записали при первом создании вашего кошелька, при помощи протокола BIP 39 превращается в приватный ключ, который при помощи алгоритма ECDSA (Elliptic Curve Digital Signature Algorithm) превращается в публичный ключ, который при помощи хеширования и обрезания превращается в ваш адрес в блокчейне. То есть:
Сид-Фраза -> Приватный ключ -> Публичный ключ -> Адрес
- И это превращение совершенно однозначное. Из одной и той же сид фразы вы всегда получите один и тот же адрес со своим балансом.
- Поэтому чтобы перенести свой аккаунт на другой кошелек (MetaMask, trust wallet, SafePal, Coin98. …) Вам всего лишь надо восстановить ваш аккаунт на новом кошельке используя сохраненную сид фразу.
- Отсюда следует, что сид фразу надо хранить как зеницу ока, поскольку она дает полный доступ к вашему аккаунту.
А где же наши токены?
- Для каждого аккаунта (адреса) в блокчейне хранится только баланс этого адреса в нативной монете блокчейна и все. А где же токены, которые мы купили?
- Баланс вашего адреса в каждом купленном токене хранится в смарт-контракте этого токена в таблице (условно) balances, состоящей из двух столбцов – адрес и его баланс в токенах.
В BSC scan эта таблица отображается на вкладке “HOLDERS”
- Именно поэтому чтобы баланс токена появился в вашем кошельке токен надо в него (кошелек) добавить. После добавления кошелек запрашивает смарт-контракт токена на предмет текущего баланса своего аккаунта и радостно отображает это в интерфейсе.
Один адрес – множество сетей
- Ethereum был первым блокчейн (спасибо Виталий!) построенным вокруг идеологии смарт-контрактов. Первым и настолько успешным, что породил множество клонов, различающихся между собой порой только алгоритмом консенсуса и стоимостью транзакций.
- Поэтому вы можете использовать (и используете) один и тот же адрес в сетях BSC, Polygon. Ethereum, и т.д. Когда вы находитесь внутри кошелька (хорошо что не чайника, да?) представьте что вы стоите на вокзале с билетом на поезд с номером 0хbc12….dd, вокруг вас множество дверей, на них написано Ethereum, BSC, Polygon,,, За дверями разные железные дороги и поезда, кто-то на угле, кто-то на ядерном реакторе, кого-то вообще еще лошади тянут. Но все они стоят на рельсах, везде есть локомотив и вагоны. И ваш билет всегда соответствует месту в одном из таких вагонов какую бы дверь вы ни открыли.
***
Итак:
- Ключом к вашему аккаунту является сид-фраза или секретный ключ, однозначно определяющая ваш адрес в сети и дающая полный доступ к аккаунту
- Ваш баланс какого-то токена лежит в смарт-контракте этого токена
- Вы можете использовать один адрес для всех Ethernet-based блокчейнов
- Смарт-Контракт это неизменяемая программа плюс изменяемые данные, которые хранятся в блокчейне
- У смарт-контракта есть две группы функций, которые можно вызвать извне – не изменяющие состояние блокчейна (READ) и изменяющие (WRITE)
Интерфейс ERC 20/BEP 20 как основа контракта токена, разбор функций контракта
Что такое Интерфейс
- Интерфейс – (грубо, но нам подойдет) это описание внешних воздействий (органов управления) каким-либо объектом и однозначных реакций объекта на это управление.
- Пример – вождение автомобиля. Интерфейсом является набор органов управления (руль, три педали, рычаг переключения передач) и описание однозначных реакций автомобиля на использование этих органов.
- Осознав этот интерфейс вы, с той или иной степенью успешности и эффективности, сможете управлять и Окой и Белазом.
Интерфейс ERC-20
- На текущий момент уже создано и каждый день создается множество токенов. Но с любым токеном мы можем взаимодействовать единообразно – пересылать, свапать, апрувить и т.д. За счет чего же достигается подобная унификация?
- Чтобы токен мог называться токеном, он должен “реализовывать” интерфейс ERC 20/BEP 20. Реализовывать означает, что смарт контракт токена должен содержать вполне определенный набор функций и параметров с однозначно прописанной реакцией (что смарт контракт должен сделать) на вызов каждой из этих функций.
Interface of the ERC20 standard as defined in the EIP.
FUNCTIONS
- totalSupply()
- balanceOf(account)
- transfer(recipient, amount)
- transferFrom(sender, recipient, amount)
- allowance(owner, spender)
- approve(spender, amount)
EVENTS
- Также не забываем, что при вызове каждой функции у нас незримо присутствуют еще два параметра (на самом деле их больше, но не будем усложнять):
msg.sender – адрес с которого прилетела транзакция (кто вызвал функцию)
msg.value – количество денег (нативных монет – ETH/BNB) пересланных с транзакцией
- EVENT – способ передать информацию из смарт-контракта наружу, в web3 программу, вызвавшую контракт. Как флажок о том, что выполнена такая-то операция. Подробно рассматривать не будем, просто запомните.
Описание функций ERC-20
Разобьем наши 6 функций на две группы:
Группа READ (только читаем из блокчейна):
- totalSupply() – возвращает общую эмиссию токена
- balance Of(account)– возвращает баланс адреса account
- allowance(owner, spender)– возвращает количество токенов, которое owner разрешил списать со своего аккаунта spender (см также approve)
Группа WRITE (меняем состояние блокчейна):
- transfer(recipient, amount)– передает amount токенов от msg.sender к recipient
- transferFrom(sender, recipient, amount)– передает amount токенов от sender к recipient
- approve(spender, amount)– выдает разрешение spender списать amount токенов с баланса msg.sender. (см также allowance)
***
- Существует стандарт ERC-20 описывающий интерфейс (функции, их параметры и возвращаемые значения), который должен реализовывать смарт-контракт, чтобы называться токеном.
- Если смарт-контракт реализует интерфейс ERC-20, то мы можем его использовать везде, где возможно использование токена – свапать его на dex, пересылать друг другу, сжигать и т.д. И совершенно неважно что на самом деле представляет собой этот контракт.
- Помните – если что-то выглядит как утка, ходит как утка и крякает как утка, то мы можем ее использовать как утку, КАКАЯ РАЗНИЦА ЧТО ЭТО ТАКОЕ НА САМОМ ДЕЛЕ )
Что происходит под капотом при работе с контрактом / Пример использования функций
Давайте рассмотрим на примере:
- Вася решает создать свой токен. Он берет самую стандартную реализацию ERC20, меняет название, количество (1000), прописывает что при создании контракта ему должны быть намечены (переданы) все 1000 токенов и деплоит смарт-контракт в блокчейн.
Смарт контракт выполняет функцию конструктора (специальная функция выполняющаяся один раз при деплое контракта), которая инициализирует внутренние переменные, в частности создает две пустые таблицы – balances и allowances, затем вызывает функцию mint, которая создает первую строчку в таблице balances:
Вася – 1000
И завершает работу. Контракт готов.
- Вася решает подарить своим друзьям Коле и Борису по 100 токенов
Кошелек Васи инициирует две транзакции к смарт-контракту токена: transfer(Коля, 100) и transfer(Борис, 100). В данном случае с кого надо списать монеты определяется тем, кто послал транзакцию, т.е. с баланса Васи (msg.sender, помните?).
Смарт-контракт просто меняет таблицу balances добавляя в нее две новые строчки и меняя сумму у Васи:
Вася – 800
Коля – 100
Борис – 100
- Вася решает вывести токен на биржу, для этого он идет на панкейк и создает пару ликвидности Token-BNB. (800 токенов – 2 BNB)
Панкейк роутер создает пару ликвидности, Вася заливает в нее 800 токенов и 2 BNB, в результате где-то в другой вселенной в контракте BNB появляется строчка CAKE-LP-Token – 2, а в контракте токена таблица balances теперь выглядит так:
Вася – 0
Коля – 100
Борис – 100
CAKE-LP-Token/Pancake Router – 800 (В BSC scan мы можем увидеть ликвидность в таблице holders)
* для простоты рассказа считаем, что Pancake Router и CAKE-LP-Token с точки зрения контракта токена это одно и то же. На самом деле нет, там все хитрее, но не будем усложнять, для наших целей такое упрощение вполне допустимо.
- Коля решает прикупить еще 100 токенов, он идет на Панкейк, говорит “Хочу купить 100 токенов за BNN, почем нынче овес?”
Панкейк рутер запрашивает у пары ликвидности текущий курс токена к BNB (по алгоритму AMM) и говорит Коле – Это будет тебе стоить 0.25 BNB + комиссия.
- Договорились, Коля отправляет Панкейку 0.25 BNB и ждет свои токены.
Панкейк рутер видит, что деньги пришли и создает транзакцию на смарт-контракт токена: transfer(Коля, 100) от имени LP пары.
Смарт контракт выполняет запрошенное, дебетуя счет пары и кредитуя счет Коли. В результате:
Вася – 0
Коля – 200
Борис – 100
CAKE-LP-Token – 700
Панкейк роутер отправляет 0.25 BNB на другой конец вселенной и на другом плече LP пары в контракте BNB значение баланса пары CAKE-LP-Token увеличивается с 2 до 2.25
- В это время Борис решает продать все токены и купить на все Binamon (БИНАМООН :). Он идет на панкейк и говорит: “Хочу продать 100 токенов, почем возьмешь?”
Панкейк рутер запрашивает у пары ликвидности текущий курс токена к BNB (по алгоритму AMM) и говорит Коле – Это будет тебе стоить 0.37 BNB + комиссия.
Одновременно с этим панкейк запрашивает у смарт-контракта токена а разрешил ли Борис ему(Панкейку) списывать токены со своего счета, для этого он запрашивает у смарт-контракта результат функции: allowance(Борис, Панкейк-рутер).
* Панкейк рутер вполне логично никому не доверяет, поэтому все транзакции списания денег происходят от его имени, именно поэтому смарт-контракту токена Борис должен сказать, что он доверяет Панкейку списать с его баланса токены.
Борис до этого ничего не продавал, результат выполнения функции = 0. Панкейк видит это и в интерфейсе свопа рисует для Бориса кнопку “APPROVE”.
- Борис нажимает на кнопку “APPROVE”
Кошелек Бориса инициирует транзакцию к смарт-контракту токена: approve(Панкейк-рутер, 99999999999999999), позволяя роутеру списывать со своего счета столько токенов, сколько ему (рутеру) надо.
* На самом деле правильнее было бы на каждую транзакцию давать разрешение только на сумму этой транзакции, но люди ленивые существа и поэтому обычно никто не заморачивается и в качестве количества разрешенных к списанию токенов ставит максимально возможное число. В нашем примере для простоты это много много 9-к.
Смарт-контракт токена выполняем операцию, добавляя в таблицу allowance строчку:
Борис – (Панкейк-рутер, 999999999) и генерирует событие Approval
Панкейк роутер видит это событие и перезапрашивает у смарт-контракта результат функции: allowance(Борис, Панкейк-рутер).
Если смарт-контракт возвращает 9999999999 и это значение больше или равно сумме текущей транзакции, то рутер убирает кнопку “APPROVE” из интерфейса и включает кнопку “SWAP”. Если возвращается 0, то кнопка “APPROVE” не исчезает, кнопка “SWAP” все еще неактивна.
- Борис нажимает на кнопку “SWAP”
Панкейк рутер дает команду BNB-шному плечу LP пары отправить 0.37 BNB Борису и создает транзакцию на смарт-контракт токена вызывая функцию transferFrom(Борис, Панкейк-рутер, 100)
Смарт-контракт проверяет наличие в таблице allowance строчки, разрешающей Панкейку списывать монеты с адреса Бориса, находит ее и выполняет операцию.
Таблица balances теперь имеет вид:
Вася – 0
Коля – 200
Борис – 0
CAKE-LP-Token – 800
- Все получилось, все довольны, все операции проведены, время пить кофе )
***
- Токены пересылаются с баланса отправителя транзакции (обычно это кошелек пользователя) на любой другой адрес с помощью функции transfer.
- Токены могут пересылаться с любого адреса на любой адрес, только если есть разрешение через функцию approve списывать деньги с адреса дебитора.
- Функция approve вызывается владельцем адреса, который выдает разрешение другому адресу списать токены с его баланса.
- Наличие разрешения можно посмотреть через функцию allowance.
- При любых трансферах токены просто переезжают из одной строчки таблицы balances в другую, никогда не покидая пределов своего смарт-контракта.
- Если вы хотите заранее апрувить продажу токена, вы заходите в смарт-контракт ТОКЕНА, вкладка WRITE, ищете там функцию APPROVE и вставляете адрес смарт-контракта РУТЕРА той свалки где хотите свапать. В нашем случае это адрес Панкейк-рутера: 0x10ED43C718714eb63d5aA57B78B54704E256024E
Разбор основных типов скама: рагпул, ханипот, свистоперделки. Где и как искать в контракте.
A) Рагпул – Ситуация, когда в токене на свалке внезапно (или очень быстро) исчезает вся ликвидность и вы остаетесь с кучей токенов, которые невозможно продать.
Заключение
В этой очень краткой методичке мы рассмотрели основополагающие вещи, касающиеся ваших аккаунтов, контрактов, увидели основные моменты взаимодействия между ними, а также изучили основные способы как НЕ влететь лицом в пол на первой же красной свече и потерять весь свой депозит из-за скама.
Настоятельно советуем пройти базовые курсы по программированию, чтобы уметь на минимальном уровне читать код контракта и понимать хотя бы примерно что тот или иной кусок кода делает.
Удачи!
- Учимся читать смарт контракты и обходить скам: Часть 1
- Расширенная работа со Смарт-контрактами. Основы языка “Solidity”. Учимся обходить скам: Часть 2
- Опасно ли аппрувить что-либо на PancakeSwap? Учимся обходить скам: Часть 3
- Трехуровневая схема работы DeFi или сам себе DApp. Учимся обходить скам: Часть 4
- Как хомяку выжить в DeFi? Учимся обходить скам: Часть 5