internal/ethapi: Add support for fetching information about the current call in JS traces
This commit is contained in:
		@@ -23,6 +23,7 @@ import (
 | 
				
			|||||||
	"math/big"
 | 
						"math/big"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/common"
 | 
						"github.com/ethereum/go-ethereum/common"
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/common/hexutil"
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/core/vm"
 | 
						"github.com/ethereum/go-ethereum/core/vm"
 | 
				
			||||||
	"github.com/robertkrimen/otto"
 | 
						"github.com/robertkrimen/otto"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -164,6 +165,37 @@ func (dw *dbWrapper) toValue(vm *otto.Otto) otto.Value {
 | 
				
			|||||||
	return value
 | 
						return value
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// contractWrapper provides a JS wrapper around vm.Contract
 | 
				
			||||||
 | 
					type contractWrapper struct {
 | 
				
			||||||
 | 
						contract *vm.Contract
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *contractWrapper) caller() common.Address {
 | 
				
			||||||
 | 
						return c.contract.Caller()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *contractWrapper) address() common.Address {
 | 
				
			||||||
 | 
						return c.contract.Address()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *contractWrapper) value() *big.Int {
 | 
				
			||||||
 | 
						return c.contract.Value()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *contractWrapper) calldata() []byte {
 | 
				
			||||||
 | 
						return c.contract.Input
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *contractWrapper) toValue(vm *otto.Otto) otto.Value {
 | 
				
			||||||
 | 
						value, _ := vm.ToValue(c)
 | 
				
			||||||
 | 
						obj := value.Object()
 | 
				
			||||||
 | 
						obj.Set("caller", c.caller)
 | 
				
			||||||
 | 
						obj.Set("address", c.address)
 | 
				
			||||||
 | 
						obj.Set("value", c.value)
 | 
				
			||||||
 | 
						obj.Set("calldata", c.calldata)
 | 
				
			||||||
 | 
						return value
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// JavascriptTracer provides an implementation of Tracer that evaluates a
 | 
					// JavascriptTracer provides an implementation of Tracer that evaluates a
 | 
				
			||||||
// Javascript function for each VM execution step.
 | 
					// Javascript function for each VM execution step.
 | 
				
			||||||
type JavascriptTracer struct {
 | 
					type JavascriptTracer struct {
 | 
				
			||||||
@@ -177,6 +209,8 @@ type JavascriptTracer struct {
 | 
				
			|||||||
	stackvalue    otto.Value             // JS view of `stack`
 | 
						stackvalue    otto.Value             // JS view of `stack`
 | 
				
			||||||
	db            *dbWrapper             // Wrapper around the VM environment
 | 
						db            *dbWrapper             // Wrapper around the VM environment
 | 
				
			||||||
	dbvalue       otto.Value             // JS view of `db`
 | 
						dbvalue       otto.Value             // JS view of `db`
 | 
				
			||||||
 | 
						contract      *contractWrapper       // Wrapper around the contract object
 | 
				
			||||||
 | 
						contractvalue otto.Value             // JS view of `contract`
 | 
				
			||||||
	err           error                  // Error, if one has occurred
 | 
						err           error                  // Error, if one has occurred
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -189,6 +223,7 @@ func NewJavascriptTracer(code string) (*JavascriptTracer, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Set up builtins for this environment
 | 
						// Set up builtins for this environment
 | 
				
			||||||
	vm.Set("big", &fakeBig{})
 | 
						vm.Set("big", &fakeBig{})
 | 
				
			||||||
 | 
						vm.Set("toHex", hexutil.Encode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	jstracer, err := vm.Object("(" + code + ")")
 | 
						jstracer, err := vm.Object("(" + code + ")")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -220,6 +255,7 @@ func NewJavascriptTracer(code string) (*JavascriptTracer, error) {
 | 
				
			|||||||
	mem := &memoryWrapper{}
 | 
						mem := &memoryWrapper{}
 | 
				
			||||||
	stack := &stackWrapper{}
 | 
						stack := &stackWrapper{}
 | 
				
			||||||
	db := &dbWrapper{}
 | 
						db := &dbWrapper{}
 | 
				
			||||||
 | 
						contract := &contractWrapper{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &JavascriptTracer{
 | 
						return &JavascriptTracer{
 | 
				
			||||||
		vm:            vm,
 | 
							vm:            vm,
 | 
				
			||||||
@@ -232,6 +268,8 @@ func NewJavascriptTracer(code string) (*JavascriptTracer, error) {
 | 
				
			|||||||
		stackvalue:    stack.toValue(vm),
 | 
							stackvalue:    stack.toValue(vm),
 | 
				
			||||||
		db:            db,
 | 
							db:            db,
 | 
				
			||||||
		dbvalue:       db.toValue(vm),
 | 
							dbvalue:       db.toValue(vm),
 | 
				
			||||||
 | 
							contract:      contract,
 | 
				
			||||||
 | 
							contractvalue: contract.toValue(vm),
 | 
				
			||||||
		err:           nil,
 | 
							err:           nil,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -283,6 +321,7 @@ func (jst *JavascriptTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode,
 | 
				
			|||||||
		jst.memory.memory = memory
 | 
							jst.memory.memory = memory
 | 
				
			||||||
		jst.stack.stack = stack
 | 
							jst.stack.stack = stack
 | 
				
			||||||
		jst.db.db = env.StateDB
 | 
							jst.db.db = env.StateDB
 | 
				
			||||||
 | 
							jst.contract.contract = contract
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ocw := &opCodeWrapper{op}
 | 
							ocw := &opCodeWrapper{op}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -292,6 +331,7 @@ func (jst *JavascriptTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode,
 | 
				
			|||||||
		jst.log["gasPrice"] = cost
 | 
							jst.log["gasPrice"] = cost
 | 
				
			||||||
		jst.log["memory"] = jst.memvalue
 | 
							jst.log["memory"] = jst.memvalue
 | 
				
			||||||
		jst.log["stack"] = jst.stackvalue
 | 
							jst.log["stack"] = jst.stackvalue
 | 
				
			||||||
 | 
							jst.log["contract"] = jst.contractvalue
 | 
				
			||||||
		jst.log["depth"] = depth
 | 
							jst.log["depth"] = depth
 | 
				
			||||||
		jst.log["account"] = contract.Address()
 | 
							jst.log["account"] = contract.Address()
 | 
				
			||||||
		jst.log["err"] = err
 | 
							jst.log["err"] = err
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user