web3j学习


学习一门知识、一项技术都先搞清楚他的概念,才能稳固、有目的信心。它是什么,干了什么(处理了什么问题)

以太坊是什么?

以太坊(英文Ethereum)是一个开源的有智能合约功能的公共区块链平台,通过其专用加密货币以太币(Ether,简称“ETH”)提供去中心化的以太虚拟机(Ethereum Virtual Machine)来处理点对点合约。

web3j是什么?

  web3j是一种高度模块化、灵活、安全的Java类库和Android类库,用于处理智能合同,并与以太网络中的客户端(节点)集成。可以通过它进行以太坊区块链的开发,而无需为你的应用平台编写集成代码。

geth

Go-Ethereum简称Geth,用golang语言实现

其官方GitHub的说法,Geth是以太坊协议的官方实现(Official golang implementation of the Ethereum protocol),是以太坊基金会对外提供的重要官方软件之一。

所谓以太坊协议的实现,个人理解就是对以太坊协议范围内的各项能力进行封装,并以简单的形式(命令行、API等)提供给用户使用,我们可以从两个使用角度来理解:

  • Geth可以当客户端来使用
    打开Geth,用户可以创建自己的以太坊私有链、管理账户、挖矿、交易、部署执行智能合约等,用户还可以下载以太坊主链、解析主链上任意交易数据等。
  • Geth可以当服务器来使用
    Geth提供很多服务和丰富的API,用户可以开发程序通过调用Geth服务,实现自己想要的功能,比如获取一段时间内以太币的所有交易账户。
infura

官网: https://infura.io/
本地安装geth的方法需要花比较多的时间和空间来同步区块,利用infura可以简单很多,infura提供公开以太坊和测试节点,可以利用infura提供的api访问以太坊以及IPFS。去官网只需要提供email注册得到链接即可。
本博客申请到的测试用例,后面代码会用到(测试用例apikey没什么价值,我在这里贴出来了)

image.png

安装

Maven

Java 8:
<dependency>
  <groupId>org.web3j</groupId>
  <artifactId>core</artifactId>
  <version>3.4.0</version>
</dependency>

持续更新中...

交易机制

当你用一些以太币Ether创建了一个有效的帐户时,你可以使用两种机制来与以太坊进行交易。

  • 通过以太坊ethereum客户端进行认证签名交易
  • 离线交易签名认证
    这两种机制都是Web3j所支持的。

这里我们使用第二种方式,不需要管理以太坊客户端
离线交易签名认证:
为了离线脱机交易,你需要有你的钱包文件或与私密钱包/账户相关的公共和私人密钥。
web3j能够为你生成一个新的安全的以太坊钱包文件Ethereum wallet file,或者与也可以通过私钥来和现有的钱包文件一起工作。

创建新的钱包文件:

  /*************创建一个钱包文件**************/
    private void creatAccount() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, CipherException, IOException {
        String walletFileName0="";//文件名
        String walletFilePath0="D:/my project/mybatis-plus-study/demo-web3j/etc-wallet";
        //钱包文件保持路径,请替换位自己的某文件夹路径

        walletFileName0 = WalletUtils.generateNewWalletFile("123456", new File(walletFilePath0), false);
        //WalletUtils.generateFullNewWalletFile("password1",new File(walleFilePath1));
        //WalletUtils.generateLightNewWalletFile("password2",new File(walleFilePath2));
        log.info("walletName: "+walletFileName0);

    }

加载凭据从钱包文件:

  /********加载钱包文件**********/
    private void loadWallet() throws IOException, CipherException {
        // FIXME:  替换为自己的钱包路径
        String walleFilePath = "D:/my project/demo-web3j/etc-wallet/UTC--2020-04-17T09-39-23.188000000Z--51003b4b5ee042480a6d2ee5f08ffd265ab311cf.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);
    }
17:34:39.186 [main] INFO com.yao.eth.util.Wallet - version=Geth/v1.9.8-omnibus-f14759fb-20191127/linux-amd64/go1.13.4
17:34:39.473 [main] INFO com.yao.eth.util.Wallet - address=0x51003b4b5ee042480a6d2ee5f08ffd265ab311cf
17:34:39.473 [main] INFO com.yao.eth.util.Wallet - public key=2252572073522424835987964408234834980696663221134034915707746353465859237410910323885187508316742508641207135834625486912634365340742976768431135181723788
17:34:39.474 [main] INFO com.yao.eth.util.Wallet - private key=84441263344107740006778209316822253467814847306459083060609524447653087837710

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

构建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/b23bd4d475cd42978a9d29293d7fb317"));// 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实体构建完成后,可以打印出版本号以测试是否连接成功。如果成功,就可以做其他的事情了。

查询账户余额

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

使用钱包转账

a.在转账之前我们得获取一些测试用的以太币
首先我们需要使用TwitterFacebookGoogle Plus发布新的公开内
容,内容是自己的钱包地址,然后粘贴相应的文章的地址到faucet.

image.png

查看是否到账和账户状态 我们可以通过我们的地址去 explorer:https://www.rinkeby.io/#explorer
这样我们就有可以操作的ETH进行转账等操作了。
b.使用钱包文件来发起交易

