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" ) // LawCategory represents the hierarchical category of a law. type LawCategory uint8 const ( // LawCategoryConstitutional represents immutable constitutional rights. LawCategoryConstitutional LawCategory = 1 // LawCategoryFederal represents national/federal laws. LawCategoryFederal LawCategory = 2 // LawCategoryRegional represents state/province laws. LawCategoryRegional LawCategory = 3 // LawCategoryLocal represents municipal/local laws. LawCategoryLocal LawCategory = 4 // LawCategoryAdministrative represents regulations and administrative rules. LawCategoryAdministrative LawCategory = 5 ) // LawStatus represents the current status of a law. type LawStatus uint8 const ( // LawStatusDraft indicates a proposed law not yet voted. LawStatusDraft LawStatus = 0 // LawStatusActive indicates a law currently in force. LawStatusActive LawStatus = 1 // LawStatusSuspended indicates a temporarily suspended law. LawStatusSuspended LawStatus = 2 // LawStatusRepealed indicates a permanently removed law. LawStatusRepealed LawStatus = 3 // LawStatusSuperseded indicates a law replaced by a newer one. LawStatusSuperseded LawStatus = 4 ) // EnforcementType specifies how a law is enforced. type EnforcementType uint8 const ( // EnforcementAutomatic means smart contracts block violations. EnforcementAutomatic EnforcementType = 1 // EnforcementLogging means violations emit events but allow transaction. EnforcementLogging EnforcementType = 2 // EnforcementAdvisory means non-binding guidance only. EnforcementAdvisory EnforcementType = 3 ) // RestrictionType represents the type of rights restriction. type RestrictionType uint8 const ( // RestrictionSuspend temporarily suspends a right. RestrictionSuspend RestrictionType = 1 // RestrictionLimit limits a right (e.g., movement within area). RestrictionLimit RestrictionType = 2 // RestrictionCondition makes a right conditional (e.g., probation). RestrictionCondition RestrictionType = 3 ) // ConstitutionalRight IDs - these are immutable and built into the protocol. const ( RightLife uint64 = 1 // Right to life RightLiberty uint64 = 2 // Freedom from arbitrary detention RightProperty uint64 = 3 // Right to own and transfer assets RightEquality uint64 = 4 // Equal treatment under law RightDueProcess uint64 = 5 // Fair legal proceedings RightPrivacy uint64 = 6 // Privacy of personal data RightExpression uint64 = 7 // Freedom of expression RightAssembly uint64 = 8 // Freedom of assembly RightMovement uint64 = 9 // Freedom of movement RightEducation uint64 = 10 // Right to education RightHealthcare uint64 = 11 // Right to healthcare RightLabor uint64 = 12 // Right to fair labor RightVote uint64 = 13 // Right to vote RightAsylum uint64 = 14 // Right to seek asylum // MaxConstitutionalRight is the highest constitutional right ID. MaxConstitutionalRight uint64 = 14 ) // Law represents a law in the registry. type Law struct { ID uint64 // Unique law identifier Name string // Human-readable name ContentHash util.Uint256 // Hash of full law text (stored off-chain) Category LawCategory // Constitutional, Federal, Regional, Local Jurisdiction uint32 // Jurisdiction ID (0 = global) ParentID uint64 // Parent law in hierarchy (0 = root) EffectiveAt uint32 // Block height when law becomes active ExpiresAt uint32 // Block height when law expires (0 = perpetual) EnactedAt uint32 // Block height of enactment EnactedBy util.Uint160 // Authority that enacted Status LawStatus // Active, Suspended, Repealed, Superseded SupersededBy uint64 // ID of law that replaced this one RequiresVita bool // Whether law applies only to Vita holders Enforcement EnforcementType // How law is enforced } // ToStackItem implements stackitem.Convertible interface. func (l *Law) ToStackItem() (stackitem.Item, error) { return stackitem.NewStruct([]stackitem.Item{ stackitem.NewBigInteger(big.NewInt(int64(l.ID))), stackitem.NewByteArray([]byte(l.Name)), stackitem.NewByteArray(l.ContentHash[:]), stackitem.NewBigInteger(big.NewInt(int64(l.Category))), stackitem.NewBigInteger(big.NewInt(int64(l.Jurisdiction))), stackitem.NewBigInteger(big.NewInt(int64(l.ParentID))), stackitem.NewBigInteger(big.NewInt(int64(l.EffectiveAt))), stackitem.NewBigInteger(big.NewInt(int64(l.ExpiresAt))), stackitem.NewBigInteger(big.NewInt(int64(l.EnactedAt))), stackitem.NewByteArray(l.EnactedBy.BytesBE()), stackitem.NewBigInteger(big.NewInt(int64(l.Status))), stackitem.NewBigInteger(big.NewInt(int64(l.SupersededBy))), stackitem.NewBool(l.RequiresVita), stackitem.NewBigInteger(big.NewInt(int64(l.Enforcement))), }), nil } // FromStackItem implements stackitem.Convertible interface. func (l *Law) FromStackItem(item stackitem.Item) error { items, ok := item.Value().([]stackitem.Item) if !ok { return errors.New("not a struct") } if len(items) != 14 { return fmt.Errorf("wrong number of elements: expected 14, got %d", len(items)) } id, err := items[0].TryInteger() if err != nil { return fmt.Errorf("invalid ID: %w", err) } l.ID = id.Uint64() name, err := items[1].TryBytes() if err != nil { return fmt.Errorf("invalid Name: %w", err) } l.Name = string(name) contentHash, err := items[2].TryBytes() if err != nil { return fmt.Errorf("invalid ContentHash: %w", err) } if len(contentHash) == 32 { copy(l.ContentHash[:], contentHash) } category, err := items[3].TryInteger() if err != nil { return fmt.Errorf("invalid Category: %w", err) } l.Category = LawCategory(category.Uint64()) jurisdiction, err := items[4].TryInteger() if err != nil { return fmt.Errorf("invalid Jurisdiction: %w", err) } l.Jurisdiction = uint32(jurisdiction.Uint64()) parentID, err := items[5].TryInteger() if err != nil { return fmt.Errorf("invalid ParentID: %w", err) } l.ParentID = parentID.Uint64() effectiveAt, err := items[6].TryInteger() if err != nil { return fmt.Errorf("invalid EffectiveAt: %w", err) } l.EffectiveAt = uint32(effectiveAt.Uint64()) expiresAt, err := items[7].TryInteger() if err != nil { return fmt.Errorf("invalid ExpiresAt: %w", err) } l.ExpiresAt = uint32(expiresAt.Uint64()) enactedAt, err := items[8].TryInteger() if err != nil { return fmt.Errorf("invalid EnactedAt: %w", err) } l.EnactedAt = uint32(enactedAt.Uint64()) enactedBy, err := items[9].TryBytes() if err != nil { return fmt.Errorf("invalid EnactedBy: %w", err) } l.EnactedBy, err = util.Uint160DecodeBytesBE(enactedBy) if err != nil { return fmt.Errorf("invalid EnactedBy address: %w", err) } status, err := items[10].TryInteger() if err != nil { return fmt.Errorf("invalid Status: %w", err) } l.Status = LawStatus(status.Uint64()) supersededBy, err := items[11].TryInteger() if err != nil { return fmt.Errorf("invalid SupersededBy: %w", err) } l.SupersededBy = supersededBy.Uint64() requiresVita, err := items[12].TryBool() if err != nil { return fmt.Errorf("invalid RequiresVita: %w", err) } l.RequiresVita = requiresVita enforcement, err := items[13].TryInteger() if err != nil { return fmt.Errorf("invalid Enforcement: %w", err) } l.Enforcement = EnforcementType(enforcement.Uint64()) return nil } // Bytes serializes the Law to bytes. func (l *Law) Bytes() []byte { item, _ := l.ToStackItem() data, _ := stackitem.Serialize(item) return data } // LawFromBytes deserializes a Law from bytes. func LawFromBytes(data []byte) (*Law, error) { item, err := stackitem.Deserialize(data) if err != nil { return nil, err } l := &Law{} if err := l.FromStackItem(item); err != nil { return nil, err } return l, nil } // RightsRestriction represents a restriction on a constitutional right. type RightsRestriction struct { Subject util.Uint160 // Who is restricted RightID uint64 // Which right is restricted RestrictionType RestrictionType // Type of restriction IssuedBy util.Uint160 // Authority that issued IssuedAt uint32 // Block height when issued ExpiresAt uint32 // When restriction ends (must be set) Reason string // Legal basis CaseID util.Uint256 // Associated legal case (required for due process) } // ToStackItem implements stackitem.Convertible interface. func (r *RightsRestriction) ToStackItem() (stackitem.Item, error) { return stackitem.NewStruct([]stackitem.Item{ stackitem.NewByteArray(r.Subject.BytesBE()), stackitem.NewBigInteger(big.NewInt(int64(r.RightID))), stackitem.NewBigInteger(big.NewInt(int64(r.RestrictionType))), stackitem.NewByteArray(r.IssuedBy.BytesBE()), stackitem.NewBigInteger(big.NewInt(int64(r.IssuedAt))), stackitem.NewBigInteger(big.NewInt(int64(r.ExpiresAt))), stackitem.NewByteArray([]byte(r.Reason)), stackitem.NewByteArray(r.CaseID[:]), }), nil } // FromStackItem implements stackitem.Convertible interface. func (r *RightsRestriction) 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)) } subject, err := items[0].TryBytes() if err != nil { return fmt.Errorf("invalid Subject: %w", err) } r.Subject, err = util.Uint160DecodeBytesBE(subject) if err != nil { return fmt.Errorf("invalid Subject address: %w", err) } rightID, err := items[1].TryInteger() if err != nil { return fmt.Errorf("invalid RightID: %w", err) } r.RightID = rightID.Uint64() restrictionType, err := items[2].TryInteger() if err != nil { return fmt.Errorf("invalid RestrictionType: %w", err) } r.RestrictionType = RestrictionType(restrictionType.Uint64()) issuedBy, err := items[3].TryBytes() if err != nil { return fmt.Errorf("invalid IssuedBy: %w", err) } r.IssuedBy, err = util.Uint160DecodeBytesBE(issuedBy) if err != nil { return fmt.Errorf("invalid IssuedBy address: %w", err) } issuedAt, err := items[4].TryInteger() if err != nil { return fmt.Errorf("invalid IssuedAt: %w", err) } r.IssuedAt = uint32(issuedAt.Uint64()) expiresAt, err := items[5].TryInteger() if err != nil { return fmt.Errorf("invalid ExpiresAt: %w", err) } r.ExpiresAt = uint32(expiresAt.Uint64()) reason, err := items[6].TryBytes() if err != nil { return fmt.Errorf("invalid Reason: %w", err) } r.Reason = string(reason) caseID, err := items[7].TryBytes() if err != nil { return fmt.Errorf("invalid CaseID: %w", err) } if len(caseID) == 32 { copy(r.CaseID[:], caseID) } return nil } // Bytes serializes the RightsRestriction to bytes. func (r *RightsRestriction) Bytes() []byte { item, _ := r.ToStackItem() data, _ := stackitem.Serialize(item) return data } // RightsRestrictionFromBytes deserializes a RightsRestriction from bytes. func RightsRestrictionFromBytes(data []byte) (*RightsRestriction, error) { item, err := stackitem.Deserialize(data) if err != nil { return nil, err } r := &RightsRestriction{} if err := r.FromStackItem(item); err != nil { return nil, err } return r, nil } // IsExpired returns true if the restriction has expired. func (r *RightsRestriction) IsExpired(currentBlock uint32) bool { return r.ExpiresAt != 0 && r.ExpiresAt <= currentBlock } // ConstitutionalRight represents an immutable constitutional right. type ConstitutionalRight struct { ID uint64 // Right ID (1-14) Name string // Human-readable name Description string // Description of the right Enforcement EnforcementType // How right is enforced } // GetConstitutionalRights returns all 14 constitutional rights. // These are hardcoded and immutable. func GetConstitutionalRights() []ConstitutionalRight { return []ConstitutionalRight{ {RightLife, "Life", "Protection from arbitrary death", EnforcementAutomatic}, {RightLiberty, "Liberty", "Freedom from arbitrary detention", EnforcementAutomatic}, {RightProperty, "Property", "Right to own and transfer assets", EnforcementAutomatic}, {RightEquality, "Equality", "Equal treatment under law", EnforcementAutomatic}, {RightDueProcess, "DueProcess", "Fair legal proceedings before restriction", EnforcementAutomatic}, {RightPrivacy, "Privacy", "Privacy of personal data", EnforcementAutomatic}, {RightExpression, "Expression", "Freedom of expression", EnforcementLogging}, {RightAssembly, "Assembly", "Freedom of assembly", EnforcementLogging}, {RightMovement, "Movement", "Freedom of movement", EnforcementAutomatic}, {RightEducation, "Education", "Right to education", EnforcementLogging}, {RightHealthcare, "Healthcare", "Right to healthcare", EnforcementLogging}, {RightLabor, "Labor", "Right to fair labor conditions", EnforcementLogging}, {RightVote, "Vote", "Right to participate in democracy", EnforcementAutomatic}, {RightAsylum, "Asylum", "Right to seek protection from persecution", EnforcementAutomatic}, } } // GetConstitutionalRight returns a specific constitutional right by ID. func GetConstitutionalRight(id uint64) *ConstitutionalRight { if id < 1 || id > MaxConstitutionalRight { return nil } rights := GetConstitutionalRights() return &rights[id-1] } // IsConstitutionalRight returns true if the right ID is a constitutional right. func IsConstitutionalRight(id uint64) bool { return id >= 1 && id <= MaxConstitutionalRight }