Как сделать смарт контракт для opensea
Перейти к содержимому

Как сделать смарт контракт для opensea

  • автор:

Зачем нужен смарт-контракт для выпуска NFT-коллекции

Существует 2 варианта выпуска NFT- коллекции.
Подробнее писал в статье Рынок NFT. Как все устроено.

  • Просто выпуск на маркетплейсе (чаще всего Opensea)
  • Drop коллекции (первая и вторая статьи о том, как сделать успешный Drop)

Если коллекция выпускается без Drop, то смарт контракт не нужен. Такой подход предполагает, что создатель коллекции сам оплачивает mint коллекции (создание NFT в блокчейне). Пользователь просто заходит на маркетплейс и грузит в блокчейн коллекцию, заплатив за это комиссию.

Выпуск коллекции без Drop-а:

  • В целом гораздо меньше затрат
  • Не нужно писать смарт контракт
  • Не нужно арендовать сервер
  • Не нужно делать сайт
  • Не нужно делать кнопку mint

  • За mint придется платить самим
  • Если самостоятельно платить за mint, то скорее всего будет выбран блокчейн не ETH, а это сильно снижает вероятность высоких продаж коллекции.
  • нет возможности автоматически распределять средства от продажи коллекции на несколько кошельков основателей проекта

Выпуск коллекции через Drop:

  • Пользователи сами платят за mint коллекции
  • Можно сделать коллекцию на несколько тысяч NFT. объем затрат не зависит от числа NFT в коллекции
  • Можно выпускать коллекцию на ETH — это сильно увеличивает объем рынка
  • Можно придумывать свою логику взаимодействия с аудиторией (аукционы, разбиение продаж на несколько этапов и проч.)
  • Можно в смарт контракте описать автоматическое распределение средств на несколько кошельков по определенному правилу

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

Без Drop-a и без смарт контракта имеет смысл выпускать коллекцию тем, кто хочет попробовать что-то сделать на данном рынке и не готов инвестировать серьезные средства в проект.

Drop нужно делать, и смарт-контракт понадобится, если есть амбиции сделать крутой проект и есть инвестиции от $70k на проект.

NFT Smart Contract Development – Road to OpenSea (Part 1)

In my last blog post “Demystifying NFTs” I talked about how NFTs work inside. Now I will show you how to create your own NFT contract from scratch, test it and make it compatible with the biggest marketplace called OpenSea.

In this part we focus on the Remix IDE, ERC11155 Smart Contract development and Smart Contract testing.

Preview of the NFT we gonna build (Link to OpenSea)

Currently we are hosting a Customer Engagement Initiative regarding this topic.
If you are interested read the business perspective blog from my colleagues or to join us directly, please register
here.

Background

In the last blog post I explained to you that there are essentially two (Non fungible Token) NFT standards. One is ERC721 and the other is ERC1155. While the former is exclusively for NFTs i.e., unique and therefore non-exchangeable items, the ERC1155 can be used for NFTs as well as for Fungible Tokens (FTs). Since the ERC1155 is more advanced, it is perceived as the successor to the ERC721. Accordingly, in this article I will show you how to develop an ERC1155 compliant NFT contract.

Getting Started

In this multi part blog, I’ll show you step-by-step how to code your own animated NFT, test it by using the frameworks Chai and Mocha, deploy it on the Testnet Blockchain called Rinkeby, and finally see it on OpenSea. At some points in the development, I will also mention security features.

To understand the blog you should be able to read code, but it is not important to know solidity in detail, because most things should be self-explanatory.

Remix Setup

To begin coding, we first need a development environment. The official Ethereum IDE is called Remix and runs entirely in the web browser. This IDE is a good start to build our smart contract.

When you open remix, you will already see a bunch of files. We don’t really need them. Therefore, we go ahead and create a new blank workspace by clicking on the plus symbol on the upper left. We will call it BlogNFT (See figure 1). Then we create two folder contracts and tests. In the contracts folder we create a file called BlogNft.sol (See figure 2). The extension sol stands for solidity, the programming language of the smart contracts.

