---
title: "Как реализовать рынок ERC-721"
description: "Как выставить токенизированные предметы на продажу на децентрализованной доске объявлений"
author: "Альберто Куэста Каньяда"
tags:
  - смарт-контракты
  - erc-721
  - solidity
  - токены
skill: intermediate
breadcrumb: "Рынок ERC-721"
lang: ru
published: 2020-03-19
source: Hackernoon
sourceUrl: https://hackernoon.com/how-to-implement-an-erc721-market-1e1a32j9
---

В этой статье я покажу вам, как написать код аналога Craigslist для блокчейна Эфириум.

До появления Gumtree, Ebay и Craigslist доски объявлений в основном делались из пробки или бумаги. Доски объявлений были в школьных коридорах, газетах, на уличных фонарях и витринах магазинов.

Все изменилось с появлением интернета. Количество людей, которые могли увидеть конкретную доску объявлений, увеличилось на много порядков. Благодаря этому рынки, которые они представляют, стали гораздо более эффективными и масштабировались до глобальных размеров. Ebay — это огромный бизнес, который берет свое начало от этих физических досок объявлений.

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

## Монетизация {#monetization}

Бизнес-модель публичной блокчейн-доски объявлений должна будет отличаться от модели Ebay и подобных компаний.

Во-первых, существует [аспект децентрализации](/developers/docs/web2-vs-web3/). Существующим платформам необходимо обслуживать собственные серверы. Децентрализованная платформа поддерживается ее пользователями, поэтому затраты на работу базовой платформы для ее владельца снижаются до нуля.

Затем идет фронтенд — веб-сайт или интерфейс, который предоставляет доступ к платформе. Здесь есть множество вариантов. Владельцы платформы могут ограничить доступ и заставить всех использовать их интерфейс, взимая за это плату. Владельцы платформы также могут решить открыть доступ (Власть народу!) и позволить любому создавать интерфейсы для платформы. Или же владельцы могут выбрать любой промежуточный подход между этими крайностями.

_Бизнес-лидеры с более широким видением, чем у меня, поймут, как это монетизировать. Все, что я вижу, — это то, что это отличается от статус-кво и, вероятно, прибыльно._

Кроме того, есть аспект автоматизации и платежей. Некоторые вещи могут быть очень [эффективно токенизированы](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com) и проданы на доске объявлений. Токенизированные активы легко передаются в блокчейне. В блокчейне можно легко реализовать очень сложные методы оплаты.

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

Я просто рад это создавать. Давайте посмотрим на код.

## Реализация {#implementation}

Некоторое время назад мы запустили [репозиторий с открытым исходным кодом](https://github.com/HQ20/contracts?ref=hackernoon.com) с примерами реализации бизнес-кейсов и другими полезными вещами, пожалуйста, взгляните.

Код для этой [доски объявлений на Эфириуме](https://github.com/HQ20/contracts/tree/master/contracts/classifieds?ref=hackernoon.com) находится там, пожалуйста, используйте его как хотите. Просто имейте в виду, что код не проходил аудит, и вам нужно провести собственную проверку, прежде чем вкладывать в него деньги.

Основы доски не сложны. Все объявления на доске будут представлять собой просто структуру с несколькими полями:

```solidity
struct Trade {
  address poster;
  uint256 item;
  uint256 price;
  bytes32 status; // Открыт, Исполнен, Отменен
}
```

Итак, есть кто-то, кто публикует объявление. Предмет для продажи. Цена предмета. Статус сделки, который может быть открытым, выполненным или отмененным.

Все эти сделки будут храниться в отображении (mapping). Потому что в Solidity, кажется, все является отображением. А еще потому, что это удобно.

```solidity
mapping(uint256 => Trade) public trades;
```

Использование отображения просто означает, что мы должны придумать идентификатор (id) для каждого объявления перед его публикацией, и нам нужно будет знать id объявления, прежде чем мы сможем с ним работать. Существует множество способов справиться с этим как в смарт-контракте, так и во фронтенде. Пожалуйста, спрашивайте, если вам нужны подсказки.

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

Что касается предметов, мы просто попросим, чтобы они реализовывали интерфейс [ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol?ref=hackernoon.com), который на самом деле является просто способом представления предметов реального мира в блокчейне, хотя он [лучше всего работает с цифровыми активами](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com). Мы собираемся указать наш собственный контракт ERC-721 в конструкторе, что означает, что любые активы на нашей доске объявлений должны быть предварительно токенизированы.

Для платежей мы собираемся сделать нечто подобное. Большинство блокчейн-проектов определяют свою собственную криптовалюту [ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol?ref=hackernoon.com). Некоторые другие предпочитают использовать популярную, такую как DAI. На этой доске объявлений вам просто нужно решить при создании, какой будет ваша валюта. Легко.

```solidity
constructor (
  address _currencyTokenAddress, address _itemTokenAddress
) public {
  currencyToken = IERC20(_currencyTokenAddress);
  itemToken = IERC721(_itemTokenAddress);
  tradeCounter = 0;
}
```

Мы почти у цели. У нас есть объявления, предметы для торговли и валюта для платежей. Создать объявление означает поместить предмет на условное депонирование (escrow), чтобы показать, что он у вас есть и что вы не опубликовали его дважды, возможно, на другой доске.

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

```solidity
function openTrade(uint256 _item, uint256 _price)
  public
{
  itemToken.transferFrom(msg.sender, address(this), _item);
  trades[tradeCounter] = Trade({
    poster: msg.sender,
    item: _item,
    price: _price,
    status: "Open"
  });
  tradeCounter += 1;
  emit TradeStatusChange(tradeCounter - 1, "Open");
}
```

Принять сделку означает выбрать объявление (сделку), заплатить цену, получить предмет. Приведенный ниже код извлекает сделку. Проверяет ее доступность. Оплачивает предмет. Извлекает предмет. Обновляет объявление.

```solidity
function executeTrade(uint256 _trade)
  public
{
  Trade memory trade = trades[_trade];
  require(trade.status == "Open", "Trade is not Open.");
  currencyToken.transferFrom(msg.sender, trade.poster, trade.price);
  itemToken.transferFrom(address(this), msg.sender, trade.item);
  trades[_trade].status = "Executed";
  emit TradeStatusChange(_trade, "Executed");
}
```

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

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

```solidity
function cancelTrade(uint256 _trade)
  public
{
  Trade memory trade = trades[_trade];
  require(
    msg.sender == trade.poster,
    "Trade can be cancelled only by poster."
  );
  require(trade.status == "Open", "Trade is not Open.");
  itemToken.transferFrom(address(this), trade.poster, trade.item);
  trades[_trade].status = "Cancelled";
  emit TradeStatusChange(_trade, "Cancelled");
}
```

Вот и все. Вы добрались до конца реализации. Довольно удивительно, насколько компактными бывают некоторые бизнес-концепции, когда они выражены в коде, и это один из таких случаев. Ознакомьтесь с полным контрактом [в нашем репозитории](https://github.com/HQ20/contracts/blob/master/contracts/classifieds/Classifieds.sol).

## Заключение {#conclusion}

Доски объявлений — это распространенная конфигурация рынка, которая масштабировалась с появлением интернета, став чрезвычайно популярной бизнес-моделью с несколькими монополистическими победителями.

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

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

Как всегда, если вы собираетесь создать что-то интересное и были бы рады совету, пожалуйста, [напишите мне](https://albertocuesta.es/)! Я всегда рад помочь.