KAS Docs Dev
한국어
한국어
  • Introduction
  • Basics
    • KAS 콘솔
    • KAS API
  • Getting Started
    • KAS 가입, 인증, 권한, SDK 설치
    • KAS Project 생성, 수정, 관리
    • 클레이튼 계정 생성
    • API 호출
    • 마이그레이션 가이드
  • Tutorial
    • 메타 정보 조회
    • JSON-RPC API
    • 계정 생성과 관리
    • 트랜잭션 전송
      • KLAY 보내기
      • 스마트 컨트랙트 배포
      • 스마트 컨트랙트 실행
      • 보류중인 트랜잭션 취소
      • RLP 문자열 트랜잭션
      • 계정 업데이트
      • 데이터 앵커링
      • 다중 서명 트랜잭션
      • 기타
    • 토큰 정보 조회
      • 송/수신 기록 조회
      • 토큰 컨트랙트 조회
      • NFT 정보 조회
      • NFT 소유권 변동 조회
    • 데이터 앵커링
    • KAS 기반 BApp 예시
      • 명품 영수증 관리 애플리케이션
      • 커피 원격 주문 애플리케이션
    • NFT 컨트랙트 배포 및 토큰 발행/전송
    • FT 컨트랙트 배포 및 토큰 발행/전송
    • MT 컨트랙트 배포 및 토큰 발행/전송
  • API
    • Klaytn Node API
    • Token History API
    • Wallet API
    • Anchor API
    • KIP-7 API
    • KIP-17 API
    • KIP-37 API
    • Metadata API
    • API Change Log
  • SDK
    • caver-js-ext-kas
    • caver-java-ext-kas
  • 개발자 포럼
  • 개인정보처리방침
  • 서비스 이용약관
Powered by GitBook
On this page
  • KIP-17 컨트랙트 배포
  • API 경로와 요청
  • 필수 헤더
  • 인증
  • API 응답
  • 결과 확인
  • KIP-17 토큰 발행
  • 토큰 발행 요청
  • 토큰 발행 응답과 발행 결과 확인
  • KIP-17 토큰 전송
  • 토큰 전송 JSON
  • 토큰 전송 결과

Was this helpful?

  1. Tutorial

NFT 컨트랙트 배포 및 토큰 발행/전송

Previous커피 원격 주문 애플리케이션NextFT 컨트랙트 배포 및 토큰 발행/전송

Last updated 4 years ago

Was this helpful?

은 Klaytn에서 정의한 NFT(Non-Fungible Token) 컨트랙트 표준입니다. KAS는 KIP-17 API를 통해 KIP-17 토큰을 쉽고 편리하게 생성/관리할 수 있는 API를 제공합니다. KIP-17 API의 대표적인 기능은 KIP-17 컨트랙트의 배포, 토큰의 발급, 소각, 전송 등입니다.

이 예제를 통해 KIP-17 API를 사용하여 KIP-17 컨트랙트를 배포하고 KIP-17 토큰을 발급 및 전송하는 것을 설명드리도록 하겠습니다. 전체 KIP-17 API에 대한 자세한 사양은 를 통해 확인하실 수 있습니다.

KIP-17 컨트랙트 배포

KIP-17 API는 KIP-17 표준을 따르는 NFT 컨트랙트를 배포하고 제어합니다.

KIP-17 컨트랙트 표준의 함수들에 관한 더 자세한 정보는 을 확인하세요.

KIP-17 컨트랙트의 배포는 다음과 같은 curl 명령어를 실행하여 수행할 수 있습니다.

curl --location --request POST "https://kip17-api.klaytnapi.com/v1/contract" \
  --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key} \
  --data-raw '{
        "alias": "my-first-kip17",
        "name": "My First KIP-17",
        "symbol": "MFK"
  }'
const result = await caver.kas.kip17.deploy('My First KIP-17', 'MFK', 'my-first-kip17')
String name = "My First KIP-17";
String symbol = "MFK";
String alias = "my-first-kip17";
Kip17TransactionStatusResponse res = caver.kas.kip17.deploy(name, symbol, alias);

API 경로와 요청

curl 명령어를 부분으로 나누어 하나씩 살펴보겠습니다. 는 POST /v1/contract로 실행할 수 있습니다. KIP-17 API가 https://kip17-api.klaytnapi.com에서 서비스 되고 있으니 curl 요청의 URL을 https://kip17-api.klaytnapi.com/v1/contract로, 요청 유형은 POST (—-request POST)로 설정합니다.

