TransactionReceipt값에 Null이 출력되는 문제가 있습니다

안녕하세요 :slight_smile:

현재 KRC 기반의 토큰을 Fee Delegation을 사용하여 전송해보는 테스트 중에 있습니다.

JAVA 11
Caver-JAVA 1.0.2

를 사용하여 개발 중이며

Caver caver = Caver.build(apiUrl);
KlayCredentials credentials = KlayCredentials.create(fromPK);
Function function = new Function(
“transferFrom”,
Arrays.asList(
new Address(fromAddress),
new Address(toAddress),
new Uint256(sendValue)
), // inputParameters
Collections.emptyList() // outputParameters
);
String data = FunctionEncoder.encode(function);
TransactionManager transactionManager = new TransactionManager.Builder(caver, credentials).setChaindId(ChainId.MAINNET).build();
SmartContractExecutionTransaction smartContractExecution =
SmartContractExecutionTransaction.create(
credentials.getAddress(), // fromAddress
tokenContractAddress, // contractAddress
BigInteger.TEN, // value
Numeric.hexStringToByteArray(data), // data
BigInteger.valueOf(300_000) // gasLimit
);
String senderRawTransaction = transactionManager.sign(smartContractExecution, true).getValueAsString();
log.debug("]-----] senderRawTransaction [-----[ {}", senderRawTransaction);
KlayCredentials feePayer = KlayCredentials.create(
“feePrivateKey”,
“feeAddress”
);
FeePayerManager feePayerManager = new FeePayerManager.Builder(caver, feePayer).setChainId(ChainId.MAINNET).build();
feePayerManager.executeTransaction(senderRawTransaction);

기능 구현을 위해 상기 코드를 사용하여 메인넷에서 테스트 해보던 도중 지속적으로 Transaction Receipt값이 Null이 출력되고 있는 에러를 마주하게 되었으며,

해당 에러에 대한 확실한 원인을 파악하지 못해 조언을 부탁드리게 되었습니다.

감사합니다.

1개의 좋아요

안녕하세요. 먼저 클레이튼 포럼에 질문을 남겨주셔서 감사합니다. :slight_smile:

알려주신 샘플코드로 테스트해보니 문제없이 Transaction Receipt 값이 생성되었습니다.

알려주신 상황으로 추측을 해보면 Klaytn network로 전달된 트랜잭션이 블록에 기록되기 전에 PollingTransactionReceiptProcessor가 동작을 마쳤기때문에 생기는 문제로 보입니다.

위 코드를 기준으로 Transaction receipt을 가지고오기 위해서 feePayerManager.executeTransaction(senderRawTransaction);

를 실행하면 FeePayerManager의 TransactionReceiptProcessor instance의 waitTransactionReceipt을 호출하게 됩니다.

FeePayManager의 Instance를 생성 시, TranasctionReceiptProcessor를 따로 Setter function을 통해 설정하지않으면 PollingTransactionReceiptProcessor instance를 자동으로 생성하여 설정하는데

이 PollingTransactionReceiptProcessor는 주어진 주기 및 횟수를 기준으로
특정 시간의 주기로 getTransactionReceipt를 호출하여 TransactionReceipt을 가지고 오기위해 시도합니다.

결론은, FeePayerManager의 자동으로 생성된 PollingTranasctionReceiptProcessor는 1초 주기로 총 15회의 getTransactionReceipt를 호출하게됩니다.

아래코드는 1초 주기로 30회를 getTransactionReceipt을 호출하는 PollingTransactionReceiptProcessor를 FeePayerManager에 등록하는 코드입니다.

TransactionReceiptProcessor transactionReceiptProcessor = new PollingTransactionReceiptProcessor(caver, 1000, 30);
FeePayerManager feePayerManager = new FeePayerManager.Builder(caver, feePayer)
            .setChainId(LOCAL_CHAIN_ID)
            .setTransactionReceiptProcessor(transactionReceiptProcessor)
            .build();

위 코드와 같이 PollingTransactionReceiptProcessor의 설정값을 조절해서 다시 한번 테스트 부탁드립니다.

1개의 좋아요

친절한 답변 감사드립니다 :slight_smile:
블록 기록과 PollingTransactionReceiptProcessor 간의 싱크에서 오는 문제였군요.
에러 때문에 헤매고 있었는데 덕분에 해결할 수 있었습니다.
다시 한번 감사드립니다.

1개의 좋아요

안녕하세요. 우선 친절한 답변 정말 감사합니다 :slightly_smiling_face:

Caver caver = Caver.build(apiUrl);
KlayCredentials credentials = KlayCredentials.create(fromPK);
Function function = new Function(
“transferFrom”,
Arrays.asList(
new Address(fromAddress),
new Address(toAddress),
new Uint256(sendValue)
), // inputParameters
Collections.emptyList() // outputParameters
);
String data = FunctionEncoder.encode(function);
TransactionManager transactionManager = new TransactionManager.Builder(caver, credentials).setChaindId(ChainId.MAINNET).build();
SmartContractExecutionTransaction smartContractExecution =
SmartContractExecutionTransaction.create(
credentials.getAddress(), // fromAddress
tokenContractAddress, // contractAddress
BigInteger.TEN, // value
Numeric.hexStringToByteArray(data), // data
BigInteger.valueOf(300_000) // gasLimit
);
String senderRawTransaction = transactionManager.sign(smartContractExecution, true).getValueAsString();
log.debug("]-----] senderRawTransaction [-----[ {}", senderRawTransaction);
KlayCredentials feePayer = KlayCredentials.create(
“feePrivateKey”,
“feeAddress”
);
TransactionReceiptProcessor transactionReceiptProcessor = new PollingTransactionReceiptProcessor(caver, 1000, 30);
FeePayerManager feePayerManager = new FeePayerManager
.Builder(caver, feePayer)
.setTransactionReceiptProcessor(transactionReceiptProcessor)
.setChainId(ChainId.MAINNET).build();
feePayerManager.executeTransaction(senderRawTransaction);

도움 주신 코드로 테스트해본 결과 정상적으로 블록이 생성되는 것을 확인할 수 있었습니다.
하지만 해당 코드로 TransferFrom 메소드를 실행한 결과 “Fail : ErrExecutionReverted - uint(0x09)” 에러가 출력 됩니다.
따라서, 아래 두 가지 내용에 대해 문의 드리고자 합니다.
1.토큰 전송 시 트랜잭션 Sender의 서명 후 FeePayer의 서명을 진행하였는데
혹시, 해당 순서로 인해 "Fail : ErrExecutionReverted - uint(0x09)"에러가 출력된 것인지 궁금합니다.
2.만약 1번 문제가 아니라면 어떤 이유로 “Fail : ErrExecutionReverted - uint(0x09)” 에러가 출력 되는 것인지 궁금합니다.

다시 한번 빠른 답변 감사합니다 :slightly_smiling_face:

============================================================

더불어, 테스트 Transaction Hash Value 첨부드리니 참고 부탁드립니다. (https://scope.klaytn.com/tx/0x3f5341995c2a87b82c6d6015e34a8f4f35470d40715ae3b7e9ab46bd4e81c8bc?tabId=internalTx)

1개의 좋아요

Transaction Error code 0x09는 Smart contract의 function을 실행하다가 생긴 에러입니다.

1번 질문과는 관련없는 내용입니다.

Smart contract의 function을 실행하기 위한 조건을 다시한번 확인해봐주시면 감사하겠습니다.

2개의 좋아요

네 감사합니다 :slight_smile: Smart Contract의 Function 을 다시한번 확인해보도록 하겠습니다.

2개의 좋아요