The generation process of bitcoin wallet address

  1. Run the OpenSSL command to randomly generate a key pair

Generates the private key for the elliptic curve

openssl ecparam -name secp256k1 -genkey -out ec-priv.pem
Copy the code

After the preceding command is executed, the ec-prive.pem file is generated and quickly decoded to a readable hexadecimal format.

openssl ec -in ec-priv.pem -text -noout
Copy the code

Take out the public key part of the above key pair and store it in an external file called EC-pub.pem:

openssl ec -in ec-priv.pem -pubout -out ec-pub.pem
Copy the code

And then decode it

openssl ec -in ec-pub.pem -pubin -text -noout
Copy the code

The public key section is displayed

read EC key
Private-Key: (256 bit)
pub: 
    04:4d:d2:58:cc:3e:05:0b:57:02:99:ef:45:de:5d:
    96:e5:24:05:10:96:a2:a9:ae:52:d2:2b:a8:92:7b:
    16:7f:ce:f2:97:f3:5a:0d:e8:b7:c5:78:92:64:d2:
    de:85:8d:c8:58:2c:39:36:8c:39:9f:d9:1d:c5:a9:
    2c:33:d8:5a:a1
ASN1 OID: secp256k1
Copy the code

  1. Sha-256 encryption is performed on the public key to extract the hexadecimal public key and convert it to a string
044dd258cc3e050b570299ef45de5d96e524051096a2a9ae52d22ba8927b167fcef297f35a0de8b7c5789264d2de858dc8582c39368c399fd91dc5a92c3 3d85aa1Copy the code

Then use SHA-256 encryption

        byte[] publicKey = new BigInteger("044dd258cc3e050b570299ef45de5d96e524051096a2a9ae52d22ba8927b167fcef297f35a0de8b7c5789264d2de858dc8582c39368c399fd91dc5a 92c33d85aa1".16).toByteArray();
        byte[] sha256Bytes = Utils.sha256(publicKey);
        System.out.println("Sha256 encryption =" + Utils.bytesToHexString(sha256Bytes));
Copy the code

Execution Result:

= C96A913851413BDC2FBF5CC60085CA2C23FB8289B44BDDAD5FC15226DB1E30A7 sha256 encryptionCopy the code
  1. RIPEMD160 is used for encryption

Bouncycastle is used for RIPEMD160 encryption.

        RIPEMD160Digest digest = new RIPEMD160Digest();
        digest.update(sha256Bytes, 0, sha256Bytes.length);
        byte[] ripemd160Bytes = new byte[digest.getDigestSize()];
        digest.doFinal(ripemd160Bytes, 0);

        System.out.println("Ripemd160 digest encryption =" + Utils.bytesToHexString(ripemd160Bytes));
Copy the code

Execution Result:

Ripemd160 digest encryption =9AF1DD0C939624E1984CB56B44B9C5F28E6B21FF
Copy the code
  1. Before adding the version number to the above encryption result, it becomes 21 bits where Main Network: 0x00, Test Network: 0x64, Namecoin Net: 0x34

Here, use Main Network

        byte[] networkID = new BigInteger("00".16).toByteArray();
        byte[] extendedRipemd160Bytes = Utils.add(networkID, ripemd160Bytes);

        System.out.println("Add NetworkID =" + Utils.bytesToHexString(extendedRipemd160Bytes));
Copy the code

Execution Result:

Add the NetworkID =009AF1DD0C939624E1984CB56B44B9C5F28E6B21FF
Copy the code
  1. Sha-256 encryption twice
        byte[] twiceSha256Bytes = Utils.sha256(Utils.sha256(extendedRipemd160Bytes));

        System.out.println("Sha256 encrypted twice =" + Utils.bytesToHexString(twiceSha256Bytes));
Copy the code

Execution Result:

Sha256 encryption twice =1C17FA056AABA3B6B9768F83F460BC190D19CC2890D933249781D476451D22B4
Copy the code
  1. The first 4bytes of the sha-256 result are used as the checksum of the address
        byte[] checksum = new byte[4];
        System.arraycopy(twiceSha256Bytes, 0, checksum, 0.4);

        System.out.println("checksum=" + Utils.bytesToHexString(checksum));
