마켓플레이스
이 튜토리얼에서는 $NEAR에 대해 대체 불가능 토큰(NFT)을 사고 팔 수 있는 NFT 마켓플레이스 컨트랙트의 기본 사항을 배웁니다. 이전 튜토리얼에서는 NFT 표준에 있는 모든 표준을 통합하는 완전한 NFT 컨트랙트를 작성했습니다.
소개
이 튜토리얼을 통해 마켓플레이스 컨트랙트가 NEAR에서 작동하는 방법을 배우게 됩니다. 이것은 예시용이며 표준 구현체는 없습니다. 당신의 요구 사항에 맞게 이 컨트랙트를 자유롭게 나누고 수정하세요.
이전 튜토리얼과 동일한 레퍼지토리를 사용하여 8.marketplace
브랜치를 확인하면, 튜토리얼을 완료하는 데 필요한 파일이 있어야 합니다.
git checkout 8.marketplace
파일 구조
market-contract
└── src
├── internal.ts
├── index.ts
├── nft_callbacks.ts
├── sale.ts
└── sale_views.ts
일반적으로 모두 동일한 레퍼지토리에 속하는 여러 스마트 컨트랙트에서 작업을 수행할 때, 이 튜토리얼에서 수행한 대로 자체 폴더에 구성하는 것이 좋습니다. 두 스마트 컨트랙트를 쉽게 빌드할 수 있도록 레퍼지토리의 package.json
파일도 수정해 두었기 때문에, 이 스마트 컨트랙트 두 개를 빌드할 때 다음 명령을 실행할 수 있습니다.
yarn build
이렇게 하면 두 컨트랙트에 대한 의존성(dependency)이 설치되고 아래 디렉터리에 저장된 wasm
파일로 컴파일됩니다.
nft-tutorial-js
└── build
├── nft.wasm
└── market.wasm
컨트랙트 이해하기
처음에는 컨트랙트가 상당히 버거울 수 있지만, 모든 부가 기능을 제외하고 핵심 기능만 파헤치면 실제로는 매우 간단합니다. 이 컨트랙트는 사람들이 NEAR를 위해 NFT를 사고 팔 수 있도록 한다는 단 한 가지를 위해 설계되었습니다. 여기에는 로열티 지불, 판매 가격 업데이트, 판매 제거 및 스토리지 비용 지불에 대한 지원이 포함됩니다.
몇 가지 중요한 기능을 하는 파일과 함수들을 살펴 봅시다.
index.ts
이 파일은 컨트랙트에 저장되는 정보와 아래에서 배우게 될 몇 가지 주요 함수에 대해 설명합니다.
생성자 로직
처음으로 살펴볼 함수는 생성자 함수입니다. 이것은 유일한 매개변수로 owner_id
를 사용하며, 모든 스토리지 컬렉션을 기본값으로 설정합니다.
Loading...
스토리지 관리 모델
Next, let's talk about the storage management model chosen for this contract. On the NFT contract, users attached $NEAR to the calls that needed storage paid for. For example, if someone was minting an NFT, they would need to attach x
amount of NEAR to cover the cost of storing the data on the contract.
On this marketplace contract, however, the storage model is a bit different. Users will need to deposit $NEAR onto the marketplace to cover the storage costs. Whenever someone puts an NFT for sale, the marketplace needs to store that information which costs $NEAR. Users can either deposit as much NEAR as they want so that they never have to worry about storage again or they can deposit the minimum amount to cover 1 sale on an as-needed basis.
You might be thinking about the scenario when a sale is purchased. What happens to the storage that is now being released on the contract? This is why we've introduced a storage withdrawal function. This allows users to withdraw any excess storage that is not being used. Let's go through some scenarios to understand the logic. The required storage for 1 sale is 0.01 NEAR on the marketplace contract.
Scenario A
- Benji는 마켓플레이스에 자신의 NFT를 리스팅하고 싶지만, 스토리지 비용을 지불한 적이 없습니다.
- 그는
storage_deposit
메서드를 사용하여 정확히 0.01 NEAR를 예치합니다. 이것은 한 번의 판매를 커버할 것입니다. - 그는 마켓플레이스에 자신의 NFT를 리스팅하였 습니다. 현재 선불 판매 1개 중 1개를 사용하고 있기 때문에 더 이상 스토리지 공간이 남아 있지 않습니다. 그가
storage_withdraw
를 호출하면 아무 일도 일어나지 않을 것입니다. - Dorian은 Benji의 NFT를 좋아하고, 다른 사람보다 먼저 빠르게 구매했습니다. 이는 Benji의 판매가 이제 중단되었으며(구매한 이후) Benji는 선불 판매 1개 중 0개를 사용하고 있음을 의미합니다. 즉, 그는 1 판매 또는 0.01 NEAR가 남습니다.
- Benji는 이제
storage_withdraw
호출을 할 수 있으며, 그의 0.01 NEAR를 다시 돌려받을 것입니다. 컨트랙트 측면에서, 그는 출금 후 판매 금액이 0이 되며, 이제 NFT를 리스팅하기 전에 스토리지 비용을 예치해야 합니다.
Scenario B
- Dorian은 100개의 아름다운 NFT를 소유하고 있으며, 모든 NFT를 리스팅하고 싶습니다.
- NFT를 나열할 때마다
storage_deposit
를 호출할 필요가 없도록, 그는 한 번만 호출하였습니다. Dorian은 성공한 사람이기 때문에 1000개의 판매를 커버하기에 충분한 10개의 NEAR를 첨부하였습니다. 이후, 그는 이제 9 NEAR 또는 900 판매를 초과했습니다. - Dorian은 다른 일을 위해 9 NEAR가 필요하지만, 100개의 리스팅을 삭제하고 싶지는 않습니다. 그는 9 NEAR가 남았기 때문에 쉽게 인출할 수 있고 여전히 100개의 목록을 보유할 수 있습니다.
storage_withdraw
호출을 하고 9 NEAR를 받으면 그는 0개의 판매 가능 수량을 가지게 될 것입니다.
With this behavior in mind, the following two functions outline the logic.
Loading...
이 컨트랙트에서 각 판매에 필요한 스토리지는 0.01 NEAR이지만, storage_minimum_balance
함수를 사용하여 해당 정보를 조회할 수 있습니다. 또한, 해당 계정이 지불한 스토리지 공간을 확인하려면 storage_balance_of
함수로 쿼리할 수 있습니다.
그 방법으로, nft_callbacks.ts
파일로 이동하여 NFT가 판매되는 방법을 볼 수 있습니다.