Caver java RoleBasedKey를 이용한 토큰이체 오류문의드립니다

boolean feePayerExists = true;

        BufferedReader br = new BufferedReader(new FileReader(projectBaseDir +"/json/Contract.json"));
        KIP7Json kip7Json = new Gson().fromJson(br, KIP7Json.class);

        Contract contract = KIP7.create(caver, kip7Json.getAbi().toString(),  "0x0bbcd245044c507ba1c9c3011d69b33ff3cbc7ed");

        Caver caver = setCaver(accessKey, secretAccessKey, chainId);
        SingleKeyring senderKeyring = KeyringFactory.createFromPrivateKey("0x15321f6b31d600b59cd5e7e2f3f63a49331eafa5de9cfbf8701c8b4c0cdee7a4");
        caver.wallet.add(senderKeyring);

        AbstractKeyring feePayerKeyring = null;
        if(feePayerExists){
            String feePayerWallet = "0x6e4d6118358d76412163d3d71510a3365e32fa64";
            String feePayerWalletFilePath = walletsRootPath + messageByLocaleService.getMessage("mcc.wallet." + feePayerWallet + ".path");

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

            feePayerKeyring = KeyringFactory.decrypt(keyStore, "1q2w3e4r");
            caver.wallet.add(feePayerKeyring);
            contract.setWallet(caver.wallet);
        }

        SendOptions sendOptions = new SendOptions(senderKeyring.getAddress());
        sendOptions.setFeeDelegation(false);
        sendOptions.setGas(BigInteger.valueOf(1000000));

        if(feePayerExists){
            sendOptions.setFeeDelegation(true);
            sendOptions.setFeePayer(feePayerKeyring.getAddress());
        }else{
            sendOptions.setFeeDelegation(false);
        }

        String account = "0xb7cc824e26fea75cb930f1036d9159eb65f73f8d";
        String convertAmount = caver.utils.convertToPeb("1", Utils.KlayUnit.KLAY);

        AbstractTransaction executionTx = contract.sign(sendOptions, "transfer", account, new BigInteger(convertAmount));
        caver.wallet.signAsFeePayer(feePayerKeyring.getAddress(), (AbstractFeeDelegatedTransaction)executionTx, 2);

        Bytes32 txHash_executed = caver.rpc.klay.sendRawTransaction(executionTx).send();
        TransactionReceiptProcessor receiptProcessor = new PollingTransactionReceiptProcessor(caver, 1000, 15);
        TransactionReceipt.TransactionReceiptData receiptData = receiptProcessor.waitForTransactionReceipt(txHash_executed.getResult());

위 소스처럼 지갑을 생성하고 RoleBasedKey로 업데이트하고 샘플에 나온 newKeyring을 encrypt하여 KeyStore를 만들어 저장해두고 그 KeyStore를 불러오는 방식으로 했습니다

위 소스를 실행했을 때 오류가 발생해서 디버깅 해보니까 feepayer 주소는 맞게 전달 된것 같은데 아래처럼 오류가 발생했습니다.

