Technology, Tutorials, for Developer, Tool support

클레이튼에서 Tatum-SDK 사용하는 방법 (Part 2)

들어가며

Tatum은 통합 Tool 및 SDK로, 개발자가 Web 기술을 만들어 프로젝트에 통합하게 해주는 사용하기 쉬운 플랫폼 입니다. Tatum은 즉시 사용이 가능한 표준 토큰 스마트 컨트랙트를 제공하여 사용자가 선택한 블록체인에 배포를 할 수 있는데, 한번의 API Call로 배포가 가능하여 사용자가 별도로 컨트랙트를 생성하고 배포할 필요가 없습니다. 이번 가이드에서는 다음 내용을 아우르는 Tatum SDK의 스마트 컨트랙트 기능 일부를 살펴볼 예정입니다.

  • 대체가능토큰 (FT) (ERC20)
  • 대체불가토큰 (NFT) (ERC721)
  • 멀티 토큰 (ERC1155)
  • 기존 컨트랙트 방식 불러오기

요구사항 

시작하기 

이번 튜토리얼을 성공적으로 완료하려면 이전 Part 1에서 설명한 대로 Tatum-js를 설치하고, 디렉토리 설정을 이미 마친 상태여야 합니다. 본 가이드는 클레이튼에서 Tatum-SDK를 사용하는 방법에 대해 이어서 다루고 있습니다.

클레이튼에서 Tatum SDK 사용하기 

이번 섹션에서는 변경가능토큰 (ERC20),변경불가토큰 (ERC721) 및 멀티 토큰 (ERC1155)의 배포 등 Tatum SDK 스마트 컨트랙트 기능 일부를 다룰 예정입니다. 

뿐만 아니라, 기존 주소 및 ABI를 고려한 기존 컨트랙트 방식 호출에 더해 토큰 컨트랙트 별 발행, 이전 및 소각 함수를 실행하기 위한 Tatum SDK 사용 방법도 다룰 예정입니다.

여기를 클릭하여 해당 기능에 대한 자세한 정보를 살펴보세요. 

ERC20 토큰 만들기

단계별 가이드를 따라 실행하면, 필요 파라미터가 제공된 경우 ERC20 토큰을 배포하고 몇 줄의 코드로 핵심 함수를 불러올 수 있습니다.   

설정 

  • 기존 프로젝트 디렉토리 탐색하기 
  • 기존 스크립트(scripts) 폴더 입력하기 
  • 새로운 파일 ‘erc20.js’을 만들어 해당 코드 저장하기 

Tatum SDK 초기화하기 

Tatum에 탑재된 기능을 프로젝트에서 사용하려면 사용자의 API Key로 SDK를 초기화해야 합니다. API Key가 없다면, 이 곳에서 키를 생성하세요.

import { TatumKlaytnSDK } from '@tatumio/klaytn'
const klaytnSDK = TatumKlaytnSDK({ apiKey: '<PASTE API KEY HERE>’ })

변수 설정하기

새로 생성한 `erc20.js`파일에 다음 변수를 복사하여 붙여넣기 하세요. MetaMask와 같은 지갑 인프라에 있는 사용자의 지갑 주소 및 개인키(Private Key)를 붙여넣기 하거나 이전 Part 1에서 설명한 대로 Tatum SDK를 활용하여 새로 생성할 수 있습니다. 

  // This address will DEPLOY, MINT and TRANSFER ERC20 to Receiver Address
const senderAddress = ‘<PASTE SENDER ADDRESS>’

  const senderPrivateKey = ‘<PASTE SENDER PRIVATE KEY>’

  // This address will RECEIVE ERC20 token and BURN it

  const receiverAddress = ‘<PASTE RECEIVER ADDRESS>’

  const receiverPrivateKey = ‘<PASTE RECEIVER PRIVATE KEY>’

참고 : 개인 키 사용하기 

이번 세션에서 사용하게 될 코드는 테스트 및 데모용으로만 사용됩니다.  

하지만 실제 운영 환경에서 사용 시, 사용자의 개인키와 니모닉은 보안 경계 내에 있어야 합니다. 따라서, 커맨드 라인에서 Tatum CLI를 사용하거나 또는 복합 키 관리 시스템, Tatum KMS를 통해 올바르고 안전하게 지갑을 구성하고 개인키로 관리할 것을 권장합니다.

A.) ERC-20 스마트 컨트랙트 배포하기 

사전에 구축한 클레이튼 상의 ERC20 컨트랙트를 배포하려면, 사용자의 `erc20.js` 파일의 코드 스니핏(snippet)을 붙여넣기 해야 합니다. Response에는 트랜잭션 ID가 포함되는데, 이로부터 배포한 스마트 컨트랙트의 주소를 도출할 수 있습니다. 

// deploys erc20 (fungible token) transaction

   const erc20Deployed =  await klaytnSDK.erc20.send.deploySignedTransaction({

        symbol: 'MTK',

        name: 'MyToken',

        address: senderAddress,

        supply: '10000',

        fromPrivateKey: senderPrivateKey,

        digits: 18,

      })

    console.log(`Here is the transaction id ${erc20Deployed.txId}`);

// This timer is used to ensure the transaction above is confirmed and added to the block

//  In a real application, the wait mechanism must be implemented properly without using this.

      setTimeout(() => {

        getContractAddress(erc20Deployed.txId)

      }, 10000);

  }

  async function getContractAddress(erc20Deployed) {

    // fetch deployed contract address from transaction hash

    const transaction = await klaytnSDK.blockchain.smartContractGetAddress("KLAY", erc20Deployed)

    console.log(`Here is the contract address ${transaction.contractAddress}`);

  }

