Как построить прибыльную торговую площадку NFT с помощью React, Solidity и CometChat

Что вы будете строить, смотрите демонстрацию на тестовой сети Rinkeby и git-репо здесь…

Введение

Web3 — это будущее интернета, и мы все должны изучить и принять эту технологию. Ее применение продолжает появляться и оказывать положительное влияние на мир.

Одним из великолепных применений технологии web3 является создание недолговечных токенов (NFT), которые представляют собой жизнеспособное решение для оцифровки активов с сохранением прав собственности.

Этот учебник научит вас, как создать прибыльный и хорошо продуманный рынок NFT с функцией чата.

Записывайтесь ко мне на индивидуальные занятия, если вам нужно, чтобы кто-то помог вам быстрее освоить web3-разработку.

С этими словами, давайте начнем…

Загляните на мой канал YouTube, чтобы получить БЕСПЛАТНЫЕ уроки по web3 прямо сейчас.

Необходимые условия

Для успешного создания этой сборки вам понадобятся следующие установленные инструменты:

  • Node
  • Ganache-Cli
  • Truffle
  • React
  • Infuria
  • Tailwind CSS
  • CometChat SDK
  • Metamask
  • Yarn

Установка зависимостей

Установка NodeJs
Проверьте, что NodeJs уже установлен на вашей машине, и если нет, установите его ЗДЕСЬ. Запустите код еще раз в терминале, чтобы убедиться, что он установлен.

Установка Yarn, Ganache-cli и Truffle
Выполните приведенные ниже команды в терминале, чтобы установить эти важные пакеты глобально.

npm i -g yarn
npm i -g truffle
npm i -g ganache-cli
Войти в полноэкранный режим Выйдите из полноэкранного режима

Чтобы подтвердить установку, введите в терминале следующий код.

yarn --version && ganache-cli --version && truffle version
Войти в полноэкранный режим Выйти из полноэкранного режима

Клонирование стартового проекта Web3
Клонируйте стартовый проект web 3.0 с помощью команд, приведенных ниже. Это гарантирует, что мы все находимся на одной странице и используем одно и то же программное обеспечение.

git clone https://github.com/Daltonic/timelessNFT
Войти в полноэкранный режим Выход из полноэкранного режима

Отлично, пожалуйста, замените файл **package.json** на следующий:

После замены пакетов, как указано, запустите **yarn install** на вашем терминале, чтобы загрузить все пакеты с указанными версиями.

Настройка CometChat SDK

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

ШАГ 1:
Зайдите в CometChat Dashboard и создайте учетную запись.

ШАГ 2:
Войдите в приборную панель CometChat, только после регистрации.

ШАГ 3:
В приборной панели добавьте новое приложение под названием timelessNFT.

ШАГ 4:
Выберите только что созданное приложение из списка.

ШАГ 5:
Из Быстрого запуска скопируйте APP_ID, REGION, и AUTH_KEY, в ваш файл .env. См. изображение и фрагмент кода.

Замените ключи-заместители REACT_COMET_CHAT на соответствующие значения.

REACT_APP_COMET_CHAT_REGION=**
REACT_APP_COMET_CHAT_APP_ID=**************
REACT_APP_COMET_CHAT_AUTH_KEY=******************************
Вход в полноэкранный режим Выход из полноэкранного режима

Настройка приложения Infuria

ШАГ 1:
Перейдите на сайт Infuria, создайте учетную запись.

ШАГ 2:
На приборной панели создайте новый проект.

ШАГ 3:
Скопируйте URL конечной точки WebSocket тестовой сети Rinkeby в файл .env.

После этого введите секретную фразу Metamask и закрытый ключ предпочитаемого аккаунта. Если вы правильно следовали инструкциям, ваши переменные окружения должны выглядеть следующим образом.

ENDPOINT_URL=***************************
DEPLOYER_KEY=**********************

