Skip to content

Commit 19c102c

Browse files
committed
transaction post
1 parent ee78920 commit 19c102c

File tree

11 files changed

+441
-108
lines changed

11 files changed

+441
-108
lines changed

block/blockchain.go

+106-48
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package block
22

33
import (
4+
"crypto/ecdsa"
45
"crypto/sha256"
56
"encoding/json"
67
"fmt"
8+
"goBlockchain/utils"
79
"log"
810
"strings"
911
"time"
@@ -18,14 +20,23 @@ const (
1820
type Block struct {
1921
timestamp int64
2022
nonce int
21-
prevHash [32]byte
23+
previousHash [32]byte
2224
transactions []*Transaction
2325
}
2426

27+
func NewBlock(nonce int, previousHash [32]byte, transactions []*Transaction) *Block {
28+
b := new(Block)
29+
b.timestamp = time.Now().UnixNano()
30+
b.nonce = nonce
31+
b.previousHash = previousHash
32+
b.transactions = transactions
33+
return b
34+
}
35+
2536
func (b *Block) Print() {
26-
fmt.Printf("Timestamp %d\n", b.timestamp)
27-
fmt.Printf("Nonce %d\n", b.nonce)
28-
fmt.Printf("Previous_hash %x\n", b.prevHash)
37+
fmt.Printf("timestamp %d\n", b.timestamp)
38+
fmt.Printf("nonce %d\n", b.nonce)
39+
fmt.Printf("previous_hash %x\n", b.previousHash)
2940
for _, t := range b.transactions {
3041
t.Print()
3142
}
@@ -38,69 +49,101 @@ func (b *Block) Hash() [32]byte {
3849

3950
func (b *Block) MarshalJSON() ([]byte, error) {
4051
return json.Marshal(struct {
41-
Nonce int `json:"nonce"`
42-
PrevHash [32]byte `json:"prevHash"`
4352
Timestamp int64 `json:"timestamp"`
53+
Nonce int `json:"nonce"`
54+
PreviousHash string `json:"previous_hash"`
4455
Transactions []*Transaction `json:"transactions"`
4556
}{
46-
Nonce: b.nonce,
47-
PrevHash: b.prevHash,
4857
Timestamp: b.timestamp,
58+
Nonce: b.nonce,
59+
PreviousHash: fmt.Sprintf("%x", b.previousHash),
4960
Transactions: b.transactions,
5061
})
5162
}
5263

53-
func newBlock(nonce int, previousHash [32]byte, transactions []*Transaction) *Block {
54-
b := new(Block)
55-
b.timestamp = time.Now().UnixNano()
56-
b.nonce = nonce
57-
b.prevHash = previousHash
58-
b.transactions = transactions
59-
return b
60-
}
61-
6264
type Blockchain struct {
6365
transactionPool []*Transaction
6466
chain []*Block
6567
blockchainAddress string
68+
port uint16
6669
}
6770

68-
func newBlockchain(blockchainAddress string) *Blockchain {
71+
func NewBlockchain(blockchainAddress string, port uint16) *Blockchain {
6972
b := &Block{}
7073
bc := new(Blockchain)
7174
bc.blockchainAddress = blockchainAddress
72-
bc.createBlock(0, b.Hash())
75+
bc.CreateBlock(0, b.Hash())
76+
bc.port = port
7377
return bc
7478
}
7579

76-
func (bc *Blockchain) createBlock(nonce int, previousHash [32]byte) *Block {
77-
b := newBlock(nonce, previousHash, bc.transactionPool)
80+
func (bc *Blockchain) MarshalJSON() ([]byte, error) {
81+
return json.Marshal(struct {
82+
Blocks []*Block `json:"chains"`
83+
}{
84+
Blocks: bc.chain,
85+
})
86+
}
87+
88+
func (bc *Blockchain) CreateBlock(nonce int, previousHash [32]byte) *Block {
89+
b := NewBlock(nonce, previousHash, bc.transactionPool)
7890
bc.chain = append(bc.chain, b)
7991
bc.transactionPool = []*Transaction{}
8092
return b
8193
}
8294

95+
func (bc *Blockchain) LastBlock() *Block {
96+
return bc.chain[len(bc.chain)-1]
97+
}
98+
8399
func (bc *Blockchain) Print() {
84100
for i, block := range bc.chain {
85-
fmt.Printf("%s Chain %d %s\n", strings.Repeat("=", 25), i, strings.Repeat("=", 25))
101+
fmt.Printf("%s Chain %d %s\n", strings.Repeat("=", 25), i,
102+
strings.Repeat("=", 25))
86103
block.Print()
87104
}
88105
fmt.Printf("%s\n", strings.Repeat("*", 25))
89106
}
90107

91-
func (bn *Blockchain) LastBlock() *Block {
92-
return bn.chain[len(bn.chain)-1]
108+
func (bc *Blockchain) AddTransaction(sender string, recipient string, value float32,
109+
senderPublicKey *ecdsa.PublicKey, s *utils.Signature) bool {
110+
t := NewTransaction(sender, recipient, value)
111+
112+
if sender == MINING_SENDER {
113+
bc.transactionPool = append(bc.transactionPool, t)
114+
return true
115+
}
116+
117+
if bc.VerifyTransactionSignature(senderPublicKey, s, t) {
118+
/*
119+
if bc.CalculateTotalAmount(sender) < value {
120+
log.Println("ERROR: Not enough balance in a wallet")
121+
return false
122+
}
123+
*/
124+
bc.transactionPool = append(bc.transactionPool, t)
125+
return true
126+
} else {
127+
log.Println("ERROR: Verify Transaction")
128+
}
129+
return false
130+
93131
}
94132

95-
func (bc *Blockchain) addTransaction(sender string, recipient string, value float32) {
96-
t := NewTransaction(sender, recipient, value)
97-
bc.transactionPool = append(bc.transactionPool, t)
133+
func (bc *Blockchain) VerifyTransactionSignature(
134+
senderPublicKey *ecdsa.PublicKey, s *utils.Signature, t *Transaction) bool {
135+
m, _ := json.Marshal(t)
136+
h := sha256.Sum256([]byte(m))
137+
return ecdsa.Verify(senderPublicKey, h[:], s.R, s.S)
98138
}
99139

100140
func (bc *Blockchain) CopyTransactionPool() []*Transaction {
101141
transactions := make([]*Transaction, 0)
102142
for _, t := range bc.transactionPool {
103-
transactions = append(transactions, NewTransaction(t.senderAddress, t.recipientAddress, t.value))
143+
transactions = append(transactions,
144+
NewTransaction(t.senderBlockchainAddress,
145+
t.recipientBlockchainAddress,
146+
t.value))
104147
}
105148
return transactions
106149
}
@@ -123,56 +166,71 @@ func (bc *Blockchain) ProofOfWork() int {
123166
}
124167

125168
func (bc *Blockchain) Mining() bool {
126-
bc.addTransaction(MINING_SENDER, bc.blockchainAddress, MINING_REWARD)
169+
bc.AddTransaction(MINING_SENDER, bc.blockchainAddress, MINING_REWARD, nil, nil)
127170
nonce := bc.ProofOfWork()
128171
previousHash := bc.LastBlock().Hash()
129-
bc.createBlock(nonce, previousHash)
172+
bc.CreateBlock(nonce, previousHash)
130173
log.Println("action=mining, status=success")
131174
return true
132175
}
133176

134-
// User amount
135177
func (bc *Blockchain) CalculateTotalAmount(blockchainAddress string) float32 {
136-
var totalValue float32 = 0.0
178+
var totalAmount float32 = 0.0
137179
for _, b := range bc.chain {
138180
for _, t := range b.transactions {
139181
value := t.value
140-
if blockchainAddress == t.recipientAddress {
141-
totalValue += value
182+
if blockchainAddress == t.recipientBlockchainAddress {
183+
totalAmount += value
142184
}
143-
if blockchainAddress == t.senderAddress {
144-
totalValue -= value
185+
186+
if blockchainAddress == t.senderBlockchainAddress {
187+
totalAmount -= value
145188
}
146189
}
147190
}
148-
return totalValue
191+
return totalAmount
149192
}
150193

151194
type Transaction struct {
152-
senderAddress string
153-
recipientAddress string
154-
value float32
195+
senderBlockchainAddress string
196+
recipientBlockchainAddress string
197+
value float32
155198
}
156199

157200
func NewTransaction(sender string, recipient string, value float32) *Transaction {
158-
return &Transaction{senderAddress: sender, recipientAddress: recipient, value: value}
201+
return &Transaction{sender, recipient, value}
159202
}
160203

161204
func (t *Transaction) Print() {
162205
fmt.Printf("%s\n", strings.Repeat("-", 40))
163-
fmt.Printf(" sender_blockchain_address %s\n", t.senderAddress)
164-
fmt.Printf(" recipient_blockchain_address %s\n", t.recipientAddress)
165-
fmt.Printf(" transaction_value %.1f\n", t.value)
206+
fmt.Printf(" sender_blockchain_address %s\n", t.senderBlockchainAddress)
207+
fmt.Printf(" recipient_blockchain_address %s\n", t.recipientBlockchainAddress)
208+
fmt.Printf(" value %.1f\n", t.value)
166209
}
167210

168211
func (t *Transaction) MarshalJSON() ([]byte, error) {
169212
return json.Marshal(struct {
170-
Sender string `json:"senderAddress"`
171-
Recipient string `json:"recipientAddress"`
213+
Sender string `json:"sender_blockchain_address"`
214+
Recipient string `json:"recipient_blockchain_address"`
172215
Value float32 `json:"value"`
173216
}{
174-
Sender: t.senderAddress,
175-
Recipient: t.recipientAddress,
217+
Sender: t.senderBlockchainAddress,
218+
Recipient: t.recipientBlockchainAddress,
176219
Value: t.value,
177220
})
178221
}
222+
223+
type TransactionRequest struct {
224+
SenderBlockchainAddress *string `json:"sender_blockchain_address"`
225+
RecipientBlockchainAddress *string `json:"recipient_blockchain_address"`
226+
SenderPublicKey *string `json:"sender_public_key"`
227+
Value *float32 `json:"value"`
228+
Signature *string `json:"signature"`
229+
}
230+
231+
func (tr *TransactionRequest) Validate() bool {
232+
if tr.SenderBlockchainAddress == nil || tr.RecipientBlockchainAddress == nil || tr.SenderPublicKey == nil || tr.Value == nil || tr.Signature == nil {
233+
return false
234+
}
235+
return true
236+
}
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package main
2+
3+
import (
4+
"goBlockchain/block"
5+
"goBlockchain/wallet"
6+
"io"
7+
"log"
8+
"net/http"
9+
"strconv"
10+
)
11+
12+
var cache map[string]*block.Blockchain = make(map[string]*block.Blockchain)
13+
14+
type BlockchainServer struct {
15+
port uint16
16+
}
17+
18+
func NewBlockchainServer(port uint16) *BlockchainServer {
19+
return &BlockchainServer{port}
20+
}
21+
22+
func (bcs *BlockchainServer) Port() uint16 {
23+
return bcs.port
24+
}
25+
26+
func (bcs *BlockchainServer) GetBlockchain() *block.Blockchain {
27+
bc, ok := cache["blockchain"]
28+
if !ok {
29+
minersWallet := wallet.NewWallet()
30+
bc = block.NewBlockchain(minersWallet.BlockchainAddress(), bcs.Port())
31+
cache["blockchain"] = bc
32+
log.Printf("private_key %v", minersWallet.PrivateKeyStr())
33+
log.Printf("publick_key %v", minersWallet.PublicKeyStr())
34+
log.Printf("blockchain_address %v", minersWallet.BlockchainAddress())
35+
}
36+
return bc
37+
}
38+
39+
func (bcs *BlockchainServer) GetChain(w http.ResponseWriter, req *http.Request) {
40+
switch req.Method {
41+
case http.MethodGet:
42+
w.Header().Add("Content-Type", "application/json")
43+
bc := bcs.GetBlockchain()
44+
m, _ := bc.MarshalJSON()
45+
io.WriteString(w, string(m[:]))
46+
default:
47+
log.Printf("ERROR: Invalid HTTP Method")
48+
49+
}
50+
}
51+
52+
func (bcs *BlockchainServer) Run() {
53+
http.HandleFunc("/", bcs.GetChain)
54+
log.Fatal(http.ListenAndServe("0.0.0.0:"+strconv.Itoa(int(bcs.Port())), nil))
55+
}

blockchain_server/main.go

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"log"
6+
)
7+
8+
func init() {
9+
log.SetPrefix("Blockchain: ")
10+
}
11+
12+
func main() {
13+
port := flag.Uint("port", 5000, "TCP Port Number for Blockchain Server")
14+
flag.Parse()
15+
app := NewBlockchainServer(uint16(*port))
16+
app.Run()
17+
}

go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ module goBlockchain
33
go 1.22.3
44

55
require (
6-
github.com/btcsuite/btcutil v1.0.2 // indirect
7-
golang.org/x/crypto v0.23.0 // indirect
6+
github.com/btcsuite/btcutil v1.0.2
7+
golang.org/x/crypto v0.23.0
88
)

main.go

-20
This file was deleted.

run.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
go run main.go blockchain_server.go

0 commit comments

Comments
 (0)