├── .gitignore
├── pom.xml
├── src
└── main
│ └── java
│ ├── Demo.java
│ ├── Block.java
│ ├── StringUtil.java
│ └── ImportChain.java
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Example user template template
3 | ### Example user template
4 |
5 | # IntelliJ project files
6 | .idea
7 | *.iml
8 | out
9 | gen
10 | .idea/
11 | blockchain-samples.iml
12 | target/
13 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.importsource
8 | blockchain-samples
9 | 1.0-SNAPSHOT
10 |
11 |
12 | com.google.code.gson
13 | gson
14 | 2.8.2
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/main/java/Demo.java:
--------------------------------------------------------------------------------
1 | import com.google.gson.GsonBuilder;
2 |
3 | import java.util.ArrayList;
4 |
5 | /**
6 | * @author hezhuofan
7 | */
8 | public class Demo {
9 | public static ArrayList blockchain = new ArrayList();
10 |
11 | public static void main(String[] args) {
12 | //add our blocks to the blockchain ArrayList:
13 | blockchain.add(new Block("Hi im the first block", "0"));
14 | blockchain.add(new Block("Yo im the second block",blockchain.get(blockchain.size()-1).hash));
15 | blockchain.add(new Block("Hey im the third block",blockchain.get(blockchain.size()-1).hash));
16 |
17 | String blockchainJson = new GsonBuilder().setPrettyPrinting().create().toJson(blockchain);
18 | System.out.println(blockchainJson);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 自己动手写区块链系列
2 |
3 | 关注此公众号了解更多相关内容
4 |
5 |
6 |
7 | ### 1.0.区块链基本的了解
8 |
9 | 参阅:https://www.zhihu.com/question/20792042
10 |
11 | ### 1.1.自己动手写区块链-创建一个基本的区块链雏形(Java版)
12 |
13 | github地址:https://github.com/importsource/blockchain-samples
14 |
15 | 开发指南:https://mp.weixin.qq.com/s?__biz=MzA5MzQ2NTY0OA==&mid=2650797410&idx=1&sn=c16d1b0064768479a05dc65cf2b542d3&chksm=8856283dbf21a12be25300c012dc344199320f54a13b54d595c4db899d74ede95cb06d7e784c#rd
16 |
17 |
18 | ### 1.2.自己动手写区块链-发起一笔交易(Java版)
19 |
20 | github地址:https://github.com/importsource/blockchain-samples-transaction
21 |
22 | 开发指南:https://mp.weixin.qq.com/s?__biz=MzA5MzQ2NTY0OA==&mid=2650797427&idx=1&sn=ba11e0bbe90b4776b73412264856e98c&chksm=8856282cbf21a13ab4e3031d4ce1eb2ea6ce66fa6ea182f509a104f5d9258c3144f4be149886#rd
23 |
24 | ### 1.3.todo。。。
25 |
--------------------------------------------------------------------------------
/src/main/java/Block.java:
--------------------------------------------------------------------------------
1 | import java.util.Date;
2 |
3 | public class Block {
4 |
5 | public String hash;
6 | public String previousHash;
7 | private String data; //our data will be a simple message.
8 | private long timeStamp; //as number of milliseconds since 1/1/1970.
9 | private int nonce;
10 |
11 | //Block Constructor.
12 | public Block(String data,String previousHash ) {
13 | this.data = data;
14 | this.previousHash = previousHash;
15 | this.timeStamp = new Date().getTime();
16 |
17 | this.hash = calculateHash(); //Making sure we do this after we set the other values.
18 | }
19 |
20 | //Calculate new hash based on blocks contents
21 | public String calculateHash() {
22 | String calculatedhash = StringUtil.applySha256(
23 | previousHash +
24 | Long.toString(timeStamp) +
25 | Integer.toString(nonce) +
26 | data
27 | );
28 | return calculatedhash;
29 | }
30 |
31 | //Increases nonce value until hash target is reached.
32 | public void mineBlock(int difficulty) {
33 | String target = StringUtil.getDificultyString(difficulty); //Create a string with difficulty * "0"
34 | while(!hash.substring( 0, difficulty).equals(target)) {
35 | nonce ++;
36 | hash = calculateHash();
37 | }
38 | System.out.println("Block已挖到!!! : " + hash);
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/src/main/java/StringUtil.java:
--------------------------------------------------------------------------------
1 | import com.google.gson.GsonBuilder;
2 |
3 | import java.security.MessageDigest;
4 |
5 | public class StringUtil {
6 |
7 | //Applies Sha256 to a string and returns the result.
8 | public static String applySha256(String input){
9 |
10 | try {
11 | MessageDigest digest = MessageDigest.getInstance("SHA-256");
12 |
13 | //Applies sha256 to our input,
14 | byte[] hash = digest.digest(input.getBytes("UTF-8"));
15 |
16 | StringBuffer hexString = new StringBuffer(); // This will contain hash as hexidecimal
17 | for (int i = 0; i < hash.length; i++) {
18 | String hex = Integer.toHexString(0xff & hash[i]);
19 | if(hex.length() == 1) hexString.append('0');
20 | hexString.append(hex);
21 | }
22 | return hexString.toString();
23 | }
24 | catch(Exception e) {
25 | throw new RuntimeException(e);
26 | }
27 | }
28 |
29 | //Short hand helper to turn Object into a json string
30 | public static String getJson(Object o) {
31 | return new GsonBuilder().setPrettyPrinting().create().toJson(o);
32 | }
33 |
34 | //Returns difficulty string target, to compare to hash. eg difficulty of 5 will return "00000"
35 | public static String getDificultyString(int difficulty) {
36 | return new String(new char[difficulty]).replace('\0', '0');
37 | }
38 |
39 |
40 | }
--------------------------------------------------------------------------------
/src/main/java/ImportChain.java:
--------------------------------------------------------------------------------
1 | import java.util.ArrayList;
2 |
3 | public class ImportChain {
4 |
5 | public static ArrayList blockchain = new ArrayList();
6 | public static int difficulty = 5;
7 |
8 | public static void main(String[] args) {
9 | //add our blocks to the blockchain ArrayList:
10 |
11 | System.out.println("正在尝试挖掘block 1... ");
12 | addBlock(new Block("Hi im the first block", "0"));
13 |
14 | System.out.println("正在尝试挖掘block 2... ");
15 | addBlock(new Block("Yo im the second block",blockchain.get(blockchain.size()-1).hash));
16 |
17 | System.out.println("正在尝试挖掘block 3... ");
18 | addBlock(new Block("Hey im the third block",blockchain.get(blockchain.size()-1).hash));
19 |
20 | System.out.println("\nBlockchain is Valid: " + isChainValid());
21 |
22 | String blockchainJson = StringUtil.getJson(blockchain);
23 | System.out.println("\nThe block chain: ");
24 | System.out.println(blockchainJson);
25 | }
26 |
27 | public static Boolean isChainValid() {
28 | Block currentBlock;
29 | Block previousBlock;
30 | String hashTarget = new String(new char[difficulty]).replace('\0', '0');
31 |
32 | //loop through blockchain to check hashes:
33 | for(int i=1; i < blockchain.size(); i++) {
34 | currentBlock = blockchain.get(i);
35 | previousBlock = blockchain.get(i-1);
36 | //compare registered hash and calculated hash:
37 | if(!currentBlock.hash.equals(currentBlock.calculateHash()) ){
38 | System.out.println("Current Hashes not equal");
39 | return false;
40 | }
41 | //compare previous hash and registered previous hash
42 | if(!previousBlock.hash.equals(currentBlock.previousHash) ) {
43 | System.out.println("Previous Hashes not equal");
44 | return false;
45 | }
46 | //check if hash is solved
47 | if(!currentBlock.hash.substring( 0, difficulty).equals(hashTarget)) {
48 | System.out.println("This block hasn't been mined");
49 | return false;
50 | }
51 |
52 | }
53 | return true;
54 | }
55 |
56 | public static void addBlock(Block newBlock) {
57 | newBlock.mineBlock(difficulty);
58 | blockchain.add(newBlock);
59 | }
60 | }
--------------------------------------------------------------------------------