-
Notifications
You must be signed in to change notification settings - Fork 79
/
contract.go
143 lines (125 loc) · 3.64 KB
/
contract.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package native
import (
"strings"
"github.com/nspcc-dev/neo-go/pkg/config"
"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"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
)
// Contracts is a set of registered native contracts.
type Contracts struct {
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 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
}
// ByHash returns a native contract with the specified hash.
func (cs *Contracts) ByHash(h util.Uint160) interop.Contract {
for _, ctr := range cs.Contracts {
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.Contracts {
if strings.ToLower(ctr.Metadata().Name) == name {
return ctr
}
}
return nil
}
// NewContracts returns a 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)
s := newStd()
cs.Std = s
cs.Contracts = append(cs.Contracts, s)
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(cfg)
policy := newPolicy()
neo.GAS = gas
neo.Policy = policy
gas.NEO = neo
mgmt.NEO = neo
mgmt.Policy = policy
policy.NEO = neo
cs.GAS = gas
cs.NEO = neo
cs.Policy = policy
cs.Contracts = append(cs.Contracts, neo, gas, 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)
if cfg.P2PSigExtensions {
notary := newNotary()
notary.GAS = gas
notary.NEO = neo
notary.Desig = desig
cs.Notary = notary
gas.Notary = notary
cs.Contracts = append(cs.Contracts, notary)
}
setDefaultHistory := len(cfg.NativeUpdateHistories) == 0
for _, c := range cs.Contracts {
var history = []uint32{0}
if !setDefaultHistory {
history = cfg.NativeUpdateHistories[c.Metadata().Name]
}
c.Metadata().NativeContract.UpdateHistory = history
}
return cs
}
// 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
}