sendRawTransaction 문의

안녕하세요.

로컬에서 raw 값을 생성하고 node api의 sendRawTransaction을 통해서 값을 전송하는 테스트를 진행하고 있습니다.

그런데 전송을 시도하면 {“jsonrpc”:“2.0”,“id”:1,“error”:{“code”:-32000,“message”:"insufficient funds of the sender for value "}} 과 같은 오류가 리턴됩니다.

https://baobab.wallet.klaytn.com/ 에서 생성한 지갑의 privatekey로 진행하였고 잔고는 6.999485 KLAY가 있습니다.

accountCreated와 getBalance 함수를 호출하여 정상적으로 존재하는 것도 확인하였습니다

to에 들어가는 주소도 https://baobab.wallet.klaytn.com/ 에서 생성하였습니다.

raw값을 생성하는 코드를 하단에 첨부하였습니다.

어느 부분이 문제인지 찾기가 어려워서 문의 드리오니 도움 부탁 드립니다. ㅠㅠ

감사합니다.

    val chainId = Numeric.toHexStringWithPrefix(BigInteger.valueOf(1001))
    val privateKey = Numeric.prependHexPrefix("0x952b2eafd95dd2e53f4aca15e747bd60045a47949031a040061442b6cb58ff08")
    val input = ""
    val to = "0x06545b70b18068ccf5ee6eb5eb1f465c5dbe4f05"
    val value = Numeric.toHexStringWithPrefix(BigInteger.valueOf(10000))
    val gas = Numeric.toHexStringWithPrefix(BigInteger.valueOf(10))
    val nonce = Numeric.toHexStringWithPrefix(BigInteger.valueOf(0))
    val gasPrice = Numeric.toHexStringWithPrefix(BigInteger.valueOf(25000000000))

    val commonRlpTypeList: MutableList<RlpType> = ArrayList()
    commonRlpTypeList.add(RlpString.create(Numeric.toBigInt(nonce)))
    commonRlpTypeList.add(RlpString.create(Numeric.toBigInt(gasPrice)))
    commonRlpTypeList.add(RlpString.create(Numeric.toBigInt(gas)))
    commonRlpTypeList.add(RlpString.create(Numeric.hexStringToByteArray(to)))
    commonRlpTypeList.add(RlpString.create(Numeric.toBigInt(value)))
    commonRlpTypeList.add(RlpString.create(Numeric.hexStringToByteArray(input)))
    commonRlpTypeList.add(RlpString.create(Numeric.toBigInt(chainId)))
    commonRlpTypeList.add(RlpString.create(0L))
    commonRlpTypeList.add(RlpString.create(0L))
    val commonEncoded = RlpEncoder.encode(RlpList(commonRlpTypeList))
    val commonFinalEncoded = Numeric.toHexString(commonEncoded)

    val txRLP = Numeric.hexStringToByteArray(commonFinalEncoded)

    val forSignatureRlpTypeList: MutableList<RlpType> = ArrayList()
    forSignatureRlpTypeList.add(RlpString.create(txRLP))
    forSignatureRlpTypeList.add(RlpString.create(Numeric.toBigInt(chainId)))
    forSignatureRlpTypeList.add(RlpString.create(0L))
    forSignatureRlpTypeList.add(RlpString.create(0L))
    val hashEncoded = RlpEncoder.encode(RlpList(forSignatureRlpTypeList))
    val finalHashEncoded = Hash.sha3(Numeric.toHexString(hashEncoded))

    val keyPair: ECKeyPair = ECKeyPair.create(Numeric.toBigInt(privateKey))
    val sData: Sign.SignatureData = Sign.signMessage(
        Numeric.hexStringToByteArray(
            finalHashEncoded
        ), keyPair, false
    )

    val signData = SignatureData(sData.v, sData.r, sData.s)
    signData.makeEIP155Signature(1001)

    val finalRlpTypeList: MutableList<RlpType> = ArrayList()
    finalRlpTypeList.add(RlpString.create(Numeric.toBigInt(nonce)))
    finalRlpTypeList.add(RlpString.create(Numeric.toBigInt(gasPrice)))
    finalRlpTypeList.add(RlpString.create(Numeric.toBigInt(gas)))
    finalRlpTypeList.add(RlpString.create(Numeric.hexStringToByteArray(to)))
    finalRlpTypeList.add(RlpString.create(Numeric.toBigInt(value)))
    finalRlpTypeList.add(RlpString.create(Numeric.hexStringToByteArray(input)))
    val signatureData: SignatureData = signData
    finalRlpTypeList.addAll(signatureData.toRlpList().values)
    val finalEncoded = RlpEncoder.encode(RlpList(finalRlpTypeList))
    val finalRaw = Numeric.toHexString(finalEncoded)

    println("Raw : $finalRaw")

안녕하세요. 클레이튼 포럼에 질문을 남겨주셔서 감사드립니다.

Legacy Transaction Type으로 KLAY전송을 해보고 싶으신 것 같은데요.

위 코드를 살펴보면 Transaction의 signature를 만들기 위한 로직이 잘못된 것 같습니다.

Legacy Transaction은 from필드가 없어서, Signature에서 address를 추출하여 검증을 하게되는데요. Signature가 틀리면 추출되는 address가 달라지게 됩니다.

https://docs.klaytn.com/klaytn/design/transactions/basic#rlp-encoding-for-signature
위 링크의 내용을 참고해보시면 좋을 것 같습니다.

추가질문이 있으면 편하게 질문 부탁드립니다. :slight_smile:

감사합니다.

1개의 좋아요