컨트랙트 배포 API는 POST 요청을 받아들이며 다음과 같은 JSON 데이터를 요구합니다.

{
    "alias": "my-first-kip17",
    "name": "My First KIP-17",
    "symbol": "MFK"
}
// caver-js-ext-kas로 KIP-17 컨트랙트를 배포하는 경우, API request의 body에 필요한 데이터를 함수의 파라미터로 전송합니다.
// caver.kas.kip17.deploy(name, symbol, alias [, callback])
const result = await caver.kas.kip17.deploy('My First KIP-17', 'MFK', 'my-first-kip17')
String name = "My First KIP-17";
String symbol = "MFK";
String alias = "my-first-kip17";

Kip17TransactionStatusResponse res = caver.kas.kip17.deploy(name, symbol, alias);
System.out.println(res);

각각의 필드에 대한 설명은 다음과 같습니다:

  • Alias (alias): 컨트랙트의 별명입니다. 이후 API들에서 컨트랙트 주소대신 사용가능합니다. 허용되는 문자는 알파벳 소문자, 숫자, 하이픈이며 별명의 첫 문자는 알파벳 소문자로 제한됩니다.

  • Name (name): 컨트랙트의 이름입니다. KIP-17 표준에서 요구하는 name으로 사용됩니다. 허용되는 문자는 알파벳, 숫자, 하이픈입니다.

  • Symbol(symbol): 컨트랙트의 심볼입니다. KIP-17 표준에서 요구하는 symbol로 사용됩니다. 일반적으로 알파벳 대문자 3~4개로 구성되나 이를 제약하지는 않습니다.

필수 헤더

모든 KIP-17 API는 x-chain-id 헤더값을 요구합니다. 허용되는 값은 1001 (Baobab), 8217 (Cypress) 입니다.

인증

API 응답

토큰 배포 curl 명령어를 실행하면 다음과 같은 결과를 받게됩니다:

{
    "transactionHash": "0x...",
    "status": "Submitted"
}
{
    status: 'Submitted',
    transactionHash: '0x...',
}
class Kip17TransactionStatusResponse {
    status: Submitted
    transactionHash: 0x....
}

결과 확인

curl --location --request GET 'https://kip17-api.klaytnapi.com/v1/contract' \
  --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key}
const result = await caver.kas.kip17.getContractList()
Kip17ContractListResponse response = caver.kas.kip17.getContractList();
System.out.println(response);

컨트랙트가 올바르게 배포되었다면 다음과 같은 응답을 받을 수 있습니다.

{
    "items": [
        {
            "address": "0x...",
            "alias": "my-first-kip17",
            "name": "My First KIP-17",
            "symbol": "MFK"
        }
    ],
    "cursor": ""
}
{
    cursor: '',
    items: [
        {
            address: '0x...',
            alias: 'my-first-kip17',
            name: 'My First KIP-17',
            symbol: 'MFK',
        },
    ],
}
class Kip17ContractListResponse {
    cursor: "..."
    items: [class Kip17ContractListResponseItem {
        address: 0x...
        alias: my-first-kip17
        name: My First KIP-17
        symbol: MFK
    }, 
    {...}
    ]
}

KIP-17 토큰 발행

컨트랙트를 성공적으로 배포했다면 이제 토큰을 발행할 수 있습니다. 토큰을 발행하는 API는 POST /v1/contract/{alias-or-address}/token 입니다. 여기서 {alias-or-address}는 토큰을 발행하려는 컨트랙트의 별명(alias) 또는 주소(address)로 토큰을 배포할 때 제출하신 alias나 토큰 배포 후 컨트랙트 목록 조회 API에서 확인하신 address를 사용하시면 됩니다.

토큰 발행 요청

curl --location --request POST 'https://kip17-api.klaytnapi.com/v1/contract/my-first-kip17/token' \
  --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key} \
    --data-raw '{
      "to": "0x...",
      "id": "0x1",
      "uri": "https://link.to.your/token/metadata-0x1.json"
    }'
