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

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

전체 KIP-7 API에 대한 자세한 사양은 KAS KIP-7 API Reference에서 확인하실 수 있습니다.

KIP-7 컨트랙트 배포

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

info

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

API 요청

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

cURLJavaScriptJava
Copy
Copied
curl --location --request POST "https://kip7-api.klaytnapi.com/v2/contract" \
  --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key} \
  --data-raw '{
		"alias": "my-first-kip7",
		"name": "My First KIP-7",
		"symbol": "MFK",
		"decimals": 8,
		"initialSupply": "0x100000000"
  }'
Copy
Copied
const result = await caver.kas.kip17.deploy(
  "My First KIP-7",
  "MFK",
  8,
  "0x100000000",
  "my-first-kip7"
);
Copy
Copied
String alias = "my-first-kip7";
String name = "My First KIP-7";
String symbol = "MFK";
int decimals = 8;
String initialSupply = "0x100000000";

Kip7TransactionStatusResponse response = caver.kas.kip7.deploy(name, symbol, decimals, initialSupply, alias);

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

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

Copy
Copied
{
  "alias": "my-first-kip7",
  "name": "My First KIP-7",
  "symbol": "MFK",
  "decimals": 8,
  "initialSupply": "0x100000000"
}

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

  • Alias ( alias ): 컨트랙트의 별명입니다. 이후 여러 API에서 컨트랙트 주소를 대신해 사용 가능합니다. 허용되는 문자는 알파벳 소문자, 숫자, 하이픈이며 별명의 첫 문자는 알파벳 소문자로 제한됩니다.
  • Name ( name ): 컨트랙트의 이름입니다. KIP-7 표준에서 요구하는 name 으로 사용됩니다.
  • Symbol( symbol ): 컨트랙트의 심볼입니다. KIP-7 표준에서 요구하는 symbol 로 사용됩니다. 일반적으로 알파벳 대문자 3~4개로 구성되나 이를 제약하지는 않습니다.
  • Decimals( decimals ): 토큰의 소수점 자리 수입니다. KIP-7 표준에서 요구하는 decimals 로 사용됩니다. 일반적으로 18자리를 사용합니다.
  • InitialSupply( initialSupply ): 컨트랙트의 초기 발행량입니다. KIP-7 표준에서 요구하는 totalSupply 로 사용됩니다.
info

모든 KIP-7 API는 x-chain-id 헤더값을 필수로 요구합니다. 허용되는 값은 1001(Kairos), 8217(Kaia Mainnet)입니다.

  • 인증

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

API 응답

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

cURLJavaScriptJava
Copy
Copied
{
  "status": "Submitted",
  "transactionHash": "0xde30017fa4474274bd8e0f8bf4eea799d6873d1f2e24f5d7afe97400b24acf4c"
}
Copy
Copied
 {
  status: 'Submitted',
  transactionHash: '0xe5bf5cbd8d9f13e31af8e1cac1ff7749f649779a1e0eb62579012b38ff7737c3'
}
Copy
Copied
 class Kip7TransactionStatusResponse {
    status: Submitted
    transactionHash: 0x55bcaa84037ce8c25c1f3560868d0d13af01fa13faeabc4547e712f6be3cc350
}

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

KIP-7 컨트랙트 목록 조회

API 호출

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

cURLJavaScriptJava
Copy
Copied
curl --location --request GET 'https://kip7-api.klaytnapi.com/v2/contract' \
  --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key}
Copy
Copied
const queryOptions = {
  size: 1,
  status: caver.kas.kip7.queryOptions.status.DEPLOYED,
};
const result = await caver.kas.kip7.getContractList(queryOptions);
Copy
Copied
KIP7QueryOptions options = new KIP7QueryOptions();
options.setSize(1);
options.setStatus(KIP7QueryOptions.STATUS_TYPE.DEPLOYED);

Kip7ContractListResponse response = caver.kas.kip7.getContractList(options);

API 응답

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

cURLJavaScriptJava
Copy
Copied
{
  "items": [
    {
      "address": "0x33779fc606de8b1c1095dc3760be4c4f8b2a1ad3",
      "alias": "my-first-kip7",
      "decimals": 8,
      "name": "My First KIP-7",
      "status": "deployed",
      "symbol": "MFK",
      "totalSupply": "0x100000000"
    }
  ],
  "cursor": ""
}
Copy
Copied
{
  items: [
    {
      address: '0x05a86c8e60aefb9ce975fe26511f72da86ab2a7a',
      alias: 'my-first-kip7',
      decimals: 8,
      name: 'My First KIP-7',
      status: 'deployed',
      symbol: 'MFK',
      totalSupply: '0x100000000'
    }
  ],
  cursor:  'eyJjcmVhdGVkX2F0IjoxNjIxODE4NTQwLCJpZCI6ImNvbnRyYWN0IzEwMDEjMTczZGI2OWMtZjFiOC00ZGQ1LTlhYzItZWQ4YTBiYWRhYjI5Iiwic19pZCI6Imphc21pbmUtcWNvYnNiNnM2d2oifQ=='
}
Copy
Copied
class Kip7ContractListResponse {
    items: [class Kip7ContractListResponseItem {
        address: 0x7b635e298b345022fbe8c53d2646ed690e0f1cb2
        alias: my-first-kip7
        decimals: 8
        name: My First KIP-7
        status: deployed
        symbol: MFK
        totalSupply: 0x100000000
    }]
    cursor: eyJjcmVhdGVkX2F0IjoxNjI0OTQ2Njc5LCJpZCI6ImNvbnRyYWN0IzEwMDEjZDVjMzQ2ZjUtYmI4MC00ZjQ1LTkwOTMtNTdlMjUyMDVjZGM4Iiwic19pZCI6ImtrLTE2MjQ5NDY2NzkzMzEifQ==
}

