Dalam tutorial ini kita akan:
- Buat 'blockchain' pertama (sangat) dasar Anda .
- Menerapkan sistem bukti kerja (penambangan) sederhana.
- Kagumi kemungkinannya .
Pengaturan.
Kami akan menggunakan Java tetapi Anda harus dapat mengikuti dalam bahasa OOP apa pun . Saya akan menggunakan Eclipse tetapi Anda dapat menggunakan editor teks mewah baru (meskipun Anda akan kehilangan banyak bloat yang bagus).
Anda akan perlu:
- Intal Java dan JDK.
- Eclipse (IDE/Editor Teks lain).
| gambar eclips |
Membuat Blockchain.
Blockchain hanyalah rantai/daftar blok. Setiap blok di blockchain akan memiliki sidik jari digitalnya sendiri, berisi sidik jari digital dari blok sebelumnya, dan memiliki beberapa data (data ini bisa berupa transaksi misalnya).
Jadi mari kita buat Blok kelas untuk membentuk blockchain:
| 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(); | |
| } | |
| } |
Seperti yang di lihat, Blok dasar kami berisi a String hashyang akan menampung tanda tangan digital kami. Variabel previousHashuntuk menyimpan hash blok sebelumnya dan String datauntuk menyimpan data blok kita.
Selanjutnya kita akan membutuhkan cara untuk menghasilkan sidik jari digital ,
ada banyak algoritme kriptografi yang dapat Anda pilih, namun SHA256 cocok untuk contoh ini. Kita bisa import java.security.MessageDigest;mendapatkan akses ke algoritma SHA256.
Kita perlu menggunakan SHA256 nanti, jadi mari kita buat metode pembantu yang berguna di kelas 'utility' StringUtil baru :
| 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); | |
| } | |
| } | |
| } |
previousHashdatatimeStamp | public String calculateHash() { | |
| String calculatedhash = StringUtil.applySha256( | |
| previousHash + | |
| Long.toString(timeStamp) + | |
| data | |
| ); | |
| return calculatedhash; | |
| } |
dan mari tambahkan metode ini ke konstruktor Blok ...
| 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. | |
| } |
Saatnya untuk beberapa pengujian… Di kelas NoobChain
| 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); | |
| } | |
| } |
Setiap blok sekarang memiliki tanda tangan digitalnya sendiri berdasarkan informasinya dan tanda tangan dari blok sebelumnya.
Saat ini tidak banyak rantai blok , jadi mari simpan blok kita di ArrayList dan juga impor gson untuk melihatnya sebagai Json.
| 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); | |
| } | |
| } |
Sekarang kita membutuhkan cara untuk memeriksa integritas blockchain kita.
Mari buat metode isChainValid() Boolean di kelas NoobChain , yang akan mengulang semua blok dalam rantai dan membandingkan hash. Metode ini perlu memeriksa apakah variabel hash benar-benar sama dengan hash yang dihitung, dan hash blok sebelumnya sama dengan variabel hash sebelumnya .
| 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; | |
| }
|
Mari kita mulai menambang blok !!!
| 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); | |
| } | |
| } |
ita harus memperbarui kelas NoobChain untuk memicu metode mineBlock () untuk setiap blok baru. IsChainValid () Boolean juga harus memeriksa apakah setiap blok memiliki hash yang dipecahkan (dengan menambang) .
| 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; | |
| } | |
| } |
Posting Komentar