Closure => Context
This commit is contained in:
parent
e2d1d832ef
commit
4dc7ee9087
@ -144,19 +144,19 @@ func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execu
|
|||||||
return core.NewExecution(self, addr, data, gas, price, value)
|
return core.NewExecution(self, addr, data, gas, price, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) Call(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
ret, err := exe.Call(addr, caller)
|
ret, err := exe.Call(addr, caller)
|
||||||
self.Gas = exe.Gas
|
self.Gas = exe.Gas
|
||||||
|
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
func (self *VMEnv) CallCode(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) CallCode(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(caller.Address(), data, gas, price, value)
|
exe := self.vm(caller.Address(), data, gas, price, value)
|
||||||
return exe.Call(addr, caller)
|
return exe.Call(addr, caller)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
|
func (self *VMEnv) Create(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
return exe.Create(caller)
|
return exe.Create(caller)
|
||||||
}
|
}
|
||||||
|
@ -52,19 +52,19 @@ func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execu
|
|||||||
return core.NewExecution(self, addr, data, gas, price, value)
|
return core.NewExecution(self, addr, data, gas, price, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) Call(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
ret, err := exe.Call(addr, caller)
|
ret, err := exe.Call(addr, caller)
|
||||||
self.Gas = exe.Gas
|
self.Gas = exe.Gas
|
||||||
|
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
func (self *VMEnv) CallCode(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) CallCode(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(caller.Address(), data, gas, price, value)
|
exe := self.vm(caller.Address(), data, gas, price, value)
|
||||||
return exe.Call(addr, caller)
|
return exe.Call(addr, caller)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
|
func (self *VMEnv) Create(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
return exe.Create(caller)
|
return exe.Create(caller)
|
||||||
}
|
}
|
||||||
|
@ -20,26 +20,6 @@ type StateQuery interface {
|
|||||||
GetAccount(addr []byte) *state.StateObject
|
GetAccount(addr []byte) *state.StateObject
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func AddTestNetFunds(block *types.Block) {
|
|
||||||
for _, addr := range []string{
|
|
||||||
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
|
|
||||||
"e4157b34ea9615cfbde6b4fda419828124b70c78",
|
|
||||||
"b9c015918bdaba24b4ff057a92a3873d6eb201be",
|
|
||||||
"6c386a4b26f73c802f34673f7248bb118f97424a",
|
|
||||||
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
|
|
||||||
"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
|
|
||||||
"e6716f9544a56c530d868e4bfbacb172315bdead",
|
|
||||||
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
|
|
||||||
} {
|
|
||||||
codedAddr := ethutil.Hex2Bytes(addr)
|
|
||||||
account := block.State().GetAccount(codedAddr)
|
|
||||||
account.SetBalance(ethutil.Big("1606938044258990275541962092341162602522202993782792835301376")) //ethutil.BigPow(2, 200)
|
|
||||||
block.State().UpdateStateObject(account)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func CalcDifficulty(block, parent *types.Block) *big.Int {
|
func CalcDifficulty(block, parent *types.Block) *big.Int {
|
||||||
diff := new(big.Int)
|
diff := new(big.Int)
|
||||||
|
|
||||||
|
@ -24,14 +24,14 @@ func (self *Execution) Addr() []byte {
|
|||||||
return self.address
|
return self.address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Execution) Call(codeAddr []byte, caller vm.ClosureRef) ([]byte, error) {
|
func (self *Execution) Call(codeAddr []byte, caller vm.ContextRef) ([]byte, error) {
|
||||||
// Retrieve the executing code
|
// Retrieve the executing code
|
||||||
code := self.env.State().GetCode(codeAddr)
|
code := self.env.State().GetCode(codeAddr)
|
||||||
|
|
||||||
return self.exec(code, codeAddr, caller)
|
return self.exec(code, codeAddr, caller)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret []byte, err error) {
|
func (self *Execution) exec(code, contextAddr []byte, caller vm.ContextRef) (ret []byte, err error) {
|
||||||
env := self.env
|
env := self.env
|
||||||
evm := vm.New(env, vm.DebugVmTy)
|
evm := vm.New(env, vm.DebugVmTy)
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Execution) Create(caller vm.ClosureRef) (ret []byte, err error, account *state.StateObject) {
|
func (self *Execution) Create(caller vm.ContextRef) (ret []byte, err error, account *state.StateObject) {
|
||||||
ret, err = self.exec(self.input, nil, caller)
|
ret, err = self.exec(self.input, nil, caller)
|
||||||
account = self.env.State().GetStateObject(self.address)
|
account = self.env.State().GetStateObject(self.address)
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vmenv := self.VmEnv()
|
vmenv := self.VmEnv()
|
||||||
var ref vm.ClosureRef
|
var ref vm.ContextRef
|
||||||
if MessageCreatesContract(msg) {
|
if MessageCreatesContract(msg) {
|
||||||
contract := MakeContract(msg, self.state)
|
contract := MakeContract(msg, self.state)
|
||||||
ret, err, ref = vmenv.Create(sender, contract.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
|
ret, err, ref = vmenv.Create(sender, contract.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
|
||||||
|
@ -46,16 +46,16 @@ func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *Execution
|
|||||||
return NewExecution(self, addr, data, gas, price, value)
|
return NewExecution(self, addr, data, gas, price, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Call(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) Call(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
return exe.Call(addr, me)
|
return exe.Call(addr, me)
|
||||||
}
|
}
|
||||||
func (self *VMEnv) CallCode(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) CallCode(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(me.Address(), data, gas, price, value)
|
exe := self.vm(me.Address(), data, gas, price, value)
|
||||||
return exe.Call(addr, me)
|
return exe.Call(addr, me)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Create(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
|
func (self *VMEnv) Create(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
return exe.Create(me)
|
return exe.Create(me)
|
||||||
}
|
}
|
||||||
|
@ -74,19 +74,19 @@ func (self *Env) vm(addr, data []byte, gas, price, value *big.Int) *core.Executi
|
|||||||
return exec
|
return exec
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Env) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *Env) Call(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
ret, err := exe.Call(addr, caller)
|
ret, err := exe.Call(addr, caller)
|
||||||
self.Gas = exe.Gas
|
self.Gas = exe.Gas
|
||||||
|
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
func (self *Env) CallCode(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *Env) CallCode(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(caller.Address(), data, gas, price, value)
|
exe := self.vm(caller.Address(), data, gas, price, value)
|
||||||
return exe.Call(addr, caller)
|
return exe.Call(addr, caller)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Env) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
|
func (self *Env) Create(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
return exe.Create(caller)
|
return exe.Create(caller)
|
||||||
}
|
}
|
||||||
|
@ -8,15 +8,15 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ClosureRef interface {
|
type ContextRef interface {
|
||||||
ReturnGas(*big.Int, *big.Int)
|
ReturnGas(*big.Int, *big.Int)
|
||||||
Address() []byte
|
Address() []byte
|
||||||
SetCode([]byte)
|
SetCode([]byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Closure struct {
|
type Context struct {
|
||||||
caller ClosureRef
|
caller ContextRef
|
||||||
object ClosureRef
|
object ContextRef
|
||||||
Code []byte
|
Code []byte
|
||||||
message *state.Message
|
message *state.Message
|
||||||
|
|
||||||
@ -25,9 +25,9 @@ type Closure struct {
|
|||||||
Args []byte
|
Args []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new closure for the given data items
|
// Create a new context for the given data items
|
||||||
func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code []byte, gas, price *big.Int) *Closure {
|
func NewContext(msg *state.Message, caller ContextRef, object ContextRef, code []byte, gas, price *big.Int) *Context {
|
||||||
c := &Closure{message: msg, caller: caller, object: object, Code: code, Args: nil}
|
c := &Context{message: msg, caller: caller, object: object, Code: code, Args: nil}
|
||||||
|
|
||||||
// Gas should be a pointer so it can safely be reduced through the run
|
// Gas should be a pointer so it can safely be reduced through the run
|
||||||
// This pointer will be off the state transition
|
// This pointer will be off the state transition
|
||||||
@ -40,11 +40,11 @@ func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code [
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Closure) GetOp(x uint64) OpCode {
|
func (c *Context) GetOp(x uint64) OpCode {
|
||||||
return OpCode(c.GetByte(x))
|
return OpCode(c.GetByte(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Closure) GetByte(x uint64) byte {
|
func (c *Context) GetByte(x uint64) byte {
|
||||||
if x < uint64(len(c.Code)) {
|
if x < uint64(len(c.Code)) {
|
||||||
return c.Code[x]
|
return c.Code[x]
|
||||||
}
|
}
|
||||||
@ -52,18 +52,18 @@ func (c *Closure) GetByte(x uint64) byte {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Closure) GetBytes(x, y int) []byte {
|
func (c *Context) GetBytes(x, y int) []byte {
|
||||||
return c.GetRangeValue(uint64(x), uint64(y))
|
return c.GetRangeValue(uint64(x), uint64(y))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Closure) GetRangeValue(x, size uint64) []byte {
|
func (c *Context) GetRangeValue(x, size uint64) []byte {
|
||||||
x = uint64(math.Min(float64(x), float64(len(c.Code))))
|
x = uint64(math.Min(float64(x), float64(len(c.Code))))
|
||||||
y := uint64(math.Min(float64(x+size), float64(len(c.Code))))
|
y := uint64(math.Min(float64(x+size), float64(len(c.Code))))
|
||||||
|
|
||||||
return ethutil.LeftPadBytes(c.Code[x:y], int(size))
|
return ethutil.LeftPadBytes(c.Code[x:y], int(size))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Closure) Return(ret []byte) []byte {
|
func (c *Context) Return(ret []byte) []byte {
|
||||||
// Return the remaining gas to the caller
|
// Return the remaining gas to the caller
|
||||||
c.caller.ReturnGas(c.Gas, c.Price)
|
c.caller.ReturnGas(c.Gas, c.Price)
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ func (c *Closure) Return(ret []byte) []byte {
|
|||||||
/*
|
/*
|
||||||
* Gas functions
|
* Gas functions
|
||||||
*/
|
*/
|
||||||
func (c *Closure) UseGas(gas *big.Int) bool {
|
func (c *Context) UseGas(gas *big.Int) bool {
|
||||||
if c.Gas.Cmp(gas) < 0 {
|
if c.Gas.Cmp(gas) < 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -86,8 +86,8 @@ func (c *Closure) UseGas(gas *big.Int) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implement the caller interface
|
// Implement the caller interface
|
||||||
func (c *Closure) ReturnGas(gas, price *big.Int) {
|
func (c *Context) ReturnGas(gas, price *big.Int) {
|
||||||
// Return the gas to the closure
|
// Return the gas to the context
|
||||||
c.Gas.Add(c.Gas, gas)
|
c.Gas.Add(c.Gas, gas)
|
||||||
c.UsedGas.Sub(c.UsedGas, gas)
|
c.UsedGas.Sub(c.UsedGas, gas)
|
||||||
}
|
}
|
||||||
@ -95,10 +95,10 @@ func (c *Closure) ReturnGas(gas, price *big.Int) {
|
|||||||
/*
|
/*
|
||||||
* Set / Get
|
* Set / Get
|
||||||
*/
|
*/
|
||||||
func (c *Closure) Address() []byte {
|
func (c *Context) Address() []byte {
|
||||||
return c.object.Address()
|
return c.object.Address()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Closure) SetCode(code []byte) {
|
func (self *Context) SetCode(code []byte) {
|
||||||
self.Code = code
|
self.Code = code
|
||||||
}
|
}
|
@ -26,9 +26,9 @@ type Environment interface {
|
|||||||
Depth() int
|
Depth() int
|
||||||
SetDepth(i int)
|
SetDepth(i int)
|
||||||
|
|
||||||
Call(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
|
Call(me ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
|
||||||
CallCode(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
|
CallCode(me ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
|
||||||
Create(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, ClosureRef)
|
Create(me ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, ContextRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Object interface {
|
type Object interface {
|
||||||
|
@ -4,7 +4,7 @@ import "math/big"
|
|||||||
|
|
||||||
type VirtualMachine interface {
|
type VirtualMachine interface {
|
||||||
Env() Environment
|
Env() Environment
|
||||||
Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, data []byte) ([]byte, error)
|
Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, data []byte) ([]byte, error)
|
||||||
Printf(string, ...interface{}) VirtualMachine
|
Printf(string, ...interface{}) VirtualMachine
|
||||||
Endl() VirtualMachine
|
Endl() VirtualMachine
|
||||||
}
|
}
|
||||||
|
2
vm/vm.go
2
vm/vm.go
@ -20,7 +20,7 @@ func New(env Environment, typ Type) VirtualMachine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Vm) Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, data []byte) (ret []byte, err error) {
|
func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, data []byte) (ret []byte, err error) {
|
||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
124
vm/vm_debug.go
124
vm/vm_debug.go
@ -37,7 +37,7 @@ func NewDebugVm(env Environment) *DebugVm {
|
|||||||
return &DebugVm{env: env, logTy: lt, Recoverable: true}
|
return &DebugVm{env: env, logTy: lt, Recoverable: true}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
|
func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
|
||||||
self.env.SetDepth(self.env.Depth() + 1)
|
self.env.SetDepth(self.env.Depth() + 1)
|
||||||
|
|
||||||
msg := self.env.State().Manifest().AddMessage(&state.Message{
|
msg := self.env.State().Manifest().AddMessage(&state.Message{
|
||||||
@ -47,7 +47,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
|
Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
|
||||||
Value: value,
|
Value: value,
|
||||||
})
|
})
|
||||||
closure := NewClosure(msg, caller, me, code, gas, price)
|
context := NewContext(msg, caller, me, code, gas, price)
|
||||||
|
|
||||||
if self.Recoverable {
|
if self.Recoverable {
|
||||||
// Recover from any require exception
|
// Recover from any require exception
|
||||||
@ -55,9 +55,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
self.Printf(" %v", r).Endl()
|
self.Printf(" %v", r).Endl()
|
||||||
|
|
||||||
closure.UseGas(closure.Gas)
|
context.UseGas(context.Gas)
|
||||||
|
|
||||||
ret = closure.Return(nil)
|
ret = context.Return(nil)
|
||||||
|
|
||||||
err = fmt.Errorf("%v", r)
|
err = fmt.Errorf("%v", r)
|
||||||
|
|
||||||
@ -66,13 +66,13 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
}
|
}
|
||||||
|
|
||||||
if p := Precompiled[string(me.Address())]; p != nil {
|
if p := Precompiled[string(me.Address())]; p != nil {
|
||||||
return self.RunPrecompiled(p, callData, closure)
|
return self.RunPrecompiled(p, callData, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
op OpCode
|
op OpCode
|
||||||
|
|
||||||
destinations = analyseJumpDests(closure.Code)
|
destinations = analyseJumpDests(context.Code)
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
stack = NewStack()
|
stack = NewStack()
|
||||||
pc uint64 = 0
|
pc uint64 = 0
|
||||||
@ -84,11 +84,19 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
p := to.Uint64()
|
p := to.Uint64()
|
||||||
|
|
||||||
self.Printf(" ~> %v", to)
|
self.Printf(" ~> %v", to)
|
||||||
|
/* NOTE: new model. Will change soon
|
||||||
|
nop := OpCode(context.GetOp(p))
|
||||||
|
if nop != JUMPDEST {
|
||||||
|
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
|
||||||
|
}
|
||||||
|
|
||||||
|
pc = to.Uint64()
|
||||||
|
*/
|
||||||
// Return to start
|
// Return to start
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
pc = 0
|
pc = 0
|
||||||
} else {
|
} else {
|
||||||
nop := OpCode(closure.GetOp(p))
|
nop := OpCode(context.GetOp(p))
|
||||||
if !(nop == JUMPDEST || destinations[from] != nil) {
|
if !(nop == JUMPDEST || destinations[from] != nil) {
|
||||||
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
|
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
|
||||||
} else if nop == JUMP || nop == JUMPI {
|
} else if nop == JUMP || nop == JUMPI {
|
||||||
@ -103,11 +111,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], closure.Address(), len(code), closure.Gas, callData)
|
vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData)
|
||||||
|
|
||||||
// Don't bother with the execution if there's no code.
|
// Don't bother with the execution if there's no code.
|
||||||
if len(code) == 0 {
|
if len(code) == 0 {
|
||||||
return closure.Return(nil), nil
|
return context.Return(nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -117,22 +125,22 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
|
|
||||||
step++
|
step++
|
||||||
// Get the memory location of pc
|
// Get the memory location of pc
|
||||||
op = closure.GetOp(pc)
|
op = context.GetOp(pc)
|
||||||
|
|
||||||
self.Printf("(pc) %-3d -o- %-14s (m) %-4d (s) %-4d ", pc, op.String(), mem.Len(), stack.Len())
|
self.Printf("(pc) %-3d -o- %-14s (m) %-4d (s) %-4d ", pc, op.String(), mem.Len(), stack.Len())
|
||||||
|
|
||||||
newMemSize, gas := self.calculateGasAndSize(closure, caller, op, statedb, mem, stack)
|
newMemSize, gas := self.calculateGasAndSize(context, caller, op, statedb, mem, stack)
|
||||||
|
|
||||||
self.Printf("(g) %-3v (%v)", gas, closure.Gas)
|
self.Printf("(g) %-3v (%v)", gas, context.Gas)
|
||||||
|
|
||||||
if !closure.UseGas(gas) {
|
if !context.UseGas(gas) {
|
||||||
self.Endl()
|
self.Endl()
|
||||||
|
|
||||||
tmp := new(big.Int).Set(closure.Gas)
|
tmp := new(big.Int).Set(context.Gas)
|
||||||
|
|
||||||
closure.UseGas(closure.Gas)
|
context.UseGas(context.Gas)
|
||||||
|
|
||||||
return closure.Return(nil), OOG(gas, tmp)
|
return context.Return(nil), OOG(gas, tmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
mem.Resize(newMemSize.Uint64())
|
mem.Resize(newMemSize.Uint64())
|
||||||
@ -410,9 +418,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
self.Printf(" => %x", data)
|
self.Printf(" => %x", data)
|
||||||
// 0x30 range
|
// 0x30 range
|
||||||
case ADDRESS:
|
case ADDRESS:
|
||||||
stack.Push(ethutil.BigD(closure.Address()))
|
stack.Push(ethutil.BigD(context.Address()))
|
||||||
|
|
||||||
self.Printf(" => %x", closure.Address())
|
self.Printf(" => %x", context.Address())
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
|
|
||||||
addr := stack.Pop().Bytes()
|
addr := stack.Pop().Bytes()
|
||||||
@ -428,7 +436,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
|
|
||||||
self.Printf(" => %x", origin)
|
self.Printf(" => %x", origin)
|
||||||
case CALLER:
|
case CALLER:
|
||||||
caller := closure.caller.Address()
|
caller := context.caller.Address()
|
||||||
stack.Push(ethutil.BigD(caller))
|
stack.Push(ethutil.BigD(caller))
|
||||||
|
|
||||||
self.Printf(" => %x", caller)
|
self.Printf(" => %x", caller)
|
||||||
@ -485,7 +493,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
|
|
||||||
code = statedb.GetCode(addr)
|
code = statedb.GetCode(addr)
|
||||||
} else {
|
} else {
|
||||||
code = closure.Code
|
code = context.Code
|
||||||
}
|
}
|
||||||
|
|
||||||
l := big.NewInt(int64(len(code)))
|
l := big.NewInt(int64(len(code)))
|
||||||
@ -497,7 +505,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
if op == EXTCODECOPY {
|
if op == EXTCODECOPY {
|
||||||
code = statedb.GetCode(stack.Pop().Bytes())
|
code = statedb.GetCode(stack.Pop().Bytes())
|
||||||
} else {
|
} else {
|
||||||
code = closure.Code
|
code = context.Code
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -519,9 +527,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
|
|
||||||
self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, codeCopy)
|
self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, codeCopy)
|
||||||
case GASPRICE:
|
case GASPRICE:
|
||||||
stack.Push(closure.Price)
|
stack.Push(context.Price)
|
||||||
|
|
||||||
self.Printf(" => %v", closure.Price)
|
self.Printf(" => %v", context.Price)
|
||||||
|
|
||||||
// 0x40 range
|
// 0x40 range
|
||||||
case PREVHASH:
|
case PREVHASH:
|
||||||
@ -560,7 +568,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
// 0x50 range
|
// 0x50 range
|
||||||
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
|
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
|
||||||
a := uint64(op - PUSH1 + 1)
|
a := uint64(op - PUSH1 + 1)
|
||||||
byts := closure.GetRangeValue(pc+1, a)
|
byts := context.GetRangeValue(pc+1, a)
|
||||||
// Push value to stack
|
// Push value to stack
|
||||||
stack.Push(ethutil.BigD(byts))
|
stack.Push(ethutil.BigD(byts))
|
||||||
pc += a
|
pc += a
|
||||||
@ -589,7 +597,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
}
|
}
|
||||||
|
|
||||||
data := mem.Geti(mStart.Int64(), mSize.Int64())
|
data := mem.Geti(mStart.Int64(), mSize.Int64())
|
||||||
log := &Log{closure.Address(), topics, data}
|
log := &Log{context.Address(), topics, data}
|
||||||
self.env.AddLog(log)
|
self.env.AddLog(log)
|
||||||
|
|
||||||
self.Printf(" => %v", log)
|
self.Printf(" => %v", log)
|
||||||
@ -614,15 +622,15 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
self.Printf(" => [%v] 0x%x", off, val)
|
self.Printf(" => [%v] 0x%x", off, val)
|
||||||
case SLOAD:
|
case SLOAD:
|
||||||
loc := stack.Pop()
|
loc := stack.Pop()
|
||||||
val := ethutil.BigD(statedb.GetState(closure.Address(), loc.Bytes()))
|
val := ethutil.BigD(statedb.GetState(context.Address(), loc.Bytes()))
|
||||||
stack.Push(val)
|
stack.Push(val)
|
||||||
|
|
||||||
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
||||||
case SSTORE:
|
case SSTORE:
|
||||||
val, loc := stack.Popn()
|
val, loc := stack.Popn()
|
||||||
statedb.SetState(closure.Address(), loc.Bytes(), val)
|
statedb.SetState(context.Address(), loc.Bytes(), val)
|
||||||
|
|
||||||
closure.message.AddStorageChange(loc.Bytes())
|
context.message.AddStorageChange(loc.Bytes())
|
||||||
|
|
||||||
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
||||||
case JUMP:
|
case JUMP:
|
||||||
@ -644,7 +652,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
case MSIZE:
|
case MSIZE:
|
||||||
stack.Push(big.NewInt(int64(mem.Len())))
|
stack.Push(big.NewInt(int64(mem.Len())))
|
||||||
case GAS:
|
case GAS:
|
||||||
stack.Push(closure.Gas)
|
stack.Push(context.Gas)
|
||||||
// 0x60 range
|
// 0x60 range
|
||||||
case CREATE:
|
case CREATE:
|
||||||
|
|
||||||
@ -653,7 +661,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
value = stack.Pop()
|
value = stack.Pop()
|
||||||
size, offset = stack.Popn()
|
size, offset = stack.Popn()
|
||||||
input = mem.Get(offset.Int64(), size.Int64())
|
input = mem.Get(offset.Int64(), size.Int64())
|
||||||
gas = new(big.Int).Set(closure.Gas)
|
gas = new(big.Int).Set(context.Gas)
|
||||||
|
|
||||||
// Snapshot the current stack so we are able to
|
// Snapshot the current stack so we are able to
|
||||||
// revert back to it later.
|
// revert back to it later.
|
||||||
@ -661,15 +669,15 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Generate a new address
|
// Generate a new address
|
||||||
n := statedb.GetNonce(closure.Address())
|
n := statedb.GetNonce(context.Address())
|
||||||
addr := crypto.CreateAddress(closure.Address(), n)
|
addr := crypto.CreateAddress(context.Address(), n)
|
||||||
statedb.SetNonce(closure.Address(), n+1)
|
statedb.SetNonce(context.Address(), n+1)
|
||||||
|
|
||||||
self.Printf(" (*) %x", addr).Endl()
|
self.Printf(" (*) %x", addr).Endl()
|
||||||
|
|
||||||
closure.UseGas(closure.Gas)
|
context.UseGas(context.Gas)
|
||||||
|
|
||||||
ret, err, ref := self.env.Create(closure, addr, input, gas, price, value)
|
ret, err, ref := self.env.Create(context, addr, input, gas, price, value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
|
|
||||||
@ -678,7 +686,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
// gas < len(ret) * CreateDataGas == NO_CODE
|
// gas < len(ret) * CreateDataGas == NO_CODE
|
||||||
dataGas := big.NewInt(int64(len(ret)))
|
dataGas := big.NewInt(int64(len(ret)))
|
||||||
dataGas.Mul(dataGas, GasCreateByte)
|
dataGas.Mul(dataGas, GasCreateByte)
|
||||||
if closure.UseGas(dataGas) {
|
if context.UseGas(dataGas) {
|
||||||
ref.SetCode(ret)
|
ref.SetCode(ret)
|
||||||
msg.Output = ret
|
msg.Output = ret
|
||||||
}
|
}
|
||||||
@ -690,7 +698,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
|
|
||||||
// Debug hook
|
// Debug hook
|
||||||
if self.Dbg != nil {
|
if self.Dbg != nil {
|
||||||
self.Dbg.SetCode(closure.Code)
|
self.Dbg.SetCode(context.Code)
|
||||||
}
|
}
|
||||||
case CALL, CALLCODE:
|
case CALL, CALLCODE:
|
||||||
self.Endl()
|
self.Endl()
|
||||||
@ -711,9 +719,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if op == CALLCODE {
|
if op == CALLCODE {
|
||||||
ret, err = self.env.CallCode(closure, addr.Bytes(), args, gas, price, value)
|
ret, err = self.env.CallCode(context, addr.Bytes(), args, gas, price, value)
|
||||||
} else {
|
} else {
|
||||||
ret, err = self.env.Call(closure, addr.Bytes(), args, gas, price, value)
|
ret, err = self.env.Call(context, addr.Bytes(), args, gas, price, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -726,11 +734,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
|
|
||||||
mem.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
mem.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||||
}
|
}
|
||||||
self.Printf("resume %x (%v)", closure.Address(), closure.Gas)
|
self.Printf("resume %x (%v)", context.Address(), context.Gas)
|
||||||
|
|
||||||
// Debug hook
|
// Debug hook
|
||||||
if self.Dbg != nil {
|
if self.Dbg != nil {
|
||||||
self.Dbg.SetCode(closure.Code)
|
self.Dbg.SetCode(context.Code)
|
||||||
}
|
}
|
||||||
|
|
||||||
case RETURN:
|
case RETURN:
|
||||||
@ -739,27 +747,27 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
|
|
||||||
self.Printf(" => [%v, %v] (%d) 0x%x", offset, size, len(ret), ret).Endl()
|
self.Printf(" => [%v, %v] (%d) 0x%x", offset, size, len(ret), ret).Endl()
|
||||||
|
|
||||||
return closure.Return(ret), nil
|
return context.Return(ret), nil
|
||||||
case SUICIDE:
|
case SUICIDE:
|
||||||
receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
|
receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
|
||||||
balance := statedb.GetBalance(closure.Address())
|
balance := statedb.GetBalance(context.Address())
|
||||||
|
|
||||||
self.Printf(" => (%x) %v", receiver.Address()[:4], balance)
|
self.Printf(" => (%x) %v", receiver.Address()[:4], balance)
|
||||||
|
|
||||||
receiver.AddAmount(balance)
|
receiver.AddAmount(balance)
|
||||||
statedb.Delete(closure.Address())
|
statedb.Delete(context.Address())
|
||||||
|
|
||||||
fallthrough
|
fallthrough
|
||||||
case STOP: // Stop the closure
|
case STOP: // Stop the context
|
||||||
self.Endl()
|
self.Endl()
|
||||||
|
|
||||||
return closure.Return(nil), nil
|
return context.Return(nil), nil
|
||||||
default:
|
default:
|
||||||
vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op)
|
vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op)
|
||||||
|
|
||||||
closure.ReturnGas(big.NewInt(1), nil)
|
context.ReturnGas(big.NewInt(1), nil)
|
||||||
|
|
||||||
return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op)
|
return context.Return(nil), fmt.Errorf("Invalid opcode %x", op)
|
||||||
}
|
}
|
||||||
|
|
||||||
pc++
|
pc++
|
||||||
@ -771,11 +779,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
if pc == uint64(instrNo) {
|
if pc == uint64(instrNo) {
|
||||||
self.Stepping = true
|
self.Stepping = true
|
||||||
|
|
||||||
if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {
|
if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
} else if self.Stepping {
|
} else if self.Stepping {
|
||||||
if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {
|
if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -785,7 +793,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
|
func (self *DebugVm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
|
||||||
gas := new(big.Int)
|
gas := new(big.Int)
|
||||||
addStepGasUsage := func(amount *big.Int) {
|
addStepGasUsage := func(amount *big.Int) {
|
||||||
if amount.Cmp(ethutil.Big0) >= 0 {
|
if amount.Cmp(ethutil.Big0) >= 0 {
|
||||||
@ -844,7 +852,7 @@ func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op
|
|||||||
|
|
||||||
var mult *big.Int
|
var mult *big.Int
|
||||||
y, x := stack.Peekn()
|
y, x := stack.Peekn()
|
||||||
val := statedb.GetState(closure.Address(), x.Bytes())
|
val := statedb.GetState(context.Address(), x.Bytes())
|
||||||
if len(val) == 0 && len(y.Bytes()) > 0 {
|
if len(val) == 0 && len(y.Bytes()) > 0 {
|
||||||
// 0 => non 0
|
// 0 => non 0
|
||||||
mult = ethutil.Big3
|
mult = ethutil.Big3
|
||||||
@ -940,22 +948,22 @@ func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op
|
|||||||
return newMemSize, gas
|
return newMemSize, gas
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *DebugVm) RunPrecompiled(p *PrecompiledAccount, callData []byte, closure *Closure) (ret []byte, err error) {
|
func (self *DebugVm) RunPrecompiled(p *PrecompiledAccount, callData []byte, context *Context) (ret []byte, err error) {
|
||||||
gas := p.Gas(len(callData))
|
gas := p.Gas(len(callData))
|
||||||
if closure.UseGas(gas) {
|
if context.UseGas(gas) {
|
||||||
ret = p.Call(callData)
|
ret = p.Call(callData)
|
||||||
self.Printf("NATIVE_FUNC => %x", ret)
|
self.Printf("NATIVE_FUNC => %x", ret)
|
||||||
self.Endl()
|
self.Endl()
|
||||||
|
|
||||||
return closure.Return(ret), nil
|
return context.Return(ret), nil
|
||||||
} else {
|
} else {
|
||||||
self.Endl()
|
self.Endl()
|
||||||
|
|
||||||
tmp := new(big.Int).Set(closure.Gas)
|
tmp := new(big.Int).Set(context.Gas)
|
||||||
|
|
||||||
closure.UseGas(closure.Gas)
|
context.UseGas(context.Gas)
|
||||||
|
|
||||||
return closure.Return(nil), OOG(gas, tmp)
|
return context.Return(nil), OOG(gas, tmp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,16 +50,16 @@ func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execu
|
|||||||
return core.NewExecution(self, addr, data, gas, price, value)
|
return core.NewExecution(self, addr, data, gas, price, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Call(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) Call(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
return exe.Call(addr, me)
|
return exe.Call(addr, me)
|
||||||
}
|
}
|
||||||
func (self *VMEnv) CallCode(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) CallCode(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(me.Address(), data, gas, price, value)
|
exe := self.vm(me.Address(), data, gas, price, value)
|
||||||
return exe.Call(addr, me)
|
return exe.Call(addr, me)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Create(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
|
func (self *VMEnv) Create(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
return exe.Create(me)
|
return exe.Create(me)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user