aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm/contract.go
diff options
context:
space:
mode:
Diffstat (limited to 'core/vm/contract.go')
-rw-r--r--core/vm/contract.go44
1 files changed, 29 insertions, 15 deletions
diff --git a/core/vm/contract.go b/core/vm/contract.go
index dac81a529..d23995218 100644
--- a/core/vm/contract.go
+++ b/core/vm/contract.go
@@ -26,7 +26,6 @@ import (
type ContractRef interface {
ReturnGas(*big.Int, *big.Int)
Address() common.Address
- SetAddress(common.Address)
Value() *big.Int
SetCode([]byte)
EachStorage(cb func(key, value []byte))
@@ -35,8 +34,12 @@ type ContractRef interface {
// Contract represents an ethereum contract in the state database. It contains
// the the contract code, calling arguments. Contract implements ContractRef
type Contract struct {
- caller ContractRef
- self ContractRef
+ // CallerAddress is the result of the caller which initialised this
+ // contract. However when the "call method" is delegated this value
+ // needs to be initialised to that of the caller's caller.
+ CallerAddress common.Address
+ caller ContractRef
+ self ContractRef
jumpdests destinations // result of JUMPDEST analysis.
@@ -51,9 +54,9 @@ type Contract struct {
DelegateCall bool
}
-// Create a new context for the given data items.
+// NewContract returns a new contract environment for the execution of EVM.
func NewContract(caller ContractRef, object ContractRef, value, gas, price *big.Int) *Contract {
- c := &Contract{caller: caller, self: object, Args: nil}
+ c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object, Args: nil}
if parent, ok := caller.(*Contract); ok {
// Reuse JUMPDEST analysis from parent context if available.
@@ -74,6 +77,16 @@ func NewContract(caller ContractRef, object ContractRef, value, gas, price *big.
return c
}
+// AsDelegate sets the contract to be a delegate call and returns the current
+// contract (for chaining calls)
+func (c *Contract) AsDelegate() *Contract {
+ c.DelegateCall = true
+ // NOTE: caller must, at all times be a contract. It should never happen
+ // that caller is something other than a Contract.
+ c.CallerAddress = c.caller.(*Contract).CallerAddress
+ return c
+}
+
// GetOp returns the n'th element in the contract's byte array
func (c *Contract) GetOp(n uint64) OpCode {
return OpCode(c.GetByte(n))
@@ -88,13 +101,19 @@ func (c *Contract) GetByte(n uint64) byte {
return 0
}
-// Return returns the given ret argument and returns any remaining gas to the
-// caller
-func (c *Contract) Return(ret []byte) []byte {
+// Caller returns the caller of the contract.
+//
+// Caller will recursively call caller when the contract is a delegate
+// call, including that of caller's caller.
+func (c *Contract) Caller() common.Address {
+ return c.CallerAddress
+}
+
+// Finalise finalises the contract and returning any remaining gas to the original
+// caller.
+func (c *Contract) Finalise() {
// Return the remaining gas to the caller
c.caller.ReturnGas(c.Gas, c.Price)
-
- return ret
}
// UseGas attempts the use gas and subtracts it and returns true on success
@@ -118,11 +137,6 @@ func (c *Contract) Address() common.Address {
return c.self.Address()
}
-// SetAddress sets the contracts address
-func (c *Contract) SetAddress(addr common.Address) {
- c.self.SetAddress(addr)
-}
-
// Value returns the contracts value (sent to it from it's caller)
func (c *Contract) Value() *big.Int {
return c.value