[] - 21-10-29 14:09:49:751 DEBUG org.web3j.protocol.http.HttpService:210 - {"jsonrpc":"2.0","method":"klay_sendRawTransaction","params":["0x31f90123378505d21dba00830f4240940bbcd245044c507ba1c9c3011d69b33ff3cbc7ed809430f645dcce248679dbb51024c85865bcbed9b7f8b844a9059cbb000000000000000000000000b7cc824e26fea75cb930f1036d9159eb65f73f8d0000000000000000000000000000000000000000000000000de0b6b3a7640000f847f8458207f5a0ed9df441702a903e68658e595a4a4eae54c696404af56ab602132db35b7a9ac4a04de08cdf8929d56d649c13dbf9c953f2372570e02386fb622ad4165a29c79d55946e4d6118358d76412163d3d71510a3365e32fa64f847f8458207f6a08f13d9ecc5054af6dc25bf53c6fde676b536c5dea7b929056326ac394eb878f2a06f7596493f99d23787d4b597ea5a07f4c91715b153a0eb6802e02276cbf833cc"],"id":3}
[] - 21-10-29 14:09:49:752 DEBUG org.web3j.protocol.http.HttpService:211 - --> END POST (665-byte body)
[] - 21-10-29 14:09:50:205 DEBUG org.web3j.protocol.http.HttpService:233 - <-- 200 OK https://node-api.klaytnapi.com/v1/klaytn (453ms)
[] - 21-10-29 14:09:50:206 DEBUG org.web3j.protocol.http.HttpService:294 - content-length: 79
[] - 21-10-29 14:09:50:207 DEBUG org.web3j.protocol.http.HttpService:294 - content-type: application/json
[] - 21-10-29 14:09:50:208 DEBUG org.web3j.protocol.http.HttpService:294 - date: Fri, 29 Oct 2021 05:09:49 GMT
[] - 21-10-29 14:09:50:209 DEBUG org.web3j.protocol.http.HttpService:294 - server: istio-envoy
[] - 21-10-29 14:09:50:209 DEBUG org.web3j.protocol.http.HttpService:294 - vary: Origin
[] - 21-10-29 14:09:50:210 DEBUG org.web3j.protocol.http.HttpService:294 - x-envoy-upstream-service-time: 2
[] - 21-10-29 14:09:50:211 DEBUG org.web3j.protocol.http.HttpService:276 - 
[] - 21-10-29 14:09:50:212 DEBUG org.web3j.protocol.http.HttpService:277 - {"jsonrpc":"2.0","id":3,"error":{"code":-32000,"message":"invalid fee payer"}}

fee payer 정보가 안맞는것 같은데 이건 어떤 오류인지 알 수 있을까요??

이후 오류는

[] - 21-10-29 14:09:50:213 DEBUG org.web3j.protocol.http.HttpService:284 - <-- END HTTP (79-byte body)
[] - 21-10-29 14:10:09:622 DEBUG org.web3j.protocol.http.HttpService:169 - --> POST https://node-api.klaytnapi.com/v1/klaytn
[] - 21-10-29 14:10:09:624 DEBUG org.web3j.protocol.http.HttpService:176 - Content-Type: application/json; charset=utf-8
[] - 21-10-29 14:10:09:625 DEBUG org.web3j.protocol.http.HttpService:179 - Content-Length: 78
[] - 21-10-29 14:10:09:626 DEBUG org.web3j.protocol.http.HttpService:294 - Authorization: Basic S0FTS09HTTVMMkoyTFZFSVlKVzhZS01DOmo4RFpISG5SZktkZzdub3EzR3JwWld0WGhJYjZ0SEQ2YitUeFcrVXo=
[] - 21-10-29 14:10:09:627 DEBUG org.web3j.protocol.http.HttpService:294 - x-chain-id: 1001
[] - 21-10-29 14:10:09:628 DEBUG org.web3j.protocol.http.HttpService:208 - 
[] - 21-10-29 14:10:09:629 DEBUG org.web3j.protocol.http.HttpService:210 - {"jsonrpc":"2.0","method":"klay_getTransactionReceipt","params":[null],"id":4}
[] - 21-10-29 14:10:09:630 DEBUG org.web3j.protocol.http.HttpService:211 - --> END POST (78-byte body)
[] - 21-10-29 14:10:09:656 DEBUG org.web3j.protocol.http.HttpService:233 - <-- 200 OK https://node-api.klaytnapi.com/v1/klaytn (25ms)
[] - 21-10-29 14:10:09:657 DEBUG org.web3j.protocol.http.HttpService:294 - content-length: 149
[] - 21-10-29 14:10:09:658 DEBUG org.web3j.protocol.http.HttpService:294 - content-type: application/json
[] - 21-10-29 14:10:09:659 DEBUG org.web3j.protocol.http.HttpService:294 - date: Fri, 29 Oct 2021 05:10:08 GMT
[] - 21-10-29 14:10:09:660 DEBUG org.web3j.protocol.http.HttpService:294 - server: istio-envoy
[] - 21-10-29 14:10:09:661 DEBUG org.web3j.protocol.http.HttpService:294 - vary: Origin
[] - 21-10-29 14:10:09:662 DEBUG org.web3j.protocol.http.HttpService:294 - x-envoy-upstream-service-time: 2
[] - 21-10-29 14:10:09:663 DEBUG org.web3j.protocol.http.HttpService:276 - 
[] - 21-10-29 14:10:09:664 DEBUG org.web3j.protocol.http.HttpService:277 - {"jsonrpc":"2.0","id":4,"error":{"code":-32602,"message":"invalid argument 0: json: cannot unmarshal non-string into Go value of type common.Hash"}}

