package core import ( "context" "crypto/sha256" "encoding/hex" "encoding/json" "errors" "fmt" "hash" "log" "time" "thesis/crypto" "thesis/ent" ) /* ** Type 1: Transaction sync ** Type 2: New Transaction cast */ type DataPacket struct { Type int Data []byte } func (p DataPacket) Serialize() []byte { data, err := json.Marshal(p) if err != nil { panic(err) } return data } func DeSerialize(p []byte) DataPacket { var msg DataPacket err := json.Unmarshal(p, &msg) if err != nil { panic(err) } return msg } func SyncContent(msg DataPacket) { if msg.Type == 1 { fmt.Println("got a tx sync") } } func ValidateContent(client *ent.Client, pk *crypto.PublicKey) error { txs, err := client.Transactions.Query().All(context.Background()) handleError(err) for i := 0; i < len(txs); i++ { currentTx := &Transaction{ Type: txs[i].Type, Timestamp: int64(txs[i].Timestamp), Comment: txs[i].Comment, Content: txs[i].Content, Hash: txs[i].Hash, Signature: txs[i].Signature, } // fmt.Println(currentTx) err := crypto.ValidateSignature(currentTx.Signature, pk, []byte(currentTx.Hash)) handleError(err) log.Printf("Valid signature for tx: %s", currentTx.Hash) } blocks, err := client.Blocks.Query().All(context.Background()) handleError(err) for i := 0; i < len(blocks); i++ { // currentBlock := &core.Block{ // Hash: blocks[i].Hash, // Nonce: blocks[i].ID, // Length: blocks[i].Length, // PreviousHash: blocks[i].PreviousHash, // } txs, err := blocks[i].QueryMinedTxs().All(context.Background()) handleError(err) var hash hash.Hash for j := 0; j < len(txs); j++ { tx := &Transaction{ Type: txs[j].Type, Timestamp: int64(txs[j].Timestamp), Comment: txs[j].Comment, Content: txs[j].Content, Hash: txs[j].Hash, Signature: txs[j].Signature, } txBytes, err := json.Marshal(tx) handleError(err) hash = sha256.New() hash.Write(txBytes) } if fmt.Sprintf("0x%x", string(hash.Sum(nil))) == blocks[i].Hash { log.Printf("Block %d validated \n", blocks[i].ID) } else { log.Printf("Block %d is invalid !!!\n", blocks[i].ID) return errors.New("invalid block detected") } } return nil } func AddNewTx(client *ent.Client, content []byte, commit string, sig string, key *ent.Key) error { // key := db.GetKeyFromHex(pk) // if key == nil { // return // } tx := &Transaction{ Type: 2, Timestamp: time.Now().Unix(), Comment: "regular tx", Content: content, Signature: sig, } txBytes, err := json.Marshal(tx) handleError(err) hash := sha256.New() hash.Write(txBytes) tx.Hash = fmt.Sprintf("0x%x", string(hash.Sum(nil))) pubBytes, err := hex.DecodeString(key.PublicKey[2:]) handleError(err) pk := new(crypto.PublicKey).Uncompress(pubBytes) fmt.Println(hash) err = crypto.ValidateSignature(sig, pk, []byte(fmt.Sprintf("%s%s%s", key.PublicKey, tx.Comment, commit))) if err != nil { fmt.Println("Invalid data submitted") // return nil } txContent := &TransactionContent{ Signer: key.PublicKey, Commitment: commit, } contentBytes, err := json.Marshal(txContent) handleError(err) dbTX, err := client.Transactions.Create(). SetComment(tx.Comment). SetHash(tx.Hash). SetTimestamp(int(tx.Timestamp)). SetSignature(tx.Signature). SetType(tx.Type). SetContent(contentBytes). Save(context.Background()) handleError(err) // db.AddTx(client, txObj) txBytes, err = json.Marshal(tx) handleError(err) hash = sha256.New() hash.Write(txBytes) blocks, err := client.Blocks.Query().All(context.Background()) handleError(err) var block Block if len(blocks) == 0 { block = Block{ Hash: fmt.Sprintf("0x%x", string(hash.Sum(nil))), Nonce: 0, Length: 1, PreviousHash: "0x000", } } else { lastBlock := blocks[len(blocks)-1] block = Block{ Hash: fmt.Sprintf("0x%x", string(hash.Sum(nil))), Nonce: lastBlock.ID, Length: 1, PreviousHash: lastBlock.Hash, } } dbBlock, err := client.Blocks.Create(). SetHash(block.Hash). SetID(block.Nonce). SetLength(block.Length). SetPreviousHash(block.PreviousHash). Save(context.Background()) handleError(err) _, err = dbTX.Update().AddBlock(dbBlock).Save(context.Background()) handleError(err) return nil } func handleError(err error) { if err != nil { panic(err) } }