package ethutil import ( "math/big" "strconv" ) // Op codes var OpCodes = map[string]byte{ // 0x0 range - arithmetic ops "STOP": 0x00, "ADD": 0x01, "MUL": 0x02, "SUB": 0x03, "DIV": 0x04, "SDIV": 0x05, "MOD": 0x06, "SMOD": 0x07, "EXP": 0x08, "NEG": 0x09, "LT": 0x0a, "GT": 0x0b, "EQ": 0x0c, "NOT": 0x0d, // 0x10 range - bit ops "AND": 0x10, "OR": 0x11, "XOR": 0x12, "BYTE": 0x13, // 0x20 range - crypto "SHA3": 0x20, // 0x30 range - closure state "ADDRESS": 0x30, "BALANCE": 0x31, "ORIGIN": 0x32, "CALLER": 0x33, "CALLVALUE": 0x34, "CALLDATA": 0x35, "CALLDATASIZE": 0x36, "GASPRICE": 0x38, // 0x40 range - block operations "PREVHASH": 0x40, "COINBASE": 0x41, "TIMESTAMP": 0x42, "NUMBER": 0x43, "DIFFICULTY": 0x44, "GASLIMIT": 0x45, // 0x50 range - 'storage' and execution "PUSH": 0x50, "POP": 0x51, "DUP": 0x52, "SWAP": 0x53, "MLOAD": 0x54, "MSTORE": 0x55, "MSTORE8": 0x56, "SLOAD": 0x57, "SSTORE": 0x58, "JUMP": 0x59, "JUMPI": 0x5a, "PC": 0x5b, "MSIZE": 0x5c, // 0x60 range - closures "CREATE": 0x60, "CALL": 0x61, "RETURN": 0x62, // 0x70 range - other "LOG": 0x70, "SUICIDE": 0x7f, } func IsOpCode(s string) bool { for key, _ := range OpCodes { if key == s { return true } } return false } func CompileInstr(s interface{}) ([]byte, error) { switch s.(type) { case string: str := s.(string) isOp := IsOpCode(str) if isOp { return []byte{OpCodes[str]}, nil } num := new(big.Int) _, success := num.SetString(str, 0) // Assume regular bytes during compilation if !success { num.SetBytes([]byte(str)) } return num.Bytes(), nil case int: return big.NewInt(int64(s.(int))).Bytes(), nil case []byte: return BigD(s.([]byte)).Bytes(), nil } return nil, nil } func Instr(instr string) (int, []string, error) { base := new(big.Int) base.SetString(instr, 0) args := make([]string, 7) for i := 0; i < 7; i++ { // int(int(val) / int(math.Pow(256,float64(i)))) % 256 exp := BigPow(256, i) num := new(big.Int) num.Div(base, exp) args[i] = num.Mod(num, big.NewInt(256)).String() } op, _ := strconv.Atoi(args[0]) return op, args[1:7], nil } // Script compilation functions // Compiles strings to machine code func Assemble(instructions ...interface{}) (script []string) { script = make([]string, len(instructions)) for i, val := range instructions { instr, _ := CompileInstr(val) script[i] = string(instr) } return }