使用web3j构建以太坊钱包

创建一个以太坊钱包有多种方式,一般情况下可以通过geth、EtherumWallet等客户端。对于前端,可以使用插件MetaMask进行创建。这几种方式技术实现虽然不同,但底层原理是一致的。本文主要介绍如何通过web3j架构创建一个以太坊的冷钱包,从而实现将这一过程部署在服务端或者android端。

文中涉及到的技术栈有:

Web3j :轻量级java库,用于连接以太坊客户端或节点

Infura :以太坊基础设施,用于访问以太坊主网络或测试网络

Java:编程语言

1.Web3j的安装

无论是java工程还是android工程,web3j都提供了maven和grade 两种依赖方式:

  1. java工程
  • manen依赖
<dependency><groupId>org.web3j</groupId><artifactId>core</artifactId><version>3.3.1</version>
</dependency>
复制代码
  • gradle依赖
compile ('org.web3j:core:3.3.1')
复制代码
  1. android工程
  • maven依赖
<dependency><groupId>org.web3j</groupId><artifactId>core</artifactId><version>3.3.1-android</version>
</dependency>
复制代码
  • gradle依赖
compile ('org.web3j:core:3.3.1-android')
复制代码

值得注意的是,目前的web3j对于高版本JDK存在不兼容的问题,如果出现如下类似的问题,直接更换JDK为version 8即可。

Could not determine Java version using executable /Library/Java/JavaVirtualMachines/jdk-10.jdk/Contents/Home/bin/java.

2.关于Infura

以太坊的客户端实现有多种,但很多都需要在本地同步所有的节点数据而占用大量硬盘存储空间,并且需要消耗同步的时间。Infura就是提供一种中心化的服务,通过web3.js或者web3j使前端或服务端能便捷的访问以太坊所有节点。可以理解为一种以太坊客户端的云端版本。使用过程需要注册,一个专属的访问token。本文中使用的客户端都是Infura提供的Rinkeby测试网络。

3.新建钱包文件keyfile

在以太坊中,钱包(wallet)和账户(account)是两个不同的概念。账户是以太坊的核心,由一对秘钥组成-公钥和私钥。账户可以分为两种,外部账户和合约账户。而钱包是指保存 地址、公钥、私钥的文件或其他机构,每个钱包文件至少包含一个账户。创建钱包的同时也是创建一个以太坊账户的过程不同的客户端创建钱包的方式不一致但原理相同,有关钱包是具体是如何生成的可以查看另外这篇文章。

  1. 新建一个java工程,初始化gradle或者maven
  2. 依赖web3j
  3. 新建Application.java文件,设置程序入口main函数
  4. 调用钱包工具类生成钱包文件
/*************创建一个钱包文件**************/
private void creatAccount() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, CipherException, IOException {String walletFileName0="";//文件名String walletFilePath0="/Users/yepeng/MyGitHub/z_wallet_temp";//钱包文件保持路径,请替换位自己的某文件夹路径walletFileName0 = WalletUtils.generateNewWalletFile("123456", new File(walletFilePath0), false);//WalletUtils.generateFullNewWalletFile("password1",new File(walleFilePath1));//WalletUtils.generateLightNewWalletFile("password2",new File(walleFilePath2));log.info("walletName: "+walletFileName0);
}
复制代码

钱包构建的过程中需要输入的三个参数,分别设置钱包的密码、保存路径、以及是否轻量级钱包。

执行创建函数后,会自动在指定路径生成一个json 文件,即钱包keyfiles。

钱包文件结构:

  • cipher:加密算法,AES算法,用于加密以太坊私钥
  • cipherparams:cipher算法需要的参数,参数iv,是aes-128-ctr加密算法需要的初始化向量
  • ciphertext:加密后的密文,aes-128-ctr函数的加密输入密文;
  • kdf:秘钥生成函数,用于使用密码加密keystore文件
  • kdfparams:kdf算法所需要的参数
  • mac:验证密码的编码

生成钱包的逆向过程 为加载钱包。

4.加载钱包文件

加载钱包的过程需要提供钱包文件和密码