Create%20Remix%20Workspace

Figure 1: Create Remix Workspace

Figure%202%3A%20Workspace%20Overview

Figure 2: Workspace Overview

Begin Coding

Let’s fill our BlogNft.sol file with some code. In each solidity file, the compatible compiler version should be specified. It is important to choose a version >= 8. This is because in previous versions no numerical overflow check was performed by default. Before you had either a security hole, had to check it yourself or had to rely on external libraries like SafeMath. As of version 8, the check is now standard. So, lets stick with Version 0.8.15 as this the latest version available at the time of writing this blog.

As you probably know, there are many reusable building blocks in software development. This is no different in the smart contract world. In particular, it is even advisable to use ready-made building blocks from trusted sources, since errors in the smart contract cannot be patched, since the blockchain is immutable (It is possible to simulate patching by using proxies, but this is not of relevance for this post).

One code source that is trusted a lot in smart contract development is OpenZeppelin, which basically acts as the solidity standard library. Of course, they also have something up their sleeve for our Nft contract, namely an ERC1155 base class. In addition, some pleasant security features such as the ownable modifier with which a function can be equipped so that it can only be called by the owner of the SmartContract. More about this later. Let’s go ahead and import everything we need from OpenZeppelin. Within remix we can import OpenZeppelin directly, because by default the corresponding NPM package is already installed. For local development you would have to add the packages manually at this point.

Now we define the contract and let it inherit from the OpenZepplin ERC1155 implementation. Within the ERC1155 constructor a string is required to store the metadata URL. More about this in the next part.

Minting

Minting is the process of producing coins or in our case FTs/NFTs. So let’s include a corresponding function mint(..) to produce tokens. As written in the last blog post, a mapping from TokenId to Address to Amount is maintained within the OpenZepplin implementation, accordingly the _mint(…) method provided internally by OpenZepplin requests exactly these values. As you can see the function is on the one hand public and on the other hand equipped with the onlyOwner modifier. Internally, the sender address, i.e. the creator of the contract, is automatically stored when the contract gets initialized/deployed. When using the onlyOwner modifier, it is ensured that the caller corresponds to the creator of the contract. In this case, only the contract owner is allowed to mint new tokens.

VM Deployment

Using remix, we can quickly and easily deploy our contract in a virtual machine. This way there are no costs, and you can see the behavior of the contract. To deploy, we switch the tab on the left to the fourth icon, select the correct contract and click deploy (see figure 3). The contract appears at the bottom as shown in step 4. We see many methods that are provided by the OpenZeppelin ERC1155 implementation as well as our own mint method.

To test the functionality, we can now for example mint 10 tokens of token id 1 and then check the balance of the account. You can find the account address above under “account”. In the console we see that our account has 10 tokens.

Figure%203%3A%20Contract%20Deployment

Figure 3: Contract Deployment

Add useful Functionalities

A ft/nft is characterized by the fact that there is a maximum number of tokens. In the case of a nft this max amount is always 1.

To implement this functionality, we need some more code. For this we first introduce a struct which contains information of a token like the mentioned maximum amount of a token. In addition to the Struct we need a mapping so that we can retrieve the information per token id.

To keep track the current token supply and thus check if we are allowed to mint more tokens, we use an OpenZeppelin implementation. As said before, using the standard implementations help to prevent errors. Therefore, we go ahead and import and inherit the OpenZeppelin ERC1155Supply contract. This gives us a function called totalSupply which returns the number of minted tokens for a token id. Since the ERC1155Supply contract has a _beforeTokenTransfer method just like the ERC1155 contract, solidity requires that we explicitly override it.
The reason why the _beforeTokenTransfer function is used at all is that minting is nothing else then a transfer starting from address 0. So the ERC1155Supply can track the supply in this method properly.

The last step is to add a method to register new tokens and allow them to be minted. At the same time, we need to check in our mint method that the token should exist and that the maximum number of tokens has not been exceeded. A check using the require keyword is always a good idea, because this way the transaction is reverted, and we can directly pass a revert reason.

