在上一篇文章中講解了ETH轉(zhuǎn)賬,這一篇講一下ERC-20 Token轉(zhuǎn)賬。
【ETH錢包開發(fā)03】web3j轉(zhuǎn)賬ETH
ERC-20 Token轉(zhuǎn)賬的2種方式
1、直接用web3j的API
2、java/Android調(diào)用合約的transfer
方法
不管用哪種方式來轉(zhuǎn)賬,你都需要先寫一個(gè)solidity智能合約文件來創(chuàng)建ERC-20 Token,然后部署合約,最后才是通過客戶端來調(diào)用。
web3j API轉(zhuǎn)賬ERC-20 Token
/**
* ERC-20Token交易
*
* @param from
* @param to
* @param value
* @param privateKey
* @param data 附加信息需要轉(zhuǎn)換成16進(jìn)制數(shù)
* @return
* @throws Exception
*/
public EthSendTransaction transferERC20Token(String from,
String to,
BigInteger value,
String privateKey,
String contractAddress) throws Exception {
//加載轉(zhuǎn)賬所需的憑證总寻,用私鑰
Credentials credentials = Credentials.create(privateKey);
//獲取nonce铸董,交易筆數(shù)
BigInteger nonce = getNonce(from);
//get gasPrice
BigInteger gasPrice = requestCurrentGasPrice();
BigInteger gasLimit = Contract.GAS_LIMIT;
//創(chuàng)建RawTransaction交易對(duì)象
Function function = new Function(
"transfer",
Arrays.asList(new Address(to), new Uint256(value)),
Arrays.asList(new TypeReference<Type>() {
}));
String encodedFunction = FunctionEncoder.encode(function);
RawTransaction rawTransaction = RawTransaction.createTransaction(nonce,
gasPrice,
gasLimit,
contractAddress, encodedFunction);
//簽名Transaction,這里要對(duì)交易做簽名
byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Numeric.toHexString(signMessage);
//發(fā)送交易
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get();
return ethSendTransaction;
}
/**
* 獲取nonce沉衣,交易筆數(shù)
*
* @param from
* @return
* @throws ExecutionException
* @throws InterruptedException
*/
private BigInteger getNonce(String from) throws ExecutionException, InterruptedException {
EthGetTransactionCount transactionCount = web3j.ethGetTransactionCount(from, DefaultBlockParameterName.LATEST).sendAsync().get();
BigInteger nonce = transactionCount.getTransactionCount();
Log.i(TAG, "transfer nonce : " + nonce);
return nonce;
}
注意:erc-20 token轉(zhuǎn)賬和eth轉(zhuǎn)賬的區(qū)別如下:
1肥隆、erc-20 token創(chuàng)建交易對(duì)象用的是這個(gè)方法createTransaction
2吸占、erc-20 token需要構(gòu)建Function
初厚,它其實(shí)對(duì)應(yīng)的就是erc-20 token合約中的那些方法。它的第一個(gè)參數(shù)就是ERC20中那幾個(gè)方法的名稱,第二個(gè)參數(shù)的話就是對(duì)應(yīng)合約方法中的參數(shù)僧著,第三個(gè)參數(shù)是和第二個(gè)參數(shù)對(duì)應(yīng)的皆怕,按照我那樣就行了岂津。轉(zhuǎn)賬的話就是transfer
,我們從合約的transfer
可以看到第一個(gè)參數(shù)是收款地址,第二個(gè)參數(shù)是金額,所以Function
這里對(duì)應(yīng)起來就好。
//創(chuàng)建Function對(duì)象
Function function = new Function(
"transfer",
Arrays.asList(new Address(to), new Uint256(value)),
Arrays.asList(new TypeReference<Type>() {
}));
String encodedFunction = FunctionEncoder.encode(function);
// 如下為 ERC20 Token 標(biāo)準(zhǔn)接口:-----------
// ERC20 Token Standard Interface
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// ----------------------------------------------------------------------------
contract ERC20 {
function name() constant returns (string name)
function symbol() constant returns (string symbol)
function decimals() constant returns (uint8 decimals)
function totalSupply() constant returns (uint totalSupply);
function balanceOf(address _owner) constant returns (uint balance);
function transfer(address _to, uint _value) returns (bool success);
function transferFrom(address _from, address _to, uint _value) returns (bool success);
function approve(address _spender, uint _value) returns (bool success);
function allowance(address _owner, address _spender) constant returns (uint remaining);
event Transfer(address indexed _from, address indexed _to, uint _value);
event Approval(address indexed _owner, address indexed _spender, uint _value);
}
java/Android調(diào)用合約的transfer
方法
這種方法不需要使用web3j封裝的方法拙泽,而是直接調(diào)用solidity合約的方法。
步驟
1移稳、web3j加載一個(gè)已經(jīng)部署的合約
2都许、驗(yàn)證合約是否加載成功isValid
3桨仿、如何加載合約成功伴嗡,則調(diào)用合約的transfer
方法
/**
* ERC-20Token交易(調(diào)用solidity合約方式) 推薦使用
*
* @param contractAddress 合約地址
* @param to 收款地址
* @param value 轉(zhuǎn)賬金額
* @param privateKey 私鑰
* @throws ExecutionException
* @throws InterruptedException
*/
public void transferERC20Token(String contractAddress,
String to,
BigInteger value,
String privateKey) throws ExecutionException, InterruptedException {
//加載轉(zhuǎn)賬所需的憑證,用私鑰
Credentials credentials = Credentials.create(privateKey);
TokenERC20 contract = TokenERC20.load(
contractAddress, web3j, credentials, Contract.GAS_PRICE, Contract.GAS_LIMIT);
TransactionReceipt transactionReceipt = contract.transfer(to, value).sendAsync().get();
String transactionHash = transactionReceipt.getTransactionHash();
Log.i(TAG, "transferERC20Token transactionHash : " + transactionHash);
}
注意:
1、這里的TokenERC20
是根據(jù)solidity智能合約生成的對(duì)應(yīng)的Java類,用于java/Android和智能合約交互的,如果你對(duì)這里不太清楚,不妨看看我之前的一篇文章浅碾。
以太坊Web3j命令行生成Java版本的智能合約
2埂陆、如果加載合約失敗鹃栽,可能的一個(gè)原因是合約對(duì)應(yīng)的Java類中的BINARY
的值不對(duì)蓬抄,這個(gè)值是你部署合約成功之后的bytecode阅爽,你最好檢查對(duì)比一下。
我發(fā)送一筆交易仍翰,可以通過這個(gè)地址查詢
https://rinkeby.etherscan.io/tx/0x05bd947e73068badbd9937854169f020980795da8a8182a67e9c2c1888f1874d