[币严区块链]数字货币交易所之以太坊(ETH)钱包对接(四) 使用web3j对接以太坊钱包
本文给大家介绍了 Web3j Java 版本的框架的基本使用,大家可根据本文的内容进行扩展性的练习,对其他 API 的使用进行尝试。
使用web3j对接以太坊钱包
一、开发准备事项
启动 Geth
此操作在(二)中已经详细介绍过了,可以参考其内容进行 Geth 节点启动,也算是对之前内容的复习,这里不再赘述操作步骤。
开发环境准备
- JDK 版本 1.8;
- 开发工具 Intellij idea(本教程使用,也可以使用 Eclipse 等其他 IDE);
- Maven 版本管理(本教程使用,要依赖一些通用的 jar 包,采用 Maven 项目管理模式,也可自行下载依赖 jar 包使用其他方式,建议用 Maven 来操作)。
二、项目实战
创建 Maven 项目
在 idea 中单击创建新项目,进入如下页面,选择 Maven 项目:

单击 Next 按钮,填写 Maven 项目中的 GroupId 和 ArtifactId:

单击 Next 按钮,设置项目名称和项目路径:

单击 Finish 按钮,这样就创建好了一个 Maven 项目:

添加依赖
在 pom.xml 文件中新增依赖父元素和 Maven 编译指定 jdk 版本:
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
然后在其中父依赖中添加一下依赖信息:
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.web3j</groupId>
<artifactId>geth</artifactId>
<version>3.2.0</version>
</dependency>
上面引入的是一套开源的支持 Web3j 调用以太坊的依赖核心包和 Geth 操作包。Web3j 开源框架提供了一套 Java 版本的操作封装,让开发人员可以方便快捷的进行 JSON-RPC 的调用。