이렇게 되는데 이부분은 invalid feepayer 부분이 오류가 발생했는데 호출해서 발생한것으로 보여집니다.

안녕하세요.
현재 알려주신 에러 메세지는 Fee Payer에 대한 서명 검증을 노드에서 진행 후에 실패 시에 나오는 에러 메세지입니다.

두가지를 확인해보셔야 할 것 같습니다.

  • Rolebased로 account가 정상적으로 업데이트 된 것을 확인하였는지???
    • 원하시는 키로 account가 클레이튼 네트워크 상에 업데이트가 되었는지 확인해보시기 바랍니다.
  • caver.validator.validateFeePayer() 함수를 통해서 fee payer의 서명을 검증해보시기 바랍니다.

감사합니다.

@Kale

답변 감사합니다

알려주신 validateFeePyaer() 함수로 fee payer의 서명을 검증하고 있는데 궁금한게 생겨 문의드립니다.

“klay_getAccountKey” 함수를 호출해서 얻은 응답값으로

{
    "jsonrpc": "2.0",
    "id": 3,
    "result": {
        "keyType": 5,
        "key": [
            {
                "keyType": 4,
                "key": {
                    "threshold": 2,
                    "keys": [
                        {
                            "weight": 1,
                            "key": {
                                "x": "0xbb8a45168a1f94ccd57856d5c640436a9676b363d02d98bec4e9ed0cea8d0853",
                                "y": "0x8d4a8c6f9bb9a7a40a1eac251aa12b6f27f12db5a0c14309565e75164038f1b"
                            }
                        },
                        {
                            "weight": 1,
                            "key": {
                                "x": "0xf88cca733bb1ef52d0b5266988987bba066a3800b15c8d122d2e50e57e2a5459",
                                "y": "0x6bc32f03b5fd7987685aa76026a69500961169d9fe4c0aad96d070a469ad332e"
                            }
                        }
                    ]
                }
            },
            {
                "keyType": 2,
                "key": {
                    "x": "0x8c965d2819c51a66fed2efe830fc4600a2e6da4fa626ec1e19335ce75377f642",
                    "y": "0xde59128d87c0307697073084137afc414acf8803f399444cd882596e3b6e9861"
                }
            },
            {
                "keyType": 4,
                "key": {
                    "threshold": 3,
                    "keys": [
                        {
                            "weight": 2,
                            "key": {
                                "x": "0xc0468a7b877fd65a1f148345cec2f6b7ff48aece2cfe59abdbcb2e4253f71374",
                                "y": "0xbdd77f095f790c74754e1d4b0ead509634aed1a7e6b4d2438ef0887d69ed1086"
                            }
                        },
                        {
                            "weight": 1,
                            "key": {
                                "x": "0xb0736414cae08f25e35f88b7bc5f69d32a75e29562cb04f3558e841483bf305d",
                                "y": "0x11f3cce7d1749e108d698ce49baca8fae3aa80c70b01cb2213abc8ba8944c4fa"
                            }
                        },
                        {
                            "weight": 1,
                            "key": {
                                "x": "0x46977bed09270887b510432dd7086a385686e8666185a0ee0c39fbf94b6526f5",
                                "y": "0x616881577f7501fb88a0c0c305fcdb532a9421d327f0c58477b42e6a57205bf0"
                            }
                        }
                    ]
                }
            }
        ]
    }
}

