aboutsummaryrefslogtreecommitdiffstats
path: root/vm.go
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-01-17 01:12:55 +0800
committerobscuren <geffobscura@gmail.com>2014-01-17 01:12:55 +0800
commit8c4eca2490fc19a488ffb5fe1160a2ae695d018f (patch)
tree2d912c02d1a8d1e403a88e92efd678180055f738 /vm.go
parent33004d704e4a77368e5b2b415cfee3f05a3b469f (diff)
downloaddexon-8c4eca2490fc19a488ffb5fe1160a2ae695d018f.tar
dexon-8c4eca2490fc19a488ffb5fe1160a2ae695d018f.tar.gz
dexon-8c4eca2490fc19a488ffb5fe1160a2ae695d018f.tar.bz2
dexon-8c4eca2490fc19a488ffb5fe1160a2ae695d018f.tar.lz
dexon-8c4eca2490fc19a488ffb5fe1160a2ae695d018f.tar.xz
dexon-8c4eca2490fc19a488ffb5fe1160a2ae695d018f.tar.zst
dexon-8c4eca2490fc19a488ffb5fe1160a2ae695d018f.zip
Moved the vm code the block manager and added more opcodes
Diffstat (limited to 'vm.go')
-rw-r--r--vm.go284
1 files changed, 0 insertions, 284 deletions
diff --git a/vm.go b/vm.go
deleted file mode 100644
index 96a3dfa05..000000000
--- a/vm.go
+++ /dev/null
@@ -1,284 +0,0 @@
-package main
-
-import (
- "fmt"
- "github.com/ethereum/ethutil-go"
- "math/big"
- "strconv"
-)
-
-// Op codes
-const (
- oSTOP int = 0x00
- oADD int = 0x01
- oMUL int = 0x02
- oSUB int = 0x03
- oDIV int = 0x04
- oSDIV int = 0x05
- oMOD int = 0x06
- oSMOD int = 0x07
- oEXP int = 0x08
- oNEG int = 0x09
- oLT int = 0x0a
- oLE int = 0x0b
- oGT int = 0x0c
- oGE int = 0x0d
- oEQ int = 0x0e
- oNOT int = 0x0f
- oMYADDRESS int = 0x10
- oTXSENDER int = 0x11
- oTXVALUE int = 0x12
- oTXFEE int = 0x13
- oTXDATAN int = 0x14
- oTXDATA int = 0x15
- oBLK_PREVHASH int = 0x16
- oBLK_COINBASE int = 0x17
- oBLK_TIMESTAMP int = 0x18
- oBLK_NUMBER int = 0x19
- oBLK_DIFFICULTY int = 0x1a
- oSHA256 int = 0x20
- oRIPEMD160 int = 0x21
- oECMUL int = 0x22
- oECADD int = 0x23
- oECSIGN int = 0x24
- oECRECOVER int = 0x25
- oECVALID int = 0x26
- oPUSH int = 0x30
- oPOP int = 0x31
- oDUP int = 0x32
- oDUPN int = 0x33
- oSWAP int = 0x34
- oSWAPN int = 0x35
- oLOAD int = 0x36
- oSTORE int = 0x37
- oJMP int = 0x40
- oJMPI int = 0x41
- oIND int = 0x42
- oEXTRO int = 0x50
- oBALANCE int = 0x51
- oMKTX int = 0x60
- oSUICIDE int = 0xff
-)
-
-type OpType int
-
-const (
- tNorm = iota
- tData
- tExtro
- tCrypto
-)
-
-type TxCallback func(opType OpType) bool
-
-// Simple push/pop stack mechanism
-type Stack struct {
- data []string
-}
-
-func NewStack() *Stack {
- return &Stack{}
-}
-func (st *Stack) Pop() string {
- s := len(st.data)
-
- str := st.data[s-1]
- st.data = st.data[:s-1]
-
- return str
-}
-
-func (st *Stack) Popn() (*big.Int, *big.Int) {
- s := len(st.data)
-
- strs := st.data[s-2:]
- st.data = st.data[:s-2]
-
- return ethutil.Big(strs[0]), ethutil.Big(strs[1])
-}
-
-func (st *Stack) Push(d string) {
- st.data = append(st.data, d)
-}
-func (st *Stack) Print() {
- fmt.Println(st.data)
-}
-
-type Vm struct {
- // Stack
- stack *Stack
-}
-
-func NewVm() *Vm {
- return &Vm{
- stack: NewStack(),
- }
-}
-
-func (vm *Vm) ProcContract(tx *ethutil.Transaction,
- block *ethutil.Block, cb TxCallback) {
- // Instruction pointer
- pc := 0
-
- contract := block.GetContract(tx.Hash())
- if contract == nil {
- fmt.Println("Contract not found")
- return
- }
-
- Pow256 := ethutil.BigPow(2, 256)
-
- //fmt.Printf("# op arg\n")
-out:
- for {
- // The base big int for all calculations. Use this for any results.
- base := new(big.Int)
- // XXX Should Instr return big int slice instead of string slice?
- // Get the next instruction from the contract
- //op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc)))))
- nb := ethutil.NumberToBytes(uint64(pc), 32)
- op, _, _ := ethutil.Instr(contract.State().Get(string(nb)))
-
- if !cb(0) {
- break
- }
-
- if Debug {
- //fmt.Printf("%-3d %-4d\n", pc, op)
- }
-
- switch op {
- case oADD:
- x, y := vm.stack.Popn()
- // (x + y) % 2 ** 256
- base.Add(x, y)
- base.Mod(base, Pow256)
- // Pop result back on the stack
- vm.stack.Push(base.String())
- case oSUB:
- x, y := vm.stack.Popn()
- // (x - y) % 2 ** 256
- base.Sub(x, y)
- base.Mod(base, Pow256)
- // Pop result back on the stack
- vm.stack.Push(base.String())
- case oMUL:
- x, y := vm.stack.Popn()
- // (x * y) % 2 ** 256
- base.Mul(x, y)
- base.Mod(base, Pow256)
- // Pop result back on the stack
- vm.stack.Push(base.String())
- case oDIV:
- x, y := vm.stack.Popn()
- // floor(x / y)
- base.Div(x, y)
- // Pop result back on the stack
- vm.stack.Push(base.String())
- case oSDIV:
- x, y := vm.stack.Popn()
- // n > 2**255
- if x.Cmp(Pow256) > 0 {
- x.Sub(Pow256, x)
- }
- if y.Cmp(Pow256) > 0 {
- y.Sub(Pow256, y)
- }
- z := new(big.Int)
- z.Div(x, y)
- if z.Cmp(Pow256) > 0 {
- z.Sub(Pow256, z)
- }
- // Push result on to the stack
- vm.stack.Push(z.String())
- case oMOD:
- x, y := vm.stack.Popn()
- base.Mod(x, y)
- vm.stack.Push(base.String())
- case oSMOD:
- x, y := vm.stack.Popn()
- // n > 2**255
- if x.Cmp(Pow256) > 0 {
- x.Sub(Pow256, x)
- }
- if y.Cmp(Pow256) > 0 {
- y.Sub(Pow256, y)
- }
- z := new(big.Int)
- z.Mod(x, y)
- if z.Cmp(Pow256) > 0 {
- z.Sub(Pow256, z)
- }
- // Push result on to the stack
- vm.stack.Push(z.String())
- case oEXP:
- x, y := vm.stack.Popn()
- base.Exp(x, y, Pow256)
-
- vm.stack.Push(base.String())
- case oNEG:
- base.Sub(Pow256, ethutil.Big(vm.stack.Pop()))
- vm.stack.Push(base.String())
- case oLT:
- x, y := vm.stack.Popn()
- // x < y
- if x.Cmp(y) < 0 {
- vm.stack.Push("1")
- } else {
- vm.stack.Push("0")
- }
- case oLE:
- x, y := vm.stack.Popn()
- // x <= y
- if x.Cmp(y) < 1 {
- vm.stack.Push("1")
- } else {
- vm.stack.Push("0")
- }
- case oGT:
- x, y := vm.stack.Popn()
- // x > y
- if x.Cmp(y) > 0 {
- vm.stack.Push("1")
- } else {
- vm.stack.Push("0")
- }
- case oGE:
- x, y := vm.stack.Popn()
- // x >= y
- if x.Cmp(y) > -1 {
- vm.stack.Push("1")
- } else {
- vm.stack.Push("0")
- }
- case oNOT:
- x, y := vm.stack.Popn()
- // x != y
- if x.Cmp(y) != 0 {
- vm.stack.Push("1")
- } else {
- vm.stack.Push("0")
- }
- case oMYADDRESS:
- vm.stack.Push(string(tx.Hash()))
- case oTXSENDER:
- vm.stack.Push(string(tx.Sender()))
- case oPUSH:
- // Get the next entry and pushes the value on the stack
- pc++
- vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(pc), 32))))
- case oPOP:
- // Pop current value of the stack
- vm.stack.Pop()
- case oLOAD:
- // Load instruction X on the stack
- i, _ := strconv.Atoi(vm.stack.Pop())
- vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(i), 32))))
- case oSTOP:
- break out
- }
- pc++
- }
-
- vm.stack.Print()
-}