公共代码示例
创建 package:com.secbro.eth,并在 package 下面创建 EthService 类,后面针对 ETH 的操作,都会封装在 EthService 中做为静态方法呈现,类内容如下,后面代码讲解不再粘贴类内容,直接展示使用到的方法:
package com.secbro.eth;
/**
* @author zzs
*/
public class EthService {
/**
* geth节点可调用的json-rpc接口地址和端口
*/
private static final String URL = "http://127.0.0.1:8545/";
}
其中需要注意的是上面的静态变量为 Geth 节点启动的 JSON-RPC 访问的地址和端口,如果不是本地启动可修改 IP 和端口,确保网络畅通。
初始化 Web3j、Geth 和 Admin 接口
Web3j 框架中提供了多类操作,我们重点介绍 Web3j、Geth 和 Admin 这三个接口,其中 Web3j 和 Admin 都在核心包 core 中,Geth 是在 Geth 包中,这三个接口与我们讲的 JSON-RPC 中说到的操作有对应的关系,其中 Web3j 接口封装了常见的 net、eth、db 等操作,与官方提供的操作一一对应。
Admin 接口对应的是 personal 的一部分操作:
- personalListAccounts()
- personalNewAccount(String password)
- personalUnlockAccount( String address, String passphrase, BigInteger duration)
- personalUnlockAccount( String address, String passphrase)
- personalSendTransaction( Transaction transaction, String password)
Geth 接口继承了 Admin 接口,并新增了以下操作:
- personalImportRawKey(String keydata, String password)
- personalLockAccount(String accountId)
- personalSign(String message, String accountId, String password)
- personalEcRecover(String message, String signiture)
下面在 EthService 类中新增如下实例化方法,来获得这三个接口的实现:
/**
* 初始化web3j普通api调用
*
* @return web3j
*/
public static Web3j initWeb3j() {
return Web3j.build(getService());
}
/**
* 初始化personal级别的操作对象
* @return Geth
*/
public static Geth initGeth(){
return Geth.build(getService());
}
/**
* 初始化admin级别操作的对象
* @return Admin
*/
public static Admin initAdmin(){
return Admin.build(getService());
}
/**
* 通过http连接到geth节点
* @return
*/
private static HttpService getService(){
return new HttpService(URL);
}
代码上的注释已经明确说明每个方法的用户,这里值得一提的是这里采用的是 HttpService 来初始化一个与 geth 通信的 http 连接,在真实生产中可以采用 OkHttpClient 来对此链接进行设置超时时间等参数。
通过上面的步骤就完成了三个接口对应的类的实例化操作,后面的内容就可以直接使用它们提供的方法来实现进行相应的业务处理。
三、常用接口使用示例
下面提供一些常用的接口(开发钱包或交易所)的具体实现的代码和解析。
创建地址
根据输入的密码创建地址,对应 personal_newAccount 操作,返回地址 hash:
/**
* 输入密码创建地址
*
* @param password 密码(建议同一个平台的地址使用一个相同的,且复杂度较高的密码)
* @return 地址hash
* @throws IOException
*/
public static String newAccount(String password) throws IOException {
Admin admin = initAdmin();
Request<?, NewAccountIdentifier> request = admin.personalNewAccount(password);
NewAccountIdentifier result = request.send();
return result.getAccountId();
}
查询区块高度
查询区块高度,对应eth_blockNumber操作,返回当前区块高度。
/**
* 获得当前区块高度
*
* @return 当前区块高度
* @throws IOException
*/
public static BigInteger getCurrentBlockNumber() throws IOException {
Web3j web3j = initWeb3j();
Request<?, EthBlockNumber> request = web3j.ethBlockNumber();
return request.send().getBlockNumber();
}
解锁账户
解锁账户,发送交易前需要对账户进行解锁,对应personal_unlockAccount操作。
/**
* 解锁账户,发送交易前需要对账户进行解锁
*
* @param address 地址
* @param password 密码
* @param duration 解锁有效时间,单位秒
* @return
* @throws IOException
*/
public static Boolean unlockAccount(String address, String password, BigInteger duration) throws IOException {
Admin admin = initAdmin();
Request<?, PersonalUnlockAccount> request = admin.personalUnlockAccount(address, password, duration);
PersonalUnlockAccount account = request.send();
return account.accountUnlocked();
}
锁定账户
账户解锁,使用完成之后需要锁定,对应操作personal_lockAccount。
/**
* 账户解锁,使用完成之后需要锁定
*
* @param address
* @return
* @throws IOException
*/
public static Boolean lockAccount(String address) throws IOException {
Geth geth = initGeth();
Request<?, BooleanResponse> request = geth.personalLockAccount(address);
BooleanResponse response = request.send();
return response.success();
}
获取交易信息
根据 hash 值获取交易信息,对应操作eth_getTransactionByHash。
/**
* 根据hash值获取交易
*
* @param hash
* @return
* @throws IOException
*/
public static EthTransaction getTransactionByHash(String hash) throws IOException {
Web3j web3j = initWeb3j();
Request<?, EthTransaction> request = web3j.ethGetTransactionByHash(hash);
return request.send();
}
查询区块内容
根据区块编号查询区块内容,对应操作eth_getBlockByNumber。
/**
* 获得ethblock
*
* @param blockNumber 根据区块编号
* @return
* @throws IOException
*/
public static EthBlock getBlockEthBlock(Integer blockNumber) throws IOException {
Web3j web3j = initWeb3j();
DefaultBlockParameter defaultBlockParameter = new DefaultBlockParameterNumber(blockNumber);
Request<?, EthBlock> request = web3j.ethGetBlockByNumber(defaultBlockParameter, true);
EthBlock ethBlock = request.send();
return ethBlock;
}
发送交易
发送交易并获得交易 hash 值,对应操作personal_sendTransaction。
/**
* 发送交易并获得交易hash值
*
* @param transaction
* @param password
* @return
* @throws IOException
*/
public static String sendTransaction(Transaction transaction, String password) throws IOException {
Admin admin = initAdmin();
Request<?, EthSendTransaction> request = admin.personalSendTransaction(transaction, password);
EthSendTransaction ethSendTransaction = request.send();
return ethSendTransaction.getTransactionHash();
}
获取指定地址 nonce
指定地址发送交易所需 nonce 获取,对应操作eth_getTransactionCount。
/**
* 指定地址发送交易所需nonce获取
*
* @param address 待发送交易地址
* @return
* @throws IOException
*/
public static BigInteger getNonce(String address) throws IOException {
Web3j web3j = initWeb3j();
Request<?, EthGetTransactionCount> request = web3j.ethGetTransactionCount(address, DefaultBlockParameterName.LATEST);
return request.send().getTransactionCount();
}
使用接口注意事项
在使用上面的接口调用时,request.send() 方法是同步返回结果,在某些情况下可能会导致响应比较慢,因此此框架提供了 request.sendAsync() 异步操作,当进行异步操作时只是将操作的执行发送出去,并没有获得相应的操作结果,需要通过监听器获取结果的通知。
本文中示例的代码大家在真实生产环境使用时需要进行相应的优化处理,比如网络优化、初始化链接优化、超时时间设定、冷钱包设置、私钥与 Geth 节点分离、系统安全考虑等。
BIZZAN(币严) 数字货币交易所官方网址:
www.bizzan.com
[币严区块链]数字货币交易所之以太坊(ETH)钱包对接(四) 使用web3j对接以太坊钱包的更多相关文章
- [币严区块链]数字货币交易所之比特币(BTC)钱包对接 | 自建节点JSON-RPC访问
BTC钱包对接流程 一. 部署BTC钱包节点 二. 分析BTC钱包的API 三. 通过JSON-RPC访问BTC钱包API 四. 部署测试 一.部署钱包节点 交易平台对接BTC之前,要 ...
- [币严区块链]数字货币交易所之瑞波(XRP)钱包对接
对接Ripple(XRP),不需要本地部署钱包,直接访问Ripple API,本文包括访问Ripple API及如何免费获取测试的XRP. 对接流程 安装Ripple API Ripple API 接 ...
- [币严BIZZAN区块链]数字货币交易所钱包对接之比特币(BTC)
在币严BIZZAN开发数字货币交易所的过程中,一共有两大难点,一个是高速撮合交易引擎,另一个是钱包对接,这两者是我们团队以前没有接触过的.这个系列的文章主要介绍数字货币交易所钱包对接实现技术.第一个要 ...
- [币严区块链]BitcoinCash - BCH钱包地址生成与扫块充值监控(JAVA版)
本文的方案无需自建节点,因为BCH当前区块数据大小已经达到200G以上,BTC区块数据也已超过300G,若每个币都自建节点,对云服务器的消耗会非常大. 认识BitcoinCash(BCH) Bitco ...
- [币严区块链]交易所钱包系统如何实现USDT自动归集操作
本文代码应用场景: 每个用户在交易所充值时,每个人都分配了独立的USDT地址,而交易所需要将所有独立的地址中USDT汇集到一个钱包地址(一般是冷钱包),从而实现资产归集与安全保障. 注意: 理解以下代 ...
- [币严区块链]USDT钱包节点搭建
USDT是基于BTC发的稳定币,它是比特币的一条侧链,说简单点,就是在比特币区块数据的不可篡改性与区块唯一性的基础上,再封装了一层.具体原理可网上查资料.总之理解一点:USDT的钱包节点就是BTC的钱 ...
- [币严区块链]以太坊(ETH)Dapp开发入门教程之宠物商店领养游戏
阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以太坊是什么 除此之外,你最好还了解一些HTML及JavaScript知识. 本文通过实例教大家来开发去中心化应用,应用效果如图 ...
- [币严区块链]简单易懂的以太坊(ETH)智能合约开发入门教程
以太坊(Ethereum)是一提供个智能合约(smart contract)功能的公共区块链(BlockChain)平台. 本文介绍了一个简单的以太坊智能合约的开发过程. 开发环境 在以太坊上开发应用 ...
- [币严区块链]ETH搭建节点区块数据同步的三种模式:full、fast、light
ETH 全节点Archive(归档)模式数据量增长图 上述图表可通过链接查看:https://etherscan.io/chartsync/chainarchive 通过上表,可以看到截止2019年 ...
随机推荐
- 鲜为人知的maven标签解说
目录 localRepository interactiveMode offline pluginGroups proxies servers mirrors profiles 使用场景 出现位置 激 ...
- vue组件传值之$attrs、$listeners
当有父组件A,子组件B,孙子组件C的时候 A-B B-C 的传值想必大家应该都非常熟悉了,通过props和$emit和$on来进行传值 那么A-C之间的传值要怎么做呢? 1.event.bus总线传值 ...
- 使用rpm安装指定版本的docker(1.12.6)
一.原因 如果系统是Centos7.3,直接使用yum install docker安装的docker版本是1.13.1,导致在创建容器的会报错,错误如下: 所以为了防止安装高版本的docker引发的 ...
- tk.mybatis扩展通用接口
一.tk.mybatis已经为我们封装好了许多拆箱即用的通用mapper,但在实际的项目开发中想必不少小伙伴在数据库设计中都会采用逻辑删除这种方案,再去使用通用的mapper接口就不行了.这时候就需要 ...
- (二)c#Winform自定义控件-按钮
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- tensorflow学习笔记——图像数据处理
喜欢摄影的盆友都知道图像的亮度,对比度等属性对图像的影响是非常大的,相同物体在不同亮度,对比度下差别非常大.然而在很多图像识别问题中,这些因素都不应该影响最后的结果.所以本文将学习如何对图像数据进行预 ...
- oracle 正则表达的使用
最近遇到有个项目,需要根据文件存储的根目录地址来判断是在云端获取,还是本地获取, 先看下具体有几个不同的根目录: , , 'i') from pmc.designmaterial d 去重关键字:di ...
- spring-boot-plus项目配置文件(四)
spring-boot-plus项目配置文件 配置文件说明 配置说明 项目中配置文件主要使用yml格式 配置文件位置:spring-boot-plus\src\main\resources\confi ...
- 对已经存在的hbase表修改压缩方式
业务上可能会遇到这种情况,在最初创建hbase表时候,未指定压缩方式,当数据导入之后,由rowkey带来的数据膨胀导致hdfs上的数据大小远远大于原始数据大小.所以这时候可能就不得不考虑使用压缩,但是 ...
- java 线程池newFixedThreadPool
工作中遇到一个这样的情况,List中的元素要每个遍历出来,然后作为参数传给后面通过spark做数据处理,元素太多,一个一个的遍历速度太慢,于是考虑使用多线程,代码如下:(已删除部分代码) 想了解更多线 ...