github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/native/contract.go (about) 1 package native 2 3 import ( 4 "strings" 5 6 "github.com/nspcc-dev/neo-go/pkg/config" 7 "github.com/nspcc-dev/neo-go/pkg/core/interop" 8 "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames" 9 "github.com/nspcc-dev/neo-go/pkg/io" 10 "github.com/nspcc-dev/neo-go/pkg/util" 11 "github.com/nspcc-dev/neo-go/pkg/vm/emit" 12 ) 13 14 // Contracts is a set of registered native contracts. 15 type Contracts struct { 16 Management *Management 17 Ledger *Ledger 18 NEO *NEO 19 GAS *GAS 20 Policy *Policy 21 Oracle *Oracle 22 Designate *Designate 23 Notary *Notary 24 Crypto *Crypto 25 Std *Std 26 Contracts []interop.Contract 27 // persistScript is a vm script which executes "onPersist" method of every native contract. 28 persistScript []byte 29 // postPersistScript is a vm script which executes "postPersist" method of every native contract. 30 postPersistScript []byte 31 } 32 33 // ByHash returns a native contract with the specified hash. 34 func (cs *Contracts) ByHash(h util.Uint160) interop.Contract { 35 for _, ctr := range cs.Contracts { 36 if ctr.Metadata().Hash.Equals(h) { 37 return ctr 38 } 39 } 40 return nil 41 } 42 43 // ByName returns a native contract with the specified name. 44 func (cs *Contracts) ByName(name string) interop.Contract { 45 name = strings.ToLower(name) 46 for _, ctr := range cs.Contracts { 47 if strings.ToLower(ctr.Metadata().Name) == name { 48 return ctr 49 } 50 } 51 return nil 52 } 53 54 // NewContracts returns a new set of native contracts with new GAS, NEO, Policy, Oracle, 55 // Designate and (optional) Notary contracts. 56 func NewContracts(cfg config.ProtocolConfiguration) *Contracts { 57 cs := new(Contracts) 58 59 mgmt := newManagement() 60 cs.Management = mgmt 61 cs.Contracts = append(cs.Contracts, mgmt) 62 63 s := newStd() 64 cs.Std = s 65 cs.Contracts = append(cs.Contracts, s) 66 67 c := newCrypto() 68 cs.Crypto = c 69 cs.Contracts = append(cs.Contracts, c) 70 71 ledger := newLedger() 72 cs.Ledger = ledger 73 cs.Contracts = append(cs.Contracts, ledger) 74 75 gas := newGAS(int64(cfg.InitialGASSupply), cfg.P2PSigExtensions) 76 neo := newNEO(cfg) 77 policy := newPolicy(cfg.P2PSigExtensions) 78 neo.GAS = gas 79 neo.Policy = policy 80 gas.NEO = neo 81 gas.Policy = policy 82 mgmt.NEO = neo 83 mgmt.Policy = policy 84 policy.NEO = neo 85 86 cs.GAS = gas 87 cs.NEO = neo 88 cs.Policy = policy 89 cs.Contracts = append(cs.Contracts, neo, gas, policy) 90 91 desig := newDesignate(cfg.P2PSigExtensions, cfg.Genesis.Roles) 92 desig.NEO = neo 93 cs.Designate = desig 94 cs.Contracts = append(cs.Contracts, desig) 95 96 oracle := newOracle() 97 oracle.GAS = gas 98 oracle.NEO = neo 99 oracle.Desig = desig 100 cs.Oracle = oracle 101 cs.Contracts = append(cs.Contracts, oracle) 102 103 if cfg.P2PSigExtensions { 104 notary := newNotary() 105 notary.GAS = gas 106 notary.NEO = neo 107 notary.Desig = desig 108 notary.Policy = policy 109 cs.Notary = notary 110 cs.Contracts = append(cs.Contracts, notary) 111 } 112 113 return cs 114 } 115 116 // GetPersistScript returns a VM script calling "onPersist" syscall for native contracts. 117 func (cs *Contracts) GetPersistScript() []byte { 118 if cs.persistScript != nil { 119 return cs.persistScript 120 } 121 w := io.NewBufBinWriter() 122 emit.Syscall(w.BinWriter, interopnames.SystemContractNativeOnPersist) 123 cs.persistScript = w.Bytes() 124 return cs.persistScript 125 } 126 127 // GetPostPersistScript returns a VM script calling "postPersist" syscall for native contracts. 128 func (cs *Contracts) GetPostPersistScript() []byte { 129 if cs.postPersistScript != nil { 130 return cs.postPersistScript 131 } 132 w := io.NewBufBinWriter() 133 emit.Syscall(w.BinWriter, interopnames.SystemContractNativePostPersist) 134 cs.postPersistScript = w.Bytes() 135 return cs.postPersistScript 136 }