9 chainjson "github.com/bytom/encoding/json"
12 // Contract is a compiled Equity contract.
13 type Contract struct {
14 // Name is the contract name.
15 Name string `json:"name"`
17 // Params is the list of contract parameters.
18 Params []*Param `json:"params,omitempty"`
20 // Clauses is the list of contract clauses.
21 Clauses []*Clause `json:"clauses"`
23 // Value is the name of the value locked by the contract.
24 Value ValueInfo `json:"value"`
26 // Body is the optimized bytecode of the contract body. This is not
27 // a complete program! Use instantiate to turn this (plus some
28 // arguments) into a program.
29 Body chainjson.HexBytes `json:"body_bytecode"`
31 // Opcodes is the human-readable string of opcodes corresponding to
33 Opcodes string `json:"body_opcodes,omitempty"`
35 // Recursive tells whether this contract calls itself. (This is
36 // used to select between two possible instantiation options.)
37 Recursive bool `json:"recursive"`
39 // Pre-optimized list of instruction steps, with stack snapshots.
40 Steps []Step `json:"-"`
43 // Param is a contract or clause parameter.
45 // Name is the parameter name.
46 Name string `json:"name"`
48 // Type is the declared parameter type.
49 Type typeDesc `json:"type"`
51 // InferredType, if available, is a more-specific type than Type,
52 // inferred from the logic of the contract.
53 InferredType typeDesc `json:"inferred_type,omitempty"`
56 // Clause is a compiled contract clause.
58 // Name is the clause name.
59 Name string `json:"name"`
61 // Params is the list of clause parameters.
62 Params []*Param `json:"params,omitempty"`
64 statements []statement
66 // BlockHeight is the list of expressions passed to greater()/less() in this
68 BlockHeight []string `json:"blockheight,omitempty"`
70 // HashCalls is the list of hash functions and their arguments used
72 HashCalls []HashCall `json:"hash_calls,omitempty"`
74 // Values is the list of values unlocked or relocked in this clause.
75 Values []ValueInfo `json:"values"`
77 // Conditions is the list of condition for if-else statements which body contains
78 // the lock or unlock statement in this clause.
79 Conditions map[string]Condition `json:"conditions"`
81 // CondValues is the map of values unlocked or relocked in this clause's
82 // if-else statements which body contains the lock or unlock statement.
83 CondValues map[string][]ValueInfo `json:"cond_values"`
85 // Contracts is the list of contracts called by this clause.
86 Contracts []string `json:"contracts,omitempty"`
89 // ValueInfo describes how a blockchain value is used in a contract clause.
90 type ValueInfo struct {
91 // Name is the clause's name for this value.
92 Name string `json:"name"`
94 // Program is the program expression used to the lock the value, if
95 // the value is locked with "lock." If it's unlocked with "unlock"
96 // instead, this is empty.
97 Program string `json:"program,omitempty"`
99 // Asset is the expression describing the asset type the value must
100 // have, as it appears in a clause's "requires" section. If this is
101 // the contract value instead, this is empty.
102 Asset string `json:"asset,omitempty"`
104 // Amount is the expression describing the amount the value must
105 // have, as it appears in a clause's "requires" section. If this is
106 // the contract value instead, this is empty.
107 Amount string `json:"amount,omitempty"`
109 // Params is the list of parameters for amount expression. If the value
110 // of amount is a variable, this is empty.
111 Params []*Param `json:"params,omitempty"`
114 // HashCall describes a call to a hash function.
115 type HashCall struct {
116 // HashType is "sha3" or "sha256".
117 HashType string `json:"hash_type"`
119 // Arg is the expression passed to the hash function.
120 Arg string `json:"arg"`
122 // ArgType is the type of Arg.
123 ArgType string `json:"arg_type"`
126 // Condition describes a condition expression.
127 type Condition struct {
128 // Source is the string format of condition expression.
129 Source string `json:"source"`
131 // Params is the list of parameters for condition expression.
132 Params []*Param `json:"params,omitempty"`
135 // ContractArg is an argument with which to instantiate a contract as
136 // a program. Exactly one of B, I, and S should be supplied.
137 type ContractArg struct {
138 B *bool `json:"boolean,omitempty"`
139 I *int64 `json:"integer,omitempty"`
140 S *chainjson.HexBytes `json:"string,omitempty"`
143 type statement interface {
144 countVarRefs(map[string]int)
147 type defineStatement struct {
152 func (s defineStatement) countVarRefs(counts map[string]int) {
153 s.expr.countVarRefs(counts)
156 type assignStatement struct {
161 func (s assignStatement) countVarRefs(counts map[string]int) {
162 s.expr.countVarRefs(counts)
165 // IfStatmentBody describes the content of if-else structure
166 type IfStatmentBody struct {
167 // if body statements
170 // else body statements
171 falseBody []statement
174 type ifStatement struct {
179 func (s ifStatement) countVarRefs(counts map[string]int) {
180 s.condition.countVarRefs(counts)
183 type verifyStatement struct {
187 func (s verifyStatement) countVarRefs(counts map[string]int) {
188 s.expr.countVarRefs(counts)
191 type lockStatement struct {
192 lockedAmount expression
193 lockedAsset expression
196 // Added as a decoration, used by CHECKOUTPUT
200 func (s lockStatement) countVarRefs(counts map[string]int) {
201 s.lockedAmount.countVarRefs(counts)
202 s.lockedAsset.countVarRefs(counts)
203 s.program.countVarRefs(counts)
206 type unlockStatement struct {
207 unlockedAmount expression
208 unlockedAsset expression
211 func (s unlockStatement) countVarRefs(counts map[string]int) {
212 s.unlockedAmount.countVarRefs(counts)
213 s.unlockedAsset.countVarRefs(counts)
216 type expression interface {
218 typ(*environ) typeDesc
219 countVarRefs(map[string]int)
222 type binaryExpr struct {
223 left, right expression
227 func (e binaryExpr) String() string {
228 return fmt.Sprintf("(%s %s %s)", e.left, e.op.op, e.right)
231 func (e binaryExpr) typ(*environ) typeDesc {
235 func (e binaryExpr) countVarRefs(counts map[string]int) {
236 e.left.countVarRefs(counts)
237 e.right.countVarRefs(counts)
240 type unaryExpr struct {
245 func (e unaryExpr) String() string {
246 return fmt.Sprintf("%s%s", e.op.op, e.expr)
249 func (e unaryExpr) typ(*environ) typeDesc {
253 func (e unaryExpr) countVarRefs(counts map[string]int) {
254 e.expr.countVarRefs(counts)
257 type callExpr struct {
262 func (e callExpr) String() string {
264 for _, a := range e.args {
265 argStrs = append(argStrs, a.String())
267 return fmt.Sprintf("%s(%s)", e.fn, strings.Join(argStrs, ", "))
270 func (e callExpr) typ(env *environ) typeDesc {
271 if b := referencedBuiltin(e.fn); b != nil {
274 if len(e.args) == 1 {
275 switch e.args[0].typ(env) {
279 return sha3PubkeyType
284 if len(e.args) == 1 {
285 switch e.args[0].typ(env) {
289 return sha256PubkeyType
296 if e.fn.typ(env) == predType {
299 if e.fn.typ(env) == contractType {
305 func (e callExpr) countVarRefs(counts map[string]int) {
306 e.fn.countVarRefs(counts)
307 for _, a := range e.args {
308 a.countVarRefs(counts)
314 func (v varRef) String() string {
318 func (v varRef) typ(env *environ) typeDesc {
319 if entry := env.lookup(string(v)); entry != nil {
325 func (v varRef) countVarRefs(counts map[string]int) {
329 type bytesLiteral []byte
331 func (e bytesLiteral) String() string {
332 return "0x" + hex.EncodeToString([]byte(e))
335 func (bytesLiteral) typ(*environ) typeDesc {
339 func (bytesLiteral) countVarRefs(map[string]int) {}
341 type integerLiteral int64
343 func (e integerLiteral) String() string {
344 return strconv.FormatInt(int64(e), 10)
347 func (integerLiteral) typ(*environ) typeDesc {
351 func (integerLiteral) countVarRefs(map[string]int) {}
353 type booleanLiteral bool
355 func (e booleanLiteral) String() string {
362 func (booleanLiteral) typ(*environ) typeDesc {
366 func (booleanLiteral) countVarRefs(map[string]int) {}
368 type listExpr []expression
370 func (e listExpr) String() string {
372 for _, elt := range e {
373 elts = append(elts, elt.String())
375 return fmt.Sprintf("[%s]", strings.Join(elts, ", "))
378 func (listExpr) typ(*environ) typeDesc {
382 func (e listExpr) countVarRefs(counts map[string]int) {
383 for _, elt := range e {
384 elt.countVarRefs(counts)