Optimisations and API changes for smart contracts (#67)

* support VM to pass method and arguments to a script.

* added support for type assertions in smartcontracts.

* added native vm support for print.

* moved VM API packages to vm -> API

* reverted the native Print opcode in favor of runtime.Log

* added support for registering custom interop hooks in the VM.

* Updated README

* Updated compiler with @OPTIMIZE tags

* Moved more tests to VM package.

* optimized and refactored compiler and vm API

* updated README with new smartcontract apis

* bumped version
This commit is contained in:
Anthony De Meulemeester 2018-04-10 11:45:31 +02:00 committed by GitHub
parent b2021c126e
commit 4bd5b2812e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 655 additions and 494 deletions

View file

@ -4,6 +4,7 @@ import (
"bufio"
"bytes"
"encoding/hex"
"errors"
"fmt"
"io/ioutil"
"os"
@ -51,7 +52,7 @@ type VMCLI struct {
// New returns a new VMCLI object.
func New() *VMCLI {
return &VMCLI{
vm: vm.New(nil, 0),
vm: vm.New(0),
}
}
@ -61,7 +62,7 @@ func (c *VMCLI) handleCommand(cmd string, args ...string) {
fmt.Printf("unknown command (%s)\n", cmd)
return
}
if len(args) < com.args {
if (len(args) < com.args || len(args) > com.args) && cmd != "run" {
fmt.Printf("command (%s) takes at least %d arguments\n", cmd, com.args)
return
}
@ -125,7 +126,31 @@ func (c *VMCLI) handleCommand(cmd string, args ...string) {
c.vm.Load(b)
fmt.Printf("READY: loaded %d instructions\n", c.vm.Context().LenInstr())
case "run", "cont":
case "run":
var (
method []byte
params []vm.StackItem
err error
start int
)
if len(args) == 0 {
c.vm.Run()
} else {
if isMethodArg(args[0]) {
method = []byte(args[0])
start = 1
}
params, err = parseArgs(args[start:])
if err != nil {
fmt.Println(err)
return
}
}
c.vm.LoadArgs(method, params)
c.vm.Run()
case "cont":
c.vm.Run()
case "step":
@ -172,6 +197,36 @@ func (c *VMCLI) Run() error {
}
}
func isMethodArg(s string) bool {
return len(strings.Split(s, ":")) == 1
}
func parseArgs(args []string) ([]vm.StackItem, error) {
items := make([]vm.StackItem, len(args))
for i, arg := range args {
typeAndVal := strings.Split(arg, ":")
if len(typeAndVal) < 2 {
return nil, errors.New("arguments need to be specified as <typ:val>")
}
typ := typeAndVal[0]
value := typeAndVal[1]
switch typ {
case "int":
val, err := strconv.Atoi(value)
if err != nil {
return nil, err
}
items[i] = vm.NewBigIntegerItem(val)
case "string":
items[i] = vm.NewByteArrayItem([]byte(value))
}
}
return items, nil
}
func printHelp() {
names := make([]string, len(commands))
i := 0