package consensus import ( "crypto/ecdsa" "crypto/rand" "crypto/sha256" "encoding/hex" "errors" "fmt" "math/big" "time" "dejo_node/internal/transactions" ) // Finalizer encapsula a lógica de selar e assinar blocos. type Finalizer struct { PrivateKey *ecdsa.PrivateKey NodeID string // opcional: ID do produtor do bloco } // Finalize executa a finalização de um bloco: // - Adiciona timestamp // - Gera hash final // - Retorna assinatura func (f *Finalizer) Finalize(block *transactions.Block) (string, error) { if block == nil { return "", errors.New("bloco nulo") } block.Timestamp = time.Now().Unix() // Geração do hash usando campos existentes do bloco hashInput := []byte( fmt.Sprintf("%d|%s|%d|%s", block.Index, block.PrevHash, block.Timestamp, f.NodeID, ), ) hash := sha256.Sum256(hashInput) block.Hash = hex.EncodeToString(hash[:]) r, s, err := ecdsa.Sign(rand.Reader, f.PrivateKey, hash[:]) if err != nil { return "", err } sig := append(r.Bytes(), s.Bytes()...) signature := hex.EncodeToString(sig) return signature, nil } // VerifySignature verifica se a assinatura é válida com a chave pública fornecida. func VerifySignature(block *transactions.Block, signature string, pubKey *ecdsa.PublicKey) bool { hash, err := hex.DecodeString(block.Hash) if err != nil { return false } sig, err := hex.DecodeString(signature) if err != nil || len(sig) < 64 { return false } r := big.NewInt(0).SetBytes(sig[:len(sig)/2]) s := big.NewInt(0).SetBytes(sig[len(sig)/2:]) return ecdsa.Verify(pubKey, hash, r, s) }