Afterwards we must recompile the contract so that remix notices that we want to deploy the latest changes. For this we go to the third remix tab and click on compile (see Figure 4). The deployment happens as described before.

Figure%204%3A%20Recompiling%20our%20Contract

Figure 4: Recompiling our Contract

Testing

To test the contract you can of course deploy it again in the virtual machine and test it by hand, but you don’t want to do that as the number of functions grows. So we take care of automated testing. To do so we use hardhat as environment and the well-known libs mocha and chai for testing. Because solidity tests can be developed easily in JavaScript, we create a corresponding javascript file called BlogNft.test.js in our test folder.

The usage is very straight forward. We import our libraries as we usually do in javascript. After that we can organize our tests with the describe function. The actual tests are written in the it blocks. Since we want to interact with our contract every time, we specify a beforeEach method that loads the interacting users using the ether module of the hardhat environment before each test. Then we create an instance of our contract using the factory pattern of hardhat. For this we only need to pass the name of our contract. Afterwards we can deploy the contract and store it in the variable contract which can be used to interact with the deployed contract instance during the test.

As you can see in the tests, we first connect to the contract using the “connect” keyword and can thus set the interacting account. Then we can call a function of the contract. The function name and function parameters are the same as in the solidity code. A very handy feature is that we can easily test our require statements by matching the revert reason.

To execute the test, you press Strg+Shift+S. You can see the test results in the console (see figure 5).

Figure%205%3A%20Test%20Execution

Figure 5: Test Execution

Summary

Today I showed you how to get started with NFT SmartContract development in Remix. We have used the OpenZeppelin ERC1155 implementation as the basis for our contract, such that the contract is standard compliant from the very beginning. Afterwards we enhanced the implementation with useful features, such as the ability to add tokens later on and tested everything using Chai and Mocha.

Leave a comment if you have any questions or suggestions. To make sure you don’t miss anything on blockchain topics, feel free to follow me.

What comes Next?

In the next part we build our animated NFT and deploy it in a decentralised way using IPFS. We also modify our contract such that we can specify the metadata on token and contract level to display the images and descriptions used by OpenSea. Afterwards i will show you how to use metamask to deploy our contract on the testnet chain.

If you are interested in part two, click here or go to my profile profile to get there.

Creating your first NFT smart contract

This tutorial will walk you through the many different components of building, deploying, and selling a non-fungible contract on Ethereum's testnet that can be traded on OpenSea.

The tutorial assumes you have some familiarity with coding, but are brand new to the world of Web3 and smart contracts. We will be using the following dependencies in the tutorial:

These tools are only some of the current community favorites so we will be using them to encourage best practices. There are many great alternatives to these tools that can also be used, and we are always open to feedback on better practices and improvements.

As we dive into new concepts in this tutorial, we will review definitions that might be new to you coming into Web3 and offer guidance on how to provide the best user experience possible for users of your smart contract. By the end of the tutorial, you will have a deployed NFT contract on the Rinkeby network, a beautifully set up collection on OpenSea, and some NFTs within that collection ready to sell on OpenSea.

Написание смарт-контракта для NFT

Карен Костанян

Привет! Меня зовут Костанян Карен, я занимаюсь разработкой на Node.js в цифровом интеграторе Secreate. В этой статье мы разберемся как написать смарт контракт и отчеканить наши нфт.

Если у вас нет медиафайлов и метаданных NFT в формате JSON, мы создали коллекцию изображений, с которыми вы можете поэкспериментировать. Вы можете найти медиафайлы здесь и файлы метаданных JSON здесь.

Мы будем использовать Hardhat, стандартную среду разработки Ethereum, для разработки, развертывания и проверки наших смарт-контрактов. Создайте пустую папку для нашего проекта и инициализируйте пустой файл package.json, выполнив в терминале следующую команду:

Теперь вы должны находиться в папке my-nft и иметь файл с именем package.json. Далее давайте установим Hardhat. Выполните следующую команду:

