1. Introduction
1.介绍
In this article, we take a look at the EthereumJ library that allows us to interact with the Ethereum blockchain, using Java.
在本文中,我们看一下EthereumJ库,它允许我们使用Java与Ethereum区块链互动。
First, let’s just briefly dive into what this technology is all about.
首先,让我们简单地深入了解一下这项技术是怎么回事。
2. About Ethereum
2.关于以太坊
Ethereum is a cryptocurrency leveraging a distributed, peer-to-peer, database in the form of a programmable blockchain, the Ethereum Virtual Machine (EVM). It’s synchronized and operated through disparate but connected nodes.
以太坊是一种加密货币,利用分布式的、点对点的、可编程区块链形式的数据库,以太坊虚拟机(EVM)。它通过不同的但相连的节点进行同步和操作。
As of 2017, Nodes synchronize the blockchain through consensus, create coins through mining (proof of work), verify transactions, execute smart contracts written in Solidity, and run the EVM.
截至2017年,节点通过共识同步区块链,通过采矿(工作证明)创造硬币,验证交易,执行智能合约以Solidity编写,并运行EVM。
The blockchain is divided into blocks which contain account states (including transactions between accounts) and proof of work.
区块链被划分为区块,其中包含账户状态(包括账户之间的交易)和工作证明。
3. The Ethereum Facade
3、以太坊Facade
The org.ethereum.facade.Ethereum class abstracts and unites many packages of EthereumJ into one easy to use interface.
org.ethereum.facade.Ethereum类将EthereumJ的许多包抽象化并统一为一个易于使用的接口。
It’s possible to connect to a node to sync with the overall network and, once connected, we can work with the blockchain.
可以连接到一个节点,与整个网络同步,一旦连接,我们就可以与区块链一起工作。
Creating a facade object is as easy as:
创建一个门面对象是很容易的。
Ethereum ethereum = EthereumFactory.createEthereum();
4. Connecting to the Ethereum Network
4.连接到Ethereum网络
To connect to the network, we must first connect to a node, i.e. a server running the official client. Nodes are represented by the org.ethereum.net.rlpx.Node class.
要连接到网络,我们必须首先连接到一个节点,即一个运行官方客户端的服务器。节点由org.ethereum.net.rlpx.Node类表示。
The org.ethereum.listener.EthereumListenerAdapter handles blockchain events detected by our client after connection to a node has been established successfully.
org.ethereum.listener.EthereumListenerAdapter处理我们的客户端在成功建立与一个节点的连接后检测到的区块链事件。
4.1. Connecting to the Ethereum Network
4.1.连接到以太坊网络
Let’s connect to a node on the network. This can be done manually:
让我们连接到网络上的一个节点。这可以手动完成。
String ip = "http://localhost";
int port = 8345;
String nodeId = "a4de274d3a159e10c2c9a68c326511236381b84c9ec...";
ethereum.connect(ip, port, nodeId);
Connecting to the network can also be done automatically using a bean:
连接到网络也可以用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();
}
}
We can then inject our EthBean into our application configuration. Then it automatically connects to the Ethereum network and starts downloading the blockchain.
然后我们可以将我们的EthBean注入我们的应用程序配置中。然后它自动连接到以太坊网络并开始下载区块链。
In fact, the most connection processing is conveniently wrapped and abstracted by merely adding an org.ethereum.listener.EthereumListenerAdapter instance to our created org.ethereum.facade.Ethereum instance, as we did in our start() method above:
事实上,大部分连接处理都被方便地包装和抽象化了,只需在我们创建的org.ethereum.listener.EthereumListenerAdapter实例中添加一个org.ethereum.facade.Ethereum实例,正如我们在上面的start()方法中所做的。
EthBean eBean = new EthBean();
Executors.newSingleThreadExecutor().submit(eBean::start);
4.2. Handling the Blockchain Using a Listener
4.2.使用监听器处理区块链
We can also subclass the EthereumListenerAdapter to handle blockchain events detected by our client.
我们也可以子类化EthereumListenerAdapter 来处理我们的客户端检测到的区块链事件。
To accomplish this step, we’ll need to make our subclassed listener:
为了完成这一步,我们需要制作我们的子类化的监听器。
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;
}
}
}
The onBlock() method is triggered on any new block received (whether old or current). EthereumJ represents and handles blocks using the org.ethereum.core.Block class.
onBlock()方法在收到任何新区块(无论是旧的还是当前的)时被触发。EthereumJ使用org.ethereum.core.Block类表示和处理区块。
The onSyncDone() method fires once syncing is complete, bringing our local Ethereum data up-to-date.
一旦同步完成, onSyncDone()方法就会启动,使我们的本地以太坊数据达到最新状态。
5. Working With the Blockchain
5.与区块链一起工作
Now that we can connect to the Ethereum network and work directly with the blockchain, we’ll dive into several basic but nevertheless very important operations we’ll often use.
现在我们可以连接到以太坊网络并直接与区块链一起工作,我们将深入研究我们经常使用的几个基本但却非常重要的操作。
5.1. Submitting a Transaction
5.1.提交事务
Now, that we’ve connected to the blockchain we can submit a transaction. Submitting a Transaction is relatively easy but creating an actual Transaction is a lengthy topic by itself:
现在,我们已经连接到区块链,我们可以提交一个交易。提交一个交易是相对容易的,但创建一个实际的交易本身就是一个很长的话题。
ethereum.submitTransaction(new Transaction(new byte[]));
5.2. Access the Blockchain Object
5.2.访问区块链对象
The getBlockchain() method returns a Blockchain facade object with getters for fetching current network difficulties and specific Blocks.
getBlockchain()方法返回一个Blockchainfacade对象,其获取器用于获取当前网络困难和特定Block。
Since we set up our EthereumListener in section 4.3, we can access the blockchain using the above method:
由于我们在第4.3节中设置了我们的EthereumListener,我们可以使用上述方法访问区块链。
ethereum.getBlockchain();
5.3. Returning an Ethereum Account Address
5.3.返还以太坊账户地址
We can also return an Ethereum Address.
我们也可以返回一个以太坊的地址。
To get an Ethereum Account – we first need to authenticate a public and private key pair on the blockchain.
要获得一个以太坊账户 – 我们首先需要在区块链上认证一个公钥和私钥对。
Let’s create a fresh key with a new random key pair:
让我们用一个新的随机密钥对创建一个新的密钥。
org.ethereum.crypto.ECKey key = new ECKey();
And let’s create a key from a given private key:
让我们从一个给定的私钥中创建一个密钥。
org.ethereum.crypto.ECKey key = ECKey.fromPivate(privKey);
We can then use our key to initialize an Account. By calling .init() we set both an ECKey and the associated Address on the Account object:
然后我们可以使用我们的密钥来初始化一个Account。通过调用.init(),我们在Account对象上设置一个ECKey和相关的Address。
org.ethereum.core.Account account = new Account();
account.init(key);
6. Other Functionality
6.其他功能
There are two other major functionalities provided for by the framework that we won’t cover here but that are worth mentioning.
该框架还提供了另外两个主要功能,我们在此不作介绍,但值得一提。
First, we have the ability to compile and execute Solidity smart contracts. However, creating contracts in Solidity, and subsequently compiling and executing them is an extensive topic in its own right.
首先,我们有能力编译和执行Solidity智能合约。然而,在Solidity中创建合约,并随后编译和执行它们,本身就是一个广泛的话题。
Second, although the framework supports limited mining using a CPU, using a GPU miner is the recommended approach given the lack of profitability of the former.
其次,尽管框架支持使用CPU进行有限的采矿,但鉴于前者缺乏盈利能力,使用GPU矿机是推荐的方法。
More advanced topics regarding Ethereum itself can be found in the official docs.
关于以太坊本身的更多高级主题可以在官方文档中找到。
7. Conclusion
7.结论
In this quick tutorial, we showed how to connect to the Ethereum network and several important methods for working with the blockchain.
在这个快速教程中,我们展示了如何连接到以太坊网络以及与区块链合作的几个重要方法。
As always the code used in this example can be found over on GitHub.
像往常一样,这个例子中使用的代码可以在GitHub上找到over。