2020-03-19 15:52:37 +00:00
|
|
|
package native
|
|
|
|
|
|
|
|
import (
|
2020-09-25 09:40:57 +00:00
|
|
|
"strings"
|
2020-09-23 08:48:31 +00:00
|
|
|
|
2021-07-20 12:54:56 +00:00
|
|
|
"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"
|
2020-12-13 18:36:06 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
2020-06-17 10:57:54 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
2020-03-19 15:52:37 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
2020-06-17 10:57:54 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
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
|
2022-04-20 18:30:09 +00:00
|
|
|
// persistScript is a vm script which executes "onPersist" method of every native contract.
|
2020-06-17 10:57:54 +00:00
|
|
|
persistScript []byte
|
2022-04-20 18:30:09 +00:00
|
|
|
// postPersistScript is a vm script which executes "postPersist" method of every native contract.
|
2020-09-23 08:48:31 +00:00
|
|
|
postPersistScript []byte
|
2020-03-19 15:52:37 +00:00
|
|
|
}
|
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
// ByHash returns a native contract with the specified hash.
|
2020-04-22 20:00:18 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
// ByName returns a native contract with the specified name.
|
2020-09-25 09:40:57 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
// NewContracts returns a new set of native contracts with new GAS, NEO, Policy, Oracle,
|
2020-11-19 10:00:46 +00:00
|
|
|
// Designate and (optional) Notary contracts.
|
2021-07-20 12:54:56 +00:00
|
|
|
func NewContracts(cfg config.ProtocolConfiguration) *Contracts {
|
2020-04-22 20:00:18 +00:00
|
|
|
cs := new(Contracts)
|
|
|
|
|
2020-12-08 15:28:00 +00:00
|
|
|
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)
|
|
|
|
|
2021-02-03 19:01:20 +00:00
|
|
|
ledger := newLedger()
|
|
|
|
cs.Ledger = ledger
|
|
|
|
cs.Contracts = append(cs.Contracts, ledger)
|
|
|
|
|
2021-12-13 15:16:27 +00:00
|
|
|
gas := newGAS(int64(cfg.InitialGASSupply), cfg.P2PSigExtensions)
|
2022-04-13 13:09:39 +00:00
|
|
|
neo := newNEO(cfg)
|
2023-09-21 15:22:32 +00:00
|
|
|
policy := newPolicy(cfg.P2PSigExtensions)
|
2020-04-22 20:00:18 +00:00
|
|
|
neo.GAS = gas
|
2022-04-27 19:58:52 +00:00
|
|
|
neo.Policy = policy
|
2020-04-22 20:00:18 +00:00
|
|
|
gas.NEO = neo
|
2023-09-21 15:22:32 +00:00
|
|
|
gas.Policy = policy
|
2021-01-21 12:05:15 +00:00
|
|
|
mgmt.NEO = neo
|
2022-05-04 10:27:41 +00:00
|
|
|
mgmt.Policy = policy
|
2022-04-27 19:58:52 +00:00
|
|
|
policy.NEO = neo
|
2020-04-22 20:00:18 +00:00
|
|
|
|
|
|
|
cs.GAS = gas
|
|
|
|
cs.NEO = neo
|
2020-06-15 18:13:32 +00:00
|
|
|
cs.Policy = policy
|
2022-04-27 19:58:52 +00:00
|
|
|
cs.Contracts = append(cs.Contracts, neo, gas, policy)
|
2020-09-18 13:26:36 +00:00
|
|
|
|
2023-10-18 21:52:29 +00:00
|
|
|
desig := newDesignate(cfg.P2PSigExtensions, cfg.Genesis.Roles)
|
2021-01-12 18:27:42 +00:00
|
|
|
desig.NEO = neo
|
|
|
|
cs.Designate = desig
|
|
|
|
cs.Contracts = append(cs.Contracts, desig)
|
|
|
|
|
2020-09-18 13:26:36 +00:00
|
|
|
oracle := newOracle()
|
|
|
|
oracle.GAS = gas
|
|
|
|
oracle.NEO = neo
|
2021-01-12 18:27:42 +00:00
|
|
|
oracle.Desig = desig
|
2020-09-18 13:26:36 +00:00
|
|
|
cs.Oracle = oracle
|
|
|
|
cs.Contracts = append(cs.Contracts, oracle)
|
2020-10-01 15:17:09 +00:00
|
|
|
|
2021-07-20 12:54:56 +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
|
2023-09-21 15:22:32 +00:00
|
|
|
notary.Policy = policy
|
2020-11-19 10:00:46 +00:00
|
|
|
cs.Notary = notary
|
|
|
|
cs.Contracts = append(cs.Contracts, notary)
|
|
|
|
}
|
|
|
|
|
2021-07-20 12:54:56 +00:00
|
|
|
setDefaultHistory := len(cfg.NativeUpdateHistories) == 0
|
2021-03-11 11:39:51 +00:00
|
|
|
for _, c := range cs.Contracts {
|
2021-07-20 12:54:56 +00:00
|
|
|
var history = []uint32{0}
|
|
|
|
if !setDefaultHistory {
|
|
|
|
history = cfg.NativeUpdateHistories[c.Metadata().Name]
|
2021-03-11 11:39:51 +00:00
|
|
|
}
|
2021-07-20 12:54:56 +00:00
|
|
|
c.Metadata().NativeContract.UpdateHistory = history
|
2021-03-11 11:39:51 +00:00
|
|
|
}
|
2020-04-22 20:00:18 +00:00
|
|
|
return cs
|
2020-06-17 10:57:54 +00:00
|
|
|
}
|
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
// GetPersistScript returns a VM script calling "onPersist" syscall for native contracts.
|
2020-06-17 10:57:54 +00:00
|
|
|
func (cs *Contracts) GetPersistScript() []byte {
|
|
|
|
if cs.persistScript != nil {
|
|
|
|
return cs.persistScript
|
|
|
|
}
|
|
|
|
w := io.NewBufBinWriter()
|
2020-12-13 18:36:06 +00:00
|
|
|
emit.Syscall(w.BinWriter, interopnames.SystemContractNativeOnPersist)
|
2020-06-17 10:57:54 +00:00
|
|
|
cs.persistScript = w.Bytes()
|
|
|
|
return cs.persistScript
|
2020-03-19 15:52:37 +00:00
|
|
|
}
|
2020-09-23 08:48:31 +00:00
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
// GetPostPersistScript returns a VM script calling "postPersist" syscall for native contracts.
|
2020-09-23 08:48:31 +00:00
|
|
|
func (cs *Contracts) GetPostPersistScript() []byte {
|
|
|
|
if cs.postPersistScript != nil {
|
|
|
|
return cs.postPersistScript
|
|
|
|
}
|
|
|
|
w := io.NewBufBinWriter()
|
2020-12-13 18:36:06 +00:00
|
|
|
emit.Syscall(w.BinWriter, interopnames.SystemContractNativePostPersist)
|
2020-09-23 08:48:31 +00:00
|
|
|
cs.postPersistScript = w.Bytes()
|
|
|
|
return cs.postPersistScript
|
|
|
|
}
|