July 17, 2022

Создание рынка NFT на Aptos

В этом руководстве мы расскажем вам о создании модуля перемещения на рынке NFT (модуль перемещения - это эквивалент смарт-контракта на языке блокчейн). Мы также будем использовать недавно запущенный aptos CLI для компиляции и развертывания модуля в Aptos Devnet.


Martian создает различные продукты для экосистемы Aptos, включая Martian Wallet, который будет доступен в качестве расширения Chrome в течение недели. Мы также создаем NFT Marketplace под названием Curiosity, который будет использовать модуль Move, описанный здесь, и будет полностью совместим с нашим кошельком в виде расширения для браузера. Пожалуйста, присоединяйтесь к нашему Discord здесь, чтобы быть в курсе событий: https://discord.gg/GaB7BpgX7h.

Смотрите на нашем сайте последние выпуски кошелька Martian Aptos Wallet: https://martianwallet.xyz/.


Этот модуль NFT Marketplace Move поддерживает следующие функции высокого уровня:

  1. Это позволит продавцу выставить свой NFT на продажу по фиксированной цене (выраженной в Aptos TestCoin).
  2. Затем покупатель может отправить продавцу Aptos TestCoin по цене NFT через функции модуля NFT Marketplace Move, и NFT продавца будут переведены на счет покупателя.

Код и стартовый пакет доступны на нашем github здесь. Однако, пожалуйста, помните, что код ядра Aptos меняется каждую неделю, и этот код может стать несовместимым из-за этих изменений. Информирование нас в Discord здесь может быть лучшим способом решения таких вопросов.

Остальная часть статьи состоит из следующих разделов:

  1. Настройка ядра Aptos и создание локальной среды сборки
  2. Написание модуля NFT Marketplace Move (суть этой статьи)
  3. Тестирование модуля Move
  4. Использование aptos CLI для компиляции и развертывания модуля Move на devnet

Настройка локальной среды сборки

Перейдите в выбранный вами каталог и выполните следующее:

git clone https://github.com/aptos-labs/aptos-core.git

Это клонирует репо ядра Aptos локально в вашей системе. Это важно сделать, так как многие зависимости модулей Move, например aptos-vm, должны быть установлены локально (на данный момент).

Далее, клонируйте стартовый пакет с нашего официального Github.

git clone https://github.com/martian-dao/aptos-nft-marketplace.git
cd aptos-nft-marketplace

Теперь вам нужно внести несколько изменений в файлы Cargo.toml и Move.toml. Добавьте локальный путь к aptos-vm и aptos-workspace-hack в Cargo.toml. Оба эти репозитория находятся внутри каталога aptos-core, который мы клонировали в первом шаге. Аналогично, добавьте путь к aptos-framework в Move.toml.

Написание модуля перемещения

Общий код модуля можно найти здесь. Мы объясним некоторые части кода в приведенных ниже фрагментах. Для более глубокого понимания Move обратитесь к серии блогов Magnum здесь.

Мы использовали Table, Token и TestCoin из AptosFramework для создания нашей торговой площадки.

Основная идея продажи NFT: Токен изымается у продавца, когда он выставляет его на продажу. Этот изъятый токен добавляется в таблицу всех токенов, выставленных на продажу. После того как покупатель успешно заплатит продавцу (цену NFT) и владельцу рынка (listing_fee), токен зачисляется на счет покупателя, закрывая строку всех транзакций.

Структуры данных, используемые на рынке:

  • MarketItem: Содержит адрес продавца, объект NFT для продажи (токен) и цену, установленную продавцом.
struct MarketItem has key, store { 
seller: address, 
token: Token, 
price: u64
}
  • Рынок: Содержит таблицу всех продаваемых MarketItems и листинг_fee, взимаемый рынком с каждой продажи.
struct Market has key {
market_items: Table<ID, MarketItem>,
listing_fee: u64,
}

Поддерживаемые функции:

  • initMarket: инициализирует торговую площадку NFT
public(script) fun init_market_script(market_owner: &signer, listing_fee: u64) 

{let market_items = Table::new<ID, MarketItem>();

move_to<Market>(market_owner, Market {market_items, listing_fee})

}

  • listTokenForSale: выставляет ваш NFT на продажу
