Reputation: 147
I want to transfer erc20 tokens from one account to another. I know that I can use transfer or transferFrom function of smart contract wrapper class. But in my case, erc20 token transaction is needed to be signed at client side. And there is no way to pass signedTransaction in smart contract wrapper functions. So, how can I sign erc20 token transaction and perform the transaction using web3j in java.
I found this similar problem. But, its code is not written in java. And I don't know how to encode transfer function in ABI. Send ERC20 token with web3
Thanks in advance.
Upvotes: 4
Views: 2181
Reputation: 2140
it's a bit late but maybe will hep someone:
You can try this:
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.Bool;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Function;
// create credentials
String privateKeyHexValue = Numeric.toHexString(privateKey.data());
Credentials credentials = Credentials.create(privateKeyHexValue);
// get the next available nonce
EthGetTransactionCount ethGetTransactionCount = web3.ethGetTransactionCount(credentials.getAddress(), DefaultBlockParameterName.LATEST).send();
BigInteger nonce = ethGetTransactionCount.getTransactionCount();
// Value to transfer (ERC20 token)
BigInteger balance = Convert.toWei("1", Convert.Unit.ETHER).toBigInteger();
// create transfer function
Function function = transfer(dstAddress, balance);
String encodedFunction = FunctionEncoder.encode(function);
// Gas Parameters
BigInteger gasLimit = BigInteger.valueOf(71000); // you should get this from api
BigInteger gasPrice = new BigInteger("d693a400", 16); // decimal 3600000000
// create the transaction
RawTransaction rawTransaction =
RawTransaction.createTransaction(
nonce, gasPrice, gasLimit, < ERC20_CONTRACT_ADDRESS >, encodedFunction);
// sign the transaction
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Numeric.toHexString(signedMessage);
// Send transaction
EthSendTransaction ethSendTransaction = web3.ethSendRawTransaction(hexValue).sendAsync().get();
String transactionHash = ethSendTransaction.getTransactionHash();
and transfer function could be:
private Function transfer(String to, BigInteger value) {
return new Function(
"transfer",
Arrays.asList(new Address(to), new Uint256(value)),
Collections.singletonList(new TypeReference<Bool>() {
}));
}
Upvotes: 5