Upped version number
This commit is contained in:
parent
05d2d8f27d
commit
16e52327a4
|
@ -6,7 +6,7 @@ Ethereum
|
||||||
Ethereum Go Development package (C) Jeffrey Wilcke
|
Ethereum Go Development package (C) Jeffrey Wilcke
|
||||||
|
|
||||||
Ethereum is currently in its testing phase. The current state is "Proof
|
Ethereum is currently in its testing phase. The current state is "Proof
|
||||||
of Concept 3.5". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)).
|
of Concept 5.0". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)).
|
||||||
|
|
||||||
Ethereum Go is split up in several sub packages Please refer to each
|
Ethereum Go is split up in several sub packages Please refer to each
|
||||||
individual package for more information.
|
individual package for more information.
|
||||||
|
|
|
@ -8,21 +8,24 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Callee interface {
|
type Callee interface {
|
||||||
ReturnGas(*big.Int, *big.Int, *State)
|
|
||||||
Address() []byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Reference interface {
|
type Reference interface {
|
||||||
Callee
|
Callee
|
||||||
ethutil.RlpEncodable
|
}
|
||||||
|
|
||||||
|
type ClosureRef interface {
|
||||||
|
ReturnGas(*big.Int, *big.Int, *State)
|
||||||
|
Address() []byte
|
||||||
GetMem(*big.Int) *ethutil.Value
|
GetMem(*big.Int) *ethutil.Value
|
||||||
SetMem(*big.Int, *ethutil.Value)
|
SetMem(*big.Int, *ethutil.Value)
|
||||||
|
N() *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basic inline closure object which implement the 'closure' interface
|
// Basic inline closure object which implement the 'closure' interface
|
||||||
type Closure struct {
|
type Closure struct {
|
||||||
callee Callee
|
callee ClosureRef
|
||||||
object Reference
|
object ClosureRef
|
||||||
Script []byte
|
Script []byte
|
||||||
State *State
|
State *State
|
||||||
|
|
||||||
|
@ -34,7 +37,7 @@ type Closure struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new closure for the given data items
|
// Create a new closure for the given data items
|
||||||
func NewClosure(callee Callee, object Reference, script []byte, state *State, gas, price, val *big.Int) *Closure {
|
func NewClosure(callee, object ClosureRef, script []byte, state *State, gas, price, val *big.Int) *Closure {
|
||||||
c := &Closure{callee: callee, object: object, Script: script, State: state, Args: nil}
|
c := &Closure{callee: callee, object: object, Script: script, State: state, Args: nil}
|
||||||
|
|
||||||
// In most cases gas, price and value are pointers to transaction objects
|
// In most cases gas, price and value are pointers to transaction objects
|
||||||
|
@ -105,10 +108,14 @@ func (c *Closure) ReturnGas(gas, price *big.Int, state *State) {
|
||||||
c.Gas.Add(c.Gas, gas)
|
c.Gas.Add(c.Gas, gas)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Closure) Object() Reference {
|
func (c *Closure) Object() ClosureRef {
|
||||||
return c.object
|
return c.object
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Closure) Callee() Callee {
|
func (c *Closure) Callee() ClosureRef {
|
||||||
return c.callee
|
return c.callee
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Closure) N() *big.Int {
|
||||||
|
return c.object.N()
|
||||||
|
}
|
||||||
|
|
|
@ -67,6 +67,18 @@ func (st *Stack) Peekn() (*big.Int, *big.Int) {
|
||||||
func (st *Stack) Push(d *big.Int) {
|
func (st *Stack) Push(d *big.Int) {
|
||||||
st.data = append(st.data, d)
|
st.data = append(st.data, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (st *Stack) Get(amount *big.Int) []*big.Int {
|
||||||
|
// offset + size <= len(data)
|
||||||
|
length := big.NewInt(int64(len(st.data)))
|
||||||
|
if amount.Cmp(length) <= 0 {
|
||||||
|
start := new(big.Int).Sub(length, amount)
|
||||||
|
return st.data[start.Int64():length.Int64()]
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (st *Stack) Print() {
|
func (st *Stack) Print() {
|
||||||
fmt.Println("### stack ###")
|
fmt.Println("### stack ###")
|
||||||
if len(st.data) > 0 {
|
if len(st.data) > 0 {
|
||||||
|
|
|
@ -47,6 +47,7 @@ func (s *State) Purge() int {
|
||||||
return s.trie.NewIterator().Purge()
|
return s.trie.NewIterator().Purge()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX Deprecated
|
||||||
func (s *State) GetContract(addr []byte) *StateObject {
|
func (s *State) GetContract(addr []byte) *StateObject {
|
||||||
data := s.trie.Get(string(addr))
|
data := s.trie.Get(string(addr))
|
||||||
if data == "" {
|
if data == "" {
|
||||||
|
@ -68,6 +69,32 @@ func (s *State) GetContract(addr []byte) *StateObject {
|
||||||
return contract
|
return contract
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *State) GetStateObject(addr []byte) *StateObject {
|
||||||
|
data := s.trie.Get(string(addr))
|
||||||
|
if data == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
stateObject := NewStateObjectFromBytes(addr, []byte(data))
|
||||||
|
|
||||||
|
// Check if there's a cached state for this contract
|
||||||
|
cachedStateObject := s.states[string(addr)]
|
||||||
|
if cachedStateObject != nil {
|
||||||
|
stateObject.state = cachedStateObject
|
||||||
|
} else {
|
||||||
|
// If it isn't cached, cache the state
|
||||||
|
s.states[string(addr)] = stateObject.state
|
||||||
|
}
|
||||||
|
|
||||||
|
return stateObject
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *State) SetStateObject(stateObject *StateObject) {
|
||||||
|
s.states[string(stateObject.address)] = stateObject.state
|
||||||
|
|
||||||
|
s.UpdateStateObject(stateObject)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *State) GetAccount(addr []byte) (account *StateObject) {
|
func (s *State) GetAccount(addr []byte) (account *StateObject) {
|
||||||
data := s.trie.Get(string(addr))
|
data := s.trie.Get(string(addr))
|
||||||
if data == "" {
|
if data == "" {
|
||||||
|
@ -97,6 +124,7 @@ const (
|
||||||
UnknownTy
|
UnknownTy
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
// Returns the object stored at key and the type stored at key
|
// Returns the object stored at key and the type stored at key
|
||||||
// Returns nil if nothing is stored
|
// Returns nil if nothing is stored
|
||||||
func (s *State) GetStateObject(key []byte) (*ethutil.Value, ObjType) {
|
func (s *State) GetStateObject(key []byte) (*ethutil.Value, ObjType) {
|
||||||
|
@ -124,6 +152,7 @@ func (s *State) GetStateObject(key []byte) (*ethutil.Value, ObjType) {
|
||||||
|
|
||||||
return val, typ
|
return val, typ
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Updates any given state object
|
// Updates any given state object
|
||||||
func (s *State) UpdateStateObject(object *StateObject) {
|
func (s *State) UpdateStateObject(object *StateObject) {
|
||||||
|
|
|
@ -65,6 +65,10 @@ func (c *StateObject) State() *State {
|
||||||
return c.state
|
return c.state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *StateObject) N() *big.Int {
|
||||||
|
return big.NewInt(int64(c.Nonce))
|
||||||
|
}
|
||||||
|
|
||||||
func (c *StateObject) Addr(addr []byte) *ethutil.Value {
|
func (c *StateObject) Addr(addr []byte) *ethutil.Value {
|
||||||
return ethutil.NewValueFromBytes([]byte(c.state.trie.Get(string(addr))))
|
return ethutil.NewValueFromBytes([]byte(c.state.trie.Get(string(addr))))
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,17 @@ var (
|
||||||
GasMemory = big.NewInt(1)
|
GasMemory = big.NewInt(1)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func CalculateTxGas(initSize, scriptSize *big.Int) *big.Int {
|
||||||
|
totalGas := new(big.Int)
|
||||||
|
totalGas.Add(totalGas, GasCreate)
|
||||||
|
|
||||||
|
txTotalBytes := new(big.Int).Add(initSize, scriptSize)
|
||||||
|
txTotalBytes.Div(txTotalBytes, ethutil.Big32)
|
||||||
|
totalGas.Add(totalGas, new(big.Int).Mul(txTotalBytes, GasSStore))
|
||||||
|
|
||||||
|
return totalGas
|
||||||
|
}
|
||||||
|
|
||||||
type Vm struct {
|
type Vm struct {
|
||||||
txPool *TxPool
|
txPool *TxPool
|
||||||
// Stack for processing contracts
|
// Stack for processing contracts
|
||||||
|
@ -125,7 +136,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
case oBALANCE:
|
case oBALANCE:
|
||||||
useGas(GasBalance)
|
useGas(GasBalance)
|
||||||
case oCREATE:
|
case oCREATE:
|
||||||
useGas(GasCreate)
|
require(3)
|
||||||
|
|
||||||
|
args := stack.Get(big.NewInt(3))
|
||||||
|
initSize := new(big.Int).Add(args[1], args[0])
|
||||||
|
|
||||||
|
useGas(CalculateTxGas(initSize, ethutil.Big0))
|
||||||
case oCALL:
|
case oCALL:
|
||||||
useGas(GasCall)
|
useGas(GasCall)
|
||||||
case oMLOAD, oMSIZE, oMSTORE8, oMSTORE:
|
case oMLOAD, oMSIZE, oMSTORE8, oMSTORE:
|
||||||
|
@ -413,6 +429,39 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
stack.Push(big.NewInt(int64(mem.Len())))
|
stack.Push(big.NewInt(int64(mem.Len())))
|
||||||
// 0x60 range
|
// 0x60 range
|
||||||
case oCREATE:
|
case oCREATE:
|
||||||
|
require(3)
|
||||||
|
|
||||||
|
value := stack.Pop()
|
||||||
|
size, offset := stack.Popn()
|
||||||
|
|
||||||
|
// Generate a new address
|
||||||
|
addr := ethutil.CreateAddress(closure.callee.Address(), closure.callee.N())
|
||||||
|
// Create a new contract
|
||||||
|
contract := NewContract(addr, value, []byte(""))
|
||||||
|
// Set the init script
|
||||||
|
contract.initScript = mem.Get(offset.Int64(), size.Int64())
|
||||||
|
// Transfer all remaining gas to the new
|
||||||
|
// contract so it may run the init script
|
||||||
|
gas := new(big.Int).Set(closure.Gas)
|
||||||
|
closure.Gas.Sub(closure.Gas, gas)
|
||||||
|
// Create the closure
|
||||||
|
closure := NewClosure(closure.callee,
|
||||||
|
closure.Object(),
|
||||||
|
contract.initScript,
|
||||||
|
vm.state,
|
||||||
|
gas,
|
||||||
|
closure.Price,
|
||||||
|
value)
|
||||||
|
// Call the closure and set the return value as
|
||||||
|
// main script.
|
||||||
|
closure.Script, err = closure.Call(vm, nil, hook)
|
||||||
|
if err != nil {
|
||||||
|
stack.Push(ethutil.BigFalse)
|
||||||
|
} else {
|
||||||
|
stack.Push(ethutil.BigD(addr))
|
||||||
|
|
||||||
|
vm.state.SetStateObject(contract)
|
||||||
|
}
|
||||||
case oCALL:
|
case oCALL:
|
||||||
require(7)
|
require(7)
|
||||||
// Closure addr
|
// Closure addr
|
||||||
|
@ -438,7 +487,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
// Prepay for the gas
|
// Prepay for the gas
|
||||||
// If gas is set to 0 use all remaining gas for the next call
|
// If gas is set to 0 use all remaining gas for the next call
|
||||||
if gas.Cmp(big.NewInt(0)) == 0 {
|
if gas.Cmp(big.NewInt(0)) == 0 {
|
||||||
gas = closure.Gas
|
// Copy
|
||||||
|
gas = new(big.Int).Set(closure.Gas)
|
||||||
}
|
}
|
||||||
closure.Gas.Sub(closure.Gas, gas)
|
closure.Gas.Sub(closure.Gas, gas)
|
||||||
// Create a new callable closure
|
// Create a new callable closure
|
||||||
|
|
|
@ -50,3 +50,11 @@ func BigCopy(src *big.Int) (ret *big.Int) {
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BigMax(x, y *big.Int) *big.Int {
|
||||||
|
if x.Cmp(y) <= 0 {
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
|
|
@ -38,5 +38,12 @@ var (
|
||||||
Big1 = big.NewInt(1)
|
Big1 = big.NewInt(1)
|
||||||
Big2 = big.NewInt(1)
|
Big2 = big.NewInt(1)
|
||||||
Big0 = big.NewInt(0)
|
Big0 = big.NewInt(0)
|
||||||
|
Big32 = big.NewInt(32)
|
||||||
Big256 = big.NewInt(0xff)
|
Big256 = big.NewInt(0xff)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func CreateAddress(b []byte, nonce *big.Int) []byte {
|
||||||
|
addrBytes := append(b, nonce.Bytes()...)
|
||||||
|
|
||||||
|
return Sha3Bin(addrBytes)[12:]
|
||||||
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func ReadConfig(base string) *config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Config = &config{ExecPath: path, Debug: true, Ver: "0.3.1"}
|
Config = &config{ExecPath: path, Debug: true, Ver: "0.5"}
|
||||||
Config.Log = NewLogger(LogFile|LogStd, LogLevelDebug)
|
Config.Log = NewLogger(LogFile|LogStd, LogLevelDebug)
|
||||||
Config.SetClientString("/Ethereum(G)")
|
Config.SetClientString("/Ethereum(G)")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue