본문으로 건너뛰기

NFT 발행

이 튜토리얼에서는 쉽게 사용할 수 있는 스마트 컨트랙트와, IPFS와 같은 분산 스토리지 솔루션을 사용하여 소프트웨어 개발을 하지 않고도 자신만의 NFT를 쉽게 생성하는 방법을 배웁니다.

개요

이 글은 NFT 스마트 컨트랙트를 설정하는 방법에 대해 안내하고, NEAR에서 NFT 컨트랙트를 구축, 테스트배포하는 방법에 대해 보여줍니다. 컨트랙트가 배포되면 IPFS에 저장된 미디어 파일에서 대체 불가능한 토큰을 생성하고, 이를 지갑에서 보는 방법을 배우게 됩니다.

전제 조건

이 튜토리얼을 성공적으로 완료하려면 다음이 필요합니다.

Wallet

To store your non-fungible tokens you'll need a NEAR Wallet. If you don't have one yet, you can create one easily by following these instructions.

팁: 이 튜토리얼에서는 testnet 지갑 계정을 사용합니다. testnet 네트워크는 무료이며, 자금을 예치할 필요가 없습니다.

Once you have your Wallet account, you can click on the Collectibles tab where all your NFTs will be listed:

Wallet

IPFS

IPFS (InterPlanetary File System)는 분산 파일 시스템에서 데이터를 저장하고 공유하기 위한 프로토콜 및 피어 투 피어 네트워크입니다. IPFS는 콘텐츠 주소를 지정하여 모든 컴퓨팅 장치를 연결하는 글로벌 네임스페이스에서 각 파일을 고유하게 식별합니다.

이미지 업로드

To upload the NFT image, you should use a decentralized storage provider such as IPFS.

노트

This example uses IPFS, but you could use a different solution like Filecoin, Arweave, or a regular centralized Web2 hosting.

Once you have uploaded your file to IPFS, you'll get a unique CID for your content, and a URL like:

https://bafyreiabag3ztnhe5pg7js4bj6sxuvkz3sdf76cjvcuqjoidvnfjz7vwrq.ipfs.dweb.link/

대체 불가능 토큰 컨트랙트

이 레퍼지토리에는 컨트랙트 표준 및 시뮬레이션 테스트를 사용하는 대체 불가능 토큰 컨트랙트의 구현 예시가 포함되어 있습니다.

NFT 레퍼지토리 복제

터미널에서 다음 명령을 실행하여 NFT 레퍼지토리를 복제합니다.

git clone https://github.com/near-examples/NFT

스마트 컨트랙트 알아보기

이 컨트랙트의 소스 코드는 nft/src/lib.rs에서 찾을 수 있습니다. 이 컨트랙트에는 NEP-171 표준(NEAR Enhancement Proposal)을 따르는 로직과 여기에서 찾을 수 있는 표준의 구현이 포함되어 있습니다.

처음에는 코드가 다소 복잡할 수 있지만, 발행과 관련된 측면만 고려하면 컨트랙트 구조와 발행 프로세스라는 두 가지 주요 범주로 나눌 수 있습니다.

컨트랙트 구조

컨트랙트는 tokensmetadata 두 가지 정보를 추적합니다. 이 튜토리얼의 목적을 위해, 우리는 tokens 필드만 다룰 것입니다.

#[near(contract_state)]
#[derive(PanicOnDefault)]
pub struct Contract {
tokens: NonFungibleToken,
metadata: LazyOption<NFTContractMetadata>,
}

이 토큰은 핵심 표준NonFungibleToken 자료형입니다. 구조체를 구성하는 여러 필드가 있지만, 이 튜토리얼의 목적상 owner_by_id 필드에만 관심을 둘 것입니다. 이 필드는 주어진 토큰의 소유자를 추적합니다.

pub struct NonFungibleToken {
// owner of contract
pub owner_id: AccountId,

// keeps track of the owner for any given token ID.
pub owner_by_id: TreeMap<TokenId, AccountId>,

...
}

이제 뒤에서 데이터가 어디에 보관되는지 살펴보았으므로, 발행 기능으로 이동하겠습니다.

발행

토큰을 발행하려면 nft_mint 함수를 호출해야 합니다. 이 함수에 전달되는 세 가지 인자는 다음과 같습니다.

  • token_id
  • receiver_id
  • token_metadata

이 함수는 핵심 표준에서 발행 함수를 호출하는 self.tokens.mint를 실행하여, receiver_id인 소유자의 토큰 기록을 생성합니다.

#[payable]
pub fn nft_mint(
&mut self,
token_id: TokenId,
receiver_id: ValidAccountId,
token_metadata: TokenMetadata,
) -> Token {
self.tokens.mint(token_id, receiver_id, Some(token_metadata))
}

