钱包开发经验分享:ETH篇开发前的准备ETH钱包代码参考生成钱包地址、公私钥和助记词/通过助记词恢复钱包地址、公私钥获取余额/获取代币余额获取代币名称、精度和符号获取交易ETH/代币离线签名转账
开发前的准备
一路开发过来,积累了一些钱包的开发利器和网站,与大家分享一下。这些东西在这行开发过的人都知道,只是给行外打算入行的人做个参考。
-
最好用的ETH钱包--MetaMask
下载:MetaMask(谷歌插件)
简介:这是一款以太坊浏览器插件,他可以很方便的查看或操作以太坊、erc20代币余额,也方便配合remix之类的合约IDE来部署合约,支持自定义代币,支持多种测试网络和正式网络以及自定义网络节点。总而言之,这是一款十分便利好用的钱包。
-
最官方的区块链浏览器--etherscan
网址:以太坊官方区块链浏览器
简介:这是以太坊最最最官方的区块链浏览器了,对于开发者而言,它不仅仅只是查询区块交易那么简单,他还有更多有利于程序员开发的功能。它提供了众多api和小工具,它是所有测试网络的父域名,可以轻松地切换查看到所有测试网络的区块和交易,在部署合约时,它又协助你发布合约,因此对于开发者而言,这是一个不可缺少的网站。
-
获取测试币的网站--rinkeby、ropsten
网址:rinkeby、ropsten
简介:以太坊有很多共享的测试网络,这篇博文介绍了各个网络的区别和其区块链浏览器,其中开发者主要使用的区块链浏览器不外乎rinkeby和ropsten,上述两个网址则是这两种测试币的水龙头网站,获取测试币的教程如下:获取rinkeby测试币、获取ropsten测试币。
-
免费的第三方节点接入--王站
网址:infura
简介:对于ETH钱包开发而言,这是个不可或缺的网站,当然,可能也有其他第三方节点免费对用户开放,不过我一直用的是这个网站。这个网站的作用是,我们不用搭建ETH节点也可以正常地进行ETH的开发,我们只需要动动手指注册一个账户,创建我们的项目,就能拿到一个免费接入的ETH节点,而且他还包括了所有流行的测试网络。而我之所以称之为王站,是因为它的网站图标类似一个王字。
-
最便捷的以太坊IDE--remix
网址:remix
简介:对于ETH钱包开发而言,合约开发和部署或许是必不可少的一部分,为什么我会这样说?那是因为在钱包开发中,总会需要对接各种erc20的代币,而我们虽然能够在获得ETH的测试币,但是其他的代币的测试币我们是很难获得的(或者说根本无法获得),而基于erc20协议的代币代码是通用的,所以接入代币钱包的时候,我们往往是考虑自己在测试网络部署一份erc20协议的合约,并自己铸币,以方便进行后续的开发,而结合remix和MetaMask来部署合约,那就是几个步骤的事情。部署合约的流程可以参考这篇教程。
ETH钱包代码参考
真正的知识就在经验中
生成钱包地址、公私钥和助记词/通过助记词恢复钱包地址、公私钥
-
导入依赖
<dependency>
<groupId>org.bitcoinjgroupId>
<artifactId>bitcoinj-coreartifactId>
<version>0.14.7version>
dependency>
<dependency>
<groupId>org.web3jgroupId>
<artifactId>coreartifactId>
<version>4.5.5version>
dependency> -
初始化web3j
private final static Web3j web3j = Web3j.build(new HttpService("https://mainnet.infura.io/v3/你自己从infura申请的id"));
-
参考代码
public static Map<String, Object> ethWalletGenerate(String mnemonic, String mnemonicPath, String passWord) {
try {
DeterministicSeed deterministicSeed = null;
List<String> mnemonicArray = null;
if (null == mnemonic || 0 == mnemonic.length()) {
deterministicSeed = new DeterministicSeed(new SecureRandom(), 128, "", System.currentTimeMillis() / 1000);
mnemonicArray = deterministicSeed.getMnemonicCode();// 助记词
} else {
deterministicSeed = new DeterministicSeed(mnemonic, null, "", System.currentTimeMillis() / 1000);
}
byte[] seedBytes = deterministicSeed.getSeedBytes();// 种子
if (null == seedBytes) {
logger.error("生成钱包失败");
return null;
}
//种子对象
DeterministicKey deterministicKey = HDKeyDerivation.createMasterPrivateKey(seedBytes);
String[] pathArray = mnemonicPath.split("/");// 助记词路径
for (int i = 1; i < pathArray.length; i++) {
ChildNumber childNumber;
if (pathArray[i].endsWith("'")) {
int number = Integer.parseInt(pathArray[i].substring(0, pathArray[i].length() - 1));
childNumber = new ChildNumber(number, true);