- Создать картину
- Как создать NFT-маркетплейс, как OpenSea?
- 1. Найдите свою нишу
- 2. Наймите опытных разработчиков
- 3. Определите бизнес-модель вашего сайта
- 4. Определитесь с поддерживаемыми блокчейнами
- 5. Выберите функции NFT-маркетплейса
- Создайте коллекцию на OpenSea
- Выберите правильный Блокчейн
- Как разработать NFT Marketplace с помощью IPFS и Flow?
- Отображение предметов коллекционирования NFT
- Получение NFT из FLOW
- Получение медиа из IPFS
- Развертывание и выпуск токенов
- Разработка торговой площадки NFT
- Поддержите блог, перечислив небольшие чаевые
- Платформа Shopify
- Зачем создавать NFT
- Что продают как NFT? Примеры
- Добавление NFT в интернет-магазин
- Целевая аудитория NFT
- Портрет ЦА
- Что должно быть на NFT маркетплейсе согласно ЦА
- Привязка вашего криптокошелька на Ethereum к OpenSea
Создать картину
Конечно, предмет искусства стоит гораздо больше, чем случайное изображение. Поэтому объясняем, как создать NFT картину.
Если вы практикующий художник, отсканируйте или сфотографируйте в хорошем качестве свои готовые работы. Затем сделайте из этого токен. Также можете пообещать покупателю токена отправить оригинал NFT-картины — это поможет добавить стоимости.

В 2021 году NFT с копией картины Бэнкси под названием «Morons» ушел с молотка за 228,69 ETH, после чего оригинал картины сожгли. Ценность токена из-за этого только выросла.
Еще можно попробовать такой вариант, как создать NFT арт. То есть нарисовать картину изначально в цифровом виде — на планшете или компьютере. Можно сделать это даже в базовой программе Paint, а эффекты добавить в Photoshop.
Как создать NFT-маркетплейс, как OpenSea?
Если вы намерены запустить свой клон NFT-маркетплейса OpenSea, то мы рекомендуем начать с деловой стороны. Сначала вам нужно определиться с тем, для кого вы создаете свою платформу и какие проблемы пользователей она может решить. Дальше вы должны определиться с бизнес-моделью и функциями сайта, и только после этого можно переходить непосредственно к самой разработке.
1. Найдите свою нишу
Поскольку сектор NFT уже заполнен многими торговыми платформами, не рекомендуется создавать площадку, которая будет напрямую конкурировать с лидерами рынка. Лучше всего сделать ставку на сравнительно пустующую нишу, даже если она не будет такой большой и разрекламированной, как рынок цифрового искусства. Такой подход позволит запустить персонализированную маркетинговую стратегию и создать более эффективный дизайн интерфейса, что сэкономит вам деньги и время на привлечение пользователей на вашу NFT-платформу.
Вот несколько перспективных ниш для запуска NFT-маркетплейса:
- Онлайн-образование. Все уроки, лекции и курсы можно перевести в NFT, а затем продавать их или сдавать в аренду. При этом благодаря блокчейну вы и их создатели смогут отслеживать их распространение и использование.
- Инвестиционные проекты. Ваш NFT-маркетплейс может функционировать, как традиционные фондовые рынки — сопровождать сделки купли-продажи реальных активов и ценных бумаг. Для этого нужно токенизировать такого рода активы и получить соответствующие разрешения у регуляторов.
- Ключи аутентификации. Невзаимозаменяемые токены также можно использовать в качестве ключей доступа к различными продуктам и контенту. И вы можете создать торговую площадку для торговли такими NFT-активами.
- Предметы роскоши. Дорогая брендовая одежда и обувь, ювелирные изделия, элитная мебель и другие предметы роскоши часто подделываются. Их токенизация позволит подтвердить подлинность и право собственности, гарантируя, что покупатель получит оригинал, а не фальшивку.
2. Наймите опытных разработчиков
При создании своего клона NFT-маркетплейса OpenSea важно иметь сильную команду разработчиков, такую как Merehead, которая поможет с реализацией технической части вашего проекта. Такая команда должна хорошо разбираться в технологиях блокчейна и иметь в портфолио несколько проектов по разработке NFT-маркетплейсов.
Где искать и на какие критерии обращать внимание при анализе кандидатов, подробно описано в статье «Как выбрать компанию-разработчика NFT». Здесь же отметим, что лучше всего нанимать блокчейн-разработчиков из Украины, Венгрии, Польши, Мексики и Словакии, поскольку именно эти страны выигрывают по соотношению цена и качество согласно анализу Skill Value.
Результаты отчета Skill Value, основанного на +550 технических оценках. Источник.
3. Определите бизнес-модель вашего сайта
OpenSea зарабатывает на плате за услуги. Сборы взимаются каждый раз, когда цифровой актив успешно продается через платформу. Размер комиссии 2,5%. Это означает, что если продается NFT стоимостью 100 долларов, то OpenSea получает 2,50 доллара. Также платформа взимает плату за газ с покупателей и продавцов, чтобы покрыть стоимость соответствующих транзакций. Создать NFT на OpenSea можно бесплатно, что стало возможным благодаря переходу на свой блокчейн.
Бизнес-модель OpenSea в нескольких словах. Источник.
4. Определитесь с поддерживаемыми блокчейнами
В идеале ваш клон NFT-маркетплейса OpenSea должен работать со всеми популярными блокчейнами. Но на их интеграцию нужно потратить много времени, денег и усилий, поэтому лучше сначала сделать ставку на один или несколько наиболее подходящих вариантов, а затем добавить поддержку остальных.
Вот сравнение самых популярных блокчейнов для чеканки NFT:
5. Выберите функции NFT-маркетплейса
Обязательные функции для всех торговых платформ NFT. Источник.
Любая торговая платформа имеет как минимум два вида пользователей: администраторы и покупатели с продавцами. Администраторы управляют площадкой, занимаются ее настройкой и решают проблемы. Продавцы с покупателями в свою очередь используют площадку для торговли товарами и услугами. Таким образом, при создании своего NFT-маркетплейса вам нужно подумать, какие функции нужны будут каждой группе его пользователей.
Вот перечень пользовательских функций для NFT-маркетплейса:
- Витрина. Это лицо вашей торговой площадки. С помощью витрины пользователи получают подробную информацию о торговых лотах, такую как название, владелец, ставки, история цен, внешний вид и прочее.
- Онлайн-аукцион. Практически все торговые платформы NFT продают виртуальные активы посредством аукционов с системой автоматических ставок, как на eBay. Эта функция, так же как и витрина, должна содержать информацию о лоте: название, продавец, количество ставок, изображение, время до подачи заявки, количество участников аукциона и прочее.
- Система поиска и фильтры. Хорошая система поиска должна иметь разделение лотов на категории и фильтры, которые помогут пользователям как можно быстрее найти нужные им товары. Кроме того, сейчас принято интегрировать в поиск систему рекомендации и исправления ошибок.
- Кошелек пользователя. На торговой площадке обязательно должен быть кошелек, с помощью которого можно получать, хранить и отправлять NFTs, а также обычные криптовалюты вроде BTC и ETH. Ваша площадка должна быть либо разработана с собственным кошельком, либо иметь возможность интегрировать существующие кошельки для обеспечения беспрепятственного взаимодействия с пользователями. Второй вариант предпочтительнее, так как он дает больше свободы пользователям и делает сайт более безопасным.
- Популярные коллекции. NFTs могут привлечь больше покупателей и получить большую цену, если они надлежащим образом представлены в разделе «Трендовые коллекции» (или «Избранные коллекции»). Поэтому в вашем будущем NFT-маркетплейсе также стоит реализовать такой раздел, в котором будут представлены наиболее перспективные торговые лоты.
- Создание листинга. С помощью этой функции художники и продавцы будут создавать свои NFTs и выставлять их на продажу. Чем удобнее и понятнее будет эта функция, тем больше будет представлено на вашем рынке NFTs. Кроме того, подумайте о том, каким образом реализовать опцию бесплатного создания NFT, как на OpenSea. Это еще больше увеличит количество лотов на вашей платформе, так как часто художники не хотят ничего платить до самой продажи, поскольку не факт, что им удастся продать созданный лот.
Создайте коллекцию на OpenSea
NFT на OpeanSea создаются в составе коллекции, поэтому, прежде всего, вы должны создать эту коллекцию. Для этого, кликните на иконку профиля справа вверху, выберите «мои коллекции – создать» (My Collections – Create).