이는 이전 섹션에서 언급한 owner_by_id 자료구조에 토큰을 삽입하여 해당 기록을 생성합니다.

self.owner_by_id.insert(&token_id, &owner_id);

컨트랙트 구축

컨트랙트를 구축하려면, 터미널에서 다음 명령을 실행해 Rust의 cargo를 사용하는 컨트랙트를 구축하세요.

./scripts/build.sh

이렇게 하면 res/ 디렉토리에 WASM 바이너리가 생성됩니다. 이 WASM 파일은 NEAR 블록체인에 배포할 스마트 컨트랙트입니다.

Tip: If you run into errors make sure you have Rust installed and are in the root directory of the NFT example.

컨트랙트 테스트

스마트 컨트랙트에는, 실행할 수 있는 미리 작성된 테스트가 작성되어 있습니다. 터미널에서 다음 명령을 실행하여 간단한 테스트를 수행하고, 컨트랙트 코드가 작동하는지 확인하십시오.

cargo test -- --nocapture

참고: 더 복잡한 시뮬레이션 테스트는 이 명령으로 수행되지 않지만, tests/sim에서 찾을 수 있습니다.

NFT 컨트랙트 사용

NFT 스마트 컨트랙트를 성공적으로 구축하고 테스트했으므로, 이제 이를 배포하고,이를 사용해 NFT를 발행할 준비가 되었습니다.

컨트랙트 배포

이 스마트 컨트랙트는 NEAR 계정에 배포됩니다. NEAR는 동일한 계정에서 컨트랙트를 업그레이드할 수 있는 기능을 허용하므로, 초기화 함수를 클리어해야 합니다.