erc20Deploy()  async function erc20Deploy () {
  async function erc20Deploy () {

   해당 트랜잭션의 결과값을 확인하려면 아래 명령어를 실행하세요.

node scripts/erc20.js

B.) 해당 주소에 토큰 발행하기

새로 생성한 변경가능 토큰을 지정한 블록체인 주소에 발행할 수 있습니다. 신규 토큰을 발행하기 위해 배포한 ERC20 토큰의 컨트랙트 주소를 제공해야 합니다. 위의 예시에서 도출한 컨트랙트 주소를 사용해도 됩니다. 

Response에는 트랜잭션 ID와 ‘수신자’의 잔고가 포함됩니다. 사용자의 `erc20.js` 파일에 아래 코드의 스니핏을 붙여넣기 하여 실제 과정을 확인할 수 있습니다.  

async function erc20Minted(contractAddress) {
// mint erc20(fungible token) to a specified address

  const erc20Mint = await klaytnSDK.erc20.send.mintSignedTransaction({

    to: receiverAddress,

    contractAddress: contractAddress,

    amount: '1',

    fromPrivateKey: senderPrivateKey,

  })

  console.log(`Minted erc20 token/s with txID ${erc20Mint.txId}`)

// This timer is used to ensure the transaction above is confirmed and added to the block

//  In a real application, the wait mechanism must be implemented properly without using this.

  setTimeout(() => {

    getErc20Balance(receiverAddress, contractAddress)

  }, 10000);

}

  async function getErc20Balance(address, contractAddress) {

    // gets the number of the fungible tokens minted on a specific smart contract that a blockchain address holds.

    const erc20Balance = await klaytnSDK.erc20.getErc20AccountBalance("KLAY", address, contractAddress);

    console.log(erc20Balance);

  }

Const contractAddress = “<PASTE CONTRACT ADDRESS HERE>”

erc20Minted(contractAddress)

  사용자의 트랜잭션 ID와 수신자의 신규 발행 토큰 잔고를 확인하려면, 아래 명령어를 실행하시기 바랍니다.   

node scripts/erc20.js

C.) ERC20 토큰 이체하기

`transfer()` 방식을 불러오기하여, 변경가능 토큰을 지정한 블록체인 주소로 이체합니다.   method. contractAddress 필드는 이전 예시에서 도출한 주소로 대체 가능합니다. 

이체 실행 후 Response에는 트랜잭션 ID와 ‘발신자’의 잔고가 포함됩니다. 사용자의 `erc20.js` file에 아래 코드의 스니핏을 붙여넣기 하여 실제 과정을 확인할 수 있습니다.

  async function er20Transferred(contractAddress) {
// send erc20 (fungible token) transaction

    const erc20Transfer = await klaytnSDK.erc20.send.transferSignedTransaction({

      to: receiverAddress,

      amount: '1',

      contractAddress,

      fromPrivateKey: senderPrivateKey,

      digits: 18,

    })

    console.log(`Transferred erc20 token/s with txID ${erc20Transfer.txId}`)

// This timer is used to ensure the transaction above is confirmed and added to the block

//  In a real application, the wait mechanism must be implemented properly without using this.

    setTimeout(() => {

      getErc20Balance(senderAddress, contractAddress)

    }, 10000);

  }

er20Transferred(contractAddress)

이체 이후 사용자의 트랜잭션 ID와 발신자의 잔고를 확인하려면, 아래 명령어를 실행하시기 바랍니다.

node scripts/erc20.js

D.) ERC20 토큰 소각하기

대체가능 토큰을 소각하면 스마트 컨트랙트의 특정 공급량이 줄어듭니다. contractAddress 필드는 이전 예시에서 도출한 주소로 대체 가능합니다. 

Response에는 트랜잭션 ID와 Token 소각 이후 ‘수신자’의 잔고를 포함합니다. 사용자의 `erc20.js` 파일에 아래 코드의 스니핏을 붙여넣기 하여 실제 과정을 확인할 수 있습니다. 

