Caver-JAVA Contract.send 함수 사용 시 FeeDelegation 을 할 수 있는 방법이 있을까요?

안녕하세요 개발 도중 궁금한점이 두가지 생겨 문의드리기 위해 글을 올리게 되었습니다.
궁금한 점은 다음과 같습니다.

  1. Caver-JAVA 의 Contrat를 사용하여 Contract 에 콜을 할 때 FeeDelegation을 적용하여 콜을 할 수 있는 방법이 있을까요?

  2. 개발 외적인 개인적인 궁금증인데… KAS Wallet 이 어떤식으로 구동되는지 궁금합니다. 특히 KAS 의 Migration 기능을 통해 기존 계정을 KAS Wallet 계정으로 Migration을 했을 시 기존 계정이 갖고 있던 자산들은 어떻게 통제해야 하는지 궁금합니다.
    제가 잘못 알고 있는 것이 아니라면 기존 EOA 를 KAS 계정으로 Migration시 PrivateKey등을 전달하던지 하는 방식이 아니라 기존 EOA의 자산을 통제하기 어려워 보여서요.

항상 친절한 답변 해주셔서 감사합니다:)

안녕하세요! 질문 올려주셔서 감사합니다. :slight_smile:

  1. caver-java의 Contract를 사용하여 Fee Delegation을 사용하는 기능은 아직 제공되고 있지 않습니다. 올해 상반기 내에 제공될 예정입니다! Klaytn Docs - getting started에 중간 부분에 Fee Delegation을 사용하여 스마트 컨트랙트를 배포하고 실행하는 예제가 있는데 이를 참고하시면 현재 제공되는 기능을 사용하여 수수료 대납을 통해 스마트 컨트랙트를 배포/실행하실 수 있습니다.

  2. KAS의 Migration 기능은 Klaytn Account 의 AccountKey를 KAS Wallet API 서비스에서 관리하는 키로 변경하는 작업입니다. 그러므로 기존의 계정은 그대로 유지되며 키만 변경되게 됩니다. 그러므로 마이그레이션 이후에 동일한 주소를 가지는 계정을 그대로 사용하실 수 있으며, 해당 계정의 자산은 그대로 유지됩니다. 다만 직접 관리하던 private key는 계정 마이그레이션 이후에 더이상 사용할 수 없으며, KAS Wallet API에 저장되어 있는 키를 사용하여 계정을 사용할 수 있습니다. Klaytn 에서 제공하는 AccountAccountKey의 개념은 Klaytn Docs를 참고해 주시기 바랍니다.

추가적으로 궁금하신 부분이 있으시면 편하게 질문 남겨주세요 감사합니다 :slight_smile:

1 Like

답변 감사합니다 :slight_smile:

1번 질문 내용에 대해서는 잘 이해할 수 있었습니다.

2번 질문에 관해 추가 문의드릴 내용이 있는데요. 내용은 다음과 같습니다.

  1. Migration 진행 후 Private Key가 아닌 Wallet API에 있는 Key를 사용하면 된다는 것은 기존 EOA 의 자산을 통제하는 서명을 진행할 시 기존 EOA의 PrivateKey가 아닌 Wallet API 의 Key를 사용해서 서명을 하면 된다는 뜻일까요?? 조금 더 구체적으로는 Caver-JAVA 의 FDContractExecutionTransactionRequest() 를 사용하여 트랜잭션을 보낼 시 From 에 Wallet API 의 Key를 사용하여 서명을 하면 되는것일까요??

  2. 위 질문의 연장선 입니다. 만약 위 내용이 맞다면 Migration 이후 Wallet API 의 Key를 활용하여 EOA 의 자산을 통제할 시 EOA 의 주소와 KAS API의 계정만 있으면 통제가 가능할 것 같습니다.(Migration 진행 시 Address 와 KAS ID, KAS Secret Key 만 있으면 되므로) 따라서 제가 생각한 1번 방식이 틀린 방식 같은데. 혹시 마이그레이션 하기 전의 EOA 의 자산을 Migration 이후 통제하는 방법을 알 수 있을까요?