После установки hardhat, мы можем создать пример проекта Hardhat, выполнив следующую команду:

После этой команды, мы увидим несколько пунктов для выбора, выберите пункт (Create a basic sample project) и согласитесь со всем по умолчанию.

Давайте проверим, правильно ли установлен наш пример проекта. Выполните следующую команду:

Если все прошло успешно, вы должны увидеть следующее, отличия может быть адрес контракта:

Теперь у нас есть успешно настроенная среда разработки hardhat.

Далее, давайте установим пакет контрактов OpenZeppelin. Это даст нам доступ к контрактам ERC721 (стандарт для NFT).

Если мы хотим поделиться кодом нашего проекта публично (на веб-сайте, таком как GitHub), и при этом мы не хотим делиться конфиденциальной информацией, такой как наш закрытый ключ, API Etherscan или наш URL-адрес Alchemy (не беспокойтесь, если некоторые из этих слов вам пока не понятны), давайте установим другую библиотеку с именем dotenv.

Теперь мы установили все зависимости и можем приступить написанию нашего контракта.

Написание смарт-контракта

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

Вот как будет сначала выглядит наш контракт:

1. pragma solidity ^0.8.9

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

Если у вас есть несколько файлов и вы хотите импортировать один файл в другой, Solidity использует ключевое слово import.

Цена для чеканки(mint) одного NFT.

URL-адрес IPFS папки, содержащей метаданные JSON.

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

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

Далее, мы установим baseTokenURI в нашем конструкторе. Мы также вызовем родительский конструктор(ERC721) и установим имя и символ для наших NFT.

Таким образом, наш конструктор выглядит так:

Когда мы устанавливаем его в качестве базового URI, реализация OpenZeppelin автоматически выводит URI для каждого токена. Предполагается, что метаданные токена 1 будут доступны по адресу

а метаданные токена 2 будут доступны по адресу ipfs:/QmTMo6DFrfzKGGbkYsyMZRe16jBJcCcV72ZJHcM3a3Z2w7/2

Однако нам нужно сообщить нашему контракту, что переменная baseTokenURI, которую мы определили, является базовым URI, который должен использовать контракт. Для этого мы переопределяем пустую функцию _baseURI() и возвращаем baseTokenURI.

Мы также пишем функцию для владельца, которая позволяет владельцу изменять baseTokenURI даже после развертывания контракта.

Резервация nft для владельца

Как владелец, вы можете зарезервировать несколько NFT для себя бесплатно (оплату надо сделать только за газ).

Здесь мы определяем публичную функцию reserveNFT, которая принимает один параметр _tokenId. Это и будет наш токен который мы хотим чеканить и зарезервировать для себя. Обратите внимание, что у этого параметра есть нижнее подчеркивание (_). Он не обязателен, но есть не прописанное внутреннее правило, что все входящие параметры мы пишем со знаком _;

Это та самая чудесная функция которая делает чеканку, ее мы берем из контракта ERC721.

Сохраняем кому принадлежит этот токен.

Запускаем наше событие, что пользователь (msg.sender) сделал чеканку (_tokenId)

Функция Mint NFT

Пришло время заработать немного денег. Для того чтобы пользователи могли чеканить наши nft они должны вызвать функцию mintNFT.

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

Проверяет чтобы отправленный эфир был достаточным для чеканки nft.

Получение всех токенов, принадлежащих определенному пользователю.

Функция принимает адрес пользователя и возвращает токены которые мы хранили в хранилище nftOwner.

Вывод баланса

Самая прекрасная функция. Ее запуск, отправляет на кошелек владельца все заработанные эфиры.

Функцию может запустить только владелец.

1. balance — выбирает всю сумму на балансе контракта.

2. Проверяет чтобы баланс был положительным.

3. Отправляет эфир на кошелек владельца.

4. Проверяет что трансфер прошел успешно, в противном случае идет откат транзакции.

Проверка токена (modifier)

