tutus-chain/pkg/core/native/contract.go

685 lines
24 KiB
Go

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
// GetTotalTokenCount returns total number of Vita tokens (for quorum calculation).
GetTotalTokenCount(d *dao.Simple) uint64
}
// 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
// RatifyAmendmentInternal is called by Eligere when a law amendment passes.
RatifyAmendmentInternal(ic *interop.Context, proposalID uint64, contentHash util.Uint256, category state.LawCategory, jurisdiction uint32) uint64
}
// IEligere is an interface required from native Eligere contract for
// interaction with Blockchain and other native contracts.
// Eligere provides democratic voting infrastructure.
IEligere interface {
interop.Contract
// GetProposalInternal returns a proposal by ID.
GetProposalInternal(d *dao.Simple, proposalID uint64) *state.Proposal
// Address returns the contract's script hash.
Address() util.Uint160
}
// IScire is an interface required from native Scire contract for
// interaction with Blockchain and other native contracts.
// Scire provides universal education infrastructure.
IScire interface {
interop.Contract
// GetAccountByOwner returns an education account by owner address.
GetAccountByOwner(d *dao.Simple, owner util.Uint160) (*state.EducationAccount, error)
// HasValidCertification checks if owner has a valid certification of the given type.
HasValidCertification(d *dao.Simple, owner util.Uint160, certType string, blockHeight uint32) bool
// Address returns the contract's script hash.
Address() util.Uint160
}
// ISalus is an interface required from native Salus contract for
// interaction with Blockchain and other native contracts.
// Salus provides universal healthcare infrastructure.
ISalus interface {
interop.Contract
// GetAccountByOwner returns a healthcare account by owner address.
GetAccountByOwner(d *dao.Simple, owner util.Uint160) (*state.HealthcareAccount, error)
// HasValidAuthorization checks if provider has valid authorization for patient.
HasValidAuthorization(d *dao.Simple, patient util.Uint160, provider util.Uint160, blockHeight uint32) bool
// Address returns the contract's script hash.
Address() util.Uint160
}
// ISese is an interface required from native Sese contract for
// interaction with Blockchain and other native contracts.
// Sese provides life planning infrastructure.
ISese interface {
interop.Contract
// GetAccountByOwner returns a life plan account by owner address.
GetAccountByOwner(d *dao.Simple, owner util.Uint160) (*state.LifePlanAccount, error)
// HasActiveCareer checks if owner has an active career.
HasActiveCareer(d *dao.Simple, owner util.Uint160) bool
// Address returns the contract's script hash.
Address() util.Uint160
}
// ITribute is an interface required from native Tribute contract for
// interaction with Blockchain and other native contracts.
// Tribute provides anti-hoarding economics with velocity tracking.
ITribute interface {
interop.Contract
// GetAccountByOwner returns a velocity account by owner address.
GetAccountByOwner(d *dao.Simple, owner util.Uint160) (*state.VelocityAccount, error)
// GetVelocity returns the current velocity score for an owner.
GetVelocity(d *dao.Simple, owner util.Uint160) uint64
// IsHoarding returns true if owner is hoarding resources.
IsHoarding(d *dao.Simple, owner util.Uint160) bool
// Address returns the contract's script hash.
Address() util.Uint160
}
// IOpus provides AI workforce integration and management.
IOpus interface {
interop.Contract
// GetWorkerByID returns an AI worker by ID.
GetWorkerByID(d *dao.Simple, workerID uint64) (*state.AIWorker, error)
// GetOperatorByOwner returns an operator profile by owner address.
GetOperatorByOwner(d *dao.Simple, owner util.Uint160) (*state.OperatorProfile, error)
// IsWorkerActive returns true if the AI worker is active.
IsWorkerActive(d *dao.Simple, workerID uint64) bool
// Address returns the contract's script hash.
Address() util.Uint160
}
// IPalam provides programmed transparency with role-based encrypted payloads.
IPalam interface {
interop.Contract
// GetFlowInternal returns a flow by ID.
GetFlowInternal(d *dao.Simple, flowID util.Uint256) *state.Flow
// HasDeclassifyGrant checks if requester has declassify grant for a flow.
HasDeclassifyGrant(d *dao.Simple, flowID util.Uint256, requester util.Uint160) 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)
}
// Eligere returns native IEligere contract implementation. It panics if
// there's no contract with proper name in cs.
func (cs *Contracts) Eligere() IEligere {
return cs.ByName(nativenames.Eligere).(IEligere)
}
// Scire returns native IScire contract implementation. It panics if
// there's no contract with proper name in cs.
func (cs *Contracts) Scire() IScire {
return cs.ByName(nativenames.Scire).(IScire)
}
// Salus returns native ISalus contract implementation. It panics if
// there's no contract with proper name in cs.
func (cs *Contracts) Salus() ISalus {
return cs.ByName(nativenames.Salus).(ISalus)
}
// Sese returns native ISese contract implementation. It panics if
// there's no contract with proper name in cs.
func (cs *Contracts) Sese() ISese {
return cs.ByName(nativenames.Sese).(ISese)
}
// Tribute returns native ITribute contract implementation. It panics if
// there's no contract with proper name in cs.
func (cs *Contracts) Tribute() ITribute {
return cs.ByName(nativenames.Tribute).(ITribute)
}
// Opus returns native IOpus contract implementation. It panics if
// there's no contract with proper name in cs.
func (cs *Contracts) Opus() IOpus {
return cs.ByName(nativenames.Opus).(IOpus)
}
// Palam returns native IPalam contract implementation. It panics if
// there's no contract with proper name in cs.
func (cs *Contracts) Palam() IPalam {
return cs.ByName(nativenames.Palam).(IPalam)
}
// 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 Lex into VTS for property rights enforcement
vts.Lex = lex
// Wire Lex into Vita for liberty rights enforcement (due process)
vita.Lex = lex
// Wire GAS dependencies for Vita fee exemption
gas.Vita = vita
gas.Federation = federation
gas.Treasury = treasury
// Create Eligere (Democratic Voting) contract
eligere := newEligere()
eligere.NEO = neo
eligere.Vita = vita
eligere.RoleRegistry = roleRegistry
eligere.Lex = lex
// Create Scire (Universal Education) contract
scire := newScire()
scire.NEO = neo
scire.Vita = vita
scire.RoleRegistry = roleRegistry
scire.Lex = lex
// Create Salus (Universal Healthcare) contract
salus := newSalus()
salus.NEO = neo
salus.Vita = vita
salus.RoleRegistry = roleRegistry
salus.Lex = lex
// Create Sese (Life Planning) contract
sese := newSese()
sese.NEO = neo
sese.Vita = vita
sese.RoleRegistry = roleRegistry
sese.Lex = lex
// Create Tribute (Anti-Hoarding Economics) contract
tribute := newTribute()
tribute.NEO = neo
tribute.Vita = vita
tribute.VTS = vts
tribute.RoleRegistry = roleRegistry
tribute.Lex = lex
// Create Opus (AI Workforce Integration) contract
opus := newOpus()
opus.NEO = neo
opus.Vita = vita
opus.VTS = vts
opus.RoleRegistry = roleRegistry
opus.Lex = lex
opus.Treasury = treasury
// Create Palam (Programmed Transparency) contract
palam := NewPalam()
palam.NEO = neo
palam.Vita = vita
palam.RoleRegistry = roleRegistry
palam.Lex = lex
// Create Pons (Inter-Government Bridge) contract
pons := newPons()
pons.NEO = neo
pons.Vita = vita
pons.Federation = federation
pons.RoleRegistry = roleRegistry
pons.VTS = vts
pons.Scire = scire
pons.Salus = salus
// Create Collocatio (Democratic Investment) contract
collocatio := newCollocatio()
collocatio.NEO = neo
collocatio.Vita = vita
collocatio.RoleRegistry = roleRegistry
collocatio.VTS = vts
collocatio.Scire = scire
collocatio.Eligere = eligere
collocatio.Tribute = tribute
return []interop.Contract{
mgmt,
s,
c,
ledger,
neo,
gas,
policy,
desig,
oracle,
notary,
treasury,
vita,
roleRegistry,
vts,
federation,
lex,
eligere,
scire,
salus,
sese,
tribute,
opus,
palam,
pons,
collocatio,
}
}