/********加载钱包文件**********/
private void loadWallet() throws IOException, CipherException {String walleFilePath="/Users/yepeng/MyGitHub/z_wallet_temp/UTC--2018-04-10T02-51-24.815000000Z--12571f46ec3f81f7ebe79112be5883194d683787.json";String passWord="123456";credentials = WalletUtils.loadCredentials(passWord, walleFilePath);String address = credentials.getAddress();BigInteger publicKey = credentials.getEcKeyPair().getPublicKey();BigInteger privateKey = credentials.getEcKeyPair().getPrivateKey();log.info("address="+address);log.info("public key="+publicKey);log.info("private key="+privateKey);}
复制代码

函数运行的结果:

通过工具类 WalletUtols的函数 loadCredentials(),会返回一个对象Credentials,这个对象即包含了钱包文件的所有信息,包括地址、秘钥对。

至此,钱包的创建和加载已经完成,但这一过程全部发生在本地,并未同步到以太坊区块链。查询地址余额前,需要连接以太坊结点。

5.构建Web3j实体,连接以太坊结点

web3j是连接java端与以太坊的桥梁,广播交易,查询账户都需要通过web3j实体。web3j支持通过http进行构建,而且兼容了infura。在本文中,使用的是infura的测试网络Rinkeby。

/*******连接以太坊客户端**************/
private void conectETHclient() throws IOException {//连接方式1:使用infura 提供的客户端web3j = Web3j.build(new HttpService("https://rinkeby.infura.io/zmd7VgRt9go0x6qlJ2Mk"));// TODO: 2018/4/10 token更改为自己的//连接方式2:使用本地客户端//web3j = Web3j.build(new HttpService("127.0.0.1:7545"));//测试是否连接成功String web3ClientVersion = web3j.web3ClientVersion().send().getWeb3ClientVersion();log.info("version=" + web3ClientVersion);
}
复制代码

web3j实体构建完成后,可以打印出版本号以测试是否连接成功。如果成功,就可以做其他的事情了。值得注意的是,web3j采用的是RxJava的设计,所以许多函数的返回值是 Request,这个对象有两种执行方式,异步和同步,即send()和sendAsyn()。

6.查询账户余额

查询账户的余额的方式:

/***********查询指定地址的余额***********/
private void getBlanceOf() throws IOException {if (web3j == null) return;String address = "0x41F1dcbC0794BAD5e94c6881E7c04e4F98908a87";//等待查询余额的地址//第二个参数:区块的参数,建议选最新区块EthGetBalance balance = web3j.ethGetBalance(address, DefaultBlockParameter.valueOf("latest")).send();//格式转化 wei-etherString blanceETH = Convert.fromWei(balance.getBalance().toString(), Convert.Unit.ETHER).toPlainString().concat(" ether");log.info(blanceETH);
}
复制代码

其中核心方法 web3j.ethGetBalance(address, defaultBlockParameter) 中的第二个参数比较特殊,指默认的区块参数。当请求余额的方法作用与以太坊的区块网络时,这个参数决定了查询区块的高度。

  • HEX String - 一个整数块号
  • String "earliest" 为最早/起源块
  • String "latest" - 为最新的采矿块
  • String "pending" - 待处理状态/交易

一般情况下,选择“latest”即可。

以太坊中,如果没有特殊标示,数字的单位都是小数点后18位,因此查询账户余额有必要将wei转化成ether

6.使用钱包进行转账

作为一个钱包,除了保存账户资产外,最重要的就是转账或交易了,利用web3j可以便捷的实现eth的转移。

/    /****************交易*****************/private void transto() throws Exception {if (web3j == null) return;if (credentials == null) return;//开始发送0.01 =eth到指定地址String address_to = "0x41F1dcbC0794BAD5e94c6881E7c04e4F98908a87";TransactionReceipt send = Transfer.sendFunds(web3j, credentials, address_to, BigDecimal.ONE, Convert.Unit.FINNEY).send();log.info("Transaction complete:");log.info("trans hash=" + send.getTransactionHash());log.info("from :" + send.getFrom());log.info("to:" + send.getTo());log.info("gas used=" + send.getGasUsed());log.info("status: " + send.getStatus());}
复制代码

核心方法需要提供4个参数:

  • web3j实体
  • Credentials 源账户
  • address 转出地址
  • value 数量
  • uint 单位

等待片刻后,会返回转账结果

可以看到交易hash、转入转出地址、gas消耗等信息。同时可以在etherscan-rinkeby上进行查看本次交易详情

7.总结

上面的代码已经完成了一个以太坊钱包所需的所有基本功能,包括创建、加载、转账、查询。本文中采用的网络是infura提供的Rinkeby测试网络,创建的钱包地址为 0x12571F46Ec3f81F7EbE79112Be5883194d683787。

在具体的业务场景中,只要将测试网络更换为以太坊主网络即可。

源码地址 github.com/initsysctrl…

转载于:https://juejin.im/post/5ba9a007f265da0a8b572530

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396754.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Html、CSS、JavaScript 实时效果在线编辑器 - 学习的好工具,算不算?!

关于 二维码 与 NFC 之间的出身贫贱说太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es)本文遵循“署名-非商业用途-保持一致”创作公用协议转载请保留此句&#xff1a;太阳火神的漂亮人生 - 本博客专注于 敏捷开发及移动和物联设备研究&#xff1a;iOS、Android、Html5、…

