199 lines
6.0 KiB
Go
199 lines
6.0 KiB
Go
package state
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
|
|
"github.com/tutus-one/tutus-chain/pkg/util"
|
|
"github.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,
|
|
}
|
|
}
|