const result = await caver.kas.kip17.mint('my-first-kip17', '0x...', '0x1', 'https://link.to.your/token/metadata-0x1.json')
String contractAlias = "my-first-kip17";
String to = "0x{toAddress}";
String id = "0x1";
String uri = "https://link.to.your/token/metadata-0x1.json";

Kip17TransactionStatusResponse response = caver.kas.kip17.mint(contractAlias, to, id, uri);
System.out.println(response);

필수 헤더, 인증 정보 등은 컨트랙트 배포와 동일하며 location, request와 같은 정보는 토큰 발행 API (POST /v1/contract/{alias-or-address}/token)에 맞추어 입력합니다.

토큰 발행 API는 다음과 같은 JSON 데이터를 요구합니다.

{
    "to": "0x...",
    "id": "0x1",
    "uri": "https://link.to.your/token/metadata-0x1.json"
}
// caver-js-ext-kas로 KIP-17 토큰을 발행하는 경우, API request의 body에 필요한 데이터를 함수의 파라미터로 전송합니다.
// caver.kas.kip17.mint(addressOrAlias, to, tokenId, tokenURI [, callback])
const result = await caver.kas.kip17.mint('my-first-kip17', '0x...', '0x1', 'https://link.to.your/token/metadata-0x1.json')
// caver-java-ext-kas로 KIP-17 토큰을 발행하는 경우, API request의 body에 필요한 데이터를 함수의 파라미터로 전송합니다.
// caver.kas.kip17.mint((addressOrAlias, to, tokenId, tokenURI);
String contractAlias = "my-first-kip17";
String to = "0x{toAddress}";
String id = "0x1"
String uri = "https://link.to.your/token/metadata-0x1.json";

Kip17TransactionStatusResponse response = caver.kas.kip17.mint(contractAlias, to, id, uri);
System.out.println(response);
  • Recipient (to): 토큰을 받는 사람의 클레이튼 계정 주소입니다. 토큰 발행 API는 지정된 주소로 새로운 토큰을 발행합니다.

  • Token ID (id): 토큰의 고유번호입니다. 16진수로 표현되며 이미 발행되어있는 토큰의 고유번호는 사용할 수 없습니다. 단, 소각된 토큰의 고유번호는 재사용할 수 있습니다.

Klaytn 계정의 주소는 16진수로 표현됩니다. 길이는 20-byte로 접두사인 "0x"를 포함하여 16진수 42자로 표현됩니다.

토큰 발행 응답과 발행 결과 확인

토큰 발행 curl을 수행하면 다음과 같은 응답을 받을 수 있습니다.

{
    "transactionHash": "0x...",
    "status": "Submitted"
}
{
    status: 'Submitted',
    transactionHash: '0x...',
}
class Kip17TransactionStatusResponse {
    status: Submitted
    transactionHash: 0x....
}

컨트랙트 배포를 실행했을 때와 같은 형식의 응답이 오는 것을 확인할 수 있습니다.

curl --location --request GET 'https://kip17-api.klaytnapi.com/v1/contract/my-first-kip17/token' \
  --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key}
const result = await caver.kas.kip17.getTokenList('my-first-kip17')
Kip17TokenListResponse response = caver.kas.kip17.getTokenList("my-first-kip17");
System.out.println(response);

토큰이 성공적으로 발행되었다면 다음과 같은 응답을 받을 수 있습니다.

{
    "items": [{
            "createdAt": <UNIX timestamp>,
            "owner": "0x...",
            "previousOwner": "0x0000000000000000000000000000000000000000",
            "tokenId": "0x1",
            "tokenUri": "https://link.to.your/token/metadata-0x1.json",
            "transactionHash": "0x...",
            "updatedAt": <UNIX timestamp>
        }],
    "cursor": ""
}
{
    cursor: '',
    items: [
        {
            createdAt: 1610524249,
            owner: '0x...',
            previousOwner: '0x0000000000000000000000000000000000000000',
            tokenId: '0x1',
            tokenUri: 'https://link.to.your/token/metadata-0x1.json',
            transactionHash: '0x...',
            updatedAt: 1610524249,
        },
    ],
}
class Kip17TokenListResponse {
    cursor: 
    items: [class Kip17TokenListResponseItem {
        createdAt: 1610524249
        owner: 0x...
        previousOwner: 0x0000000000000000000000000000000000000000
        tokenId: 0x1
        tokenUri: https://link.to.your/token/metadata-0x1.json
        transactionHash: 0x...
        updatedAt: 1610524249
    }, class Kip17TokenListResponseItem {
        ...
    }]
}

