converted vm
This commit is contained in:
parent
8ce6a36478
commit
515d9432fc
@ -4,6 +4,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
"github.com/ethereum/go-ethereum/vm"
|
"github.com/ethereum/go-ethereum/vm"
|
||||||
@ -11,26 +12,23 @@ import (
|
|||||||
|
|
||||||
type Execution struct {
|
type Execution struct {
|
||||||
env vm.Environment
|
env vm.Environment
|
||||||
address, input []byte
|
address *common.Address
|
||||||
|
input []byte
|
||||||
Gas, price, value *big.Int
|
Gas, price, value *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewExecution(env vm.Environment, address, input []byte, gas, gasPrice, value *big.Int) *Execution {
|
func NewExecution(env vm.Environment, address *common.Address, input []byte, gas, gasPrice, value *big.Int) *Execution {
|
||||||
return &Execution{env: env, address: address, input: input, Gas: gas, price: gasPrice, value: value}
|
return &Execution{env: env, address: address, input: input, Gas: gas, price: gasPrice, value: value}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Execution) Addr() []byte {
|
func (self *Execution) Call(codeAddr common.Address, caller vm.ContextRef) ([]byte, error) {
|
||||||
return self.address
|
|
||||||
}
|
|
||||||
|
|
||||||
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(&codeAddr, code, caller)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Execution) exec(code, contextAddr []byte, caller vm.ContextRef) (ret []byte, err error) {
|
func (self *Execution) exec(contextAddr *common.Address, code []byte, caller vm.ContextRef) (ret []byte, err error) {
|
||||||
env := self.env
|
env := self.env
|
||||||
evm := vm.NewVm(env)
|
evm := vm.NewVm(env)
|
||||||
if env.Depth() == vm.MaxCallDepth {
|
if env.Depth() == vm.MaxCallDepth {
|
||||||
@ -40,14 +38,15 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ContextRef) (ret
|
|||||||
}
|
}
|
||||||
|
|
||||||
vsnapshot := env.State().Copy()
|
vsnapshot := env.State().Copy()
|
||||||
if len(self.address) == 0 {
|
if self.address == nil {
|
||||||
// Generate a new address
|
// Generate a new address
|
||||||
nonce := env.State().GetNonce(caller.Address())
|
nonce := env.State().GetNonce(caller.Address())
|
||||||
self.address = crypto.CreateAddress(caller.Address(), nonce)
|
addr := crypto.CreateAddress(caller.Address(), nonce)
|
||||||
|
self.address = &addr
|
||||||
env.State().SetNonce(caller.Address(), nonce+1)
|
env.State().SetNonce(caller.Address(), nonce+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
from, to := env.State().GetStateObject(caller.Address()), env.State().GetOrNewStateObject(self.address)
|
from, to := env.State().GetStateObject(caller.Address()), env.State().GetOrNewStateObject(*self.address)
|
||||||
err = env.Transfer(from, to, self.value)
|
err = env.Transfer(from, to, self.value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
env.State().Set(vsnapshot)
|
env.State().Set(vsnapshot)
|
||||||
@ -73,8 +72,8 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ContextRef) (ret
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Execution) Create(caller vm.ContextRef) (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(nil, self.input, caller)
|
||||||
account = self.env.State().GetStateObject(self.address)
|
account = self.env.State().GetStateObject(*self.address)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
)
|
)
|
||||||
@ -16,8 +16,8 @@ type FilterOptions struct {
|
|||||||
Earliest int64
|
Earliest int64
|
||||||
Latest int64
|
Latest int64
|
||||||
|
|
||||||
Address [][]byte
|
Address []common.Address
|
||||||
Topics [][][]byte
|
Topics [][]common.Hash
|
||||||
|
|
||||||
Skip int
|
Skip int
|
||||||
Max int
|
Max int
|
||||||
@ -29,9 +29,9 @@ type Filter struct {
|
|||||||
earliest int64
|
earliest int64
|
||||||
latest int64
|
latest int64
|
||||||
skip int
|
skip int
|
||||||
address [][]byte
|
address []common.Address
|
||||||
max int
|
max int
|
||||||
topics [][][]byte
|
topics [][]common.Hash
|
||||||
|
|
||||||
BlockCallback func(*types.Block)
|
BlockCallback func(*types.Block)
|
||||||
PendingCallback func(*types.Block)
|
PendingCallback func(*types.Block)
|
||||||
@ -67,11 +67,11 @@ func (self *Filter) SetLatestBlock(latest int64) {
|
|||||||
self.latest = latest
|
self.latest = latest
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Filter) SetAddress(addr [][]byte) {
|
func (self *Filter) SetAddress(addr []common.Address) {
|
||||||
self.address = addr
|
self.address = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Filter) SetTopics(topics [][][]byte) {
|
func (self *Filter) SetTopics(topics [][]common.Hash) {
|
||||||
self.topics = topics
|
self.topics = topics
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,9 +131,9 @@ func (self *Filter) Find() state.Logs {
|
|||||||
return logs[skip:]
|
return logs[skip:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func includes(addresses [][]byte, a []byte) bool {
|
func includes(addresses []common.Address, a common.Address) bool {
|
||||||
for _, addr := range addresses {
|
for _, addr := range addresses {
|
||||||
if !bytes.Equal(addr, a) {
|
if addr != a {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,13 +151,13 @@ Logs:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
logTopics := make([][]byte, len(self.topics))
|
logTopics := make([]common.Hash, len(self.topics))
|
||||||
copy(logTopics, log.Topics())
|
copy(logTopics, log.Topics())
|
||||||
|
|
||||||
for i, topics := range self.topics {
|
for i, topics := range self.topics {
|
||||||
for _, topic := range topics {
|
for _, topic := range topics {
|
||||||
var match bool
|
var match bool
|
||||||
if bytes.Equal(log.Topics()[i], topic) {
|
if log.Topics()[i] == topic {
|
||||||
match = true
|
match = true
|
||||||
}
|
}
|
||||||
if !match {
|
if !match {
|
||||||
@ -176,7 +176,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool {
|
|||||||
if len(self.address) > 0 {
|
if len(self.address) > 0 {
|
||||||
var included bool
|
var included bool
|
||||||
for _, addr := range self.address {
|
for _, addr := range self.address {
|
||||||
if types.BloomLookup(block.Bloom(), addr) {
|
if types.BloomLookup(block.Bloom(), addr.Hash()) {
|
||||||
included = true
|
included = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,12 +26,11 @@ var GenesisDiff = big.NewInt(131072)
|
|||||||
var GenesisGasLimit = big.NewInt(3141592)
|
var GenesisGasLimit = big.NewInt(3141592)
|
||||||
|
|
||||||
func GenesisBlock(db common.Database) *types.Block {
|
func GenesisBlock(db common.Database) *types.Block {
|
||||||
genesis := types.NewBlock(ZeroHash256, ZeroHash160, nil, GenesisDiff, 42, "")
|
genesis := types.NewBlock(common.Hash{}, common.Address{}, common.Hash{}, GenesisDiff, 42, "")
|
||||||
genesis.Header().Number = common.Big0
|
genesis.Header().Number = common.Big0
|
||||||
genesis.Header().GasLimit = GenesisGasLimit
|
genesis.Header().GasLimit = GenesisGasLimit
|
||||||
genesis.Header().GasUsed = common.Big0
|
genesis.Header().GasUsed = common.Big0
|
||||||
genesis.Header().Time = 0
|
genesis.Header().Time = 0
|
||||||
genesis.Header().MixDigest = make([]byte, 32)
|
|
||||||
|
|
||||||
genesis.Td = common.Big0
|
genesis.Td = common.Big0
|
||||||
|
|
||||||
@ -49,7 +48,7 @@ func GenesisBlock(db common.Database) *types.Block {
|
|||||||
statedb := state.New(genesis.Root(), db)
|
statedb := state.New(genesis.Root(), db)
|
||||||
for addr, account := range accounts {
|
for addr, account := range accounts {
|
||||||
codedAddr := common.Hex2Bytes(addr)
|
codedAddr := common.Hex2Bytes(addr)
|
||||||
accountState := statedb.GetAccount(codedAddr)
|
accountState := statedb.GetAccount(common.BytesToAddress(codedAddr))
|
||||||
accountState.SetBalance(common.Big(account.Balance))
|
accountState.SetBalance(common.Big(account.Balance))
|
||||||
statedb.UpdateStateObject(accountState)
|
statedb.UpdateStateObject(accountState)
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ var ()
|
|||||||
* 6) Derive new state root
|
* 6) Derive new state root
|
||||||
*/
|
*/
|
||||||
type StateTransition struct {
|
type StateTransition struct {
|
||||||
coinbase []byte
|
coinbase common.Address
|
||||||
msg Message
|
msg Message
|
||||||
gas, gasPrice *big.Int
|
gas, gasPrice *big.Int
|
||||||
initialGas *big.Int
|
initialGas *big.Int
|
||||||
@ -119,7 +119,7 @@ func (self *StateTransition) BuyGas() error {
|
|||||||
|
|
||||||
sender := self.From()
|
sender := self.From()
|
||||||
if sender.Balance().Cmp(MessageGasValue(self.msg)) < 0 {
|
if sender.Balance().Cmp(MessageGasValue(self.msg)) < 0 {
|
||||||
return fmt.Errorf("insufficient ETH for gas (%x). Req %v, has %v", sender.Address()[:4], MessageGasValue(self.msg), sender.Balance())
|
return fmt.Errorf("insufficient ETH for gas (%x). Req %v, has %v", sender.Address().Bytes()[:4], MessageGasValue(self.msg), sender.Balance())
|
||||||
}
|
}
|
||||||
|
|
||||||
coinbase := self.Coinbase()
|
coinbase := self.Coinbase()
|
||||||
@ -195,8 +195,9 @@ func (self *StateTransition) transitionState() (ret []byte, usedGas *big.Int, er
|
|||||||
vmenv := self.env
|
vmenv := self.env
|
||||||
var ref vm.ContextRef
|
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)
|
//addr := contract.Address()
|
||||||
|
ret, err, ref = vmenv.Create(sender, self.msg.Data(), self.gas, self.gasPrice, self.value)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
dataGas := big.NewInt(int64(len(ret)))
|
dataGas := big.NewInt(int64(len(ret)))
|
||||||
dataGas.Mul(dataGas, vm.GasCreateByte)
|
dataGas.Mul(dataGas, vm.GasCreateByte)
|
||||||
@ -230,7 +231,7 @@ func (self *StateTransition) refundGas() {
|
|||||||
for addr, ref := range self.state.Refunds() {
|
for addr, ref := range self.state.Refunds() {
|
||||||
refund := common.BigMin(uhalf, ref)
|
refund := common.BigMin(uhalf, ref)
|
||||||
self.gas.Add(self.gas, refund)
|
self.gas.Add(self.gas, refund)
|
||||||
self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice()))
|
self.state.AddBalance(common.StringToAddress(addr), refund.Mul(refund, self.msg.GasPrice()))
|
||||||
}
|
}
|
||||||
|
|
||||||
coinbase.RefundGas(self.gas, self.msg.GasPrice())
|
coinbase.RefundGas(self.gas, self.msg.GasPrice())
|
||||||
@ -242,10 +243,13 @@ func (self *StateTransition) gasUsed() *big.Int {
|
|||||||
|
|
||||||
// Converts an message in to a state object
|
// Converts an message in to a state object
|
||||||
func makeContract(msg Message, state *state.StateDB) *state.StateObject {
|
func makeContract(msg Message, state *state.StateDB) *state.StateObject {
|
||||||
addr := AddressFromMessage(msg)
|
/*
|
||||||
|
addr := AddressFromMessage(msg)
|
||||||
|
|
||||||
contract := state.GetOrNewStateObject(addr)
|
contract := state.GetOrNewStateObject(addr)
|
||||||
contract.SetInitCode(msg.Data())
|
contract.SetInitCode(msg.Data())
|
||||||
|
|
||||||
return contract
|
return contract
|
||||||
|
*/
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -47,9 +47,9 @@ func bloom9(b []byte) *big.Int {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func BloomLookup(bin, topic []byte) bool {
|
func BloomLookup(bin Bloom, topic common.Hash) bool {
|
||||||
bloom := common.BigD(bin)
|
bloom := bin.Big()
|
||||||
cmp := bloom9(crypto.Sha3(topic))
|
cmp := bloom9(crypto.Sha3(topic[:]))
|
||||||
|
|
||||||
return bloom.And(bloom, cmp).Cmp(cmp) == 0
|
return bloom.And(bloom, cmp).Cmp(cmp) == 0
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import "math/big"
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
)
|
||||||
|
|
||||||
type BlockProcessor interface {
|
type BlockProcessor interface {
|
||||||
Process(*Block) (*big.Int, error)
|
Process(*Block) (*big.Int, error)
|
||||||
@ -24,3 +28,7 @@ func (b *Bloom) SetBytes(d []byte) {
|
|||||||
b[i] = b[i]
|
b[i] = b[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b Bloom) Big() *big.Int {
|
||||||
|
return common.Bytes2Big(b[:])
|
||||||
|
}
|
||||||
|
@ -28,24 +28,24 @@ func NewEnv(state *state.StateDB, chain *ChainManager, msg Message, block *types
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Origin() common.Address { return self.msg.From() }
|
func (self *VMEnv) Origin() common.Address { return self.msg.From() }
|
||||||
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
|
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
|
||||||
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
|
func (self *VMEnv) Coinbase() common.Address { return self.block.Coinbase() }
|
||||||
func (self *VMEnv) Time() int64 { return self.block.Time() }
|
func (self *VMEnv) Time() int64 { return self.block.Time() }
|
||||||
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
|
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
|
||||||
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
|
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
|
||||||
func (self *VMEnv) Value() *big.Int { return self.msg.Value() }
|
func (self *VMEnv) Value() *big.Int { return self.msg.Value() }
|
||||||
func (self *VMEnv) State() *state.StateDB { return self.state }
|
func (self *VMEnv) State() *state.StateDB { return self.state }
|
||||||
func (self *VMEnv) Depth() int { return self.depth }
|
func (self *VMEnv) Depth() int { return self.depth }
|
||||||
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
||||||
func (self *VMEnv) VmType() vm.Type { return self.typ }
|
func (self *VMEnv) VmType() vm.Type { return self.typ }
|
||||||
func (self *VMEnv) SetVmType(t vm.Type) { self.typ = t }
|
func (self *VMEnv) SetVmType(t vm.Type) { self.typ = t }
|
||||||
func (self *VMEnv) GetHash(n uint64) []byte {
|
func (self *VMEnv) GetHash(n uint64) common.Hash {
|
||||||
if block := self.chain.GetBlockByNumber(n); block != nil {
|
if block := self.chain.GetBlockByNumber(n); block != nil {
|
||||||
return block.Hash()
|
return block.Hash()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return common.Hash{}
|
||||||
}
|
}
|
||||||
func (self *VMEnv) AddLog(log state.Log) {
|
func (self *VMEnv) AddLog(log state.Log) {
|
||||||
self.state.AddLog(log)
|
self.state.AddLog(log)
|
||||||
@ -54,20 +54,21 @@ func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
|
|||||||
return vm.Transfer(from, to, amount)
|
return vm.Transfer(from, to, amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *Execution {
|
func (self *VMEnv) vm(addr *common.Address, 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.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) Call(me vm.ContextRef, addr common.Address, 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.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *VMEnv) CallCode(me vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
exe := self.vm(me.Address(), data, gas, price, value)
|
maddr := me.Address()
|
||||||
|
exe := self.vm(&maddr, data, gas, price, value)
|
||||||
return exe.Call(addr, me)
|
return exe.Call(addr, me)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Create(me vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
|
func (self *VMEnv) Create(me vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
|
||||||
exe := self.vm(common.Address{}, data, gas, price, value)
|
exe := self.vm(nil, data, gas, price, value)
|
||||||
return exe.Create(me)
|
return exe.Create(me)
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/crypto/ecies"
|
"github.com/ethereum/go-ethereum/crypto/ecies"
|
||||||
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
||||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"golang.org/x/crypto/pbkdf2"
|
"golang.org/x/crypto/pbkdf2"
|
||||||
"golang.org/x/crypto/ripemd160"
|
"golang.org/x/crypto/ripemd160"
|
||||||
)
|
)
|
||||||
@ -47,8 +48,10 @@ func Sha3Hash(data ...[]byte) (h common.Hash) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates an ethereum address given the bytes and the nonce
|
// Creates an ethereum address given the bytes and the nonce
|
||||||
func CreateAddress(b []byte, nonce uint64) []byte {
|
func CreateAddress(b common.Address, nonce uint64) common.Address {
|
||||||
return Sha3(common.NewValue([]interface{}{b, nonce}).Encode())[12:]
|
data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
|
||||||
|
return common.BytesToAddress(Sha3(data)[12:])
|
||||||
|
//return Sha3(common.NewValue([]interface{}{b, nonce}).Encode())[12:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func Sha256(data []byte) []byte {
|
func Sha256(data []byte) []byte {
|
||||||
|
@ -18,7 +18,7 @@ type Context struct {
|
|||||||
self ContextRef
|
self ContextRef
|
||||||
|
|
||||||
Code []byte
|
Code []byte
|
||||||
CodeAddr common.Address
|
CodeAddr *common.Address
|
||||||
|
|
||||||
value, Gas, UsedGas, Price *big.Int
|
value, Gas, UsedGas, Price *big.Int
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ func (self *Context) SetCode(code []byte) {
|
|||||||
self.Code = code
|
self.Code = code
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Context) SetCallCode(addr common.Address, code []byte) {
|
func (self *Context) SetCallCode(addr *common.Address, code []byte) {
|
||||||
self.Code = code
|
self.Code = code
|
||||||
self.CodeAddr = addr
|
self.CodeAddr = addr
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,8 @@ type Environment interface {
|
|||||||
|
|
||||||
Origin() common.Address
|
Origin() common.Address
|
||||||
BlockNumber() *big.Int
|
BlockNumber() *big.Int
|
||||||
GetHash(n uint64) []byte
|
GetHash(n uint64) common.Hash
|
||||||
Coinbase() []byte
|
Coinbase() common.Address
|
||||||
Time() int64
|
Time() int64
|
||||||
Difficulty() *big.Int
|
Difficulty() *big.Int
|
||||||
GasLimit() *big.Int
|
GasLimit() *big.Int
|
||||||
@ -38,7 +38,7 @@ type Account interface {
|
|||||||
SubBalance(amount *big.Int)
|
SubBalance(amount *big.Int)
|
||||||
AddBalance(amount *big.Int)
|
AddBalance(amount *big.Int)
|
||||||
Balance() *big.Int
|
Balance() *big.Int
|
||||||
Address() []byte
|
Address() common.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// generic transfer method
|
// generic transfer method
|
||||||
|
10
vm/vm.go
10
vm/vm.go
@ -58,8 +58,10 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if p := Precompiled[context.CodeAddr.Str()]; p != nil {
|
if context.CodeAddr != nil {
|
||||||
return self.RunPrecompiled(p, callData, context)
|
if p := Precompiled[context.CodeAddr.Str()]; p != nil {
|
||||||
|
return self.RunPrecompiled(p, callData, context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -500,7 +502,7 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
|||||||
|
|
||||||
n := new(big.Int).Sub(self.env.BlockNumber(), common.Big257)
|
n := new(big.Int).Sub(self.env.BlockNumber(), common.Big257)
|
||||||
if num.Cmp(n) > 0 && num.Cmp(self.env.BlockNumber()) < 0 {
|
if num.Cmp(n) > 0 && num.Cmp(self.env.BlockNumber()) < 0 {
|
||||||
stack.push(common.BigD(self.env.GetHash(num.Uint64())))
|
stack.push(self.env.GetHash(num.Uint64()).Big())
|
||||||
} else {
|
} else {
|
||||||
stack.push(common.Big0)
|
stack.push(common.Big0)
|
||||||
}
|
}
|
||||||
@ -509,7 +511,7 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
|||||||
case COINBASE:
|
case COINBASE:
|
||||||
coinbase := self.env.Coinbase()
|
coinbase := self.env.Coinbase()
|
||||||
|
|
||||||
stack.push(common.BigD(coinbase))
|
stack.push(coinbase.Big())
|
||||||
|
|
||||||
self.Printf(" => 0x%x", coinbase)
|
self.Printf(" => 0x%x", coinbase)
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
Loading…
Reference in New Issue
Block a user