Split code for contracts

This commit is contained in:
obscuren 2014-04-09 12:27:54 -04:00
parent 4f2e9c2640
commit e09f0a5f2c
5 changed files with 33 additions and 20 deletions

View File

@ -12,18 +12,18 @@ type Callee interface {
Address() []byte
}
type ClosureBody interface {
type Reference interface {
Callee
ethutil.RlpEncodable
GetMem(*big.Int) *ethutil.Value
SetMem(*big.Int, *ethutil.Value)
GetInstr(*big.Int) *ethutil.Value
}
// Basic inline closure object which implement the 'closure' interface
type Closure struct {
callee Callee
object ClosureBody
object Reference
Script []byte
State *State
Gas *big.Int
@ -33,8 +33,8 @@ type Closure struct {
}
// Create a new closure for the given data items
func NewClosure(callee Callee, object ClosureBody, state *State, gas, val *big.Int) *Closure {
return &Closure{callee, object, state, gas, val, nil}
func NewClosure(callee Callee, object Reference, script []byte, state *State, gas, val *big.Int) *Closure {
return &Closure{callee, object, script, state, gas, val, nil}
}
// Retuns the x element in data slice
@ -47,8 +47,14 @@ func (c *Closure) GetMem(x *big.Int) *ethutil.Value {
return m
}
func (c *Closure) GetInstr(x *big.Int) *ethutil.Value {
return c.object.GetInstr(x)
func (c *Closure) Get(x *big.Int) *ethutil.Value {
return c.Gets(x, big.NewInt(1))
}
func (c *Closure) Gets(x, y *big.Int) *ethutil.Value {
partial := c.Script[x.Int64() : x.Int64()+y.Int64()]
return ethutil.NewValue(partial)
}
func (c *Closure) SetMem(x *big.Int, val *ethutil.Value) {
@ -86,7 +92,7 @@ func (c *Closure) ReturnGas(gas *big.Int, state *State) {
c.Gas.Add(c.Gas, gas)
}
func (c *Closure) Object() ClosureBody {
func (c *Closure) Object() Reference {
return c.object
}

View File

@ -12,6 +12,7 @@ type Contract struct {
state *State
address []byte
script []byte
initScript []byte
}
func NewContract(address []byte, Amount *big.Int, root []byte) *Contract {
@ -88,12 +89,17 @@ func MakeContract(tx *Transaction, state *State) *Contract {
value := tx.Value
contract := NewContract(addr, value, []byte(""))
state.trie.Update(string(addr), string(contract.RlpEncode()))
contract.script = tx.Data
contract.initScript = tx.Init
/*
for i, val := range tx.Data {
if len(val) > 0 {
bytNum := ethutil.BigToBytes(big.NewInt(int64(i)), 256)
contract.state.trie.Update(string(bytNum), string(ethutil.Encode(val)))
}
}
*/
state.trie.Update(string(addr), string(contract.RlpEncode()))
return contract

View File

@ -311,7 +311,7 @@ func (sm *StateManager) ProcessContract(contract *Contract, tx *Transaction, blo
}()
caller := sm.procState.GetAccount(tx.Sender())
closure := NewClosure(caller, contract, sm.procState, tx.Gas, tx.Value)
closure := NewClosure(caller, contract, contract.script, sm.procState, tx.Gas, tx.Value)
vm := NewVm(sm.procState, RuntimeVars{
origin: caller.Address(),
blockNumber: block.BlockInfo().Number,

View File

@ -72,7 +72,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
for {
step++
// Get the memory location of pc
val := closure.GetInstr(pc)
val := closure.Get(pc)
// Get the opcode (it must be an opcode!)
op := OpCode(val.Uint())
if ethutil.Config.Debug {
@ -357,7 +357,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
// Fetch the contract which will serve as the closure body
contract := vm.state.GetContract(addr.Bytes())
// Create a new callable closure
closure := NewClosure(closure, contract, vm.state, gas, value)
closure := NewClosure(closure, contract, contract.script, vm.state, gas, value)
// Executer the closure and get the return value (if any)
ret := closure.Call(vm, args)

View File

@ -112,7 +112,8 @@ func TestRun4(t *testing.T) {
// Contract addr as test address
account := NewAccount(ContractAddr, big.NewInt(10000000))
callerClosure := NewClosure(account, MakeContract(callerTx, state), state, big.NewInt(1000000000), new(big.Int))
c := MakeContract(callerTx, state)
callerClosure := NewClosure(account, c, c.script, state, big.NewInt(1000000000), new(big.Int))
vm := NewVm(state, RuntimeVars{
origin: account.Address(),