package main

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"time"
)

const rewardValue = 500 // Reward value for miners in ZUA

// Define the block structure
type Block struct {
	Name          string      // Name of the block (e.g., "zua")
	ParentHash    []byte
	Timestamp     int64
	Transactions  [][]byte
	Nonce         uint64
	CoinbaseValue uint64 // Value of coins created in this block
}

func main() {
	// Initialize the blockchain with the Genesis block
	genesisBlock := createGenesisBlock()
	blockchain := []*Block{genesisBlock}

	// Print the details of the Genesis block
	printBlockDetails("Genesis Block", genesisBlock)

	// Start mining new blocks at a fixed interval of 1 second
	for {
		time.Sleep(time.Second) // Wait for 1 second

		// Create a new block
		newBlock := mineBlock(blockchain[len(blockchain)-1])
		blockchain = append(blockchain, newBlock)

		// Print the details of the new block
		printBlockDetails("New Block", newBlock)

		// Break the loop after reaching the desired number of blocks (for demonstration)
		if len(blockchain) >= 10 {
			break
		}
	}
}

// Function to create the Genesis block
func createGenesisBlock() *Block {
	// Define the timestamp for the genesis block (January 5th, 2024)
	genesisTimestamp := time.Date(2024, time.January, 5, 0, 0, 0, 0, time.UTC).Unix()

	// Define the parent hash for the genesis block
	genesisParentHash, _ := hex.DecodeString("7c380ae690f9eaa64f300451d5e466371113c38b96ed96fe3f1e934869355ffa")

	return &Block{
		Name:          "zua",
		ParentHash:    genesisParentHash,
		Timestamp:     genesisTimestamp,
		Transactions:  [][]byte{[]byte("First Transaction")}, // Include a sample transaction
		Nonce:         0,
		CoinbaseValue: 28_000_000_000, // 28 billion coins
	}
}

// Function to mine a new block
func mineBlock(previousBlock *Block) *Block {
	// Increment the nonce until a valid block hash is found
	nonce := uint64(0)
	for {
		// Create a new block with the incremented nonce
		newBlock := &Block{
			Name:          fmt.Sprintf("%s-%d", previousBlock.Name, nonce),
			ParentHash:    calculateBlockHash(previousBlock),
			Timestamp:     time.Now().Unix(),
			Transactions:  [][]byte{createCoinbaseTransaction()}, // Include reward transaction
			Nonce:         nonce,
			CoinbaseValue: rewardValue, // Set the reward value for miners
		}

		// Calculate the block hash
		blockHash := calculateBlockHash(newBlock)

		// Check if the block hash meets the difficulty target (e.g., starts with a certain number of zeros)
		if isBlockHashValid(blockHash) {
			return newBlock // Return the mined block
		}

		// Increment the nonce for the next iteration
		nonce++
	}
}

// Function to create the Coinbase transaction for the reward
func createCoinbaseTransaction() []byte {
	return []byte(fmt.Sprintf("Coinbase Transaction: %d ZUA", rewardValue))
}

// Function to print block details
func printBlockDetails(title string, block *Block) {
	fmt.Println(title + ":")
	fmt.Println("  Name:", block.Name)
	fmt.Println("  Timestamp:", block.Timestamp)
	fmt.Println("  Nonce:", block.Nonce)
	fmt.Println("  Coinbase Value:", block.CoinbaseValue, "ZUA")
	fmt.Println("  Block Hash:", hex.EncodeToString(calculateBlockHash(block)))
	fmt.Println("  Parent Hash:", hex.EncodeToString(block.ParentHash))
	fmt.Println("  Transactions:")
	for _, tx := range block.Transactions {
		fmt.Println("    -", string(tx))
	}
	fmt.Println("")
}

// Function to calculate the hash of a block
func calculateBlockHash(block *Block) []byte {
	header := fmt.Sprintf("%s-%d-%d-%x", block.Name, block.Timestamp, block.Nonce, block.Transactions)
	hash := sha256.Sum256([]byte(header))
	return hash[:]
}

// Function to check if a block hash meets the difficulty target (placeholder implementation)
func isBlockHashValid(hash []byte) bool {
	// Placeholder implementation: Check if the hash starts with a certain number of zeros
	return hash[0] == 0 && hash[1] == 0 // Example: Difficulty target is 2 leading zeros
}
 
by

Go Online Compiler

Write, Run & Share Go code online using OneCompiler's Go online compiler for free. It's one of the robust, feature-rich online compilers for Go language, running on the latest version 1.10.2. Getting started with the OneCompiler's Go compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as GO and start coding.

Read inputs from stdin

OneCompiler's Go online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Go program which takes name as input and prints hello message with your name.

package main
import "fmt"

func main() {
  var name string 
  fmt.Scanf("%s", &name) 
	fmt.Printf("Hello %s", name)
}

About Go

Go language is an open-source, statically typed programming language by Google. Go is highly recommended for creation of highly scalable and available web applications.

Some of the products developed using Go are Kubernetes, Docker, Dropbox, Infoblox etc.

Key Features

  • Fast compilation
  • Easy to write concurrent programs
  • Simple and concise syntax
  • Supports static linking
  • Opensource and huge community support.

Syntax help

Data Types

Data typeDescriptionSizeRange
uint88-bit unsigned integer1 byte0 to 255
int88-bit signed integer1 byte-128 to 127
int1616-bit signed integer2 bytes-32768 to 32767
unit1616-bit unsigned integer2 bytes0 to 65,535
int3232-bit signed integer4 bytes-2,147,483,648 to 2,147,483,647
uint3232-bit unsigned integer4 bytes0 to 4,294,967,295
int6464-bit signed integer8 bytes-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
uint6464-bit unsigned integer8 bytes0 to 18,446,744,073,709,551,615
float3232-bit signed floating point number4 bytes±1.5e-45 to ±3.4e38
float64-bit signed floating point number8 bytes±5.0e-324 to ±1.7e308
stringsequence of immutable text
boolStores either true or false1 byteTrue or false

Variables

Variable is a name given to the storage area in order to manipulate them in our programs.

var varible-names datatype;

Loops

1. If-Else:

When ever you want to perform a set of operations based on a condition or set of conditions then If or IF-ELSE or Nested If-Elif-Else are used.

If

if(conditional-expression) {
   // code
} 

If-Else

if(conditional-expression) {
   // code
} else {
   // code
}

Nested If-Else

if(conditional-expression) {
   // code
} else if(conditional-expression) {
   // code
} else {
   // code
}

2. For:

For loop is used to iterate a set of statements based on a condition.

for Initialization; Condition; Increment/decrement {  
  // code  
} 

3. Switch:

Switch is an alternative to If-Else-If ladder.

switch conditional-expression {    
case value1:    
 // code    
 break;  // optional  
case value2:    
 // code    
 break;  // optional  
...    
    
default:     
 // code to be executed when all the above cases are not matched;    
} 

Note:

Go doesn't have while or do-while loops like in C.

Functions

Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity.

func functionname(parameter-name type) returntype {  
 //code
}