android自定义更新,Android 完美解决自定义preference与ActivityGroup UI更新的问题

之前发过一篇有关于自定义preference 在ActivityGroup 的包容下出现UI不能更新的问题&#xff0c;当时还以为是Android 的一个BUG 现在想想真可笑 。其实是自己对机制的理解不够深刻&#xff0c;看来以后要多看看源码才行。本篇讲述内容大致为如何自定义preference 开始到与Act…

vxlan 资料及其在 neutron中的应用

2019独角兽企业重金招聘Python工程师标准>>> VXLAN 是一个新兴的SDN 标准&#xff0c;它定义了一种新的 overlay 网络&#xff0c;它主要的创造者是 VMware, Cisco 和 Arista。它被设计来消除虚拟化网络世界中的 VLAN 数目的限制。VXLAN 本身是一个多播标准&#xf…

横流式冷却塔计算风量_研讨丨卓展标准高效制冷机房技术之影响冷却塔效率的几个因素...

集中制冷用空调系统中&#xff0c;单台冷却塔的冷却水量基本上都小于1,000m/h&#xff0c;且装有淋水填料的横流机械通风开式居多。本文将已横流开式冷却塔为对象&#xff0c;探讨影响其效率的几个因素。横流开式冷却塔示意图如下所示&#xff1a;横流开式冷却塔示意图 Fig 01说…

我是培训出来的我怕谁

引子: 江小峰是我带过的徒弟中跟我最久&#xff0c;也是最聪明的一个。 他一个高中生&#xff0c;没上过大学&#xff0c;高中毕业后在老家卖了三年电脑&#xff0c;天天给人装操作系统&#xff0c;有天他在网上看到某培训机构招生简介&#xff0c;一时冲动揣上三年血汗钱&…

android平台gallery2应用分析,Android5.1图库Gallery2代码分析数据加载流程