성가신 질문 드려 죄송하며 항상 빠른답변 주셔 감사합니다 :slight_smile:

네넵 답변 드리겠습니다.

  1. 트랜잭션에 서명하는 경우, KAS Wallet API 서비스 내에 키가 보관되어 있으므로 KAS Wallet API에 트랜잭션 서명 요청을 전송해야 합니다. caver-java-ext-kas를 사용하는 경우 KAS Docs - Tuturial 에 설명된 caver.kas.wallet.requestFDSmartContractExecutionPaidByUser(fee payer pool에 있는 fee payer 사용하는 경우) 혹은 caver.kas.wallet.requestFDSmartContractExecutionPaidByGlobalFeePayer(global fee payer 사용시)를 사용할 수 있습니다.

  2. 네네 서명을 직접 하시는 것이 아니라, 트랜잭션 내용을 KAS Wallet API로 전송하고 서명을 요청해야 합니다. 마이그레이션 하기 전의 EOA 자산은 마이그레이션 이후에도 동일하게 보존되며 키를 관리하는 주체만 질문자님에서 KAS Wallet API로 바뀌는 것이므로, KAS Wallet API를 사용하여 자산을 통제할 수 있습니다.

추가적으로 궁금하신 사항 있으시면 말씀해 주세요! :slight_smile:

1 Like

빠른 답변 해주셔 너무 감사합니다.

추가적으로 궁금한점 있어 질의드립니다.

  1. 제공해주신 튜토리얼을 참고해보면 setFrom 메소드에 KAS Wallet 주소를 입력하게 되어있는데, 이 뜻이 KAS Wallet 주소를 입력하면, 해당 주소에 페어링 되어있는 키로 서명을 진행하게 되는 구조인건가요? 만약 위 구조가 맞다면 KAS Wallet 의 주소를 Private 하게 관리해야 되는것일까요?

  2. 특정 EOA 를 KAS 로 마이그레이션 했을 시 그럼 두개의 주소값이 생성되는 것일까요? (기존 EOA 의 주소, KAS 에 마이그레이션 하여 얻은 주소) 만약 그렇다면 외부에서 FT, NFT 토큰을 보내고자 할 시 기존 EOA 의 주소, KAS 주소 중 어느 주소로 보내야 하는 것일까요??

  3. KAS 계정으로 Migration을 진행할시 PrivateKey를 넘기는 구조가 아니라 Address 를 넘기는것이 맞을까요? 만약 해당 사항이 맞다면 Address 전달 만으로도 서명이 가능한 이유가 궁금합니다.

  4. 기존 ERC-20표준으로 개발된 FT 컨트랙트의 경우 Transfer함수 실행 시 서명한 계정의 FT 를 통제하도록 되어있습니다. KAS Wallet API 를 통해 기존 계정을 마이그레이션 한 후 서명 시에도 FT 컨트랙에서 서명대상자의 소유 계정을 확인할 수 있나요?

  5. 만약 동일한 주소를 여러번 마이그레이션 하여 기존 EOA 하나에 여러 KAS Wallet 계정이 페어링 되어있을 시 연결 된 모든 KAS 계정으로 서명할 수 있을까요??

시스템을 KAS로 완전 마이그레이션 하기 전 점검을 하고있는 과정이라 질문을 많이 드리게 되어 죄송합니다.

