stack.go 3.76 KB
Newer Older
obscuren's avatar
obscuren committed
1 2 3 4 5 6 7 8 9 10 11
package ethchain

import (
	"fmt"
	"math/big"
)

type OpCode int

// Op codes
const (
obscuren's avatar
obscuren committed
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
	oSTOP           = 0x00
	oADD            = 0x01
	oMUL            = 0x02
	oSUB            = 0x03
	oDIV            = 0x04
	oSDIV           = 0x05
	oMOD            = 0x06
	oSMOD           = 0x07
	oEXP            = 0x08
	oNEG            = 0x09
	oLT             = 0x0a
	oLE             = 0x0b
	oGT             = 0x0c
	oGE             = 0x0d
	oEQ             = 0x0e
	oNOT            = 0x0f
	oMYADDRESS      = 0x10
	oTXSENDER       = 0x11
	oTXVALUE        = 0x12
	oTXDATAN        = 0x13
	oTXDATA         = 0x14
	oBLK_PREVHASH   = 0x15
	oBLK_COINBASE   = 0x16
	oBLK_TIMESTAMP  = 0x17
	oBLK_NUMBER     = 0x18
	oBLK_DIFFICULTY = 0x19
	oBLK_NONCE      = 0x1a
	oBASEFEE        = 0x1b
	oSHA256         = 0x20
	oRIPEMD160      = 0x21
	oECMUL          = 0x22
	oECADD          = 0x23
	oECSIGN         = 0x24
	oECRECOVER      = 0x25
	oECVALID        = 0x26
	oSHA3           = 0x27
	oPUSH           = 0x30
	oPOP            = 0x31
	oDUP            = 0x32
	oSWAP           = 0x33
	oMLOAD          = 0x34
	oMSTORE         = 0x35
	oSLOAD          = 0x36
	oSSTORE         = 0x37
	oJMP            = 0x38
	oJMPI           = 0x39
	oIND            = 0x3a
	oEXTRO          = 0x3b
	oBALANCE        = 0x3c
	oMKTX           = 0x3d
	oSUICIDE        = 0x3f
obscuren's avatar
obscuren committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
)

// Since the opcodes aren't all in order we can't use a regular slice
var opCodeToString = map[OpCode]string{
	oSTOP:           "STOP",
	oADD:            "ADD",
	oMUL:            "MUL",
	oSUB:            "SUB",
	oDIV:            "DIV",
	oSDIV:           "SDIV",
	oMOD:            "MOD",
	oSMOD:           "SMOD",
	oEXP:            "EXP",
	oNEG:            "NEG",
	oLT:             "LT",
	oLE:             "LE",
	oGT:             "GT",
	oGE:             "GE",
	oEQ:             "EQ",
	oNOT:            "NOT",
	oMYADDRESS:      "MYADDRESS",
	oTXSENDER:       "TXSENDER",
	oTXVALUE:        "TXVALUE",
	oTXDATAN:        "TXDATAN",
	oTXDATA:         "TXDATA",
	oBLK_PREVHASH:   "BLK_PREVHASH",
	oBLK_COINBASE:   "BLK_COINBASE",
	oBLK_TIMESTAMP:  "BLK_TIMESTAMP",
	oBLK_NUMBER:     "BLK_NUMBER",
	oBLK_DIFFICULTY: "BLK_DIFFICULTY",
	oBASEFEE:        "BASEFEE",
	oSHA256:         "SHA256",
	oRIPEMD160:      "RIPEMD160",
	oECMUL:          "ECMUL",
	oECADD:          "ECADD",
	oECSIGN:         "ECSIGN",
	oECRECOVER:      "ECRECOVER",
	oECVALID:        "ECVALID",
	oSHA3:           "SHA3",
	oPUSH:           "PUSH",
	oPOP:            "POP",
	oDUP:            "DUP",
	oSWAP:           "SWAP",
	oMLOAD:          "MLOAD",
	oMSTORE:         "MSTORE",
	oSLOAD:          "SLOAD",
	oSSTORE:         "SSTORE",
	oJMP:            "JMP",
	oJMPI:           "JMPI",
	oIND:            "IND",
	oEXTRO:          "EXTRO",
	oBALANCE:        "BALANCE",
	oMKTX:           "MKTX",
	oSUICIDE:        "SUICIDE",
}

func (o OpCode) String() string {
	return opCodeToString[o]
}

type OpType int

const (
	tNorm = iota
	tData
	tExtro
	tCrypto
)

type TxCallback func(opType OpType) bool

// Simple push/pop stack mechanism
type Stack struct {
	data []*big.Int
}

func NewStack() *Stack {
	return &Stack{}
}

func (st *Stack) Pop() *big.Int {
	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)

	ints := st.data[s-2:]
	st.data = st.data[:s-2]

	return ints[0], ints[1]
}

obscuren's avatar
obscuren committed
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
func (st *Stack) Peek() *big.Int {
	s := len(st.data)

	str := st.data[s-1]

	return str
}

func (st *Stack) Peekn() (*big.Int, *big.Int) {
	s := len(st.data)

	ints := st.data[s-2:]

	return ints[0], ints[1]
}

obscuren's avatar
obscuren committed
177 178 179 180
func (st *Stack) Push(d *big.Int) {
	st.data = append(st.data, d)
}
func (st *Stack) Print() {
obscuren's avatar
obscuren committed
181
	fmt.Println("### STACK ###")
obscuren's avatar
obscuren committed
182 183 184 185 186 187 188
	if len(st.data) > 0 {
		for i, val := range st.data {
			fmt.Printf("%-3d  %v\n", i, val)
		}
	} else {
		fmt.Println("-- empty --")
	}
obscuren's avatar
obscuren committed
189
	fmt.Println("#############")
obscuren's avatar
obscuren committed
190
}