交易机制(Transaction mechanisms)
web3j支持使用以太坊钱包文件(推荐)和以太网客户端管理命令来发起一笔交易。当你创建了一个拥有以太币的账户后,你可以通过以下两种交易机制,和以太坊网络(私网/公网)交易:
- 通过以太坊客户端签名交易 - Transaction signing via an Ethereum client
- 线下签名交易 - Offline transaction signing
这里主要讲一下线下签名交易(Offline transaction signing)。线下签名交易允许你使用web3j提供的钱包账户发起交易,你完全控制自己的私钥,交易发送到网络上的其它节点并广播。
交易签名步骤
线下签名交易使用 RawTransaction 对象来完成,一共有如下几步:
1、通过私钥或密码+钱包文件(keystore)来加载转账凭证Credentials
2、获取发起转账账户的nonce 值,也就是第几笔交易
3、创建 RawTransaction交易 对象
4、签名 RawTransaction 对象,也就是对交易做签名
5、发送交易( RawTransaction 对象)给节点处理。
6、获取交易哈希值TxHash
public static void transfer() throws Exception {
Web3j web3j = Web3jFactory.build(new HttpService("https://rinkeby.infura.io/v3/5d5eff28c13d486081a28feaf45a5275"));
String from = "0x85a22B7ECC69C6E7E888BD9E9164bD3841e0E21d";
String to = "0xc706ddcd78ccd994c604770787e71d231cc66fd2";
String privateKey = "your privatekey";
BigInteger value = Convert.toWei("0.01", Convert.Unit.ETHER).toBigInteger();
//加载转账所需的凭证,用私钥
Credentials credentials = Credentials.create(privateKey);
//获取nonce,交易笔数
EthGetTransactionCount transactionCount = web3j.ethGetTransactionCount(from, DefaultBlockParameterName.LATEST).sendAsync().get();
BigInteger nonce = transactionCount.getTransactionCount();
Log.i(TAG, "transfer nonce : " + nonce);
//创建RawTransaction交易对象
RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, Contract.GAS_PRICE, Contract.GAS_LIMIT, to, value, "abc");
//签名Transaction,这里要对交易做签名
byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Numeric.toHexString(signMessage);
//发送交易
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get();
String transactionHash = ethSendTransaction.getTransactionHash();
Log.i(TAG, "transfer txhash : " + transactionHash);
}
关于Nonce
以太坊实战-再谈nonce使用陷阱:https://blog.csdn.net/wo541075754/article/details/79054937
- nonce 值用来唯一标识账户的交易,一个值只能使用一次
- nonce 值可以通过eth_getTransactionCount方法获取
- 如果一个账户使用相同的 nonce通过发起多个交易,只有一个交易会被接受,(gas price)手续费高的会覆盖手续费低的交易,如果交易费一样,后发起的交易会被拒绝。
- Transaction的 nonce 值可以为空,不指定 nonce 值由客户端自动排序赋值
- RawTransaction的 nonce 值不能为空
此外,还有一种简单的转账方式
Web3j web3j = Web3jFactory.build(new HttpService("https://rinkeby.infura.io/v3/5d5eff28c13d486081a28feaf45a5275"));
String from = "0x85a22B7ECC69C6E7E888BD9E9164bD3841e0E21d";
String to = "0xc706ddcd78ccd994c604770787e71d231cc66fd2";
String privateKey = "xxxx";
BigDecimal value = BigDecimal.valueOf(0.01);
//加载转账所需的凭证,用私钥
Credentials credentials = Credentials.create(privateKey);
TransactionReceipt transactionReceipt = Transfer.sendFunds(web3j, credentials, to, value, Convert.Unit.ETHER).sendAsync().get();
String transactionHash = transactionReceipt.getTransactionHash();
Log.i(TAG, "transfer transactionHash : " + transactionHash);
这种方式,不需要自己管理nonce。
这2种方式都是离线交易,先组装交易,然后发送到链上。
参考:
https://docs.web3j.io/getting_started.html#transactions
https://www.jianshu.com/p/6650d2a3aea9
网友评论