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 Address() []byte
} }
type ClosureBody interface { type Reference interface {
Callee Callee
ethutil.RlpEncodable ethutil.RlpEncodable
GetMem(*big.Int) *ethutil.Value GetMem(*big.Int) *ethutil.Value
SetMem(*big.Int, *ethutil.Value) SetMem(*big.Int, *ethutil.Value)
GetInstr(*big.Int) *ethutil.Value
} }
// 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 Callee
object ClosureBody object Reference
Script []byte
State *State State *State
Gas *big.Int Gas *big.Int
@ -33,8 +33,8 @@ 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 ClosureBody, state *State, gas, val *big.Int) *Closure { func NewClosure(callee Callee, object Reference, script []byte, state *State, gas, val *big.Int) *Closure {
return &Closure{callee, object, state, gas, val, nil} return &Closure{callee, object, script, state, gas, val, nil}
} }
// Retuns the x element in data slice // Retuns the x element in data slice
@ -47,8 +47,14 @@ func (c *Closure) GetMem(x *big.Int) *ethutil.Value {
return m return m
} }
func (c *Closure) GetInstr(x *big.Int) *ethutil.Value { func (c *Closure) Get(x *big.Int) *ethutil.Value {
return c.object.GetInstr(x) 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) { 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) c.Gas.Add(c.Gas, gas)
} }
func (c *Closure) Object() ClosureBody { func (c *Closure) Object() Reference {
return c.object return c.object
} }

View File

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

View File

@ -311,7 +311,7 @@ func (sm *StateManager) ProcessContract(contract *Contract, tx *Transaction, blo
}() }()
caller := sm.procState.GetAccount(tx.Sender()) 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{ vm := NewVm(sm.procState, RuntimeVars{
origin: caller.Address(), origin: caller.Address(),
blockNumber: block.BlockInfo().Number, blockNumber: block.BlockInfo().Number,

View File

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

View File

@ -112,7 +112,8 @@ func TestRun4(t *testing.T) {
// Contract addr as test address // Contract addr as test address
account := NewAccount(ContractAddr, big.NewInt(10000000)) 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{ vm := NewVm(state, RuntimeVars{
origin: account.Address(), origin: account.Address(),