Если вы заметили, наши функции для чеканки reserveNFT, mintNFT могут чеканить токен который уже ранее уже был отчеканен. И перед началом процесса, мы не проверяем был ли данный токе уже отчеканен или нет. Для этого мы создадим модифаер который будет проверять статус токена до чеканки.

Модификатор функции выглядит так же как функция, но использует ключевое слово modifier вместо function. Его нельзя вызвать напрямую как функцию, вместо этого мы можем присоединить имя модификатора в конце определения функции, чтобы изменить ее поведение.

В modifier мы проверяем отчеканен ли переданный на чеканку токен. А все уже отчеканенные токены мы будем хранить в хранилище soldedTokenIds.

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

Для того чтобы наш модификатор начал правильно функционировать, мы должны добавить одно хранилище (Storage) soldedTokenIds и немного отредактировать наши функции для чеканки reserveNFT и mintNFT.

1. В самом верху контракт добавляем наше хранилище.

2. Отредактируем наши функции reserveNFT и mintNFT.

После чеканки мы храним ид токен в хранилище soldedTokenIds, и в конце функции мы добавили наш модификатор с параметром который получает наша функция.

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

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

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

Примечание. Советую развернуть его на сети Rinkeby, чтобы мы могли посмотреть результат на платформе opensea, так как из других сетей на данный момент это будет невозможно.

Для развертывания нам понадобятся следующие вещи. URL-адрес RPC, закрытый ключ от кошелька и апи ключ от etherscan.io

1. Нам понадобится URL-адрес RPC, который позволит транслировать нашу транзакцию создания контракта. Мы будем использовать Алхимию. Создайте учетную запись в Alchemy, потом необходимо создать приложение (это бесплатно).

Пишем любое название, CHAIN: Ethereum, NETWORK: Rinkeby

После того как приложение создано, перейдите на панель инструментов Alchemy и выберите его. Откроется новое окно с кнопкой View Key в правом верхнем углу. Нажмите на кнопку и выберите URL-адрес HTTP.

2. Для того чтобы получить приватный ключ от кошелька, откройте расширение Metamask, нажмите на троеточие в правом углу, и в открывшемся окне нажмите на «Реквизиты счета», затем на кнопку «Экспортировать закрытый ключ».

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

Теперь замените файл hardhat.config.js следующим содержимым.

Затем создадим файл scripts/run.js со следующим содержимым. IPFS URL замените со своим ipfs-ом (пример: ipfs://some_token/) или можете использовать наш ipfs который был описан выше.

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

Фейковый эфир, вы можете взять отсюда:

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

Если все прошло успешно вы должны увидеть адрес вашего контракта. В нашем случае:

0xd440a80F4845D5bf1AdD3868573e286e2Df04df0

Вы можете проверить этот контракт на Etherscan. Перейдите на Etherscan и введите адрес контракта. Вы должны увидеть что-то вроде этого.

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

Для верификации нам понадобится ключ Etherscan API. Зарегистрируйте бесплатную учетную запись здесь и получите доступ к своим ключам API здесь. Добавим этот ключ API в наш файл .env.

Установим следующий пакет для проверки нашего контракта.

npm install @nomiclabs/hardhat-etherscan

Теперь наш hardhat.config.js должен выглядеть следующим образом:

Теперь выполните следующие две команды:

npx hardhat clean

На места DEPLOYED_CONTRACT_ADDRESS поставьте тот адрес контракта который получили ранее, на места BASE_TOKEN_URI поставьте ваш ipfs url.

В нашем случае вторая команда выглядела так:

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

Подключите учетную запись, которую вы использовали для развертывания контракта и вызовите функцию reserveNFT, потом можете попросить кого-нибудь сделать чеканку через функцию mintNFT.

После того как вы отчеканили nft через reserveNFT или через mintNFT, вы на стороне OpenSea должны увидеть ваши nft (testnets.opensea.io)

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

Заключение

Теперь у нас есть развернутый смарт-контракт, который позволяет пользователям чеканить NFT из нашей коллекции. Очевидным следующим шагом будет создание приложения web3, которое позволит нашим пользователям создавать NFT прямо с вашего веб-сайта.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *