mirror of https://github.com/ethereum/go-ethereum
parent
33004d704e
commit
8c4eca2490
@ -1,284 +0,0 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"github.com/ethereum/ethutil-go" |
||||
"math/big" |
||||
"strconv" |
||||
) |
||||
|
||||
// Op codes
|
||||
const ( |
||||
oSTOP int = 0x00 |
||||
oADD int = 0x01 |
||||
oMUL int = 0x02 |
||||
oSUB int = 0x03 |
||||
oDIV int = 0x04 |
||||
oSDIV int = 0x05 |
||||
oMOD int = 0x06 |
||||
oSMOD int = 0x07 |
||||
oEXP int = 0x08 |
||||
oNEG int = 0x09 |
||||
oLT int = 0x0a |
||||
oLE int = 0x0b |
||||
oGT int = 0x0c |
||||
oGE int = 0x0d |
||||
oEQ int = 0x0e |
||||
oNOT int = 0x0f |
||||
oMYADDRESS int = 0x10 |
||||
oTXSENDER int = 0x11 |
||||
oTXVALUE int = 0x12 |
||||
oTXFEE int = 0x13 |
||||
oTXDATAN int = 0x14 |
||||
oTXDATA int = 0x15 |
||||
oBLK_PREVHASH int = 0x16 |
||||
oBLK_COINBASE int = 0x17 |
||||
oBLK_TIMESTAMP int = 0x18 |
||||
oBLK_NUMBER int = 0x19 |
||||
oBLK_DIFFICULTY int = 0x1a |
||||
oSHA256 int = 0x20 |
||||
oRIPEMD160 int = 0x21 |
||||
oECMUL int = 0x22 |
||||
oECADD int = 0x23 |
||||
oECSIGN int = 0x24 |
||||
oECRECOVER int = 0x25 |
||||
oECVALID int = 0x26 |
||||
oPUSH int = 0x30 |
||||
oPOP int = 0x31 |
||||
oDUP int = 0x32 |
||||
oDUPN int = 0x33 |
||||
oSWAP int = 0x34 |
||||
oSWAPN int = 0x35 |
||||
oLOAD int = 0x36 |
||||
oSTORE int = 0x37 |
||||
oJMP int = 0x40 |
||||
oJMPI int = 0x41 |
||||
oIND int = 0x42 |
||||
oEXTRO int = 0x50 |
||||
oBALANCE int = 0x51 |
||||
oMKTX int = 0x60 |
||||
oSUICIDE int = 0xff |
||||
) |
||||
|
||||
type OpType int |
||||
|
||||
const ( |
||||
tNorm = iota |
||||
tData |
||||
tExtro |
||||
tCrypto |
||||
) |
||||
|
||||
type TxCallback func(opType OpType) bool |
||||
|
||||
// Simple push/pop stack mechanism
|
||||
type Stack struct { |
||||
data []string |
||||
} |
||||
|
||||
func NewStack() *Stack { |
||||
return &Stack{} |
||||
} |
||||
func (st *Stack) Pop() string { |
||||
s := len(st.data) |
||||
|
||||
str := st.data[s-1] |
||||
st.data = st.data[:s-1] |
||||
|
||||
return str |
||||
} |
||||
|
||||
func (st *Stack) Popn() (*big.Int, *big.Int) { |
||||
s := len(st.data) |
||||
|
||||
strs := st.data[s-2:] |
||||
st.data = st.data[:s-2] |
||||
|
||||
return ethutil.Big(strs[0]), ethutil.Big(strs[1]) |
||||
} |
||||
|
||||
func (st *Stack) Push(d string) { |
||||
st.data = append(st.data, d) |
||||
} |
||||
func (st *Stack) Print() { |
||||
fmt.Println(st.data) |
||||
} |
||||
|
||||
type Vm struct { |
||||
// Stack
|
||||
stack *Stack |
||||
} |
||||
|
||||
func NewVm() *Vm { |
||||
return &Vm{ |
||||
stack: NewStack(), |
||||
} |
||||
} |
||||
|
||||
func (vm *Vm) ProcContract(tx *ethutil.Transaction, |
||||
block *ethutil.Block, cb TxCallback) { |
||||
// Instruction pointer
|
||||
pc := 0 |
||||
|
||||
contract := block.GetContract(tx.Hash()) |
||||
if contract == nil { |
||||
fmt.Println("Contract not found") |
||||
return |
||||
} |
||||
|
||||
Pow256 := ethutil.BigPow(2, 256) |
||||
|
||||
//fmt.Printf("# op arg\n")
|
||||
out: |
||||
for { |
||||
// The base big int for all calculations. Use this for any results.
|
||||
base := new(big.Int) |
||||
// XXX Should Instr return big int slice instead of string slice?
|
||||
// Get the next instruction from the contract
|
||||
//op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc)))))
|
||||
nb := ethutil.NumberToBytes(uint64(pc), 32) |
||||
op, _, _ := ethutil.Instr(contract.State().Get(string(nb))) |
||||
|
||||
if !cb(0) { |
||||
break |
||||
} |
||||
|
||||
if Debug { |
||||
//fmt.Printf("%-3d %-4d\n", pc, op)
|
||||
} |
||||
|
||||
switch op { |
||||
case oADD: |
||||
x, y := vm.stack.Popn() |
||||
// (x + y) % 2 ** 256
|
||||
base.Add(x, y) |
||||
base.Mod(base, Pow256) |
||||
// Pop result back on the stack
|
||||
vm.stack.Push(base.String()) |
||||
case oSUB: |
||||
x, y := vm.stack.Popn() |
||||
// (x - y) % 2 ** 256
|
||||
base.Sub(x, y) |
||||
base.Mod(base, Pow256) |
||||
// Pop result back on the stack
|
||||
vm.stack.Push(base.String()) |
||||
case oMUL: |
||||
x, y := vm.stack.Popn() |
||||
// (x * y) % 2 ** 256
|
||||
base.Mul(x, y) |
||||
base.Mod(base, Pow256) |
||||
// Pop result back on the stack
|
||||
vm.stack.Push(base.String()) |
||||
case oDIV: |
||||
x, y := vm.stack.Popn() |
||||
// floor(x / y)
|
||||
base.Div(x, y) |
||||
// Pop result back on the stack
|
||||
vm.stack.Push(base.String()) |
||||
case oSDIV: |
||||
x, y := vm.stack.Popn() |
||||
// n > 2**255
|
||||
if x.Cmp(Pow256) > 0 { |
||||
x.Sub(Pow256, x) |
||||
} |
||||
if y.Cmp(Pow256) > 0 { |
||||
y.Sub(Pow256, y) |
||||
} |
||||
z := new(big.Int) |
||||
z.Div(x, y) |
||||
if z.Cmp(Pow256) > 0 { |
||||
z.Sub(Pow256, z) |
||||
} |
||||
// Push result on to the stack
|
||||
vm.stack.Push(z.String()) |
||||
case oMOD: |
||||
x, y := vm.stack.Popn() |
||||
base.Mod(x, y) |
||||
vm.stack.Push(base.String()) |
||||
case oSMOD: |
||||
x, y := vm.stack.Popn() |
||||
// n > 2**255
|
||||
if x.Cmp(Pow256) > 0 { |
||||
x.Sub(Pow256, x) |
||||
} |
||||
if y.Cmp(Pow256) > 0 { |
||||
y.Sub(Pow256, y) |
||||
} |
||||
z := new(big.Int) |
||||
z.Mod(x, y) |
||||
if z.Cmp(Pow256) > 0 { |
||||
z.Sub(Pow256, z) |
||||
} |
||||
// Push result on to the stack
|
||||
vm.stack.Push(z.String()) |
||||
case oEXP: |
||||
x, y := vm.stack.Popn() |
||||
base.Exp(x, y, Pow256) |
||||
|
||||
vm.stack.Push(base.String()) |
||||
case oNEG: |
||||
base.Sub(Pow256, ethutil.Big(vm.stack.Pop())) |
||||
vm.stack.Push(base.String()) |
||||
case oLT: |
||||
x, y := vm.stack.Popn() |
||||
// x < y
|
||||
if x.Cmp(y) < 0 { |
||||
vm.stack.Push("1") |
||||
} else { |
||||
vm.stack.Push("0") |
||||
} |
||||
case oLE: |
||||
x, y := vm.stack.Popn() |
||||
// x <= y
|
||||
if x.Cmp(y) < 1 { |
||||
vm.stack.Push("1") |
||||
} else { |
||||
vm.stack.Push("0") |
||||
} |
||||
case oGT: |
||||
x, y := vm.stack.Popn() |
||||
// x > y
|
||||
if x.Cmp(y) > 0 { |
||||
vm.stack.Push("1") |
||||
} else { |
||||
vm.stack.Push("0") |
||||
} |
||||
case oGE: |
||||
x, y := vm.stack.Popn() |
||||
// x >= y
|
||||
if x.Cmp(y) > -1 { |
||||
vm.stack.Push("1") |
||||
} else { |
||||
vm.stack.Push("0") |
||||
} |
||||
case oNOT: |
||||
x, y := vm.stack.Popn() |
||||
// x != y
|
||||
if x.Cmp(y) != 0 { |
||||
vm.stack.Push("1") |
||||
} else { |
||||
vm.stack.Push("0") |
||||
} |
||||
case oMYADDRESS: |
||||
vm.stack.Push(string(tx.Hash())) |
||||
case oTXSENDER: |
||||
vm.stack.Push(string(tx.Sender())) |
||||
case oPUSH: |
||||
// Get the next entry and pushes the value on the stack
|
||||
pc++ |
||||
vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(pc), 32)))) |
||||
case oPOP: |
||||
// Pop current value of the stack
|
||||
vm.stack.Pop() |
||||
case oLOAD: |
||||
// Load instruction X on the stack
|
||||
i, _ := strconv.Atoi(vm.stack.Pop()) |
||||
vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(i), 32)))) |
||||
case oSTOP: |
||||
break out |
||||
} |
||||
pc++ |
||||
} |
||||
|
||||
vm.stack.Print() |
||||
} |
@ -1,76 +0,0 @@ |
||||
package main |
||||
|
||||
/* |
||||
import ( |
||||
_"fmt" |
||||
"testing" |
||||
) |
||||
|
||||
|
||||
func TestVm(t *testing.T) { |
||||
InitFees() |
||||
|
||||
db, _ := NewMemDatabase() |
||||
Db = db |
||||
|
||||
ctrct := NewTransaction("", 200000000, []string{ |
||||
"PUSH", "1a2f2e", |
||||
"PUSH", "hallo", |
||||
"POP", // POP hallo
|
||||
"PUSH", "3", |
||||
"LOAD", // Load hallo back on the stack
|
||||
|
||||
"PUSH", "1", |
||||
"PUSH", "2", |
||||
"ADD", |
||||
|
||||
"PUSH", "2", |
||||
"PUSH", "1", |
||||
"SUB", |
||||
|
||||
"PUSH", "100000000000000000000000", |
||||
"PUSH", "10000000000000", |
||||
"SDIV", |
||||
|
||||
"PUSH", "105", |
||||
"PUSH", "200", |
||||
"MOD", |
||||
|
||||
"PUSH", "100000000000000000000000", |
||||
"PUSH", "10000000000000", |
||||
"SMOD", |
||||
|
||||
"PUSH", "5", |
||||
"PUSH", "10", |
||||
"LT", |
||||
|
||||
"PUSH", "5", |
||||
"PUSH", "5", |
||||
"LE", |
||||
|
||||
"PUSH", "50", |
||||
"PUSH", "5", |
||||
"GT", |
||||
|
||||
"PUSH", "5", |
||||
"PUSH", "5", |
||||
"GE", |
||||
|
||||
"PUSH", "10", |
||||
"PUSH", "10", |
||||
"NOT", |
||||
|
||||
"MYADDRESS", |
||||
"TXSENDER", |
||||
|
||||
"STOP", |
||||
}) |
||||
tx := NewTransaction("1e8a42ea8cce13", 100, []string{}) |
||||
|
||||
block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx}) |
||||
db.Put(block.Hash(), block.MarshalRlp()) |
||||
|
||||
bm := NewBlockManager() |
||||
bm.ProcessBlock( block ) |
||||
} |
||||
*/ |
Loading…
Reference in new issue