응답의 status를 눈여겨 보셨다면 "Success"나 "Completed"가 아닌 "Submitted"인 것을 확인할 수 있습니다. Klaytn을 비롯한 모든 블록체인은 요청에 대한 응답이 즉시 돌아오지 않는 비동기 형태로 동작하기 때문에 요청이 성공했는지 바로 확인할 수 없습니다. 특히 토큰 발행과 같이 요청값에 따라 요청이 실패할 수 있는 경우(e.g., 이미 존재하는 토큰 고유번호를 사용)가 존재하기 때문에 토큰 목록 조회 실행과 같은 명시적인 확인이 필요합니다.

KIP-17 토큰 전송

이 예제는 KAS 사용자가 KAS Wallet Account Pool에 사전에 등록한 계정이 존재하며 편의상 그 계정의 주소가 0xOWNER라고 가정합니다.

KIP-17 API로 토큰을 전송하려면 토큰을 보내는 사람의 계정의 (cryptographic) key가 KAS Wallet Account Pool에 등록되어 있어야 합니다. 또한, Key가 Default Account Pool에 등록되어 있지 않을 경우 해당 Pool의 KRN을 x-krn 헤더에 직접 입력해야합니다.

예제에서는 편의상 0xOWNER라고 표기했으나 실제 주소는 Klaytn 계정 주소로 올바르게 표현되어야 합니다.

다음 curl 명령어는 0xOWNER가 소유한 my-first-kip17 컨트랙트의 0x321 토큰을 0xRECIPIENT에게 전송합니다.

curl --location --request POST 'https://kip17-api.klaytnapi.com/v1/contract/my-first-kip17/token/0x321' \
  --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key} \
    --data-raw '{
      "sender": "0xOWNER",
      "owner": "0xOWNER",
      "to": "0xRECIPIENT"
    }'
// caver.kas.kip17.transfer(addressOrAlias, sender, owner, to, tokenId [, callback])
const result = await caver.kas.kip17.transfer('my-first-kip17', '0xOWNER', '0xOWNER', '0xRECIPIENT', '0x321')
String contractAlias = "my-first-kip17";
String ownerAddress = "0x{OwnerAddress}";
String recipientAddress = "0x{RecipientAddress}";
String tokenId = "0x321";
Kip17TransactionStatusResponse response = caver.kas.kip17.transfer(contractAlias, ownerAddress, ownerAddress, recipientAddress, tokenId);
System.out.println(response);

토큰 전송 JSON

토큰 전송에 필요한 JSON 데이터는 다음과 같습니다.

  • Sender (sender): 토큰 전송 API를 실행하는 사람의 주소입니다.

  • Recipient (to): 토큰을 받는 사람의 주소입니다. 블록체인 특성상 소유권이 넘어가면 되돌릴 수 없으니 주의하시기 바랍니다.

Sender, owner 정보가 올바르지 않을 경우 전송 요청은 실패합니다. Sender는 전송 승인을 받은 주소가 아닐 경우 owner와 동일해야 하며 owner는 반드시 전송하려는 토큰을 소유한 사람의 주소여야 합니다.

Sender, owner의 정보가 올바르지 않을 때에도 전송 요청 API는 응답을 반환합니다. KIP-17 API는 요청의 형태, 형식(syntax)이 올바른지에 대해서만 검증합니다. Sender가 사전에 승인을 받았는지, owner가 정말 토큰을 소유하고 있는지와 같은 내용(semantic)에 대해서는 검증하지 않습니다.

토큰 전송 결과

토큰 전송 API를 실행하면 다음과 같은 응답을 받습니다.

{
    "transactionHash": "0x...",
    "status": "Submitted"
}
{
    status: 'Submitted',
    transactionHash: '0x...',
}
class Kip17TransactionStatusResponse {
    status: Submitted
    transactionHash: 0x....
}
curl --location --request GET 'https://kip17-api.klaytnapi.com/v1/contract/my-first-kip17/token'
    --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key}
const result = await caver.kas.kip17.getTokenList('my-first-kip17')
Kip17TokenListResponse response = caver.kas.kip17.getTokenList("my-first-kip17");
System.out.println(response);

