tutus-chain/pkg/core/state/annos.go

199 lines
6.0 KiB
Go

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,
}
}