RoleBasedKey 테스트 하다가 오류가 발생하여 문의드립니다

오전에 문의드렸던 내용으로 테스트 코드를 작성해서 테스트를 진행하고 있습니다.

// baobabWallet_3
        String feePayerWallet = "0x9ad50";

        try {
            // 보내는 사람
            SingleKeyring senderKeyring = KeyringFactory.createFromPrivateKey("0x15321");

            Caver caver = setCaver(accessKey, secretAccessKey, chainId);
            caver.wallet.add(senderKeyring);

            // feepayer
            String feePayerWalletFilePath = walletsRootPath + messageByLocaleService.getMessage("mcc.wallet." + feePayerWallet + ".path");

            //Decrypt keystore.
            ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
            KeyStore keyStore = objectMapper.readValue(new File(feePayerWalletFilePath), KeyStore.class);

            AbstractKeyring feePayerKeyring = KeyringFactory.decrypt(keyStore, "asdf1234!");
            log.info("### feePayerKeyring : {}", feePayerKeyring.getAddress());

            // 새로운 key 생성
            List<String[]> newRoleBasedKeyList = caver.wallet.keyring.generateRoleBasedKeys(new int[]{1, 1, 1});

            // 새로운 keyring 생성
            RoleBasedKeyring newKeyring = caver.wallet.keyring.create(feePayerKeyring.getAddress(), newRoleBasedKeyList);

            // account 인스턴스 생성
//            BigInteger[][] optionWeight = {
//                    {},
//                    {},
//                    {},
//            };

            WeightedMultiSigOptions[] options = {
                    new WeightedMultiSigOptions(),
                    new WeightedMultiSigOptions(),
                    new WeightedMultiSigOptions(),
            };

            Account account = newKeyring.toAccount(Arrays.asList(options));

            log.info("### account : {}", account);

            // private key update 트랜잭션 생성
            AccountUpdate accountUpdate = caver.transaction.accountUpdate.create(
                    TxPropertyBuilder.accountUpdate()
                            .setFrom(feePayerKeyring.getAddress())
                            .setAccount(account)
                            .setGas(BigInteger.valueOf(150000))
            );

            // 트랜잭션에 서명하기
            caver.wallet.sign(feePayerKeyring.getAddress(), accountUpdate);

            // 결과값 확인
            Bytes32 sendResult = caver.rpc.klay.sendRawTransaction(accountUpdate).send();
            String txHash = sendResult.getResult();

            TransactionReceiptProcessor receiptProcessor = new PollingTransactionReceiptProcessor(caver, 1000, 15);
            TransactionReceipt.TransactionReceiptData receiptData = receiptProcessor.waitForTransactionReceipt(txHash);

            log.info(objectToString(receiptData));
        } catch(Exception e) {
            log.warn("{}", e);
        }

위와 같이 작성하고 실행을 했는데 Failed to find keyring from wallet with address이런 오류가 발생하여
발생한 위치를 보니 caver.wallet.sign(feePayerKeyring.getAddress(), accountUpdate);부분에서 발생했습니다

디버깅을 했을 때 accountUpdate의 주소와 feePayerKeyring의 주소가 달라서 발생한 오류처럼 보여집니다.
미디움참고했습니다.

setAccount부분을 수정해줘야 할것 같은데 어떻게 수정해야할 지 몰라 문의드립니다.

안녕하세요.

이 문서에 나와있는 순서대로 코드 작성해보고 Role-based Account 타입을 사용하기 위한 방법을 숙지하신 뒤에 코드를 참고해서 변형을 하시는게 좋을 것 같습니다.

감사합니다.

@Kale

알려주신 링크를 참고해서
정상적인 응답을 받은 것 같습니다

txHash : 0x9876ab238bf14e1813c5542414a0f2107052fb1c96e561fd280598603102ff61

{
  "blockHash" : "0xfe67db5ea086a2f9e4079f27d821b4472dfb4c0440f8baf1f5ea5672e936e588",
  "blockNumber" : "0x459349a",
  "codeFormat" : null,
  "contractAddress" : null,
  "feePayer" : null,
  "feePayerSignatures" : null,
  "feeRatio" : null,
  "from" : "0x9ad50a9334cd2f420d65ab1f35abeb388d298a33",
  "gas" : "0x249f0",
  "gasPrice" : "0x5d21dba00",
  "gasUsed" : "0x13c68",
  "humanReadable" : false,
  "key" : "0x05f86ca302a103e4371f9006fe2f67fc704fe9961d5ce84e81a5e9ccdd9e63c49eec189407bbbaa302a102d26d5d77d6fed2ce8c18fbed3daeea4c19ae646119ae6d856a9050e1700c450fa302a103aa91b9cc7b156842263b78eaf44093894e05daec519bf47c7678074338b459f1",
  "input" : null,
  "logs" : [ ],
  "logsBloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce" : "0x0",
  "senderTxHash" : "0x9876ab238bf14e1813c5542414a0f2107052fb1c96e561fd280598603102ff61",
  "signatures" : [ {
    "v" : "0x7f5",
    "r" : "0xd42014a8a4159962831a763a6a35bc4bf9be8ea01387a08a1b5a9846bd1dbde1",
    "s" : "0x6e293c815869132f1baa43c9e7ccf68738904ceb433cf55a56bf8787b3a02ed8"
  } ],
  "status" : "0x1",
  "to" : null,
  "transactionIndex" : "0x0",
  "transactionHash" : "0x9876ab238bf14e1813c5542414a0f2107052fb1c96e561fd280598603102ff61",
  "txError" : null,
  "type" : "TxTypeAccountUpdate",
  "typeInt" : "32",
  "value" : null
}

