Эй, сегодня я покажу нам, как легко создать децентрализованное приложение.

Теперь это просто для образовательных целей, но в этой статье вы увидите, как работает децентрализованное приложение и почему оно удивительное и инновационное.

Что мы строим?

Мы создадим простую игру-угадайку, используя Solidity, но на блокчейне. Звучит круто, верно? Приступим к делу.

Что нам нужно?

  1. Аккаунт в Alchemy, зарегистрируйтесь бесплатно здесь.
  2. Кошелёк metamask, (скачать только по официальной ссылке).
  3. Solidity и Hardhat (мы поговорим о них позже).

Инициализация нашего проекта

Предполагается, что вы немного знакомы с node.js и уже установили его на своем терминале, запустите:

npm init

Установка и инициализация каски

Это должно запустить файл package.json, чтобы он мог отслеживать наши зависимости. Далее мы собираемся установить каску.

npm install --save-dev hardhat

Hardhat — это среда разработки для компиляции, развертывания, тестирования и отладки программного обеспечения Ethereum, а Polygon — решение второго уровня для Ethereum. Это помогает разработчикам создавать смарт-контракты и dApps локально перед развертыванием в живой цепочке.

После завершения установки запустите это, чтобы создать новый проект каски.

npx hardhat

Вы должны увидеть это на своем терминале, просто нажмите Enter, так как настройки по умолчанию подходят для этого урока.

Хранение наших ключей

Мы почти закончили настройку, нам нужен способ безопасного хранения наших ключей, поэтому запустите:

npm install dotenv

Когда установка будет завершена, создайте файл с именем .env, через мгновение мы сохраним в нем наши ключи.

ВНИМАНИЕ! Если вы используете систему контроля версий, такую ​​как git, для управления своим проектом, НЕ отслеживайте файл .env. Добавьте .env в свой файл .gitignore, чтобы случайно не опубликовать свои секреты в мире.

Настройка Алхимии

Alchemy — это платформа для разработчиков блокчейнов, которая позволяет нам взаимодействовать с цепочкой Polygon без необходимости создавать собственные узлы, поэтому обязательно зарегистрируйтесь, указав ссылку.

После регистрации учетной записи вы можете генерировать ключи API, создав приложение.

Теперь вы можете легко скопировать свои API-КЛЮЧИ и сохранить их в файле .env, добавив в него это.

API_URL = "https://polygon-mumbai.g.alchemy.com/v2/your-api-key"

Конфигурация метамаски

После создания учетной записи выполните следующие действия, чтобы настроить сеть Polygon в своем кошельке.

Выберите «Настройки» в раскрывающемся меню в правом верхнем углу вашего кошелька Metamask.

Выберите «Сети» в меню слева.

Подключите свой кошелек к Mumbai Testnet, используя следующие параметры.

Имя сети: Polygon Mumbai Testnet
Новый URL RPC: https://polygon-mumbai.g.alchemy.com/v2/your-api-key
ChainID: 80001
> Символ: MATIC
URL-адрес обозревателя блоков: https://mumbai.polygonscan.com/

Получение тестовых токенов

Далее вам понадобится поддельный MATIC для тестирования, вы можете получить его в Polygon Mumbai Testnet. Выберите Мумбаи, выберите MATIC Token и введите адрес своего кошелька Polygon, затем нажмите Отправить. Получение поддельного Eth может занять некоторое время из-за сетевого трафика.

Экспортируйте и скопируйте закрытый ключ кошелька метамаски, а также включите его в файл .env.

PRIVATE_KEY = "your-metamask-private-key"

Ваш файл .env должен выглядеть так, подробнее о файлах переменных окружения читайте здесь.

Игра Угадай

Перейдите в каталог контрактов и создайте новый файл Solidity, запустите:

cd contracts && touch Guess_Game.sol

Теперь откройте Guess_Game.sol и вставьте его, обязательно прочитайте комментарии, чтобы понять, как это работает.

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import "../node_modules/hardhat/console.sol";

