Skip to content

Commit

Permalink
feat: add initial implementation of mining
Browse files Browse the repository at this point in the history
  • Loading branch information
stinkymonkeyph committed Jul 25, 2024
1 parent ef000a3 commit d1e4667
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 11 deletions.
44 changes: 44 additions & 0 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package blockchain

import (
"encoding/json"
"log"
"strings"

"github.com/stinkymonkeyph/gopher-blocks/constants"
)
Expand Down Expand Up @@ -33,3 +35,45 @@ func (bc *Blockchain) AddTransactionToTransactionPool(txn *Transaction) {
txn.Status = constants.STATUS_PENDING
bc.TransactionPool = append(bc.TransactionPool, txn)
}

func (bc *Blockchain) AddBlock(b *Block) {
m := map[string]bool{}
for _, txn := range b.Transactions {
m[txn.TransactioHash] = true
}

for idx, txn := range bc.TransactionPool {
_, ok := m[txn.TransactioHash]

if ok {
bc.TransactionPool = append(bc.TransactionPool[:idx], bc.TransactionPool[idx+1:]...)
}
}

bc.Blocks = append(bc.Blocks, b)
}

func (bc *Blockchain) ProofOfWorkMining(minerAddress string) {
nonce := 0
for {
prevHash := bc.Blocks[len(bc.Blocks)-1].Hash()
guessBlock := NewBlock(prevHash, nonce)

for _, txn := range bc.TransactionPool {
tx := NewTransaction(txn.From, txn.To, txn.Value, txn.Data)
guessBlock.AddTransactionToTheBlock(tx)
}

zeroes := strings.Repeat("0", constants.MINING_DIFFICULTY)
guessHash := guessBlock.Hash()

if zeroes == guessHash[2:2+constants.MINING_DIFFICULTY] {
rewardTxn := NewTransaction(constants.BLOCKCHAIN_REWARD_ADDRESS, minerAddress, constants.MINING_REWARD, []byte{})
guessBlock.Transactions = append(guessBlock.Transactions, rewardTxn)
bc.AddBlock(guessBlock)
log.Printf(bc.ToJSON(), "\n\n")
nonce = 0
continue
}
}
}
31 changes: 25 additions & 6 deletions blockchain/transaction.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package blockchain

import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"math"

"github.com/stinkymonkeyph/gopher-blocks/constants"
)

type Transaction struct {
From string `json:"from"`
To string `json:"to"`
Value uint64 `json:"value"`
Data []byte `json:"data"`
Status string `json:"status"`
From string `json:"from"`
To string `json:"to"`
Value uint64 `json:"value"`
Data []byte `json:"data"`
Status string `json:"status"`
TransactioHash string `json:"transaction_hash"`
}

func NewTransaction(from string, to string, value uint64, data []byte) *Transaction {
Expand All @@ -19,7 +24,7 @@ func NewTransaction(from string, to string, value uint64, data []byte) *Transact
t.To = to
t.Value = value
t.Data = data

t.TransactioHash = ""
return t
}

Expand All @@ -46,3 +51,17 @@ func (t *Transaction) VerifyTransaction() bool {

return true
}

func (t *Transaction) Hash() string {
ts, err := json.Marshal(t)

if err != nil {
panic("Something went wrong while serializing transaction object")
}

sum := sha256.Sum256(ts)
hex := hex.EncodeToString(sum[:32])
hex = constants.HEX_PREFIX + hex

return hex
}
15 changes: 10 additions & 5 deletions constants/constants.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package constants

const (
BLOCKCHAIN_NAME = "GopherBlocks"
HEX_PREFIX = "0x"
STATUS_SUCCESS = "success"
STATUS_FAILED = "failed"
STATUS_PENDING = "pending"
BLOCKCHAIN_NAME = "GopherBlocks"
HEX_PREFIX = "0x"
STATUS_SUCCESS = "success"
STATUS_FAILED = "failed"
STATUS_PENDING = "pending"
MINING_DIFFICULTY = 4
MINING_REWARD = 1200 * DECIMAL
CURRENCY_NAME = "gopher"
DECIMAL = 100
BLOCKCHAIN_REWARD_ADDRESS = "Gopher_Reward_Pool"
)
12 changes: 12 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package main

import (
"log"
"sync"
"time"

"github.com/stinkymonkeyph/gopher-blocks/blockchain"
"github.com/stinkymonkeyph/gopher-blocks/constants"
Expand All @@ -12,7 +14,17 @@ func init() {
}

func main() {

var wg sync.WaitGroup

block := blockchain.NewBlock("0x0", 0)
transaction1 := blockchain.NewTransaction("0x1", "0x2", 12, []byte{})
bc := blockchain.NewBlockchain(block)
log.Print(bc.ToJSON())

wg.Add(1)
go bc.ProofOfWorkMining("alice")
time.Sleep(2000)
bc.AddTransactionToTransactionPool(transaction1)
wg.Wait()
}

0 comments on commit d1e4667

Please sign in to comment.