응답값을 확인해봤을 때 이렇게 나왔고 caver.wallet.updateKeyring(newKeyring)부분은 실행하지 않았습니다
caver.wallet.updateKeyring(newKeyring) 부분 직전까지 정상적으로 동작하는지 확인하기 위해 실행하지 않아 알려주신 링크대로 나머지 소스를 작성해서 실행하려고 했는데

caver.wallet.sign(feePayerKeyring.getAddress(), accountUpdate);

// 결과값 확인
Bytes32 sendResult = caver.rpc.klay.sendRawTransaction(accountUpdate).send(); <- 이 부분에서 에러가 발생했습니다.

{"jsonrpc":"2.0","id":3,"error":{"code":-32000,"message":"invalid transaction v, r, s values of the sender"}} 이런 에러가 발생했습니다.
제가 받은 응답값으로 서명을하고 트랜잭션을 전송하면 되는건가요??

위에 나온 TransactionReceipt은 무엇을 실행해서 나온걸까요?

Account를 Update하기전까지는 Account Type이 Legacy Type이므로 기존에 사용하던 하나의 키로 서명 하고 트랜잭션을 전송하셔야합니다.

Account를 Update한 이후에는 Account Type이 Role-based Type일 것이기때문에 이 Account가 정상적으로 update되었는지 klay_getAccount와 같은 API로 확인하여 정상적으로 Update가 되었는지? 확인을 먼저 하신 뒤에
Role-based Type으로 update되었다면 그때 Role-based Type의 의도에 맞게 사용하시면 될 것 같습니다.

@Kale
말씀하신 Account를 Update를 한다는 말씀은 caver.wallet.updateKeyring(newKeyring)을 말씀하시는건가요?
TransactionReceipt은

// private key update 트랜잭션 생성
            AccountUpdate accountUpdate = caver.transaction.accountUpdate.create(
                    TxPropertyBuilder.accountUpdate()
                            .setFrom(feePayerKeyring.getAddress())
                            .setAccount(account)
                            .setGas(BigInteger.valueOf(150000))
            );

            // 트랜잭션에 서명하기
            caver.wallet.sign(feePayerKeyring.getAddress(), accountUpdate);

            // 결과값 확인
            Bytes32 sendResult = caver.rpc.klay.sendRawTransaction(accountUpdate).send();
            String txHash = sendResult.getResult();

            TransactionReceiptProcessor receiptProcessor = new PollingTransactionReceiptProcessor(caver, 1000, 15);
            TransactionReceipt.TransactionReceiptData receiptData = receiptProcessor.waitForTransactionReceipt(txHash);

위 코드를 실행해서 나온 결과값입니다.

KAS API로 "klay_getAccount"로 계정을 확인해보니까 정상적으로 변경된것 같습니다.

RoleBaseKey로 업데이트한 계정은 keyType이 "5"로 되어 있고 업데이트 안한 계정은 keyType이 "1"이 되어있었습니다.

"key": [
                    {
                        "keyType": 2,
                        "key": {
                            "x": "0xe4371f9006fe2f67fc704fe9961d5ce84e81a5e9ccdd9e63c49eec189407bbba",
                            "y": "0x4255f0cbd3505c459557933913a03cb19ef0708ae3c8923a3ec7b8fd55d99559"
                        }
                    },
                    {
                        "keyType": 2,
                        "key": {
                            "x": "0xd26d5d77d6fed2ce8c18fbed3daeea4c19ae646119ae6d856a9050e1700c450f",
                            "y": "0x16cd326806ebbbaf0af9b616723734a644712cae8c5ad30b6e70a461f9e75c78"
                        }
                    },
                    {
                        "keyType": 2,
                        "key": {
                            "x": "0xaa91b9cc7b156842263b78eaf44093894e05daec519bf47c7678074338b459f1",
                            "y": "0x876452802e3dd58b2cceca68454bfb31b4a1737036754212d544017cfe44eba7"
                        }
                    }
                ]

이 응답값중에 수수료대납트랜잭션 서명에 사용하는 키는 어떤걸 사용해야하나요??
key[2].key.x / key[2].key.y 둘중에 아무거나 사용하면 되나요??

네. 이 문서의 10번부터 확인부탁드립니다.

@Kale

죄송하지만…
10번부터 확인하며 테스트를 하고 있는데 caver.wallet.updateKeyring(newKeyring);부분을 실행을 못하고 있습니다.

RoleBasedKey를 새로 만들어서 다시 트랜잭션을 발생시켜 업데이트를 하려고 하는데 이미 업데이트된 서명값으로 서명을 하지 않아 에러가 발생하고 있습니다…

앞서 제가 서명했던 값에 대한 keyRing을 가져와서 caver.wallet.updateKeyring을 하고 싶은데 방법이 없을까요?

공개 키가 이미 업데이트 된 Account는 업데이트된 공개 키에 해당하는 개인 키로 서명을 하셔야합니다.

새로운 테스트용 Account를 생성하셔서 진행해 보시길 추천드립니다.

감사합니다.

@Kale

제가 백업해둔 응답값이 있는데 이 값으로 서명하면 될까요??

{
    "v" : "0x7f5",
    "r" : "0xd42014a8a4159962831a763a6a35bc4bf9be8ea01387a08a1b5a9846bd1dbde1",
    "s" : "0x6e293c815869132f1baa43c9e7ccf68738904ceb433cf55a56bf8787b3a02ed8"
  }

이렇게 받아둔것을 백업해 두었는데 이것도 못쓰는건가보네요…

새로 생성해서 해보겠습니다
감사합니다.

이미 트랜잭션의 응답값이 있다는 것은 블록에 기록된 트랜잭션이고,
Account별로 매 트랜잭션마다, update되는 필드값이 있기때문에, 서명에 사용되는 data는 매번 달라집니다.
백업해둔 서명값을 재사용할 수는 없습니다.