이렇게 받았습니다
이때 x, y값과 제가 테스트한 소스의 keyring의 private key가 다른것 같은데
"klay_getAccountKey"의 x, y값과 keyStore로 저장한 파일(caver.wallet.keyring.create(feePayer.getAddress(), newRoleBasedKeyList)의 리턴값을 파일로 저장)의 private key가 같아야 하나요??

getAccount를 통해 나오는 키는 public key입니다.

keyStore에 저장되어있는 private Key를 통해 public key를 생성해보시고 생성된 public key와 블록체인에 기록된 public key가 같은지 확인해보시기 바랍니다.

@Kale

네 감사합니다

알려주신대로 private key를 통해서 public key를 생성하려고 하는데 DOC를 참고하려고 합니다.
이 메소드는 caver java로 호출해보고 싶은데 어떻게 호출하는지 모르겠네요…

참고할만한 샘플이 있으면 알려주실 수 있으신가요??

RoleBasedAccount에 해당하는 KeyStore를 만들었고 이를 로딩하셨으니, RolebasedKeyring이라는 클래스로 접근하시면됩니다.

아래 문서 참고부탁드립니다.
https://javadoc.io/doc/com.klaytn.caver/core/1.6.3/com/klaytn/caver/wallet/keyring/RoleBasedKeyring.html

@Kale

알려주신 링크에서 “getKeyByRole(2)” (feePayer에 관련된 Role이라서 2로 전달)로 받은 응답값이
디버그 모드에서 확인한 private key랑 동일했습니다.

" getPublicKey" 메소드도 호출해 보았는데
위에 댓글로 작성한 public key라고 알려주신 값과 다른 값이 나왔습니다.

private key를 통해 public key를 생성하는 매소드가 없는 것 같아서 문의드립니다.

getPublicKey()가 privateKey로 부터 생성하는 메서드입니다.
getPublicKey()로 나온 값과 비교했는데 틀렸으면 Update하신 public key와 현재 Key store로 로딩한 private key가 안 맞는 것 같네요.

다시 한번 제대로 AccountUpdate를 하셔서 테스트해보시면 좋을 것 같습니다.

@Kale

또 문의드려서 죄송합니다…

알려주신대로 Account Update를 해서 테스트를 진행하였습니다.
DOC를 참고하여 RoleBasedKeyring newKeyring = caver.wallet.keyring.create(feePayer.getAddress(), newRoleBasedKeyList);로 keyring을 만들고 newKeyring.encrypt(“1q2w3e4r”);로 Keystore를 만들어서 file로 저장했습니다

