There are several ways to create an Ethereum wallet, typically through geth, EtherumWallet and other clients. For the front end, you can create it using the plug-in MetaMask. Although these methods are different, the underlying principle is the same. This article focuses on how to create an Ethereum cold wallet using the Web3J architecture to deploy the process on the server or Android side.

The technology stacks mentioned in this paper are:

Web3j: Lightweight Java library for connecting ethereum clients or nodes

Infura: Ethereum infrastructure for accessing the main or test network of Ethereum

Java: Programming language

1. Web3j installation

For both Java and Android projects, Web3J provides maven and Grade dependencies:

  1. Java project
  • Manen rely on
<dependency>
  <groupId>org.web3j</groupId>
  <artifactId>core</artifactId>
  <version>3.3.1</version>
</dependency>
Copy the code
  • Gradle rely on
compile ('org. Web3j: core: 3.3.1')
Copy the code
  1. The android project
  • Maven rely on
<dependency>
  <groupId>org.web3j</groupId>
  <artifactId>core</artifactId>
  <version>3.3.1 - android</version>
</dependency>
Copy the code
  • Gradle rely on
compile ('org. Web3j: core: 3.3.1 - android')
Copy the code

It is worth noting that web3J is incompatible with older JDK versions. If the following problems occur, simply replace the JDK with version 8.

Could not determine Java version using executable /Library/Java/JavaVirtualMachines/jdk-10.jdk/Contents/Home/bin/java.

2. About Infura

There are several client implementations of Ethereum, but many require local synchronization of all node data, taking up a lot of hard disk storage space and consuming synchronization time. Infura is a centralized service that enables the front-end or server to easily access all ethereum nodes through Web3.js or Web3J. It can be understood as a cloud version of ethereum client. The use process requires registration, a proprietary access token. The clients used in this article are the Rinkeby test network provided by Infura.

3. Create the wallet file keyFile

In Ethereum, a wallet and an account are two different concepts. The account is the heart of Ethereum and consists of a pair of secret keys — public and private. There are two types of accounts, external accounts and contract accounts. A wallet is a file or other institution that holds an address, public key, private key, and each wallet file contains at least one account. Creating a wallet is also the process of creating an Ethereum account. Different clients create a wallet in different ways but the principle is the same. See this article for details on how a wallet is generated.

  1. Create a New Java project and initialize Gradle or Maven
  2. Rely on web3j
  3. Create a new application. Java file and set the main function
  4. Call the wallet utility class to generate the wallet file