토큰 발행

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

info

KAS KIP-7에서 배포한 컨트랙트는 IKIP7Mintable 인터페이스를 구현합니다. 토큰을 발행하면 총 발행량 또한 증가합니다.

API 요청

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

cURLJavaScriptJava
Copy
Copied
curl --location --request POST 'https://kip7-api.klaytnapi.com/v2/contract/my-first-kip7/mint' \
  --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key} \
	--data-raw '{
	  "to": "0x72b03ca464609c82be1d490ecfce004e2d3c4cfc",
	  "amount": "0x100"
	}'
Copy
Copied
const result = await caver.kas.kip7.mint(
  "my-first-kip7",
  "0x72b03ca464609c82be1d490ecfce004e2d3c4cfc",
  "0x100"
);
Copy
Copied
String alias = "my-first-kip7";
String to = "0x72b03ca464609c82be1d490ecfce004e2d3c4cfc";
String amount = "0x100";

Kip7TransactionStatusResponse response = caver.kas.kip7.mint(alias, to, amount);

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

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

Copy
Copied
{
  "to": "0x72b03ca464609c82be1d490ecfce004e2d3c4cfc",
  "amount": "0x100"
}
  • Recipient ( to ): 토큰을 받는 사람의 Kaia 계정 주소입니다. 토큰 발행 API는 지정된 주소로 새로운 토큰을 발행합니다.
  • Amount ( amount ): 토큰을 발행할 수량입니다. 16진수로 표현되며 토큰 소수점( decimals )을 포함한 값을 사용합니다. 위의 예제는 0.00000256(0x100 / 10 ^ 8) MFK 토큰을 생성합니다.
info

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

API 응답

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

cURLJavaScriptJava
Copy
Copied
{
  "transactionHash": "0x8fa73465785c5aedc7df3123ed2670f37f3cd42f63d32c53aba37c8fe1afc078",
  "status": "Submitted"
}
Copy
Copied
{
  status: 'Submitted',
  transactionHash: '0xe4db23b626f98e592156b4e69761cfecff414839fbcec0b6b73080d8a6b0a3e9'
}
Copy
Copied
class Kip7TransactionStatusResponse {
    status: Submitted
    transactionHash: 0x3198aa4826852e8897b2af78fe0b1974071c5110ec32c379d559bb8108d044c1
}

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

발행 결과 조회

API 호출

토큰이 잘 발행되었는지 확인하려면 컨트랙트 잔액 조회 API (GET /v2/contract/{contract-address-or-alias}/account/{owner}/balance)를 사용하여 owner 주소의 잔액을 확인합니다. 다음 curl 명령어를 사용하여 my-first-kip7 컨트랙트의 0x72b03ca464609c82be1d490ecfce004e2d3c4cfc 계정 잔액을 조회할 수 있습니다.

cURLJavaScriptJava
Copy
Copied
curl --location --request GET 'https://kip7-api.klaytnapi.com/v2/contract/my-first-kip7/account/0x72b03ca464609c82be1d490ecfce004e2d3c4cfc/balance' \
  --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key}
Copy
Copied
const result = await caver.kas.kip7.balance(
  "my-first-kip7",
  "0x72b03ca464609c82be1d490ecfce004e2d3c4cfc"
);
Copy
Copied
String alias = "my-first-kip7";
String account = "0x72b03ca464609c82be1d490ecfce004e2d3c4cfc";
Kip7TokenBalanceResponse response = caver.kas.kip7.balance(alias, account);

API 응답

토큰이 올바르게 발행되었다면 다음과 같은 응답을 받습니다.

cURLJavaScriptJava
Copy
Copied
{
  "balance": "0x100",
  "decimals": 8
}
Copy
Copied
{ balance: '0x100', decimals: 8 }
Copy
Copied
class Kip7TokenBalanceResponse {
    balance: 0x100
    decimals: 8
}
info

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

토큰 전송

KIP-7 토큰을 전송하는 APIPOST /v2/contract/{contract-address-or-alias}/transfer입니다. {contract-address-or-alias}는 전송하려는 컨트랙트를 사용합니다.

