# Как делать 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. Скопируем один из этих ключей - он понадобится нам позже. ![](https://i.imgur.com/ppCOS5f.png) ## Шаг 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: ![](https://i.imgur.com/lqAGJ6w.png) Установим 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> ``` ![](https://i.imgur.com/OJB9yJ5.png) #