package dao import ( "encoding/json" "log" "sync" "time" ) type ProposalType string const ( GenericProposal ProposalType = "GENERIC" ParamChangeProposal ProposalType = "PARAM_CHANGE" ) type Proposal struct { ID uint64 Title string Content string Type ProposalType Creator string CreatedAt int64 Duration int64 // segundos até expiração Votes map[string]bool Closed bool Approved bool mu sync.Mutex } func NewProposal(id uint64, title, content, creator string, typ ProposalType, duration int64) *Proposal { return &Proposal{ ID: id, Title: title, Content: content, Type: typ, Creator: creator, CreatedAt: time.Now().Unix(), Duration: duration, Votes: make(map[string]bool), Closed: false, Approved: false, } } func (p *Proposal) Vote(address string, approve bool) error { p.mu.Lock() defer p.mu.Unlock() if p.Closed { return nil } p.Votes[address] = approve return nil } func (p *Proposal) Tally(stakes map[string]uint64) (yes uint64, no uint64, total uint64) { p.mu.Lock() defer p.mu.Unlock() for addr, vote := range p.Votes { stake := stakes[addr] total += stake if vote { yes += stake } else { no += stake } } return } func (p *Proposal) CheckAndClose(stakes map[string]uint64) { if p.Closed { return } if time.Now().Unix() >= p.CreatedAt+p.Duration { yes, _, total := p.Tally(stakes) if yes*100/total > 66 { p.Approved = true } p.Closed = true if p.Approved { p.Execute() } } } // Execute aplica os efeitos da proposta, se for do tipo que altera estado func (p *Proposal) Execute() { if p.Type == ParamChangeProposal { var payload struct { Target string `json:"target"` Value uint64 `json:"value"` } err := json.Unmarshal([]byte(p.Content), &payload) if err != nil { log.Printf("❌ Erro ao executar proposta PARAM_CHANGE: %v", err) return } // Exemplo: muda parâmetro global (placeholder) log.Printf("⚙️ Aplicando PARAM_CHANGE: %s = %d", payload.Target, payload.Value) // Aqui você aplicaria no config real } }