참고: 이전에 컨트랙트가 배포되었던 NEAR 계정에서 이 예제를 실행하려면, near delete라는 near-cli 명령을 사용한 다음 지갑에서 이를 재생성하세요. To create (or recreate) an account, please follow the directions in Test Wallet or (NEAR Wallet if we're using mainnet).

터미널에서 다음 명령을 실행하여 near-cli로 새로 만든 계정에 로그인하세요.

near login

이 튜토리얼을 더 쉽게 복사/붙여넣기할 수 있도록, 계정 ID에 대한 환경 변수를 설정하겠습니다. 아래 명령에서 YOUR_ACCOUNT_NAME.testnet (또는mainnet을 쓰는 경우 .near)에서 방금 로그인한 계정 이름으로 바꿔 보세요.

export ID=YOUR_ACCOUNT_NAME

다음을 실행하여 환경 변수가 올바르게 설정되었는지 테스트합니다.

echo $ID

터미널에 올바른 계정 ID가 표시되어 있는지 확인하십시오. 모든 것이 올바르게 보이면 이제 컨트랙트를 배포할 수 있습니다. NFT 프로젝트의 루트에서 다음 명령을 실행하여 스마트 컨트랙트를 배포합니다.

near deploy --wasmFile res/non_fungible_token.wasm --accountId $ID
응답 예시:

Starting deployment. Account id: ex-1.testnet, node: https://rpc.testnet.near.org, file: res/non_fungible_token.wasm
Transaction Id E1AoeTjvuNbDDdNS9SqKfoWiZT95keFrRUmsB65fVZ52
To see the transaction in the transaction explorer, please open this url in your browser
https://testnet.nearblocks.io/txns/E1AoeTjvuNbDDdNS9SqKfoWiZT95keFrRUmsB65fVZ52
Done deploying to ex-1.testnet

참고: mainnet에서는 명령 앞에 NEAR_ENV=mainnet를 붙여야 합니다. 더 많은 정보는 여기서 볼 수 있습니다.

NFT 발행

스마트 컨트랙트는 컨트랙트의 초기 상태를 설정하는 데 사용할 수 있는 초기화 방법을 정의할 수 있습니다. 우리의 경우, 사용하기 전에 NFT 컨트랙트를 초기화해야 합니다. 지금은 기본 메타데이터로 초기화하겠습니다.

참고: 각 계정에는 함수 호출과 트랜잭션 간 지속되는 storage라는 데이터 영역이 있습니다. 예를 들어, 컨트랙트를 초기화하면 초기 상태가 영구 스토리지에 저장됩니다.

near call $ID new_default_meta '{"owner_id": "'$ID'"}' --accountId $ID

팁: nomicon.io에서 NFT 메타데이터에 대한 자세한 정보를 찾을 수 있습니다.

그런 다음, view 호출을 실행하여 메타데이터를 볼 수 있습니다.

near view $ID nft_metadata
응답 예시:

{
"spec": "nft-1.0.0",
"name": "Example NEAR non-fungible token",
"symbol": "EXAMPLE",
"icon": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 288 288'%3E%3Cg id='l' data-name='l'%3E%3Cpath d='M187.58,79.81l-30.1,44.69a3.2,3.2,0,0,0,4.75,4.2L191.86,103a1.2,1.2,0,0,1,2,.91v80.46a1.2,1.2,0,0,1-2.12.77L102.18,77.93A15.35,15.35,0,0,0,90.47,72.5H87.34A15.34,15.34,0,0,0,72,87.84V201.16A15.34,15.34,0,0,0,87.34,216.5h0a15.35,15.35,0,0,0,13.08-7.31l30.1-44.69a3.2,3.2,0,0,0-4.75-4.2L96.14,186a1.2,1.2,0,0,1-2-.91V104.61a1.2,1.2,0,0,1,2.12-.77l89.55,107.23a15.35,15.35,0,0,0,11.71,5.43h3.13A15.34,15.34,0,0,0,216,201.16V87.84A15.34,15.34,0,0,0,200.66,72.5h0A15.35,15.35,0,0,0,187.58,79.81Z'/%3E%3C/g%3E%3C/svg%3E",
"base_uri": null,
"reference": null,
"reference_hash": null
}

이제 첫 번째 토큰을 발행해 봅시다! 다음 명령은 NFT의 사본 하나를 생성합니다. media URL을 이전에 IPFS에 업로드한 URL로 바꿉니다.

near call $ID nft_mint '{"token_id": "0", "receiver_id": "'$ID'", "token_metadata": { "title": "Some Art", "description": "My NFT media", "media": "https://bafkreiabag3ztnhe5pg7js4bj6sxuvkz3sdf76cjvcuqjoidvnfjz7vwrq.ipfs.dweb.link/", "copies": 1}}' --accountId $ID --deposit 0.1
응답 예시:

{
"token_id": "0",
"owner_id": "dev-xxxxxx-xxxxxxx",
"metadata": {
"title": "Some Art",
"description": "My NFT media",
"media": "https://bafkreiabag3ztnhe5pg7js4bj6sxuvkz3sdf76cjvcuqjoidvnfjz7vwrq.ipfs.dweb.link/",
"media_hash": null,
"copies": 1,
"issued_at": null,
"expires_at": null,
"starts_at": null,
"updated_at": null,
"extra": null,
"reference": null,
"reference_hash": null
},
"approved_account_ids": {}
}

계정이 소유한 토큰을 보려면, 다음과 같은 near-cli 명령을 사용하여 NFT 컨트랙트를 호출할 수 있습니다.

near view $ID nft_tokens_for_owner '{"account_id": "'$ID'"}'
응답 예시:

[
{
"token_id": "0",
"owner_id": "dev-xxxxxx-xxxxxxx",
"metadata": {
"title": "Some Art",
"description": "My NFT media",
"media": "https://bafkreiabag3ztnhe5pg7js4bj6sxuvkz3sdf76cjvcuqjoidvnfjz7vwrq.ipfs.dweb.link/",
"media_hash": null,
"copies": 1,
"issued_at": null,
"expires_at": null,
"starts_at": null,
"updated_at": null,
"extra": null,
"reference": null,
"reference_hash": null
},
"approved_account_ids": {}
}
]


Tip: after you mint your first non-fungible token, you can view it in your Wallet:

Wallet with token


축하합니다! NEAR 블록체인에서 첫 번째 NFT 토큰을 발행했습니다! 🎉

끝맺는 말

이 기본 예제는 NFT 스마트 컨트랙트를 배포하고, IPFS에 미디어 파일을 저장하며, 대체 불가능 토큰을 만들기 시작하는 데 필요한 모든 단계를 보여줍니다.

이제 프로세스에 익숙해졌으므로, NFT 예제를 확인하고 스마트 컨트랙트 코드와 발행된 토큰을 다른 계정으로 전송하는 방법에 대해 자세히 알아볼 수 있습니다. Finally, if you are new to Rust and want to dive into smart contract development, our Quick-start guide is a great place to start.

즐거운 민팅 되세요! 🪙

Blockcraft - 실용적인 확장

Minecraft를 사용하여 NFT를 생성하고 모든 데이터를 온체인에 저장하면서 여러 세계에서 빌드를 복사/붙여넣는 방법을 알아보려면 Minecraft 튜토리얼을 확인하세요.

문서 버전 관리

이 글을 쓰는 시점에서 이 예제는 다음 버전에서 작동합니다.

  • cargo: cargo 1.54.0 (5ae8d74b3 2021-06-22)
  • rustc: rustc 1.54.0 (a178d0322 2021-07-26)
  • near-cli: 2.1.1
Was this page helpful?