大概是个反射弧巨长,区块链的概念火了这么久,最近才开始学习区块链相关的技术。基础概念学完了,朋友推荐了宇宙第一链
:Ethereum
。经过了周末的学习,终于完成了第一个目标:第一笔转账。
分享一下学习过程和成果,仅供参考。文中涉及的知识均来源于官方文档,地址可以自行搜索。文档有中文版本,但是在代码实践部分还是英文居多。建议初学者把概念性的文档也看一遍,不要直接上手代码。
测试链
首先呢,我们需要在本地搭建一条测试链,就好像 HTTP 接口测试,我们需要一个本地的测试服务器一样。这个 po 一下官方提醒:您应该先理解以太坊堆栈和以太坊网络基础知识才能进入开发网络。
在官方给出的开发工具中,我选择了Ganache
,无他,因为它排在第一位。可以部署测试链,部署智能合约,完全满足了我的需求。
安装同其他软件,然后启动就可以界面:
对于新手而言,选择QUICKSTART
即可,就可以看到主页面。这里就不放图片占用篇幅了。启动成功后你就得到一个本地服务的 IP 和端口,这个就是代码中的host
值。关于如何获取主网的查询的host
这块,我建议小白先跳过,没必要在本地搞一个Ethereum
的客户端。
创建 Java 项目
由于我习惯用了 Java,所以先从 Java 开始。当然后面等我熟练了之后还是会尝试使用 Groovy 实现。后期计划用 Golang 再写一遍,这里不多说了。
我用了 Java 依赖Web3j
,就我看到的资料很多jsonrpc
的实现,本质上还是 HTTP 的请求。本来想着用FunTester
框架实现。但是目下的场景不太允许我这个区块链小白这么搞。
依赖配置:
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>4.3.0</version>
</dependency>
复制代码
然后需要个类和main
方法,其他无。
验证 Demo
当准备工作就绪,我们编写一些代码调用Ethereum
的 API 验证本地测试链是否有效。
import com.funtester.frame.SourceCode;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.EthProtocolVersion;
import org.web3j.protocol.http.HttpService;
import java.io.IOException;
public class Demo extends SourceCode {
static Web3j drive = Web3j.build(new HttpService("http://127.0.0.1:7545"));
public static void main(String[] args) throws IOException {
EthProtocolVersion send = drive.ethProtocolVersion().send();
output(parse(send));
}
}
复制代码
当控制台输出一下格式信息,表示环境搭建工作已经完成了。
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
♨ ♨ {
♨ ♨ ① ➤ "result":"0x3f",
♨ ♨ ① ➤ "protocolVersion":"0x3f",
♨ ♨ ① ➤ "id":0,
♨ ♨ ① ➤ "jsonrpc":"2.0"
♨ ♨ }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
复制代码
转账
Ethereum
的 API 很多,Web3j
都有对应的实现方法,虽然文档写测试链公共不全,但是就我目前使用来看,用来学习足够,没有遇到缺失的功能。
账号之前的转账是个非常重要的 API,相比其他查询 API 也是比较麻烦的,因为涉及到签名加密。PS:有文档写Ganache
允许无签名转账,这个我没试过,毕竟将来是要去主网冲浪的。
下面是转账的 Demo,其中 key 均为测试链上测试账号的,可以通过Ganache
页面上小钥匙按钮获得。
package com.funtester.ethereum;
import com.funtester.frame.SourceCode;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.*;
import org.web3j.protocol.http.HttpService;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Optional;
public class Demo extends SourceCode {
static Web3j drive = Web3j.build(new HttpService("http://127.0.0.1:7545"));
public static void main(String[] args) throws IOException, InterruptedException {
String privateKey = "0x04c02dc2381e1f69a274fa7cc4851c9eb01358fae8753dd4273014b43e34ab0c";
Credentials credentials = Credentials.create(privateKey);
EthGetTransactionCount ethGetTransactionCount = drive.ethGetTransactionCount(credentials.getAddress(), DefaultBlockParameterName.LATEST).send();
BigInteger nonce = ethGetTransactionCount.getTransactionCount();
String recipientAddress = "0x9483df5Bb8183548B4D7eb66B44C41FccD7c40A6";
BigInteger value = Convert.toWei("1", Convert.Unit.ETHER).toBigInteger();
BigInteger gasLimit = BigInteger.valueOf(22100);
BigInteger gasPrice = Convert.toWei("11", Convert.Unit.GWEI).toBigInteger();
RawTransaction rawTransaction = RawTransaction.createEtherTransaction(
nonce,
gasPrice,
gasLimit,
recipientAddress,
value);
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Numeric.toHexString(signedMessage);
EthSendTransaction ethSendTransaction = drive.ethSendRawTransaction(hexValue).send();
String transactionHash = ethSendTransaction.getTransactionHash();
Optional<TransactionReceipt> transactionReceipt = null;
do {
EthGetTransactionReceipt ethGetTransactionReceiptResp = drive.ethGetTransactionReceipt(transactionHash).send();
transactionReceipt = ethGetTransactionReceiptResp.getTransactionReceipt();
Thread.sleep(3000);
} while (!transactionReceipt.isPresent());
System.out.println("deal confirm");
}
}
复制代码
后面循环等待响应写得不够优雅,等熟练了封装一个趁手的方法。
控制台输出deal confirm
的话,说明转账已经被确认了。可以去Ganache
确认一下余额是否正确。当然可以通过Ethereum
的 API 查询对应账户的余额前后变化量是否与预期一致。
年轻人的第一笔Ethereum
转账已经完成。
评论