package native import ( "math/big" "strings" "github.com/tutus-one/tutus-chain/pkg/config" "github.com/tutus-one/tutus-chain/pkg/core/dao" "github.com/tutus-one/tutus-chain/pkg/core/interop" "github.com/tutus-one/tutus-chain/pkg/core/interop/interopnames" "github.com/tutus-one/tutus-chain/pkg/core/native/nativenames" "github.com/tutus-one/tutus-chain/pkg/core/native/noderoles" "github.com/tutus-one/tutus-chain/pkg/core/state" "github.com/tutus-one/tutus-chain/pkg/core/transaction" "github.com/tutus-one/tutus-chain/pkg/crypto/keys" "github.com/tutus-one/tutus-chain/pkg/io" "github.com/tutus-one/tutus-chain/pkg/util" "github.com/tutus-one/tutus-chain/pkg/vm/emit" ) // Native contract interfaces sufficient for Blockchain functioning and // cross-native interaction. type ( // IManagement is an interface required from native ContractManagement // contract for interaction with Blockchain and other native contracts. IManagement interface { interop.Contract GetNEP11Contracts(d *dao.Simple) []util.Uint160 GetNEP17Contracts(d *dao.Simple) []util.Uint160 } // INEO is an interface required from native NeoToken contract for // interaction with Blockchain and other native contracts. INEO interface { interop.Contract GetCommitteeAddress(d *dao.Simple) util.Uint160 GetNextBlockValidatorsInternal(d *dao.Simple) keys.PublicKeys BalanceOf(d *dao.Simple, acc util.Uint160) (*big.Int, uint32) CalculateBonus(ic *interop.Context, acc util.Uint160, endHeight uint32) (*big.Int, error) GetCommitteeMembers(d *dao.Simple) keys.PublicKeys ComputeNextBlockValidators(d *dao.Simple) keys.PublicKeys GetCandidates(d *dao.Simple) ([]state.Validator, error) // Methods required for proper cross-native communication. CheckCommittee(ic *interop.Context) bool RevokeVotes(ic *interop.Context, h util.Uint160) error } // IGAS is an interface required from native GasToken contract for // interaction with Blockchain and other native contracts. IGAS interface { interop.Contract BalanceOf(d *dao.Simple, acc util.Uint160) *big.Int // Methods required for proper cross-native communication. Burn(ic *interop.Context, h util.Uint160, amount *big.Int) Mint(ic *interop.Context, h util.Uint160, amount *big.Int, callOnPayment bool) } // IPolicy is an interface required from native PolicyContract contract for // interaction with Blockchain and other native contracts. IPolicy interface { interop.Contract // GetStoragePriceInternal returns the current storage price in picoGAS units. GetStoragePriceInternal(d *dao.Simple) int64 GetMaxVerificationGas(d *dao.Simple) int64 // GetExecFeeFactorInternal returns the current execution fee factor in picoGAS units. GetExecFeeFactorInternal(d *dao.Simple) int64 GetMaxTraceableBlocksInternal(d *dao.Simple) uint32 GetMillisecondsPerBlockInternal(d *dao.Simple) uint32 GetMaxValidUntilBlockIncrementFromCache(d *dao.Simple) uint32 GetAttributeFeeInternal(d *dao.Simple, attrType transaction.AttrType) int64 CheckPolicy(d *dao.Simple, tx *transaction.Transaction) error GetFeePerByteInternal(d *dao.Simple) int64 // Methods required for proper cross-native communication. BlockAccountInternal(ic *interop.Context, hash util.Uint160) bool GetMaxValidUntilBlockIncrementInternal(ic *interop.Context) uint32 CleanWhitelist(ic *interop.Context, cs *state.Contract) error interop.PolicyChecker } // IOracle is an interface required from native OracleContract contract for // interaction with Blockchain and other native contracts. IOracle interface { interop.Contract GetOracleResponseScript() []byte GetRequests(d *dao.Simple) (map[uint64]*state.OracleRequest, error) GetScriptHash(d *dao.Simple) (util.Uint160, error) GetRequestInternal(d *dao.Simple, id uint64) (*state.OracleRequest, error) SetService(o OracleService) } // IDesignate is an interface required from native RoleManagement contract // for interaction with Blockchain and other native contracts. IDesignate interface { interop.Contract GetDesignatedByRole(d *dao.Simple, r noderoles.Role, index uint32) (keys.PublicKeys, uint32, error) GetLastDesignatedHash(d *dao.Simple, r noderoles.Role) (util.Uint160, error) SetOracleService(o OracleService) SetNotaryService(n NotaryService) SetStateRootService(s StateRootService) } // INotary is an interface required from native Notary contract for // interaction with Blockchain and other native contracts. INotary interface { interop.Contract BalanceOf(dao *dao.Simple, acc util.Uint160) *big.Int ExpirationOf(dao *dao.Simple, acc util.Uint160) uint32 GetMaxNotValidBeforeDelta(dao *dao.Simple) uint32 } // IVita is an interface required from native Vita contract // for interaction with Blockchain and other native contracts. IVita interface { interop.Contract GetTokenByOwner(d *dao.Simple, owner util.Uint160) (*state.Vita, error) GetTokenByIDPublic(d *dao.Simple, tokenID uint64) (*state.Vita, error) TokenExists(d *dao.Simple, owner util.Uint160) bool GetAttribute(d *dao.Simple, tokenID uint64, key string) (*state.Attribute, error) // IsAdultVerified checks if the owner has a verified "age_verified" attribute // indicating they are 18+ years old. Used for age-restricted purchases. IsAdultVerified(d *dao.Simple, owner util.Uint160) bool } // IRoleRegistry is an interface required from native RoleRegistry contract // for interaction with Blockchain and other native contracts. // RoleRegistry provides democratic governance for Tutus, replacing NEO.CheckCommittee(). IRoleRegistry interface { interop.Contract // CheckCommittee returns true if caller has COMMITTEE role. // This replaces NEO.CheckCommittee() for Tutus democratic governance. CheckCommittee(ic *interop.Context) bool // HasRoleInternal checks if address has role (includes hierarchy). HasRoleInternal(d *dao.Simple, address util.Uint160, roleID uint64, blockHeight uint32) bool // HasPermissionInternal checks if address has permission via roles. HasPermissionInternal(d *dao.Simple, address util.Uint160, resource, action string, scope state.Scope, blockHeight uint32) bool } // IVTS is an interface required from native VTS contract for // interaction with Blockchain and other native contracts. // VTS is programmable money with spending restrictions and automatic tax accounting. IVTS interface { interop.Contract // BalanceOf returns total VTS balance (unrestricted + all restricted). BalanceOf(d *dao.Simple, acc util.Uint160) *big.Int // UnrestrictedBalanceOf returns only unrestricted VTS balance. UnrestrictedBalanceOf(d *dao.Simple, acc util.Uint160) *big.Int // Mint mints unrestricted VTS to the account. Mint(ic *interop.Context, to util.Uint160, amount *big.Int) // MintRestricted mints VTS with spending category restrictions. MintRestricted(ic *interop.Context, to util.Uint160, amount *big.Int, category uint8) // Burn burns unrestricted VTS from the account. Burn(ic *interop.Context, from util.Uint160, amount *big.Int) // IsVendor returns true if address is a registered active vendor. IsVendor(d *dao.Simple, addr util.Uint160) bool } // IFederation is an interface required from native Federation contract for // interaction with Blockchain and other native contracts. // Federation manages cross-chain Vita coordination and visiting fee governance. IFederation interface { interop.Contract // GetVisitingFeePercent returns the percentage of fees the host chain pays for visitors. GetVisitingFeePercent(d *dao.Simple) uint8 // IsVisitor checks if an address is a registered visitor from another chain. IsVisitor(d *dao.Simple, owner util.Uint160) bool // GetHomeChain returns the home chain ID for a visitor. GetHomeChain(d *dao.Simple, owner util.Uint160) uint32 // AddInterChainDebt adds to the inter-chain debt owed to a specific chain. AddInterChainDebt(d *dao.Simple, chainID uint32, amount *big.Int) // GetInterChainDebt returns the inter-chain debt owed to a specific chain. GetInterChainDebt(d *dao.Simple, chainID uint32) *big.Int // Address returns the contract's script hash. Address() util.Uint160 // HasAsylum checks if an address has asylum status (humanitarian override). HasAsylum(d *dao.Simple, owner util.Uint160) bool // IsNaturalizedCitizen checks if an address is a naturalized citizen (permanent immigration). IsNaturalizedCitizen(d *dao.Simple, owner util.Uint160) bool } // ITreasury is an interface required from native Treasury contract for // interaction with Blockchain and other native contracts. ITreasury interface { interop.Contract // Address returns the contract's script hash. Address() util.Uint160 // AddDeficit adds to the cumulative deficit tracking. AddDeficit(d *dao.Simple, amount *big.Int) // GetDeficit returns the current cumulative deficit. GetDeficit(d *dao.Simple) *big.Int } // ILex is an interface required from native Lex contract for // interaction with Blockchain and other native contracts. // Lex provides universal law registry and rights enforcement. ILex interface { interop.Contract // HasRightInternal checks if subject has a specific constitutional right. HasRightInternal(d *dao.Simple, subject util.Uint160, rightID uint64, blockHeight uint32) bool // IsRestrictedInternal checks if a subject's right is restricted. IsRestrictedInternal(d *dao.Simple, subject util.Uint160, rightID uint64, blockHeight uint32) bool // CheckPropertyRight checks if subject has property rights. CheckPropertyRight(d *dao.Simple, subject util.Uint160, blockHeight uint32) bool // CheckMovementRight checks if subject has movement rights. CheckMovementRight(d *dao.Simple, subject util.Uint160, blockHeight uint32) bool // CheckLibertyRight checks if subject has liberty rights. CheckLibertyRight(d *dao.Simple, subject util.Uint160, blockHeight uint32) bool // Address returns the contract's script hash. Address() util.Uint160 } ) // Contracts is a convenient wrapper around an arbitrary set of native contracts // providing common helper contract accessors. type Contracts struct { List []interop.Contract // persistScript is a vm script which executes "onPersist" method of every native contract. persistScript []byte // postPersistScript is a vm script which executes "postPersist" method of every native contract. postPersistScript []byte } // NewContracts initializes a wrapper around the provided set of native // contracts. func NewContracts(natives []interop.Contract) *Contracts { return &Contracts{ List: natives, } } // ByHash returns a native contract with the specified hash. func (cs *Contracts) ByHash(h util.Uint160) interop.Contract { for _, ctr := range cs.List { if ctr.Metadata().Hash.Equals(h) { return ctr } } return nil } // ByName returns a native contract with the specified name. func (cs *Contracts) ByName(name string) interop.Contract { name = strings.ToLower(name) for _, ctr := range cs.List { if strings.ToLower(ctr.Metadata().Name) == name { return ctr } } return nil } // GetPersistScript returns a VM script calling "onPersist" syscall for native contracts. func (cs *Contracts) GetPersistScript() []byte { if cs.persistScript != nil { return cs.persistScript } w := io.NewBufBinWriter() emit.Syscall(w.BinWriter, interopnames.SystemContractNativeOnPersist) cs.persistScript = w.Bytes() return cs.persistScript } // GetPostPersistScript returns a VM script calling "postPersist" syscall for native contracts. func (cs *Contracts) GetPostPersistScript() []byte { if cs.postPersistScript != nil { return cs.postPersistScript } w := io.NewBufBinWriter() emit.Syscall(w.BinWriter, interopnames.SystemContractNativePostPersist) cs.postPersistScript = w.Bytes() return cs.postPersistScript } // Management returns native IManagement implementation. It panics if there's no // contract with proper name in cs. func (cs *Contracts) Management() IManagement { return cs.ByName(nativenames.Management).(IManagement) } // NEO returns native INEO contract implementation. It panics if there's no // contract with proper name in cs. func (cs *Contracts) NEO() INEO { return cs.ByName(nativenames.Neo).(INEO) } // GAS returns native IGAS contract implementation. It panics if there's no // contract with proper name in cs. func (cs *Contracts) GAS() IGAS { return cs.ByName(nativenames.Gas).(IGAS) } // Designate returns native IDesignate contract implementation. It panics if // there's no contract with proper name in cs. func (cs *Contracts) Designate() IDesignate { return cs.ByName(nativenames.Designation).(IDesignate) } // Policy returns native IPolicy contract implementation. It panics if there's // no contract with proper name in cs. func (cs *Contracts) Policy() IPolicy { return cs.ByName(nativenames.Policy).(IPolicy) } // Oracle returns native IOracle contract implementation. It returns nil if // there's no contract with proper name in cs. func (cs *Contracts) Oracle() IOracle { res := cs.ByName(nativenames.Oracle) // Oracle contract is optional. if res != nil { return res.(IOracle) } return nil } // Notary returns native INotary contract implementation. It returns nil if // there's no contract with proper name in cs. func (cs *Contracts) Notary() INotary { res := cs.ByName(nativenames.Notary) // Notary contract is optional. if res != nil { return res.(INotary) } return nil } // Vita returns native IVita contract implementation. It panics if // there's no contract with proper name in cs. func (cs *Contracts) Vita() IVita { return cs.ByName(nativenames.Vita).(IVita) } // RoleRegistry returns native IRoleRegistry contract implementation. It panics if // there's no contract with proper name in cs. func (cs *Contracts) RoleRegistry() IRoleRegistry { return cs.ByName(nativenames.RoleRegistry).(IRoleRegistry) } // VTS returns native IVTS contract implementation. It panics if // there's no contract with proper name in cs. func (cs *Contracts) VTS() IVTS { return cs.ByName(nativenames.VTS).(IVTS) } // Federation returns native IFederation contract implementation. It panics if // there's no contract with proper name in cs. func (cs *Contracts) Federation() IFederation { return cs.ByName(nativenames.Federation).(IFederation) } // Treasury returns native ITreasury contract implementation. It panics if // there's no contract with proper name in cs. func (cs *Contracts) Treasury() ITreasury { return cs.ByName(nativenames.Treasury).(ITreasury) } // Lex returns native ILex contract implementation. It panics if // there's no contract with proper name in cs. func (cs *Contracts) Lex() ILex { return cs.ByName(nativenames.Lex).(ILex) } // NewDefaultContracts returns a new set of default native contracts. func NewDefaultContracts(cfg config.ProtocolConfiguration) []interop.Contract { mgmt := NewManagement() s := newStd() c := newCrypto() ledger := NewLedger() gas := newGAS(int64(cfg.InitialGASSupply)) neo := newNEO(cfg) policy := newPolicy() neo.GAS = gas neo.Policy = policy gas.NEO = neo gas.Policy = policy mgmt.NEO = neo mgmt.Policy = policy policy.NEO = neo ledger.Policy = policy desig := NewDesignate(cfg.Genesis.Roles) desig.NEO = neo oracle := newOracle() oracle.GAS = gas oracle.NEO = neo oracle.Desig = desig notary := newNotary() notary.GAS = gas notary.NEO = neo notary.Desig = desig notary.Policy = policy treasury := newTreasury() treasury.NEO = neo vita := newVita() vita.NEO = neo // Parse TutusCommittee addresses from config var tutusCommittee []util.Uint160 for _, addrStr := range cfg.TutusCommittee { addr, err := util.Uint160DecodeStringLE(addrStr) if err != nil { // Try parsing as hex (BE format) addr, err = util.Uint160DecodeStringBE(addrStr) if err != nil { continue // Skip invalid addresses } } tutusCommittee = append(tutusCommittee, addr) } roleRegistry := newRoleRegistry(tutusCommittee) roleRegistry.NEO = neo // Set RoleRegistry on Vita for cross-contract integration vita.RoleRegistry = roleRegistry // Create VTS (Value Transfer System) contract vts := newVTS() vts.NEO = neo vts.RoleRegistry = roleRegistry vts.Vita = vita // Create Federation contract for cross-chain Vita coordination federation := newFederation() federation.NEO = neo // Create Lex (Law Registry) contract for universal rights and law enforcement lex := newLex() lex.NEO = neo lex.Vita = vita lex.RoleRegistry = roleRegistry lex.Federation = federation // Wire GAS dependencies for Vita fee exemption gas.Vita = vita gas.Federation = federation gas.Treasury = treasury return []interop.Contract{ mgmt, s, c, ledger, neo, gas, policy, desig, oracle, notary, treasury, vita, roleRegistry, vts, federation, lex, } }