항상 빠른 답변주셔 너무 감사합니다! :slight_smile:

  1. 주소는 private하게 관리될 필요는 없습니다. KAS API 를 사용할 때 필요한 auth정보를 private하게 관리하시면 됩니다.

  2. 아니요. 위에서 말씀드렸다시피, 마이그레이션은 Klaytn 계정의 AccountKey를 변경하는 것이기 때문에 주소는 동일합니다.

  3. Migration을 할 때에는 기존의 사용하시던 key로 서명을 해서 결과를 전송해야 합니다. 마이그레이션 할 경우 KAS Wallet API에 키를 먼저 생성(결과로 생성된 키와 매핑되는 public key가 리턴됩니다)합니다. 리턴 받은 public key를 사용하여 Account Update 트랜잭션을 생성하고 기존의 키로 서명한 뒤 KAS Wallet API로 전송하는 방식으로 migration을 진행할 수 있습니다. 아래 코드를 참고해 주세요.

         CaverExtKAS caver;
    
         String accessKeyId = "";
         String secretAccessKey = "";
         String chainId = "1001"; // Cypress 8217
    
         caver = new CaverExtKAS(chainId, accessKeyId, secretAccessKey);
         KeyCreationResponse response = caver.kas.wallet.createKeys(1);
    
         // Create a keyring with the original Klaytn account
         String address = "";
         String privateKey = "";
         SingleKeyring keyring = KeyringFactory.create(address, privateKey);
    
         String newPublicKeyString = response.getItems().get(0).getPublicKey();
         com.klaytn.caver.account.Account account = com.klaytn.caver.account.Account.createWithAccountKeyPublic(keyring.getAddress(), newPublicKeyString);
         FeeDelegatedAccountUpdate tx = new FeeDelegatedAccountUpdate.Builder()
                 .setKlaytnCall(caver.rpc.klay)
                 .setFrom(keyring.getAddress())
                 .setGas(BigInteger.valueOf(250000))
                 .setAccount(account)
                 .build();
    
         tx.sign(keyring);
    
         AccountRegistration registration = new AccountRegistration();
         registration.setAddress(keyring.getAddress());
         registration.setKeyId(response.getItems().get(0).getKeyId());
         registration.setRlp(tx.getRLPEncoding());
    
         AccountRegistrationRequest request = new AccountRegistrationRequest();
         request.add(registration);
    
         RegistrationStatusResponse result = caver.kas.wallet.registerAccounts(request);
    
  4. 서명 대상자의 소유 계정이 어떤 말씀인지 추가 설명 부탁드립니다. 제가 이해한 바가 맞으면 마이그레이션을 해서 계정의 키를 업데이트하는 것에 대해서 잘못 이해하고 계신 것 같습니다. 문서를 한 번 읽어보시기 바랍니다. 마이그레이션을 하는 것은 Klaytn 계정에서 사용하는 키를 KAS Wallet API 서비스에서 관리하는 키로 변경하는 작업입니다. 그러므로 컨트랙트를 실행하는 from이 명시되어 있다면 KAS Wallet API를 사용하여 트랜잭션에 서명하면 됩니다.

  5. 마이그레이션은 기존 계정에 페어링되는 것이 아니라 Klaytn 계정의 키를 변경하는 것입니다. Klaytn 계정에서 키가 업데이트 되는 것에 대한 문서를 읽어보시기 바랍니다.

1 Like

답변주셔 감사합니다!

샘플코드를 보고 정확히 이해할 수 있었습니다. KAS Reference Documentation 주소에서 RLP 값에 어떤값을 넣어야 하는지 잘 와 닿지 않았었는데 기존 Key로 서명한 값 이군요. 기존에 궁금했던점이 확실히 해결되었습니다.

제공해주신 문서(Accounts - Klaytn Docs)를 보고 사소한 궁금증이 생겼는데요.

Multiple Key Pairs and Role-Based Keys 에서 Klaytn account allows the key pair associated with the account to be changed. 이 부분이 조금 궁금합니다. 해당 문서 초반에 Klaytn Account 는 일종의 Data Structure 라고 했는데요. 그럼 Address, PrivateKey등이 Data Structure 에 접근하기 위한 Key Pair 고 이 값은 Data Structure의 주인(그 당시 등록된 Key Pair를 소유한 사람)이 원할 때 삭제, 변경이 가능한 구조라고 생각하면 될까요? 마찬가지로 Klaytn Account (Data Structure) 에 대한 접근 할 수 있는 Key Pair 가 여러개 등록될수도 있는 구조이구요.

PrivateKey를 ECC에 넣어도 나오는 값이 변하지 않을텐데 어떻게 Key Pair 가 여러개가 될 수 있지?라고 계속 생각했는데 답변 덕분에 이해가 잘 된 것 같습니다.

