OSDN Git Service

try to fix ban peer bug (#273)
[bytom/vapor.git] / api / compile.go
1 package api
2
3 import (
4         "strings"
5
6         chainjson "github.com/vapor/encoding/json"
7         "github.com/vapor/equity/compiler"
8         "github.com/vapor/errors"
9         "github.com/vapor/protocol/vm"
10 )
11
12 // pre-define contract error types
13 var (
14         ErrCompileContract = errors.New("compile contract failed")
15         ErrInstContract    = errors.New("instantiate contract failed")
16 )
17
18 type (
19         compileReq struct {
20                 Contract string                 `json:"contract"`
21                 Args     []compiler.ContractArg `json:"args"`
22         }
23
24         compileResp struct {
25                 Name    string             `json:"name"`
26                 Source  string             `json:"source"`
27                 Program chainjson.HexBytes `json:"program"`
28                 Params  []*compiler.Param  `json:"params"`
29                 Value   string             `json:"value"`
30                 Clauses []*compiler.Clause `json:"clause_info"`
31                 Opcodes string             `json:"opcodes"`
32                 Error   string             `json:"error"`
33         }
34 )
35
36 func compileEquity(req compileReq) (*compileResp, error) {
37         compiled, err := compiler.Compile(strings.NewReader(req.Contract))
38         if err != nil {
39                 return nil, errors.WithDetail(ErrCompileContract, err.Error())
40         }
41
42         // if source contract maybe contain import statement, multiple contract objects will be generated
43         // after the compilation, and the last object is what we need.
44         contract := compiled[len(compiled)-1]
45         resp := &compileResp{
46                 Name:    contract.Name,
47                 Source:  req.Contract,
48                 Program: contract.Body,
49                 Value:   contract.Value.Amount + " of " + contract.Value.Asset,
50                 Clauses: contract.Clauses,
51                 Opcodes: contract.Opcodes,
52         }
53
54         if req.Args != nil {
55                 resp.Program, err = compiler.Instantiate(contract.Body, contract.Params, contract.Recursive, req.Args)
56                 if err != nil {
57                         return nil, errors.WithDetail(ErrInstContract, err.Error())
58                 }
59
60                 resp.Opcodes, err = vm.Disassemble(resp.Program)
61                 if err != nil {
62                         return nil, err
63                 }
64         }
65
66         for _, param := range contract.Params {
67                 if param.InferredType != "" {
68                         param.Type = param.InferredType
69                         param.InferredType = ""
70                 }
71                 resp.Params = append(resp.Params, param)
72         }
73
74         return resp, nil
75 }
76
77 func (a *API) compileEquity(req compileReq) Response {
78         resp, err := compileEquity(req)
79         if err != nil {
80                 return NewErrorResponse(err)
81         }
82         return NewSuccessResponse(&resp)
83 }