Upped version number

This commit is contained in:
obscuren 2014-04-27 16:50:44 +02:00
parent 05d2d8f27d
commit 16e52327a4
9 changed files with 129 additions and 12 deletions

@ -6,7 +6,7 @@ Ethereum
Ethereum Go Development package (C) Jeffrey Wilcke
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
individual package for more information.

@ -8,21 +8,24 @@ import (
)
type Callee interface {
ReturnGas(*big.Int, *big.Int, *State)
Address() []byte
}
type Reference interface {
Callee
ethutil.RlpEncodable
}
type ClosureRef interface {
ReturnGas(*big.Int, *big.Int, *State)
Address() []byte
GetMem(*big.Int) *ethutil.Value
SetMem(*big.Int, *ethutil.Value)
N() *big.Int
}
// Basic inline closure object which implement the 'closure' interface
type Closure struct {
callee Callee
object Reference
callee ClosureRef
object ClosureRef
Script []byte
State *State
@ -34,7 +37,7 @@ type Closure struct {
}
// 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}
// 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)
}
func (c *Closure) Object() Reference {
func (c *Closure) Object() ClosureRef {
return c.object
}
func (c *Closure) Callee() Callee {
func (c *Closure) Callee() ClosureRef {
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) {
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() {
fmt.Println("### stack ###")
if len(st.data) > 0 {

@ -47,6 +47,7 @@ func (s *State) Purge() int {
return s.trie.NewIterator().Purge()
}
// XXX Deprecated
func (s *State) GetContract(addr []byte) *StateObject {
data := s.trie.Get(string(addr))
if data == "" {
@ -68,6 +69,32 @@ func (s *State) GetContract(addr []byte) *StateObject {
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) {
data := s.trie.Get(string(addr))
if data == "" {
@ -97,6 +124,7 @@ const (
UnknownTy
)
/*
// Returns the object stored at key and the type stored at key
// Returns nil if nothing is stored
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
}
*/
// Updates any given state object
func (s *State) UpdateStateObject(object *StateObject) {

@ -65,6 +65,10 @@ func (c *StateObject) State() *State {
return c.state
}
func (c *StateObject) N() *big.Int {
return big.NewInt(int64(c.Nonce))
}
func (c *StateObject) Addr(addr []byte) *ethutil.Value {
return ethutil.NewValueFromBytes([]byte(c.state.trie.Get(string(addr))))
}

@ -20,6 +20,17 @@ var (
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 {
txPool *TxPool
// Stack for processing contracts
@ -125,7 +136,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
case oBALANCE:
useGas(GasBalance)
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:
useGas(GasCall)
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())))
// 0x60 range
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:
require(7)
// Closure addr
@ -438,7 +487,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
// Prepay for the gas
// If gas is set to 0 use all remaining gas for the next call
if gas.Cmp(big.NewInt(0)) == 0 {
gas = closure.Gas
// Copy
gas = new(big.Int).Set(closure.Gas)
}
closure.Gas.Sub(closure.Gas, gas)
// Create a new callable closure

@ -50,3 +50,11 @@ func BigCopy(src *big.Int) (ret *big.Int) {
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)
Big2 = big.NewInt(1)
Big0 = big.NewInt(0)
Big32 = big.NewInt(32)
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.SetClientString("/Ethereum(G)")
}