merge upstream

This commit is contained in:
zelig 2014-07-30 18:02:43 +02:00
commit 34e937c976
12 changed files with 144 additions and 68 deletions

View File

@ -1,11 +1,13 @@
Ethereum Ethereum
======== ========
[![Build Status](https://travis-ci.org/ethereum/go-ethereum.png?branch=master)](https://travis-ci.org/ethereum/go-ethereum) Master [![Build
Status](http://cpt-obvious.ethercasts.com:8010/buildstatusimage?builder=go-ethereum-master-docker)](http://cpt-obvious.ethercasts.com:8010/builders/go-ethereum-master-docker/builds/-1) Develop [![Build
Status](http://cpt-obvious.ethercasts.com:8010/buildstatusimage?builder=go-ethereum-develop-docker)](http://cpt-obvious.ethercasts.com:8010/builders/go-ethereum-develop-docker/builds/-1)
Ethereum Go Client © 2014 Jeffrey Wilcke. Ethereum Go Client © 2014 Jeffrey Wilcke.
Current state: Proof of Concept 0.5.17. Current state: Proof of Concept 0.6.0.
For the development package please see the [eth-go package](https://github.com/ethereum/eth-go). For the development package please see the [eth-go package](https://github.com/ethereum/eth-go).

View File

@ -26,6 +26,22 @@ ApplicationWindow {
shortcut: "Ctrl+o" shortcut: "Ctrl+o"
onTriggered: openAppDialog.open() onTriggered: openAppDialog.open()
} }
MenuSeparator {}
MenuItem {
text: "Import key"
shortcut: "Ctrl+i"
onTriggered: importDialog.open()
}
MenuItem {
text: "Export keys"
shortcut: "Ctrl+e"
onTriggered: exportDialog.open()
}
//MenuSeparator {}
} }
Menu { Menu {
@ -249,6 +265,8 @@ ApplicationWindow {
} }
TextField { TextField {
text: eth.getCustomIdentifier() text: eth.getCustomIdentifier()
width: 500
placeholderText: "Anonymous"
onTextChanged: { onTextChanged: {
eth.setCustomIdentifier(text) eth.setCustomIdentifier(text)
} }
@ -373,9 +391,7 @@ ApplicationWindow {
//ui.open(openAppDialog.fileUrl.toString()) //ui.open(openAppDialog.fileUrl.toString())
//ui.openHtml(Qt.resolvedUrl(ui.assetPath("test.html"))) //ui.openHtml(Qt.resolvedUrl(ui.assetPath("test.html")))
var path = openAppDialog.fileUrl.toString() var path = openAppDialog.fileUrl.toString()
console.log(path)
var ext = path.split('.').pop() var ext = path.split('.').pop()
console.log(ext)
if(ext == "html" || ext == "htm") { if(ext == "html" || ext == "htm") {
ui.openHtml(path) ui.openHtml(path)
}else if(ext == "qml"){ }else if(ext == "qml"){
@ -384,6 +400,22 @@ ApplicationWindow {
} }
} }
FileDialog {
id: exportDialog
title: "Export keys"
onAccepted: {
}
}
FileDialog {
id: importDialog
title: "Import key"
onAccepted: {
var path = this.fileUrl.toString()
ui.importKey(path)
}
}
statusBar: StatusBar { statusBar: StatusBar {
height: 30 height: 30
RowLayout { RowLayout {
@ -658,7 +690,7 @@ ApplicationWindow {
anchors.left: aboutIcon.right anchors.left: aboutIcon.right
anchors.leftMargin: 10 anchors.leftMargin: 10
font.pointSize: 12 font.pointSize: 12
text: "<h2>Ethereal</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Maran Hidskes<br>Viktor Trón<br>" text: "<h2>Ethereal - Adrastea</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Maran Hidskes<br>Viktor Trón<br>"
} }
} }

View File

@ -2,12 +2,16 @@ package main
import ( import (
"fmt" "fmt"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethutil"
"github.com/go-qml/qml"
"math/big" "math/big"
"strconv" "strconv"
"strings" "strings"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethstate"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethvm"
"github.com/ethereum/go-ethereum/utils"
"github.com/go-qml/qml"
) )
type DebuggerWindow struct { type DebuggerWindow struct {
@ -15,10 +19,10 @@ type DebuggerWindow struct {
engine *qml.Engine engine *qml.Engine
lib *UiLib lib *UiLib
vm *ethchain.Vm vm *ethvm.Vm
Db *Debugger Db *Debugger
state *ethchain.State state *ethstate.State
} }
func NewDebuggerWindow(lib *UiLib) *DebuggerWindow { func NewDebuggerWindow(lib *UiLib) *DebuggerWindow {
@ -32,7 +36,7 @@ func NewDebuggerWindow(lib *UiLib) *DebuggerWindow {
win := component.CreateWindow(nil) win := component.CreateWindow(nil)
w := &DebuggerWindow{engine: engine, win: win, lib: lib, vm: &ethchain.Vm{}} w := &DebuggerWindow{engine: engine, win: win, lib: lib, vm: &ethvm.Vm{}}
w.Db = NewDebugger(w) w.Db = NewDebugger(w)
return w return w
@ -130,22 +134,16 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
state := self.lib.eth.StateManager().TransState() state := self.lib.eth.StateManager().TransState()
account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address()) account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address())
contract := ethchain.NewStateObject([]byte{0}) contract := ethstate.NewStateObject([]byte{0})
contract.Amount = value contract.Balance = value
callerClosure := ethchain.NewClosure(account, contract, script, state, gas, gasPrice) self.SetAsm(script)
block := self.lib.eth.BlockChain().CurrentBlock block := self.lib.eth.BlockChain().CurrentBlock
vm := ethchain.NewVm(state, self.lib.eth.StateManager(), ethchain.RuntimeVars{
Block: block, callerClosure := ethvm.NewClosure(account, contract, script, gas, gasPrice)
Origin: account.Address(), env := utils.NewEnv(state, block, account.Address(), value)
BlockNumber: block.Number, vm := ethvm.New(env)
PrevHash: block.PrevHash,
Coinbase: block.Coinbase,
Time: block.Time,
Diff: block.Difficulty,
Value: ethutil.Big(valueStr),
})
vm.Verbose = true vm.Verbose = true
vm.Dbg = self.Db vm.Dbg = self.Db
@ -255,13 +253,13 @@ type storeVal struct {
Key, Value string Key, Value string
} }
func (self *Debugger) BreakHook(pc int, op ethchain.OpCode, mem *ethchain.Memory, stack *ethchain.Stack, stateObject *ethchain.StateObject) bool { func (self *Debugger) BreakHook(pc int, op ethvm.OpCode, mem *ethvm.Memory, stack *ethvm.Stack, stateObject *ethstate.StateObject) bool {
self.main.Logln("break on instr:", pc) self.main.Logln("break on instr:", pc)
return self.halting(pc, op, mem, stack, stateObject) return self.halting(pc, op, mem, stack, stateObject)
} }
func (self *Debugger) StepHook(pc int, op ethchain.OpCode, mem *ethchain.Memory, stack *ethchain.Stack, stateObject *ethchain.StateObject) bool { func (self *Debugger) StepHook(pc int, op ethvm.OpCode, mem *ethvm.Memory, stack *ethvm.Stack, stateObject *ethstate.StateObject) bool {
return self.halting(pc, op, mem, stack, stateObject) return self.halting(pc, op, mem, stack, stateObject)
} }
@ -273,7 +271,7 @@ func (self *Debugger) BreakPoints() []int64 {
return self.breakPoints return self.breakPoints
} }
func (d *Debugger) halting(pc int, op ethchain.OpCode, mem *ethchain.Memory, stack *ethchain.Stack, stateObject *ethchain.StateObject) bool { func (d *Debugger) halting(pc int, op ethvm.OpCode, mem *ethvm.Memory, stack *ethvm.Stack, stateObject *ethstate.StateObject) bool {
d.win.Root().Call("setInstruction", pc) d.win.Root().Call("setInstruction", pc)
d.win.Root().Call("clearMem") d.win.Root().Call("clearMem")
d.win.Root().Call("clearStack") d.win.Root().Call("clearStack")

View File

@ -4,6 +4,7 @@ import (
"github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethpub" "github.com/ethereum/eth-go/ethpub"
"github.com/ethereum/eth-go/ethreact" "github.com/ethereum/eth-go/ethreact"
"github.com/ethereum/eth-go/ethstate"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
"github.com/go-qml/qml" "github.com/go-qml/qml"
) )
@ -16,8 +17,8 @@ type AppContainer interface {
Engine() *qml.Engine Engine() *qml.Engine
NewBlock(*ethchain.Block) NewBlock(*ethchain.Block)
ObjectChanged(*ethchain.StateObject) ObjectChanged(*ethstate.StateObject)
StorageChanged(*ethchain.StorageState) StorageChanged(*ethstate.StorageState)
NewWatcher(chan bool) NewWatcher(chan bool)
} }
@ -107,9 +108,9 @@ out:
app.container.NewBlock(block) app.container.NewBlock(block)
} }
case object := <-app.changeChan: case object := <-app.changeChan:
if stateObject, ok := object.Resource.(*ethchain.StateObject); ok { if stateObject, ok := object.Resource.(*ethstate.StateObject); ok {
app.container.ObjectChanged(stateObject) app.container.ObjectChanged(stateObject)
} else if storageObject, ok := object.Resource.(*ethchain.StorageState); ok { } else if storageObject, ok := object.Resource.(*ethstate.StorageState); ok {
app.container.StorageChanged(storageObject) app.container.StorageChanged(storageObject)
} }
} }

