안녕하세요 대냡용 계정을 만들어서 Caver-js로 사이닝 한 이후 Raw transaction 을 보내면 사이닝v,r,s가 맞지 않다고 합니다

SDK : Caver-js 1.3.1

Role based account 를 만들때 update key, tx key, fee payer key를 따로 저장하진 않고 ( Console.log 로 키를 따로 메모장에 저장해놓지 않았음 ) Account update 를 진행했습니다.

Signing 을 From to , Feepayer address 를 지정해서 한 후
Caver-js 를 사용하여 feePayerSignTransaction 을 한 이후 ( 물론 Caver -js 에 대납계정은 Wallet.add로 저장해놓았습니다. ) sendSignedTransaction 을 실행했더니

Error: Returned error: invalid transaction v, r, s values of the sender
라는 메시지가 나옵니다.

이럴땐 어떻게 해결해야 하나요?

추가 : 아님 SDK 에서 RoleBased Feepayer 키를 따로 구할 수 있는 방법이 있나요??
추가 : Wallet add 된 Account는 readsync 로 Role based로 업데이트 된 Account 의 키스토어에서 직접 읽어서
SDK로 decrypt 이후 memory wallet 에 add 했습니다.

안녕하세요,

클레이튼 포럼에 질문을 올려주셔서 감사드립니다.

일단 해당 에러는 sender의 서명이 잘못되었다는 메시지입니다.

account update이후에 해당 키들을 wallet.add()로 기존 키를 변경해야 하는데 이 부분이 진행되지 않은 것 같습니다.

  1. key 생성
  2. account update transaction 생성 및 서명 (기존 키로)
  3. wallet.add()를 통해 새로 생성된 키를 기존 주소와 연결
  4. value transfer transaction 실행

순으로 실행하셔야 하는데, 3번이 빠지지 않았나 생각합니다. 확인 부탁드립니다.

감사합니다.

안녕하세요.
답변 감사합니다.

Account update는 transaction 보내는 것과 따로 구현되었어요.
예를 들어 Account update 는 accup.js
fee delegation transaction 보내는 곳은 feedel.js 입니다.

feedel.js가 실행되지 않은 상태 ( wallet add가 메모리 상에 없는 경우)
에서 accup.js 를 먼저 실행하고
이후 Role based 로 update 된 acc를 feedel.js 에 정보를 넣어서 실행하면 ( 아마 klay docs에 관련된 내용이 있었던 걸로 기억해요 )
Error: Returned error: invalid transaction v, r, s values of the sender

라고 메시지가 나옵니다.

혹시나 해서 feedel.js 에 wallet add를 한 이후 Privatekey를 로그로 불러보니
update 하기 이전의 Private key만 나오더라구요
Key 가 세개가 나오질 않습니다.

참고로 말씀드리자면 Sender의 unlock과 signing 은 JSON RPC call로 실행했습니다.
Fee payer 부분은 raw tx hash만 받아서 처리합니다.

실행한 코드를 보여주셔야 좀 더 이해가 쉬울 것 같습니다. 해당 코드 부분을 보여주실 수 있으실지요?

1 Like

넵 잠시만요
기다려주세용 ㅠㅜㅠ ㅎㅎ

혹시 SDK 에서 Rolebased key account 의 Fee payer key 는 가져올 수 없나요?

