Введение
В этом руководстве мы будем использовать контракт Signature Drop
для создания коллекции НФТ, соответствующих стандарту ERC-721A!
По сравнению с обычным стандартом ERC-721, реализация ERC-721A
оптимизирует газовые сборы контракта, чтобы пользователи могли получать более дешевые газовые сборы при майнинге нескольких токенов в одной транзакции.
Контракт с падением подписи также позволяет майнить на основе подписи
что позволяет нам (администратору кошелька) утверждать запросы пользователей на майнинг по требованию, если они соответствуют определенным критериям, например, являются держателями другого токена!
Демонстрация
Вот что мы будем делать в этом руководстве:
- Развертывание контракта ERC-721A Signature Drop.
- Ленивый майнинг наших НФТ путем пакетной загрузки файлов метаданных.
- Создание веб-приложения, в котором пользователи могут заявлять о скидках на НМТ.
- Добавление специальной кнопки «Заявление о скидке», с помощью которой пользователи, владеющие NFT из другой коллекции, могут заявить о скидке на NFT!
Посмотрите демо-версию здесь: https://signature-drop.thirdweb-example.com/
Вы можете просмотреть полный исходный код ниже:
%[https://github.com/thirdweb-example/signature-drop]
Создание контракта на сброс подписей
Чтобы развернуть один из предварительно созданных контрактов Thirdweb, перейдите на приборную панель и подключите свой кошелек.
Если у вас еще нет кошелька, узнайте, как настроить MetaMask в нашем «Руководстве: Создание кошелька MetaMask».
Отсюда нажмите кнопку Deploy New Contract
-> Pre-Built Contracts
-> Release a drop
-> Signature Drop
.
Здесь вы можете загрузить метаданные для самого контракта. Именно эти метаданные будут отображаться на таких страницах, как страница коллекции OpenSea.
Дайте своему контракту название
, символ
, описание
, изображение
и настройте роялти по своему усмотрению! Вот как выглядит мой вариант:
Я буду развертывать в тестовой сети Arbitrum, так как она
предлагает супербыстрое время утверждения транзакций (что очень удобно для тестирования)!
Когда вы будете готовы, нажмите Deploy Now
и одобрите транзакцию Deploy Proxy
в своем кошельке.
Вы только что развернули свою собственную коллекцию ERC-721A NFT!
Пакетный ленивый майнинг НФТ
В контракте Signature Drop мы лениво майним все наши NFT, загружая метаданные с помощью функции пакетной загрузки.
Нажмите кнопку Batch Upload
, чтобы начать.
Вы попадете на страницу, где можно перетащить метаданные и активы для их загрузки. Вы можете использовать примеры файлов CSV и JSON по ссылкам на этой странице или ниже:
- Пример файла CSV
- Пример файла JSON
Вот предварительный просмотр моего файла:
Подготовив файлы, перетащите их все в поле загрузки на приборной панели:
Это позволит вам предварительно просмотреть ваши NFT, прежде чем лениво майнить их.
Убедитесь, что свойства и метаданные отображаются так, как вы ожидаете, поскольку вы не сможете изменить их после загрузки.
Когда вы будете удовлетворены, нажмите Next
:
Затем вы можете выбрать, хотите ли вы добавить отложенное раскрытие для ваших NFT. Для этого руководства мы оставим значение Reveal upon mint
и нажмем кнопку Upload NFTs!
Настройка фазы утверждения
Фазы претензий — это условия, которые определяют, как, когда и кто может претендовать на NFT из вашей коллекции; например, разрешительный список, дата выпуска или отложенное раскрытие.
Чтобы добавить фазу претензий, нажмите на вкладку Claim Phases
, а затем кнопку Add Claim Phase
:
Здесь мы можем настроить, кто может претендовать на это место. Я собираюсь установить значение :
Когда вы будете довольны, нажмите Сохранить фазы требований
!
Настройка проекта
Мы будем использовать thirdweb CLI для инициализации нашего приложения с помощью Next.js и TypeScript.
Чтобы создать новый проект с помощью CLI, выполните следующую команду:
npx thirdweb create
Дайте вашему приложению имя, и проект будет инициализирован для нас! Давайте теперь откроем проект в текстовом редакторе, я буду использовать VS Code.
Я буду использовать стили, доступные в исходном коде,
не стесняйтесь скопировать эти файлы в свой проект, если вы хотите использовать те же стили.
Если мы посмотрим на наш файл pages/app.tsx
, у нас есть настроенный activeChainId
как Mainnet
, который является Ethereum Mainnet.
Поскольку мы развернули наш контракт в тестовой сети Arbitrum, давайте изменим это значение:
// This is the chainId your dApp will work on.
const activeChainId = ChainId.ArbitrumTestnet;
Подключение к нашему контракту
Теперь мы готовы взаимодействовать с нашим смарт-контрактом с падением подписи из нашего кода, для этого мы воспользуемся хуком useSignatureDrop из React SDK.
На странице index.tsx
:
const signatureDrop = useSignatureDrop(
"0xBdEa6C9B18843cEA8262ead23767737512e452bC",
);
Вы можете получить адрес вашего контракта из панели управления:
Claiming NFTs
Поскольку логика подключения к кошельку уже настроена внутри нашего приложения благодаря thirdweb CLI, вот как теперь выглядит наша страница:
const Home: NextPage = () => {
const address = useAddress();
const connectWithMetamask = useMetamask();
const disconnectWallet = useDisconnect();
const signatureDrop = useSignatureDrop(
"0xBdEa6C9B18843cEA8262ead23767737512e452bC",
);
return (
<div>
{address ? (
<>
<button onClick={disconnectWallet}>Disconnect Wallet</button>
<p>Your address: {address}</p>
</>
) : (
<button onClick={connectWithMetamask}>Connect with Metamask</button>
)}
</div>
);
};
export default Home;
React SDK автоматически использует подписанта подключенного кошелька, когда пользователь хочет выполнить действие в нашем смарт-контракте, например claim
NFT.
Давайте теперь напишем логику для этого. Во-первых, функция claim
:
async function claim() {
const tx = await signatureDrop?.claim(1);
console.log(tx);
}
И прикрепите эту функцию к кнопке:
<button onClick={claim}>Claim</button>
Если мы предварительно просмотрим наше приложение, запустив yarn dev
из терминала и посетив сайт http://localhost:3000/, мы увидим нашу кнопку claim:
Если нажать на кнопку Claim
и одобрить транзакцию, то можно успешно отчеканить первый NFT из капли.
Теперь на приборной панели у нас есть заявленное предложение 1
.
Это самые основы настройки нашей страницы чеканки!
Заявка с подписью
Контракт на сброс с подписью также позволяет пользователям заявлять свои права, используя подпись, сгенерированную администратором кошелька. Этот процесс состоит из трех шагов:
- Пользователь запрашивает подпись для майнинга.
- Кошелек администратора (на сервере) одобряет (или отклоняет) запрос пользователя, основываясь на любых критериях, выбранных администратором, и отправляет обратно монетную подпись при одобрении.
- Пользователь использует мятную подпись для получения NFT из сброса подписей.
Это открывает перед нами всевозможные возможности, такие как:
- Ограничения на то, кто может претендовать на НМТ, основанные на данных вне цепочки.
- Скидки для пользователей, отвечающих определенным критериям (например, владеющих другим NFT или являющихся частью сервера Discord).
Мы собираемся проверить, владеет ли кошелек одним из наших НФТ с картой раннего доступа на третьемweb, и предложить им бесплатный майнинг, если да!
Создание маршрута API
Давайте вернемся к нашему коду и в папке pages
создадим папку api
. В ней создайте файл generate-mint-signature.ts
.
Сначала создадим базовую структуру нашего маршрута API:
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import type { NextApiRequest, NextApiResponse } from "next";
export default async function generateMintSignature(
req: NextApiRequest,
res: NextApiResponse,
) {
// De-construct body from request
const { address } = JSON.parse(req.body);
// Next code snippet here
}
Когда мы вызываем эту конечную точку API, мы будем передавать аргумент address
в теле запроса. В этом маршруте API мы деструктурируем это значение, чтобы использовать его при генерации подписи мяты.
Поскольку мы собираемся предоставлять НФТ бесплатно кошелькам, которые владеют одним из НФТ Early Access от Thirdweb, давайте проверим это сейчас.
Для этого мы инстанцируем thirdweb SDK с подключением только для чтения в сети Polygon и получим thirdweb-community
NFT Collection, используя его контрактный адрес.
// Get the Early Access NFT Edition Drop contract
const polygonSDK = new ThirdwebSDK("polygon");
const earlyAccessNfts = polygonSDK.getEditionDrop(
"0xa9e893cc12026a2f6bd826fdb295eac9c18a7e88", // this is the thirdweb-community NFT Collection address.
);
Затем мы можем использовать функцию balanceOf
, чтобы проверить, есть ли в кошельке, который сделал этот запрос API, какие-либо NFT из этой коллекции. Поскольку это коллекция ERC-1155, мы проверяем, есть ли у них balanceOf
любой из токенов в этой коллекции в цикле:
// Check to see if the wallet address has an early access NFT
const numTokensInCollection = await earlyAccessNfts.getTotalCount();
let userHasToken = false;
// Check each token in the Edition Drop
for (let i = 0; i < numTokensInCollection.toNumber(); i++) {
// See if they have the token
const balance = await earlyAccessNfts.balanceOf(address, i);
if (balance.toNumber() > 0) {
userHasToken = true;
break;
}
}
Отлично! Теперь у нас есть переменная userHasToken
, которая истинна, если у пользователя баланс больше нуля для любого токена в этой коллекции ERC-1155 NFT.
Теперь мы можем использовать эту переменную, чтобы определить, генерировать или нет мятную подпись для этого пользователя:
// Now use the SDK on Goerli to get the signature drop
const arbitrumSDK = ThirdwebSDK.fromPrivateKey(
process.env.PRIVATE_KEY as string,
"arbitrum-testnet"
);
const signatureDrop = arbitrumSDK.getSignatureDrop(
"your-contract-address-here" // Your contract address here
);
// If the user has an early access NFT, generate a mint signature
if (userHasToken) {
const mintSignature = await signatureDrop.signature.generate({
to: address, // Can only be minted by the address we checked earlier
price: "0", // Free!
mintStartTime: new Date(0), // now
});
res.status(200).json(mintSignature);
} else {
res.status(400).json({
message: "User does not have an early access NFT",
});
}
В приведенном выше фрагменте мы используем наш закрытый ключ для инстанцирования SDK от имени нашего кошелька администратора.
Узнайте, как экспортировать свой закрытый ключ из кошелька.
Для этого создайте файл .env
в корне вашего проекта и добавьте в него следующее:
PRIVATE_KEY=your-private-key-here
Убедитесь, что вы надежно храните свой закрытый ключ и имеете к нему доступ.
Использование маршрута API на фронтенде
На главной странице нам нужен способ вызова нашего маршрута API, давайте напишем эту функцию сейчас.
Здесь мы проверяем, вернулась ли подпись mint из запроса API. Если нет, мы выводим сообщение об ошибке. Если вернулась, мы вызываем функцию
async function claimWithSignature() {
const signedPayloadReq = await fetch(`/api/generate-mint-signature`, {
method: "POST",
body: JSON.stringify({
address: address,
}),
});
if (signedPayloadReq.status === 400) {
alert(
"Looks like you don't own an early access NFT :( You don't qualify for the free mint."
);
return;
}
try {
const signedPayload =
(await signedPayloadReq.json()) as SignedPayload721WithQuantitySignature;
console.log(signedPayload);
const nft = await signatureDrop?.signature.mint(signedPayload);
alert(`Succesfully minted NFT!`);
} catch (error: any) {
alert(error?.message);
}
}
Теперь все, что нам нужно сделать, это добавить новую кнопку, которая вызывает эту функцию:
<button onClick={() => claimWithSignature()}>Claim Free with signature</button>
Давайте проверим это:
На кошельке, который не владеет одним из этих НФТ раннего доступа, подпись для майнинга не предоставляется, что означает, что они не могут майнить бесплатно, используя метод подписи для майнинга:
На кошельке, который владеет НФТ Раннего доступа, они могут чеканить НФТ бесплатно, а не платить обычным методом!
Как только транзакция будет подтверждена, мы должны увидеть:
Вывод
Вот и все! Вы успешно создали свою собственную коллекцию ERC-721A NFT с фирменной чеканкой и создали приложение для предъявления претензий на NFT!
Чтобы узнать больше о том, что вы можете сделать с контрактом на сброс подписи, ознакомьтесь с документацией портала!