Block. Go
Package mainimport ("time ") // define the Block Structure Type Block struct {version int64 prevblockhash [] Byte hash [] Byte timestamp int64 targetbits int64 nonce int64 merkelroot [] byte data [] Byte} // set the block to be created method func newblock (data string, prevblockhash [] Byte) * block {block: = & Block {version: 1, prevblockhash: prevblockhash, // hash: Timestamp: time. now (). unix (), targetbits: 10, Nonce: 0, merkelroot: [] Byte {}, data: [] Byte (data ),} // Block. sethash () // set the block hash value ---> V2 proof of workload PoW: = newproofofwork (Block) nonce, hash: = pow. run () block. hash = hash block. nonce = nonce return block} // Add hash value ----> V2 from POW // func (Block * block) sethash () {// TMP: = [] [] Byte {// tool function for converting int type to byte type // inttobyte (Block. version), // block. prevblockhash, // inttobyte (Block. timestamp), // block. merkelroot, // inttobyte (Block. nonce), // block. data ,//}// // Link each field of the block into a slice and use [] Byte {} For link to avoid the information of the source block/data: = bytes. join (TMP, [] Byte {}) //// hash the block using sha256. The returned value is a [32] byte array instead of a slice/HASH: = sha256.sum256 (data) // block. hash = hash [:] // is converted from an array to a slice //} // The creation of the Creation block. The hash value of func newgenesisblock () is null for one kubernetes shard () * block {return newblock ("Genesis block! ", [] Byte {})}
Blockchain. Go
Package mainimport "OS" // define the blockchain type blockchain struct {blocks [] * block} // create the blockchain and add the creation block func newblockchain () * blockchain {return & blockchain {[] * block {newgenesisblock (), }}// add block func (BC * blockchain) addblock (data string) {// simple validation if Len (BC. blocks) <= 0 {OS. exit (1)} // create a new block named lastblock: = BC. blocks [Len (BC. blocks)-1] prevblockhash: = lastblock. hash block: = newblock (data, prevblockhash) // Add to blockchain BC. blocks = append (BC. blocks, block )}
Utils
package mainimport ( "bytes" "encoding/binary" "fmt" "os")func IntToByte(num int64)[]byte{ var buffer bytes.Buffer err := binary.Write(&buffer, binary.BigEndian, num) //if err != nil{ // fmt.Println("IntToByte err occur:",err) // os.Exit(1) //} CheckErr(err) return buffer.Bytes()}func CheckErr(err error){ if err != nil{ fmt.Println("err occur:",err) os.Exit(1) }}
Proofofwork. Go
Package mainimport ("Math/big" "bytes" "math" "crypto/sha256" "FMT ") const targetbits = 24 // assuming the difficulty Value Type proofofwork struct {block * block targetbit * big. int} func newproofofwork (Block * block) * proofofwork {var inttarget = big. newint (1) // Assumed value // 000000000000000000000000000000001 Initial Value // 100000000000000000000000000000000 decimal // 000000000100000000000000000000000 decimal // 000001000000000000000000000000000 hexadecimal target hash value // 10000000a0000000000001234560000000 actual value inttarget. lsh (inttarget, uint (256-targetbits) Return & proofofwork {block, inttarget} func (Pow * proofofwork) preparerawdata (nonce int64) [] Byte {block: = pow. block // obtain the block to be processed TMP: = [] [] Byte {// The tool function that converts int type to byte type inttobyte (Block. version), block. prevblockhash, inttobyte (Block. timestamp), block. merkelroot, inttobyte (nonce), inttobyte (targetbits), // Add the difficulty Value block. data,} // link each field of the block into a slice and use [] Byte {} For the link to avoid the information of the source block data: = bytes. join (TMP, [] Byte {}) return data} func (Pow * proofofwork) Run () (int64, [] Byte) {var nonce int64 var hash [32] Byte var hashint big. int FMT. println ("begin minng... ") FMT. printf ("target hash: % x \ n", pow.tar getbit. bytes () for nonce <math. maxint64 {data: = pow. preparerawdata (nonce) hash = sha256.sum256 (data) // obtain the string hashint. setbytes (hash [:]) // convert the byte value to a large number // compare the hash value if hashint.cmp(pow.tar getbit) =-1 {FMT. printf ("found hash: % x \ n", hash) break} else {nonce ++} return nonce, hash [:]} // provide the method func (Pow * proofofwork) isvalid () bool {data: = pow. preparerawdata (pow. block. nonce) hash: = sha256.sum256 (data) var inthash big. int inthash. setbytes (hash [:]) return inthash.cmp(pow.tar getbit) =-1}
Main. Go
Package mainimport "FMT" func main () {BC: = newblockchain () BC. addblock ("the shift leader transfers a bitcoin to the instructor") BC. addblock ("") for I, block: = range BC. blocks {FMT. println ("=== block num:", I) FMT. printf ("data: % s \ n", block. data) FMT. println ("version:", block. version) FMT. printf ("prevhash: % x \ n", block. prevblockhash) FMT. printf ("hash: % x \ n", block. timestamp) FMT. printf ("timestamp: % d \ n", block. timestamp) FMT. printf ("Merkel: % x \ n", block. merkelroot) FMT. printf ("nonce: % d \ n", block. nonce) // PoW: = newproofofwork (Block) FMT. printf ("isvalid: % V \ n", pow. isvalid ())}}
The final running result is as follows:
Begin minng ..tar get hash: 010000000000000000000000000000000000000000000000000000000000 found hash: 00000014312c76058b55905dbf9915019c484df5f64b9655d01985e050e16eddbegin minng ...tar get hash: 010000000000000000000000000000000000000000000000000000000000 found hash: 000000d3c28e9cff07f43949c6c6f23444c1beb7494aebb3be5cf74614e77f04begin minng ...tar get hash: 01000000000000000000000000000000000000000000 0000000000000000 found hash: 10000004b9205eab846bcf921c952ea2a91e103a4c37170304c4e1bb85d32d73e === block num: 0 data: Genesis block! Version: 1 prevhash: Hash: 5bd09d11timestamp: 1540398353 Merkel: nonce: 26865217 isvalid: True === block num: 1 Data: The Shift Leader transfers a bitcoin to the instructor version: 1 prevhash: protocol: 5bd09d35timestamp: 1540398389 Merkel: nonce: 6908425 isvalid: True === block num: 2 Data: The Shift Leader transfers another bitcoin version: 1 prevhash: Protocol: 5bd09d42timestamp: 1540398402 Merkel: nonce: 70302967 isvalid: True
Create blockchain V2 to implement POW (proofofwork workload proof)