/************* Create a wallet file **************/
private void creatAccount(a) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, CipherException, IOException {
    String walletFileName0="";/ / file name
    String walletFilePath0="/Users/yepeng/MyGitHub/z_wallet_temp";
    // Keep the wallet file path, please replace your folder path

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

The wallet construction process needs to enter three parameters, respectively set the password of the wallet, save path, and whether the lightweight wallet.

After executing the create function, a JSON file, wallet KeyFiles, is automatically generated in the specified path.

Wallet file structure:

  • Cipher: encryption algorithm, AES algorithm, used to encrypt ethereum private key
  • Cipherparams: indicates the parameter required by the cipher algorithm. Parameter IV is the initialization vector required by the AES-128-CTR encryption algorithm
  • Ciphertext: indicates the encrypted ciphertext. The ciphertext is the encrypted input of the AES-128-CTR function.
  • KDF: key generation function, used to encrypt keystore file with password
  • Kdfparams: parameters required by the KDF algorithm
  • MAC: indicates the code of the authentication password

The reverse process of generating a wallet is to load the wallet.

4. Load the wallet file

The process of loading a wallet requires the wallet file and password

/******** Load the wallet file **********/
private void loadWallet(a) throws IOException, CipherException {
    String walleFilePath="/ Users/yepeng/MyGitHub/z_wallet_temp/UTC - 2018-04-10 T02-51-24.815000000 - Z - 12571 f46ec3f81f7ebe79112be5883194d683787. 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);

}
Copy the code

The result of a function run:

The loadCredentials() function of the utility class WalletUtols returns an object credential containing all the information about the wallet file, including the address and the secret key pair.

At this point, the wallet is created and loaded, but it all happens locally and is not synchronized to the Ethereum blockchain. Before querying the address balance, you need to connect the Ethereum node.

5. Build Web3j entities and connect ethereum nodes

Web3j is the bridge between The Java side and Ethereum. Broadcasting transactions and querying accounts are all required through Web3J entities. Web3j supports building over HTTP and is infura compatible. In this article, Infura’s test network, Rinkeby, is used.

/******* Connect to the Ethereum client **************/
private void conectETHclient(a) throws IOException {
    Connection mode 1: use the client provided by Infura
    web3j = Web3j.build(new HttpService("https://rinkeby.infura.io/zmd7VgRt9go0x6qlJ2Mk"));// TODO:Token changed to own
    // Connection mode 2: Use the local client
    / / web3j = web3j. Build (new HttpService (127.0.0.1: "7545"));
    // Test whether the connection is successful
    String web3ClientVersion = web3j.web3ClientVersion().send().getWeb3ClientVersion();
    log.info("version=" + web3ClientVersion);
}
Copy the code

Once the Web3J entity has been built, you can print out this number to test if the connection is successful. If successful, you can move on to other things. It is worth noting that Web3J is designed with RxJava, so many functions return Request, which can be executed in two ways, asynchronous and synchronous, namely send() and sendAsyn().

6. Check the account balance

Check the balance of your account:

/*********** Query the balance of the specified address ***********/
private void getBlanceOf(a) throws IOException {
    if (web3j == null) return;
    String address = "0x41F1dcbC0794BAD5e94c6881E7c04e4F98908a87";// Wait to query the balance of the address
    // The second parameter: block parameter. You are advised to select the latest block
    EthGetBalance balance = web3j.ethGetBalance(address, DefaultBlockParameter.valueOf("latest")).send();
    // Format transformation wei-ether
    String blanceETH = Convert.fromWei(balance.getBalance().toString(), Convert.Unit.ETHER).toPlainString().concat(" ether");
    log.info(blanceETH);
}
Copy the code

The second parameter in the core method web3j.ethgetbalance (address, defaultBlockParameter) is special and refers to the defaultBlockParameter. This parameter determines the height of the query block when the balance request method interacts with ethereum’s block network.

  • HEX String– An integer block number
  • String "earliest"Is the earliest/origin block
  • String "latest"– For the latest mining blocks
  • String "pending"– Pending status/transaction

In most cases, select Latest.

In Ethereum, numbers are in 18 decimal places unless specified, so it is necessary to convert wei to ether to query the account balance.

6. Use your wallet to transfer money

As a wallet, in addition to saving account assets, the most important thing is to transfer money or trade. Using Web3J, ETH can be easily transferred.

/    / * * * * * * * * * * * * * * * * trade * * * * * * * * * * * * * * * * * /
    private void transto(a) throws Exception {
        if (web3j == null) return;
        if (credentials == null) return;
        // Start sending 0.01 =eth to the specified address
        String address_to = "0x41F1dcbC0794BAD5e94c6881E7c04e4F98908a87";
        TransactionReceipt send = Transfer.sendFunds(web3j, 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());
    }
Copy the code

The core method needs to provide four parameters:

  • Web3j entity
  • Source account Credentials
  • Address Indicates the outgoing address
  • The value amount
  • Uint unit

After waiting for a while, the transfer result will be returned

You can see transaction hashes, roll-in and roll-out addresses, gas consumption, and more. Details of the transaction can also be viewed on EtherScan-Rinkeby

7. To summarize

The code above has completed all the basic functions required for an Ethereum wallet, including creating, loading, transferring, and querying. In this paper by using the network is infura Rinkeby test network, address 0 x12571f46ec3f81f7ebe79112be5883194d683787 create a wallet.

In a specific business scenario, simply replace the test network with the main Ethereum network.

Source address github.com/initsysctrl…