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

411 lines
13 KiB
Go
Executable File

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
}