View File

@ -3,6 +3,11 @@ package main
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"math/big"
"strconv"
"strings"
"time"
"github.com/ethereum/eth-go" "github.com/ethereum/eth-go"
"github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethdb"
@ -14,10 +19,6 @@ import (
"github.com/ethereum/eth-go/ethwire" "github.com/ethereum/eth-go/ethwire"
"github.com/ethereum/go-ethereum/utils" "github.com/ethereum/go-ethereum/utils"
"github.com/go-qml/qml" "github.com/go-qml/qml"
"math/big"
"strconv"
"strings"
"time"
) )
var logger = ethlog.NewLogger("GUI") var logger = ethlog.NewLogger("GUI")
@ -144,16 +145,21 @@ func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) {
win := gui.createWindow(component) win := gui.createWindow(component)
gui.setInitialBlockChain() go func() {
gui.loadAddressBook() go gui.setInitialBlockChain()
gui.readPreviousTransactions() gui.loadAddressBook()
gui.setPeerInfo() gui.setPeerInfo()
gui.readPreviousTransactions()
}()
gui.update() gui.update()
return win, nil return win, nil
} }
func (gui *Gui) ImportKey(filePath string) {
}
func (gui *Gui) showKeyImport(context *qml.Context) (*qml.Window, error) { func (gui *Gui) showKeyImport(context *qml.Context) (*qml.Window, error) {
context.SetVar("lib", gui) context.SetVar("lib", gui)
component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/first_run.qml")) component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/first_run.qml"))
@ -295,7 +301,7 @@ func (gui *Gui) update() {
state := gui.eth.StateManager().TransState() state := gui.eth.StateManager().TransState()
unconfirmedFunds := new(big.Int) unconfirmedFunds := new(big.Int)
gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Amount))) gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Balance)))
gui.getObjectByName("syncProgressIndicator").Set("visible", !gui.eth.IsUpToDate()) gui.getObjectByName("syncProgressIndicator").Set("visible", !gui.eth.IsUpToDate())
lastBlockLabel := gui.getObjectByName("lastBlockLabel") lastBlockLabel := gui.getObjectByName("lastBlockLabel")
@ -307,9 +313,8 @@ func (gui *Gui) update() {
block := b.Resource.(*ethchain.Block) block := b.Resource.(*ethchain.Block)
gui.processBlock(block, false) gui.processBlock(block, false)
if bytes.Compare(block.Coinbase, gui.address()) == 0 { if bytes.Compare(block.Coinbase, gui.address()) == 0 {
gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.address()).Amount, nil) gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.address()).Balance, nil)
} }
case txMsg := <-txChan: case txMsg := <-txChan:
tx := txMsg.Resource.(*ethchain.Transaction) tx := txMsg.Resource.(*ethchain.Transaction)
@ -328,7 +333,7 @@ func (gui *Gui) update() {
unconfirmedFunds.Add(unconfirmedFunds, tx.Value) unconfirmedFunds.Add(unconfirmedFunds, tx.Value)
} }
gui.setWalletValue(object.Amount, unconfirmedFunds) gui.setWalletValue(object.Balance, unconfirmedFunds)
} else { } else {
object := state.GetAccount(gui.address()) object := state.GetAccount(gui.address())
if bytes.Compare(tx.Sender(), gui.address()) == 0 { if bytes.Compare(tx.Sender(), gui.address()) == 0 {
@ -337,7 +342,7 @@ func (gui *Gui) update() {
object.AddAmount(tx.Value) object.AddAmount(tx.Value)
} }
gui.setWalletValue(object.Amount, nil) gui.setWalletValue(object.Balance, nil)
state.UpdateStateObject(object) state.UpdateStateObject(object)
} }

