RoleBasedKey를 업데이트하고 해당 정보의 Keystore를 만드는 방법이 있나요?

이전 질문에 질문으로 주소에 RoleBasedKey를 업데이트에 성공했습니다

그리고 해당 feePayer Role의 프라이빗키를 가지고 서명을 하려고 했는데 "invalid feepayer"라는 에러가 발생했었는데 소스를 보니 keyStore에 RoleBasedKey로 업데이트한 정보가 없어 invalid feepayer가 발생한 것으로 생각되는데

RoleBasedKey로 업데이트하고 해당 정보를 포함한 keyStore를 만드는 방법이 있을까요?

안녕하세요

RoleBasedKeyring(이전 질문에 올려주신 소스코드 상의 newKeyring에 해당하는 키링)의 encrypt 함수를 호출하면 됩니다.

@Jamie

답변감사합니다
제가 가지고 있는 KeyStore파일이 바오밥월렛에서 만든 지갑의 KeyStore인데 이 KeyStore를 encrypt함수를 호출하면 될까요??

아니요 Keystore는 encrypt의 결과로 리턴되게 됩니다.
그러므로 바오밥 월렛에서 받은 키스토어는 업데이트 되기 전 키 정보를 포함하고 있을 것이며,
업데이트한 이후의 키 정보를 얻고자 하는 경우 새롭게 사용할 개인키를 들고있는 키링의 encrypt를 호출해야 합니다.
제가 위에 적어놨듯이 이전질문의 newKeyringencrypt를 호출하면 됩니다.

@Jamie

newKeyring의 encrypt함수를 호출해서 key가 배열로 내여로는것을 확인했습니다.

공개키가 업데이트 된 이후에 업데이트된 키 정보로 FeeDelegatedValueTransfer를 호출하려고 합니다.

말씀해주신대로 newKeyring을 encrypt를 한다면 caver.wallet.keyring.create로 매번 키값을 업데이트 해주고 그 keyring을 encrypt함수를 호출해서 해당 값으로 sign을 해주어야 하나요??

서명을 어떤 방식으로 해주고 있는지는 모르겠지만, keystore를 갖고 계시다면 그거를 caver.wallet.keyring.decrypt해서 키링을 생성할 수 있습니다.
그러면 역할 별로 사용할 키가 정의된 키링이 리턴이 되며, 이를 사용하여 sign를 하면 됩니다.

@Jamie

AbstractKeyring testKeyring = caver.wallet.keyring.decrypt(keyStore, pw);
AbstractKeyring testKeyring2 = KeyringFactory.decrypt(keyStore, "pw");

이 함수를 호출하면 역할별로 사용할 키가 정의된 키링이 리턴된다고 하셨는데
스크린샷 2021-10-19 오전 10.13.16
역할별로 키값이 리턴되지 않는 것 같습니다.

keystore파일은 아래에 작성했습니다

{
	"version": 4,
	"id": "7f7bd952-0d3a-4481-9053-e92b947bfd1f",
	"address": "0xc02336408c8dca623206d1e88904418bb3d49d18",
	"keyring": [
		{
			"ciphertext": "2dafea1e4045c58bdcaee8a85b79b938414e2996d2abbfa49e0a830f3e84cb62",
			"cipherparams": {
				"iv": "baf9802886f7720c634c52c887419a2a"
			},
			"cipher": "aes-128-ctr",
			"kdf": "scrypt",
			"kdfparams": {
				"dklen": 32,
				"salt": "3b703f5be4ac128fea4632bc14012e2ec25ebaf620a2989397b5a6d6870bd734",
				"n": 4096,
				"r": 8,
				"p": 1
			},
			"mac": "f6f9d9c9dd3c004e1f16097c9b473b537e4f6535d33f1fa1fbfa80266e86d76d"
		}
	]
}

@ToTheMoon
위에 샘플은 키가 하나만 들어있는 key store json파일인 것 같습니다.
update한 keyring의 key store정보를 저장하여 가지고 오신게 맞을까요?

encrypt이후에, Utils.printString()을 통해서 KeyStore의 정보를 console에 출력하셔서 key store파일에 복사붙여넣기 한 다음 시도해보시기 바랍니다.

그리고 질문을 해주실때는 작성자 분께서 한번 더 테스트해보고 실수한건 없는지? 문서는 찾아봤는지? 한번 더 고민해보고 질문을 작성해주시면 좋겠습니다.

@Kale

update한 keyring의 keystore정보를 가져오고 싶어서 encrypt를 했는데

String feePayerWalletFilePath = keystore 파일 경로;

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

        AbstractKeyring feePayer = KeyringFactory.decrypt(keyStore, "pw:);

// Keyring 만들기
        SingleKeyring feePayerKeyring = caver.wallet.keyring.create(feePayer.getAddress(), feePayerWalletPrivateKey);
        caver.wallet.add(feePayerKeyring);

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

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

어제 작성된 소스를 기준으로 여기까지 작성하고 newKeyring을 encrypt를 해서 keyStore를 가져오고 그 정보를 가지고 KeyringFactory.decrypt를 해야하는건가요??

네. 맞습니다.

기본적으로 caver로 접근하는 wallet은 in-memory wallet이기 때문에, Caver인스턴스를 매번 로딩할때마다 거기에 keyring을 넣어줘야합니다.

그렇기 때문에, Account를 다른 Account type으로 업데이트했을 경우, 업데이트 한 어카운트의 키링을 KeyStore형태로 encrypt 및 json파일로 저장해야되고, 이를 불러와서 사용해야합니다.

아니면, Caver 인스턴스를 생성한 뒤에, RoleBasedKeyring을 직접 작성하셔서 caver.wallet에 넣는 방법도 있습니다.

그리고 위에서도 말씀드렸지만,

질문을 남기기 전에 실수한 건 없는지, 문서는 찾아봤는지, 좀 더 직접 고민해보시고 질문을 남겨주셨으면 합니다.

감사합니다.

@Kale

네 자주 질문을 드려 죄송합니다
나름 찾아보면서 테스트한다고 테스트를 했는데 제가 부족했습니다…

답변주신 내용을 읽어보니 어제 질문드내용에서 이어서 하는 것이 아닌 다시 처음부터 계정을 새로 만들어서
update를 하고 그 업데이트한 어카운트의 키링을 json파일로 저장하고 그 json파일을 활용해서 keyring을 만들어야 한다는 말씀이시죠?