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  }