{
  "address" : "0x77c8db5694685e96b0543106f28387f1fc74bb66",
  "id" : "cde44b7e-01de-452f-817b-dcc6719c491a",
  "version" : 4,
  "crypto" : null,
  "keyring" : [ [ {
    "cipher" : "aes-128-ctr",
    "ciphertext" : "37f41ebc272b618cbf65413a582302b91d2c53cd6a40c1b2853cacd0f99f7915",
    "cipherparams" : {
      "iv" : "92a34950115617af6340d9cdde7097e0"
    },
    "kdf" : "scrypt",
    "kdfparams" : {
      "dklen" : 32,
      "n" : 4096,
      "p" : 1,
      "r" : 8,
      "salt" : "a3b9505ecd8ebc94d955ee2b7791a3892b675618ee9fed25ca2c845863a8b38d"
    },
    "mac" : "ec80abdfa57c74da370bee9aea5d751a7b0fde1996363609f40815eb6674bef1"
  }, {
    "cipher" : "aes-128-ctr",
    "ciphertext" : "78803590675d0dffb84dabfc4c4c83cc4957c132e57aeab064c043f5919bd5ad",
    "cipherparams" : {
      "iv" : "92a34950115617af6340d9cdde7097e0"
    },
    "kdf" : "scrypt",
    "kdfparams" : {
      "dklen" : 32,
      "n" : 4096,
      "p" : 1,
      "r" : 8,
      "salt" : "a3b9505ecd8ebc94d955ee2b7791a3892b675618ee9fed25ca2c845863a8b38d"
    },
    "mac" : "246bf17f87feb4c385f168176531d49a899de8b9278f4622ca240aaa6bb961a9"
  } ], [ {
    "cipher" : "aes-128-ctr",
    "ciphertext" : "669ccd2f1d09e0a6d40a0b1ab223d9ae7dcabeb08862e4f74f511842c5f3e6ba",
    "cipherparams" : {
      "iv" : "92a34950115617af6340d9cdde7097e0"
    },
    "kdf" : "scrypt",
    "kdfparams" : {
      "dklen" : 32,
      "n" : 4096,
      "p" : 1,
      "r" : 8,
      "salt" : "a3b9505ecd8ebc94d955ee2b7791a3892b675618ee9fed25ca2c845863a8b38d"
    },
    "mac" : "cffc61d9c16be31be34267e4bdceb656d5c9a16a5bfb47fad0d7a9bed7750fed"
  } ], [ {
    "cipher" : "aes-128-ctr",
    "ciphertext" : "aa9103f94e3197103a332694df84d758b2c7cd664cf06eedd839d7b3c5874283",
    "cipherparams" : {
      "iv" : "92a34950115617af6340d9cdde7097e0"
    },
    "kdf" : "scrypt",
    "kdfparams" : {
      "dklen" : 32,
      "n" : 4096,
      "p" : 1,
      "r" : 8,
      "salt" : "a3b9505ecd8ebc94d955ee2b7791a3892b675618ee9fed25ca2c845863a8b38d"
    },
    "mac" : "f0c6e05123cb6a3a3b48f27f8f690ab505bd07668f04654fc5250bc7d5f5b11f"
  }, {
    "cipher" : "aes-128-ctr",
    "ciphertext" : "78d9bbb94daa6ae1de10070e9a9759963cc39bb0a0241f33a16af7d6dfd487e5",
    "cipherparams" : {
      "iv" : "92a34950115617af6340d9cdde7097e0"
    },
    "kdf" : "scrypt",
    "kdfparams" : {
      "dklen" : 32,
      "n" : 4096,
      "p" : 1,
      "r" : 8,
      "salt" : "a3b9505ecd8ebc94d955ee2b7791a3892b675618ee9fed25ca2c845863a8b38d"
    },
    "mac" : "78da7788737b24abb410babcaba002f6207a52528b84b7875481c4eb21c5a531"
  }, {
    "cipher" : "aes-128-ctr",
    "ciphertext" : "908ed6f4bd835469c586e6a37529f81455c2ae312c2e7f8691729aa092e4ca7e",
    "cipherparams" : {
      "iv" : "92a34950115617af6340d9cdde7097e0"
    },
    "kdf" : "scrypt",
    "kdfparams" : {
      "dklen" : 32,
      "n" : 4096,
      "p" : 1,
      "r" : 8,
      "salt" : "a3b9505ecd8ebc94d955ee2b7791a3892b675618ee9fed25ca2c845863a8b38d"
    },
    "mac" : "950acc450d150f15c62f921aa78a1b6ef56f5cf043abece5e58ce7f58723f779"
  } ] ]
}

그때 keystore형식은 이렇게 되고 getPublicKey()를 호출한 결과는