let feePayerKeystoreFile = fs.readFileSync(config.walletDirectory+'/'+config.feePayerKeystoreFile)
let feePayerAccount = caver.klay.accounts.decrypt(feePayerKeystoreFile.toString(), config.feePayerKeystorePass)
console.log("fee acc priv ", feePayerAccount.privateKey)
caver.klay.accounts.wallet.add(feePayerAccount.privateKey, feePayerAccount.address);
caver.klay.accounts.feePayerSignTransaction(rawTransactionHash, 
feePayerAccount.address).then((signedTransaction) => {

console.log(new Date().toLocaleString('en-US',{timeZone: 'Asia/Seoul'}), "Signed TX : " +req.url,JSON.stringify(signedTransaction),"\n");
caver.klay.sendSignedTransaction(signedTransaction).then(function(transactionReceipt){

console.log(new Date().toLocaleString('en-US',{timeZone: 'Asia/Seoul'}), "Daemon RESPONSE: " + req.url,JSON.stringify(transactionReceipt),"\n");

return res.status(200).json(transactionReceipt)	

			})
}

입니다

제가 단 댓글이 업데이트 되었어요.
바쁘신 와중에 실례지만 한번 더 확인 부탁드려도 될까요? ㅠ

let feePayerKeystoreFile = fs.readFileSync(config.walletDirectory+'/'+config.feePayerKeystoreFile)
let feePayerAccount = caver.klay.accounts.decrypt(feePayerKeystoreFile.toString(), config.feePayerKeystorePass)
console.log("fee acc priv ", feePayerAccount.privateKey)
caver.klay.accounts.wallet.add(feePayerAccount.privateKey, feePayerAccount.address);
caver.klay.accounts.feePayerSignTransaction(rawTransactionHash, 
feePayerAccount.address).then((signedTransaction) => {

console.log(new Date().toLocaleString('en-US',{timeZone: 'Asia/Seoul'}), "Signed TX : " +req.url,JSON.stringify(signedTransaction),"\n");
caver.klay.sendSignedTransaction(signedTransaction).then(function(transactionReceipt){

console.log(new Date().toLocaleString('en-US',{timeZone: 'Asia/Seoul'}), "Daemon RESPONSE: " + req.url,JSON.stringify(transactionReceipt),"\n");

return res.status(200).json(transactionReceipt)	

			})
}

입니다

안녕하세요. 위에도 말씀드렸지만, fee payer 서명이 문제가 아니고 sender의 서명이 문제입니다.

주신 코드는 fee payer가 서명하는 코드만 들어있는 것 같습니다. Signed transaction은 어떻게 생성하셨나요?

아… RPC로 생성했는데
보내는 주소도 Role based account 였거든요 ㅠㅠ

감사합니다.
한번 테스트 해볼게요 ㅋㅋ
sender의 주소가 role based account 면 에러가 난다는 말씀이신거죠?

질문이 하나 더 있습니다.
제가 썼던 Sender의 role based account 는
feepayer의 role based account 와는 다른 것이거든요

그래도 에러가 발생하나요?

Fee payer 주소를 넣고 서명하실 때, 해당 주소의 fee payer role로 서명하셔야 합니다. Fee payer 서명에 실패하실 경우,
아래와 같이, 유사해보이지만 다른 에러 메시지보실 수 있습니다.

invalid transaction v, r, s values of the fee layer

그렇다면 제가 첨부드린 코드에서는 별다르게 오류가 보이지 않는거죠?
SDK 에서는 Fee payer role key만을 가져올 수는 없는거구요…

헤헤 일반 레거시 어카운트를 Sender 로 하니까 잘 됩니다.
감사합니다.
좋은 주말 보내세요. :slight_smile:

1 Like

안녕하세요, docs에는 wallet에 관련 함수가 없긴 하네요. caver.wallet.getKeyring(“0xaddr”)함수를 이용하시면 주소를 기반으로 해당 계정의 키를 얻어오실 수 있습니다. 이 함수로는 전체 role을 얻어올테고, 이 중 3번째 role이 fee payer role이 됩니다.

감사합니다.

1 Like

안녕하세요 콜린님?
v3 버전으로 Keystore를 쓰니까 caver.wallet.getKeyring(“0xaddr”) 으로는 Role based key 를 가져올수 없습니다. ( EN 노드 V 1.3.0 , Baobab 기준)
이부분 어떻게 해결해야 될지 여쭤봐도 될까요??

처음 생성시 fee delegation privatekey를 저장해놓고 쓰는 방법 밖에는 없나요?

안녕하세요,

아래 함수를 사용해서 가능한지 확인 부탁드리겠습니다.

아 제가 설명을 드리지 않은 부분이 있군요 ㅠㅠ 죄송합니다.
sdk를 1.5.0 버전으로 바꾸고 테스트를 해보니 single key로 나오더라고요.

그래서 여쭤봤습니다.

재스민님께도 여쭤봤는데 아직 말씀이 없으셔서요 ㅠㅠ ㅎㅎ