안녕하세요.
Medium을 보고 ERC6551 토큰바운드 관련해서 테스트를 진행하고 있습니다
문서대로 deploy를 진행하고 transfer를 하고 싶어서 샘플을 만들고 있습니다
HttpService httpService = new HttpService(caverKasNodeUrl);
httpService.addHeader("Authorization", okhttp3.Credentials.basic(accessKey, secretAccessKey));
httpService.addHeader("x-chain-id", kasChainId);
// web3j 객체생성
Web3j web3j = Web3j.build(httpService);
// NFT 컨트랙트 주소 토큰 ID, 구현 주소 설정
String nftAddress = "0x5b7277160ad5c8ece803d7b9639f01469ebd79ff"; // ERC6551 배포하면서 만든 ERC721 Contract
BigInteger tokenId = BigInteger.valueOf(2);
String implementationAddress = "0xd1e41543089265d80cf0c15b952cbca4af1a9cf3"; // Account Contract Address
// ERC20 token 컨트랙트 주소, 수신자 주소, 전송할 토큰 양 설정
String erc20Address = "0x8a29c80c512ec6284ffaa8cb79fbf52cfc240b98"; // ERC20 Contract 주소
String receiverAddress = "0xd0ebb148db719bf24a7033acdcffaf18bcb68b1d"; // 받는사람
BigInteger tokenAmount = BigInteger.valueOf(100); // NFT 구매금액
// ERC6551 Registry 컨트랙트의 account 함수를 호출하여 TokenBoundAccount 주소를 얻음
Function accountFunction = new Function(
"account",
Arrays.asList(new Address(implementationAddress), new Uint256(1001), new Address(nftAddress), new Uint256(tokenId), new Uint256(0)),
Arrays.asList(new TypeReference<Address>() {})
);
log.info("======== accountFunction : {}", objectToString(accountFunction));
String encodedAccountFunction = FunctionEncoder.encode(accountFunction);
log.info("======== encodedAccountFunction : {}", objectToString(encodedAccountFunction));
// to : ERC6551Registry 컨트랙트 주소
EthCall ethCall = web3j.ethCall(
Transaction.createEthCallTransaction(null, "0x16159d0a1901350989bd7174614436686b606a07", encodedAccountFunction),
DefaultBlockParameterName.LATEST
).send();
log.info("======== ethCall : {}", objectToString(ethCall));
String tokenBoundAccountAddress = (String) FunctionReturnDecoder.decode(
ethCall.getValue(),
accountFunction.getOutputParameters()
).get(0).getValue();
log.info("======= tokenBoundAccountAddress : {}", tokenBoundAccountAddress);
// Account 조회 종료
// TokenBoundAccount 주소를 사용하여 Contract 객체 생성
Credentials credentials = Credentials.create("0xf6Defb44d5d4EB3d3ef31631AFF16436cBf2d6c3"); // 메타마스크 지갑주소의 PrivateKey
TransactionManager transactionManager = new RawTransactionManager(web3j, credentials);
ERC6551Account erc6551Account = ERC6551Account.load(
tokenBoundAccountAddress,
web3j,
transactionManager,
BigInteger.valueOf(20000000),
BigInteger.valueOf(250_000_000_000L)
);
// ERC20 token의 transfer 함수에 대한 ABI 인코딩된 데이터 생성
Function transferFunction = new Function(
"transfer",
Arrays.asList(new Address(receiverAddress), new Uint256(tokenAmount)),
Collections.emptyList()
);
String encodedTransferFunction = FunctionEncoder.encode(transferFunction);
byte[] data = Numeric.hexStringToByteArray(encodedTransferFunction);
// Contract 객체의 execute 함수를 호출하여 ERC20 token의 transfer 함수를 실행
TransactionReceipt transactionReceipt = erc6551Account.execute(
erc20Address,
BigInteger.ONE,
data,
BigInteger.ZERO,
BigInteger.valueOf(20000000)
).send();
erc6551Account.execute 부분은
public RemoteFunctionCall<TransactionReceipt> execute(String to, BigInteger value, byte[] data, BigInteger operation, BigInteger weiValue) {
final Function function = new Function(
FUNC_EXECUTE,
Arrays.<Type>asList(new org.web3j.abi.datatypes.Address(160, to),
new org.web3j.abi.datatypes.generated.Uint256(value),
new org.web3j.abi.datatypes.DynamicBytes(data),
new org.web3j.abi.datatypes.generated.Uint256(operation)),
Collections.<TypeReference<?>>emptyList());
return executeRemoteCallTransaction(function, weiValue);
}
이런식으로 구현했습니다.
위의 샘플처럼 "transfer"를 execute를 호출하였는데
java.lang.RuntimeException: Error processing transaction request: invalid gas price. It must be set to value greater than or equal to baseFee
at org.web3j.tx.TransactionManager.processResponse(TransactionManager.java:162)
at org.web3j.tx.TransactionManager.executeTransaction(TransactionManager.java:81)
at org.web3j.tx.ManagedTransaction.send(ManagedTransaction.java:127)
at org.web3j.tx.Contract.executeTransaction(Contract.java:364)
at org.web3j.tx.Contract.executeTransaction(Contract.java:347)
at org.web3j.tx.Contract.executeTransaction(Contract.java:341)
at org.web3j.tx.Contract.lambda$executeRemoteCallTransaction$4(Contract.java:412)
at org.web3j.protocol.core.RemoteCall.send(RemoteCall.java:42)
처럼 오류가 발생하였습니다.
어느 부분을 수정해야하는지 문의드립니다.