# Как делать CTF для Web3?
## Шаг 0. Как выглядит Web3 приложение?
Web3 приложение состоит из двух частей: смартконтракта и клиента.
Смартконтракт находится на блокчейне и выполняет всю бэкенд логику приложения. Клиент (android приложение, desktop, web) использует публичные смартконтракты и рисует пользователю красивые окошки.
Кроме этих двух компонентов, в схеме взаимодействия так же присутсвует кошелёк - это представление аккаунта пользователя на блокчейне, которое позволяет клиентскому приложению использовать блокчейн.
## Шаг 1. Настройка testnet
В качестве testnet будем использовать ganache-cli на локальной машине.
Для начала установим его:
```bash=
yay -S ganache-cli
```
Далее нам понадобится RPC провайдер для ноды. URL RPC провайдера можно получить на alchemy.com или infura.io
Теперь запустим ganache-cli:
```
ganache-cli -f <RPC provider URL>
```
Ganache выводит набор приватных ключей для аккаунтов с балансами по 100 ETH. Скопируем один из этих ключей - он понадобится нам позже.

## Шаг 2. Разработка смартконтракта
IDE для разработки: http://remix.ethereum.org/
Для примера далее будем использовать следующий смартконтракт:
```solidity=
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Task1 {
string private flag;
address private owner;
constructor(string memory newFlag) {
flag = newFlag;
}
function getFlag() public returns (string memory) {
require(msg.sender == owner);
return flag;
}
function changeOwner() public {
owner = msg.sender;
}
}
```
Тут есть две публичные функции - getFlag() и changeOwner()
## Шаг 3. Создание скрипта для деплоя смартконтракта
Для деплоя смартконтракта будем использовать hardhat - https://hardhat.org/
Создаём hardhat проект:
```
npx hardhat
```
Выбираем 'create JS project'
Далее, в папку contracts ложим написанный нами контракт, назовём его Task1.sol
Контракт-пример (Lock.sol), нужно удалить
В hardhat.config.js надо указать правильную версию solidity:

Установим ganache для hardhat:
```bash
npm install --save-dev @nomiclabs/hardhat-ganache
```
Добавим эту строчку в начало hardhat.config.js
```javascript=
require("@nomiclabs/hardhat-ganache");
```
Изменим scripts/deploy.js
```javascript=
// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat
// will compile your contracts, add the Hardhat Runtime Environment's members to the
// global scope, and execute the script.
const hre = require("hardhat");
async function main() {
const Task = await hre.ethers.getContractFactory("Task1");
const task = await Task.deploy('ctf{flag}');
await task.deployed();
console.log(
`Task deployed to ${task.address}`
);
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
```
И задеплоим на ganache:
```bash=
npx hardhat run --network ganache scripts/deploy.js
```
## 4. Создание сайта для web3
Создадим отдельную папку для форнтенда.
Будем использовать следующий HTML шаблон:
```htmlmixed=
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h1>CTF task #01</h1>
<button type="button-getflag" class="btn btn-outline-secondary my-3">Get flag</button><br/>
<button type="button-changeowner" class="btn btn-outline-secondary">Change owner</button>
</div>
</body>
</html>
```

#