The purpose of this series of tutorials is to help you understand how to develop block chain technology. In this tutorial, we will:
- Create your first very basic block chain.
- Implement a simple workload certification system (mining).
- Explore any possibility.
I assume you have a basic understanding of object-oriented programming. It is noteworthy that this is not a fully functional production block chain. Instead, this is a proof-of-concept implementation that helps you understand the role of block chains in future tutorials.
To configure
We will use Java, but you should be able to use any OOP language. I'll use Eclipse, but you can use any new fancy text editor (although you'll miss a lot of good extensions).
You will need:
- Java and JDK are installed.
- Eclipse or other IDE.
Or you can get it through Google GSON Library . This will allow us to convert objects to Json. This is a very useful library, and we will use more in peer2peer, but we can use alternatives at will.
Create a Java project in Eclipse (file > New >). I'll call my project noobchain and use the same name to create a new class NoobChain.
Now you can try:)
Create block chains.
A block chain is just a chain/list block. Each block in the block chain has its own digital signature, including the digital signature of the previous block, and has some data (for example, these data may be transactions).
Hash = Digital signature.
Each block contains not only the hash value of the previous block, but also its own hash part is calculated from the previous hash. If the data of the previous block is changed, then the hash of the previous block will change (because it is partially computed by the data), and then affect all the hashes of the subsequent blocks. Computing and comparing hash values allows us to see whether block chains are invalid.
What's the meaning of this? ... Changing any data in this list will change the signature and break the block chain.
So let's first create the Block class that makes up the block chain:
import java.util.Date; public class Block { public String hash; public String previousHash; private String data; //our data will be a simple message. private long timeStamp; //as number of milliseconds since 1/1/1970. //Block Constructor. public Block(String data,String previousHash ) { this.data = data; this.previousHash = previousHash; this.timeStamp = new Date().getTime(); } }
As you can see, our basic block contains a String hash that will save our digital signature. The variable previousHash is used to save the hash and String data of the previous block to save our block data.
Next we need a way to generate digital signatures. You can choose many encryption algorithms, but SHA256 is suitable for this example. We can import java.security.MessageDigest; access the SHA256 algorithm.
We need to use SHA256 later to create a convenient helper method in the new StringUtil utility class:
import java.security.MessageDigest; public class StringUtil { //Applies Sha256 to a string and returns the result. public static String applySha256(String input){ try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); //Applies sha256 to our input, byte[] hash = digest.digest(input.getBytes("UTF-8")); StringBuffer hexString = new StringBuffer(); // This will contain hash as hexidecimal for (int i = 0; i < hash.length; i++) { String hex = Integer.toHexString(0xff & hash[i]); if(hex.length() == 1) hexString.append('0'); hexString.append(hex); } return hexString.toString(); } catch(Exception e) { throw new RuntimeException(e); } } }
If you don't understand the content of this help method, don't worry too much. What you need to know is that it needs a string and applies the SHA256 algorithm to it, and returns the generated signature as a string.
Now let's use our applySha256 helper to compute hash values in a new method of the Block class. We have to calculate the hash values for all parts of a block that we don't want to tamper with. So for our block, we will include previous Hash, data and timeStamp.
public String calculateHash() { String calculatedhash = StringUtil.applySha256( previousHash + Long.toString(timeStamp) + data ); return calculatedhash; }
And let's add this method to the Block constructor...
public Block(String data,String previousHash ) { this.data = data; this.previousHash = previousHash; this.timeStamp = new Date().getTime(); this.hash = calculateHash(); //Making sure we do this after we set the other values. }
Some test time...
In our main NoobChain class, we can create blocks and print hash values to the screen to see if everything works.
Let's test it... The first block is called genesis block, because there is no previous block, we just need to enter "0" as the previous hash.
public class NoobChain { public static void main(String[] args) { Block genesisBlock = new Block("Hi im the first block", "0"); System.out.println("Hash for block 1 : " + genesisBlock.hash); Block secondBlock = new Block("Yo im the second block",genesisBlock.hash); System.out.println("Hash for block 2 : " + secondBlock.hash); Block thirdBlock = new Block("Hey im the third block",secondBlock.hash); System.out.println("Hash for block 3 : " + thirdBlock.hash); } }
The output should be similar to:
Your values will vary, because your timestamps will vary.
Each block now has its own digital signature, based on its information and the signature of the previous block.
Now it's not a block chain, so let's store blocks in ArrayList and import them into gson as Json. (click) here Learn how to import gson Libraries
import java.util.ArrayList; import com.google.gson.GsonBuilder; public class NoobChain { public static ArrayList<Block> blockchain = new ArrayList<Block>(); public static void main(String[] args) { //add our blocks to the blockchain ArrayList: blockchain.add(new Block("Hi im the first block", "0")); blockchain.add(new Block("Yo im the second block",blockchain.get(blockchain.size()-1).hash)); blockchain.add(new Block("Hey im the third block",blockchain.get(blockchain.size()-1).hash)); String blockchainJson = new GsonBuilder().setPrettyPrinting().create().toJson(blockchain); System.out.println(blockchainJson); } }
Now our output should look closer to our expectations for block chains.
Now we need a way to check the integrity of block chains.
Let's create a Boolean method of isChainValid() in the NoobChain class that traverses all blocks in the chain and compares hash values. This method needs to check whether the hash variable is actually equal to the calculated hash value, and the hash value of the previous block is equal to the previous Hash variable.
public static Boolean isChainValid() { Block currentBlock; Block previousBlock; //loop through blockchain to check hashes: for(int i=1; i < blockchain.size(); i++) { currentBlock = blockchain.get(i); previousBlock = blockchain.get(i-1); //compare registered hash and calculated hash: if(!currentBlock.hash.equals(currentBlock.calculateHash()) ){ System.out.println("Current Hashes not equal"); return false; } //compare previous hash and registered previous hash if(!previousBlock.hash.equals(currentBlock.previousHash) ) { System.out.println("Previous Hashes not equal"); return false; } } return true; }
Any change to the block chain will cause this method to return false.
Bitcoin network nodes share their block chains, and the network accepts the longest effective chains. What prevents someone from tampering with data in old blocks and then creating a new, longer block chain and presenting it to the network? Workload certification. hashcash proof of the working system means that creating new blocks takes considerable time and computing power. Therefore, attackers need more computing power than other peer groups.
Let's start digging blocks!
We will require miners to prove their workload by trying different variable values in the block until their hash begins with a certain number of zeros.
Let's add an int called nonce to the calculateHash() method, as well as the mineBlock() method, which is badly needed:
import java.util.Date; public class Block { public String hash; public String previousHash; private String data; //our data will be a simple message. private long timeStamp; //as number of milliseconds since 1/1/1970. private int nonce; //Block Constructor. public Block(String data,String previousHash ) { this.data = data; this.previousHash = previousHash; this.timeStamp = new Date().getTime(); this.hash = calculateHash(); //Making sure we do this after we set the other values. } //Calculate new hash based on blocks contents public String calculateHash() { String calculatedhash = StringUtil.applySha256( previousHash + Long.toString(timeStamp) + Integer.toString(nonce) + data ); return calculatedhash; } public void mineBlock(int difficulty) { String target = new String(new char[difficulty]).replace('\0', '0'); //Create a string with difficulty * "0" while(!hash.substring( 0, difficulty).equals(target)) { nonce ++; hash = calculateHash(); } System.out.println("Block Mined!!! : " + hash); } }
In fact, each miner will iterate from a random point. Some miners can even try to get random numbers. It is also worth noting that in a more difficult solution, which may need to exceed integer.MAX_VALUE, miners can try to change the timestamp.
The mineBlock() method accepts an int called difficulty, which has to deal with a number of zero problems. On most computers, low-difficulty problems like 1 or 2 can be solved almost immediately. I recommend a difficulty test around 4-6. At the time of writing this article, Litecoin's difficulty was about 442,592.
Let's add difficulty as a static variable to the NoobChain class:
public static int difficulty = 5;
We should update the NoobChain class to touch the mineBlock() method for each new block. The isChainValid() Boolean value should also check whether each block has a resolved hash.
import java.util.ArrayList; import com.google.gson.GsonBuilder; public class NoobChain { public static ArrayList<Block> blockchain = new ArrayList<Block>(); public static int difficulty = 5; public static void main(String[] args) { //add our blocks to the blockchain ArrayList: blockchain.add(new Block("Hi im the first block", "0")); System.out.println("Trying to Mine block 1... "); blockchain.get(0).mineBlock(difficulty); blockchain.add(new Block("Yo im the second block",blockchain.get(blockchain.size()-1).hash)); System.out.println("Trying to Mine block 2... "); blockchain.get(1).mineBlock(difficulty); blockchain.add(new Block("Hey im the third block",blockchain.get(blockchain.size()-1).hash)); System.out.println("Trying to Mine block 3... "); blockchain.get(2).mineBlock(difficulty); System.out.println("\nBlockchain is Valid: " + isChainValid()); String blockchainJson = new GsonBuilder().setPrettyPrinting().create().toJson(blockchain); System.out.println("\nThe block chain: "); System.out.println(blockchainJson); } public static Boolean isChainValid() { Block currentBlock; Block previousBlock; String hashTarget = new String(new char[difficulty]).replace('\0', '0'); //loop through blockchain to check hashes: for(int i=1; i < blockchain.size(); i++) { currentBlock = blockchain.get(i); previousBlock = blockchain.get(i-1); //compare registered hash and calculated hash: if(!currentBlock.hash.equals(currentBlock.calculateHash()) ){ System.out.println("Current Hashes not equal"); return false; } //compare previous hash and registered previous hash if(!previousBlock.hash.equals(currentBlock.previousHash) ) { System.out.println("Previous Hashes not equal"); return false; } //check if hash is solved if(!currentBlock.hash.substring( 0, difficulty).equals(hashTarget)) { System.out.println("This block hasn't been mined"); return false; } } return true; } }
Note that we also check and print isChainValid.
Running this result should be as follows:
It takes some time to dig every block! (About 3 seconds) You should scramble the difficulty values to see how this affects the time it takes to dig each block.
If someone wants to tamper with the data in the block chain system:
- Their block chains are invalid.
- They can't create longer block chains.
- The honest block chain in your network will have a time advantage over the longest chain.
Tampered block chains will not be able to catch up with longer and more efficient chains.
Unless their computational speed is much faster than the sum of all the other nodes in the network. Quantum computers or something in the future.
You have completed the basic block chain!
Your block chain:
- It consists of blocks for storing data.
- Have a digital signature that links your blocks together.
- Work mining certificates are required to validate new blocks.
- You can check whether the data is valid and unchanged.
You can be there. Github Download project files.
======================================================================
Share some interactive online programming practical tutorials related to block chains such as ethernet, EOS, Bitcoin, etc.
- java Ethernet workshop development tutorial It is mainly for java and android programmers to develop block chain etheric workshop web3j in detail.
- python etheric workshop Mainly for python engineers to use web3.py for block chain Ethernet development in detail.
- php Ethernet It mainly introduces the use of php for intelligent contract development interaction, account creation, transactions, transfer, token development, filters and transactions.
- Introductory Course of ETF This paper mainly introduces the development of intelligent contract and dapp application, which is suitable for introduction.
- Advanced Course of ETF Development It mainly introduces how to use node.js, mongodb, block chain and ipfs to realize the de-centralized e-commerce DApp, which is suitable for advanced stage.
- C# Ethernet It mainly explains how to use C# to develop Ethernet Application Based on. Net, including account management, status and transaction, intelligent contract development and interaction, filters and transactions.
- EOS tutorial This course helps you get a quick start on the development of decentralized application of EOS block chain. It covers the core knowledge points of EOS toolchain, account and wallet, issuing tokens, intelligent contract development and deployment, code and intelligent contract interaction, and finally completes the development of a note DApp with all knowledge points.
- java Bitcoin Development Tutorial This course is for beginners. It covers the core concepts of Bitcoin, such as block chain storage, decentralized consensus mechanism, key and script, transaction and UTXO. It also explains in detail how to integrate Bitcoin support functions in Java code, such as creating addresses, managing wallets, building bare transactions, etc. It is a rare Bitcoin development course for Java engineers. .
- php Bitcoin Development Tutorial This course is for beginners. It covers the core concepts of Bitcoin, such as block chain storage, decentralized consensus mechanism, key and script, transaction and UTXO. It also explains in detail how to integrate Bitcoin support functions in Php code, such as creating addresses, managing wallets, building bare transactions, etc. It is a rare Bitcoin development course for Php engineers.
- Detailed description of tendermint block chain development This course is suitable for engineers who want to use tendermint to develop block chains. It includes the core concepts of tendermint application development model, such as ABCI interface, Merkel tree, multi-version state library, and rich practical codes such as token issuance. It is the best choice for go language engineers to develop fast-start block chains.
Huizhi original translation, reprinted please indicate the source. Here is the original text. Create the first block chain using Java