토큰 전송이 올바르게 수행되었을 경우 다음과 같이 전송한 토큰의 정보가 변경된 것을 확인할 수 있습니다. owner와 previousOwner를 확인하시기 바랍니다.

{
    "items": [
        ...,
        {
            "createdAt": <UNIX timestamp>,
            "owner": "0xRECIPIENT",
            "previousOwner": "0xOWNER",
            "tokenId": "0x321",
            "tokenUri": "https://link.to.your/token/metadata-0x1.json",
            "transactionHash": "0x...",
            "updatedAt": <UNIX timestamp>
        },
        ...],
    "cursor": ""
}
{
    cursor: '',
    items: [
        ...
        {
            createdAt: 1610524249,
            owner: '0xRECIPIENT',
            previousOwner: '0xOWNER',
            tokenId: '0x321',
            tokenUri: 'https://link.to.your/token/metadata-0x1.json',
            transactionHash: '0x...',
            updatedAt: 1610524249,
        },
        ...
    ],
}
class Kip17TokenListResponse {
    cursor: 
    items: [class Kip17TokenListResponseItem {
        createdAt: 1610524249
        owner: 0x...
        previousOwner: 0x0000000000000000000000000000000000000000
        tokenId: 0x1
        tokenUri: https://link.to.your/token/metadata-0x1.json
        transactionHash: 0x...
        updatedAt: 1610524249
    }, class Kip17TokenListResponseItem {
        ...
    }]
}

KAS가 제공하는 모든 API는 계정 인증 정보, 즉 access-key-id와 secret-access-key를 제출해야합니다. 인증 정보의 생성 및 획득은 다음 를 참조해주세요.

결과로 받게된 transactionHash는 과 같은 RPC 함수를 실행할 때 사용할 수 있습니다.

KIP-17 API의 (GET /v1/contract)를 사용하여 배포한 컨트랙트들을 조회할 수 있습니다. 다음 curl 명령어를 실행하여 컨트랙트 목록을 조회합니다.

다음은 앞서 예제에서 사용된 alias my-first-kip17을 사용하여 를 호출하는 curl 명령어입니다.

Token URI (uri): 토큰 정보를 담은 JSON 파일의 위치를 로 표현한 값입니다. 해당 토큰의 정보, 속성 등을 기록하여 사전에 URI로 표현될 수 있는 위치에 배포한 뒤 토큰 발행 시 URI를 포함합니다. URI링크가 존재하는 링크인지는 확인하지 않으니, 주의하여 입력 부탁드립니다.

URI란? Wikipedia 링크 (, )

토큰이 잘 발행되었는지 확인하려면 GET /v1/contract/{alias-or-address}/token을 사용하여 새로 발행한 토큰이 컨트랙트에 추가되었는지 확인합니다. 다음 curl 명령어를 사용하여 my-first-kip17 컨트랙트의 토큰 목록을 조회할 수 있습니다.

KIP-17 는 POST /v1/contract/{alias-or-address}/token/{id}입니다. {alias-or-address}, {id}는 전송하려는 컨트랙트, 토큰 정보를 사용합니다.

계정 생성과 관리는 를 참조해주시기 바랍니다.

Owner (owner): 전송하려는 토큰을 소유한 사람의 주소입니다. Sender가 owner와 다를 경우 sender는 사전에 토큰 전송 승인을 받은 받은 주소여야 합니다. 토큰 전송 승인에 대한 자세한 API는 에서 확인하실 수 있습니다.

전송 요청이 올바르게 블록체인에 적용되었는지 확인하려면 KIP-17 API의 또는 를 사용하거나 Node API를 통해 을 실행하여 결과를 확인하시기 바랍니다.

토큰 전송이 성공했는지 확인하기 위해 GET /v1/contract/{alias-or-address}/token을 사용하여 전송한 토큰의 정보가 올바르게 변경되었는지 확인할 수 있습니다.

KIP-17
KAS KIP-17 API Reference
KIP-17
컨트랙트 배포 API
링크
klay_getTransactionReceipt
컨트랙트 목록 조회 API
토큰 발행 API
URI
한글
영문
토큰 발행 목록 조회 API
토큰을 전송하는 API
여기
토큰 전송 승인
토큰 목록 조회
토큰 정보 조회
klay_getTransactionReceipt
토큰 목록 조회 API