图片数据加载流程。Gallery---->GalleryActivity------>AlbumSetPage------->AlbumPage--------->PhotoPage相册集 照片集 某张图片1,AlbumSetPage.javaprivate void initializeData(Bundle data) {String mediaPath data…

python开课吧1980课程_开课吧的课程怎么样?

就那那些编程开发课来说。现在网络上充斥着大量的编程开发课程&#xff0c;什么python的&#xff0c;java的&#xff0c;c的&#xff0c;而且名字一个比一个夸张&#xff0c;21天精通c&#xff0c;7天熟练运用java&#xff0c;3天掌握python核心代码&#xff0c;这些课程标题简…

专业概念

1.JDBC: java数据库连接&#xff08;JDBC&#xff09;用于在java程序中实现数据库的操作功能&#xff0c;它提供了执行sql语句&#xff0c;访问各种数据库的方法&#xff0c;并为各种不同的数据库提供统一的操作接口&#xff0c;java.sql包中 包含了jdbc操作数据库的所有类 2.…

前端解决跨域问题的8种方案

2019独角兽企业重金招聘Python工程师标准>>> 1.同源策略如下&#xff1a; URL说明是否允许通信http://www.a.com/a.js http://www.a.com/b.js同一域名下允许http://www.a.com/lab/a.js http://www.a.com/script/b.js同一域名下不同文件夹允许http://www.a.com:8000/…

k歌的录音伴奏合成技术如何实现_K歌神器,用唱吧麦克风攀登天籁高峰

自从喜欢上了手机K歌&#xff0c;经常会上传一些自己的作品&#xff0c;起初无论音质如何都是乐在其中&#xff0c;可时间久了发现回放效果确实不如那榜单上的高手&#xff0c;究其原因想到了麦克风&#xff0c;网上一搜果然有各种K歌辅助工具&#xff0c;多番对比之下&#xf…

浅谈内存开辟问题和Block内存问题

我们知道&#xff0c;内存分为栈&#xff0c;堆&#xff0c;块。 栈中的内存由系统自己释放&#xff0c;堆是存对象初始化的地方&#xff0c;块是CPU与内存连接的缓冲器&#xff0c;运行速度比内存快&#xff0c;比CPU慢。 例如&#xff0c;我们NSMutableArray *array [NSMuta…

vue render函数_Vue原理解析(一):Vue到底是什么?

Vue&#xff0c;现在前端的当红炸子鸡&#xff0c;随着热度指数上升&#xff0c;实在是有必要从源码的角度&#xff0c;对它功能的实现原理一窥究竟。个人觉得看源码主要是看两样东西&#xff0c;从宏观上来说是它的设计思想和实现原理&#xff1b;微观上来说就是编程技巧&…

scrapy爬虫-setting.py

# Obey robots.txt rulesROBOTSTXT_OBEY False  不遵从网站的robots.txt法则 # See also autothrottle settings and docsDOWNLOAD_DELAY 3  每次下载延迟3秒&#xff0c;防止造成网站攻击 # Override the default request headers:DEFAULT_REQUEST_HEADERS { Accept:…

android点击左上角划出,使用Android中的Path和RectF在左上角右上角左下角绘制圆角...

有一个Path#addRoundRect()重载,它接受一个包含八个值的float数组,其中我们可以为四个角中的每一个指定x和y半径.这些值为[x,y]对,从左上角开始,顺时针绕其余部分.对于我们想要舍入的那些角,我们将该对的两个值都设置为半径值,并将它们保留为零,而不是那些.作为一个说明性示例,…

Nodejs微信开发

因为使用了Bot Framework开发了一个小功能&#xff0c;它目前支持了Skype\Teams\Slack等&#xff0c;但在国内来讲&#xff0c;微信还是一个比较流行的软件&#xff0c;所以需要接上微信 原来开发Bot的时候使用的是.Net开发的&#xff0c;这次我决定使用Nodejs开发一个简单的后…

性别有什么用_为啥不让男孩玩布娃娃?别让你的“性别偏见”,给孩子的人生设限...

在养育孩子的过程中&#xff0c;父母总是会犯许多错误&#xff0c;更是有一些错误会直接使孩子毁掉一生&#xff0c;而性别偏见正是很多家长都会去犯的错误&#xff0c;对男孩和女孩有着刻板印象&#xff0c;也正是因为这一点使孩子的潜力和天赋被压制。前几天我带着孩子去逛商…

android的时间代码怎么写,Android 日期和时间的使用实例详解

Android 日期和时间的使用日期和时间的使用&#xff1b;1&#xff1a;弹出框TimePickerDialog,DatePickerDialog2&#xff1a;组件TimePicker,DatePickerTimePickerDialog的使用&#xff1a;通过点击button显示图一&#xff0c;然后用户可以设置时间DatePickerDialog的使用只需…

andriod studio 查看项目依赖_Intellij IDEA 中如何查看maven项目中所有jar包的依赖关系图...

Maven 组件界面介绍如上图标注 1 所示&#xff0c;为常用的 Maven 工具栏&#xff0c;其中最常用的有&#xff1a;第一个按钮&#xff1a;Reimport All Maven Projects 表示根据 pom.xml 重新载入项目。一般单我们在 pom.xml 添加了依赖包或是插件的时候&#xff0c;发现标注 4…

Springboot 2.0.0单元测试

1. 引入spring-boot-starter-test包 1 <?xml version"1.0" encoding"UTF-8"?>2 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"3 xsi:schemaLocation"…

SPRING IN ACTION 第4版笔记-第二章-002-@ComponentScan、@Autowired的用法

一、ComponentScan 1. Configuration //说明此类是配置文件 ComponentScan //开启扫描&#xff0c;会扫描当前类的包及其子包 public class CDPlayerConfig { } 2. ComponentScan(basePackages{"soundsystem", "video"})//扫描多个包 public class CDP…