친절한 답변주셔 감사합니다 :slight_smile:

Klaytn에서 계정의 키를 유동적으로 바꿀 수 있는 기능을 지원하기 위해 Klaytn 네트워크 상의 계정은 모두 AccountKey를 가지고 있습니다. 처음 생성된 Klaytn Account A가 ([privateKey A - publicKey A] - address A)라고 가정할 때에 Klaytn에서는 [privateKey A - publicKey A]와 address A의 강결합을 끊을 수 있다는 의미입니다.

(실제로 Klaytn 네트워크에는 해당 계정에서 사용하는 키가 public Key의 포맷으로 저장이 됩니다.)

처음 생성하는 경우(AccountKeyLegacy)에는 private key와 public key 그리고 address가 강결합된 상태이기 때문에 따로 public key를 저장할 필요가 없습니다. 하지만 Klatyn Account A에서 사용하는 key를 변경하는 경우 (즉 address와 key pair의 강경할 상태를 끊는 경우) 에는 실제로 Klaytn 네트워크에서 서명을 검증할 때에 해당 계정에서 사용하는 private key에 매핑되는 pubic key정보가 필요하기 때문에 해당 계정에서 사용하는 새로운 키가 public key 형태로 저장됩니다. 그것이 바로 AccountKey 입니다.

addrss와 private key를 소유하고 있는 경우 계정의 키를 업데이트 (Account update 트랜잭션을 전송)하여 네트워크의 Klyatn Account A에 저장되어 있는 AccountKey를 변경할 수 있으며, 업데이트 이후에는 기존의 키는 사용이 불가합니다.

만약 하나의 계정 Klaytn A에서 여러 개의 private key를 사용하는 경우 사용되는 AccountKey 타입이 AccountKeyWeightedMultiSig입니다. 만약 Key Pair를 여러 개 사용하기 위하여 AccountKeyWeightedMultiSig로 업데이트 하는 경우 Klaytn Account A ([[privateKey B - publicKey B], [privateKey C - publicKey C], …] - address A) 이런식으로 된다고 생각하시면 됩니다. 그럼 privateKey B 그리고 privateKey C를 사용하여 Klaytn Account A가 전송하는 트랜잭션에 서명할 수 있습니다.(threshold와 weight관련 내용은 문서 확인 부탁드립니다.)

위와 같이 AccountKeyWeightedMultiSig로 업데이트하는 트랜잭션이 실행이 완료되면, 실제 네트워크의 Klaytn Account A는 여러 개의 키를 public key 포맷으로 저장하고 있는 AccountKeyWeightedMultiSig를 AccountKey로 갖게됩니다. 업데이트 된 이후에는 새로운 키를 사용하여 트랜잭션 전송 및 계정키 업데이트, 수수료 대납 모두 가능합니다. 기존의 키는 ([privateKey A - publicKey A])는 사용이 불가합니다.

만약에 계정을 더이상 사용하고 싶지 않은 경우 (위에서 언급하신 삭제의 경우) AccountKeyFail로 계정의 키를 업데이트 할 수 있습니다.

아래 테크 블로그를 읽어보시면 조금 더 도움이 되실 것 같습니다.

1 Like

친절하게 답변주셔 감사합니다 :slight_smile:

덕분에 Klaytn Account에 대한 개념이 보다 확실히 잡힌 것 같습니다.
과거 처음 클레이튼을 도입했을 때는 이더리움과 큰 차이 없이 사용했었는데 클레이튼이 개발자 님들 노고로 짧은 시간에 정말 많이 변화했네요.
지난 1년 반 동안 앱 개발을 위해 블록체인 외에 다른 개발 분야를 주로 팔로우업 하다 보니, 예전 이더리움에 개념이 멈춰있었는데 궁금한 점을 자세히 답변해 주신 덕분에 짧은 시간에 많이 배울 수 있었습니다.

감사합니다 :slight_smile:

1 Like

:slight_smile: 클레이튼을 관심있게 지켜봐 주셔서 감사합니다. !!

1 Like