Renamed
This commit is contained in:
parent
ca747f2688
commit
116516158d
@ -52,7 +52,7 @@ func (c *Closure) Get(x *big.Int) *ethutil.Value {
|
||||
}
|
||||
|
||||
func (c *Closure) Gets(x, y *big.Int) *ethutil.Value {
|
||||
if x.Int64() > int64(len(c.Script)) || y.Int64() > int64(len(c.Script)) {
|
||||
if x.Int64() >= int64(len(c.Script)) || y.Int64() >= int64(len(c.Script)) {
|
||||
return ethutil.NewValue(0)
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ func (c *Closure) Address() []byte {
|
||||
return c.object.Address()
|
||||
}
|
||||
|
||||
type DebugHook func(op OpCode)
|
||||
type DebugHook func(op OpCode, mem *Memory, stack *Stack)
|
||||
|
||||
func (c *Closure) Call(vm *Vm, args []byte, hook DebugHook) []byte {
|
||||
c.Args = args
|
||||
|
@ -69,6 +69,14 @@ func (c *Contract) Address() []byte {
|
||||
return c.address
|
||||
}
|
||||
|
||||
func (c *Contract) Script() []byte {
|
||||
return c.script
|
||||
}
|
||||
|
||||
func (c *Contract) Init() []byte {
|
||||
return c.initScript
|
||||
}
|
||||
|
||||
func (c *Contract) RlpEncode() []byte {
|
||||
return ethutil.Encode([]interface{}{c.Amount, c.Nonce, c.state.trie.Root, c.script, c.initScript})
|
||||
}
|
||||
|
@ -173,6 +173,10 @@ func NewStack() *Stack {
|
||||
return &Stack{}
|
||||
}
|
||||
|
||||
func (st *Stack) Data() []*big.Int {
|
||||
return st.data
|
||||
}
|
||||
|
||||
func (st *Stack) Pop() *big.Int {
|
||||
str := st.data[len(st.data)-1]
|
||||
|
||||
@ -246,6 +250,10 @@ func (m *Memory) Len() int {
|
||||
return len(m.store)
|
||||
}
|
||||
|
||||
func (m *Memory) Data() []byte {
|
||||
return m.store
|
||||
}
|
||||
|
||||
func (m *Memory) Print() {
|
||||
fmt.Printf("### mem %d bytes ###\n", len(m.store))
|
||||
if len(m.store) > 0 {
|
||||
|
@ -318,14 +318,14 @@ func (sm *StateManager) ProcessContract(contract *Contract, tx *Transaction, blo
|
||||
caller := sm.procState.GetAccount(tx.Sender())
|
||||
closure := NewClosure(caller, contract, contract.script, sm.procState, tx.Gas, tx.Value)
|
||||
vm := NewVm(sm.procState, RuntimeVars{
|
||||
origin: caller.Address(),
|
||||
blockNumber: block.BlockInfo().Number,
|
||||
prevHash: block.PrevHash,
|
||||
coinbase: block.Coinbase,
|
||||
time: block.Time,
|
||||
diff: block.Difficulty,
|
||||
Origin: caller.Address(),
|
||||
BlockNumber: block.BlockInfo().Number,
|
||||
PrevHash: block.PrevHash,
|
||||
Coinbase: block.Coinbase,
|
||||
Time: block.Time,
|
||||
Diff: block.Difficulty,
|
||||
// XXX Tx data? Could be just an argument to the closure instead
|
||||
txData: nil,
|
||||
TxData: nil,
|
||||
})
|
||||
closure.Call(vm, nil, nil)
|
||||
|
||||
|
@ -2,7 +2,7 @@ package ethchain
|
||||
|
||||
import (
|
||||
_ "bytes"
|
||||
_ "fmt"
|
||||
"fmt"
|
||||
"github.com/ethereum/eth-go/ethutil"
|
||||
_ "github.com/obscuren/secp256k1-go"
|
||||
_ "math"
|
||||
@ -33,13 +33,13 @@ type Vm struct {
|
||||
}
|
||||
|
||||
type RuntimeVars struct {
|
||||
origin []byte
|
||||
blockNumber uint64
|
||||
prevHash []byte
|
||||
coinbase []byte
|
||||
time int64
|
||||
diff *big.Int
|
||||
txData []string
|
||||
Origin []byte
|
||||
BlockNumber uint64
|
||||
PrevHash []byte
|
||||
Coinbase []byte
|
||||
Time int64
|
||||
Diff *big.Int
|
||||
TxData []string
|
||||
}
|
||||
|
||||
func NewVm(state *State, vars RuntimeVars) *Vm {
|
||||
@ -65,9 +65,11 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) []byte {
|
||||
// The base for all big integer arithmetic
|
||||
base := new(big.Int)
|
||||
|
||||
if ethutil.Config.Debug {
|
||||
ethutil.Config.Log.Debugf("# op\n")
|
||||
}
|
||||
/*
|
||||
if ethutil.Config.Debug {
|
||||
ethutil.Config.Log.Debugf("# op\n")
|
||||
}
|
||||
*/
|
||||
|
||||
for {
|
||||
step++
|
||||
@ -75,9 +77,11 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) []byte {
|
||||
val := closure.Get(pc)
|
||||
// Get the opcode (it must be an opcode!)
|
||||
op := OpCode(val.Uint())
|
||||
if ethutil.Config.Debug {
|
||||
ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
|
||||
}
|
||||
/*
|
||||
if ethutil.Config.Debug {
|
||||
ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO Get each instruction cost properly
|
||||
gas := new(big.Int)
|
||||
@ -270,7 +274,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) []byte {
|
||||
case oBALANCE:
|
||||
stack.Push(closure.Value)
|
||||
case oORIGIN:
|
||||
stack.Push(ethutil.BigD(vm.vars.origin))
|
||||
stack.Push(ethutil.BigD(vm.vars.Origin))
|
||||
case oCALLER:
|
||||
stack.Push(ethutil.BigD(closure.Callee().Address()))
|
||||
case oCALLVALUE:
|
||||
@ -286,15 +290,15 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) []byte {
|
||||
|
||||
// 0x40 range
|
||||
case oPREVHASH:
|
||||
stack.Push(ethutil.BigD(vm.vars.prevHash))
|
||||
stack.Push(ethutil.BigD(vm.vars.PrevHash))
|
||||
case oCOINBASE:
|
||||
stack.Push(ethutil.BigD(vm.vars.coinbase))
|
||||
stack.Push(ethutil.BigD(vm.vars.Coinbase))
|
||||
case oTIMESTAMP:
|
||||
stack.Push(big.NewInt(vm.vars.time))
|
||||
stack.Push(big.NewInt(vm.vars.Time))
|
||||
case oNUMBER:
|
||||
stack.Push(big.NewInt(int64(vm.vars.blockNumber)))
|
||||
stack.Push(big.NewInt(int64(vm.vars.BlockNumber)))
|
||||
case oDIFFICULTY:
|
||||
stack.Push(vm.vars.diff)
|
||||
stack.Push(vm.vars.Diff)
|
||||
case oGASLIMIT:
|
||||
// TODO
|
||||
|
||||
@ -406,7 +410,59 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) []byte {
|
||||
pc.Add(pc, ethutil.Big1)
|
||||
|
||||
if hook != nil {
|
||||
hook(op)
|
||||
hook(op, mem, stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Disassemble(script []byte) (asm []string) {
|
||||
pc := new(big.Int)
|
||||
for {
|
||||
if pc.Cmp(big.NewInt(int64(len(script)))) >= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Get the memory location of pc
|
||||
val := script[pc.Int64()]
|
||||
// Get the opcode (it must be an opcode!)
|
||||
op := OpCode(val)
|
||||
|
||||
asm = append(asm, fmt.Sprintf("%v", op))
|
||||
|
||||
switch op {
|
||||
case oPUSH: // Push PC+1 on to the stack
|
||||
pc.Add(pc, ethutil.Big1)
|
||||
data := script[pc.Int64() : pc.Int64()+32]
|
||||
val := ethutil.BigD(data)
|
||||
|
||||
var b []byte
|
||||
if val.Int64() == 0 {
|
||||
b = []byte{0}
|
||||
} else {
|
||||
b = val.Bytes()
|
||||
}
|
||||
|
||||
asm = append(asm, fmt.Sprintf("0x%x", b))
|
||||
|
||||
pc.Add(pc, big.NewInt(31))
|
||||
case oPUSH20:
|
||||
pc.Add(pc, ethutil.Big1)
|
||||
data := script[pc.Int64() : pc.Int64()+20]
|
||||
val := ethutil.BigD(data)
|
||||
var b []byte
|
||||
if val.Int64() == 0 {
|
||||
b = []byte{0}
|
||||
} else {
|
||||
b = val.Bytes()
|
||||
}
|
||||
|
||||
asm = append(asm, fmt.Sprintf("0x%x", b))
|
||||
|
||||
pc.Add(pc, big.NewInt(19))
|
||||
}
|
||||
|
||||
pc.Add(pc, ethutil.Big1)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -130,14 +130,29 @@ func TestRun4(t *testing.T) {
|
||||
callerClosure := NewClosure(account, c, c.script, state, big.NewInt(1000000000), new(big.Int))
|
||||
|
||||
vm := NewVm(state, RuntimeVars{
|
||||
origin: account.Address(),
|
||||
blockNumber: 1,
|
||||
prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
|
||||
coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
|
||||
time: 1,
|
||||
diff: big.NewInt(256),
|
||||
Origin: account.Address(),
|
||||
BlockNumber: 1,
|
||||
PrevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
|
||||
Coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
|
||||
Time: 1,
|
||||
Diff: big.NewInt(256),
|
||||
// XXX Tx data? Could be just an argument to the closure instead
|
||||
txData: nil,
|
||||
TxData: nil,
|
||||
})
|
||||
callerClosure.Call(vm, nil, nil)
|
||||
}
|
||||
|
||||
func TestRun5(t *testing.T) {
|
||||
ethutil.ReadConfig("")
|
||||
|
||||
asm, _ := mutan.Compile(strings.NewReader(`
|
||||
int32 a = 10
|
||||
int32 b = 20
|
||||
if a > b {
|
||||
int32 c = this.caller()
|
||||
}
|
||||
exit()
|
||||
`), false)
|
||||
script := ethutil.Assemble(asm...)
|
||||
fmt.Println(Disassemble(script))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user