Создание новой коллекции на OpenSea
Большинство важных вещей, которые вам предстоит сделать, происходят здесь.
Выберите правильный Блокчейн
Далее, выберите правильный блокчейн для своей коллекции. Выбор – между Ethereum и Polygon. Если вы хотите взять бесплатный блокчейн, выбирайте Polygon.

выбор бесплатного блокчейна Polygon
Наконец, кликните на «создать». Вам понадобится подтверждать действия по настройке коллекции с помощью кошелька на Ethereum.
Как разработать NFT Marketplace с помощью IPFS и Flow?
Мы поделились примером создания контракта,выпуска токена, создания приложения для просмотра NFT, сделанных с помощью этого контракта, и создания торговой площадки для перемещения NFT другим пользователям.
Начнем с создания контракта и выпуска токена.
Установите Flow CLI в вашу систему.
Существуют разные команды для установки CLI в зависимости от разных операционных систем.
Например, чтобы установить Flow CLI на macOS, используйте команду:
data-hren="https://storage.googleapis.com/flow-cli/install.ps1" rel= https://storage.googleapis.com/flow-cli/install.ps1') }data-hren="https://storage.googleapis.com/flow-cli/install.sh" rel=>https://storage.googleapis.com/flow-cli/install.sh)Файлы активов будут храниться в IPFS.
В этом примере мы собираемся использовать Pinata для хранения файлов. Вы можете зарегистрировать бесплатную учетную запись и получить ключ API здесь.
Также важно установить NodeJS и текстовый редактор, чтобы выделить код смарт-контракта Flow.
Второй шаг — создать каталог для проекта с помощью команды:
Инициализируйте новый потоковый проект и поместите его в этот каталог:
cd pinata-party
flow project initТеперь откройте проект в редакторе кода и приступим к работе. Сначала создайте папку с именем cadence. Добавьте в эту папку еще одну папку с именем contracts . Наконец, создайте файл в папке контрактов с именем PinataPartyContract.cdc
Прежде чем двигаться дальше, важно указать на все, что мы делаем в отношении платформы блокчейна Flow.
Настройте файл для среды эмулятора, и тогда мы можем приступить к написанию контракта.
Нам нужно обновить объект контракта в flow.json, используя код:
contracts": {
"PinataPartyContract": "./cadence/contracts/PinataPartyContract.cdc"
}Обновите объект развертывания в этом файле, используя приведенный ниже код:
deployments": {
"emulator": {
"emulator-account": ["PinataPartyContract"]
}
}Это позволит Flow CLI использовать эмулятор для развертывания нашего контракта. Этот код также ссылается на учетную запись и контракт, которые мы собираемся написать в ближайшее время.
Нам нужно создать контракты для выпуска NFT, связывания метаданных с NFT и обеспечения того, чтобы метаданные указывали на базовые активы, хранящиеся в IPFS.
Откройте PinataPartyContract.cdc и выполните следующий код:
pub contract PinataPartyContract {
pub resource NFT {
pub let id: UInt64
init(initID: UInt64) {
self.id = initID
}
}
}Первый шаг — составить контракт.
Давайте начнем с определения PinataPartyContract и создадим внутри него ресурс. Ресурсы — это элементы, сохраненные в учетных записях пользователей, которые доступны через меры контроля доступа.
NFT должны быть идентифицируемыми, а свойство id позволяет идентифицировать токены.
Затем создается интерфейс ресурсов, чтобы определить, какие возможности доступны другим.
pub resource interface NFTReceiver {
pub fun deposit(token: @NFT, metadata: {String : String})
pub fun getIDs(): [UInt64]
pub fun idExists(id: UInt64): Bool
pub fun getMetadata(id: UInt64) : {String : String}
}Поместите приведенный выше код под кодом ресурса NFT. Интерфейс ресурса NFTReceiver сообщает, что ресурс может вызывать следующие методы:
getIDs
idExists
deposit
getMetadataЗатем необходимо определить интерфейс сбора токенов. Рассматривайте его как кошелек, в котором хранятся NFT всех пользователей.
pub resource Collection: NFTReceiver {
pub var ownedNFTs: @{UInt64: NFT}
pub var metadataObjs: {UInt64: { String : String }}
init () {
self.ownedNFTs <- {}
self.metadataObjs = {}
}
pub fun withdraw(withdrawID: UInt64): @NFT {
let token <- self.ownedNFTs.remove(key: withdrawID)!
return <-token
}
pub fun deposit(token: @NFT, metadata: {String : String}) {
self.metadataObjs[token.id] = metadata
self.ownedNFTs[token.id] <-! token
}
pub fun idExists(id: UInt64): Bool {
return self.ownedNFTs[id] != nil
}
pub fun getIDs(): [UInt64] {
return self.ownedNFTs.keys
}
pub fun updateMetadata(id: UInt64, metadata: {String: String}) {
self.metadataObjs[id] = metadata
}
pub fun getMetadata(id: UInt64): {String : String} {
return self.metadataObjs[id]!
}
destroy() {
destroy self.ownedNFTs
}
}Переменная ownedNFTs отслеживает все NFT, которыми пользователь может владеть от контактора. Переменная metadataObjs уникальна, поскольку мы расширяем функциональность контракта Flow NFT, чтобы хранить отображение метаданных для каждого NFT.
Она сопоставляет идентификатор токена с соответствующими метаданными, что означает, что идентификатор токена необходим, прежде чем мы сможем его установить. Переменные инициализируются, чтобы определить их в ресурсе внутри Flow.
Наконец, у нас будут все доступные функции, необходимые для ресурса коллекции NFT. Так же, как стандартный контракт NFT был расширен для включения отображения metadataObjs, мы расширим функцию депонирования по умолчанию, чтобы она принимала дополнительный параметр метаданных.
Это сделано для того, чтобы гарантировать, что только майнер токена может добавить метаданные к токену.
Мы ограничиваем первоначальное добавление метаданных выполнением майнинга, чтобы сохранить его конфиденциальность. Добавьте следующий код ниже ресурса Collection:
pub fun createEmptyCollection(): @Collection {
return <- create Collection()
}
pub resource NFTMinter {
pub var idCount: UInt64
init() {
self.idCount = 1
}
pub fun mintNFT(): @NFT {
var newNFT <- create NFT(initID: self.idCount)
self.idCount = self.idCount + 1 as UInt64
return <-newNFT
}
}Во-первых, у нас будет функция для создания пустой коллекции NFT при вызове. Пользователь, взаимодействующий с контрактом, будет иметь место хранения, которое отображает определенный ресурс Collection.
После этого мы создадим еще один ресурс. Без него мы не сможем выпускать токены. NFTMinter включает в себя idCount, который увеличивается каждый раз, чтобы у нас не было дублирующихся идентификаторов для NFT. Он также содержит функцию для создания NFT.
Добавьте инициализатор основного контракта ниже ресурса NFTMinter:
init() {
self.account.save(<-self.createEmptyCollection(),to: /storage/NFTCollection)
self.account.link<&{NFTReceiver}>(/public/NFTReceiver,target:/storage/NFTCollection)
self.account.save(<-create NFTMinter(), to: /storage/NFTMinter)
}Функция инициализатора вызывается только при развертывании контракта. Она выполняет три действия:
Создает пустую коллекцию для развертывателя коллекции, чтобы контракт-владелец мог создавать и владеть NFT из контракта.
Ресурс NFTMinter хранится в хранилище счета для создателя контракта. Это означает, что только создатель контракта может выпускать токены.
Ресурс Collection публикуется в публичном месте со ссылкой на интерфейс NFTReceiver, созданный в самом начале. Так мы сообщаем контракту, что любой может вызывать функции, определенные в NFTReceiver.
Когда контракт готов, давайте развернем его. Прежде чем развернуть его:
Протестируйте его на игровой площадке Flow Playground.
Перейдите на Flow Playground и нажмите на первый аккаунт в левой боковой панели.
Замените весь код на код контракта и нажмите кнопку Развернуть.
Если все прошло успешно, вы должны увидеть журнал в нижней части экрана:
16:48:55 Deployment Deployed Contract To: 0x01
Поскольку теперь настало время развернуть контракт на локально запущенном эмуляторе, выполните следующую команду:
<p class="in io ip iq ir lt lu dy">flow project start-emulator</p>Запустив эмулятор и настроив файл flow.json, можно развернуть контракт с помощью следующей команды:
<p class="in io ip iq ir lt lu dy">flow project deploy</p>Если все прошло успешно, вы должны увидеть результат, подобный этому:
Deploying 1 contracts for accounts: emulator-account
Теперь перейдем к выпуску NFT.
В этом разделе мы обсудим процесс выпуска NFT с помощью приложения и пользовательского интерфейса. Для получения демонстрации того, как метаданные работают с NFT на Flow, мы будем использовать командную строку и скрипты Cadence.
Создайте новую директорию в корне нашего проекта pinata-party и назовите ее «transactions». После создания папки создайте в ней новый файл с именем MintPinataParty.cdc.
У нас должен быть файл, на который мы будем ссылаться в метаданных, предлагаемых NFT. Файл загружается в IPFS через Pinata. В этом учебном пособии NFT сфокусированы на продаваемых видеороликах о том, как Pinata разбивается на вечеринках. В этой демонстрации мы загрузим видео ребенка, разбивающего Pinata на вечеринке по случаю дня рождения. Вы можете загрузить любой медиафайл и связать его с NFT.
После загрузки файла вам будет присвоен хэш IPFS. Скопируйте хэш, так как он будет использоваться в процессе выпуска. Теперь добавьте следующий код в файл MintPinataParty.cdc.
import PinataPartyContract from 0xf8d6e0586b0a20c7
transaction {
let receiverRef: &{PinataPartyContract.NFTReceiver}
let minterRef: &PinataPartyContract.NFTMinter
prepare(acct: AuthAccount) {
self.receiverRef=acct.getCapability<&{PinataPartyContract.NFTReceiver}>(/public/NFTReceiver)
.borrow()
?? panic("Could not borrow receiver reference")
self.minterRef = acct.borrow<&PinataPartyContract.NFTMinter>(from: /storage/NFTMinter)
?? panic("could not borrow minter reference")
}
execute {
let metadata : {String : String} = {
"name": "The Big Swing",
"swing_velocity": "29",
"swing_angle": "45",
"rating": "5",
"uri": "ipfs://QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6"
}
let newNFT <- self.minterRef.mintNFT()
self.receiverRef.deposit(token: <-newNFT, metadata: metadata)
log("NFT Minted and deposited to Account 2's Collection")
}
}Во-первых, мы определили две ссылочные переменные, minterRef и receiverRef. В этом сценарии мы одновременно являемся получателем и создателем NFT. Эти переменные ссылаются на ресурсы, созданные в контракте. Транзакция завершится неудачей, если лицо, выполняющее ее, не имеет доступа к ресурсу.
Приведенный выше контракт будет выпускать и депонировать НФТ. Теперь мы отправим транзакцию и зачислим NFT. Но перед этим нам нужно подготовить счет. Создайте закрытый ключ для подписи из командной строки в корневой папке проекта.
Выполните приведенную ниже команду:
Он предоставит вам открытый и закрытый ключи. Обязательно защитите свой закрытый ключ.
Закрытый ключ понадобится вам для подписания транзакции, который нужно вставить в наш файл flow.json. Также необходимо указать алгоритм подписания, и вот как должен выглядеть ваш объект счетов в файле flow.json:
<p style="text-align: left;">"accounts": {
"emulator-account": {
"address": "YOUR ACCOUNT ADDRESS",
"privateKey": "YOUR PRIVATE KEY",
"chain": "flow-emulator",
"sigAlgorithm": "ECDSA_P256",
"hashAlgorithm": "SHA3_256"
}
},Если вы хотите хранить что-либо из этого проекта в удаленном git-репозитории или на Github, вам не следует включать закрытый ключ. Вам может понадобиться .gitignore всего flow.json. Хотя мы используем только локальный эмулятор, хорошо бы держать ключи под защитой.
Последнее, что нам нужно сделать, это проверить, что токен находится в нашем аккаунте, и получить метаданные. Чтобы проверить это, нам нужно написать простой сценарий и вызвать его из командной строки.
Создайте новую папку scripts в корне вашего проекта. Создайте внутри папки файл CheckTokenMetadata.cdc. Добавьте в этот файл следующий код:
<p style="text-align: left;">import PinataPartyContract from 0xf8d6e0586b0a20c7</p>
<p style="text-align: left;">pub fun main() : {String : String} {</p>
<p style="text-align: left;">let nftOwner = getAccount(0xf8d6e0586b0a20c7) // log("NFT Owner")</p>
<p style="text-align: left;">let capability = nftOwner.getCapability<&{PinataPartyContract.NFTReceiver}>(/public/NFTReceiver)</p>
<p style="text-align: left;">let receiverRef = capability.borrow()</p>
<p style="text-align: left;">?? panic("Could not borrow the receiver reference")</p>
<p style="text-align: left;">return</p>
<p style="text-align: left;">receiverRef.getMetadata(id: 1)</p>
<p style="text-align: left;">}</p>В этом сценарии мы импортируем контракт с развернутого адреса. Мы определяем главную функцию и определяем три переменные внутри нее:
- nftOwner
This account owns the NFT.
- capability
Capabilities are access-controlled. If a capability is not available to the address attempting to borrow it, the script gets failed. In this example, we borrow capabilities from the NFTReceiver resource.
- receiverRef
The variable takes our capability and states the script to borrow from the deployed contract.
Мы хотим убедиться, что адрес, о котором идет речь, получил NFT, который мы выпустили, а затем мы хотим просмотреть метаданные, связанные с токеном.
Запустите скрипт с помощью следующей команды и посмотрите, что мы получим:
<p class="in io ip iq ir lt lu dy"><span class="ce lv ko fe ls b cb lw lx s ly">flow scripts execute ./scripts/CheckTokenMetadata.cdc</span></p>Вы получите результат, подобный этому:
{“name”: “The Big Swing”, “swing_velocity”: “29”, “swing_angle”: “45”, “rating”: “5”, “uri”: “ipfs://QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6“}Наконец, вы создали смарт-контракт Flow, создали токен, связали метаданные с токеном и сохранили базовые цифровые активы токена на IPFS.
Затем мы создадим внешнее приложение React, которое позволит вам отображать NFT, получая метаданные.
Отображение предметов коллекционирования NFT
Мы будем создавать простое приложение React, которое взаимодействует со смарт-контрактами Flow для проверки и получения NFT, принадлежащих пользователям.
Настройка React и зависимостей
Создайте приложение React в родительском каталоге pinata-party. Выполните следующую команду, чтобы создать приложение React:
<span class="ce lv ko fe ls b cb lw lx s ly">npx create-react-app pinata-party-frontend </span>Когда вы закончите установку, вы увидите новый каталог с именем pinata-party-frontend. Перейдите в этот каталог и установите зависимости. Для первой части настройки внешнего интерфейса запустите:
<p class="in io ip iq ir mq mr dy"><span class="ce ms ld fe mp b cb mt mu s mv">npm i @onflow/fcl @onflow/types
</span>Мы будем хранить некоторые значения как глобальные переменные для нашего приложения и использовать переменные среды. В качестве реакции это означает создание файла .env и установку пар ключ-значение, в которых вам нужно добавить префикс REACT_APP.
Затем создайте файл конфигурации, который будет использоваться для взаимодействия с Flow JS SDK. Создайте файл config.js в каталоге src и добавьте следующий код:
<p class="in io ip iq ir mq mr dy"><span class="ce ms ld fe mp b cb mt mu s mv">import {config} from "@onflow/fcl"
config()
.put("accessNode.api", process.env.REACT_APP_ACCESS_NODE)
.put("challenge.handshake", process.env.REACT_APP_WALLET_DISCOVERY)
.put("0xProfile", process.env.REACT_APP_CONTRACT_PROFILE)</span>Этот файл конфигурации просто помогает JS SDK работать с блокчейном Flow (или в данном случае с эмулятором). Чтобы сделать этот файл доступным во всем приложении, откройте файл и добавьте эту строку:
class="ji jj fe jk b gc jl jm jn gf jo jp jq jr js jt ju jv jw jx jy jz ka kb kc kd ew ce">import "./config"Важно иметь функцию аутентификации в приложении, чтобы обеспечить безопасную передачу активов NFT. Нам нужен компонент аутентификации. Создайте файл AuthCluster.js в каталоге src. Добавьте в этот файл следующее:
import React, {useState, useEffect} from 'react'
import * as fcl from "@onflow/fcl"
const AuthCluster = () => {
const [user, setUser] = useState({loggedIn: null})
useEffect(() => fcl.currentUser().subscribe(setUser), [])
if (user.loggedIn) {
return (
<div>
<span>{user?.addr ?? "No Address"}</span>
<p style="text-align: left;"><button className="btn-primary" onClick={fcl.unauthenticate}>Log Out</button></p>
</div>
)
} else {
return (
<div>
<p style="text-align: left;"><button className="btn-primary"onClick={fcl.logIn}>Log In</button></p>
<p style="text-align: left;"><button className="btn-secondary" onClick={fcl.signUp}>Sign Up</button></p>
</div>
)
}
}
export default AuthClusterЧтобы добавить этот компонент в приложение, замените файл app.js следующим:
<p class="hh hi hj hk hl ln lo by"><span class="ec lp ka df lm b jp lq lr s ls">
import './App.css';
import AuthCluster from './AuthCluster';</span><span class="ec lp ka df lm b jp lt lu lv lw lx lr s ls">function App() {
return (
<div className="App">
<AuthCluster />
</div>
);
}</span><span class="ec lp ka df lm b jp lt lu lv lw lx lr s ls">export default App;</span>После добавления вышеуказанного кода вы увидите страницу с кнопкой регистрации при запуске приложения. Теперь пришло время создать возможность получать NFT для учетной записи и отображать их.
Получение NFT из FLOW
Чтобы отображать созданные нами NFT, необходимо взаимодействовать с блокчейном Flow. В этом руководстве мы должны иметь возможность общаться с эмулятором Flow.
Давайте создадим компонент, который позволяет получать данные и отображать данные NFT. Создайте файл TokenData.js в каталоге src и добавьте в него следующий код:
import React, { useState } from "react";
import * as fcl from "@onflow/fcl";
const TokenData = () => {
const [nftInfo, setNftInfo] = useState(null)
const fetchTokenData = async () => {
const encoded = await fcl
.send([
fcl.script`
import PinataPartyContract from 0xf8d6e0586b0a20c7
pub fun main() : {String : String} {
let nftOwner = getAccount(0xf8d6e0586b0a20c7)
<p style="text-align: left;">let capability = nftOwner.getCapability<&{PinataPartyContract.NFTReceiver}>(/public/NFTReceiver)
let receiverRef = capability.borrow()
?? panic("Could not borrow the receiver reference")
return receiverRef.getMetadata(id: 1)
}`
])
const decoded = await fcl.decode(encoded)
setNftInfo(decoded)
};
return (
<div className="token-data">
<div className="center">
<button className="btn-primary" onClick={fetchTokenData}>Fetch Token Data</button>
</div>
{
nftInfo &&
<div>
{
Object.keys(nftInfo).map(k => {
return (
<p>{k}: {nftInfo[k]}</p>
)
})
}
<p style="text-align: left;"><button onClick={()=>setNftInfo(null)} className="btn-secondary">Clear Token Info</button></p>
</div>
}
</div>
);
};
export default TokenData;В этом файле мы создаем компонент с кнопкой для получения данных токена. Мы также создали кнопку для очистки данных токена. При нажатии кнопки выборки вызывается функция fetchTokenData. Функция использует Flow JS SDK для запуска скрипта, который мы выполнили из командной строки. Получение результатов выполнения и установка результатов в переменную состояния nftInfo. Если переменная существует, пары ключ-значение отображаются из метаданных NFT на экране и кнопки для очистки данных.
Получение медиа из IPFS
Поскольку мы уже зарегистрировались в учетной записи Pinata и добавили видеофайл в IPFS через интерфейс загрузки Pinata, вы попадаете на шлюз Pinata IPFS, где содержимое IPFS отображается при нажатии на хэш в проводнике контактов.
В файле TokenData.js добавьте способ отображения видеофайла, полученного из IPFS. Обновите файл, чтобы он выглядел так:
import React, { useState } from "react";
import * as fcl from "@onflow/fcl";
const TokenData = () => {
const [nftInfo, setNftInfo] = useState(null)
const fetchTokenData = async () => {
const encoded = await fcl
.send([
fcl.script`
import PinataPartyContract from 0xf8d6e0586b0a20c7
pub fun main() : {String : String} {
let nftOwner = getAccount(0xf8d6e0586b0a20c7)
<p style="text-align: left;">let capability = nftOwner.getCapability<&{PinataPartyContract.NFTReceiver}>(/public/NFTReceiver)</p>
let receiverRef = capability.borrow()
?? panic("Could not borrow the receiver reference")
return receiverRef.getMetadata(id: 1)
}
])
const decoded = await fcl.decode(encoded)
setNftInfo(decoded)
};
return (
<div className="token-data">
<div className="center">
<button className="btn-primary" onClick={fetchTokenData}>Fetch Token Data</button>
</div>
{
nftInfo &&
<div>
{
Object.keys(nftInfo).map(k => {
return (
<p>{k}: {nftInfo[k]}</p>
)
})
}
<div className="center video">
<video id="nft-video" canplaythrough controls width="85%">
<p style="text-align: left;"><source src={`https://ipfs.io/ipfs/${nftInfo["uri"].split("://")[1]}`} type="video/mp4" /></p>
</video>
<div>
<p style="text-align: left;"><button onClick={() => setNftInfo(null)} className="btn-secondary">Clear Token Info</button></p>
</div>
</div>
</div>
}
</div>
);
};
export default TokenData;Мы сделали это так, потому что настольный клиент IPFS позволяет нажимать и открывать ссылки.
Теперь NFT станет настоящим живым цифровым активом на блокчейне.
Теперь мы включим передачу NFT.
Прежде всего, нам нужно создать контракты на создание торговой площадки. Контракты будут заключаться на:
- Механизм оплаты взаимозаменяемых токенов
- Настройки подачи токенов
- Возможности передачи токенов
Давайте создадим взаимозаменяемый токен-контракт, который будет использоваться для платежей при покупке NFT.
Мы создадим взаимозаменяемый контракт токена, определив пустой контракт:
class="hh hi hj hk hl ln lo by"><span class="ec lp kb df lm b jp lq lr s ls">pub contract PinnieToken {</span><span class="ec lp kb df lm b jp lt lu lv lw lx lr s ls">} </span>Переменные публикации токена, связанные с ресурсами токена и провайдера, необходимо добавить в контракт.
pub var totalSupply: UFix64
pub var tokenName: String
pub resource interface Provider {
pub fun withdraw(amount: UFix64): @Vault {
post {
result.balance == UFix64(amount):
"Withdrawal amount must be the same as the balance of the withdrawn Vault"
}
}
}Добавьте вышеуказанный контракт в пустой контракт.
Интерфейс ресурса под названием Provider определяет общедоступную функцию, но владелец учетной записи может только вызывать ее. Затем мы определим еще два интерфейса общедоступных ресурсов:
pub resource interface Receiver {
pub fun deposit(from: @Vault)
}
pub resource interface Balance {
pub var balance: UFix64
}Вышеупомянутые интерфейсы располагаются непосредственно под интерфейсом ресурсов провайдера. Интерфейс Receiver включает функцию, которую может выполнить любой. Это гарантирует, что депозиты на счет могут выполняться до тех пор, пока получатель инициализирует хранилище для обработки токенов, созданных в рамках контракта. Ресурс Balance возвращает баланс нового токена для любой предоставленной учетной записи.
Давайте создадим ресурс Vault и добавим следующий код под ресурсом Balance:
pub resource Vault: Provider, Receiver, Balance {
pub var balance: UFix64
init(balance: UFix64) {
self.balance = balance
}
pub fun withdraw(amount: UFix64): @Vault {
self.balance = self.balance - amount
return <-create Vault(balance: amount)
}
pub fun deposit(from: @Vault) {
self.balance = self.balance + from.balance
destroy from
}
}Добавьте следующую функцию в интерфейс хранилища:
pub fun createEmptyVault(): @Vault {
return <-create Vault(balance: 0.0)
}Как следует из названия, функция создает пустой ресурс Vault для учетной записи. Баланс равен 0.
Следовательно, теперь нам нужно настроить возможность минтинга. Добавьте следующий код под функцией createEmptyVault:
pub resource VaultMinter {
style="text-align: left;">pub fun mintTokens(amount: UFix64, recipient: Capability<&AnyResource{Receiver}>)
{
let recipientRef = recipient.borrow()
?? panic("Could not borrow a receiver reference to the vault")
PinnieToken.totalSupply = PinnieToken.totalSupply + UFix64(amount)
recipientRef.deposit(from: <-create Vault(balance: amount))
}
}Ресурс VaultMinter является общедоступным, но доступен только владельцу контрактной учетной записи.
Ресурс VaultMinter включает в себя только одну функцию: mintTokens, для которой требуется сумма, которую нужно монетизировать, и получатель. Вновь отчеканенные токены могут быть депонированы в эту учетную запись, если у получателя будет храниться ресурс Vault.
Переменную totalSupply необходимо обновлять при чеканке токенов. Следовательно, отчеканенная сумма добавляется к предыдущему запасу для получения нового запаса.
Теперь нам нужно инициализировать контракт и добавить следующий код после ресурса VaultMinter:
init() {
self.totalSupply = 30.0
self.tokenName = "Pinnie"
let vault <- create Vault(balance: self.totalSupply)
self.account.save(<-vault, to: /storage/MainVault)
self.account.save(<-create VaultMinter(), to: /storage/MainMinter)
style="text-align: left;">self.account.link<&VaultMinter>(/private/Minter, target: /storage/MainMinter)
}При заключении контракта важно установить общий объем поставки. В этом примере мы инициализировали контракт с поставкой 30 и установили имя токена как «Пинни».
Развертывание и выпуск токенов
Обновите файл flow.json в проекте, чтобы развернуть новый контракт. Убедитесь, что файл flow.json ссылается на новый контракт и содержит ссылку на ключ учетной записи эмулятора:
{
"emulators": {
"default": {
"port": 3569,
"serviceAccount": "emulator-account"
}
},
"contracts": {
"PinataPartyContract": "./cadence/contracts/PinataPartyContract.cdc",
"PinnieToken": "./cadence/contracts/PinnieToken.cdc"
},
"networks": {
"emulator": {
"host": "127.0.0.1:3569",
"chain": "flow-emulator"
}
},
"accounts": {
"emulator-account": {
"address": "f8d6e0586b0a20c7",
"keys": "e5ca2b0946358223f0555206144fe4d74e65cbd58b0933c5232ce195b9058cdd"
}
},
"deployments": {
"emulator": {
"emulator-account": ["PinataPartyContract", "PinnieToken"]
}
}
}В другом окне терминала в каталоге проекта стороны пината запустите развертывание проекта потока. Теперь давайте протестируем функцию чеканки. Мы создадим транзакцию, которая позволит нам создавать токены Pinnie. Но сначала нам нужно обновить файл flow.json.
Измените json под учетной записью эмулятора:
style="text-align: left;">"emulator-account": {
"address": "f8d6e0586b0a20c7",
"privateKey": "e5ca2b0946358223f0555206144fe4d74e65cbd58b0933c5232ce195b9058cdd",
"sigAlgorithm": "ECDSA_P256",
"hashAlgorithm": "SHA3_256",
"chain": "flow-emulator"
},Поле ключа становится полем privateKey, и мы добавляем свойства, включая sigAlgorithm, цепочку и hashAlgorithm.
Разработка торговой площадки NFT
Прежде чем приступить к работе над внешним интерфейсом торговой площадки, у нас должен быть контракт на создание и управление торговой площадкой.
В папке cadence / контракты создайте новый файл с именем MarketplaceContract.cdc.
import PinataPartyContract from 0xf8d6e0586b0a20c7
import PinnieToken from 0xf8d6e0586b0a20c7
pub contract MarketplaceContract {
pub event ForSale(id: UInt64, price: UFix64)
pub event PriceChanged(id: UInt64, newPrice: UFix64)
pub event TokenPurchased(id: UInt64, price: UFix64)
pub event SaleWithdrawn(id: UInt64)
pub resource interface SalePublic {
style="text-align: left;">pub fun purchase(tokenID: UInt64, recipient: &AnyResource{PinataPartyContract.NFTReceiver}, buyTokens: @PinnieToken.Vault)
pub fun idPrice(tokenID: UInt64): UFix64?
pub fun getIDs(): [UInt64]
}
}Нам нужно импортировать как контракт NFT, так и контракт заменяемого токена. В определении контракта мы определили четыре события:
- ForSale: продажа NFT
- PriceChanged: изменение цены на NFT.
- TokenPurchased: при покупке NFT
- SaleWithdrawn: когда NFT удаляются с торговой площадки.
Мы добавили интерфейс ресурса под названием SalePublic под эмиттерами событий. Интерфейс должен быть общедоступным для всех, а не только для владельца контракта.
Нам нужно добавить ресурс SaleCollection под интерфейсом SalePublic. Мы определили несколько переменных в этом ресурсе. Например, отображение токенов для продажи, отображение цен на каждый токен для продажи и защищенная переменная, доступная только владельцу контракта, под названием ownerVault.
Нам нужно инициализировать переменные при их определении на ресурсе. Это выполняется в функции init и инициализируется ресурсом хранилища владельца и пустыми значениями.
Затем важно определить функции для управления действиями торговой площадки NFT. Функции:
- listForSale
- changePrice
- withdraw
- idPrice
- purchase
- destroy
- getIDs
Как упоминалось выше, три из этих функций общедоступны, это означает, что listForSale, remove, destroy и changePrice доступны только для перечисленных владельцев NFT. Например, changePrice не доступен публично, потому что мы не хотим, чтобы кто-либо менял цену NFT.
Последняя часть рыночного контракта — это функция CreateSaleCollection. Это позволяет добавить коллекцию в качестве ресурса к учетной записи. После написания этого контракта мы развернем его с учетной записью эмулятора. Выполните следующую команду из корня вашего проекта:
Наконец, он развернет рыночный контракт и позволит нам использовать его во внешнем приложении.
Как только это будет сделано, нам нужно поработать над интерфейсом и подключить эти контракты с помощью инструмента Flow CLI.
Если вы хотите создать собственную торговую площадку NFT, проконсультируйтесь с нашими экспертами по разработке NFT, которые помогут вам от консультаций до разработки и запуска платформы торговой площадки.
Поддержите блог, перечислив небольшие чаевые
Если у вас нет кошелька MetaMask, вы можете получить его здесь
Платформа Shopify
Благодаря простоте и удобству использования, скорости создания eCommerce проектов — Shopify занимает лидирующие позиции в рейтингах платформ для создания интернет-магазинов. Ещё в июле 2021 года Shopify приняла решение предоставить пользователям возможность для продажи NFT-токенов.
Для многих пользователей это событие стало эпохальным. У них появилась возможность конвертировать цифровую продукцию в NFT и продавать ее без затруднений. Кроме того, теперь NFT можно покупать и продавать используя дебетовые и кредитные карты.
Теперь если вы автор и/или владелец цифровых продуктов (видео, изображения, игры, и т. д.), вы можете их продать в качестве NFT в своём магазине на Shopify.
Зачем продавать NFT на Shopify?
Продавая на своей платформе, Вы не делитесь комиссией с маркетплейсом, а также получаете полный доступ к данным о покупателях и аналитике вашей витрины NFT.
Зачем создавать NFT
Не так давно вокруг NFT было много шума и слухов в средствах массовой информации. В настоящее время все больше известных людей, в том числе из сферы творчества, размещают результаты своего труда для продажи на платформе блокчейн.
Сделать NFT можно практически из всего, что является уникальным — это может быть авторская песня, написанная картина (физическая или цифровая) и многое другое. Таким способом можно подтвердить при необходимости права владельца и доказать, что у вас оригинал продукта, а не подделка или копия.

Если у вас есть творческий дар, то с помощью NFT можно отлично заработать, если продать ваше произведение в цифровом формате. В зависимости от спроса цена на токен может увеличиваться. Ярким примером служит история художника Майка Винкельманна. Он продал на рынке криптовалют более чем за 69 миллионов долларов авторский токен, который называется «Каждый день: первые 5 000 дней».
Сегодня большое количество художников продают свои картины методом NFT на маркетплейсах, которые созданы по принципу блокчейна. Высокая прибыль от продаж говорит сама за себя.
Перед тем как создать NFT, вам нужны три вещи:
- результат вашего творчества или имущество (песня, книга, монета из коллекции и т. д.);
- определенная сумма криптовалюты, чтобы оплатить комиссию за разработку NFT;
- кошелек для цифровых денег.

Еще надо будет выбрать платформу на блокчейне, чтобы создать ваш NFT.
Что продают как NFT? Примеры
Гифки. Самый известный проданный NFT в интернете гифка Nyan Cat — кот, который несется в космосе и оставляет за собой шлейф из радуги. В феврале 2021 ей исполнилось 10 лет, в честь этого ее продали на платформе Foundation за 590 тысяч долларов.

Фотографии. Фото Кевина Эбоша под названием Forever Rose была продана за 1 миллион долларов в День Святого Валентина. При этом до увлечения NFT автору удалось продать фотографию картофеля за 1 миллион евро.

NFT-игра. К примеру, в Axie Infinity игроки создают и разводят цифровых питомцев. Каждый персонаж является NFT-токеном, которого создатель может продать или приобрести на специальном маркетплейсе. Игра очень популярна во всем мире и некоторые игроки зарабатывают до 1000 долларов каждый месяц.

Аудио треки и альбомы. Американский диджей 3LAU продал свой музыкальный альбом через NFT-токены. В общей сложности он выставил 33 токена, привязанные к альбому и заработал 11,6 миллионов долларов. А основатель группы Linkin Park Майк Шинода продал анимационный ролик с музыкой за 30 000 долларов. Анимированные обложки к его альбому «Happy Endings» принесли ему 6600 долларов все в той же NFT индустрии.

Билеты на мероприятия. Футбольный клуб “Динамо” выпустил NFT-билеты на сезон 2021 года. Авиакомпания AirEuropa создала серию билетов на рейс из Мадрида до Майями на 29 ноября 2022. Авиакомпания S7 также задумалась о продаже авиабилетов за токены, чтобы ускорить оформление заказов.
NFT-коллекции. Талисман Зимних Олимпийских игр в Китае приобрел новую жизнь в виде токенов. Коллекция состоит из панды, занимающейся разными видами спорта.
Gucci и Superplastic выпустили коллекции NFT-игрушек. Всего представлено 250 токенов. Владельцы обещают прислать покупателям NFT оригинал этой игрушки.

Личные вещи. Бывший сотрудник ЦРУ Эдвард Сноуден продал свой портрет, собранный из постановления судьи. Работу продали за 5,4 миллион долларов, а все средства были переданы в фонд за свободу слова в прессе. Работа называлась “Оставайтесь свободными”.
Личные вещи Джона Леннона и Пола Маккартни выставили на аукционе в формате NFT. В качестве токенов представлены гитары, куртка, личные заметки.

Добавление NFT в интернет-магазин
Данный этап самый сложный. Как вы помните, Shopify не несет ответственности за хранение и передачу цифровых продуктов. За безопасность и передачу продуктов покупателю отвечает продавец. Команда Shopify обращает особое внимание на то, что все NFT должны соответствовать Правилам использования платформы.
Также, Shopify не предоставляет каких-либо инструкций или советов по созданию NFT. В то же время, имеются вполне достойные сторонние источники информации о продажах NFT. Первое сообщение о продаже токена появилось в июле 2021 года, когда баскетбольная команда «Чикаго буллз» «оцифровала» свое чемпионское кольцо и продала его на Shopify в качестве NFT.
Способ реализации NFT в интернет-магазине может быть как с помощью блокчейна, так и с помощью продажи обычного цифрового товара.
Вы можете создавать и продавать NFT используя блокчейны Ethereum, Polygon и Flow. Это будет чуть сложнее и самостоятельно реализовать вряд ли получится.
Есть более упрощённые способы: приложения SendOwl (позволят продавать цифровые товары) и Foridev (используется для продажи лицензионных ключей активации).
Целевая аудитория NFT
Кто же покупает, создает и продает все эти гифки, картинки?
Согласно исследованию Morning Consult каждый третий американец что-то коллекционирует. Если говорить про коллекционирование NFT, то наиболее активная группа по покупке и продаже NFT — это мужчины (45%) и поколение миллениалов (42%). В то время как взрослое поколение вообще не знакомо с понятием NFT.

Исследование запросов по NFT говорит о том, что Азиатские страны чаще интересуются этой индустрией. Гонконг, Сингапур, Китай — тройка лидеров. Позиции между ними могут меняться в разные периоды времени, но всегда остаются в топе.
Инвестирование и покупка NFT не сильно зависит от дохода, это подтверждают данные CivicScience. Люди, которые зарабатывают менее 25 000 долларов в год, покупают так же как и те, кто зарабатывают более 150 000 долларов.
Портрет ЦА
Если сделать вывод, то портрет целевой аудитории NFT будет следующим:
- молодой человек,
- в возрасте 24 лет,
- следует современным трендам развития технологий и медиаресурсов.
Начинает свой карьерный рост и одной из важнейших потребностей является — самовыражение, стремление выделится из толпы.
Активный участник онлайн-сообществ, потребность в самовыражении реализует через интернет-ресурсы. NFT для него будет способом заработка и возможностью выделиться или даже стать известным в некоторых онлайн-сообществах.

Что должно быть на NFT маркетплейсе согласно ЦА
- Акции и система лояльности. Обязательно продумайте программы акций, скидок, программы лояльности. Это важная составляющая процесса покупок миллениалов.
- Удобная мобильная версия. Обратите внимание, чтобы платформой было удобно пользоваться на различных устройствах. Так как аудитория является последователями новых технологий.
- Коммьюнити. Реализуйте на площадке возможность создать сообщества, делится информацией в соцсетях или же просто оставлять комментарии под токенами.
- Списки и рейтинги. Создавайте рейтинги самых активных продавцов, самых дорогих продавцов и т.д. — дайте возможность выделиться и быть в топе чего-либо.
Привязка вашего криптокошелька на Ethereum к OpenSea
Прежде всего, вы должны привязать ваш криптокошелёк на Ethereum к OpenSea. Он может быть абсолютно пустым – вам не нужно покупать криптовалюту. Если у вас до сих пор нет криптокошелька, я рекомендую использовать MetaMask или Coinbase Wallet. Оба они хорошо работают, удобны в использовании и популярны.

Кошелёк Coinbase — популярный и простой в использовании кошелек для криптовалюты
Не забудьте сделать бэкап вашей восстанавливающей фразы во время этого шага. Кошелёк понадобится вам для подтверждения определённых шагов, описанных в этом руководстве, поэтому держите его наготове по ходу всего процесса.
