@ -19,6 +19,7 @@ package gethclient
import (
import (
"context"
"context"
"encoding/json"
"math/big"
"math/big"
"runtime"
"runtime"
"runtime/debug"
"runtime/debug"
@ -118,15 +119,6 @@ func (ec *Client) GetProof(ctx context.Context, account common.Address, keys []s
return & result , err
return & result , err
}
}
// OverrideAccount specifies the state of an account to be overridden.
type OverrideAccount struct {
Nonce uint64 ` json:"nonce" `
Code [ ] byte ` json:"code" `
Balance * big . Int ` json:"balance" `
State map [ common . Hash ] common . Hash ` json:"state" `
StateDiff map [ common . Hash ] common . Hash ` json:"stateDiff" `
}
// CallContract executes a message call transaction, which is directly executed in the VM
// CallContract executes a message call transaction, which is directly executed in the VM
// of the node, but never mined into the blockchain.
// of the node, but never mined into the blockchain.
//
//
@ -141,7 +133,7 @@ func (ec *Client) CallContract(ctx context.Context, msg ethereum.CallMsg, blockN
var hex hexutil . Bytes
var hex hexutil . Bytes
err := ec . c . CallContext (
err := ec . c . CallContext (
ctx , & hex , "eth_call" , toCallArg ( msg ) ,
ctx , & hex , "eth_call" , toCallArg ( msg ) ,
toBlockNumArg ( blockNumber ) , toOverrideMap ( overrides ) ,
toBlockNumArg ( blockNumber ) , overrides ,
)
)
return hex , err
return hex , err
}
}
@ -218,26 +210,48 @@ func toCallArg(msg ethereum.CallMsg) interface{} {
return arg
return arg
}
}
func toOverrideMap ( overrides * map [ common . Address ] OverrideAccount ) interface { } {
// OverrideAccount specifies the state of an account to be overridden.
if overrides == nil {
type OverrideAccount struct {
return nil
// Nonce sets nonce of the account. Note: the nonce override will only
}
// be applied when it is set to a non-zero value.
type overrideAccount struct {
Nonce uint64
Nonce hexutil . Uint64 ` json:"nonce" `
Code hexutil . Bytes ` json:"code" `
// Code sets the contract code. The override will be applied
Balance * hexutil . Big ` json:"balance" `
// when the code is non-nil, i.e. setting empty code is possible
State map [ common . Hash ] common . Hash ` json:"state" `
// using an empty slice.
StateDiff map [ common . Hash ] common . Hash ` json:"stateDiff" `
Code [ ] byte
}
result := make ( map [ common . Address ] overrideAccount )
// Balance sets the account balance.
for addr , override := range * overrides {
Balance * big . Int
result [ addr ] = overrideAccount {
Nonce : hexutil . Uint64 ( override . Nonce ) ,
// State sets the complete storage. The override will be applied
Code : override . Code ,
// when the given map is non-nil. Using an empty map wipes the
Balance : ( * hexutil . Big ) ( override . Balance ) ,
// entire contract storage during the call.
State : override . State ,
State map [ common . Hash ] common . Hash
StateDiff : override . StateDiff ,
}
// StateDiff allows overriding individual storage slots.
}
StateDiff map [ common . Hash ] common . Hash
return & result
}
func ( a OverrideAccount ) MarshalJSON ( ) ( [ ] byte , error ) {
type acc struct {
Nonce hexutil . Uint64 ` json:"nonce,omitempty" `
Code string ` json:"code,omitempty" `
Balance * hexutil . Big ` json:"balance,omitempty" `
State interface { } ` json:"state,omitempty" `
StateDiff map [ common . Hash ] common . Hash ` json:"stateDiff,omitempty" `
}
output := acc {
Nonce : hexutil . Uint64 ( a . Nonce ) ,
Balance : ( * hexutil . Big ) ( a . Balance ) ,
StateDiff : a . StateDiff ,
}
if a . Code != nil {
output . Code = hexutil . Encode ( a . Code )
}
if a . State != nil {
output . State = a . State
}
return json . Marshal ( output )
}
}