diff --git a/README.md b/README.md index 02e7e309..a74a1eb1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Перед тем как создавать pull request, изучите [требования к оформлению вопросов и ресурсов](./requirements.md). ## Статус -Сейчас программа находится в фазе активного переноса с прошлой платформы, где мы её писали (rizzoma.com), поэтому многие куски пока что ещё упущены, структура материала не окончательно заполнена. +Работы по основным направлениям завершены, а материалы активно используются нами и другими командами. На данный момент репозиторий активно поддерживается и развивается. Добавляются новые топики, обновляются и актуализируются старые. ## Градации Ниже приведены наши субъективные представления стандартных уровней мастерства разработчиков. diff --git a/backend/README.md b/backend/README.md index 431fa8c1..9eefe29c 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,6 +1,7 @@ # Programming languages - [Haskell](./haskell/README.md) +- [Node.js](./node.js/README.md) - [Python](./python/README.md) ## Optional topics diff --git a/backend/node.js/README.md b/backend/node.js/README.md new file mode 100644 index 00000000..8015e78e --- /dev/null +++ b/backend/node.js/README.md @@ -0,0 +1,8 @@ +# Список уровней: + +- **Junior:** + * [junior-1](./junior-1/README.md) + +- **Middle** + +- **Senior** diff --git a/backend/node.js/junior-1/README.md b/backend/node.js/junior-1/README.md new file mode 100644 index 00000000..af85dcea --- /dev/null +++ b/backend/node.js/junior-1/README.md @@ -0,0 +1,9 @@ +# Node.js Junior 1 level + +- [JavaScript](../../../frontend/junior-1/js.md) +- [TypeScript](../../../frontend/junior-2/ts.md) +- [Node.js](../junior-1/nodejs.md) +- [Nest.js](../junior-1/nestjs.md) +- [DB](../../shared/junior-1/db.md) +- [Testing](../../../shared/junior-1/testing.md) +- [Git](../../../shared/junior-1/git.md) diff --git a/backend/node.js/junior-1/databases/MongoDB.md b/backend/node.js/junior-1/databases/MongoDB.md new file mode 100644 index 00000000..21b0a8e8 --- /dev/null +++ b/backend/node.js/junior-1/databases/MongoDB.md @@ -0,0 +1,25 @@ +# MongoDB + + +* What is MongoDB? +* What are the basic most commonly used types? +* What are these methods for? + * insertOne, insertMany + * find + * updateOne, updateMany, replaceOne, replaceMany + * deleteOne, deleteMany, drop +* What are these operators for? + * $eq, $gt, $lt, $lte, $gte, $ne + * $include, $exclude + * $in, $nin, $all + * $and, $or, $not, $nor + * $match, $group, $sort, $skip, $limit +* What are replications? How replications relate to transactions? +* How to create dump? +* How to restore dump? + +### Resources + +* [MongoDB CRUD Operations](https://www.mongodb.com/resources/products/fundamentals/crud) +* [MongoDB Operators](https://www.mongodb.com/docs/manual/reference/operator/) +* [MongoDB Transactions](https://www.mongodb.com/docs/manual/core/transactions/) diff --git a/backend/node.js/junior-1/databases/NoSQL.md b/backend/node.js/junior-1/databases/NoSQL.md new file mode 100644 index 00000000..ea83f207 --- /dev/null +++ b/backend/node.js/junior-1/databases/NoSQL.md @@ -0,0 +1,9 @@ +# NoSQL + +* What is NoSQL database? +* What the difference from a relational db? +* NoSQL use cases. When it should be used? + +### Resources + +* [What is NoSQL?](https://www.mongodb.com/resources/basics/databases/nosql-explained) diff --git a/backend/node.js/junior-1/databases/ORM.md b/backend/node.js/junior-1/databases/ORM.md new file mode 100644 index 00000000..67d0333f --- /dev/null +++ b/backend/node.js/junior-1/databases/ORM.md @@ -0,0 +1,22 @@ +# ORM + +## Common + +* What is ORM? Why do we prefer to use ORMs instead of native drivers? + +## Typeorm +* What it is. +* Write a simple table with numbers, strings, and arrays. +* Write the relationship options: + * OneToOne. + * ManyToOne (OneToMany). + * ManyToMany. +* Migrations + * What are the commands for running and creating migrations? + * If you need to add a new field to an existing table on a prod (or change the field type) what do you do? +* What is QueryBuilder? +* How do you load a record including relationships from a database? How to load only certain fields? Sorting and pagination? + +### Resources + +* [Type ORM documentation](https://typeorm.io/) diff --git a/backend/node.js/junior-1/databases/PostgreSQL.md b/backend/node.js/junior-1/databases/PostgreSQL.md new file mode 100644 index 00000000..a90c1415 --- /dev/null +++ b/backend/node.js/junior-1/databases/PostgreSQL.md @@ -0,0 +1,28 @@ +# PostgreSQL + +* What is PostreSQL? +* What are the basic most commonly used types? +* What are domains? How to create a domain? How to create custom type? Enum type? +* What is constraint? +* How to use this constraints? + * Primary Key + * Foreign Key + * Unique + * Not Null +* How to use transactions in sql? +* How to create dump? +* How to restore dump? +* What is a View table? + * How to create it? + * How to update it? + * What is materialized views? + + +### Resources + +* [Postgresql documentation: Chapter 8. Data Types](https://www.postgresql.org/docs/current/datatype.html) +* [A Look at PostgreSQL User-defined Data Types](https://neon.tech/postgresql/postgresql-tutorial/postgresql-user-defined-data-types) +* [PostgreSQL enum](https://neon.tech/postgresql/postgresql-tutorial/postgresql-enum) +* [Postgres Constraints for Newbies](https://www.crunchydata.com/blog/postgres-constraints-for-newbies) +* [PostgreSQL Transaction](https://neon.tech/postgresql/postgresql-tutorial/postgresql-transaction) +* [PostgreSQL Views](https://neon.tech/postgresql/postgresql-views) diff --git a/backend/node.js/junior-1/databases/README.md b/backend/node.js/junior-1/databases/README.md new file mode 100644 index 00000000..ba86f18c --- /dev/null +++ b/backend/node.js/junior-1/databases/README.md @@ -0,0 +1,7 @@ +# Databases + +* [Relational database and SQL](../../../shared/junior-1/db.md) +* [NoSQL](./NoSQL.md) +* [PostgreSQL](./PostgreSQL.md) +* [MongoDB](./MongoDB.md) +* [ORM](./ORM.md) diff --git a/backend/node.js/junior-1/nestjs.md b/backend/node.js/junior-1/nestjs.md new file mode 100644 index 00000000..f1be9d58 --- /dev/null +++ b/backend/node.js/junior-1/nestjs.md @@ -0,0 +1,30 @@ +# Nest.js + + +* What is it and what is it used for? +* What are Dependency injection and Inversion of Control? How does it relate to NestJS? +* Tell about Module, Provider, Controller. + * What is Scope? How do different values change the behavior of the application? +* Controller + * Http decorators + * Request validation +* What is Guard and Strategy? How to use it to create auth module? +* What are the basic ways to catch exceptions? +* How to resolve cyclic dependencies issue? +* What is Middleware? What is it used for? How to create it? +* What is Interceptor? +* How to create custom decorators? +* Tell about life cycles and there purpose? +* What is Dynamic module? How to create it? + * What is the difference between forRoot, forFeature and register? +* How to do unit testing of a module? +* What is Custom providers? How to use it in testing? +* How to setup CORS? +* How to rate-limit an app? +* How to create a microservice and connect it to another NestJS application? + * How to make a two-way system so that both applications are both consumers and producers at the same time? + + +### Resources + +* [NestJS documentation](https://docs.nestjs.com/) diff --git a/backend/node.js/junior-1/nodejs.md b/backend/node.js/junior-1/nodejs.md new file mode 100644 index 00000000..0afb5d7a --- /dev/null +++ b/backend/node.js/junior-1/nodejs.md @@ -0,0 +1,34 @@ +# Node.js + +* What is NodeJS? +* What parts does node consist of? +* What is the difference between node and js in the browser? +* What is the difference between CommonJS and ES modules in node? +* What is an EventEmitter? What can it be used for? +* What is an Event Loop? How does it work? How is it different from event loop in browser? +* How to use a debugger? +* What modules are there for working with the file system? +* What is the child_process module for? + * What is the difference between spawn and exec? + * How to create a process so that it can send logs in the current application console in runtime? + * How to transfer a running process to promises? +* What is a WorkerThread and how to work with it? +* What is a garbage collector and how does it work? Under what conditions can a garbage collector fail? +* What are Stream? What types of streams are there? What can they be used for? + +### Resources + +* [Introduction to Node.js](https://nodejs.org/en/learn/getting-started/introduction-to-nodejs) +* [Node.js Under The Hood Series' Articles](https://dev.to/_staticvoid/series/2008) +* [Differences between Node.js and the Browser](https://nodejs.org/en/learn/getting-started/differences-between-nodejs-and-the-browser/#differences-between-nodejs-and-the-browser) +* [Understanding CommonJS vs. ES Modules in JavaScript](https://www.syncfusion.com/blogs/post/js-commonjs-vs-es-modules) +* [CommonJS vs. ES modules in Node.js](https://blog.logrocket.com/commonjs-vs-es-modules-node-js/) +* [The Node.js Event Loop](https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick#what-is-the-event-loop) +* [Don't Block the Event Loop (or the Worker Pool)](https://nodejs.org/en/learn/asynchronous-work/dont-block-the-event-loop) +* [JavaScript Visualized Series' Articles](https://dev.to/lydiahallie/series/3341) +* [The Node.js Event emitter](https://nodejs.org/en/learn/asynchronous-work/the-nodejs-event-emitter#the-nodejs-event-emitter) +* [Node.js v23.1.0 documentation: Debugger](https://nodejs.org/api/debugger.html) +* [Node.js v23.1.0 documentation: Child process](https://nodejs.org/api/child_process.html#child-process) +* [Node.js v23.1.0 documentation: Worker threads](https://nodejs.org/api/worker_threads.html#worker-threads) +* [Garbage collection](https://javascript.info/garbage-collection) +* [Node.js v23.1.0 documentation: Stream](https://nodejs.org/api/stream.html#stream) \ No newline at end of file diff --git a/backend/shared/junior-1/db.md b/backend/shared/junior-1/db.md index cc3e1980..ad815c30 100644 --- a/backend/shared/junior-1/db.md +++ b/backend/shared/junior-1/db.md @@ -17,6 +17,8 @@ - [What is a database?](https://www.oracle.com/database/what-is-database/) - [What is a relational database?](https://www.oracle.com/database/what-is-a-relational-database/) +- [Relational database](https://www.techtarget.com/searchdatamanagement/definition/relational-database) +- [Реляционные базы данных](https://yandex.cloud/ru/docs/glossary/relational-databases?utm_referrer=https%3A%2F%2Fgist.github.com%2F) ## SQL @@ -41,3 +43,14 @@ #### Resources - [SQL Tutorial](https://www.w3schools.com/sql/default.asp) +- [Введение в SQL и работу с базой данных](https://netology.ru/programs/vvedenie-v-sql-i-rabotu-s-bazoi-dannih#/) + + +#### Additional resources + +* [Литература с Postgrespro](https://postgrespro.ru/education/books): + * Новиков, Б. А. Основы технологий баз данных, часть 1: + * Теоретические основы БД - 2.1, 2.2 + * Моргунов, Е. П. PostgreSQL. Основы языка SQL: + * Основы SQL - главы 1-7 +* [Введение в базы данных, курс Stepik](https://stepik.org/course/551/) diff --git a/backend/shared/middle-1/ddd.md b/backend/shared/middle-1/ddd.md new file mode 100644 index 00000000..f656ad13 --- /dev/null +++ b/backend/shared/middle-1/ddd.md @@ -0,0 +1,52 @@ +### Domain-Driven Design (DDD) + +#### **Strategic Design** +- Что такое Domain-Driven Design (DDD)? Каковы его цели и задачи? +- В чем заключается стратегическое проектирование в DDD? +- Какова роль эксперта предметной области в DDD? +- Что такое предметная область (Domain) и почему важно ее правильное моделирование? +- Какие бывают типы доменов: Core Domain, Supporting Domain, Generic Domain? +- Что такое Ubiquitous Language (единый язык). Почему он важен в DDD-проектах? +- Какие требования предъявляются к единому языку в рамках проекта? +- Что такое модель предметной области (Domain Model)? +- Как организовано разделение ответственности в DDD? + - Что такое Subdomain? + - Что такое Problem Domain? + - Что такое Bounded Context и почему он важен? + - В чем разница между Bounded Context и Subdomain? + - Как применяется единый язык внутри системы? +- Что такое Problem и Solution Space? +- Как организовать взаимодействие между несколькими Bounded Context внутри одной системы? + - Паттерн **Cooperation** – когда стоит использовать? + - Паттерн **Partnership** – когда стоит использовать? + - Паттерн **Shared Kernel** – когда стоит использовать? + - Паттерн **Conformist** – когда стоит использовать? + - Что такое **Anticorruption Layer (ACL)** и зачем он нужен? + - Паттерн **Open-Host Service** – когда стоит использовать? + - Паттерн **Customer-Supplier** – когда стоит использовать? + - Паттерн **Separate Ways** – когда стоит использовать? +- Что такое Context Map (карта контекстов). Зачем нужен Context Mapping? +- Почему DDD не всегда применим во всех проектах? + +#### **Tactical Design** +- Что такое тактическое проектирование и чем оно отличается от стратегического? +- В чем отличие DDD от data-oriented и service-oriented подходов? +- Что такое чистая архитектура? Из каких слоев она состоит и как применяется в DDD? +- Что такое Value Object (объект-значение)? Для чего применяется? +- Что такое Entity (сущность)? +- Что такое Aggregate (агрегат). В чем его отличие от сущности? +- Что такое анемичная модель? Почему это плохо? Как с этим бороться? +- Что такое Domain Events (события предметной области). Зачем и как их использовать? +- Что такое Domain Service. В каких случаях он нужен? +- Какие архитектурные паттерны применяются в DDD? + - Какие слои входят в Layered Architecture (слоистая архитектура)? Как они связываются? Зачем они нужны? + - Что такое Ports and Adapters Architecture (архитектура портов и адаптеров)? Чем она лучше слоистой архитектуры? + - Что такое CQRS? Для чего он нужен? Как он применяется в DDD? + - Что такое Event-driven Design? Для чего он нужен? Как он применяется в DDD? +- Как DDD соотносится с архитектурой микросервисов? + +### **Ресурсы** +- Хононов Влад. *Изучаем DDD - предметно-ориентированное проектирование* +- Вернон Вон. *Реализация методов предметно-ориентированного проектирования* +- [Владимир Хориков – *Domain-Driven Design: самое важное*](https://www.youtube.com/watch?v=JOy_SNK3qj4) +- Ричард Маркс, Форд Нил. *Фундаментальный подход к программной архитектуре: паттерны, свойства, проверенные методы* diff --git a/frontend-web3/README.md b/frontend-web3/README.md new file mode 100644 index 00000000..a859ce4c --- /dev/null +++ b/frontend-web3/README.md @@ -0,0 +1,12 @@ +# Frontend Web3 + +Данный раздел посвящён разработке децентрализованных фронтенд приложений - dApp. Он предназначен для опытных фронтенд разработчиков, которые владеют глубокими знаниями в HTML, CSS, JS, изучили один из фреймворков (React или др.), и имеют несколько коммерческих проектов за своими плечами. Если вы новичок в веб-разработке, то вам сперва [сюда](../frontend/). + +## Теория + +* [Основы](./basics.md) + +## Практика + +* [Send ERC-20 (базовый уровень)](./practice/1-send-erc-20.md) +* [Mint NFT (продвинутый уровень)](./practice/2-mint-nft.md) \ No newline at end of file diff --git a/frontend-web3/basics.md b/frontend-web3/basics.md new file mode 100644 index 00000000..0370f928 --- /dev/null +++ b/frontend-web3/basics.md @@ -0,0 +1,127 @@ +# Основы Web3 + +### Блокчейн +* Что такое Web1, Web2 и Web3? +* Что такое блокчейн? +* Что такое транзакция? Что такое revert транзакции? Почему транзакция исполняется с задержкой? +* Что такое цифровая подпись? +* Что такое dApp? +* Что такое ethereum? +* Что такое evm-совместимые сети? +* Что такое тестовые сети (testnets)? +* Что такое газ? От чего зависит стоимость транзакций в блокчейне? + +##### Ресурсы + +* [Introduction to Web3](https://ethereum.org/en/web3/) +* [Блокчейн изнутри: как устроен биткоин](https://vas3k.blog/blog/blockchain/) +* [Ethereum docs: Transactions](https://ethereum.org/en/developers/docs/transactions/) +* [Digital Signatures on ethereum](https://github.com/fullstack-development/blockchain-wiki/blob/main/concepts/digital-signature-on-ethereum/README.md) +* [Как устроен Ethereum и смарт-контракты](https://vas3k.blog/blog/ethereum/) +* [What are EVM Compatible Blockchains?](https://blog.thirdweb.com/evm-compatible-blockchains-and-ethereum-virtual-machine/) +* [Тестовая сеть](https://academy.binance.com/ru/glossary/testnet) +* [Ethereum: Network fees](https://ethereum.org/en/gas/) +* [What is Ethereum Gas? (Examples + Easy Explanation)](https://www.youtube.com/watch?v=3ehaSqwUZ0s) + +### Смарт-контракты +* Что такое смарт-контракт? +* Что такое “события” в смарт контракте? + * Что такое indexed параметры? +* В чем отличия функций view, pure, payable в смарт-контракте? +* Что такое keccak256 и для чего применяется? + +##### Ресурсы + +* [Anatomy of smart contracts: Events and logs](https://ethereum.org/en/developers/docs/smart-contracts/anatomy/#events-and-logs) +* [Solidity docs: Events](https://docs.soliditylang.org/en/v0.8.27/contracts.html#events) +* [Event argument indexing](https://github.com/fullstack-development/blockchain-wiki/blob/main/solidity/event-argument-indexing/README.md) +* [Solidity docs: State mutability](https://docs.soliditylang.org/en/v0.8.27/contracts.html#state-mutability) +* [What are Payable Functions in Solidity?](https://docs.alchemy.com/docs/solidity-payable-functions) +* [Keccak256](https://github.com/fullstack-development/blockchain-wiki/tree/main/concepts/keccak256) + +### Кошельки +* Что такое account и wallet? В чём отличие между ними? Перечислите хотя бы 5 кошельков. +* Что такое private key и public key? +* Что такое WalletConnect? + +##### Ресурсы + +* [What Is a Crypto Wallet?](https://academy.binance.com/en/articles/crypto-wallet-types-explained) +* [What is a Cryptocurrency Wallet? (3 Types + Key Examples)](https://www.youtube.com/watch?v=SQyg9pyJ1Ac&t=3s) +* [What's the difference between a wallet and an account?](https://support.metamask.io/ru/managing-my-wallet/using-metamask/whats-the-difference-between-a-wallet-and-an-account-/) +* [How to Use WalletConnect](https://academy.binance.com/en/articles/how-to-use-walletconnect) [[RU](https://academy.binance.com/ru/articles/how-to-use-walletconnect)] + +### Токены +* Что такое ERC-20 и ERC-721? В чем отличие этих токенов от нативной валюты блокчейна? + * Какие вы знаете методы у ERC-20 и ERC-721? + * Какие вы знаете популярные ERC-20 токены? +* Что такое ERC-1155? +* Что такое аппрув токена, зачем он нужен? + * Как можно узнать количество токенов, разрешенных для управления сторонним адресом? +* Что такое permit? в чем его отличие от approve? +* Что такое decimals, зачем нужен? Почему это важно для работы dApp? Как узнать значение decimals? +* Что такое minting и burning? +* Что такое staking? +* Что такое стейблкоин? + * Какие бывают виды стейблкоинов? + * Что такое обеспечение стейблкоина? + * Какие самые популярные стейблкоины есть? + +##### Ресурсы + +* [An Introduction to ERC-20 Tokens](https://academy.binance.com/en/articles/an-introduction-to-erc-20-tokens) +* [ERC-20: Token Standard](https://eips.ethereum.org/EIPS/eip-20) +* [ERC-721 Non-Fungible Token Standard](https://ethereum.org/en/developers/docs/standards/tokens/erc-721/) +* [Ethereum Token Standards Part-II (ERC721)](https://medium.com/coinmonks/ethereum-token-standards-part-ii-erc721-4a4a7cbd5c74) +* [What Is ERC-1155 and How Does It Work?](https://academy.binance.com/en/articles/what-is-erc-1155-and-how-does-it-work) [[RU](https://academy.binance.com/ru/articles/what-is-erc-1155-and-how-does-it-work)] +* [Что такое апрувы токенов (Token Approvals)?](https://revoke.cash/ru/learn/approvals/what-are-token-approvals) +* [Understanding ERC-20 Permit and Associated Risks](https://readmedium.com/understanding-erc-20-permit-and-associated-risks-41c29c969862) +* [ERC-2612: Permit Extension for EIP-20 Signed Approvals](https://eips.ethereum.org/EIPS/eip-2612) +* Что такое decimals? Ответ от chat-gpt [тут](./img/Screenshot_1.png) и [тут](./img/Screenshot_2.png). И косвенный ответ [тут](https://ethereum.stackexchange.com/questions/134958/erc20-decimals-in-smart-contract). +* [Base mechanics: minting, burning, staking](https://github.com/fullstack-development/web3-roadmap/blob/main/defi/tokens/tokenomics/token_mechanics.md) +* [Стейблкоины. Как привязывают и почему не отвязывается!?](https://habr.com/ru/companies/metalamp/articles/763538/) +* [What are stablecoins, and how do they work?](https://www.youtube.com/watch?v=fdPmjHtQ5aM) + +### IPFS +* Что такое IPFS и при чём тут NFT? + +##### Ресурсы + +* [IPFS: Interplanetary file storage!](https://www.youtube.com/watch?v=5Uj6uR3fp-U) +* [Scaling Your NFT Project: A Beginner’s Guide to IPFS By Pinata](https://www.bueno.art/blog/pinata-ipfs-guide) +* [Storing NFTs on IPFS](https://blog.ipfs.tech/2021-04-05-storing-nfts-on-ipfs/) + +### Фронтенд +* Как прочесть информацию из блокчейна и при чём тут RPC? +* Почему при работе с числами из блокчейна нельзя пользоваться обычным типом `number`? Какой тип использовать вместо `number`? +* Что такое etherscan? Есть ли аналоги в других сетях? + * Как посмотреть код контракта? + * Как посмотреть историю транзакций для выбранного контракта? + * Как посмотреть методы на чтение/запись контракта? Можно ли их вызвать через интерфейс etherscan? + * Что такое ABI контракта и где его взять? +* Что такое TransactionReceipt? +* Что такое viem? Что такое ethers.js? +* Что такое wagmi? + * Рассказать про следующие хуки: + * useReadContract + * useReadContracts + * useWriteContract + * useWaitForTransactionReceipt + * useAccount + * useBalance +* Как можно слушать события на смарт контракте? Как получить историю событий? + +##### Ресурсы + +* [Anatomy of smart contracts](https://ethereum.org/en/developers/docs/smart-contracts/anatomy/) +* [JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/).
*Стоит ознакомиться как минимум с вводной частью. По сути это то, как шлются запросы в блокчейн на самом низком уровне, то есть под капотом у всех библиотек и sdk, таких как web3.js, ethers.js, viem, alchemy sdk и множества других. Например, у viem на каждый метод в документации есть ссылка на функцию в JSON-RPC API, которую viem вызывает у себя под капотом.* +* [Viem docs: Transaction Receipt](https://viem.sh/docs/glossary/terms#transaction-receipt) +* [Viem docs: waitForTransactionReceipt](https://viem.sh/docs/actions/public/waitForTransactionReceipt.html) +* [Wagmi docs](https://wagmi.sh/react/getting-started) +* [Viem docs: watchEvent](https://viem.sh/docs/actions/public/watchEvent) +* [Viem docs: getLogs](https://viem.sh/docs/actions/public/getLogs) + + +### Общие ресурсы + +* [Playlist web2 to web3](https://www.youtube.com/playlist?list=PLJz1HruEnenAf80uOfDwBPqaliJkjKg69) \ No newline at end of file diff --git a/frontend-web3/img/Screenshot_1.png b/frontend-web3/img/Screenshot_1.png new file mode 100644 index 00000000..92ac5b80 Binary files /dev/null and b/frontend-web3/img/Screenshot_1.png differ diff --git a/frontend-web3/img/Screenshot_2.png b/frontend-web3/img/Screenshot_2.png new file mode 100644 index 00000000..32555cb7 Binary files /dev/null and b/frontend-web3/img/Screenshot_2.png differ diff --git a/frontend-web3/practice/1-send-erc-20.md b/frontend-web3/practice/1-send-erc-20.md new file mode 100644 index 00000000..5da6d563 --- /dev/null +++ b/frontend-web3/practice/1-send-erc-20.md @@ -0,0 +1,36 @@ +# Отправка ERC-20 + +Отправка ERC-20 токенов другому пользователю. + +**Примечание:** такое задание не встретится вам на реальных проектах, по скольку пересылать ERC-20 токены можно в интерфейсе любого кошелька. Но это самый быстрый и простой способ познакомиться с разработкой dApp и базовыми вещами, которые вам придётся делать на любом web3 проекте. + +## Какие навыки даст задание? + +- Базовые навыки по работе с кошельками. Подключение/отключение кошелька, смена сети. +- Базовые навыки по работе с смарт контрактами, в частности, ERC-20. Вызов методов на чтение и запись, использование ABI. +- Реализуете поддержку работы в нескольких сетях. +- Научитесь обрабатывать различные события при работе с блокчейном и отображать соответствующий интерфейс - результат вызова смарт контракта (успех или ошибка), результат действий пользователя с кошельком и др. + +## Тех. задание + +- У пользователя должна быть возможность отправить ERC-20 токены другому пользователю. +- Для этого пользователь может выбрать один из токенов по умолчанию или добавить любой другой токен, которого нет в списке по умолчанию. Таким образом он выбирает токен, который хочет отправить. Для основных сетей токены по умолчанию можно взять из [топ-10]((https://etherscan.io/tokens)), а для тестовых сетей мы задеплоили типичные [ERC-20 токены](./test-erc-20-tokens.md). +- Затем он должен указать адрес кошелька получателя и сумму, которую хочет отправить. После чего нажать на кнопку “Отправить”. +- Приложение должно работать в нескольких сетях, например Ethereum и Polygon. Разработку вести в соответствующих тестовых сетях. Смена тестовых сетей на основные должна происходить путём изменения одной переменной окружения в `.env` файле. + +## Тех. требования + +- Интерфейс приложения должен быть отзывчивым. Необходимо показывать различные лоадеры, состояния загрузок, уведомления об успешных или неуспешных действиях. +- В приложении должны быть учтены и обработаны все возможные ошибки, как с точки зрения интерфейса, так и с точки зрения работы с кошельками и смарт контрактами. +- Для работы с блокчейном рекомендуется использоваться [wagmi](https://wagmi.sh/) + [viem](https://viem.sh/). Для интерфейса подключения кошелька можно использовать одно из [сторонних решений](https://wagmi.sh/react/guides/connect-wallet#third-party-libraries). +- Для запросов в блокчейн использовать в качестве RPC провайдера [стороннего провайдера](https://wagmi.sh/core/api/transports/http), а не публичные RPC URL. Например, Alchemy, RPC URL которого можно получить в [личном кабинете](https://dashboard.alchemy.com/). + +## Макеты + +Макеты можно взять [тут](https://www.figma.com/design/5bea2k2sfc8CMytdahfeKW/MetaLamp-Developers-Roadmap-%2F-Frontend-Web3?node-id=0-1&node-type=canvas&t=1DOUk1Gc2KxNbpNr-0). Ссылка на конкретные макеты больше нужна для понимания того, как может выглядеть ваш интерфейс. Вы можете использовать эти макеты или реализовать свой интерфейс. + +В макетах есть Preview Mode, можете прокликать интерфейс. + +## Смарт контракт + +Отдельного смарт контракта для реализации данного функционала не требуется. Стандарт ERC-20 подразумевает наличие некоторого поведения и методов по умолчанию, которых нам достаточно. В частности такие методы как `transfer`, `approve`, `balanceOf` и другие, есть у любого ERC-20 токена. Вы можете импортировать стандартное ABI для всех ERC-20 токенов из viem - `import { erc20Abi } from 'viem';`. \ No newline at end of file diff --git a/frontend-web3/practice/2-mint-nft.md b/frontend-web3/practice/2-mint-nft.md new file mode 100644 index 00000000..d5f76812 --- /dev/null +++ b/frontend-web3/practice/2-mint-nft.md @@ -0,0 +1,178 @@ +# Mint NFT + +Минтинг NFT коллекции + +## Какие навыки даст задание? + +- Базовые навыки по работе с кошельками. Подключение/отключение кошелька, подпись сообщений. +- Базовые навыки по работе с смарт контрактами. Вызов методов на чтение и запись, использование ABI. +- Навыки работы с ERC-721. +- Навыки работы с функционалом администрирования на смарт-контракте. +- Навыки работы с деревом Меркла. +- Навыки работы с IPFS. +- Научитесь обрабатывать различные события при работе с блокчейном и отображать соответствующий интерфейс - результат вызова смарт контракта (успех или ошибка), результат действий пользователя с кошельком и др. + +## Тех. задание + +Необходимо выпустить свою коллекцию NFT. Пользователи смогут получить NFT из этой коллекции в 3 этапа - Airdrop, Private presale, Public sale. Необходимо реализовать: +1. Интерфейс минтинга NFT в 3 этапа для пользователей. +2. Административную панель для владельца продукта, который будет управлять этапами минтинга и whitelists. + +Каждый этап может быть в одном из 3х состояний - Soon, Available, Finished. Ограничений на очерёдность этапов нет. Теоретически все 3 этапа могут быть одновременно Available, этим будет управлять владелец продукта в админ панели. Но в базовом случае, очерёдность этапов следующая - Airdrop, Private presale, Public sale. + +- На этапе Airdrop счастливчики, которые попали в airdrop whitelist, смогут сминтить (mint) 2 NFT из коллекции бесплатно (заплатив только за газ). Для этого им нужно всего лишь нажать на кнопку mint на нашем сайте и подтвердить в кошельке транзакцию на минтинг двух NFT. Так же в админ панели, владелец продукта должен иметь возможность добавлять и убирать людей из airdrop whitelist. +- На этапе Private presale, другие счастливчики, которые попали в private presale whitelist, смогут купить до 3х NFT за более выгодную цену, чем на этапе Public Sale. Покупка происходит за нативную валюту сети (например для мейннета это ETH). Теперь пользователь может ввести количество NFT для покупки (не больше 3х) и нажать кнопку mint, с дальнейшим подтверждением транзакции в кошельке. Пользователь может купить токены на всём периоде действия этого этапа. То есть, если пользователь сначала купил 1 NFT, а через неделю вернулся и этап всё ещё доступен, он может докупить оставшиеся 2 NFT. Так же в админ панели, владелец продукта должен иметь возможность добавлять и убирать людей из private presale whitelist. +- На этапе Public sale, токены из NFT коллекции наконец сможет купить любой желающий, кто попадёт на наш сайт. Стоимость будет выше, чем на этапе Private presale, а ограничение количества NFT на одного пользователя станет 10 токенов. Пользователь также может купить токены на всём периоде действия этого этапа. +- На всю NFT коллекцию есть ограничение в 10000 токенов, которые могут быть сминчены пользователями. +- У пользователя должна быть возможность просмотреть все NFT из нашей коллекции, которые есть у него на кошельке. + +## Тех. требования + +- Интерфейс приложения должен быть отзывчивым. Необходимо показывать различные лоадеры, состояния загрузок, уведомления об успешных или неуспешных действиях. +- В приложении должны быть учтены и обработаны все возможные ошибки, как с точки зрения интерфейса, так и с точки зрения работы с кошельками и смарт контрактами. +- Для работы с блокчейном рекомендуется использоваться [wagmi](https://wagmi.sh/) + [viem](https://viem.sh/). Для интерфейса подключения кошелька можно использовать одно из [сторонних решений](https://wagmi.sh/react/guides/connect-wallet#third-party-libraries). +- Для запросов в блокчейн использовать в качестве RPC провайдера [стороннего провайдера](https://wagmi.sh/core/api/transports/http), а не публичные RPC URL. Например, Alchemy, RPC URL которого можно получить в [личном кабинете](https://dashboard.alchemy.com/). + +## Макеты + +Макеты можно взять [тут](https://www.figma.com/design/5bea2k2sfc8CMytdahfeKW/MetaLamp-Developers-Roadmap-%2F-Frontend-Web3?node-id=2008-1789&node-type=canvas&t=HaYr0qVXTtVr2aDV-0). Ссылка на конкретные макеты больше нужна для понимания того, как может выглядеть ваш интерфейс. Вы можете использовать эти макеты или реализовать свой интерфейс. Обратите внимание, что в макетах нет интерфейса админки, вам его нужно продумать самим. + +В макетах есть Preview Mode, можете прокликать интерфейс. + + +## Смарт-контракт + +Для реализации функционала, описанного выше, был разработан смарт-контракт. Смарт-контракт находится [здесь](https://github.com/fullstack-development/frontend-practice-nft), там же присутствует гайд по деплою (читать README). На реальном проекте вам необходимо будет общаться с разработчиком смарт контракта, что бы он вам рассказал как и что работает. Но в данном задании, для вашего удобства, ниже представлено описание некоторых методов этого смарт контракта на чтение и запись. + +### Работа с ролями + +У владельца продукта должна быть возможность управлять этапами продаж NFT и вайтлистами через админ панель. Для этого на контракте был реализован классический, для смарт контрактов, функционал ролей. Есть следующие роли: + +- `DEFAULT_ADMIN_ROLE` - главная роль на контракте. Только аккаунты с этой ролью могут выдавать (`grantRole`) и забирать (`revokeRole`) роли на контракте. По умолчанию эта роль имеется у того, кто задеплоил контракт. +- `SELL_PHASE_MANAGER_ROLE` - роль, позволяющая вызывать методы по управлению фазами продаж. +- `WHITE_LIST_MANAGER_ROLE` - роль, позволяющая вызывать методы по управлению вайтлистами. +- `PRICE_MANAGER_ROLE` - роль, позволяющая вызывать методы по управлению ценами на этапах public и private. + +Каждой роли соответствует строка `bytes32`, узнать которую можно, вызвав соответствующий метод на контракте (`DEFAULT_ADMIN_ROLE`, `SELL_PHASE_MANAGER_ROLE` и т.д.). + +Методы на чтение: + +- `hasRole` - получает строку `bytes32` роли и адрес кошелька, проверяя наличие указанной роли у переданного кошелька. Возвращает булевое значение. + +Методы на запись может вызвать только адрес с `DEFAULT_ADMIN_ROLE`: + +- `grantRole` - выдаёт указанную роль (`bytes32`) на указанный адрес кошелька. +- `revokeRole` - забирает указанную роль (`bytes32`) у указанного адрес кошелька. +- `renounceRole` - позволяет отозвать роль у самого себя. + +### Работа с этапами продаж + +Этапами продаж может управлять только адрес с ролью `SELL_PHASE_MANAGER_ROLE`. У каждого этапа продаж может быть одно из 3х состояний - 0, 1, 2, где 0 - Soon, 1 - Available, 2 - Finished. + +Методы на чтение: + +- `airDrop` - состояние этапа airdrop, от 0 до 2. +- `whiteListSale` - состояние этапа private presale, от 0 до 2. +- `publicSale` - состояние этапа public sale, от 0 до 2. + +Методы на запись: + +- `toggleAirDrop` - переключает состояние этапа airdrop, принимает цифру от 0 до 2. +- `toggleWhiteListSale` - переключает состояние этапа private presale, принимает цифру от 0 до 2. +- `togglePublicSale` - переключает состояние этапа public sale, принимает цифру от 0 до 2. + +### Работа с вайтлистами и Merkle Tree + +Два из трёх этапа доступны только пользователем, которые попали в соответствующий whitelist. Управление вайтлистами будет происходить в админ панели при помощи дерева Меркла (Merkle Tree) и библиотеки `merkletreejs`. У админа должен быть простой интерфейс, в котором он сможет просто добавлять и удалять адреса из двух вайтлистов и устанавливать новый вайтлист на контракт. А под капотом будет происходить работа с деревом Меркла. + +Листья дерева в нашем случае - это захэшированные адреса кошельков пользователей при помощи функции `keccack256`. Создать дерево можно следующим образом: + +```ts +import { MerkleTree } from 'merkletreejs'; +import { keccak256 } from 'viem'; + +const merkleTree = new MerkleTree( + [ + '0x0000000000000000000000000000000000000000', // адреса кошельков + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + ], + keccak256, + { hashLeaves: true, sortPairs: true }, +); +``` + +После чего необходимо получить корень дерева - `merkleTree.getHashRoot()` и вызвать соответствующий метод на контракте - `setMerkleRootAirDrop` или `setMerkleRootWhiteList`. Метод будет вызываться админом и таким образом, мы установим на контракт Root hash для каждого этапа, по которому контракт будет проверять, есть ли пользователь в вайтлисте или нет. + +Так же для того, что бы вызывать методы `claimAirdrop`, `whitelistMint`, `canClaimAirDrop` и `isWhiteListed` - вам понадобится передавать в них массив `proof`. Каждому листку дерева Меркла (каждому кошельку) соответствует свой массив `proof`. Получить его можно следующим образом - `merkleTree.getHexProof(keccak256(address))`. + +Так как дерево Меркла создаётся в админ панели, а массив `proof` необходимо использовать в основном приложении, то встаёт вопрос о том, где и как хранить массив `proof` для каждого адреса из вайтлиста. Так как у нас нет своей базы данных, то воспользуемся децентрализованным хранилищем - IPFS. Данные будут храниться в формате JSON в следующем виде: + +```json +{ + "airdrop": [ // для этапа airdrop + { + "address": "0x0000000000000000000000000000000000000000", + "proof": [ + "0x00314e565e0574cb412563df634608d76f5c59d9f817e85966100ec1d48005c0", + "0x1ebaa930b8e9130423c183bf38b0564b0103180b7dad301013b18e59880541ae" + ] + }, + { + "address": "0x0000000000000000000000000000000000000000", + "proof": [ + "0xe9707d0e6171f728f7473c24cc0432a9b07eaaf1efed6a137a4a8c12c79552d9", + "0x1ebaa930b8e9130423c183bf38b0564b0103180b7dad301013b18e59880541ae" + ] + } + ], + "private": [...] // для этапа private presale +} +``` + +Таким образом в админ панели данные о массиве `proof` для каждого адреса будут загружаться в IPFS ([как загрузить в IPFS?](./how-to-IPFS.md)). А в основном приложении данные будут считываться из IPFS. После чего будет происходить поиск по `address` для конкретного адреса и соответствующий `proof` будет передаваться на контракт при вызове вышеупомянутых методов. + +Методы на чтение: + +- `getMerkleRootAirDrop` - возвращает Root hash для вайтлиста, который используется на этапе airdrop. +- `getMerkleRootWhiteList` - возвращает Root hash для вайтлиста, который используется на этапе private presale. +- `getMerkleProofs` - возвращает IPFS хэш, в котором должен лежать JSON файл с массивами `proof`. +- `canClaimAirDrop` - проверяет, есть ли указанный кошелёк в вайтлисте airdrop. +- `isWhiteListed` - проверяет, есть ли указанный кошелёк в вайтлисте private presale. + +Методы на запись: + +- `setMerkleRootAirDrop` - устанавливает Root hash для вайтлиста, который используется на этапе airdrop. Может вызвать только `WHITE_LIST_MANAGER_ROLE`. +- `setMerkleRootWhiteList` - устанавливает Root hash для вайтлиста, который используется на этапе private presale. Может вызвать только `WHITE_LIST_MANAGER_ROLE`. +- `setMerkleProofs` - устанавливает IPFS хэш, в котором будет лежать JSON файл с массивами `proof`. Может вызвать только `WHITE_LIST_MANAGER_ROLE`. + + +### Другие методы на чтение + +- `CAT` - строка `bytes32`, которую необходимо подписать пользователю перед вызовом метода `mint` на этапе public sale. Подробнее в описании метода `mint`. +- `MAX_AIRDROP_MINT` - максимальное количество NFT, которое можно получить на этапе airdrop. +- `MAX_WHITELIST_MINT` - максимальное количество NFT, которое можно получить на этапе private presale. +- `MAX_PUBLIC_MINT` - максимальное количество NFT, которое можно получить на этапе public sale. +- `MAX_SUPPLY` - максимальное количество NFT, которое могут сминтить все пользователи суммарно. +- `tokenURI` - возвращает ссылку на метаданные для указанного `tokenId`. Метаданные как правило хранятся на IPFS и содержат в себе различную информацию о конкретном токене - ссылку на картинку, описание, атрибуты и др. [Пример метаданных](https://ipfs.io/ipfs/QmNe7EebKaNuRoN2ov9nMuwHXQvXbYXCLM9W1nDBxnqLgL/1.json). +- `placeholderTokenUri` - возвращает ссылку на метаданные-заглушку, которая будет возвращаться для всех `tokenUri` до тех пор, пока `isRevealed === false`. +- `isRevealed` - состояние контракта, по умолчанию `false`. Пока `false`, все `tokenUri` будут возвращать `placheloderTokenUri`, то есть метаданные-заглушку. Когда станет `true`, `tokenUri` будет возвращать настоящие метаданные для каждого токена. Зачем это нужно? Представьте, что владелец продукта не хочет раскрывать пользователям, какие NFT они сминтили до тех пор, пока не пройдут все этапы минтинга. Для этого он может переключать состояние `isRevealed` и в нужный для себя момент раскрыть информацию о каждом сминченном токене всем пользователям. +- `allowedToClaimDropAmount` - количество NFT, которое пользователю осталось сминтить на этапе airdrop. +- `allowedToWhiteListMintAmount` - количество NFT, которое пользователю осталось сминтить на этапе private presale. +- `allowedToPublicMintAmount` - количество NFT, которое пользователю осталось сминтить на этапе public sale. +- `whiteListSalePrice` - стоимость покупки одной NFT на этапе private presale. +- `publicSalePrice` - стоимость покупки одной NFT на этапе public sale. +- `totalAirdropMint` - возвращает количество NFT, которое сминтил указанный адрес на этапе airdrop. +- `totalWhitelistMint` - возвращает количество NFT, которое сминтил указанный адрес на этапе private presale. +- `totalPublicMint` - возвращает количество NFT, которое сминтил указанный адрес на этапе public sale. +- `tokensOfOwner` - возвращает список ID токенов, которыми владеет указанный адрес. +- `totalSupply` - общее количество сминченных NFT. + +### Другие методы на запись + +- `setPlaceHolderUri` - устанавливает ссылку на метаданные-заглушку, которую будет возвращать `tokenUri` до тех пор, пока `isRevealed === false`. Может вызвать только `DEFAULT_ADMIN_ROLE`. +- `setTokenUri` - устанавливает ссылку на метаданные. Может вызвать только `DEFAULT_ADMIN_ROLE`. +- `toggleReveal` - переключает состояние `isRevealed` на противоположное (см. методы на чтение). Может вызвать только `SELL_PHASE_MANAGER_ROLE`. +- `claimAirdrop` - минтинг NFT на этапе airdrop. Принимает количество NFT и массив `proof`. Благодаря массиву `proof` контракт может проверить, есть ли пользователь в вайтлисте airdrop или нет. +- `whitelistMint` - покупка NFT на этапе private presale. Принимает количество NFT, нативный токен для оплаты, а так же массив `proof`. Благодаря массиву `proof` контракт может проверить, есть ли пользователь в вайтлисте private presale или нет. +- `mint` - покупка NFT на этапе public sale. Принимает количество NFT, нативный токен для оплаты, а так же сигнатуру подписи (`signature`). Сигнатуру подписи можно получить, подписав пользователем специальное сообщение. В нашем случае это строка `bytes32` слова `CAT` (см. методы на чтение). Данную строку необходимо прогнать через утилиту `toBytes` из `viem` и передать в метод `signMessage` из `wagmi`. Метод попросит пользователя подписать сообщение и после подписи вернёт сигнатуру, которую и необходимо передать в вызов `mint`. В итоге, пользователь сначала подписывает сообщение, а затем вызывается `mint`. \ No newline at end of file diff --git a/frontend-web3/practice/how-to-IPFS.md b/frontend-web3/practice/how-to-IPFS.md new file mode 100644 index 00000000..ce028efb --- /dev/null +++ b/frontend-web3/practice/how-to-IPFS.md @@ -0,0 +1,48 @@ +# Как загрузить данные в IPFS? + +Так как IPFS - это децентрализованное хранилище, то загружать и читать из него данные можно напрямую, а можно используя сторонние решения, которые предоставляют более удобный API. Можно воспользоваться одним из таких решений - [thirdweb](https://portal.thirdweb.com/typescript/v5). Сама по себе библиотека предоставляет много чего, но нас интересует только работа с IPFS. + +Заранее зарегистрируйтесь и в [личном кабинете](https://thirdweb.com/dashboard/settings/api-keys) получите clientId. + +```ts +import { createThirdwebClient } from 'thirdweb'; +import { download, upload } from 'thirdweb/storage'; + +const proofs = { // Объект с пруфами, будущий JSON файл + airdrop: [ + { + address: '0x0000000000000000000000000000000000000000', + proof: [ + '0x00314e565e0574cb412563df634608d76f5c59d9f817e85966100ec1d48005c0', + '0x1ebaa930b8e9130423c183bf38b0564b0103180b7dad301013b18e59880541ae', + ], + }, + { + address: '0x0000000000000000000000000000000000000000', + proof: [ + '0xe9707d0e6171f728f7473c24cc0432a9b07eaaf1efed6a137a4a8c12c79552d9', + '0x1ebaa930b8e9130423c183bf38b0564b0103180b7dad301013b18e59880541ae', + ], + }, + ], + private: [...], +}; + +const clientId = process.env.clientId; // ваш clientId, который нужно получить в личном кабинете, на сайте thirdweb +const client = createThirdwebClient({ clientId }); + +// загрузка в IPFS +const file = new File([JSON.stringify(proofs)], '1.json'); +const uri = await upload({ + client, + files: [file], +}); + +// После загрузки, полученный uri необходимо сохранить на контракте, вызвав метод setMerkleProofs. После этого можно будет в любой момент получить этот uri из контракта, вызвав метод getMerkleProofs и передать его в функцию download, как написано ниже. + +// получение данных из IPFS +const file = await download({ + client, + uri, +}); +``` \ No newline at end of file diff --git a/frontend-web3/practice/test-erc-20-tokens.md b/frontend-web3/practice/test-erc-20-tokens.md new file mode 100644 index 00000000..65e074d5 --- /dev/null +++ b/frontend-web3/practice/test-erc-20-tokens.md @@ -0,0 +1,47 @@ +# Тестовые ERC-20 токены + +У каждого нижеперечисленного токена можно вызвать метод claim, который отправит на ваш баланс 10000 токенов. + +## Sepolia + +ARB - [0xf300c9bf1A045844f17B093a6D56BC33685e5D05](https://sepolia.etherscan.io/address/0xf300c9bf1A045844f17B093a6D56BC33685e5D05#code) + +DAI - [0xA68ecAb53bdcFdC753378a088CfB29d42915617E](https://sepolia.etherscan.io/address/0xA68ecAb53bdcFdC753378a088CfB29d42915617E#code) + +DOGE - [0xd409ffeb2f2e9dB0A75483a6417776CD6D7Ce774](https://sepolia.etherscan.io/address/0xd409ffeb2f2e9dB0A75483a6417776CD6D7Ce774#code) + +LINK - [0x53BB015921600B6E4b373125B90143090F957d50](https://sepolia.etherscan.io/address/0x53BB015921600B6E4b373125B90143090F957d50#code) + +OP - [0x54d412Fee228E13A42F38bC760faEFfDFE838536](https://sepolia.etherscan.io/address/0x54d412Fee228E13A42F38bC760faEFfDFE838536#code) + +PEPE - [0x8903FE8C94F3b7db3482d53ccE000998d112cC7d](https://sepolia.etherscan.io/address/0x8903FE8C94F3b7db3482d53ccE000998d112cC7d#code) + +TRX - [0xd445682a9B9FE0aE4053056E005f9393413407e1](https://sepolia.etherscan.io/address/0xd445682a9B9FE0aE4053056E005f9393413407e1#code) + +USDT - [0x8aC43Ed0652168827FA3906577dD44e4819B11D1](https://sepolia.etherscan.io/address/0x8aC43Ed0652168827FA3906577dD44e4819B11D1#code) + +USDC - [0x85d30853B690eEfa87854f240a81b4621b13FDF8](https://sepolia.etherscan.io/address/0x85d30853B690eEfa87854f240a81b4621b13FDF8#code) + +WBTC - [0x8805B377F0a28846198e81120179C4Ca5c6D5318](https://sepolia.etherscan.io/address/0x8805B377F0a28846198e81120179C4Ca5c6D5318#code) + +## Polygon Amoy + +ARB - [0x34cd8b477eb916c1c4224b2FFA80DE015cCC671b](https://amoy.polygonscan.com/address/0x34cd8b477eb916c1c4224b2FFA80DE015cCC671b#code) + +DAI - [0x1519d41F48F3621bCd583aa646C95217F87D3A99](https://amoy.polygonscan.com/address/0x1519d41F48F3621bCd583aa646C95217F87D3A99#code) + +DOGE - [0x0de27cBf804F1665eBc2F927944f54aA70cB4fC1](https://amoy.polygonscan.com/address/0x0de27cBf804F1665eBc2F927944f54aA70cB4fC1#code) + +LINK - [0xaa79133956a0F53Ef774c5b0e302784caF4A8Cc2](https://amoy.polygonscan.com/address/0xaa79133956a0F53Ef774c5b0e302784caF4A8Cc2#code) + +OP - [0x8E4eCf56B8736A83CE17213187118231D3C06FFF](https://amoy.polygonscan.com/address/0x8E4eCf56B8736A83CE17213187118231D3C06FFF#code) + +PEPE - [0x0c02cb84eEF5f3EA61be9DfeC7F884dffc1fa6c0](https://amoy.polygonscan.com/address/0x0c02cb84eEF5f3EA61be9DfeC7F884dffc1fa6c0#code) + +TRX - [0xEe7356FB1362fD659D03892719d424Bd8D9D8f70](https://amoy.polygonscan.com/address/0xEe7356FB1362fD659D03892719d424Bd8D9D8f70#code) + +USDT - [0x0a6DFA1eEf85B94E7e753bA222A6AcF2aE6C1a8b](https://amoy.polygonscan.com/address/0x0a6DFA1eEf85B94E7e753bA222A6AcF2aE6C1a8b#code) + +USDC - [0x6fD3B0bfB19Dc9C02f79E1e6E32444A390842700](https://amoy.polygonscan.com/address/0x6fD3B0bfB19Dc9C02f79E1e6E32444A390842700#code) + +WBTC - [0x36Ea22735269Cb7AA2A931Dd871a73c0a9124f2B](https://amoy.polygonscan.com/address/0x36Ea22735269Cb7AA2A931Dd871a73c0a9124f2B#code) \ No newline at end of file diff --git a/frontend/junior-1/css.md b/frontend/junior-1/css.md index a6160f18..480edeb5 100644 --- a/frontend/junior-1/css.md +++ b/frontend/junior-1/css.md @@ -83,6 +83,7 @@ * `transition-duration` * `transition-property` * `transition-timing-function` + * `transition-behavior` * Можно ли задать несколько анимаций для элемента? * Трансформации * Что делает свойство `transform`? Какие значения ему можно задавать? @@ -95,7 +96,7 @@ * Как пользоваться `vh`, `vw`, `vmin`, `vmax`? * Что делает свойство `object-fit`? * Что делает свойство `aspect-ratio`? -* Как стилизовать чекбокс? +* Как стилизовать чекбокс (практика)? * Как прижать футер к низу страницы (назвать хотя бы два способа)? * Как отцентровать элемент по горизонтали (назвать хотя бы три способа)? * Как отцентровать элемент по вертикали (назвать хотя бы три способа)? diff --git a/frontend/junior-1/html.md b/frontend/junior-1/html.md index e4a0c8b5..e3d3b900 100644 --- a/frontend/junior-1/html.md +++ b/frontend/junior-1/html.md @@ -36,7 +36,7 @@ * Как препроцессоры помогают избежать боли с дублированием названий в коде? * Какие альтернативы есть БЭМ и в чем сила/слабость каждого? Знать хотя бы 2 альтернативы данному подходу, плюсы/минусы подходов. * Что такое миксы в БЭМе и какие особенности работы с ними есть? - * Как бы отрефакторили данный код: + * Как бы отрефакторили данный код (практика): ```html
diff --git a/frontend/junior-1/js.md b/frontend/junior-1/js.md index 2b45ef20..6284379a 100644 --- a/frontend/junior-1/js.md +++ b/frontend/junior-1/js.md @@ -85,7 +85,7 @@ * Как получить все аргументы функции (включая те, что не объявлены, но все-таки были переданы)? * Что такое рекурсия? Когда удобно её использовать? * Что такое замыкания, и в каких случаях они могут быть полезны? Как сохранить состояние с помощью замыкания, и для чего это состояние может быть использовано? -* Как реализовать функцию `bind`? +* Как реализовать функцию `bind` (практика)? * Решить такую вот проблему: пускай у нас есть массив ссылок, и наша задача — сделать так, чтобы при клике на каждую выводился `alert`ом ее порядковый номер. Первое решение, что приходит в голову, выглядит так: ```javascript for (var i = 0; i < links.length; i++) { @@ -94,7 +94,7 @@    } } ``` - На деле же оказывается, что при клике на любую ссылку выводится одно и то же число — значение `links.length`. Почему так происходит и как эту гадость исправить? + На деле же оказывается, что при клике на любую ссылку выводится одно и то же число — значение `links.length`. Почему так происходит и как эту гадость исправить (практика)? * Что такое callback (функция обратного вызова)? Когда они обычно применяются? * Что такое каррирование? * Что такое частичное применение? @@ -120,7 +120,7 @@ * Как создать объект, который ни от чего не наследуется? * Какие 3 (как минимум) способа есть отнаследоваться в JavaScript-е? В чем отличия и нюансы? * Как объявить приватное поле класса в JS? -* Как в переопределенном методе у наследующего класса вызвать переопределяемый метод родительского? +* Как в переопределенном методе у наследующего класса вызвать переопределяемый метод родительского (практика)? Пример псевдокода: ```javascript class Person diff --git a/frontend/junior-1/react.md b/frontend/junior-1/react.md index 201ccc09..73bafd50 100644 --- a/frontend/junior-1/react.md +++ b/frontend/junior-1/react.md @@ -1,13 +1,15 @@ # React * Что такое React? +* Что такое декларативное UI программирование? Чем оно отличается от императивного подхода? * Что такое React Element? Как его можно создать? Из чего он состоит? * Что будет, если передать булевые, `null` или `undefined` значения в children? + * В чем разница между `ReactElement`, `JSX.Element`, `ReactNode`? Какой тип выбрать для типизации значения на рендер? * Что такое React Component? * Что такое JSX и зачем он нужен? * Почему атрибуты в JSX пишутся, используя camelCase (например, `tabIndex`, а не `tab-index`)? Почему `className`, а не `class`? * Почему название компоненты, которая используется в JSX, нужно писать с большой буквы? - * Написать аналог с `React.createElement`: + * Написать аналог с `React.createElement` (практика): ```javascript ``` * Что такое Virtual DOM и зачем он нужен? +* Что такое React Fragment? Для чего он нужен? Как его использовать? * Что такое `props` у компонента? +* `props.children` + * Что это такое? + * Когда может быть полезным? + * Что позволяет делать `React.Children` API? * Что такое условный рендеринг? * В чём проблема следующего кода `

{items.length && }

`? +* Что такое чистые компоненты и почему компоненты должны быть чистыми (не путать с `React.PureComponents`)? + * Где можно вызывать побочные эффекты? * Что такое хуки? * Какие существуют правила при работе с хуками? +* `use` + * Для чего предназначен? + * Какие есть условия для использования в клиентских компонентах? Можно ли использовать в серверных компонентах? + * Какие правила хуков может игнорировать, а какие нет? + * Что произойдет, если `promise` стал rejected? * Что такое `stateful` и `stateless` компоненты? - * Что делает хук `useState`? Как обновить состояние? - * Как обновить состояние из `useState` на основе предыдущего значения? Какие могут при этом возникнуть проблемы? + * Что делает хук `useState`? Как обновить состояние? + * Произойдет ли ререндер компонента, если сеттер установил значение, совпадающее с предыдущим? + * Как обновить состояние из `useState` на основе предыдущего значения? Какие могут при этом возникнуть проблемы? * Что такое top-down data flow? Что является основным механизмом синхронизации нескольких компонент? +* Controlled и uncontrolled компоненты + * Что это такое? Как происходит работа с инпутами? + * Как задать дефолтное значение для инпута в uncontrolled компоненте? * Lifecycle of reactive effects * Что это такое? * Что такое эффекты? Что означает "синхронизация с эффектом"? * Для чего предназначен хук `useEffect`? Как с ним работать? + * Что такое массив зависимостей? Как он влияет на работу `useEffect`? * Что может возвращать колбэк, передаваемый в `useEffect`? - * Что такое массив зависимостей? Рассказать как он влияет на работу хука на примере useEffect (в том числе на возвращаемое колбэком значение). + * Для чего не должен использоваться `useEffect`? Почему? * У вас есть несколько эффектов. Куда вы их поместите, в один общий `useEffect` или в разные? Почему? -* `props.children` - * Что это такое? - * Когда может быть полезным? - * Что позволяет делать `React.Children` API? -* Что такое чистые компоненты и почему компоненты должны быть чистыми (не путать с `React.PureComponents`)? - * Где можно вызывать побочные эффекты? -* Что такое React Fragment? Для чего он нужен? Как его использовать? * refs * Что это такое? Зачем нужны? Как их использовать? - * Как и для чего использовать хук `useRef`? - * Что делает и зачем нужен метод `React.forwardRef`? + * Как и для чего использовать хуки `useRef` и `useImperativeHandle`? + * Вам необходимо передать ref в каждый элемент списка, но вы не знаете заранее сколько элементов в этом списке может быть. Как поступить в таком случае (практика)? + +
+ Подробности: + + ```jsx + + ``` + +
+ * Почему refs стоит использовать умеренно? -* Controlled и uncontrolled компоненты - * Что это такое? Как происходит работа с инпутами? - * Как задать дефолтное значение для инпута в uncontrolled компоненте? ### Ресурсы -* [React Documentation](https://reactJS.org/docs/getting-started.html) -* [New React Documentation](https://beta.reactjs.org/) +* [React Documentation](https://react.dev/learn) * [Making Sense of React Hooks](https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889) * [React hooks: not magic, just arrays](https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e) -* [Keeping Components Pure](https://beta.reactjs.org/learn/keeping-components-pure) -* [Lifecycle of reactive effects](https://beta.reactjs.org/learn/lifecycle-of-reactive-effects) +* [Keeping Components Pure](https://react.dev//learn/keeping-components-pure) +* [Lifecycle of reactive effects](https://react.dev//learn/lifecycle-of-reactive-effects) +* [How to manage a list of refs using a ref callback](https://react.dev/learn/manipulating-the-dom-with-refs#how-to-manage-a-list-of-refs-using-a-ref-callback) diff --git a/frontend/junior-2/html.md b/frontend/junior-2/html.md index d4589750..b9446398 100644 --- a/frontend/junior-2/html.md +++ b/frontend/junior-2/html.md @@ -29,7 +29,7 @@ * Тег `