View File

@ -2,16 +2,18 @@ package main
import ( import (
"errors" "errors"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethpub"
"github.com/ethereum/eth-go/ethutil"
"github.com/go-qml/qml"
"github.com/howeyc/fsnotify"
"io/ioutil" "io/ioutil"
"net/url" "net/url"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethpub"
"github.com/ethereum/eth-go/ethstate"
"github.com/ethereum/eth-go/ethutil"
"github.com/go-qml/qml"
"github.com/howeyc/fsnotify"
) )
type HtmlApplication struct { type HtmlApplication struct {
@ -40,7 +42,7 @@ func (app *HtmlApplication) Create() error {
return errors.New("Ethereum package not yet supported") return errors.New("Ethereum package not yet supported")
// TODO // TODO
ethutil.OpenPackage(app.path) //ethutil.OpenPackage(app.path)
} }
win := component.CreateWindow(nil) win := component.CreateWindow(nil)
@ -121,11 +123,11 @@ func (app *HtmlApplication) NewBlock(block *ethchain.Block) {
app.webView.Call("onNewBlockCb", b) app.webView.Call("onNewBlockCb", b)
} }
func (app *HtmlApplication) ObjectChanged(stateObject *ethchain.StateObject) { func (app *HtmlApplication) ObjectChanged(stateObject *ethstate.StateObject) {
app.webView.Call("onObjectChangeCb", ethpub.NewPStateObject(stateObject)) app.webView.Call("onObjectChangeCb", ethpub.NewPStateObject(stateObject))
} }
func (app *HtmlApplication) StorageChanged(storageObject *ethchain.StorageState) { func (app *HtmlApplication) StorageChanged(storageObject *ethstate.StorageState) {
app.webView.Call("onStorageChangeCb", ethpub.NewPStorageState(storageObject)) app.webView.Call("onStorageChangeCb", ethpub.NewPStorageState(storageObject))
} }

