Учимся читать смарт контракты и обходить скам: Часть 1
Оглавление
1 Основы мира DeFi
2 Интерфейс ERC 20/BEP 20 как основа контракта токена, разбор функций контракта
3 Что происходит под капотом при работе с контрактом / Пример использования функций
4 Разбор основных типов скама: рагпул, ханипот, свистоперделки. Где и как искать в контракте.
5 Заключение
Данная методичка предназначена, в первую очередь, для крипто энтузиастов, которые хотят научиться разбираться в том крипто мире, в котором они находятся, но при этом не обладают глубокими знаниями о протоколах, внутреннем устройстве блокчейнов и т.д.
Поэтому в данной работе многие понятия сознательно сокращены (впрочем без потери их адекватности и применимости) для лучшего усвоения материала без излишних технических подробностей.
Основы мира 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
Transfer(from, to, value)
Approval(owner, spender, value)
Также не забываем, что при вызове каждой функции у нас незримо присутствуют еще два параметра (на самом деле их больше, но не будем усложнять):
msg.sender – адрес с которого прилетела транзакция (кто вызвал функцию)
msg.value – количество денег (нативных монет – ETH/BNB) пересланных с транзакцией
EVENT – способ передать информацию из смарт-контракта наружу, в web3 программу, вызвавшую контракт. Как флажок о том, что выполнена такая-то операция. Подробно рассматривать не будем, просто запомните.
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