[
[
"04a2b9defe6909a8d6a29b0bcb1e176cbb4653fa6d2482e1aa4eb477b0c69f580a5d3fdd79243f7cbcb7248949de61d3aae9185eae5594d1191ac33c4a399635",
"1d6d31d03998992d2901e454edd638f7e8faa48154b1d360a471d9483897c9d4154a258e53ff4429ccdb3816b2447990db115545537a6148196d4f39e6348837"
],
[
"b13ea29f8e3225443deed3ec70933f49eceaa4e2f0981098f82f96e5e61e50d0e2f46c361ad2f3d34a468d617f413ae308693352059272dcd49f8cce8bee5ac7"
],
[
"51ca1f0e0309f88179fb724d673e122facae1e2bd86c3143410b2e9574dc9432eb50ee598b6c77c9fbb556310e0905992fc1cee0ae7b1443201b0aab5277f2e4",
"ccd7474dda3dc797efba07ec2bba7c63ea3fd0b98a7d883be8c03547db5751b48e877f7f5db294836d7235cd8a13ca210d35a4b3a6f6c459108e00e414da71b4",
"a15b7612aad7d2f00d86e457bcfdc60fa921dd8ecfee78b17cca59b6ec0014594d80bef3281ee25d6669a17fdc04cc1a0f9cfe1eca82cb5ee8b4426813ecd0a4"
]
]

이렇게 응답을 받았습니다.

Keystore파일로 저장한 방법이 잘못된건가요??

죄송하지만 질문의 의도를 제대로 파악을 못했습니다.

위 코드와 결과값을 봐서는 제대로 public key가 나온 것 같은데 어떤 저장하는 방법이 잘못됬다고 이야기하시는걸까요?

Rolebased keyring은 Tx key, Account update key, fee payer를 각각 가지고 있기때문에 getPublicKey()를 호출하면 List<String[]> 타입으로 리턴하게 됩니다.

getAccount를 통해서 나온 publicKey와 Role-based keyring의 getPublicKey()를 통해 나온 public key를 비교해보라는 이야기였고 그 값이 잘못되었다면 다시 Account Update를 진행하여 FeeDelegated 트랜잭션을 테스트 해보라고 이야기드린거였습니다.

@Kale

제가 제대로 질문을 드리지 못했네요… 죄송합니다

우선 말씀해주신대로 getPublicKey()를 호출하면 PublicKey를 응답으로 받는것과 keyStore 파일 안의 값과 getPublicKey()의 결과를 비교했었고 getPublicKey()를 호출하면 keyStore의 private key를 이용하여 public key로 생성하는것으로 이해했습니다.

질문의 의도는 getPublicKey()를 호출하여 응답으로 받은 값이 KeyStore로 로딩한 private key가 안맞는다고 하셨었는데 이 부분 확인을 어떻게 해야하는지 모르겠습니다.

우선 말씀해주신대로 getPublicKey()를 호출하면 PublicKey를 응답으로 받는것과 keyStore 파일 안의 값과 getPublicKey()의 결과를 비교했었고 getPublicKey()를 호출하면 keyStore의 private key를 이용하여 public key로 생성하는것으로 이해했습니다.

잘못 이해하고 있으신 것 같은데

  1. 블록체인상에 저장된 account의 public key를 klay_getAccount로 조회한 결과값
  2. KeyStore를 caver-java로 로딩한 뒤 RoleBasedKeyring의 getPublicKey()로 나온 public key

위 1, 2번이 동일해야 서명을 블록체인 상에서 검증할 때 검증이 가능합니다.

몇번 이야기드린 것 같은데
1번에 해당하는 klay_getAccount는 caver.rpc.klay.getAccount().send()를 통해서 값을 가지고와서 Account라는 클래스에 저장할 수 있습니다. 이 Account클래스를 통해 public key를 가지고오신다음

2번에 해당하는 keyring의 getPublicKey()를 통해 가져온 데이터와 비교해보시기 바랍니다.

@Kale

네 감사합니다
방금 확인해봤는데 keyring의 getPublicKey()를 통해 가져온 값이
Account클래스의 x,y값에서 "0x"가 빠진 64자리의 문자가 응답으로 오고 있습니다

keyring의 getPublicKey()를 통해 가져온 값

