diff --git a/ethchain/closure.go b/ethchain/closure.go index 7e911ad99..0f1e386ae 100644 --- a/ethchain/closure.go +++ b/ethchain/closure.go @@ -24,20 +24,18 @@ type Closure struct { Gas *big.Int Price *big.Int - Value *big.Int Args []byte } // Create a new closure for the given data items -func NewClosure(callee, object *StateObject, script []byte, state *State, gas, price, val *big.Int) *Closure { +func NewClosure(callee, object *StateObject, script []byte, state *State, gas, price *big.Int) *Closure { c := &Closure{callee: callee, object: object, Script: script, State: state, Args: nil} // In most cases gas, price and value are pointers to transaction objects // and we don't want the transaction's values to change. c.Gas = new(big.Int).Set(gas) c.Price = new(big.Int).Set(price) - c.Value = new(big.Int).Set(val) return c } diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index e8843a89e..b8a893d15 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -323,7 +323,7 @@ func (sm *StateManager) EvalScript(script []byte, object *StateObject, tx *Trans return } - closure := NewClosure(account, object, script, sm.procState, tx.Gas, tx.GasPrice, tx.Value) + closure := NewClosure(account, object, script, sm.procState, tx.Gas, tx.GasPrice) vm := NewVm(sm.procState, sm, RuntimeVars{ Origin: account.Address(), BlockNumber: block.BlockInfo().Number, diff --git a/ethchain/types.go b/ethchain/types.go index f9b7a84f5..9964bbe3b 100644 --- a/ethchain/types.go +++ b/ethchain/types.go @@ -97,8 +97,8 @@ const ( // 0xf0 range - closures oCREATE = 0xf0 - oCALL = 0xf2 - oRETURN = 0xf3 + oCALL = 0xf1 + oRETURN = 0xf2 // 0x70 range - other oLOG = 0xfe // XXX Unofficial diff --git a/ethchain/vm.go b/ethchain/vm.go index b4c77c849..ee470c269 100644 --- a/ethchain/vm.go +++ b/ethchain/vm.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/ethereum/eth-go/ethutil" _ "github.com/obscuren/secp256k1-go" - "log" _ "math" "math/big" ) @@ -96,7 +95,6 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro if ethutil.Config.Debug { ethutil.Config.Log.Debugf("# op\n") } - fmt.Println(closure.Script) for { @@ -320,13 +318,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro case oADDRESS: stack.Push(ethutil.BigD(closure.Object().Address())) case oBALANCE: - stack.Push(closure.Value) + stack.Push(closure.object.Amount) case oORIGIN: stack.Push(ethutil.BigD(vm.vars.Origin)) case oCALLER: stack.Push(ethutil.BigD(closure.Callee().Address())) case oCALLVALUE: - log.Println("Value:", vm.vars.Value) stack.Push(vm.vars.Value) case oCALLDATALOAD: require(1) @@ -406,13 +403,15 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro require(1) pc = stack.Pop() // Reduce pc by one because of the increment that's at the end of this for loop - pc.Sub(pc, ethutil.Big1) + //pc.Sub(pc, ethutil.Big1) + continue case oJUMPI: require(2) cond, pos := stack.Popn() if cond.Cmp(ethutil.BigTrue) == 0 { pc = pos - pc.Sub(pc, ethutil.Big1) + //pc.Sub(pc, ethutil.Big1) + continue } case oPC: stack.Push(pc) @@ -441,8 +440,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro contract.initScript, vm.state, gas, - closure.Price, - value) + closure.Price) // Call the closure and set the return value as // main script. closure.Script, err = closure.Call(vm, nil, hook) @@ -469,10 +467,13 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro break } + // Get the arguments from the memory args := mem.Get(inOffset.Int64(), inSize.Int64()) + // Fetch the contract which will serve as the closure body contract := vm.state.GetContract(addr.Bytes()) + fmt.Println("before", contract.Amount) if contract != nil { // Prepay for the gas @@ -482,8 +483,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro gas = new(big.Int).Set(closure.Gas) } closure.Gas.Sub(closure.Gas, gas) + + // Add the value to the state object + contract.AddAmount(value) + // Create a new callable closure - closure := NewClosure(closure.Object(), contract, contract.script, vm.state, gas, closure.Price, value) + closure := NewClosure(closure.Object(), contract, contract.script, vm.state, gas, closure.Price) // Executer the closure and get the return value (if any) ret, err := closure.Call(vm, args, hook) if err != nil { @@ -496,6 +501,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro vm.stateManager.manifest.AddObjectChange(contract) } + vm.state.SetStateObject(contract) + fmt.Println("after", contract.Amount) + mem.Set(retOffset.Int64(), retSize.Int64(), ret) } else { ethutil.Config.Log.Debugf("Contract %x not found\n", addr.Bytes())