// Check out the official documentation to learn more about every concept here: https://docs.soliditylang.org/en/v0.8.13/index.html
contract Guess_Game {

    //  Declared state variables whose values are permanently stored in contract storage.
    uint random_number;
    bool game_completion;
    address winner;

    // This is a Struct that defines value for the user interacting with the smart contract
    struct player {
        uint guess;
        uint trials;
        bool registered;
    }

    // Created a mapping of an address to the player Struct
    mapping (address => player) player_structs;

    // Created a dynamic array of player addresses 
    address[] internal players_addresses;


    // Defining the Contructor which is a block of code that runs the instant the contract is deployed
    constructor() {

        // Depending on the timestamp of the current block, the keccak function will generate a random number and we're keeping it between 1 and 100
        random_number = uint(keccak256(abi.encodePacked(block.timestamp))) % 100;

        // When the contract is deployed, we initialize this variable as false since no one has won yet
        game_completion = false;
    }

    // Generates a new struct with msg.sender which just the user's wallet address and appends it to the array 
    function set_Player() internal {
        player_structs[msg.sender].guess = 0;
        player_structs[msg.sender].trials = 5;
        player_structs[msg.sender].registered = true;

        players_addresses.push(msg.sender);
    }

    // A function for verifying if a user has been tried to guess before and is registered
    function get_Player(address _player) internal view returns(bool) {
        return player_structs[_player].registered;
    }

    // This function is visible to the user, it reads the user's input and calls the game function
    function Guess(uint _Guess) public {
        if (game_completion) {
            console.log("Game has been completed and the winning address is ", winner);
        }

        // Checks to see if player has been assigned a struct
        if (get_Player(msg.sender) != false) {
            set_Player();
        }

        // Passes in the input and stores it for that particular player
        player_structs[msg.sender].guess = _Guess;

        Game();
    }

    // The Game Logic, this internal function is called whenever a guess is made
    function Game() internal {
        uint guess = player_structs[msg.sender].guess;
        uint attempts = player_structs[msg.sender].trials;

        if (attempts > 0) {
            if (guess > random_number) {
                console.log("Your guess was too big, Guess again");
            }

            else if (guess < random_number) {
                console.log("Your guess was too small, Guess again");
            }

            else if (guess == random_number && game_completion) {
                console.log("You got the number but the game has already been won");
            }

            else if (guess == random_number && !game_completion) {
                console.log("Congrats! You won the guess game first");
                winner = msg.sender;
                game_completion = true;
            }
        }

        else {
            console.log("You're out of attempts");
        }
    }
}

Подключите Metamask & Alchemy к вашему проекту

Мы создали кошелек Metamask и учетную запись Alchemy и написали наш смарт-контракт, теперь пришло время соединить все три.

Наши ключи для кошелька и учетной записи Alchemy уже сохранены, поэтому пришло время обновить наш файл hardhat.config.js, чтобы иметь возможность инициировать подключение.

Перейдите в свой корневой каталог и обновите файл hardhat.config.js, чтобы он выглядел следующим образом:

/**
* @type import('hardhat/config').HardhatUserConfig
*/

require('dotenv').config();
require("@nomiclabs/hardhat-ethers");

const { API_URL, PRIVATE_KEY } = process.env;

module.exports = {
  solidity: "0.8.9",
  defaultNetwork: "polygon_mumbai",
  networks: {
    hardhat: {},
    polygon_mumbai: {
      url: API_URL,
      accounts: [`0x${PRIVATE_KEY}`]
    }
  },
}

Скомпилируйте наш договор

Чтобы убедиться, что пока все работает, давайте скомпилируем наш контракт. Задача компиляции — одна из встроенных задач каски.

Из командной строки запустите:

npx hardhat compile

Разверните наш контракт

Наш контракт написан, и наш файл конфигурации тоже готов к работе, пришло время написать наш сценарий развертывания контракта, чтобы мы могли развернуть контракт.

Перейдите в папку scripts/ и создайте новый файл с именем deploy.js и добавьте в него следующее:

async function main() {
    const Guess_Game = await ethers.getContractFactory("Guess_Game");

    // Start deployment, returning a promise that resolves to a contract object
    const guess_game = await Guess_Game.deploy(); 
    console.log("Contract deployed to address:", guess_game.address);
   }

   main()
    .then(() => process.exit(0))
    .catch(error => {
    console.error(error);
    process.exit(1);
    });

Обязательно ознакомьтесь с документами каски, чтобы понять, что делает каждая строка.

Время развертывания

Теперь, наконец, пришло время для развертывания. Перейдите в командную строку и запустите:

npx hardhat run scripts/deploy.js --network polygon_mumbai

Затем вы должны увидеть что-то вроде:

Contract deployed to address: 0x56D94982E71867c007c57659d5a2b199E581b502

Скопируйте этот адрес; давайте проверим это, заходим в Polygon Mumbai explorer и ищем адрес нашего контракта, мы должны увидеть, что он был успешно развернут.

Поздравляю! Вы только что развернули смарт-контракт в цепочке Polygon. 🎉

Чтобы понять, что происходит под капотом, перейдите на вкладку «Проводник» на панели инструментов Alchemy «Игра в угадайку».

В последующих статьях мы создадим пользовательский интерфейс для этого децентрализованного приложения. Вот репозиторий Github для приведенного выше кода.

Спасибо, что дочитали до конца, отзывы всегда приветствуются.

Первоначально опубликовано на https://dev.to 4 мая 2022 г.