优盾钱包(www.uduncloud.com)提供BTC_ETH_USDT_EOS_XRP等主流erc20代币对接交易所钱包充提币_转账支付归集_API/RPC的php/java开发接口。API快捷接入,多币种多地址钱包余额一键归集、私钥冷存储、多级复签、全终端支持。
►点此立即试用◄
纵观整个区块链行业,监管越来越规范化、明朗化,区块链行业正逐步朝着合规化方向大踏步前进。随着区块链技术的场景应用,让人们渐渐开始认知加密货币。有需求的地方就会有市场,那么有货币的地方就会有安全存储的需求,数字货币也不例外,基于区块链技术诞生了一款适合守护数字资产的钱包——区块链钱包。区块链钱包通过技术原理解决了信任问题,秉承着安全至上的理念,作为链接区块链生态的重要入口,引起业内广泛关注,很多开发者与投资者纷纷投入技术与资金涌入这个赛道。今天我们就来聊一聊如何通过 Java 语言实现以太坊JSON-RPC接口调用呢?
开发准备事项
启动 dev 模式的 Geth
其实也就是 Geth 节点启动
开发环境准备
JDK 版本 1.8(本教程应用,也能够应用 1.7、1.6 或其他版本);
开发工具 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 的调用需求。
enter image description here
公共代码示例
创建 package:com.secbro.eth,且基于 package 下面创建 EthService 类,之后咱们一些针对以太坊的操作,都会被封装在 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 来对此链接设置超时时间等参数。
根据以上步骤完成了3个接口对应的类的实例化操作,接下来的步骤就能够直接使用它们提供的方法从而完成相应的业务处理。
常用接口使用示例
接下来给大家提供一些常用的接口(开发钱包或交易所)的具体实现的代码和解析。
创建地址
通过输入的密码创建地址,对应 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();
}
得到交易信息
通过哈希值得到交易信息,对应操作eth_getTransactionByHash。
/**
* 通过哈希值得到交易信息
*
* @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;
}
发送交易
发送交易并获得交易哈希值,对应操作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 节点分离、初始化链接优化、系统安全考虑等等。
现在一般的交易所都不会自己去单独开发一套钱包系统了。 不仅因为比特币以太坊等区块节点数据庞大,同步传输慢,而且在服务器和带宽的花费成本比较高。最重要的是养不起这样的一个技术团队!最重要的是原生钱包这种私钥放在服务器非常不安全,被偷就凉凉了。 现在市面上大家用的比较多的优盾钱包(www.uduncloud.com)就很好用,最赞的就是他的多币种多地址资产一键归集和冷热钱包隔离功能了。
优盾钱包,是目前国内最好用的企业钱包开放平台。API一键对接,支持当下多数主流币种、多资产多地址统一管理、用户提币初审+复核安全模式、系统代付自动放币、多员工多钱包多权限一键分配、资产交易查询、资金流动消息提醒等多种功能。
防黑客技术上:
①API接口信息访问验签、基于HTTPS安全传输,拒绝被监听;
②私钥不上传、不触网,并通过二次加密托管在客户端侧;
③钱包绑定电脑MAC地址,拒绝非认证设备访问;
④冷热钱包分离,大额资产用冷钱包离线保存;
防内鬼技术上:
①员工操作权限管理员一键设置;
②员工操作记录管理员一键查询;
③员工只接触管理独立小额子钱包;
④超额转出交易需管理员复核;
⑤员工在非公司指定电脑设备登录优盾账号需管理员同意;
便捷接入:
①免节点同步;
②标准接口;
③详细接口文档;
④接入DEMO;
⑤7*24小时技术支持。
相关文章:
1、钱包对接交易所教程·
2、答疑笔记 | 这10类区块链钱包问题,业内人士最关注
3、区块链交易所钱包实现原理揭秘!
4、区块链交易所钱包对接