區(qū)塊鏈?zhǔn)怯梢粋€個的區(qū)塊構(gòu)成,區(qū)塊主要包含前一個區(qū)塊的hash值庇谆,加密的數(shù)據(jù)data,當(dāng)前區(qū)塊的hash值凭疮。
package noobchain;
import java.util.Date;
public class Block {
public Stringhash;
public StringpreviousHash;
private Stringdata;//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;
}
//Increases nonce value until hash target is reached.
? public void mineBlock(int difficulty) {
String target = StringUtil.getDificultyString(difficulty);//Create a string with difficulty * "0"
? ? ? while(!hash.substring(0, difficulty).equals(target)) {
nonce ++;
hash = calculateHash();
}
System.out.println("Block Mined!!! : " +hash);
}
}
package noobchain;
import java.util.ArrayList;
public class NoobChain {
public static ArrayListblockchain =new ArrayList();
public static int difficulty =5;
public static void main(String[] args) {
//add our blocks to the blockchain ArrayList:
? ? ? System.out.println("Trying to Mine block 1... ");
addBlock(new Block("Hi im the first block","0"));
System.out.println("Trying to Mine block 2... ");
addBlock(new Block("Yo im the second block",blockchain.get(blockchain.size()-1).hash));
System.out.println("Trying to Mine block 3... ");
addBlock(new Block("Hey im the third block",blockchain.get(blockchain.size()-1).hash));
System.out.println("\nBlockchain is Valid: " +isChainValid());
String blockchainJson = StringUtil.getJson(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
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;
}
public static void addBlock(Block newBlock) {
newBlock.mineBlock(difficulty);
blockchain.add(newBlock);
}
}
package noobchain;
import java.security.MessageDigest;
import com.google.gson.GsonBuilder;
public class StringUtil {
//Applies Sha256 to a string and returns the result.
? public static String applySha256(Stringinput){
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);
}
}
//Short hand helper to turn Object into a json string
? public static String getJson(Object o) {
return new GsonBuilder().setPrettyPrinting().create().toJson(o);
}
//Returns difficulty string target, to compare to hash. eg difficulty of 5 will return "00000"
? public static String getDificultyString(int difficulty) {
return new String(new char[difficulty]).replace('\0','0');
}
}