public(script) fun list_token_for_sale_script(

seller: &signer,

creator: address,

token_creation_num: u64,

price: u64,

market_owner_addr: address,

) acquires Market {

let token_id = GUID::create_id(creator, token_creation_num);

list_token_for_sale(seller, &token_id, price, market_owner_addr);

}

public(script) fun list_token_for_sale(

seller: &signer,

token_id: &ID,

price: u64,

market_owner_addr: address,

) acquires Market {

let seller_addr = Signer::address_of(seller);

let token = Token::withdraw_token(seller, token_id, 1);

let token_id = *Token::token_id(&token);

let market_items = &mut borrow_global_mut<Market>(market_owner_addr).market_items;

Table::add(market_items, &token_id, MarketItem {seller: seller_addr, token: token, price: price})

}
  • buyToken: покупает вам указанный НФТ
public(script) fun buy_token_script(

buyer: &signer,

seller: address,

creator: address,

token_creation_num: u64,

market_owner_addr: address,

) acquires Market {

let token_id = GUID::create_id(creator, token_creation_num);

buy_token(buyer, seller, &token_id, market_owner_addr);

}

public(script) fun buy_token(

buyer: &signer,

seller: address,

token_id: &ID,

market_owner_addr: address,

) acquires Market {

let listing_fee = borrow_global<Market>(market_owner_addr).listing_fee;

let buyer_addr = Signer::address_of(buyer);

assert!(buyer_addr != seller, ERROR_INVALID_BUYER);

let market_items = &mut borrow_global_mut<Market>(market_owner_addr).market_items;

let market_item = Table::borrow(market_items, token_id);

let price = market_item.price;

TestCoin::transfer(buyer, seller, price);

TestCoin::transfer(buyer, market_owner_addr, listing_fee);

let market_item = Table::remove(market_items, token_id);

let MarketItem{ seller: _, token: token, price: _,} = market_item;

Token::deposit_token(buyer, token)

}

Используемые счета:

  • Продавец: счет, который пытается продать свой NFT
  • Покупатель: аккаунт, который пытается купить NFT
  • MarketOwner: аккаунт, который хранит все данные, связанные с рынком NFT, и взимает плату за листинг со всех продаваемых NFT.

Тестирование модуля перемещения

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

#[test(market_owner = @0x1, seller = @0x2, buyer = @CoreResources)]

public(script) fun list_buy_test(market_owner: signer, seller: signer, buyer: signer) acquires Market {

let market_owner_addr = Signer::address_of(&market_owner);

let seller_addr = Signer::address_of(&seller);

let buyer_addr = Signer::address_of(&buyer);

init_market_script(&market_owner, 1);

let token_id = create_token(&seller, 1);

TestCoin::initialize(&buyer, 1000000);

TestCoin::register(&market_owner);

TestCoin::register(&seller);

let amount = 1000;

TestCoin::mint_internal(&buyer, buyer_addr, amount);

list_token_for_sale(&seller, &token_id, 10, market_owner_addr);

buy_token(&buyer, seller_addr, &token_id, market_owner_addr);

}

Компиляция и развертывание модуля перемещения

Для этого шага мы будем использовать aptos CLI. Aptos CLI - удобный инструмент, напоминающий hardhat на ethereum, но более удобный в использовании!

Сначала установите aptos CLI.

cargo install --git https://github.com/aptos-labs/aptos-core.git aptos

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

aptos init

Компиляция:

aptos move compile --package-dir aptos-nft-marketplace

Тест:

aptos move test --package-dir aptos-nft-marketplace

Развернуть:

aptos move publish --package-dir apos-nft-marketplace --named-addresses NFTMarketplace=default

Откройте проводник Aptos Devnet, чтобы проверить, был ли опубликован ваш модуль перемещения. Он должен выглядеть примерно так.

В качестве следующих шагов мы добавим в этот базовый модуль аукционные механизмы для продажи НМТ. Следите за расширением нашего кошелька и приложением Curiosity (NFT Marketplace), которое будет запущено в ближайшее время на следующей неделе.

Понравилась статья? Пошлите нам немного любви, следуя за нами в Twitter здесь и присоединившись к нашему Discord здесь.

Команда Martian