diff options
Diffstat (limited to 'vm')
-rw-r--r-- | vm/environment.go | 20 | ||||
-rw-r--r-- | vm/execution.go | 16 | ||||
-rw-r--r-- | vm/vm.go | 2 |
3 files changed, 29 insertions, 9 deletions
diff --git a/vm/environment.go b/vm/environment.go index 2d933b65c..23b46c5df 100644 --- a/vm/environment.go +++ b/vm/environment.go @@ -1,6 +1,7 @@ package vm import ( + "errors" "math/big" "github.com/ethereum/eth-go/ethstate" @@ -18,9 +19,28 @@ type Environment interface { Difficulty() *big.Int BlockHash() []byte GasLimit() *big.Int + Transfer(from, to Account, amount *big.Int) error } type Object interface { GetStorage(key *big.Int) *ethutil.Value SetStorage(key *big.Int, value *ethutil.Value) } + +type Account interface { + SubBalance(amount *big.Int) + AddBalance(amount *big.Int) + Balance() *big.Int +} + +// generic transfer method +func Transfer(from, to Account, amount *big.Int) error { + if from.Balance().Cmp(amount) < 0 { + return errors.New("Insufficient balance in account") + } + + from.SubBalance(amount) + to.AddBalance(amount) + + return nil +} diff --git a/vm/execution.go b/vm/execution.go index 6bed43026..4c4bd1e3c 100644 --- a/vm/execution.go +++ b/vm/execution.go @@ -48,17 +48,17 @@ func (self *Execution) exec(code, caddr []byte, caller ClosureRef) (ret []byte, Value: self.value, }) - object := caller.Object() - if object.Balance.Cmp(self.value) < 0 { + from, to := caller.Object(), env.State().GetOrNewStateObject(self.address) + err = env.Transfer(from, to, self.value) + if err != nil { caller.ReturnGas(self.Gas, self.price) - err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, object.Balance) + err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, from.Balance) } else { - stateObject := env.State().GetOrNewStateObject(self.address) - self.object = stateObject + self.object = to - caller.Object().SubAmount(self.value) - stateObject.AddAmount(self.value) + //caller.Object().SubAmount(self.value) + //stateObject.AddAmount(self.value) // Pre-compiled contracts (address.go) 1, 2 & 3. naddr := ethutil.BigD(caddr).Uint64() @@ -69,7 +69,7 @@ func (self *Execution) exec(code, caddr []byte, caller ClosureRef) (ret []byte, } } else { // Create a new callable closure - c := NewClosure(msg, caller, stateObject, code, self.Gas, self.price) + c := NewClosure(msg, caller, to, code, self.Gas, self.price) c.exe = self if self.vm.Depth() == MaxCallDepth { @@ -692,7 +692,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { receiver := self.env.State().GetOrNewStateObject(stack.Pop().Bytes()) - receiver.AddAmount(closure.object.Balance) + receiver.AddAmount(closure.object.Balance()) closure.object.MarkForDeletion() |