View File

@ -1,24 +1,24 @@
package main package main
import ( import (
"os"
"runtime"
"github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/go-ethereum/utils" "github.com/ethereum/go-ethereum/utils"
"github.com/go-qml/qml" "github.com/go-qml/qml"
"os"
"runtime"
) )
const ( const (
ClientIdentifier = "Ethereal" ClientIdentifier = "Ethereal"
Version = "0.5.17" Version = "0.6.1"
) )
func main() { func main() {
// Leave QT on top at ALL times. Qt Needs to be initialized from the main thread
qml.Init(nil)
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())
qml.Init(nil)
var interrupted = false var interrupted = false
utils.RegisterInterrupt(func(os.Signal) { utils.RegisterInterrupt(func(os.Signal) {
interrupted = true interrupted = true

View File

@ -3,6 +3,7 @@ package main
import ( import (
"github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethpub" "github.com/ethereum/eth-go/ethpub"
"github.com/ethereum/eth-go/ethstate"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
"github.com/go-qml/qml" "github.com/go-qml/qml"
"runtime" "runtime"
@ -24,7 +25,7 @@ func (app *QmlApplication) Create() error {
path := string(app.path) path := string(app.path)
// For some reason for windows we get /c:/path/to/something, windows doesn't like the first slash but is fine with the others so we are removing it // For some reason for windows we get /c:/path/to/something, windows doesn't like the first slash but is fine with the others so we are removing it
if string(app.path[0]) == "/" && runtime.GOOS == "windows" { if app.path[0] == '/' && runtime.GOOS == "windows" {
path = app.path[1:] path = app.path[1:]
} }
@ -50,11 +51,11 @@ func (app *QmlApplication) NewBlock(block *ethchain.Block) {
app.win.Call("onNewBlockCb", pblock) app.win.Call("onNewBlockCb", pblock)
} }
func (app *QmlApplication) ObjectChanged(stateObject *ethchain.StateObject) { func (app *QmlApplication) ObjectChanged(stateObject *ethstate.StateObject) {
app.win.Call("onObjectChangeCb", ethpub.NewPStateObject(stateObject)) app.win.Call("onObjectChangeCb", ethpub.NewPStateObject(stateObject))
} }
func (app *QmlApplication) StorageChanged(storageObject *ethchain.StorageState) { func (app *QmlApplication) StorageChanged(storageObject *ethstate.StorageState) {
app.win.Call("onStorageChangeCb", ethpub.NewPStorageState(storageObject)) app.win.Call("onStorageChangeCb", ethpub.NewPStorageState(storageObject))
} }

View File

@ -78,8 +78,8 @@ func (ui *UiLib) AssetPath(p string) string {
func (self *UiLib) StartDbWithContractAndData(contractHash, data string) { func (self *UiLib) StartDbWithContractAndData(contractHash, data string) {
dbWindow := NewDebuggerWindow(self) dbWindow := NewDebuggerWindow(self)
object := self.eth.StateManager().CurrentState().GetStateObject(ethutil.Hex2Bytes(contractHash)) object := self.eth.StateManager().CurrentState().GetStateObject(ethutil.Hex2Bytes(contractHash))
if len(object.Script()) > 0 { if len(object.Code) > 0 {
dbWindow.SetCode("0x" + ethutil.Bytes2Hex(object.Script())) dbWindow.SetCode("0x" + ethutil.Bytes2Hex(object.Code))
} }
dbWindow.SetData("0x" + data) dbWindow.SetData("0x" + data)

View File

@ -1,15 +1,16 @@
package main package main
import ( import (
"runtime"
"github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/go-ethereum/utils" "github.com/ethereum/go-ethereum/utils"
"runtime"
) )
const ( const (
ClientIdentifier = "Ethereum(G)" ClientIdentifier = "Ethereum(G)"
Version = "0.5.17" Version = "0.6.1"
) )
var logger = ethlog.NewLogger("CLI") var logger = ethlog.NewLogger("CLI")

View File

@ -7,6 +7,7 @@ import (
"github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/eth-go/ethpub" "github.com/ethereum/eth-go/ethpub"
"github.com/ethereum/eth-go/ethreact" "github.com/ethereum/eth-go/ethreact"
"github.com/ethereum/eth-go/ethstate"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/go-ethereum/utils" "github.com/ethereum/go-ethereum/utils"
"github.com/obscuren/otto" "github.com/obscuren/otto"
@ -67,7 +68,7 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE {
// Subscribe to events // Subscribe to events
reactor := ethereum.Reactor() reactor := ethereum.Reactor()
reactor.Subscribe("newBlock", self.blockChan) reactor.Subscribe("newBlock", re.blockChan)
re.Bind("eth", &JSEthereum{re.lib, re.vm}) re.Bind("eth", &JSEthereum{re.lib, re.vm})
@ -122,12 +123,12 @@ out:
if _, ok := block.Resource.(*ethchain.Block); ok { if _, ok := block.Resource.(*ethchain.Block); ok {
} }
case object := <-self.changeChan: case object := <-self.changeChan:
if stateObject, ok := object.Resource.(*ethchain.StateObject); ok { if stateObject, ok := object.Resource.(*ethstate.StateObject); ok {
for _, cb := range self.objectCb[ethutil.Bytes2Hex(stateObject.Address())] { for _, cb := range self.objectCb[ethutil.Bytes2Hex(stateObject.Address())] {
val, _ := self.vm.ToValue(ethpub.NewPStateObject(stateObject)) val, _ := self.vm.ToValue(ethpub.NewPStateObject(stateObject))
cb.Call(cb, val) cb.Call(cb, val)
} }
} else if storageObject, ok := object.Resource.(*ethchain.StorageState); ok { } else if storageObject, ok := object.Resource.(*ethstate.StorageState); ok {
for _, cb := range self.objectCb[ethutil.Bytes2Hex(storageObject.StateAddress)+ethutil.Bytes2Hex(storageObject.Address)] { for _, cb := range self.objectCb[ethutil.Bytes2Hex(storageObject.StateAddress)+ethutil.Bytes2Hex(storageObject.Address)] {
val, _ := self.vm.ToValue(ethpub.NewPStorageState(storageObject)) val, _ := self.vm.ToValue(ethpub.NewPStorageState(storageObject))
cb.Call(cb, val) cb.Call(cb, val)

33
utils/vm_env.go Normal file
View File

@ -0,0 +1,33 @@
package utils
import (
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethstate"
"math/big"
)
type VMEnv struct {
state *ethstate.State
block *ethchain.Block
transactor []byte
value *big.Int
}
func NewEnv(state *ethstate.State, block *ethchain.Block, transactor []byte, value *big.Int) *VMEnv {
return &VMEnv{
state: state,
block: block,
transactor: transactor,
value: value,
}
}
func (self *VMEnv) Origin() []byte { return self.transactor }
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number }
func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase }
func (self *VMEnv) Time() int64 { return self.block.Time }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
func (self *VMEnv) Value() *big.Int { return self.value }
func (self *VMEnv) State() *ethstate.State { return self.state }