diff --git a/vm.go b/vm.go index f38e7be06b..d7e3f77cf6 100644 --- a/vm.go +++ b/vm.go @@ -6,12 +6,15 @@ import ( "fmt" _"strconv" _ "encoding/hex" + "strconv" ) // Op codes const ( oSTOP int = 0x00 - oPSH int = 0x30 + oPUSH int = 0x30 + oPOP int = 0x31 + oLOAD int = 0x36 /* oADD int = 0x10 oSUB int = 0x11 @@ -70,7 +73,7 @@ func NewStack() *Stack { func (st *Stack) Pop() string { s := len(st.data) - str := st.data[s] + str := st.data[s-1] st.data = st.data[:s-1] 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 iptr := 0 - // Index pointer for the memory - memIndex := 0 + contract := block.GetContract(tx.Hash()) + if contract == nil { + fmt.Println("Contract not found") + return + } fmt.Printf("# op arg\n") - for iptr < len(tx.data) { - memIndex++ +out: + for { // The base big int for all calculations. Use this for any results. base := new(big.Int) base.SetString("0",0) // so it doesn't whine about it // 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 { fmt.Printf("%-3d %-4d %v\n", iptr, op, args) } 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++ } } diff --git a/vm_test.go b/vm_test.go index 00b8809a12..fe0358a42a 100644 --- a/vm_test.go +++ b/vm_test.go @@ -1,7 +1,7 @@ package main import ( - "fmt" + _"fmt" "testing" ) @@ -10,17 +10,23 @@ func TestVm(t *testing.T) { db, _ := NewMemDatabase() Db = db - tx := NewTransaction("", 20, []string{ - "PSH 10", + ctrct := NewTransaction("", 20, []string{ + "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()) bm := NewBlockManager() bm.ProcessBlock( block ) - contract := block.GetContract(tx.Hash()) - fmt.Println(contract) - fmt.Println("it is", contract.state.Get(string(Encode(0)))) }