async function erc20Burned(contractAddress) {
// burn erc20 (fungible token) transaction

  const erc20Burn = await klaytnSDK.erc20.send.burnSignedTransaction({

    contractAddress: contractAddress,

    amount: '1',

    fromPrivateKey: receiverPrivateKey,

  })

  console.log(`Burned erc20 token/s with txID ${erc20Burn.txId}`)

// This timer is used to ensure the transaction above is confirmed and added to the block

//  In a real application, the wait mechanism must be implemented properly without using this.

 setTimeout(() => {

   getErc20Balance(receiverAddress, contractAddress)

 }, 10000);

}

erc20Burned(contractAddress)

사용자의 트랜잭션 ID와 토큰 소각후 수신자의 잔고를 보려면, 아래 명령어를 실행하시기 바랍니다.

node scripts/erc20.js

전체 코드

import { TatumKlaytnSDK } from '@tatumio/klaytn'
const klaytnSDK = TatumKlaytnSDK({ apiKey: '<PASTE API KEY HERE>’ })

  // This address will DEPLOY, MINT and TRANSFER ERC20 to Receiver Address

  const senderAddress = ‘<PASTE SENDER ADDRESS>’

  const senderPrivateKey = ‘<PASTE  SENDER PRIVATE KEY>’

  // This address will RECEIVE ERC20 token and BURN it

  const receiverAddress = ‘<PASTE RECEIVER ADDRESS>’

  const receiverPrivateKey = ‘<PASTE RECEIVER PRIVATE KEY>’

  async function erc20Deploy () {

    // deploys erc20 (fungible token) transaction

   const erc20Deployed =  await klaytnSDK.erc20.send.deploySignedTransaction({

        symbol: 'MTK',

        name: 'MyToken',

        address: senderAddress,

        supply: '10000',

        fromPrivateKey: senderPrivateKey,

        digits: 18,

      })

    console.log(`Here is the transaction id ${erc20Deployed.txId}`);

      setTimeout(() => {

        getContractAddress(erc20Deployed.txId)

      }, 10000);

  }

  async function getContractAddress(erc20Deployed) {

    // fetch deployed contract address from transaction hash

    const transaction = await klaytnSDK.blockchain.smartContractGetAddress("KLAY", erc20Deployed)

    console.log(`Here is the contract address ${transaction.contractAddress}`);

  }

  async function er20Transferred(contractAddress) {

     // send erc20 (fungible token) transaction

    const erc20Transfer = await klaytnSDK.erc20.send.transferSignedTransaction({

      to: receiverAddress,

      amount: '1',

      contractAddress,

      fromPrivateKey: senderPrivateKey,

      digits: 18,

    })

    console.log(`Transferred erc20 token/s with txID ${erc20Transfer.txId}`)

    setTimeout(() => {

      getErc20Balance(senderAddress, contractAddress)

    }, 10000);

  }

 async function erc20Minted(contractAddress) {

  // mint erc20(fungible token) to a specified address

  const erc20Mint = await klaytnSDK.erc20.send.mintSignedTransaction({

    to: receiverAddress,

    contractAddress: contractAddress,

    amount: '1',

    fromPrivateKey: senderPrivateKey,

  })

  console.log(`Minted erc20 token/s with txID ${erc20Mint.txId}`)

  setTimeout(() => {

    getErc20Balance(receiverAddress, contractAddress)

  }, 10000);

}

async function erc20Burned(contractAddress) {

  // burn erc20 (fungible token) transaction

  const erc20Burn = await klaytnSDK.erc20.send.burnSignedTransaction({

    contractAddress: contractAddress,

    amount: '3',

    fromPrivateKey: receiverPrivateKey,

  })

  console.log(`Burned erc20 token/s with txID ${erc20Burn.txId}`)

 setTimeout(() => {

   getErc20Balance(receiverAddress, contractAddress)

 }, 10000);

}

  async function getErc20Balance(address,contractAddress) {

    // gets the number of the fungible tokens minted on a specific smart contract that a blockchain address holds.

    const erc20Balance = await klaytnSDK.erc20.getErc20AccountBalance("KLAY", address, contractAddress);

    console.log(erc20Balance);

  }

const contractAddress = “<PASTE CONTRACT ADDRESS>”

erc20Deploy()

er20Transferred(contractAddress);

getErc20Balance(receiverAddress,contractAddress);

erc20Burned(contractAddress);

erc20Minted(contractAddress);

ERC721 토큰 만들기

단계별 가이드를 따라 실행하면, 필요 파라미터가 입력된 경우 ERC721 토큰을 배포하고, 몇 줄의 코드로 핵심 함수를 불러올 수 있습니다. 

이번 섹션에서는 다음 내용을 다루게 됩니다. 

  • ERC721 컨트랙트 배포하기  
  • 단일 및 복수의 ERC721 토큰 발행하기
  • NFT 토큰 Metadata 확보하기  
  • NFT 이체하기 
  • NFT 소각하기 

먼저, `ERC20 토큰 만들기’ 섹션에서 수행한 것처럼 scripts 폴더에 신규 `erc721.js` 파일을 생성하고, Tatum SDK를 초기화 한 다음 변수를 설정합니다. 

그 다음  `erc721.js` 파일에 아래 코드를 붙여넣기하고 아래 명령어를 수행하여 함수 별 결과값을 확인합니다. 

node scripts/erc721.js

A. NFT 스마트 컨트랙트 배포하기 

아래 코드 스니핏으로 클레이튼 블록체인에서 NFT 스마트 컨트랙트를 배포하세요. 배포된 NFT 스마트 컨트랙트로 (한 번에 한 개 또는 여러 개의) NFT를 발행, 소각 및 이체할 수 있습니다.

async function erc721Deploy () {
// deploys erc721 (non-fungible token) transaction

    const nftDeploy = await klaytnSDK.nft.send.deploySignedTransaction({

        name: 'My NFT',

        symbol: 'MNFT',

        // your private key of the address that has coins

        fromPrivateKey: senderPrivateKey,

    })

    console.log(`Here is the transaction id ${nftDeploy.txId}`);

    setTimeout(() => {

        getContractAddress(nftDeploy.txId)

    }, 10000);

}

async function getContractAddress(erc721Deployed) {

    // fetch deployed contract address from transaction hash

    const transaction = await klaytnSDK.blockchain.smartContractGetAddress("KLAY", erc721Deployed)

    console.log(`Here is the contract address ${transaction.contractAddress}`);

}

erc721Deploy()

결과값

B. NFT 발행하기

코드 라인을 가지고, 사용자의 컨트랙트 주소와 Token ID를 기반으로 클레이튼 블록체인에서 네이티브 NFT를 발행할 수 있습니다. 

참고: 이 함수는 사용자의 metadata IPFS 해시 정보를 필요로 합니다. 가이드를 따라 사용자의 메타데이터를 IPFS에 업로드 할 수 있습니다. 

async function nftMint(contractAddress) {
// Mint NFTs on your own smart contract

  // Put any number here. For a start 1

    const tokenId = '<PUT TOKEN-ID HERE>';

    const nftMinted = await klaytnSDK.nft.send.mintSignedTransaction({

        chain: "KLAY",

        tokenId,

        contractAddress,

        fromPrivateKey: senderPrivateKey,

        to: senderAddress,

        // uploaded metadata from ipfs

        url: '<IPFS HASH>’,

      })

      console.log(`Minted nft with txID: ${nftMinted.txId}`)

}

Const contractAddress = “<PASTE CONTRACT ADDRESS>”

nftMint(contractAddress)

결과값

C. 다수의 NFT 발행하기 

다음 방법을 활용하여 여러 개의 NFT 토큰을 지정한 블록체인 주소에 발행할 수 있습니다.

async function nftMintBatch(contractAddress) {
// Mint multiple NFTs on your own smart contract

    const nftMinted = await klaytnSDK.nft.send.mintMultipleSignedTransaction({

        chain: "KLAY",

        tokenId: [“<INPUT VALID TOKEN-ID>", "<INPUT VALID TOKEN-ID>"],

        contractAddress,

        fromPrivateKey: senderPrivateKey,

        to: [senderAddress, receiverAddress],

        // uploaded metadata from ipfs

        url: [“<PASTE IPFS HASH HERE>”, “PASTE IPFS HASH HERE”]

      })

      console.log(`Minted multiple nft with txID: ${nftMinted.txId}`)

}

결과값

D.  발행한 전체 NFT를 컬렉션에 확보하기  

async function getContractNftBalance(contractAddress) {
// Get all minted NFTs in the collection. Returns all NFTs this contract minted.

  const nftAccountBalance = await klaytnSDK.nft.getNFTAccountBalance(

    "KLAY",

    senderAddress,

    contractAddress,

  )

  console.log(`Nfts on ${contractAddress}:`, nftAccountBalance)

}

getContractNftBalance(contractAddress)

결과값

E. NFT 토큰 메타데이터 확보하기 

async function getNFTMetadata(contractAddress, tokenId) {
// Get NFT token metadata

  const response = await klaytnSDK.nft.getNFTMetadataURI("KLAY", contractAddress, tokenId)

  console.log(`Token metadata: ${JSON.stringify(response)}`)

}

Const tokenId = <”VALID TOKEN ID”>

getNFTMetadata(contractAddress, tokenId)

결과값

F. NFT 이체하기 

해당 스마트 컨트랙트 주소를 바탕으로 스마트 컨트랙트에서 지정한 블록체인 주소로 NFT를 이체합니다.  

async function transferNFT(contractAddress, tokenId) {
const nftTransferred = await klaytnSDK.nft.send.transferSignedTransaction({

    to: receiverAddress,

    tokenId,

    contractAddress,

    fromPrivateKey: senderPrivateKey,

  }) 

  console.log(`Transferred nft with transaction hash: ${nftTransferred.txId}`)

}

transferNFT(contractAddress, tokenId)

비고: 발신자는 해당 tokenId에 연결된 NFT를 보유하고 있어야 합니다.

결과값

G. NFT 소각하기  

소각한 NFT를 아무도 접근할 수 없는 주소 0에 이체합니다.

async function burnNFT(contractAddress, tokenId) {
// Burn one NFT Token. This method destroys any NFT token from smart contract defined in contractAddress.

  const nftBurned = await klaytnSDK.nft.send.burnSignedTransaction({

    tokenId,

    contractAddress,

    fromPrivateKey: receiverPrivateKey,

  })

  console.log(`NFT burn transaction sent with txID: ${nftBurned.txId}`)

}

burnNFT(contractAddress, tokenId)

비고: 수신자는 해당 tokenId에 연결된 NFT를 보유하고 있어야 합니다.

결과값 

전체 코드

import { TatumKlaytnSDK } from '@tatumio/klaytn'
const klaytnSDK = TatumKlaytnSDK({ apiKey: '<PASTE API KEY HERE>’ })

  // This address will DEPLOY, MINT and TRANSFER ERC20 to Receiver Address

  const senderAddress = ‘<PASTE SENDER ADDRESS>’

  const senderPrivateKey = ‘<PASTE SENDER PRIVATE KEY>’

  // This address will RECEIVE ERC20 token and BURN it

  const receiverAddress = ‘<PASTE RECEIVER ADDRESS>’

  const receiverPrivateKey = ‘<PASTE RECEIVER PRIVATE KEY>’

  async function erc721Deploy () {

    // deploys erc721 (non fungible token) transaction

    const nftDeploy = await klaytnSDK.nft.send.deploySignedTransaction({

        name: 'My NFT',

        symbol: 'MNFT',

        // your private key of the address that has coins

        fromPrivateKey: senderPrivateKey,

    })

    console.log(`Here is the transaction id ${nftDeploy.txId}`);

    setTimeout(() => {

        getContractAddress(nftDeploy.txId)

    }, 10000);

}

async function getContractAddress(erc721Deployed) {

    // fetch deployed contract address from transaction hash

    const transaction = await klaytnSDK.blockchain.smartContractGetAddress("KLAY", erc721Deployed)

    console.log(`Here is the contract address ${transaction.contractAddress}`);

}

async function nftMint(contractAddress) {

    // Mint NFTs on your own smart contract

  // Put any number here. For a start 1

    const tokenId = '<PUT TOKEN-ID HERE>';

    const nftMinted = await klaytnSDK.nft.send.mintSignedTransaction({

        chain: "KLAY",

        tokenId,

        contractAddress,

        fromPrivateKey: senderPrivateKey,

        to: senderAddress,

        // uploaded metadata from ipfs

        url: '<IPFS HASH>’,

      })

      console.log(`Minted nft with txID: ${nftMinted.txId}`)

}

async function nftMintBatch(contractAddress) {

    // Mint multiple NFTs on your own smart contract

    const nftMinted = await klaytnSDK.nft.send.mintMultipleSignedTransaction({

        chain: "KLAY",

        tokenId: [“<INPUT VALID TOKEN-ID>", "<INPUT VALID TOKEN-ID>"],

        contractAddress,

        fromPrivateKey: senderPrivateKey,

        to: [senderAddress, receiverAddress],

        // uploaded metadata from ipfs

        url: [“<PASTE IPFS HASH HERE>”, “PASTE IPFS HASH HERE”]

      })

      console.log(`Minted multiple nft with txID: ${nftMinted.txId}`)

}

async function getContractNftBalance(contractAddress) {

    // Get all minted NFTs in the collection. Returns all NFTs this contract minted.

  const nftAccountBalance = await klaytnSDK.nft.getNFTAccountBalance(

    "KLAY",

    senderAddress,

    contractAddress,

  )

  console.log(`Nfts on ${contractAddress}:`, nftAccountBalance)

}

async function getNFTMetadata(contractAddress, tokenId) {

  // Get NFT token metadata

  const response = await klaytnSDK.nft.getNFTMetadataURI("KLAY", contractAddress, tokenId)

  console.log(`Token metadata: ${JSON.stringify(response)}`)

}

async function transferNFT(contractAddress, tokenId) {

  // Transfer an NFT from the smart contract (the contractAddress parameter in the request body) to the specified blockchain address (the to parameter in the request body).

  const nftTransferred = await klaytnSDK.nft.send.transferSignedTransaction({

    to: receiverAddress,

    tokenId,

    contractAddress,

    fromPrivateKey: senderPrivateKey,

  }) 

  console.log(`Transferred nft with transaction hash: ${nftTransferred.txId}`)

}

async function burnNFT(contractAddress, tokenId) {

  // Burn one NFT Token. This method destroys any NFT token from smart contract defined in contractAddress.

  const nftBurned = await klaytnSDK.nft.send.burnSignedTransaction({

    tokenId,

    contractAddress,

    fromPrivateKey: receiverPrivateKey,

  })

  console.log(`NFT burn transaction sent with txID: ${nftBurned.txId}`)

}

const contractAddress = "<PASTE CONTRACT ADDRESS HERE>";

const tokenId = "<VALID TOKEN ID>";

erc721Deploy();

nftMint(contractAddress);

nftMintBatch(contractAddress);

getContractNftBalance(contractAddress);

getNFTMetadata(contractAddress, tokenId);

transferNFT(contractAddress, tokenId);

burnNFT(contractAddress, tokenId);

ERC1155 토큰 만들기

단계별 가이드를 따라 실행하면, 클레이튼 블록체인 상의 KIP37과 동일한 ERC1155 토큰을 배포할 수 있습니다. 뿐만 아니라, 필요 파라미터가 입력된 경우 몇 줄의 코드로 핵심 함수를 불러올 수 있습니다.   

이번 섹션을 통해 사용자는 다음 작업을 수행할 수 있게 됩니다.

  • ERC1155 컨트랙트 배포하기
  • ERC1155 토큰 발행하기
  • 멀티 토큰 (MT) 이체하기 
  • 멀티 토큰 (MT) 소각하기 

먼저, `ERC20 토큰 만들기’ 섹션에서 수행한 것처럼 scripts 폴더에 신규 `erc1155.js` 파일을 생성하고, Tatum SDK를 초기화 한다음 변수를 설정합니다. 

그 다음,  `erc721.js` 파일에 다음 코드를 붙여넣기하고 아래 명령어를 수행하여 함수 별 결과값을 확인합니다.

node scripts/erc1155.js

A. ERC1155 컨트랙트 배포하기

이 방법을 통해 클레이튼 블록체인 상에서 새로운 ERC1155 스마트 컨트랙트(멀티 토큰용)를 만들 수 있습니다. ERC1155 컨트랙트를 배포한 후, 토큰 발행, 소각 및 이체가 가능합니다.

  async function erc1155Deploy () {
// deploys Multi token transaction

    const multiTokenDeployed = await klaytnSDK.multiToken.send.deployMultiTokenTransaction({

        // your private key of the address that has coins

        fromPrivateKey: senderPrivateKey,

        // uploaded metadata from ipfs

        uri: 'ipfs://bafkreidinxo4cuds5ybcl72al5sywstc3m6i7lwmkz5wcdna7ccadjssm4',

      }) 

      console.log(`Deployed multi token with txID ${multiTokenDeployed.txId}`)

    setTimeout(() => {

        getContractAddress(multiTokenDeployed.txId)

    }, 10000);

}

async function getContractAddress(multiTokenDeployed) {

    // fetch deployed contract address from transaction hash

    const transaction = await klaytnSDK.blockchain.smartContractGetAddress("KLAY", multiTokenDeployed)

    console.log(`Here is the contract address ${transaction.contractAddress}`);

}

erc1155Deploy()

참고: 이 함수는 사용자의 metadata IPFS 해시 정보를 필요로 합니다. 가이드를 따라 사용자의 메타데이터를 IPFS에 업로드 할 수 있습니다. 

결과값

B. 멀티 토큰 발행하기

이 방법으로 지정한 블록체인 주소에 정해진 수량의 멀티 토큰을 발행할 수 있습니다. 

async function mintmultiToken(contractAddress) {
// Paste a number lets say 1    

const tokenId = "<INPUT VALID ID>"

    const multiTokenMinted = await klaytnSDK.multiToken.send.mintMultiTokenTransaction({

        to: senderAddress,

        tokenId,

        amount: '1000',

        fromPrivateKey: senderPrivateKey,

        contractAddress,

      })

      console.log(`Multi Token mint transaction sent with txID: ${multiTokenMinted.txId}`)

}

const contractAddress = “<PASTE YOUR CONTRACT ADDRESS>” 

mintmultiToken(contractAddress)

결과값

C. 멀티 토큰 이체하기 

이 방법을 사용해서 특정 수량의 멀티 토큰을 한 계좌에서 다른 계좌로 이체할 수 있습니다. 

async function transferMT(contractAddress, tokenId) {
// Transfer multi-token from the smart contract to the specified blockchain address

    const multiTokenTransferred = await klaytnSDK.multiToken.send.transferMultiTokenTransaction({

      to: receiverAddress,

      tokenId,

      amount: '10',

      fromPrivateKey: senderPrivateKey,

      contractAddress,

    })

    console.log(`Sent Multi Token with txID: ${multiTokenTransferred.txId}`)

  }

 const tokenId=“<PASTE VALID TOKEN ID>”  

transferMT(contractAddress, tokenId)

결과값

D. 멀티토큰 소각하기 

이 방법으로 id별로 정해진 수량의 멀티 토큰을 소각합니다. contractAddress에서 정의한 스마트 컨트랙트에서 해당 멀티 토큰을 삭제합니다.

  async function burnMT(contractAddress, tokenId) {
// Burn one multi-token. This method destroys any MT token from smart contract defined in contractAddress.

    const multiTokenBurned = await klaytnSDK.multiToken.send.burnMultiTokenTransaction({

      tokenId,

      amount: '1',

      fromPrivateKey: receiverPrivateKey,

      contractAddress,

      account: receiverAddress,

    })

    console.log(`Burned Multi Token/s with txID: ${multiTokenBurned.txId}`)

  }

burnMT(contractAddress, tokenId)

결과값

전체 코드

import { TatumKlaytnSDK } from '@tatumio/klaytn'
const klaytnSDK = TatumKlaytnSDK({ apiKey: '<PASTE API KEY HERE>’ })

  // This address will DEPLOY, MINT and TRANSFER ERC20 to Receiver Address

  const senderAddress = ‘<PASTE SENDER ADDRESS>’

  const senderPrivateKey = ‘<PASTE SENDER PRIVATE KEY>’

  // This address will RECEIVE ERC20 token and BURN it

  const receiverAddress = ‘<PASTE RECEIVER ADDRESS>’

  async function erc1155Deploy () {

    // deploys Multi token transaction

    const multiTokenDeployed = await klaytnSDK.multiToken.send.deployMultiTokenTransaction({

        // your private key of the address that has coins

        fromPrivateKey: senderPrivateKey,

        // uploaded metadata from ipfs

        uri: '<PASTE IPFS HASH>’,

      }) 

      console.log(`Deployed multi token with txID ${multiTokenDeployed.txId}`)

    setTimeout(() => {

        getContractAddress(multiTokenDeployed.txId)

    }, 10000);

}

async function getContractAddress(multiTokenDeployed) {

    // fetch deployed contract address from transaction hash

    const transaction = await klaytnSDK.blockchain.smartContractGetAddress("KLAY", multiTokenDeployed)

    console.log(`Here is the contract address ${transaction.contractAddress}`);

}

async function mintmultiToken(contractAddress) {

// Paste a number lets say 1    

const tokenId = "<INPUT VALID ID>"

    const multiTokenMinted = await klaytnSDK.multiToken.send.mintMultiTokenTransaction({

        to: senderAddress,

        tokenId,

        amount: '1000',

        fromPrivateKey: senderPrivateKey,

        contractAddress,

      })

      console.log(`Multi Token mint transaction sent with txID: ${multiTokenMinted.txId}`)

}

async function transferMT(contractAddress, tokenId) {

    // Transfer multi-token from the smart contract to the specified blockchain address

    const multiTokenTransferred = await klaytnSDK.multiToken.send.transferMultiTokenTransaction({

      to: receiverAddress,

      tokenId,

      amount: '10',

      fromPrivateKey: senderPrivateKey,

      contractAddress,

    })

    console.log(`Sent Multi Token with txID: ${multiTokenTransferred.txId}`)

}

async function burnMT(contractAddress, tokenId) {

    // Burn one multi-token. This method destroys any MT token from the smart contract defined in contractAddress.

    const multiTokenBurned = await klaytnSDK.multiToken.send.burnMultiTokenTransaction({

      tokenId,

      amount: '1',

      fromPrivateKey: receiverPrivateKey,

      contractAddress,

      account: receiverAddress,

    })

    console.log(`Burned Multi Token/s with txID: ${multiTokenBurned.txId}`)

  }

  const contractAddress = "0x5C128284F7846698134228e4a197664DE075AcDB";

  const tokenId = "1"

 erc1155Deploy();

mintmultiToken(contractAddress)

transferMT(contractAddress, tokenId);

burnMT(contractAddress, tokenId);

클레이튼 상의 스마트 컨트랙트 방식 불러오기 

이번 섹션에서는 Tatum SDK를 사용하여 클레이튼 상의 기존 스마트 컨트랙트를 불러오는 방법을 다룹니다. 포괄적인 관점에서 살펴보면, Tatum-js를 활용하여 컨트랙트 주소와 ABI를 바탕으로 기존에 배포한 컨트랙트 방식을 실행할 수 있습니다.

사용자는 read-only 또는 write 방식을 실행할 수 있습니다. read-only 방식은 불러오기 한 방식의 결과값을 보여주는 반면, write 방식은 트랜잭션 id 값을 보여줍니다. 

설정 

  • 기존 프로젝트 디렉토리 탐색하기 
  • 기존 스크립트(scripts) 폴더 입력하기 
  • 새로운 파일 `invoke.js`을 만들어 해당 코드 저장하기 

Tatum SDK 초기화 하기 

Tatum에 탑재된 기능을 프로젝트에서 사용하려면 사용자의 API Key로 SDK를 초기화해야 합니다. API Key가 없다면, 이 곳에서 키를 생성하세요.

import { TatumKlaytnSDK } from '@tatumio/klaytn'
const klaytnSDK = TatumKlaytnSDK({ apiKey: '<PASTE API KEY HERE>’ })

변수 설정하기

새로 생성한 `invoke.js`파일에 다음 변수를 복사하여 붙여넣기 하세요. MetaMask와 같은 지갑 인프라에 있는 사용자의 지갑 주소 및 개인키(Private Key)를 붙여넣기 하거나 이전 Part 1에서 설명한 대로 Tatum SDK를 활용하여 새로 생성할 수 있습니다.

const senderPrivateKey = “<PASTE PRIVATE KEY HERE>”

퀵스타트

기존 스마트 컨트랙트 방식을 불러오려면, 해당하는 컨트랙트 주소와 ABI를 알고 있어야 합니다. 이번 튜토리얼에서 기존의 은행 컨트랙트를 배포했으므로, getbalancedeposit 함수를 모두 호출할 것입니다. .

사용자의 은행 컨트랙트를 배포하기 위해서는, 이 링크를 클릭하여 Remix에서 열어주세요. 컨트랙트가 배포되면, Deployed Contracts 탭에서 해당 컨트랙트 주소와 Remix IDE상의 Solidity Compiler 탭에서 ABI를 복사해 주세요. 

아래 명령어를 실행하여 각 함수의 결과값을 확인해 주세요. 

node scripts/invoke.js

A. Read 방식

다음 코드 라인을 활용하여 사용자의 스마트 컨트랙트 안에 있는 Read 방식을 호출하세요. 

async function readFromSmartContract () {
const address = “<PASTE YOUR ADDRESS>”

    // your previously deployed contract address

    const contractAddress = “<PASTE YOUR CONTRACT ADDRESS>”

    // smart contract read method

    const  data  = await klaytnSDK.smartContract.send.smartContractReadMethodInvocationTransaction({

    contractAddress: contractAddress,

    methodABI: {

        "inputs": [

            {

                "internalType": "address",

                "name": "_addr",

                "type": "address"

            }

        ],

        "name": "getBalance",

        "outputs": [

            {

                "internalType": "uint256",

                "name": "",

                "type": "uint256"

            }

        ],

        "stateMutability": "view",

        "type": "function"

    },

    methodName: "getBalance",

    params: [address]

    })

    console.log(`Smart contract data: ${data.data}`) 

}

결과값

B. Write 방식

다음 코드 라인을 활용하여 사용자의 스마트 컨트랙트 안에 있는 Write 방식을 호출하세요.

async function invokeWriteMethod () {
// your previously deployed contract address

    const contractAddress = “<PASTE YOUR CONTRACT ADDRESS>”

    // smart contract read method

    const  data  = await klaytnSDK.smartContract.send.smartContractMethodInvocationTransaction({

    amount: "2",

    contractAddress: contractAddress,

    methodABI: {

        "inputs": [],

        "name": "deposit",

        "outputs": [],

        "stateMutability": "payable",

        "type": "function"

    },

    methodName: "deposit",

    fromPrivateKey: senderPrivateKey,

    params: []

    })

    console.log(`Smart contract tx id: ${ data.txId }`)

}

결과값

마치며

Tatum은 다양한 방식으로 개발자를 지원하며, 여러 블록체인을 위한 오픈소스 개발 플랫폼으로 포지셔닝하고 있습니다. 이번 튜토리얼에서 스마트 컨트랙트 및 토큰 컨트랙트 (ERC20, ERC721, and ERC1155) 활용법 뿐만 아니라 클레이튼 상의 기존 스마트 컨트랙트 호출 방법을 살펴보았습니다. 이로써, 사용자들은 민감한 데이터를 인터넷으로 전송하지 않고도 안전하게 트랜잭션에 서명하고 로컬 전파를 할 수 있습니다. 이에 따라 개인키와 니모닉 처리시 고도의 보안성을 제공하게 됩니다. 

보다 자세한 정보는 Klaytn DocsTatum을 참고하시기 바라며, 질문이 있으시면 Klaytn Forum에 남겨주세요. 

또한, 클레이튼 블록체인에서 안전하게 트랜잭션에 서명을 하고 전파를 하기 위해 Tatum Key Management System(KMS)를 살펴보시기 바랍니다.