package state import ( "errors" "fmt" "math/big" "git.marketally.com/tutus-one/tutus-chain/pkg/util" "git.marketally.com/tutus-one/tutus-chain/pkg/vm/stackitem" ) // LifeStage represents age-based life stages. type LifeStage uint8 const ( // LifeStageChild indicates ages 0-17 years. LifeStageChild LifeStage = 0 // LifeStageYouth indicates ages 18-25 years. LifeStageYouth LifeStage = 1 // LifeStageAdult indicates ages 26-64 years. LifeStageAdult LifeStage = 2 // LifeStageElder indicates ages 65+ years. LifeStageElder LifeStage = 3 ) // LifespanStatus represents the living status of a person. type LifespanStatus uint8 const ( // LifespanActive indicates the person is alive. LifespanActive LifespanStatus = 0 // LifespanDeceased indicates the person has passed away. LifespanDeceased LifespanStatus = 1 ) // LifespanRecord tracks a person's lifespan tied to their Vita. type LifespanRecord struct { VitaID uint64 // Owner's Vita token ID Owner util.Uint160 // Owner's address BirthTimestamp uint64 // Unix timestamp of actual birth (provided during registration) RegistrationBlock uint32 // Block height when Vita was minted RegistrationTime uint64 // Timestamp when Vita was minted DeathTimestamp uint64 // 0 = alive, >0 = time of death DeathBlock uint32 // 0 = alive, >0 = block when death recorded Status LifespanStatus // Current lifespan status } // ToStackItem implements stackitem.Convertible interface. func (r *LifespanRecord) ToStackItem() (stackitem.Item, error) { return stackitem.NewStruct([]stackitem.Item{ stackitem.NewBigInteger(big.NewInt(int64(r.VitaID))), stackitem.NewByteArray(r.Owner.BytesBE()), stackitem.NewBigInteger(new(big.Int).SetUint64(r.BirthTimestamp)), stackitem.NewBigInteger(big.NewInt(int64(r.RegistrationBlock))), stackitem.NewBigInteger(new(big.Int).SetUint64(r.RegistrationTime)), stackitem.NewBigInteger(new(big.Int).SetUint64(r.DeathTimestamp)), stackitem.NewBigInteger(big.NewInt(int64(r.DeathBlock))), stackitem.NewBigInteger(big.NewInt(int64(r.Status))), }), nil } // FromStackItem implements stackitem.Convertible interface. func (r *LifespanRecord) FromStackItem(item stackitem.Item) error { items, ok := item.Value().([]stackitem.Item) if !ok { return errors.New("not a struct") } if len(items) != 8 { return fmt.Errorf("wrong number of elements: expected 8, got %d", len(items)) } vitaID, err := items[0].TryInteger() if err != nil { return fmt.Errorf("invalid vitaID: %w", err) } r.VitaID = vitaID.Uint64() ownerBytes, err := items[1].TryBytes() if err != nil { return fmt.Errorf("invalid owner: %w", err) } r.Owner, err = util.Uint160DecodeBytesBE(ownerBytes) if err != nil { return fmt.Errorf("invalid owner hash: %w", err) } birthTimestamp, err := items[2].TryInteger() if err != nil { return fmt.Errorf("invalid birthTimestamp: %w", err) } r.BirthTimestamp = birthTimestamp.Uint64() registrationBlock, err := items[3].TryInteger() if err != nil { return fmt.Errorf("invalid registrationBlock: %w", err) } r.RegistrationBlock = uint32(registrationBlock.Int64()) registrationTime, err := items[4].TryInteger() if err != nil { return fmt.Errorf("invalid registrationTime: %w", err) } r.RegistrationTime = registrationTime.Uint64() deathTimestamp, err := items[5].TryInteger() if err != nil { return fmt.Errorf("invalid deathTimestamp: %w", err) } r.DeathTimestamp = deathTimestamp.Uint64() deathBlock, err := items[6].TryInteger() if err != nil { return fmt.Errorf("invalid deathBlock: %w", err) } r.DeathBlock = uint32(deathBlock.Int64()) status, err := items[7].TryInteger() if err != nil { return fmt.Errorf("invalid status: %w", err) } r.Status = LifespanStatus(status.Int64()) return nil } // AnnosConfig represents configurable parameters for the Annos contract. type AnnosConfig struct { VotingAge uint8 // Age required to vote (default: 18) AdultAge uint8 // Age of legal adulthood (default: 18) RetirementAge uint8 // Age of retirement eligibility (default: 65) YouthMaxAge uint8 // Maximum age for youth stage (default: 25) ElderMinAge uint8 // Minimum age for elder stage (default: 65) } // ToStackItem implements stackitem.Convertible interface. func (c *AnnosConfig) ToStackItem() (stackitem.Item, error) { return stackitem.NewStruct([]stackitem.Item{ stackitem.NewBigInteger(big.NewInt(int64(c.VotingAge))), stackitem.NewBigInteger(big.NewInt(int64(c.AdultAge))), stackitem.NewBigInteger(big.NewInt(int64(c.RetirementAge))), stackitem.NewBigInteger(big.NewInt(int64(c.YouthMaxAge))), stackitem.NewBigInteger(big.NewInt(int64(c.ElderMinAge))), }), nil } // FromStackItem implements stackitem.Convertible interface. func (c *AnnosConfig) FromStackItem(item stackitem.Item) error { items, ok := item.Value().([]stackitem.Item) if !ok { return errors.New("not a struct") } if len(items) != 5 { return fmt.Errorf("wrong number of elements: expected 5, got %d", len(items)) } votingAge, err := items[0].TryInteger() if err != nil { return fmt.Errorf("invalid votingAge: %w", err) } c.VotingAge = uint8(votingAge.Int64()) adultAge, err := items[1].TryInteger() if err != nil { return fmt.Errorf("invalid adultAge: %w", err) } c.AdultAge = uint8(adultAge.Int64()) retirementAge, err := items[2].TryInteger() if err != nil { return fmt.Errorf("invalid retirementAge: %w", err) } c.RetirementAge = uint8(retirementAge.Int64()) youthMaxAge, err := items[3].TryInteger() if err != nil { return fmt.Errorf("invalid youthMaxAge: %w", err) } c.YouthMaxAge = uint8(youthMaxAge.Int64()) elderMinAge, err := items[4].TryInteger() if err != nil { return fmt.Errorf("invalid elderMinAge: %w", err) } c.ElderMinAge = uint8(elderMinAge.Int64()) return nil } // DefaultAnnosConfig returns the default configuration for Annos. func DefaultAnnosConfig() AnnosConfig { return AnnosConfig{ VotingAge: 18, AdultAge: 18, RetirementAge: 65, YouthMaxAge: 25, ElderMinAge: 65, } }