зачем знать смарт-контракты??1⃣ Интеграция с Web3 - разработка ботов и софта, работающего с блокчейном (арбитражный бот, DEX-агрегатор).2⃣ Автоматизация финансов - создание контрактов для DeFi, лендинга, стейкинга, автоматических платежей.3⃣ Безопасность блокчейна - проверка и аудит смарт-контрактов (поиск уязвимостей, защита от взломов)4⃣ Доходы – Web3-разработчики зарабатывают $100k+ в год, а аудиторы контрактов $10k+ за проверку5⃣ Чтение ABI и взаимодействие с контрактами - анализируем чужие контракты, отправлять транзакции без UI и работаем напрямую с Etherscan, Infura, Alchemy.
ПОЭТОМУ СЕГОДНЯ РАЗБЕРЕМ!
Что такое ABI и зачем оно нада?📸
Как читать ABI, находить методы и отправлять транзакции через JS/TS
🤫 ABI (Application Binary Interface) - описание всех функций смарт-контракта, их аргументов и возвращаемых данных.
Без ABI мы не сможем вызвать методы контракта из кода
[
{
"constant": true,
"inputs": [{"name": "owner", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "", "type": "uint256"}],
"type": "function"
}
]
😭 balanceOf(address) - возвращает баланс указанного адреса.
inputs: owner (address) - принимает адрес кошелька.
outputs: uint256 - возвращает баланс в токенах.
Находим контракт на Etherscan
Contract - Read/Write
Скачать ABI - "Contract ABI"
Вставить в код для работы с контрактом
Структра Проекта👮♂️
npm install ethers dotenv
index.js - основной скрипт
.env для приватных данных
скрипт
import { ethers } from "ethers";
import as dotenv from "dotenv";
dotenv.config();
const provider = new ethers.JsonRpcProvider(
https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}
);
// адрес контракта USDT
const contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
// ABI для ERC-20
const abi = [
"function balanceOf(address owner) view returns (uint256)",
"function transfer(address to, uint256 amount)",
];
// объект контракта
const contract = new ethers.Contract(contractAddress, abi, provider);
async function getBalance(address) {
const balance = await contract.balanceOf(address);
console.log(💰 Баланс: ${ethers.formatUnits(balance, 6)} USDT);
}
getBalance("0xКошелек");🔫 Как?
Подключаемся к Ethereum через Infura
Находим контракт USDT по адресу
Вызываем balanceOf() и получает баланс
пример №следующий
Как читать переменные из контракта (name, symbol, totalSupply) - $USDC
// адрес контракта USDC
const contractAddress = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
// ABI с нужными методами
const abi = [
"function name() view returns (string)",
"function symbol() view returns (string)",
"function totalSupply() view returns (uint256)"
];
const contract = new ethers.Contract(contractAddress, abi, provider);
async function getContractInfo() {
const name = await contract.name();
const symbol = await contract.symbol();
const totalSupply = await contract.totalSupply();
console.log(📌 Токен: ${name} (${symbol}));
console.log(💰 Всего выпущено: ${ethers.formatUnits(totalSupply, 6)} ${symbol});
}
getContractInfo();
пример №ФИНАЛ
const provider = new ethers.WebSocketProvider(
wss://mainnet.infura.io/ws/v3/${process.env.INFURA_API_KEY}
);
// адрес USDC
const contractAddress = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
// ABI с событием Transfer
const abi = [
"event Transfer(address indexed from, address indexed to, uint256 value)"
];
const contract = new ethers.Contract(contractAddress, abi, provider);
// Подписка на события Transfer
contract.on("Transfer", (from, to, value) => {
console.log(🔄 Перевод: от ${from} → к ${to} на сумму ${ethers.formatUnits(value, 6)} USDC);
});
console.log("📡 Ожидание новых переводов USDC...");
БАЗА ВЫДАНА!! РАЗБЕРЕМ ПОДРОБНЕЕ ABI???
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤6🐳4💘1
Если ты хочешь отслеживать крупные сделки, мемпул или события контрактов в блокчейне, нужно использовать WebSocket (wss://)
🤨 Компоненты
npm install ethers dotenv
dotenv (.env файл) служит для приватных данных
INFURA_API_KEY=НАШ_INFURA_API_KEY
ethers.js - подключение к блокчейну
скрипт
Подключаемся к WebSocket ноде:
import { ethers } from "ethers";
import as dotenv from "dotenv";
dotenv.config();
const provider = new ethers.WebSocketProvider(
wss://mainnet.infura.io/ws/v3/${process.env.INFURA_API_KEY}
);
console.log("📡 WebSocket подключен к Ethereum...");provider.on("block", (blockNumber) => {
console.log(📡 Новый блок: ${blockNumber});
});
// так мы "мониторим" активность в блокчейнеОтслеживаем входящие транзакции (mempool)
provider.on("pending", async (txHash) => {
try {
const tx = await provider.getTransaction(txHash);
if (tx) {
console.log(`🔄 Входящая транзакция: От ${tx.from} → Кому: ${tx.to} | Сумма: ${ethers.formatEther(tx.value)} ETH`);
}
} catch (error) {
console.error("Ошибка при получении транзакции:", error);
}
});Отслеживаем события контрактов (переводы токенов)
отслеживаем переводы $USDC (Transfer)
ABI для события Transfer:
const abi = [
"event Transfer(address indexed from, address indexed to, uint256 value)"
];
const contractAddress = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; // USDC
const contract = new ethers.Contract(contractAddress, abi, provider);
contract.on("Transfer", (from, to, value) => {
console.log(🔄 Перевод USDC: От ${from} → Кому: ${to} | Сумма: ${ethers.formatUnits(value, 6)} USDC);
});
const myWallet = "0xКошелек";
contract.on("Transfer", (from, to, value) => {
if (to.toLowerCase() === myWallet.toLowerCase()) {
console.log(
✅ Ты получил ${ethers.formatUnits(value, 6)} USDC от ${from}
);
}
});
скрипт показываем переводы только на наш кошелек
Теперь мы мониторим все события в блокчейне в реальном времени!
😕 Эти знания помогут в последующем написании арбитражных ботов, фронт раннинга и создании WEB3 Приложений
ВАШИ ИДЕИ? Что ДАЛЕЕ!!
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍11❤2🔥2🐳2
шо такое газ в Ethereum??
👊 Gas - плата за выполнение транзакций и смарт-контрактов.
Каждая операция в блокчейне требует вычислений - майнеры / валидаторы тратят ресурсы - мы платим за это gas
😮 Структура gas fees в EIP-1559
Раньше (до EIP-1559) в Ethereum комиссии работали как аукцион - кто поставил больше gasPrice, того транзакция проходила быстрее.🤫 После EIP-1559 (Лондонский хардфорк):
Нет аукциона, есть base fee (основная комиссия).
Если сеть загружена - base fee растет
Если сеть свободна - base fee падает
Дополнительно можно платить maxPriorityFeePerGas, чтобы ускорить транзакцию.
Если у нас:
gasLimit = 21,000 (стандарт для перевода ETH)
maxFeePerGas = 50 gwei
maxPriorityFeePerGas = 3 gwei💰 комиссия будет:
Готовы заплатить: 50 gwei за gas
Майнеры получат: 3 gwei (priority fee)
Базовая комиссия (base fee) определяется сетью
Итоговая стоимость = gasUsed * (baseFee + priorityFee)😊
скрипт получения данных газа
import { ethers } from "ethers";
import as dotenv from "dotenv";
dotenv.config();
const provider = new ethers.JsonRpcProvider(
https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}
);
async function getGasFees() {
const feeData = await provider.getFeeData();
const latestBlock = await provider.getBlock("latest"); // Получаем последний блок
// Если baseFeePerGas есть в блоке, используем его
const baseFee = latestBlock.baseFeePerGas ?? ethers.toBigInt(0);
const priorityFee = feeData.maxPriorityFeePerGas ?? ethers.toBigInt(0);
const maxFee = feeData.maxFeePerGas ?? ethers.toBigInt(0);
console.log("🔍 Получены данные о газе:", feeData);
console.log("🔍 Данные из последнего блока:", latestBlock);
console.log(⛽ Base Fee: ${ethers.formatUnits(baseFee, "gwei")} gwei);
console.log(
🚀 Priority Fee: ${ethers.formatUnits(priorityFee, "gwei")} gwei
);
console.log(📌 Max Fee Per Gas: ${ethers.formatUnits(maxFee, "gwei")} gwei);
}
getGasFees();💃 план:
Получает актуальные данные о газе с provider.getFeeData() и provider.getBlock("latest"):
Base Fee из последнего блока.
Priority Fee и Max Fee из feeData.
Выводит их в Gwei.
Если поставить слишком низкий gasLimit, транзакция зафейлится и сгорит комиссия!
Если поставить слишком высокий gasLimit, можно переплатить☺️
используем estimateGas(), который сам вычисляет лимит.
функция
async function estimateGasLimit(to, amount) {
const tx = {
to: to,
value: ethers.parseEther(amount),
};
const estimatedGas = await provider.estimateGas(tx);
console.log(📊 Предполагаемый gasLimit: ${estimatedGas.toString()});
}
estimateGasLimit("0xКошелек", "0.01");😣 Оценивает, сколько газа (gasLimit) потребуется для транзакции с помощью provider.estimateGas()
Выводит расчетный gasLimit для перевода 0.01 ETH.
Экономим деньги на комиссиях, выставляя оптимальные maxFeePerGas и maxPriorityFeePerGas.🍌 Рассчитываем gasLimit заранее через estimateGas(), чтобы транзакции не зафейлились.
Можно разрабатывать ботов, которые анализируют газ и отправляют транзакции в лучшее время.😄 Понимание, когда сеть загружена, помогает ловить моменты низких комиссий для выгодных сделок.
!!! Эти знания нужны для всех Web3-разработчиков: от трейдеров до создателей DeFi/NFT-приложений.
ВАШИ КОММЕНТАРИИ!!! ЧТО ДАЛЕЕЕ???
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍8❤🔥3🔥1💘1
📕 разберем оптимизацию, зависание, комиссии, EIP-1559 и сырые транзакции
скрипт к уроку ниже
ethers.js v6 библиотекаПозволяет подписывать транзакции без подключения к интернету, а отправлять их в сеть позже.🏆 Повышает безопасность - приватный ключ не хранится в онлайне
мини-план:
- создаем сырую транзакцию
- подписываем её приватником
🚶♀️ Как отправить подписанную транзакцию broadcastTransaction☕️ Raw Transaction - готовая подписанная транзакция, в виде Hex-кода, которую можно передавать в сеть без использования приватника на сервере.😐 в результате - если у нас есть подписанная транзакция, мы можем отправить ее в любой момент (например, при низкой комиссии)
+ можно повысить безопасность, подписывая транзакции на холодном кошельке (офлайн), а отправляя их из другого устройства.
🔫 Как избежать зависших транзакций?
Иногда транзакция зависает из-за слишком низкого gas fee
Можно повторно отправить ту же транзакцию, но с большей комиссией😱
p.s - Блокчейн видит новую транзакцию с тем же nonce и заменяет старую
зачем понимать??
☺️ Создание оптимизированных Web3-ботов, которые платят меньше комиссии.
Разработка офлайн-подписи для арбитражных и маркет-мейкинговых стратегий.
Безопасное хранение приватных ключей без необходимости их постоянного использования
далее, начинаем внедрять TS и пишем софт
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤3🤩2
первая неделя - разобрали БАЗУ web3
ПЛАН ДАЛЕЕ:
> Подключение к контракту через ethers.Contract.
> Подписка на события в реальном времени (contract.on()).
> Фильтрация событий по адресу и топикам (topics).
> Получение исторических логов через provider.getLogs().
> Разбираем EIP-191 и EIP-712 (подпись структурированных данных).
> Подключаемся к Uniswap Quoter
> Узнаём цену токенов перед свапом.
> Анализируем спред цен между разными DEX.
> Проверяем ликвидность на Uniswap V3.
> Подключаемся к Uniswap Router.
> Делаем свап токенов
> Устанавливаем slippage и deadline.
> Разбираемся с gasLimit и priorityFee.
> Симулируем сделки перед отправкой (используем callStatic).
> Настраиваем MultiSig (Gnosis Safe).
> Разбираем угрозы (фишинг, утечка приватных ключей, уязвимости API).
> Настраиваем Ethers.js с TypeScript🍷
> Добавляем строгую типизацию
> Покрываем код тестами
> Склеиваем всё вместе: контракт + события + свапы + авторизация.
> Настраиваем автоматический мониторинг сделок.
> Разворачиваем бота для уведомлений в Telegram.
> Научились отслеживать события в блокчейне.
> Автоматически проверяем цены на Uniswap.
> Реализовали полностью автоматизированные свапы.
> Защитили приватные ключи и API-ключи
> написали мощный Web3-код с TypeScript
Подняли реальный проект, который сам зарабатывает бабло🏆
ГОТОВИМСЯ
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍9❤3💘2
зачем логирование?
📖 Безопасность - избегаем утечек приватных ключей, seed-фраз, access-токенов.
Отладка - транзакции занимают время, важно видеть их статусы.
Аналитика - отслеживаем взаимодействие с контрактами, биржами и пользователями.
Мониторинг - логирование помогает выявлять аномалии (резкий рост комиссий etc..)🕵️♀️
debug
npm install debug
скрипт-тестирования
import debug from "debug";
const log = debug("app:info");
const warn = debug("app:warn");
const error = debug("app:error");
log("Запуск приложение...");
warn("Предупреждение: сеть перегружена.");
error("Ошибка: транзакция отклонена!");
просмотр логов debug:
Linux / macOS
DEBUG=* node logging.js
Windows
$env:DEBUG = "app:*"; node logging.js
Универсальный Способ
npx cross-env DEBUG='app:*' node logging.js
const logger = winston.createLogger({
level: "info",
format: winston.format.json(),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: "app.log" }),
],
});
logger.info("Приложение запущено.");
logger.warn("Высокая газовая комиссия!");
logger.error("Ошибка при отправке транзакции!");запуск логов:
node logging.js
const Exchangelogger = winston.createLogger({
transports: [new winston.transports.Console()],
});
async function getPrice(symbol) {
try {
const res = await axios.get(
https://api.binance.com/api/v3/ticker/price?symbol=${symbol}
);
logger.info(Цена ${symbol}: ${res.data.price});
} catch (err) {
logger.error(Ошибка запроса к Binance: ${err.message});
}
}const maskSecrets = winston.format((info) => {
if (info.message.includes("private_key")) {
info.message = info.message.replace(/(0x[a-fA-F0-9]{60})/, "**");
}
return info;
});
const replaceLogger = winston.createLogger({
format: winston.format.combine(maskSecrets(), winston.format.json()),
transports: [new winston.transports.Console()],
});async function consoleLog() {
const provider = new ethers.JsonRpcProvider(
https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}
);
const balance = await provider.getBalance("ethers.eth");
console.log("Balance:", ethers.formatEther(balance));
}
consoleLog();🎧 Отслеживаем производительность и поведение приложения в продакшене
Обнаруживаем атаки, взломы и несанкционированные действия.
Логирование критических операций (снятие, ввод средств) помогает расследовать инциденты.🤟
Логирование действий пользователей помогает анализировать их поведение и улучшать продукт.
Отслеживание успешных и неудачных API-запросов помогает находить проблемы.😱
В РЕЗУЛЬТАТЕ МЫ КОНТРОЛИРУЕМ КОД! Двигаемся ДАЛЕЕ!!
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13🐳5🤩4
часть №1
🐺 ПРОЦЕСС СВОПА1⃣ Создание контракта $WETH
> создаётся объект wethContract с ABI (интерфейсом):
deposit() — функция внесения ETH и получения WETH.
balanceOf(address) — функция просмотра баланса WETH2⃣ Обмен $ETH на $WETH
swapETHtoWETH(amountInETH) выполняет обмен:3⃣ Конвертация $ETH -> $Wei
> Введённое значение ETH (amountInETH) переводится в Wei (ethers.parseEther())4⃣ Отправка транзакции
Вызывается deposit() с переданным значением ({ value: amountInWei })
Логируется hash транзакции
Ожидание подтверждения
Используется await tx.wait(), чтобы дождаться включения в блок5⃣ Проверка баланса $WETH
> Запрашивается баланс WETH для текущего кошелька (wallet.address)
> Логируется обновлённый баланс WETH (ethers.formatUnits()).
async function swapETHtoWETH(amountInETH) {
try {
const amountInWei = ethers.parseEther(amountInETH.toString());
console.log(🔄 Обмен ${amountInETH} ETH на WETH...);
const tx = await wethContract.deposit({ value: amountInWei });
console.log(⏳ Транзакция отправлена: ${tx.hash});
await tx.wait();
// проверка баланса $WETH
const wethBalance = await wethContract.balanceOf(wallet.address);
console.log(
✅ Обмен завершен! Твой WETH баланс: ${ethers.formatUnits(
wethBalance,
18
)} WETH
);
} catch (error) {
console.error("❌ Ошибка свапа:", error);
}
}ДНЕМ ПРОДОЛЖИМ DEXировать
Please open Telegram to view this post
VIEW IN TELEGRAM
🐳8🔥3😍3❤1
часть №2
разбираем ПРИНЦИПЫ взаимодействия с DAPPS
etherscan.io
defillama.com
dappradar.com
Вся информация по DAPPs и смарт-контрактам на этих сайтах
😐 Хранения ABI и других компонентов -> (ООП)
Инкапсуляция - создаем отдeльный класс для хранения ABI.
Модульность - один класс для работы с провайдером, другой для управления подписанными транзакциями и т.д🤟
Полиморфизм - интерфейсы или абстрактные классы для описания общих методов (вызываем методы контрактов одинаково, независимо от их реализаци)😱 Наследование - классы, которые расширяют базовый класс "BaseContract" и добавляют специфичные методы для каждого DEX.
проверка существующих контрактов
etherscan.io/contractsverified
honeypot.rugdoc.io
defillama.com
skynet.certik.com/leaderboards/crypto
проверка твоих контактов
mythx.io
alchemy.com/dapps/slither
openzeppelin.com/defender
СОХРАНЯЕМ И ПРИМЕНЯЕМ!!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8😍3🐳2💘1
зачем??
> Смарт-контракты неизменяемы после деплоя.
> Ошибки могут привести к потере реальных денег😮
> Дорогие газовые транзакции - лучше проверить код локально.
> Децентрализованные приложения взаимодействуют с контрактами – ошибки в JS/TS-коде могут привести к уязвимостям😭
☕️ Виды тестирования:
> Unit-тесты (модульное тестирование)
Проверяют отдельные функции и модули🤵♂️
В Solidity - тестируем методы контракта.😺 В TypeScript - тестируем утилиты (расчеты, подписи, ABI-декодеры).
> Integration-тесты
Проверяют взаимодействие разных частей системы.
В dApp - тестируем фронт + бэкенд (Ethers.js ↔ смарт-контракт).
> End-to-end (E2E) тестирование
Проверяет весь флоу от UI до блокчейна.
И например - тестируем реальный обмен токенов через DEX.
> Fuzz-тестирование
Генерирует случайные входные данные.
В Solidity можно использовать Foundry (Forge) или Echidna.
😊 Инструменты для тестирования в JS/TS
Mocha - тестовый раннер для JS/TS.
Jest - фреймворк для тестирования JS/TS-кода
Hardhat Chai Matchers - расширение для Hardhat, помогающее тестировать контракты.💃 Тестовые блокчейн-среды
Hardhat - Локальная сеть для тестирования
Ganache - локальный блокчейн для тестов
Anvil (из Foundry) - быстрая альтернатива ganache
☺️ Библиотеки для работы с контрактами
ethers.js - библиотека для взаимодействия с контрактами
wagmi - упрощает интеграцию смарт-контрактов с фронтом.
ДНЕМ РАЗБИРАЕМ УСТАНОВКУ!!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤3🐳2
ПРАКТИКА
mkdir crypto-testing && cd crypto-testing
npm init -y
Зависимости
npm install --save-dev hardhat
npm install --save-dev mocha chai ethers
npm install --save-dev @openzeppelin/contracts
TypeScript
npm install --save-dev ts-node typenoscript @types/mocha @types/chai
simpleToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract SimpleToken is ERC20 {
constructor() ERC20("SimpleToken", "STK") {
_mint(msg.sender, 1000 * 10**18);
}
}
hardhat.config.ts
import { expect } from "chai";
import { ethers } from "hardhat";
describe("SimpleToken", function () {
it("Должен выдавать 1000 токенов создателю", async function () {
const [owner] = await ethers.getSigners();
const Token = await ethers.getContractFactory("SimpleToken");
const token = await Token.deploy();
await token.waitForDeployment();
expect(await token.balanceOf(owner.address)).to.equal(
ethers.parseUnits("1000", 18)
);
});
});test/SimpleToken.test.ts
import { expect } from "chai";
import { ethers } from "hardhat";
describe("SimpleToken", function () {
it("Должен выдавать 1000 токенов создателю", async function () {
const [owner] = await ethers.getSigners();
const Token = await ethers.getContractFactory("SimpleToken");
const token = await Token.deploy();
await token.waitForDeployment();
expect(await token.balanceOf(owner.address)).to.equal(
ethers.parseUnits("1000", 18)
);
});
});ТЕСТИРУЕМ
ВАМИ ВАРИАНТЫ ДАЛЕЕ
Please open Telegram to view this post
VIEW IN TELEGRAM
🐳5🔥3🤩2👍1
материалы на погружение
КРИПТО
статьи:
Крипта уровня Advanced
Лучший гайд по крипте
DYOR: великий гайд по ресерчу
КОД
статьи
How to Code или как выносить проекты на 1000 аккаунтов
ЯЗЫКИ
Solidity - написание смарт-контрактов на Ethereum и совместимых блокчейнах (EVM).
используется в Ethereum, BNB Chain, Polygon, Arbitrum, Optimism.
Rust - разработка блокчейнов софтов и смарт-контрактов.
используем в Solana, Near, Polkadot, Substrate, Cosmos SDK
Go - разработка нод, инфраструктуры, серверной логики.
Используем в Ethereum (Geth), Cosmos SDK.
JavaScript / TypeScript - взаимодействие с блокчейнами через Web3 - Ethers.js, разработка DApp-фронтендов, скриптов и софта
используем в любых блокчейнах с Web3-интерфейсом
Python - бэкенд, анализ блокчейн-данных, написание ботов, автоматизация
используем в блокчейн-аналитике, алгоритмической торговле, web3-сервисах
гайды по языкам в закрепе
YouTube-Каналы
youtube.com/@DappUniversity/videos
youtube.com/@EatTheBlocks/videos
youtube.com/@MoralisWeb3/videos
youtube.com/c/PatrickCollins
ИГРЫ & ПРАКТИКА
ethernaut.openzeppelin.com - игра, созданная OpenZeppelin, в которой нужно решать головоломки, связанные с безопасностью смарт-контрактов.
capturetheether.com - ряд задач, связанных с безопасностью смарт-контрактов, необходимо «захватывать эфир»
eth.build - платформа, созданная в стиле «песочницы», создаем децентрализованные приложения и визуализируем их работу
Solidity
cryptozombies.io - бесплатная игра, в игровой форме изучаем разработку на Solidity.
Solidity by Example - пошаговые примеры и небольшие задачи по Solidity.
Rust & Solana / Near / Polkadot
Solana Playground - песочница для написания и тестирования Solana-программ на Rust.
Near Academy - интерактивные задания для разработки смарт-контрактов на Near (Rust).
Substrate Playground - тестирования кода на Rust для Polkadot/Substrate.
JavaScript/TypeScript & Web3
Speed Run Ethereum – практические задания по разработке DApp с Ethers.js и Solidity.
🐘 100 РЕАКЦИЙ И ДРОПАЮ СЛЕДУЮЩУЮ ЧАСТЬ!!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥45❤10🐳7❤🔥1🗿1