Pop, push, load for vm

poc8
obscuren 11 years ago
parent 7cd41ac45a
commit 78d18b134f
  1. 38
      vm.go
  2. 20
      vm_test.go

38
vm.go

@ -6,12 +6,15 @@ import (
"fmt" "fmt"
_"strconv" _"strconv"
_ "encoding/hex" _ "encoding/hex"
"strconv"
) )
// Op codes // Op codes
const ( const (
oSTOP int = 0x00 oSTOP int = 0x00
oPSH int = 0x30 oPUSH int = 0x30
oPOP int = 0x31
oLOAD int = 0x36
/* /*
oADD int = 0x10 oADD int = 0x10
oSUB int = 0x11 oSUB int = 0x11
@ -70,7 +73,7 @@ func NewStack() *Stack {
func (st *Stack) Pop() string { func (st *Stack) Pop() string {
s := len(st.data) s := len(st.data)
str := st.data[s] str := st.data[s-1]
st.data = st.data[:s-1] st.data = st.data[:s-1]
return str return str
@ -91,30 +94,45 @@ func NewVm() *Vm {
} }
} }
func (vm *Vm) RunTransaction(tx *Transaction, block *Block, cb TxCallback) { func (vm *Vm) ProcContract(tx *Transaction, block *Block, cb TxCallback) {
// Instruction pointer // Instruction pointer
iptr := 0 iptr := 0
// Index pointer for the memory contract := block.GetContract(tx.Hash())
memIndex := 0 if contract == nil {
fmt.Println("Contract not found")
return
}
fmt.Printf("# op arg\n") fmt.Printf("# op arg\n")
for iptr < len(tx.data) { out:
memIndex++ for {
// The base big int for all calculations. Use this for any results. // The base big int for all calculations. Use this for any results.
base := new(big.Int) base := new(big.Int)
base.SetString("0",0) // so it doesn't whine about it base.SetString("0",0) // so it doesn't whine about it
// XXX Should Instr return big int slice instead of string slice? // XXX Should Instr return big int slice instead of string slice?
op, args, _ := Instr(tx.data[iptr]) // Get the next instruction from the contract
op, args, _ := Instr(contract.state.Get(string(Encode(uint32(iptr)))))
if Debug { if Debug {
fmt.Printf("%-3d %-4d %v\n", iptr, op, args) fmt.Printf("%-3d %-4d %v\n", iptr, op, args)
} }
switch op { switch op {
case oPSH: case oPUSH:
// Get the next entry and pushes the value on the stack
iptr++
vm.stack.Push(contract.state.Get(string(Encode(uint32(iptr)))))
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(Encode(uint32(i)))))
case oSTOP:
break out
} }
// Increment instruction pointer
iptr++ iptr++
} }
} }

@ -1,7 +1,7 @@
package main package main
import ( import (
"fmt" _"fmt"
"testing" "testing"
) )
@ -10,17 +10,23 @@ func TestVm(t *testing.T) {
db, _ := NewMemDatabase() db, _ := NewMemDatabase()
Db = db Db = db
tx := NewTransaction("", 20, []string{ ctrct := NewTransaction("", 20, []string{
"PSH 10", "PUSH",
"1a2f2e",
"PUSH",
"hallo",
"POP", // POP hallo
"PUSH",
"3",
"LOAD", // Load hallo back on the stack
"STOP",
}) })
tx := NewTransaction("1e8a42ea8cce13", 100, []string{})
block := CreateBlock("", 0, "", "", 0, 0, "", []*Transaction{tx}) block := CreateBlock("", 0, "", "", 0, 0, "", []*Transaction{ctrct, tx})
db.Put(block.Hash(), block.MarshalRlp()) db.Put(block.Hash(), block.MarshalRlp())
bm := NewBlockManager() bm := NewBlockManager()
bm.ProcessBlock( block ) bm.ProcessBlock( block )
contract := block.GetContract(tx.Hash())
fmt.Println(contract)
fmt.Println("it is", contract.state.Get(string(Encode(0))))
} }

Loading…
Cancel
Save