Copy the code

Execution Result:

checksum=1C17FA05
Copy the code
  1. Generate a 25-byte binary Bitcoin Address

You need to add the checksum to the end of step 4 to form a 25-bit address.

        byte[] binaryBitcoinAddressBytes = Utils.add(extendedRipemd160Bytes, checksum);

        System.out.println("Add checksum =" + Utils.bytesToHexString(binaryBitcoinAddressBytes));
Copy the code

Execution Result:

Add checksum =009AF1DD0C939624E1984CB56B44B9C5F28E6B21FF1C17FA05
Copy the code
  1. Generate the wallet address of bitcoin using Base58 encoding
        String bitcoinAddress = Base58.encode(binaryBitcoinAddressBytes);
        System.out.println("bitcoinAddress=" + bitcoinAddress);
Copy the code

Execution Result:

bitcoinAddress=1F8GoWchAb56ePqftqRvLf7L729JGQSdqW
Copy the code

The code for the whole process above:

        byte[] publicKey = new BigInteger("044dd258cc3e050b570299ef45de5d96e524051096a2a9ae52d22ba8927b167fcef297f35a0de8b7c5789264d2de858dc8582c39368c399fd91dc5a 92c33d85aa1".16).toByteArray();
        byte[] sha256Bytes = Utils.sha256(publicKey);
        System.out.println("Sha256 encryption =" + Utils.bytesToHexString(sha256Bytes));

        RIPEMD160Digest digest = new RIPEMD160Digest();
        digest.update(sha256Bytes, 0, sha256Bytes.length);
        byte[] ripemd160Bytes = new byte[digest.getDigestSize()];
        digest.doFinal(ripemd160Bytes, 0);

        System.out.println("Ripemd160 digest encryption =" + Utils.bytesToHexString(ripemd160Bytes));

        byte[] networkID = new BigInteger("00".16).toByteArray();
        byte[] extendedRipemd160Bytes = Utils.add(networkID, ripemd160Bytes);

        System.out.println("Add NetworkID =" + Utils.bytesToHexString(extendedRipemd160Bytes));

        byte[] twiceSha256Bytes = Utils.sha256(Utils.sha256(extendedRipemd160Bytes));

        System.out.println("Sha256 encrypted twice =" + Utils.bytesToHexString(twiceSha256Bytes));

        byte[] checksum = new byte[4];
        System.arraycopy(twiceSha256Bytes, 0, checksum, 0.4);

        System.out.println("checksum=" + Utils.bytesToHexString(checksum));

        byte[] binaryBitcoinAddressBytes = Utils.add(extendedRipemd160Bytes, checksum);

        System.out.println("Add checksum =" + Utils.bytesToHexString(binaryBitcoinAddressBytes));

        String bitcoinAddress = Base58.encode(binaryBitcoinAddressBytes);
        System.out.println("bitcoinAddress=" + bitcoinAddress);
Copy the code

Execution Result:

= = sha256 encryption C96A913851413BDC2FBF5CC60085CA2C23FB8289B44BDDAD5FC15226DB1E30A7 ripemd160 digest encryption9Add NetworkID AF1DD0C939624E1984CB56B44B9C5F28E6B21FF =009AF1DD0C939624E1984CB56B44B9C5F28E6B21FF sha256 encryption = twice1C17FA056AABA3B6B9768F83F460BC190D19CC2890D933249781D476451D22B4
checksum=1C17FA05 Checksum =009AF1DD0C939624E1984CB56B44B9C5F28E6B21FF1C17FA05
bitcoinAddress=1F8GoWchAb56ePqftqRvLf7L729JGQSdqW
Copy the code

Finally, now that we’ve generated the wallet address, how do we validate it?

Can access the website: http://lenschulwitz.com/base58

Verify the final results

You can see that the above address is the correct one.

conclusion

The whole process simulates the generation of bitcoin wallet address, which is my review of the learning process of bitcoin wallet address.

All the code is on Github,

Making address: https://github.com/fengzhizi715/blockchain_study