REACT_APP_COMET_CHAT_REGION=**
REACT_APP_COMET_CHAT_APP_ID=**************
REACT_APP_COMET_CHAT_AUTH_KEY=******************************
Вход в полноэкранный режим Выйти из полноэкранного режима

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

Доступ к закрытому ключу Metamask

ШАГ 1:
Убедитесь, что Rinkeby выбран в качестве тестовой сети в расширении браузера Metamask. Затем на предпочитаемом аккаунте нажмите на вертикальную пунктирную линию и выберите детали аккаунта. Пожалуйста, смотрите изображение ниже.

ШАГ 2:
Введите свой пароль в поле и нажмите кнопку подтверждения, это позволит вам получить доступ к закрытому ключу вашей учетной записи.

ШАГ 3:
Нажмите на кнопку «экспортировать закрытый ключ», чтобы увидеть свой закрытый ключ. Убедитесь, что вы никогда не раскрываете свои ключи на публичных страницах, таких как Github. Именно поэтому мы добавляем его в качестве переменной среды.

ШАГ 4:
Скопируйте свой закрытый ключ в файл .env. Смотрите изображение и фрагмент кода ниже:

ENDPOINT_URL=***************************
SECRET_KEY=******************
DEPLOYER_KEY=**********************

REACT_APP_COMET_CHAT_REGION=**
REACT_APP_COMET_CHAT_APP_ID=**************
REACT_APP_COMET_CHAT_AUTH_KEY=******************************
Вход в полноэкранный режим Выход из полноэкранного режима

Что касается вашего SECRET_KEY, вам необходимо вставить вашу секретную фразу Metamask в отведенное место в файле окружения.

Смарт-контракт TimlessNFT

Здесь представлен полный код смарт-контракта; давайте рассмотрим все функции и переменные по очереди.

Импорт кода и информация о контракте
В приведенном ниже коде мы сообщили компилятору solidity идентификатор лицензии и версии компилятора, подходящие для компиляции этого кода.

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

import "./ERC721.sol";
import "./ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract TimelessNFT is ERC721Enumerable, Ownable {
  // codes goes in here...
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Также этот смарт-контракт использует некоторые смарт-контракты openzepplin's ERC721. Вам необходимо убедиться, что вы поместили их в ту же директорию, как показано на изображении ниже:

Перейдите по этой ссылке и загрузите эти смарт-контракты, как показано на изображении выше.

Объявление переменных состояния

using Strings for uint256;

mapping(string => uint8) existingURIs;
mapping(uint256 => address) public holderOf;

address public artist;
uint256 public royalityFee;
uint256 public supply = 0;
uint256 public totalTx = 0;
uint256 public cost = 0.01 ether;
Вход в полноэкранный режим Выйти из полноэкранного режима

Мы указали, что используем библиотеку string для выполнения операций uint to string. Далее мы также объявили связки для записи майнинга произведений NFT, а также для получения информации о текущем владельце токена.

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

Настройка событий и структур

event Sale(
    uint256 id,
    address indexed owner,
    uint256 cost,
    string metadataURI,
    uint256 timestamp
);

struct TransactionStruct {
    uint256 id;
    address owner;
    uint256 cost;
    string title;
    string description;
    string metadataURI;
    uint256 timestamp;
}

TransactionStruct[] transactions;
TransactionStruct[] minted;
Вход в полноэкранный режим Выход из полноэкранного режима

В предыдущем коде у нас есть событие sales, которое выдает данные от любой транзакции, происходящей на смарт-контракте, будь то майнинг или перевод NFT.

Мы разработали структуру транзакций для сбора данных о майнинге или передаче NFT. Используя определенную нами структуру транзакций, мы создали две переменные под названием transactions и minted.

Инициализация конструктора