KAS Wallet Account Pool(https://console.klaytnapi.com/ko/service/wallet/accounts/list)에서 계정을 생성한 후에 KAS KIP-7 토큰 전송 API를 이용할 수 있습니다. 이 예제에서 사용하는 계정 주소(0x72b03ca464609c82be1d490ecfce004e2d3c4cfc)는 사전에 등록한 계정입니다.

info

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

info

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

API 호출

다음은 0x72b03ca464609c82be1d490ecfce004e2d3c4cfc가 소유한 my-first-kip7 컨트랙트의 토큰을 0x4d3224314b704be8887551e8c9b9bbb9aa5c48b3에게 전송하는 curl 명령어입니다.

cURLJavaScriptJava
Copy
Copied
curl --location --request POST 'https://kip7-api.klaytnapi.com/v2/contract/my-first-kip7/transfer' \
  --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key} \
	--data-raw '{
	  "from": "0x72b03ca464609c82be1d490ecfce004e2d3c4cfc",
	  "to": "0x4d3224314b704be8887551e8c9b9bbb9aa5c48b3",
	  "amount": "0x1"
	}'
Copy
Copied
const result = await caver.kas.kip7.transfer(
  "my-first-kip7",
  "0x72b03ca464609c82be1d490ecfce004e2d3c4cfc",
  "0x4d3224314b704be8887551e8c9b9bbb9aa5c48b3",
  "0x1"
);
Copy
Copied
String alias = "my-first-kip7";
String owner = "0x72b03ca464609c82be1d490ecfce004e2d3c4cfc";
String spender = "0x4d3224314b704be8887551e8c9b9bbb9aa5c48b3";
String amount = "0x1";

Kip7TransactionStatusResponse response = caver.kas.kip7.transfer(alias, owner, spender, amount);

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

  • From ( from ): 전송하려는 토큰을 소유한 사람의 주소입니다.
  • To ( to ): 토큰을 받는 사람의 주소입니다. 블록체인 특성상 토큰을 전송하면 되돌릴 수 없으니 주의하시기 바랍니다.
  • Amount ( amount ): 전송할 토큰 수량입니다. 16진수로 표현하며 토큰 소수점( decimals )이 포함된 값을 사용합니다.

From 정보가 올바르지 않거나 잔액이 부족한 경우 전송 요청은 실패합니다.

info

잔액 부족과 같은 경우에도 전송 요청 API는 정상 응답을 반환합니다. KIP-7 API는 요청의 형태, 형식(syntax)이 올바른지에 대해서만 검증합니다.

전송 요청이 블록체인에 올바르게 적용되었는지 그 결과를 확인하려면 KIP-7 API의 토큰 잔액 조회를 사용하거나, Node API로 klay_getTransactionReceipt을 실행하시기 바랍니다.

API 응답

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

cURLJavaScriptJava
Copy
Copied
{
  "transactionHash": "0xf55b6bda2b0b610b461f0a8533001d38e4fad95a77eb4e2a60d38c14fdf0c997",
  "status": "Submitted"
}
Copy
Copied
{
  status: 'Submitted',
  transactionHash: '0x736dd99fc06dbc237d55eddf204b053fdc35b07faf30dcd1bfa504c7cb651192'
}
Copy
Copied
class Kip7TransactionStatusResponse {
    status: Submitted
    transactionHash: 0xcc5a4bd89cf64d6dc72bcc00b7743f524bfc9d78c6d37ba510c993d75f740c48
}

전송 결과 조회

API 호출

토큰 전송이 성공했는지 확인하기 위해서는 컨트랙트 잔액 조회 API (GET /v2/contract/{contract-address-or-alias}/account/{owner}/balance)를 사용합니다. 전송한 토큰 정보가 올바르게 변경되었다면 성공입니다.

cURLJavaScriptJava
Copy
Copied
curl --location --request GET 'https://kip7-api.klaytnapi.com/v2/contract/my-first-kip7/account/0x4d3224314b704be8887551e8c9b9bbb9aa5c48b3/balance' \
  --header "x-chain-id: {chain-id}" \
  -u {access-key-id}:{secret-access-key}
Copy
Copied
const result = await caver.kas.kip7.balance(
  "my-first-kip7",
  "0x4d3224314b704be8887551e8c9b9bbb9aa5c48b3"
);
Copy
Copied
String alias = "my-first-kip7";
String account = "0x4d3224314b704be8887551e8c9b9bbb9aa5c48b3";

Kip7TokenBalanceResponse response = caver.kas.kip7.balance(alias, account);

API 응답

토큰 전송이 올바르게 수행되었을 경우 다음과 같이 잔액이 변경된 것을 확인할 수 있습니다.

cURLJavaScriptJava
Copy
Copied
{
  "balance": "0x1",
  "decimals": 8
}
Copy
Copied
{ balance: '0x1', decimals: 8 }
Copy
Copied
class Kip7TokenBalanceResponse {
    balance: 0x1
    decimals: 8
}