forked from cerc-io/plugeth
Split code for contracts
This commit is contained in:
parent
4f2e9c2640
commit
e09f0a5f2c
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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(),
|
||||||
|
Loading…
Reference in New Issue
Block a user