constructor(
    string memory _name,
    string memory _symbol,
    uint256 _royalityFee,
    address _artist
) ERC721(_name, _symbol) {
    royalityFee = _royalityFee;
    artist = _artist;
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Конструктор принимает четыре параметра для инициализации смарт-контракта. Имя токена, символ, аккаунт исполнителя и плата за роялти за транзакцию. Имя токена и символ затем передаются в смарт-контракт ERC721 во время развертывания.

Алгоритм функции монетного двора

function payToMint(
    string memory title,
    string memory description,
    string memory metadataURI,
    uint256 salesPrice
) external payable {
    require(msg.value >= cost, "Ether too low for minting!");
    require(existingURIs[metadataURI] == 0, "This NFT is already minted!");
    require(msg.sender != owner(), "Sales not allowed!");


    uint256 royality = (msg.value * royalityFee) / 100;
    payTo(artist, royality);
    payTo(owner(), (msg.value - royality));

    supply++;

    minted.push(
        TransactionStruct(
            supply,
            msg.sender,
            salesPrice,
            title,
            description,
            metadataURI,
            block.timestamp
        )
    );

    emit Sale(
        supply,
        msg.sender,
        msg.value,
        metadataURI,
        block.timestamp
    );

    _safeMint(msg.sender, supply);
    existingURIs[metadataURI] = 1;
    holderOf[supply] = msg.sender;
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Приведенная выше функция отвечает за майнинг новых токенов на смарт-контракте. Вызывающий этот метод должен предоставить четыре параметра, которые включают: название НФТ, описание, URI метаданных и цену продажи НФТ после майнинга.

Чтобы убедиться в том, что НМТ чеканится, проводятся валидации, которые осуществляются соответствующим образом с выплатами за каждую чеканку. Кроме того, валидация гарантирует, что каждое художественное произведение уникально связано с токеном, и ни один другой токен не имеет такого же художественного произведения. Наконец, при проверке мы убедились, что вызывающий этот метод не является развертывателем смарт-контракта, это необходимо для того, чтобы не напутать ничего лишнего.

Следующей функцией является правило распределения платежей. Процент роялти идет исполнителю, а остальная часть эфиров идет владельцу.

Затем мы записали этот NFT в майнинговый массив и выдали событие продажи. Наконец, мы майнили NFT, записывая адрес звонящего как владельца токена.

Алгоритм функции передачи NFT

function payToBuy(uint256 id) external payable {
    require(msg.value >= minted[id - 1].cost, "Ether too low for purchase!");
    require(msg.sender != minted[id - 1].owner, "Operation Not Allowed!");

    uint256 royality = (msg.value * royalityFee) / 100;
    payTo(artist, royality);
    payTo(minted[id - 1].owner, (msg.value - royality));

    totalTx++;

    transactions.push(
        TransactionStruct(
            totalTx,
            msg.sender,
            msg.value,
            minted[id - 1].title,
            minted[id - 1].description,
            minted[id - 1].metadataURI,
            block.timestamp
        )
    );

    emit Sale(
        totalTx,
        msg.sender,
        msg.value,
        minted[id - 1].metadataURI,
        block.timestamp
    );

    minted[id - 1].owner = msg.sender;
}
Вход в полноэкранный режим Выход из полноэкранного режима

Приведенная выше функция принимает идентификатор NFT и совершает покупку NFT по установленной майнером (владельцем) цене.

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

Далее на счет исполнителя отправляется гонорар, а текущий владелец НМТ получает остаток.

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

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

Другие основные функции

// changes the price of an NFT
function changePrice(uint256 id, uint256 newPrice) external returns (bool) {
    require(newPrice > 0 ether, "Ether too low!");
    require(msg.sender == minted[id - 1].owner, "Operation Not Allowed!");

    minted[id - 1].cost = newPrice;
    return true;
}

// sends ethers to a specific account
function payTo(address to, uint256 amount) internal {
    (bool success, ) = payable(to).call{value: amount}("");
    require(success);
}

// returns all minted NFTs
function getAllNFTs() external view returns (TransactionStruct[] memory) {
    return minted;
}

// returns a specific NFT by token id
function getNFT(uint256 id) external view returns (TransactionStruct memory) {
    return minted[id - 1];
}

// returns all transactions
function getAllTransactions() external view returns (TransactionStruct[] memory) {
    return transactions;
}
Вход в полноэкранный режим Выход из полноэкранного режима

На этом разработка смарт-контракта закончена, дальше мы займемся созданием компонентов пользовательского интерфейса с помощью ReactJs.

Настройка скрипта развертывания

Еще одна вещь, которую необходимо сделать для смарт-контракта, — это настроить скрипт развертывания.

В проекте перейдите в папку migrations >> 2_deploy_contracts.js и обновите его с помощью приведенного ниже фрагмента кода.

const TimelessNFT = artifacts.require('TimelessNFT')

module.exports = async (deployer) => {
  const accounts = await web3.eth.getAccounts()
  await deployer.deploy(
    TimelessNFT, 
    'Timeless NFTs', 
    'TNT', 10, accounts[1]
  )
}
Вход в полноэкранный режим Выход из полноэкранного режима

Отлично, мы только что закончили смарт-контракт для нашего приложения; теперь пора приступить к интерфейсу DApp. Если вам нужен частный репетитор, который поможет вам изучить разработку смарт-контракта, запишитесь на занятия ко мне.

Разработка фронтенда

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

Компонент заголовка

Этот компонент был создан с помощью tailwind CSS и использует розовую кнопку Connect Wallet для доступа к кошельку Metamask. Приведенные ниже коды демонстрируют программирование.

Компонент героя

Этот компонент отвечает за отображение подключенного кошелька, а также за запуск модала, используемого для создания нового NFT. Кроме того, он отвечает за регистрацию или включение пользователей в чат один на один с продавцом NFT. Ниже приведен код, отвечающий за эти действия.

Компонент Artworks

Этот компонент отвечает за отображение списка НМТ, добытых на платформе, с помощью красиво оформленных карточек tailwind CSS. Каждая карточка содержит изображение НМТ, название, описание, цену и владельца. Как это реализовано, смотрите в кодах ниже.

Компонент транзакций

Этот компонент отвечает за отображение всех транзакций, которые произошли в нашем смарт-контракте. Например, транзакцией может быть покупка Элисоном NFT у Duke. Эта покупка будет отражена в этом компоненте как транзакция. См. фрагмент ниже.

Компонент нижнего колонтитула

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

Фантастика, это все для очевидных компонентов, давайте включим скрытые компоненты, которые вызываются только через модальный интерфейс.

Компонент CreateNFT

На этот компонент возложена обязанность чеканить новые NFT, предоставляя изображение, название, цену и описание. После нажатия кнопки Mint Now изображение загружается в IPFS (Inter Planetary File System) и возвращается URL изображения.

Возвращенный URL изображения вместе с данными NFT, указанными в форме, отправляется нашему смарт-контракту для майнинга сразу после того, как пользователь авторизует транзакцию в своем кошельке Metamask.

После завершения транзакции NFT попадает в список произведений искусства, и заинтересованные покупатели могут приобрести их и даже изменить цену. Подробности смотрите в приведенном ниже коде.

Компонент ShowNFT


Этот компонент отображает дополнительную информацию о конкретном NFT, предлагая владельцу кнопку для изменения цены, а покупателю — кнопку для покупки NFT или общения с продавцом. Подробнее см. код ниже.

Компонент UpdateNFT

Задача этого компонента — изменить цену НМТ. Это действие может быть выполнено только владельцем НМТ. Хотя эта возможность доступна, для осуществления этих изменений потребуется определенная плата за газ. Как только NFT обменяет руку с другим покупателем, новый владелец может решить увеличить цену, и именно поэтому эта опция была сделана доступной. Смотрите фрагмент кода ниже.

Компонент ChatList

Этот компонент отображает последние чаты, которые пользователь вел с продавцом или покупателем на платформе. Компонент также фиксирует последнее сообщение, которое было отправлено в разговоре. Щелчок по каждой беседе приведет к интерфейсу чата. Смотрите код ниже.

Компонент чата

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

Отлично, теперь, когда мы включили эти фантастические компоненты, давайте закончим с последними двумя.

Компонент загрузки

Этот компонент просто отображает текущую активность и статус, когда транзакция находится в процессе. Смотрите код ниже.

Компонент приложения
В этом файле собраны все компоненты, рассмотренные в данной работе. Именно так работает архитектура ReactJs. Смотрите код ниже.

Фантастика, мы только что завершили интеграцию различных компонентов, давайте скрепим их с другими частями этого проекта.

Другие важные файлы

Это приложение использует хранилище управления состояниями, CometChat SDK и файл службы контрактов. Давайте рассмотрим их один за другим.

Магазин
Этот файл управления состоянием использует пакет react-hooks-global-state npm. Он простой, быстрый и более легкий, чем Redux. Все глобальные переменные и функции, используемые в этом приложении, были созданы в этом магазине.

В корне проекта перейдите в каталог src и создайте папку с именем store. Теперь в этой папке создайте файл index.js и вставьте в него приведенные ниже коды.

Служба CometChat
Этот файл содержит все необходимые функции для взаимодействия с CometChat SDK. Смотрите коды ниже.

Файл службы Contract
Этот файл содержит все функции и процедуры, отвечающие за взаимодействие со смарт-контрактом на блокчейне с помощью библиотеки Web3. См. коды ниже.

Активы проекта
Скачайте этот логотип и включите его в папку assets в вашем корневом каталоге. Таким образом, вы успешно включили все, что необходимо для запуска этого приложения.

Запуск сервера

Чтобы перейти к этому шагу, перенесите смарт-контракт в веб, чтобы вы могли взаимодействовать с ним. Запустите следующий код на терминале.

truffle migrate --network rinkeby
Войти в полноэкранный режим Выйти из полноэкранного режима

Приведенный выше код отправит ваш смарт-контракт на сервер с помощью infuria RPC.

Вы также можете установить локальный блокчейн с помощью сервера ganache-cli, который мы установили в начале этого руководства. Просто выполните приведенный ниже код, чтобы отправить его на локальный блокчейн-сервер, если вы предпочитаете такой способ.

Откройте один терминал и запустите **ganache-cli -d**, а в другом терминале запустите **truffle migrate** или **truffle deploy**.

Обратите внимание, если вы используете ganache-cli в качестве EVM, вы также должны добавить сервер localhost в Metamask и импортировать закрытые ключи, созданные ganache. См. руководство в разделе Запуск среды разработки.

Если вам нужна моя помощь в решении проблем по вашему проекту, обратитесь ко мне на этой странице.

Теперь запустите yarn start, чтобы загрузить ваше приложение react. Вот и все с этой сборкой на NFT marketplace.

Смотрите мои БЕСПЛАТНЫЕ учебники по web3 на YouTube прямо сейчас.

Заключение

Мы подошли к финишной черте этого NFT билда, я знаю, что вы получили тонну ценностей, создавая их вместе со мной.

Какого бы уровня вы ни были, если вы хотите быстрее развиваться в своих навыках разработки web3, запишитесь в мой частный класс.

До следующего раза, продолжайте сокрушать!

Об авторе

Госпел Дарлингтон — полнофункциональный разработчик блокчейна с 6+летним опытом работы в индустрии разработки программного обеспечения.

Совмещая разработку программного обеспечения, написание статей и преподавание, он демонстрирует, как создавать децентрализованные приложения на EVM-совместимых блокчейн-сетях.

Его стеки включают JavaScript, React, Vue, Angular, Node, React Native, NextJs, Solidity и многое другое.

Для получения дополнительной информации о нем, пожалуйста, посетите и следите за его страницей в Twitter, Github, LinkedIn или на его сайте.

Оцените статью
devanswers.ru
Добавить комментарий