[ 
  [ "04a2b9defe6909a8d6a29b0bcb1e176cbb4653fa6d2482e1aa4eb477b0c69f580a5d3fdd79243f7cbcb7248949de61d3aae9185eae5594d1191ac33c4a399635", "1d6d31d03998992d2901e454edd638f7e8faa48154b1d360a471d9483897c9d4154a258e53ff4429ccdb3816b2447990db115545537a6148196d4f39e6348837" ], 
  [ "b13ea29f8e3225443deed3ec70933f49eceaa4e2f0981098f82f96e5e61e50d0e2f46c361ad2f3d34a468d617f413ae308693352059272dcd49f8cce8bee5ac7" ], 
  [ "51ca1f0e0309f88179fb724d673e122facae1e2bd86c3143410b2e9574dc9432eb50ee598b6c77c9fbb556310e0905992fc1cee0ae7b1443201b0aab5277f2e4", "ccd7474dda3dc797efba07ec2bba7c63ea3fd0b98a7d883be8c03547db5751b48e877f7f5db294836d7235cd8a13ca210d35a4b3a6f6c459108e00e414da71b4", "a15b7612aad7d2f00d86e457bcfdc60fa921dd8ecfee78b17cca59b6ec001459 4d80bef3281ee25d6669a17fdc04cc1a0f9cfe1eca82cb5ee8b4426813ecd0a4" ] 
]

Account값

{
  "id" : 0,
  "jsonrpc" : "2.0",
  "result" : {
    "type" : "0x05",
    "accountKey" : {
      "keyType" : 5,
      "key" : [ {
        "keyType" : 4,
        "key" : {
          "threshold" : 2,
          "keys" : [ {
            "weight" : 1,
            "key" : {
              "x" : "0x04a2b9defe6909a8d6a29b0bcb1e176cbb4653fa6d2482e1aa4eb477b0c69f58",
              "y" : "0x0a5d3fdd79243f7cbcb7248949de61d3aae9185eae5594d1191ac33c4a399635"
            }
          }, {
            "weight" : 1,
            "key" : {
              "x" : "0x1d6d31d03998992d2901e454edd638f7e8faa48154b1d360a471d9483897c9d4",
              "y" : "0x154a258e53ff4429ccdb3816b2447990db115545537a6148196d4f39e6348837"
            }
          } ]
        }
      }, {
        "keyType" : 2,
        "key" : {
          "x" : "0xb13ea29f8e3225443deed3ec70933f49eceaa4e2f0981098f82f96e5e61e50d0",
          "y" : "0xe2f46c361ad2f3d34a468d617f413ae308693352059272dcd49f8cce8bee5ac7"
        }
      }, {
        "keyType" : 4,
        "key" : {
          "threshold" : 3,
          "keys" : [ {
            "weight" : 2,
            "key" : {
              "x" : "0x51ca1f0e0309f88179fb724d673e122facae1e2bd86c3143410b2e9574dc9432",
              "y" : "0xeb50ee598b6c77c9fbb556310e0905992fc1cee0ae7b1443201b0aab5277f2e4"
            }
          }, {
            "weight" : 1,
            "key" : {
              "x" : "0xccd7474dda3dc797efba07ec2bba7c63ea3fd0b98a7d883be8c03547db5751b4",
              "y" : "0x8e877f7f5db294836d7235cd8a13ca210d35a4b3a6f6c459108e00e414da71b4"
            }
          }, {
            "weight" : 1,
            "key" : {
              "x" : "0xa15b7612aad7d2f00d86e457bcfdc60fa921dd8ecfee78b17cca59b6ec001459",
              "y" : "0x4d80bef3281ee25d6669a17fdc04cc1a0f9cfe1eca82cb5ee8b4426813ecd0a4"
            }
          } ]
        }
      } ]
    }
  },
  "error" : null,
  "rawResponse" : null
}

이런 경우 정상적인 케이스로 보면 되나요??

@Kale

위 링크를 참고하여 해결하였습니다