logo资料库

ETH钱包操作文档(使用web3j实现).doc

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
1. 引入 pom 文件 org.web3j core 4.5.5 2. https://infura.io/测试网站 web3j 的 api 获取测试币种步骤 https://www.jianshu.com/p/89aa70bdbb4d https://twitter.com/中的账号 2270506143@qq.com 密码*****.com 3. 测试 url 获取步骤 进入 https://infura.io/docs 使用邮箱注册 账号密码:lpn199501@gmail.com/Admin1@dxoption 4. java 代码如下: 代码中的 url:https://rinkeby.infura.io/v3/603a3ce24ee04e32a1201a6a9e1072cf package com.common.wallet.client.impl; import com.common.wallet.client.ICoinClient; import com.common.wallet.dto.TransactionsDTO; import com.common.wallet.dto.WalletBalanceDTO; import com.common.wallet.dto.WalletGetAddressDTO; import com.common.wallet.dto.WalletSendToAddressDTO; import com.common.wallet.util.*; import com.common.wallet.vo.TransactionVO; import com.common.wallet.vo.WalletGetAddressVO; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.web3j.crypto.*; import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.DefaultBlockParameterName; import org.web3j.protocol.core.methods.response.EthBlock; import org.web3j.protocol.core.methods.response.Transaction; import org.web3j.protocol.http.HttpService; import org.web3j.utils.Convert; import org.web3j.utils.Numeric; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; @Slf4j public class EthCoinClient implements ICoinClient{ private Web3j web3j = null; public EthCoinClient(String url) { web3j = Web3j.build(new HttpService(url)); } /** * 获取转账地址 * @param walletGetAddressDTO * @return */ @Override public DataModel walletGetAddressDTO) { try { getGetNewAddress(WalletGetAddressDTO log.info("ETH 系 列 进 入 获 取 转 账 地 址 getGetNewAddress 方 法 {}", walletGetAddressDTO.toString()); final ECKeyPair keyPair = Keys.createEcKeyPair(); final org.web3j.crypto.Credentials credentials = org.web3j.crypto.Credentials.create(keyPair); final String passphrase = credentials.getEcKeyPair().getPrivateKey().toString(16); final String address = credentials.getAddress(); return new DataModel<>(ResultStatusEnum.OK,new WalletGetAddressVO(address,passphrase)); } catch (Exception e) { log.error("ETH 系列钱包服务(getGetNewAddress)方法出错{}", e);
return new DataModel<>(ResultStatusEnum.WALLET_GETADDRESS_ERROR); } } /** * 验证转账地址 * @param address * @return */ @Override public DataModel validateAddress(String address) { try { log.info("ETH 系列进入验证转账地址 validateAddress 方法{}",address); boolean isValid = false; if (isValidAddress(address)) { isValid = true; } return new DataModel<>(ResultStatusEnum.OK,isValid); } catch (Exception e) { log.error("ETH 系列验证转账地址(validateAddress)方法出错{}", e); return new DataModel<>(ResultStatusEnum.WALLET_VALIDATEADDRESS_ERROR,false); } } /** * 通过 private key 生成 credentials */ public static Credentials generateCredentials(String privateKey) { return Credentials.create(privateKey); } /** * 转账 * @param walletSendToAddressDTO fromAddress 转出地址,Amount 转出数量,ToAddress 转入地址,PrivateKey 转出地址私钥 * @return */ @Override public DataModel sendToAddress(WalletSendToAddressDTO walletSendToAddressDTO) { try { log.info("ETH 系 列 进 入 验 证 转 账 validateAddress 方 法 , 转 账 数 据 {}",walletSendToAddressDTO.toString());
BigInteger nonce = web3j.ethGetTransactionCount(walletSendToAddressDTO.getFromAddress(), DefaultBlockParameterName.PENDING).send().getTransactionCount(); /*BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice(); BigInteger gasLimit = BigInteger.valueOf(21000L);*/ //支付该笔交易每个单元的 gas 的价格,单位是 wei(将 BigDecimal 转换成 wei) = Convert.toWei(walletSendToAddressDTO.getGasPrice(), BigInteger gasPrice Convert.Unit.GWEI).toBigInteger(); //支付该笔交易最大数量的 gas(将 BigDecimal 转换成 wei) BigInteger = Convert.toWei(walletSendToAddressDTO.getGasLimit(), gasLimit Convert.Unit.GWEI).toBigInteger(); //转账数量(数量乘以 18 次幂) BigInteger amountWei = Convert.toWei(walletSendToAddressDTO.getAmount(), Convert.Unit.ETHER).toBigInteger(); RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, walletSendToAddressDTO.getToAddress(), amountWei, ""); byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, generateCredentials(walletSendToAddressDTO.getPrivateKey())); String = web3j.ethSendRawTransaction(Numeric.toHexString(signMessage)).sendAsync().get().getTransac tionHash(); result return new DataModel<>(ResultStatusEnum.OK,result); } catch (Exception e) { log.error("ETH 系列转账(sendToAddress)方法出错{}", e); return new DataModel<>(ResultStatusEnum.WALLET_SENDTOADDRESS_ERROR); } } /** * 根据 txid 查询用户交易信息 * @param txId * @return */ @Override public DataModel getTransaction(String txId) { try { log.info("ETH 系列查询用户交易信息 getTransaction 方法,txid{}",txId); Transaction transaction =
web3j.ethGetTransactionByHash(txId).send().getTransaction().get(); TransactionVO transactionVO = new TransactionVO(); transactionVO.setToAddress(transaction.getTo()); transactionVO.setCategory("ETH"); ///转账数量,数量除以 1 的 18 次幂 BigDecimal amount = Convert.fromWei(String.valueOf(transaction.getValue()), Convert.Unit.ETHER); transactionVO.setAmount(amount); transactionVO.setTxId(transaction.getHash()); return new DataModel<>(ResultStatusEnum.OK, transactionVO); } catch (Exception e) { log.error("ETH 系列查询用户交易信息(getTransaction)方法出错{}", e); return new DataModel<>(ResultStatusEnum.WALLET_GETTRANSACTIONBYTXID_ERROR); } } /** * 根据钱包 id 查询,拉取交易信息 * @return count 系统累加区块高度,numberPlus 要查询区块的数量 */ @Override public DataList listTransactions(TransactionsDTO transactionsDTO) { try { log.info("ETH 系列拉取交易信息方法{}", transactionsDTO.toString()); //获取当前块高度 BigInteger currentBlockNumber = web3j.ethBlockNumber().send().getBlockNumber(); //查询区块的截止位置(系统累加区块高度 ount+查询区块数量 numberPlus) = BigInteger lastBlockNumber BigInteger.valueOf(transactionsDTO.getCount()+transactionsDTO.getNumberPlus()); //查询的区块高度 if (lastBlockNumber.compareTo(currentBlockNumber) > 0) { log.error(">>>>系统累加区块高度:" + transactionsDTO.getAccount() + ", "ETH 区块高度:" + currentBlockNumber 缓冲区块高度:" + lastBlockNumber + ",大于当前" + + "跳出拉取<<<<"); return new DataList(ResultStatusEnum.WALLET_LISTTRANSACTIONS_ETH_HEIGHT_ERROR); } long futureBlockNum = lastBlockNumber.intValue() + 1; List list = new ArrayList();
//遍历区块 for (int i = transactionsDTO.getCount(); i < futureBlockNum; i++) { //获取 block EthBlock.Block block web3j.ethGetBlockByNumber(DefaultBlockParameter.valueOf(BigInteger.valueOf(i)), true).send().getBlock(); if (block == null) { continue; } // 遍历 block 中的交易 for (EthBlock.TransactionResult tx : block.getTransactions()) { if (tx instanceof EthBlock.TransactionObject) { //transaction: 块中的单笔交易 EthBlock.TransactionObject transaction (EthBlock.TransactionObject) tx; TransactionVO transactionVO = new TransactionVO(); transactionVO.setToAddress(transaction.getTo()); transactionVO.setCategory("ETH"); //转账数量,数量除以 1 的 18 次幂 BigDecimal amount Convert.fromWei(String.valueOf(transaction.getValue()), Convert.Unit.ETHER); transactionVO.getAmount()); transactionVO.setAmount(amount); transactionVO.setFromAddress(transaction.getFrom()); log.debug(transactionVO.getToAddress() + "\t" transactionVO.setTxId(transaction.getHash()); list.add(transactionVO); = = = + } } } if(list.size() > 0){ return new DataList(ResultStatusEnum.OK,list); } return new DataList(ResultStatusEnum.WALLET_LISTTRANSACTIONS_IS_NULL); } catch(Exception e){ log.error("ETH 系列拉取交易信息(listTransactions)方法出错{}", e); return new DataList(ResultStatusEnum.WALLET_LISTTRANSACTIONS_ERROR); } }
/** * 当前区块高度查询 * @return */ @Override public DataModel getBlockCount() { try { log.info("ETH 系列拉取交易信息方法!"); BigInteger ethBlockNumber = web3j.ethBlockNumber().send().getBlockNumber(); return new DataModel(ResultStatusEnum.OK,ethBlockNumber); } catch (Exception e) { log.error("ETH 系列钱包获取区块高度(getBlockCount)方法出错{}", e); return new DataModel<>(ResultStatusEnum.WALLET_GETBLOCKCOUNT_ERROR); } } /** * 查询区块差(当前区块-交易所在区块+1) * @param txId * @return */ @Override public DataModel getBlockDiffer(String txId) { try { log.info("ETH 系列查询区块差方法,txId{}",txId); DataModel dataModelBlock = this.getBlockCount(); if(dataModelBlock.getCode() != ResultStatusEnum.OK.getCode()){ return dataModelBlock; } BigInteger blockCount = (BigInteger)dataModelBlock.getModel(); Transaction transaction web3j.ethGetTransactionByHash(txId).send().getTransaction().get(); = blockCount = blockCount.subtract(transaction.getBlockNumber()).add(new BigInteger("1")); return new DataModel<>(ResultStatusEnum.OK,blockCount); } catch (Exception e) { log.error("ETH 查询区块差,交易信息(getBlockCount)方法出错{}", e); return new DataModel<>(ResultStatusEnum.WALLET_GETBLOCKDIFFER_ERROR); } }
/** * 查询钱包余额 * @return */ @Override public DataModel getBalance(WalletBalanceDTO walletBalanceDTO) { BigInteger balance = new BigInteger("0"); try { log.info("ETH 系列查询钱包余额方法,address{}",walletBalanceDTO.toString()); balance = web3j.ethGetBalance(walletBalanceDTO.getAddress(), DefaultBlockParameterName.PENDING).send().getBalance(); ///转账数量,数量除以 1 的 18 次幂 BigDecimal amount = Convert.fromWei(String.valueOf(balance), Convert.Unit.ETHER); return new DataModel<>(ResultStatusEnum.OK,amount); }catch (Exception e){ log.error("ETH 系列,查询钱包余额(getbalance)方法出错{}",e); return DataModel<>(ResultStatusEnum.WALLET_GETBALANCE_ERROR, new balance); } } private boolean isValidAddress(String addr) { String regex = "^0x[0-9a-fA-F]{40}$"; //Print for testing purpose and more verbose output // System.out.println("Incoming Address " + addr); if (addr.matches(regex)) { return true; } return false; } }
分享到:
收藏