콘텐츠로 이동

2022 07 15

2022-07-15

KAS Fee-payer Pools

  • 문제 상황

    • 바오밥 네트워크에서는 KAS를 통해 NFT를 발행할 수 있었는데, 메인넷으로 넘어가니까 Unauthorized가 뜨며 안 됨
      Unauthorized
      xyz.groundx.caver_ext_kas.rest_client.io.swagger.client.ApiException: Unauthorized
          at app//xyz.groundx.caver_ext_kas.rest_client.io.swagger.client.ApiClient.handleResponse(ApiClient.java:923)
          at app//xyz.groundx.caver_ext_kas.rest_client.io.swagger.client.ApiClient.execute(ApiClient.java:839)
          at app//xyz.groundx.caver_ext_kas.rest_client.io.swagger.client.api.kip17.api.Kip17Api.deployContractWithHttpInfo(Kip17Api.java:596)
          at app//xyz.groundx.caver_ext_kas.rest_client.io.swagger.client.api.kip17.api.Kip17Api.deployContract(Kip17Api.java:581)
          at app//xyz.groundx.caver_ext_kas.kas.kip17.KIP17.deploy(KIP17.java:77)
      
    • 찾아보니까 KAS 무료 플랜에서는 Fee Payer Pool을 통해 수수료를 대납한다고 함
      • 참고: https://forum.klaytn.foundation/t/kip-17/2666
      • 무료 플랜은 API에 대한 권한이 없음 => global fee payer를 위한 API
      • 따라서 user fee payer pool을 만들어서 진행해보는 것을 권장한다는데...

KAS Getting Started

  • Klaytn 계정 생성
    • 계정(Account): 클레이튼에 트랜잭션 전송하는 주체
    • 수수료 대납 계정(FeePayerAccount): 클레이튼 트랜잭션 수수료 납부 주체
    • 오퍼레이터(Operator): 서비스 체인 데이터를 메인 체인에 앵커링하는 주체
      • 서비스 체인: 클레이튼의 확장성 솔루션으로 메인넷을 사용하기엔 부담스러운 서비스를 위한 전용 블록체인

아! 그냥 만들자!

  • 참고: https://refs.klaytnapi.com/ko/kip17/latest
  • 만드는 이유
    • KAS Java Docs 매우 불편함
    • 버전 별로 또 상이한 API Call
      • 1.9.0 버전은 컴파일도 안됨
      • v2 endpoint로 쏴야한다는데...?
    • Connectable에서 필요한 기능 정도는 OpenAPI로 충분할 것 같으니, 모듈화 시켜서 만들어보자!
  • 필요한 기능
    1. 아티스트의 NFT 스마트컨트랙트를 배포해주기
    2. 아티스트의 NFT 스마트컨트랙트에 대해 토큰 민팅
    3. 해당 토큰의 소유자를 불러와야 하는 경우
    4. 사용자가 NFT 구매시 전송해주기
  • Fee Payer Options
    • 사용자 대납 계정을 사용해야 함
    • 아래와 같이 json body 작성 및 추가 필요
      "options": {
        "enableGlobalFeePayer": false,
        "userFeePayer": {
          "krn": "krn:1001:wallet:20bab367-141b-439a-8b4c-ae8788b86316:feepayer-pool:default",
          "address": "0xd6905b98E4Ba43a24E842d2b66c1410173791cab"
        }
      }
      
  • Authentication
    • 요청 시 Http Headers에 다음 정보를 넣어둬야 함
      Content-Type: application/json
      x-chain-id: 8217
      Authorization: Basic KEYKEYKEY
      

