From 06bfdfeea3cf71506cb620107f3a2df944fcdc3f Mon Sep 17 00:00:00 2001 From: server Date: Wed, 15 Jul 2020 14:58:13 -0400 Subject: [PATCH] update again --- blockchain/block.go | 185 +++++++++++++++++++++++++++++++++++++- blockchain/chain.go | 171 ++--------------------------------- blockchain/crypto.go | 13 --- blockchain/settings.go | 13 ++- blockchain/transaction.go | 29 +----- client.go | 18 ++-- network/net.go | 2 +- network/settings.go | 2 +- node.go | 9 +- serve.go | 47 +++++----- values.go | 11 ++- 11 files changed, 244 insertions(+), 256 deletions(-) diff --git a/blockchain/block.go b/blockchain/block.go index 8564250..bea3b44 100644 --- a/blockchain/block.go +++ b/blockchain/block.go @@ -1,6 +1,8 @@ package blockchain import ( + "time" + "errors" "bytes" "crypto/rsa" "math/big" @@ -16,6 +18,178 @@ func NewBlock(miner string, prevHash []byte) *Block { } } +func (block *Block) Accept(chain *BlockChain, user *User, ch chan bool) error { + if !block.transactionsIsValid(chain) { + return errors.New("transactions is not valid") + } + block.AddTransaction(chain, &Transaction{ + RandBytes: GenerateRandomBytes(RAND_BYTES), + Sender: STORAGE_CHAIN, + Receiver: user.Address(), + Value: STORAGE_REWARD, + }) + block.TimeStamp = time.Now().Format(time.RFC3339) + block.CurrHash = block.hash() + block.Signature = block.sign(user.Private()) + block.Nonce = block.proof(ch) + return nil +} + +func (block *Block) AddTransaction(chain *BlockChain, tx *Transaction) error { + if tx.Value == 0 { + return errors.New("tx value = 0") + } + if len(block.Transactions) == TXS_LIMIT && tx.Sender != STORAGE_CHAIN { + return errors.New("len tx = limit") + } + var balanceInChain uint64 + balanceInTX := tx.Value + tx.ToStorage + if value, ok := block.Mapping[tx.Sender]; ok { + balanceInChain = value + } else { + balanceInChain = chain.Balance(tx.Sender) + } + if tx.Value > START_PERCENT && tx.ToStorage != STORAGE_REWARD { + return errors.New("storage reward pass") + } + if balanceInTX > balanceInChain { + return errors.New("insufficient funds") + } + block.Mapping[tx.Sender] = balanceInChain - balanceInTX + block.addBalance(chain, tx.Receiver, tx.Value) + block.addBalance(chain, STORAGE_CHAIN, tx.ToStorage) + block.Transactions = append(block.Transactions, *tx) + return nil +} + +func (block *Block) IsValid(chain *BlockChain) bool { + switch { + case block == nil: + return false + case block.Difficulty != DIFFICULTY: + return false + case !block.hashIsValid(chain, chain.Size()): + return false + case !block.signIsValid(): + return false + case !block.proofIsValid(): + return false + case !block.mappingIsValid(): + return false + case !block.timeIsValid(chain, chain.Size()): + return false + case !block.transactionsIsValid(chain): + return false + } + return true +} + +func (block *Block) timeIsValid(chain *BlockChain, index uint64) bool { + btime, err := time.Parse(time.RFC3339, block.TimeStamp) + if err != nil { + return false + } + + diff := time.Now().Sub(btime) + if diff < 0 { + return false + } + + var sblock string + row := chain.DB.QueryRow("SELECT Block FROM BlockChain WHERE Hash=$1", + Base64Encode(block.PrevHash)) + row.Scan(&sblock) + + lblock := DeserializeBlock(sblock) + if lblock == nil { + return false + } + + ltime, err := time.Parse(time.RFC3339, lblock.TimeStamp) + if err != nil { + return false + } + + result := btime.Sub(ltime) + return result > 0 +} + +func (block *Block) transactionsIsValid(chain *BlockChain) bool { + lentxs := len(block.Transactions) + plusStorage := 0 + for i := 0; i < lentxs; i++ { + if block.Transactions[i].Sender == STORAGE_CHAIN { + plusStorage = 1 + break + } + } + if lentxs == 0 || lentxs > TXS_LIMIT+plusStorage { + return false + } + for i := 0; i < lentxs-1; i++ { + for j := i + 1; j < lentxs; j++ { + // rand bytes not be equal + if bytes.Equal(block.Transactions[i].RandBytes, block.Transactions[j].RandBytes) { + return false + } + // storage tx only one + if block.Transactions[i].Sender == STORAGE_CHAIN && + block.Transactions[j].Sender == STORAGE_CHAIN { + return false + } + } + } + for i := 0; i < lentxs; i++ { + tx := block.Transactions[i] + // storage tx has no hash and signature + if tx.Sender == STORAGE_CHAIN { + if tx.Receiver != block.Miner || tx.Value != STORAGE_REWARD { + return false + } + } else { + if !tx.hashIsValid() { + return false + } + if !tx.signIsValid() { + return false + } + } + if !block.balanceIsValid(chain, tx.Sender) { + return false + } + if !block.balanceIsValid(chain, tx.Receiver) { + return false + } + } + return true +} + +func (block *Block) balanceIsValid(chain *BlockChain, address string) bool { + if _, ok := block.Mapping[address]; !ok { + return false + } + lentxs := len(block.Transactions) + balanceInChain := chain.Balance(address) + balanceSubBlock := uint64(0) + balanceAddBlock := uint64(0) + for j := 0; j < lentxs; j++ { + tx := block.Transactions[j] + if tx.Sender == address { + balanceSubBlock += tx.Value + tx.ToStorage + } + if tx.Receiver == address { + balanceAddBlock += tx.Value + } + if STORAGE_CHAIN == address { + balanceAddBlock += tx.ToStorage + } + } + if (balanceInChain + balanceAddBlock - balanceSubBlock) != block.Mapping[address] { + return false + } + return true +} + func (block *Block) hash() []byte { var tempHash []byte for _, tx := range block.Transactions { @@ -62,8 +236,15 @@ func (block *Block) proof(ch chan bool) uint64 { return ProofOfWork(block.CurrHash, block.Difficulty, ch) } -func (block *Block) hashIsValid() bool { - return bytes.Equal(block.hash(), block.CurrHash) +func (block *Block) hashIsValid(chain *BlockChain, index uint64) bool { + if !bytes.Equal(block.hash(), block.CurrHash) { + return false + } + var id uint64 + row := chain.DB.QueryRow("SELECT Id FROM BlockChain WHERE Hash=$1", + Base64Encode(block.PrevHash)) + row.Scan(&id) + return id == index } func (block *Block) signIsValid() bool { diff --git a/blockchain/chain.go b/blockchain/chain.go index 6b0fd96..45fa61b 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -49,30 +49,6 @@ func LoadChain(filename string) *BlockChain { return chain } -func (chain *BlockChain) BlockIsValid(block *Block) bool { - switch { - case block == nil: - return false - case block.Difficulty != DIFFICULTY: - return false - case !block.hashIsValid(): - return false - case !chain.hashIsValid(block, chain.Size()): - return false - case !block.signIsValid(): - return false - case !block.proofIsValid(): - return false - case !block.mappingIsValid(): - return false - case !chain.timeIsValid(block, chain.Size()): - return false - case !chain.transactionsIsValid(block): - return false - } - return true -} - func (chain *BlockChain) Size() uint64 { var index uint64 row := chain.DB.QueryRow("SELECT Id FROM BlockChain ORDER BY Id DESC") @@ -111,16 +87,10 @@ func (chain *BlockChain) PrintChain() error { fmt.Printf("[%d][SUCCESS] difficulty is valid\n", index) } - if !block.hashIsValid() { - fmt.Printf("[%d][FAILED] block hash is not valid\n", index) + if !block.hashIsValid(chain, index-1) { + fmt.Printf("[%d][FAILED] hash is not valid\n", index) } else { - fmt.Printf("[%d][SUCCESS] block hash is valid\n", index) - } - - if !chain.hashIsValid(block, index-1) { - fmt.Printf("[%d][FAILED] chain hash is not valid\n", index) - } else { - fmt.Printf("[%d][SUCCESS] chain hash is valid\n", index) + fmt.Printf("[%d][SUCCESS] hash is valid\n", index) } if !block.signIsValid() { @@ -141,7 +111,7 @@ func (chain *BlockChain) PrintChain() error { fmt.Printf("[%d][SUCCESS] mapping is valid\n", index) } - if !chain.timeIsValid(block, index-1) { + if !block.timeIsValid(chain, index-1) { fmt.Printf("[%d][FAILED] time is not valid\n", index) } else { fmt.Printf("[%d][SUCCESS] time is valid\n", index) @@ -149,7 +119,7 @@ func (chain *BlockChain) PrintChain() error { size = chain.index chain.index = index - 1 - if !chain.transactionsIsValid(block) { + if !block.transactionsIsValid(chain) { fmt.Printf("[%d][FAILED] transactions is not valid\n", index) } else { fmt.Printf("[%d][SUCCESS] transactions is valid\n", index) @@ -168,7 +138,8 @@ func (chain *BlockChain) Balance(address string) uint64 { block *Block balance uint64 ) - rows, err := chain.DB.Query("SELECT Block FROM BlockChain WHERE Id <= $1 ORDER BY Id DESC", chain.index) + rows, err := chain.DB.Query("SELECT Block FROM BlockChain WHERE Id <= $1 ORDER BY Id DESC", + chain.index) if err != nil { return balance } @@ -191,23 +162,6 @@ func (chain *BlockChain) LastHash() []byte { return Base64Decode(hash) } -func (chain *BlockChain) AcceptBlock(user *User, block *Block, ch chan bool) *Block { - if !chain.transactionsIsValid(block) { - return nil - } - block.AddTransaction(chain, &Transaction{ - RandBytes: GenerateRandomBytes(RAND_BYTES), - Sender: STORAGE_CHAIN, - Receiver: user.Address(), - Value: STORAGE_REWARD, - }) - block.TimeStamp = time.Now().Format(time.RFC3339) - block.CurrHash = block.hash() - block.Signature = block.sign(user.Private()) - block.Nonce = block.proof(ch) - return block -} - func (chain *BlockChain) AddBlock(block *Block) { chain.index += 1 chain.DB.Exec("INSERT INTO BlockChain (Hash, Block) VALUES ($1, $2)", @@ -215,114 +169,3 @@ func (chain *BlockChain) AddBlock(block *Block) { SerializeBlock(block), ) } - -func (chain *BlockChain) timeIsValid(block *Block, index uint64) bool { - btime, err := time.Parse(time.RFC3339, block.TimeStamp) - if err != nil { - return false - } - - diff := time.Now().Sub(btime) - if diff < 0 { - return false - } - - var sblock string - row := chain.DB.QueryRow("SELECT Block FROM BlockChain WHERE Hash=$1", Base64Encode(block.PrevHash)) - row.Scan(&sblock) - - lblock := DeserializeBlock(sblock) - if lblock == nil { - return false - } - - ltime, err := time.Parse(time.RFC3339, lblock.TimeStamp) - if err != nil { - return false - } - - result := btime.Sub(ltime) - return result > 0 -} - -func (chain *BlockChain) hashIsValid(block *Block, index uint64) bool { - var id uint64 - row := chain.DB.QueryRow("SELECT Id FROM BlockChain WHERE Hash=$1", Base64Encode(block.PrevHash)) - row.Scan(&id) - return id == index -} - -func (chain *BlockChain) transactionsIsValid(block *Block) bool { - lentxs := len(block.Transactions) - plusStorage := 0 - for i := 0; i < lentxs; i++ { - if block.Transactions[i].Sender == STORAGE_CHAIN { - plusStorage = 1 - break - } - } - if lentxs == 0 || lentxs > TXS_LIMIT+plusStorage { - return false - } - for i := 0; i < lentxs-1; i++ { - for j := i + 1; j < lentxs; j++ { - // rand bytes not be equal - if bytes.Equal(block.Transactions[i].RandBytes, block.Transactions[j].RandBytes) { - return false - } - // storage tx only one - if block.Transactions[i].Sender == STORAGE_CHAIN && block.Transactions[j].Sender == STORAGE_CHAIN { - return false - } - } - } - for i := 0; i < lentxs; i++ { - tx := block.Transactions[i] - // storage tx has no hash and signature - if tx.Sender == STORAGE_CHAIN { - if tx.Receiver != block.Miner || tx.Value != STORAGE_REWARD { - return false - } - } else { - if !tx.hashIsValid() { - return false - } - if !tx.signIsValid() { - return false - } - } - if !chain.balanceIsValid(block, tx.Sender) { - return false - } - if !chain.balanceIsValid(block, tx.Receiver) { - return false - } - } - return true -} - -func (chain *BlockChain) balanceIsValid(block *Block, address string) bool { - lentxs := len(block.Transactions) - balanceInChain := chain.Balance(address) - balanceSubBlock := uint64(0) - balanceAddBlock := uint64(0) - for j := 0; j < lentxs; j++ { - tx := block.Transactions[j] - if tx.Sender == address { - balanceSubBlock += tx.Value + tx.ToStorage - } - if tx.Receiver == address { - balanceAddBlock += tx.Value - } - if STORAGE_CHAIN == address { - balanceAddBlock += tx.ToStorage - } - } - if _, ok := block.Mapping[address]; !ok { - return false - } - if (balanceInChain + balanceAddBlock - balanceSubBlock) != block.Mapping[address] { - return false - } - return true -} diff --git a/blockchain/crypto.go b/blockchain/crypto.go index 0ad4663..6525494 100644 --- a/blockchain/crypto.go +++ b/blockchain/crypto.go @@ -15,7 +15,6 @@ import ( mrand "math/rand" ) -// Create private key by size bits. func GeneratePrivate(bits uint16) *rsa.PrivateKey { priv, err := rsa.GenerateKey(rand.Reader, int(bits)) if err != nil { @@ -24,7 +23,6 @@ func GeneratePrivate(bits uint16) *rsa.PrivateKey { return priv } -// Generate bytes in range [0:256). func GenerateRandomBytes(max uint) []byte { var slice []byte = make([]byte, max) _, err := rand.Read(slice) @@ -34,13 +32,11 @@ func GenerateRandomBytes(max uint) []byte { return slice } -// SHA256(bytes). func HashSum(data []byte) []byte { hash := sha256.Sum256(data) return hash[:] } -// Sign data by private key. func Sign(priv *rsa.PrivateKey, data []byte) []byte { signature, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, data, nil) if err != nil { @@ -49,12 +45,10 @@ func Sign(priv *rsa.PrivateKey, data []byte) []byte { return signature } -// Verify data and signature by public key. func Verify(pub *rsa.PublicKey, data, sign []byte) error { return rsa.VerifyPSS(pub, crypto.SHA256, data, sign, nil) } -// POW for check hash package by Nonce. func ProofOfWork(blockHash []byte, difficulty uint8, ch chan bool) uint64 { var ( Target = big.NewInt(1) @@ -94,12 +88,10 @@ func ProofOfWork(blockHash []byte, difficulty uint8, ch chan bool) uint64 { return nonce } -// base64.StdEncoding.EncodeToString func Base64Encode(data []byte) string { return base64.StdEncoding.EncodeToString(data) } -// base64.StdEncoding.DecodeString func Base64Decode(data string) []byte { result, err := base64.StdEncoding.DecodeString(data) if err != nil { @@ -108,7 +100,6 @@ func Base64Decode(data string) []byte { return result } -// Translate uint64 to slice of bytes. func ToBytes(num uint64) []byte { var data = new(bytes.Buffer) err := binary.Write(data, binary.BigEndian, num) @@ -118,12 +109,10 @@ func ToBytes(num uint64) []byte { return data.Bytes() } -// Translate public key as *rsa.PublicKey to string. func StringPublic(pub *rsa.PublicKey) string { return Base64Encode(x509.MarshalPKCS1PublicKey(pub)) } -// Translate public key as string to *rsa.PublicKey. func ParsePublic(pubData string) *rsa.PublicKey { pub, err := x509.ParsePKCS1PublicKey(Base64Decode(pubData)) if err != nil { @@ -132,12 +121,10 @@ func ParsePublic(pubData string) *rsa.PublicKey { return pub } -// Translate public key as *rsa.PublicKey to string. func StringPrivate(priv *rsa.PrivateKey) string { return Base64Encode(x509.MarshalPKCS1PrivateKey(priv)) } -// Translate public key as string to *rsa.PublicKey. func ParsePrivate(privData string) *rsa.PrivateKey { pub, err := x509.ParsePKCS1PrivateKey(Base64Decode(privData)) if err != nil { diff --git a/blockchain/settings.go b/blockchain/settings.go index 6642b8b..6d3f935 100644 --- a/blockchain/settings.go +++ b/blockchain/settings.go @@ -21,7 +21,6 @@ CREATE TABLE BlockChain ( ) const ( - // DEBUG = false DEBUG = true KEY_SIZE = 512 STORAGE_CHAIN = "STORAGE-CHAIN" @@ -29,8 +28,8 @@ const ( STORAGE_REWARD = 1 GENESIS_BLOCK = "GENESIS-BLOCK" GENESIS_REWARD = 100 - DIFFICULTY = 20 // 15 - TXS_LIMIT = 2 // 6 + DIFFICULTY = 20 + TXS_LIMIT = 2 START_PERCENT = 10 RAND_BYTES = 32 ) @@ -47,16 +46,16 @@ type Block struct { PrevHash []byte Transactions []Transaction Mapping map[string]uint64 - Miner string // Hashname - Signature []byte // Miner sign + Miner string + Signature []byte TimeStamp string } type Transaction struct { RandBytes []byte PrevBlock []byte - Sender string // Hashname - Receiver string // Hashname + Sender string + Receiver string Value uint64 ToStorage uint64 CurrHash []byte diff --git a/blockchain/transaction.go b/blockchain/transaction.go index de983e9..e342d61 100644 --- a/blockchain/transaction.go +++ b/blockchain/transaction.go @@ -3,7 +3,6 @@ package blockchain import ( "bytes" "crypto/rsa" - "errors" ) func NewTransaction(user *User, lasthash []byte, to string, value uint64) *Transaction { @@ -22,32 +21,12 @@ func NewTransaction(user *User, lasthash []byte, to string, value uint64) *Trans return tx } -func (block *Block) AddTransaction(chain *BlockChain, tx *Transaction) error { - if len(block.Transactions) == TXS_LIMIT && tx.Sender != STORAGE_CHAIN { - return errors.New("len tx = limit") - } - balanceInChain := chain.Balance(tx.Sender) - balanceInBlock := tx.Value + tx.ToStorage - if value, ok := block.Mapping[tx.Sender]; ok { - balanceInChain = value - } - if tx.Value > START_PERCENT && tx.ToStorage != STORAGE_REWARD { - return errors.New("storage reward pass") - } - if balanceInBlock > balanceInChain { - return errors.New("insufficient funds") - } - block.Mapping[tx.Sender] = balanceInChain - balanceInBlock - chain.addBalance(block, tx.Receiver, tx.Value) - chain.addBalance(block, STORAGE_CHAIN, tx.ToStorage) - block.Transactions = append(block.Transactions, *tx) - return nil -} - -func (chain *BlockChain) addBalance(block *Block, receiver string, value uint64) { - balanceInChain := chain.Balance(receiver) +func (block *Block) addBalance(chain *BlockChain, receiver string, value uint64) { + var balanceInChain uint64 if v, ok := block.Mapping[receiver]; ok { balanceInChain = v + } else { + balanceInChain = chain.Balance(receiver) } block.Mapping[receiver] = balanceInChain + value } diff --git a/client.go b/client.go index 6eaa656..fc16077 100644 --- a/client.go +++ b/client.go @@ -104,6 +104,8 @@ func handleClient() { case "balance": chainBalance(splited[1:]) } + default: + fmt.Println("command undefined\n") } } } @@ -111,7 +113,7 @@ func handleClient() { func chainPrint() { for i := 0; ; i++ { res := nt.Send(Addresses[0], &nt.Package{ - Option: GET_CHAIN, + Option: GET_BLOCK, Data: fmt.Sprintf("%d", i), }) if res.Data == "" { @@ -134,14 +136,14 @@ func chainTX(splited []string) { } for _, addr := range Addresses { res := nt.Send(addr, &nt.Package{ - Option: GET_LASTHASH, + Option: GET_LHASH, }) if res == nil { continue } tx := bc.NewTransaction(User, bc.Base64Decode(res.Data), splited[1], uint64(num)) res = nt.Send(addr, &nt.Package{ - Option: ADD_TRANSACTION, + Option: ADD_TRNSX, Data: bc.SerializeTX(tx), }) if res == nil { @@ -164,14 +166,10 @@ func chainBalance(splited []string) { printBalance(splited[1]) } -func userBalance() { - printBalance(User.Address()) -} - func printBalance(useraddr string) { for _, addr := range Addresses { res := nt.Send(addr, &nt.Package{ - Option: GET_BALANCE, + Option: GET_BLNCE, Data: useraddr, }) fmt.Printf("Balance (%s): %s coins\n", addr, res.Data) @@ -187,6 +185,10 @@ func userPurse() { fmt.Println("Purse:", User.Purse(), "\n") } +func userBalance() { + printBalance(User.Address()) +} + func inputString(begin string) string { fmt.Print(begin) msg, _ := bufio.NewReader(os.Stdin).ReadString('\n') diff --git a/network/net.go b/network/net.go index 42e3d2a..32547f9 100644 --- a/network/net.go +++ b/network/net.go @@ -50,7 +50,7 @@ func Send(address string, pack *Package) *Package { return readPackage(conn) } -func Handle(option string, conn Conn, pack *Package, handle func(*Package) string) bool { +func Handle(option int, conn Conn, pack *Package, handle func(*Package) string) bool { if pack.Option != option { return false } diff --git a/network/settings.go b/network/settings.go index 9442a36..eb8e36c 100644 --- a/network/settings.go +++ b/network/settings.go @@ -7,6 +7,6 @@ const ( ) type Package struct { - Option string + Option int Data string } diff --git a/node.go b/node.go index 81aec63..fab4c0e 100644 --- a/node.go +++ b/node.go @@ -53,8 +53,10 @@ func init() { } } - if !(userNewExist || userLoadExist) || !(chainNewExist || chainLoadExist) || !serveExist || !addrExist { - panic("failed: !(userNewExist || userLoadExist) || !(chainNewExist || chainLoadExist) || !serveExist || !addrExist") + if !(userNewExist || userLoadExist) || !(chainNewExist || chainLoadExist) || + !serveExist || !addrExist { + panic("failed: !(userNewExist || userLoadExist)"+ + "|| !(chainNewExist || chainLoadExist) || !serveExist || !addrExist") } Serve = serveStr @@ -111,9 +113,6 @@ func main() { } func chainNew(filename string) *bc.BlockChain { - if User == nil { - return nil - } err := bc.NewChain(filename, User.Address()) if err != nil { return nil diff --git a/serve.go b/serve.go index 9695f06..f904f18 100644 --- a/serve.go +++ b/serve.go @@ -19,21 +19,19 @@ var ( Serve string Chain *bc.BlockChain Block *bc.Block +) + +var ( IsMining bool BreakMining = make(chan bool) ) func handleServer(conn nt.Conn, pack *nt.Package) { - nt.Handle(GET_SIZE, conn, pack, getSize) nt.Handle(ADD_BLOCK, conn, pack, addBlock) - nt.Handle(GET_CHAIN, conn, pack, getChain) - nt.Handle(GET_LASTHASH, conn, pack, getLastHash) - nt.Handle(GET_BALANCE, conn, pack, getBalance) - nt.Handle(ADD_TRANSACTION, conn, pack, addTransaction) -} - -func getSize(pack *nt.Package) string { - return fmt.Sprintf("%d", Chain.Size()) + nt.Handle(GET_BLOCK, conn, pack, getBlock) + nt.Handle(GET_LHASH, conn, pack, getLastHash) + nt.Handle(GET_BLNCE, conn, pack, getBalance) + nt.Handle(ADD_TRNSX, conn, pack, addTransaction) } func addBlock(pack *nt.Package) string { @@ -41,8 +39,9 @@ func addBlock(pack *nt.Package) string { if len(splited) != 3 { return "fail" } + block := bc.DeserializeBlock(splited[2]) - if !Chain.BlockIsValid(block) { + if !block.IsValid(Chain) { currSize := Chain.Size() num, err := strconv.Atoi(splited[1]) if err != nil { @@ -77,7 +76,7 @@ func compareChains(address string, num uint64) string { }() res := nt.Send(address, &nt.Package{ - Option: GET_CHAIN, + Option: GET_BLOCK, Data: fmt.Sprintf("%d", 0), }) if res == nil { @@ -107,7 +106,7 @@ func compareChains(address string, num uint64) string { for i := uint64(1); i < num; i++ { res := nt.Send(address, &nt.Package{ - Option: GET_CHAIN, + Option: GET_BLOCK, Data: fmt.Sprintf("%d", i), }) if res == nil { @@ -117,7 +116,7 @@ func compareChains(address string, num uint64) string { if block == nil { return "fail" } - if !chain.BlockIsValid(block) { + if !block.IsValid(chain) { return "fail" } chain.AddBlock(block) @@ -158,25 +157,18 @@ func copyFile(src, dst string) error { return out.Close() } -func getChain(pack *nt.Package) string { +func getBlock(pack *nt.Package) string { num, err := strconv.Atoi(pack.Data) if err != nil { return "" } size := Chain.Size() if uint64(num) < size { - return getBlock(Chain, num) + return selectBlock(Chain, num) } return "" } -func getBlock(chain *bc.BlockChain, i int) string { - var block string - row := chain.DB.QueryRow("SELECT Block FROM BlockChain WHERE Id=$1", i+1) - row.Scan(&block) - return block -} - func getLastHash(pack *nt.Package) string { return bc.Base64Encode(Chain.LastHash()) } @@ -185,6 +177,13 @@ func getBalance(pack *nt.Package) string { return fmt.Sprintf("%d", Chain.Balance(pack.Data)) } +func selectBlock(chain *bc.BlockChain, i int) string { + var block string + row := chain.DB.QueryRow("SELECT Block FROM BlockChain WHERE Id=$1", i+1) + row.Scan(&block) + return block +} + func addTransaction(pack *nt.Package) string { var tx = bc.DeserializeTX(pack.Data) if tx == nil || len(Block.Transactions) == bc.TXS_LIMIT { @@ -197,9 +196,9 @@ func addTransaction(pack *nt.Package) string { go func() { block := *Block IsMining = true - res := Chain.AcceptBlock(User, &block, BreakMining) + res := (&block).Accept(Chain, User, BreakMining) IsMining = false - if res != nil && bytes.Equal(block.PrevHash, Block.PrevHash) { + if res == nil && bytes.Equal(block.PrevHash, Block.PrevHash) { Chain.AddBlock(&block) pushBlockToNet(&block) } diff --git a/values.go b/values.go index 41958ae..d2df7f5 100644 --- a/values.go +++ b/values.go @@ -15,12 +15,11 @@ const ( ) const ( - GET_SIZE = "[GET_SIZE]" - ADD_BLOCK = "[ADD_BLOCK]" - GET_CHAIN = "[GET_CHAIN]" - GET_LASTHASH = "[GET_LASTHASH]" - GET_BALANCE = "[GET_BALANCE]" - ADD_TRANSACTION = "[ADD_TRANSACTION]" + ADD_BLOCK = iota + 1 + ADD_TRNSX + GET_BLOCK + GET_LHASH + GET_BLNCE ) func userNew(filename string) *bc.User {