try {
    Credentials credentials = WalletUtils.loadCredentials(password,filePath);
    TransactionReceipt transferReceipt = Transfer.sendFunds(web3j, credentials, to,amount, Convert.Unit.WEI).send();
    String hash = transferReceipt.getTransactionHash();
    log.info("转账成功,转账hash = {}",hash);
} catch (Exception e) {
    log.error("转账失败,失败原因{}",e);
}

这种方式相对安全一些,这里需要注意的是一些ETH的最小单位——WEI.

1ETH = 1*10^18 wei;

提示:转账这里存在一些gas的问题,所谓gas我们都知道是转账时需要花费的旷工费。这里我们可以通过gasLimit和gasPrice来调整,当然我们肯定希望gas小,但是gas一味的小,会导致没有人愿意帮我们打包我们得到交易,导致交易最终无法成交,形成一个pending的状态。如果gas给的多,那么交易成交速度会比较快,但是我们花费的钱就会变多。

在之前实现的基础上,我们可以拿到自己创建的钱包,和对应钱包的文件和密码。

相关问题

1.ETH交易模块的特点

  1. 必须按顺序处理事务(具有1的nonce为1的事务必须在具有2的nonce的事务之前处理)
  2. 不跳过(具有4的nonce的事务不能包含在块中,直到具有1,2,3的nonce的事务

通过这种方式,网络能够识别交易的重复并强制执行订单(这对于智能合约至关重要) 这也就上文中说过的nonce, ### 2.如何查看我们转账的状态 我们可以通过转账后拿到的TxHash去https://etherscan.io/查询。

2.如何取消Pending状态转账

上文说到了转账因为gas设置的比较小,可能造成无法成交,一直处于Pending状态。 然后我们可以通过nonce去取消Pending的转账, 我们通过nonce的机制可以得知,我们只要新创建一笔转账,其中nonce和Pending状态的订单的nonce一样就可以替换当前Pending状态得到转账。

那么最好的操作来实现就是发起一笔向自己转账的订单,当然gas我们需要设置得到>合理。 转账参考以上两种方法。

3.取消或者取代转账

通过之前2中所提到了,我们可以知道,其实一个交易发出后,被覆盖,代替,取消等操作的几率很小。但是也不是不可能。只要当前交易不被挖矿和包含在区块中,是可以做相关关操作的。 具体操作方法还是和3相似,但是切记不可更改nonce.(具体情况还要和实际相比较,毕竟这种操作实现的概率几乎为0)

上述过程需要翻墙

更新补充,(博主的Facebook和Twitter由于发送上述消息给封禁了,莫名其妙~)上诉过程测试网更改成Ropsten(https://infura.io/

)

image.png

这个端点获取测试币相交简单些
所以在构建Web3j实体,连接以太坊结点时构建web3j客户端参数更换一下

 web3j = Web3j.build(new HttpService("https://ropsten.infura.io/v3/b23bd4d475cd42978a9d29293d7fb317"));

获取测试币
https://faucet.ropsten.be/
在网站中输入钱包地址就ok了

image.png

查询交易记录
https://ropsten.etherscan.io/
同样是输入钱包地址
image.png

转账记录

  /****************交易*****************/
    private void transto() throws Exception {
        if (web3 == null) return;
        if (credentials == null) return;
        //开始发送0.01 =eth到指定地址
        String address_to = "0x41F1dcbC0794BAD5e94c6881E7c04e4F98908a87";
        TransactionReceipt send = Transfer.sendFunds(web3, 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());

打印结果:

19:28:37.062 [main] INFO com.yao.eth.util.Wallet - Transaction complete:
19:28:37.062 [main] INFO com.yao.eth.util.Wallet - trans hash=0xa8dd680b1fa7d82693d922f16f554746bba06ec0558daa0be30e6f50ed620071
19:28:37.062 [main] INFO com.yao.eth.util.Wallet - from :0x51003b4b5ee042480a6d2ee5f08ffd265ab311cf
19:28:37.062 [main] INFO com.yao.eth.util.Wallet - to:0x41f1dcbc0794bad5e94c6881e7c04e4f98908a87
19:28:37.062 [main] INFO com.yao.eth.util.Wallet - gas used=21000
19:28:37.062 [main] INFO com.yao.eth.util.Wallet - status: 0x1

把trans hash复制到框内,查询交易记录详情:https://ropsten.etherscan.io

image.png

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容

  • 本文列出2019年最新整理的用于区块链开发的43种流行的开发库、开发工具与开发框架。 1、MetaMask 人人都...
    编程狂魔阅读 2,132评论 0 1
  • 根据英文原版整理,内容有增删 1、开发语言、框架与工具 语言 Solidity - 官方推荐以太坊智能合约开发语言...
    Rakutens阅读 843评论 0 2
  • 目标读者: 专业的程序员; 想深入了解以太坊/区块链及其生态的读者; 如果你已经有一定的以太坊技术基础,只想研究一...
    编程狂魔阅读 1,659评论 0 11
  • 夜 上 安 澜 楼 文/安康Mr.车 曲 径 通 幽 望 江 亭 登 高 望...
    安康Mr车阅读 404评论 0 1