One of the buzzwords in the IT world of blockchain recently. This technology about digital cryptocurrencies, together with Bitcoin, constitutes this hot trend. It is a decentralized, immutable block data structure, which is a cryptographic algorithm that can be securely connected and used. Each block in this structure usually contains a cryptographic hash of the previous block, a timestamp, and transaction data. The blockchain is a peer-to-peer management network, and verification of inter-node communication is performed before each new block is added. This is part of the theory about blockchain. In short, this is a technology that allows us to manage transactions between two parties in a decentralized way. Now, the question is how do we implement it in our system.
So Ethereum came. This is a decentralized platform provided by Vitarik Buterin, which can create development applications through scripting languages. The idea was derived from Bitcoin and powered by a new cryptocurrency called Ether, or Ethereum. Today, Ethereum is the second largest encrypted digital currency after Bitcoin. The core of Ethereum technology is EVM (Ethereum Virtual Machine), which can be considered similar to the Java Virtual Machine and uses a completely decentralized network of nodes. To implement Ethereum transactions based on the java world, we use the web3j library. This is a lightweight, responsive, type-safe Java and Android library that combines Ethereum blockchain nodes. More details can be found here web3j.io Chinese version.
1. Run locally
Although there are many articles on blockchain, it is not easy to find a solution in Ethereum-related web content describing how to prepare to run Ethereum on a local machine using examples. It is worth mentioning that there are generally two basic clients that can be used: Geth and Parity. It turned out that we could easily run the node locally using a Docker container. By default, the Ethereum main network (public chain) that connects the nodes. Alternatively, you can connect it to a test network or Rinkeby network. But the best option to start with is to run in development mode with the development parameters set (--dev) and run commands in a Docker container.
The following command starts the Docker container development mode to call the Ethereum RPC API on port 8545.
$ docker run -d --name ethereum -p 8545: 8545 -p 30303: 30303 ethereum / client-go --rpc --rpcaddr "0.0.0.0" --rpcapi = "db, eth, net, web3, personal" --rpccorsdomain "*" --dev
When running the container in development mode, a very good news is that there is a large amount of Ether on the default test account. In this case, you don't have to dig any Ether to start testing. Excellent! Now let's create some other test accounts and do some checks. To achieve this, we need to run Geth's interactive JavaScript console inside the container.
$ docker exec -it ethereum geth attach ipc: /tmp/geth.ipc
2.Ethereum node management using JavaScript console
Running the JavaScript console makes it easy to display the default account (Coinbase), a list of all available accounts and their balances. The screen here shows my Ethereum results.
Now we have to create some test accounts. We can do this by calling the personal.newAccount (password) function. After creating the required accounts, we can use the JavaScript console to perform some test transactions and transfer some funds from the base account to the newly created account. Below are the commands used to create an account and execute transactions.
3. System architecture
The architecture of our demo system is very simple. Don't think about complicated things, just tell everyone how to send transactions to geth nodes and receive transaction receipts. The transaction-service sends new transactions to the Ethereum node, and the bonus-service node listens for incoming transactions. The sender's account then receives a bonus every 10 transactions. The diagram here illustrates the system architecture of our demo.
4.Spring boot application using web3j
I think now we know exactly what we want to do. So let's implement it. First, we should include all the required dependencies to be able to use the web3j library in a Spring boot application. Fortunately, there is a starter available.
<dependency>
<groupId> org.web3j </ groupId>
<artifactId> web3j-spring-boot-starter </ artifactId>
<version> 1.6.0 </ version>
</ dependency>
Because we run the Ethereum client in a Docker container, we need to change the web3j calling address of the client's automatic default configuration.
spring:
application:
name: transaction-service
server:
port: $ {PORT: 8090}
web3j:
client-address: http://192.168.99.100:8545
5. Build the application
If we include the web3j starter into the project dependencies, all we need is to load the web3j beans automatically. web3j is responsible for sending transactions to Geth client nodes. It receives the response with a transaction hash, whether it was accepted by the node or rejected due to an error. When creating a transaction object, it is important to set the gas limit minimum to 21000. If you send a lower value, you may receive an error message: intrinsic gas too low.
@Service
public class BlockchainService {
private static final Logger LOGGER = LoggerFactory.getLogger (BlockchainService.class);
@Autowired
Web3j web3j;
public BlockchainTransaction process (BlockchainTransaction trx) throws IOException {
EthAccounts accounts = web3j.ethAccounts (). Send ();
EthGetTransactionCount transactionCount = web3j.ethGetTransactionCount (accounts.getAccounts (). Get (trx.getFromId ()), DefaultBlockParameterName.LATEST) .send ();
Transaction transaction = Transaction.createEtherTransaction (accounts.getAccounts (). Get (trx.getFromId ()), transactionCount.getTransactionCount (), BigInteger.valueOf (trx.getValue ()), BigInteger.valueOf (21_000), accounts.getAccounts ( ) .get (trx.getToId ()), BigInteger.valueOf (trx.getValue ()));
EthSendTransaction response = web3j.ethSendTransaction (transaction) .send ();
if (response.getError ()! = null) {
trx.setAccepted (false);
return trx;
}
trx.setAccepted (true);
String txHash = response.getTransactionHash ();
LOGGER.info ("Tx hash: {}", txHash);
trx.setId (txHash);
EthGetTransactionReceipt receipt = web3j.ethGetTransactionReceipt (txHash) .send ();
if (receipt.getTransactionReceipt (). isPresent ()) {
LOGGER.info ("Tx receipt: {}", receipt.getTransactionReceipt (). Get (). GetCumulativeGasUsed (). IntValue ());
}
return trx;
}
}
@Service is called by the controller from the above code. The POST method requires a BlockchainTransaction object as a parameter. You can send sender ID, recipient ID and transaction amount. The sender and receiver IDs are queried via eth.account [index].
@RestController
public class BlockchainController {
@Autowired
BlockchainService service;
@PostMapping ("/ transaction")
public BlockchainTransaction execute (@RequestBody BlockchainTransaction transaction) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, CipherException, IOException {
return service.process (transaction);
}
}
You can use the following command to call the POST method to send a test transaction.
You should unlock the sender's account before sending any transactions.
$ curl --header "Content-Type: application / json" --request POST --data '{"fromId": 2, "toId": 1, "value": 3}' http: // localhost: 8090 / transaction
The application bonus-service listens to transactions processed by Ethereum nodes. It subscribes notification messages from the web3j library by calling the web3j.transactionObservable (). Subscribe (...) method. It will send to the sender's account once every 10 transactions return from this address. The following is the implementation of listenable methods in bonus-service.
@Autowired
Web3j web3j;
@PostConstruct
public void listen () {
Subscription subscription = web3j.transactionObservable (). Subscribe (tx-> {
LOGGER.info ("New tx: id = {}, block = {}, from = {}, to = {}, value = {}", tx.getHash (), tx.getBlockHash (), tx.getFrom ( ), tx.getTo (), tx.getValue (). intValue ());
try {
EthCoinbase coinbase = web3j.ethCoinbase (). Send ();
EthGetTransactionCount transactionCount = web3j.ethGetTransactionCount (tx.getFrom (), DefaultBlockParameterName.LATEST) .send ();
LOGGER.info ("Tx count: {}", transactionCount.getTransactionCount (). IntValue ());
if (transactionCount.getTransactionCount (). intValue ()% 10 == 0) {
EthGetTransactionCount tc = web3j.ethGetTransactionCount (coinbase.getAddress (), DefaultBlockParameterName.LATEST) .send ();
Transaction transaction = Transaction.createEtherTransaction (coinbase.getAddress (), tc.getTransactionCount (), tx.getValue (), BigInteger.valueOf (21_000), tx.getFrom (), tx.getValue ());
web3j.ethSendTransaction (transaction) .send ();
}
} catch (IOException e) {
LOGGER.error ("Error getting transactions", e);
}
});
LOGGER.info ("Subscribed");
to sum up
Blockchain and digital currencies are not easy topics to start with. By providing a complete scripting language, Ethereum simplifies the difficulty of application development using the blockchain. Using web3j, spring boot, and docker container images of the Ethereum geth client, you can quickly launch the solution and achieve local development of blockchain technology.
If you want to clone my library for local development, you can download the source code on github.
If you want to quickly develop web3j, java, and Ethereum, please see our carefully crafted tutorials:
The web3j tutorial is a detailed web3j development for blockchain and Ethereum for java and android programmers.
Other Ethereum tutorials are as follows:
Ethereum tutorial, which mainly introduces smart contract and dapp application development, is suitable for getting started.
Ethereum development mainly introduces the use of node.js, mongodb, blockchain, and ipfs to implement decentralized e-commerce DApp combat, which is suitable for advanced.
Python Ethereum is mainly a detailed explanation of blockchain Ethereum development using python engineers using web3.py.
PHP Ethereum mainly introduces the use of PHP for smart contract development interaction, account creation, transactions, transfers, token development, and filters and events.
C # Ethereum, mainly explains how to use C # to develop .Net-based Ethereum applications, including account management, status and transactions, smart contract development and interaction, filters and events.