컨트랙트

  • 컨트랙트 배포

    • 요청
      • [POST] https://kip17-api.klaytnapi.com/v2/contract
        {
          "alias": "test",
          "symbol": "TEST",
          "name": "TEST NFT",
          "owner": "0xa809284C83b901eD106Aba4Ccda14628Af128e14",
          "options": {
            "enableGlobalFeePayer": true,
            "userFeePayer": {
              "krn": "krn:1001:wallet:88c1223c-66af-4122-9818-069b2e3c6b30:feepayer-pool:default",
              "address": "0xE8964cA0C83cBbF520df5597dc1f5EFc27E5E729"
            }
          }
        }
        
    • 응답
      {
        "options":{
          "enableGlobalFeePayer":false,
          "userFeePayer":{
            "address":"0xC99382456a715b298f59875133D6D59beF1D77B2",
            "krn":"krn:8217:wallet:ac18f71f-230d-4e5e-9912-59b546e3cd4a:feepayer-pool:default"
          }
        },
        "owner":"0x5D54a7e12542aF5433fa7665F4546ed4e4BC98c1",
        "status":"Submitted",
        "transactionHash":"0xa2834a970cd5abb1a5f058d7e02672aaafa09b95a5b4d7873c554e97949356fc"
      }
      
  • 컨트랙트 목록 조회
    • 요청
    • 응답
      {
        "cursor": "",
        "items": [
          {
            "address": "0xab48e18fc58b80ff507c3eabecd4f0b6ab0daefd",
            "alias": "joel2",
            "chainId": "8217",
            "name": "JOEL2 NFT",
            "options": {
              "enableGlobalFeePayer": false,
              "userFeePayer": {
                "address": "0xC99382456a715b298f59875133D6D59beF1D77B2",
                "krn": "krn:8217:wallet:ac18f71f-230d-4e5e-9912-59b546e3cd4a:feepayer-pool:default"
              }
            },
            "symbol": "JOEL2"
          },
          {
            "address": "0x01229a3c198ffdd60df460f2fdd0fc1ff31beb4c",
            "alias": "joel",
            "chainId": "8217",
            "name": "JOEL NFT",
            "options": {
              "enableGlobalFeePayer": true,
              "userFeePayer": {
                "address": "0xC99382456a715b298f59875133D6D59beF1D77B2",
                "krn": "krn:8217:wallet:ac18f71f-230d-4e5e-9912-59b546e3cd4a:feepayer-pool:default"
              }
            },
            "symbol": "JOEL"
          }
        ]
      }
      
  • 컨트랙트 목록 조회
    • 요청
    • 응답
      {
          "address": "0xab48e18fc58b80ff507c3eabecd4f0b6ab0daefd",
          "alias": "joel2",
          "chainId": "8217",
          "name": "JOEL2 NFT",
          "options": {
              "enableGlobalFeePayer": false,
              "userFeePayer": {
                  "address": "0xC99382456a715b298f59875133D6D59beF1D77B2",
                  "krn": "krn:8217:wallet:ac18f71f-230d-4e5e-9912-59b546e3cd4a:feepayer-pool:default"
              }
          },
          "symbol": "JOEL2"
      }
      
  • 컨트랙트 소유권 포기
    • 흐음... 내가 Owner가 맞다고 조회되는데, 블록체인상엔 다르게 기록되어있네...?

토큰

  • 토큰 발행 및 전송

    • 응답
      {
          "status": "Submitted",
          "transactionHash": "0xa5e5b49eb5955cd1f0200a4b361e81f03ec11679a287a347303890a24588987f"
      }
      
  • 토큰 목록 조회
    • 요청
    • 응답
      {
          "cursor": "",
          "items": [
              {
                  "createdAt": 1657870730,
                  "owner": "0xbc29741452272c432e8cd3984b4c7f2362dff7f0",
                  "previousOwner": "0x0000000000000000000000000000000000000000",
                  "tokenId": "0x2",
                  "tokenUri": "https://connectable-events.s3.ap-northeast-2.amazonaws.com/json/2.json",
                  "transactionHash": "0xdd2783e8ba70cbbac680279c5ce2c068a7e96fbf3129d2720bac65ba3672f9f8",
                  "updatedAt": 1657870730
              },
              {
                  "createdAt": 1657870640,
                  "owner": "0x3ab31d219d45ce40d6862d68d37de6bb73e21a8d",
                  "previousOwner": "0x0000000000000000000000000000000000000000",
                  "tokenId": "0x1",
                  "tokenUri": "https://connectable-events.s3.ap-northeast-2.amazonaws.com/json/1.json",
                  "transactionHash": "0xe9e2885389af373b35758d281eb1fef8b212a1a894d4901a77c5e4f5de21b4c5",
                  "updatedAt": 1657870640
              }
          ]
      }
      
  • 토큰 정보 조회
    • 요청
    • 응답
      {
          "createdAt": 1657870640,
          "owner": "0x3ab31d219d45ce40d6862d68d37de6bb73e21a8d",
          "previousOwner": "0x0000000000000000000000000000000000000000",
          "tokenId": "0x1",
          "tokenUri": "https://connectable-events.s3.ap-northeast-2.amazonaws.com/json/1.json",
          "transactionHash": "0xe9e2885389af373b35758d281eb1fef8b212a1a894d4901a77c5e4f5de21b4c5",
          "updatedAt": 1657870640
      }
      
  • 토큰 전송

    • 정해진 주소로 토큰을 전송할 것!
    • Sender와 Owner가 다를 경우 Sender가 해당 토큰의 전송권한이 있을 것
      • Sender의 전송권한은 v2/contract/{contract-address-or-alias}/approve/{token-id} 로 부여 가능
    • 요청
    • 응답
      {
          "status": "Submitted",
          "transactionHash": "0xf85eb0917fdec4c23f3f2b4668676d8f0cdbfe4e911a3933e338528c23ec6bd5"
      }