neo-go/pkg/core/native/contract.go

147 lines
3.8 KiB
Go
Raw Normal View History

2020-03-19 15:52:37 +00:00
package native
import (
"strings"
"github.com/nspcc-dev/neo-go/pkg/config"
2020-03-19 15:52:37 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/io"
2020-03-19 15:52:37 +00:00
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
2020-03-19 15:52:37 +00:00
)
2020-11-19 10:00:46 +00:00
// reservedContractID represents the upper bound of the reserved IDs for native contracts.
const reservedContractID = -100
2020-03-19 15:52:37 +00:00
// Contracts is a set of registered native contracts.
type Contracts struct {
2021-05-17 09:38:01 +00:00
Management *Management
Ledger *Ledger
NEO *NEO
GAS *GAS
Policy *Policy
Oracle *Oracle
Designate *Designate
Notary *Notary
Crypto *Crypto
Std *Std
Contracts []interop.Contract
// persistScript is vm script which executes "onPersist" method of every native contract.
persistScript []byte
// postPersistScript is vm script which executes "postPersist" method of every native contract.
postPersistScript []byte
2020-03-19 15:52:37 +00:00
}
// ByHash returns native contract with the specified hash.
func (cs *Contracts) ByHash(h util.Uint160) interop.Contract {
2020-03-19 15:52:37 +00:00
for _, ctr := range cs.Contracts {
if ctr.Metadata().Hash.Equals(h) {
return ctr
}
}
return nil
}
// ByName returns native contract with the specified name.
func (cs *Contracts) ByName(name string) interop.Contract {
name = strings.ToLower(name)
for _, ctr := range cs.Contracts {
if strings.ToLower(ctr.Metadata().Name) == name {
return ctr
}
}
return nil
}
2020-11-19 10:00:46 +00:00
// NewContracts returns new set of native contracts with new GAS, NEO, Policy, Oracle,
// Designate and (optional) Notary contracts.
func NewContracts(cfg config.ProtocolConfiguration) *Contracts {
cs := new(Contracts)
mgmt := newManagement()
cs.Management = mgmt
cs.Contracts = append(cs.Contracts, mgmt)
2021-03-03 15:59:10 +00:00
s := newStd()
cs.Std = s
cs.Contracts = append(cs.Contracts, s)
2021-02-15 15:43:10 +00:00
c := newCrypto()
cs.Crypto = c
cs.Contracts = append(cs.Contracts, c)
ledger := newLedger()
cs.Ledger = ledger
cs.Contracts = append(cs.Contracts, ledger)
gas := newGAS(int64(cfg.InitialGASSupply), cfg.P2PSigExtensions)
neo := newNEO()
neo.GAS = gas
gas.NEO = neo
2021-01-21 12:05:15 +00:00
mgmt.NEO = neo
cs.GAS = gas
cs.NEO = neo
cs.Contracts = append(cs.Contracts, neo)
cs.Contracts = append(cs.Contracts, gas)
policy := newPolicy()
2021-01-21 12:05:15 +00:00
policy.NEO = neo
cs.Policy = policy
cs.Contracts = append(cs.Contracts, policy)
desig := newDesignate(cfg.P2PSigExtensions)
desig.NEO = neo
cs.Designate = desig
cs.Contracts = append(cs.Contracts, desig)
oracle := newOracle()
oracle.GAS = gas
oracle.NEO = neo
oracle.Desig = desig
cs.Oracle = oracle
cs.Contracts = append(cs.Contracts, oracle)
2020-10-01 15:17:09 +00:00
if cfg.P2PSigExtensions {
2020-11-19 10:00:46 +00:00
notary := newNotary()
notary.GAS = gas
2021-01-21 12:05:15 +00:00
notary.NEO = neo
2020-11-19 10:00:46 +00:00
notary.Desig = desig
cs.Notary = notary
cs.Contracts = append(cs.Contracts, notary)
}
setDefaultHistory := len(cfg.NativeUpdateHistories) == 0
2021-03-11 11:39:51 +00:00
for _, c := range cs.Contracts {
var history = []uint32{0}
if !setDefaultHistory {
history = cfg.NativeUpdateHistories[c.Metadata().Name]
2021-03-11 11:39:51 +00:00
}
c.Metadata().NativeContract.UpdateHistory = history
2021-03-11 11:39:51 +00:00
}
return cs
}
// GetPersistScript returns 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
2020-03-19 15:52:37 +00:00
}
// GetPostPersistScript returns 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
}