chainjson "github.com/bytom/encoding/json"
"github.com/bytom/equity/compiler"
+ "github.com/bytom/errors"
"github.com/bytom/protocol/vm"
)
+// pre-define contract error types
+var (
+ ErrCompileContract = errors.New("compile contract failed")
+ ErrInstContract = errors.New("instantiate contract failed")
+)
+
type (
compileReq struct {
Contract string `json:"contract"`
}
)
-func compileEquity(req compileReq) (compileResp, error) {
- var resp compileResp
+func compileEquity(req compileReq) (*compileResp, error) {
compiled, err := compiler.Compile(strings.NewReader(req.Contract))
if err != nil {
- resp.Error = err.Error()
+ return nil, errors.WithDetail(ErrCompileContract, err.Error())
}
// if source contract maybe contain import statement, multiple contract objects will be generated
// after the compilation, and the last object is what we need.
contract := compiled[len(compiled)-1]
- resp = compileResp{
+ resp := &compileResp{
Name: contract.Name,
Source: req.Contract,
Program: contract.Body,
if req.Args != nil {
resp.Program, err = compiler.Instantiate(contract.Body, contract.Params, contract.Recursive, req.Args)
if err != nil {
- resp.Error = err.Error()
+ return nil, errors.WithDetail(ErrInstContract, err.Error())
}
resp.Opcodes, err = vm.Disassemble(resp.Program)
if err != nil {
- return resp, err
+ return nil, err
}
}
if err != nil {
return NewErrorResponse(err)
}
- return NewSuccessResponse(resp)
+ return NewSuccessResponse(&resp)
}
signers.ErrNoXPubs: {400, "BTM202", "At least one xpub is required"},
signers.ErrDupeXPub: {400, "BTM203", "Root XPubs cannot contain the same key more than once"},
+ // Contract error namespace (3xx)
+ ErrCompileContract: {400, "BTM300", "Compile contract failed"},
+ ErrInstContract: {400, "BTM301", "Instantiate contract failed"},
+
// Transaction error namespace (7xx)
// Build transaction error namespace (70x ~ 72x)
account.ErrInsufficient: {400, "BTM700", "Funds of account are insufficient"},
func parseContracts(p *parser) []*Contract {
var result []*Contract
+ if pos := scanKeyword(p.buf, p.pos, "contract"); pos < 0 {
+ p.errorf("expected contract")
+ }
+
for peekKeyword(p) == "contract" {
contract := parseContract(p)
result = append(result, contract)