Ethereumj 简介
1. 简介
在本文中,我们看一下EthereumJ 库,它允许我们使用 Java与Ethereum 区块链进行交互。
首先,让我们简要介绍一下这项技术的全部内容。
2. 关于以太坊
以太坊 是一种加密货币,它利用可编程blockchain形式的分布式点对点数据库,即以太坊虚拟机 (EVM)。它通过不同但连接的nodes进行同步和操作。
截至 2017 年,nodes通过共识同步blockchain ,通过挖掘创建硬币(proof of work),验证交易,执行用Solidity 编写的smart contracts,并运行 EVM。
blockchain 分为包含account states(包括account之间的交易)和proof of work的区块。
3. *Ethereum *门面类
org.ethereum.facade.Ethereum类将EthereumJ的许多包抽象并统一到一个易于使用的接口中。
可以连接到一个节点以与整个网络同步,一旦连接,我们就可以使用区块链。
创建外观对象很简单:
Ethereum ethereum = EthereumFactory.createEthereum();
4. 连接以太坊网络
要连接网络,我们必须先连接到一个节点,即运行官方客户端的服务器。节点由org.ethereum.net.rlpx.Node类表示。
org.ethereum.listener.EthereumListenerAdapter处理我们的客户端在成功建立与节点的连接后检测到的区块链事件。
4.1. 连接到以太坊网络
让我们连接到网络上的一个节点。这可以手动完成:
String ip = "http://localhost";
int port = 8345;
String nodeId = "a4de274d3a159e10c2c9a68c326511236381b84c9ec...";
ethereum.connect(ip, port, nodeId);
也可以使用 bean 自动连接到网络:
public class EthBean {
private Ethereum ethereum;
public void start() {
ethereum = EthereumFactory.createEthereum();
ethereum.addListener(new EthListener(ethereum));
}
public Block getBestBlock() {
return ethereum.getBlockchain().getBestBlock();
}
public BigInteger getTotalDifficulty() {
return ethereum.getBlockchain().getTotalDifficulty();
}
}
然后我们可以将我们的EthBean注入到我们的应用程序配置中。然后它会自动连接到以太坊网络并开始下载区块链。
事实上,大多数连接处理都被方便地包装和抽象,只需将org.ethereum.listener.EthereumListenerAdapter实例添加到我们创建的org.ethereum.facade.Ethereum实例中,就像我们在上面的*start()*方法中所做的那样:
EthBean eBean = new EthBean();
Executors.newSingleThreadExecutor().submit(eBean::start);
4.2. 使用监听器处理区块链
我们还可以继承 EthereumListenerAdapter来处理我们的客户端检测到的区块链事件。
为了完成这一步,我们需要创建我们的子类监听器:
public class EthListener extends EthereumListenerAdapter {
private void out(String t) {
l.info(t);
}
//...
@Override
public void onBlock(Block block, List receipts) {
if (syncDone) {
out("Net hash rate: " + calcNetHashRate(block));
out("Block difficulty: " + block.getDifficultyBI().toString());
out("Block transactions: " + block.getTransactionsList().toString());
out("Best block (last block): " + ethereum
.getBlockchain()
.getBestBlock().toString());
out("Total difficulty: " + ethereum
.getBlockchain()
.getTotalDifficulty().toString());
}
}
@Override
public void onSyncDone(SyncState state) {
out("onSyncDone " + state);
if (!syncDone) {
out(" ** SYNC DONE ** ");
syncDone = true;
}
}
}
*onBlock()*方法在接收到的任何新块(无论是旧的还是当前的)上触发。EthereumJ 使用org.ethereum.core.Block类表示和处理块。
一旦同步完成,*onSyncDone()*方法就会触发,从而使我们的本地以太坊数据保持最新。
5. 使用区块链
现在我们可以连接到以太坊网络并直接使用区块链,我们将深入研究我们经常使用的几个基本但非常重要的操作。
5.1. 提交交易
现在,我们已经连接到区块链,我们可以提交交易。提交Transaction相对容易,但创建实际Transaction本身就是一个冗长的话题:
ethereum.submitTransaction(new Transaction(new byte[]));
5.2. 访问Blockchain对象
getBlockchain()方法返回一个带有 getter的Blockchain外观对象,用于获取当前的网络困难和特定的Blocks。
由于我们在 4.3 节中设置了EthereumListener,我们可以使用上述方法访问区块链:
ethereum.getBlockchain();
5.3. 返回以太坊账户地址
我们还可以返回一个以太坊Address。
要获得以太坊Account——我们首先需要在区块链上验证公钥和私钥对。
让我们用一个新的随机密钥对创建一个新的密钥:
org.ethereum.crypto.ECKey key = new ECKey();
让我们从给定的私钥创建一个密钥:
org.ethereum.crypto.ECKey key = ECKey.fromPivate(privKey);
然后我们可以使用我们的密钥来初始化一个Account。通过调用*.init()我们在Account对象上设置ECKey和关联的Address*:
org.ethereum.core.Account account = new Account();
account.init(key);
6. 其他功能
该框架还提供了另外两个主要功能,我们不会在这里介绍,但值得一提。
首先,我们有能力编译和执行 Solidity 智能合约。然而,在 Solidity 中创建合约,然后编译和执行它们本身就是一个广泛的话题。
其次,虽然该框架支持使用 CPU 进行有限挖矿,但鉴于前者缺乏盈利能力,建议使用 GPU 矿工。
有关以太坊本身的更高级主题可以在官方文档 中找到。