Beispiel #1
0
Datei: graph.go Projekt: rsc/tmp
func ratProb(mode int) func(*big.Rat) *big.Rat {
	return func(x *big.Rat) *big.Rat {
		lo := big.NewInt(0)
		hi := new(big.Int).Set(big2p63)
		n := 0
		for lo.Cmp(hi) != 0 {
			m := new(big.Int).Add(lo, hi)
			m = m.Rsh(m, 1)
			if n++; n > 100 {
				fmt.Printf("??? %v %v %v\n", lo, hi, m)
				break
			}
			v := new(big.Rat).SetFrac(m, big2p63)
			f, _ := v.Float64()
			v.SetFloat64(f)
			if v.Cmp(x) < 0 {
				lo.Add(m, bigOne)
			} else {
				hi.Set(m)
			}
		}
		switch mode {
		default: // case 0
			return new(big.Rat).SetFrac(lo, big2p63)
		case 1:
			if lo.Cmp(big.NewInt(cutoff1)) <= 0 {
				lo.Add(lo, big.NewInt(1<<63-cutoff1))
			}
			return new(big.Rat).SetFrac(lo, big2p63)
		case 2:
			return new(big.Rat).SetFrac(lo, big.NewInt(cutoff1))
		}
	}
}
Beispiel #2
0
func getBalance(balance string) (bool, *big.Rat) {
	rationalNum := new(big.Rat)
	if strings.Contains(balance, "(") {
		rationalNum.SetFloat64(calc.Solve(balance))
		return true, rationalNum
	}
	_, isValid := rationalNum.SetString(balance)
	return isValid, rationalNum
}
Beispiel #3
0
//export OFXTransactionCallback
func OFXTransactionCallback(transaction_data C.struct_OfxTransactionData, data unsafe.Pointer) C.int {
	iobj := (*ImportObject)(data)
	itl := iobj.TransactionList
	transaction := new(Transaction)

	if transaction_data.name_valid != 0 {
		transaction.Description = C.GoString(&transaction_data.name[0])
	}
	//	if transaction_data.reference_number_valid != 0 {
	//		fmt.Println("reference_number: ", C.GoString(&transaction_data.reference_number[0]))
	//	}
	if transaction_data.date_posted_valid != 0 {
		transaction.Date = time.Unix(int64(transaction_data.date_posted), 0)
	} else if transaction_data.date_initiated_valid != 0 {
		transaction.Date = time.Unix(int64(transaction_data.date_initiated), 0)
	}
	if transaction_data.fi_id_valid != 0 {
		transaction.RemoteId = C.GoString(&transaction_data.fi_id[0])
	}

	if transaction_data.amount_valid != 0 {
		split := new(Split)
		r := new(big.Rat)
		r.SetFloat64(float64(transaction_data.amount))
		security, err := GetSecurity(itl.Account.SecurityId, itl.Account.UserId)
		if err != nil {
			if iobj.Error == nil {
				iobj.Error = err
			}
			return 1
		}
		split.Amount = r.FloatString(security.Precision)
		if transaction_data.memo_valid != 0 {
			split.Memo = C.GoString(&transaction_data.memo[0])
		}
		if transaction_data.check_number_valid != 0 {
			split.Number = C.GoString(&transaction_data.check_number[0])
		}
		split.SecurityId = -1
		split.AccountId = itl.Account.AccountId
		transaction.Splits = append(transaction.Splits, split)
	} else {
		if iobj.Error == nil {
			iobj.Error = errors.New("OFX transaction amount invalid")
		}
		return 1
	}

	var security *Security
	var err error
	split := new(Split)
	units := new(big.Rat)

	if transaction_data.units_valid != 0 {
		units.SetFloat64(float64(transaction_data.units))
		if transaction_data.security_data_valid != 0 {
			security_data := transaction_data.security_data_ptr
			if security_data.ticker_valid != 0 {
				s, err := GetSecurityByName(C.GoString(&security_data.ticker[0]))
				if err != nil {
					if iobj.Error == nil {
						iobj.Error = errors.New("Failed to find OFX transaction security: " + C.GoString(&security_data.ticker[0]))
					}
					return 1
				}
				security = s
			} else {
				if iobj.Error == nil {
					iobj.Error = errors.New("OFX security ticker invalid")
				}
				return 1
			}
			if security.Type == Stock && security_data.unique_id_valid != 0 && security_data.unique_id_type_valid != 0 && C.GoString(&security_data.unique_id_type[0]) == "CUSIP" {
				// Validate the security CUSIP, if possible
				if security.AlternateId != C.GoString(&security_data.unique_id[0]) {
					if iobj.Error == nil {
						iobj.Error = errors.New("OFX transaction security CUSIP failed to validate")
					}
					return 1
				}
			}
		} else {
			security, err = GetSecurity(itl.Account.SecurityId, itl.Account.UserId)
			if err != nil {
				if iobj.Error == nil {
					iobj.Error = err
				}
				return 1
			}
		}
	} else {
		// Calculate units from other available fields if its not present
		//		units = - (amount + various fees) / unitprice
		units.SetFloat64(float64(transaction_data.amount))
		fees := new(big.Rat)
		if transaction_data.fees_valid != 0 {
			fees.SetFloat64(float64(-transaction_data.fees))
		}
		if transaction_data.commission_valid != 0 {
			commission := new(big.Rat)
			commission.SetFloat64(float64(-transaction_data.commission))
			fees.Add(fees, commission)
		}
		units.Add(units, fees)
		units.Neg(units)
		if transaction_data.unitprice_valid != 0 && transaction_data.unitprice != 0 {
			unitprice := new(big.Rat)
			unitprice.SetFloat64(float64(transaction_data.unitprice))
			units.Quo(units, unitprice)
		}

		// If 'units' wasn't present, assume we're using the account's security
		security, err = GetSecurity(itl.Account.SecurityId, itl.Account.UserId)
		if err != nil {
			if iobj.Error == nil {
				iobj.Error = err
			}
			return 1
		}
	}

	split.Amount = units.FloatString(security.Precision)
	split.SecurityId = security.SecurityId
	split.AccountId = -1
	transaction.Splits = append(transaction.Splits, split)

	if transaction_data.fees_valid != 0 {
		split := new(Split)
		r := new(big.Rat)
		r.SetFloat64(float64(-transaction_data.fees))
		security, err := GetSecurity(itl.Account.SecurityId, itl.Account.UserId)
		if err != nil {
			if iobj.Error == nil {
				iobj.Error = err
			}
			return 1
		}
		split.Amount = r.FloatString(security.Precision)
		split.Memo = "fees"
		split.SecurityId = itl.Account.SecurityId
		split.AccountId = -1
		transaction.Splits = append(transaction.Splits, split)
	}

	if transaction_data.commission_valid != 0 {
		split := new(Split)
		r := new(big.Rat)
		r.SetFloat64(float64(-transaction_data.commission))
		security, err := GetSecurity(itl.Account.SecurityId, itl.Account.UserId)
		if err != nil {
			if iobj.Error == nil {
				iobj.Error = err
			}
			return 1
		}
		split.Amount = r.FloatString(security.Precision)
		split.Memo = "commission"
		split.SecurityId = itl.Account.SecurityId
		split.AccountId = -1
		transaction.Splits = append(transaction.Splits, split)
	}

	//	if transaction_data.payee_id_valid != 0 {
	//		fmt.Println("payee_id: ", C.GoString(&transaction_data.payee_id[0]))
	//	}

	transaction_list := append(*itl.Transactions, *transaction)
	iobj.TransactionList.Transactions = &transaction_list

	return 0
}
Beispiel #4
0
func (vm *Vm) Process(contract *Contract, state *State, vars RuntimeVars) {
	vm.mem = make(map[string]*big.Int)
	vm.stack = NewStack()

	addr := vars.address // tx.Hash()[12:]
	// Instruction pointer
	pc := 0

	if contract == nil {
		fmt.Println("Contract not found")
		return
	}

	Pow256 := ethutil.BigPow(2, 256)

	if ethutil.Config.Debug {
		ethutil.Config.Log.Debugf("#   op\n")
	}

	stepcount := 0
	totalFee := new(big.Int)

out:
	for {
		stepcount++
		// The base big int for all calculations. Use this for any results.
		base := new(big.Int)
		val := contract.GetMem(pc)
		//fmt.Printf("%x = %d, %v %x\n", r, len(r), v, nb)
		op := OpCode(val.Uint())

		var fee *big.Int = new(big.Int)
		var fee2 *big.Int = new(big.Int)
		if stepcount > 16 {
			fee.Add(fee, StepFee)
		}

		// Calculate the fees
		switch op {
		case oSSTORE:
			y, x := vm.stack.Peekn()
			val := contract.Addr(ethutil.BigToBytes(x, 256))
			if val.IsEmpty() && len(y.Bytes()) > 0 {
				fee2.Add(DataFee, StoreFee)
			} else {
				fee2.Sub(DataFee, StoreFee)
			}
		case oSLOAD:
			fee.Add(fee, StoreFee)
		case oEXTRO, oBALANCE:
			fee.Add(fee, ExtroFee)
		case oSHA256, oRIPEMD160, oECMUL, oECADD, oECSIGN, oECRECOVER, oECVALID:
			fee.Add(fee, CryptoFee)
		case oMKTX:
			fee.Add(fee, ContractFee)
		}

		tf := new(big.Int).Add(fee, fee2)
		if contract.Amount.Cmp(tf) < 0 {
			fmt.Println("Insufficient fees to continue running the contract", tf, contract.Amount)
			break
		}
		// Add the fee to the total fee. It's subtracted when we're done looping
		totalFee.Add(totalFee, tf)

		if ethutil.Config.Debug {
			ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
		}

		switch op {
		case oSTOP:
			fmt.Println("")
			break out
		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)
		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)
		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)
		case oDIV:
			x, y := vm.stack.Popn()
			// floor(x / y)
			base.Div(x, y)
			// Pop result back on the stack
			vm.stack.Push(base)
		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)
		case oMOD:
			x, y := vm.stack.Popn()
			base.Mod(x, y)
			vm.stack.Push(base)
		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)
		case oEXP:
			x, y := vm.stack.Popn()
			base.Exp(x, y, Pow256)

			vm.stack.Push(base)
		case oNEG:
			base.Sub(Pow256, vm.stack.Pop())
			vm.stack.Push(base)
		case oLT:
			x, y := vm.stack.Popn()
			// x < y
			if x.Cmp(y) < 0 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oLE:
			x, y := vm.stack.Popn()
			// x <= y
			if x.Cmp(y) < 1 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oGT:
			x, y := vm.stack.Popn()
			// x > y
			if x.Cmp(y) > 0 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oGE:
			x, y := vm.stack.Popn()
			// x >= y
			if x.Cmp(y) > -1 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oNOT:
			x, y := vm.stack.Popn()
			// x != y
			if x.Cmp(y) != 0 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oMYADDRESS:
			vm.stack.Push(ethutil.BigD(addr))
		case oTXSENDER:
			vm.stack.Push(ethutil.BigD(vars.sender))
		case oTXVALUE:
			vm.stack.Push(vars.txValue)
		case oTXDATAN:
			vm.stack.Push(big.NewInt(int64(len(vars.txData))))
		case oTXDATA:
			v := vm.stack.Pop()
			// v >= len(data)
			if v.Cmp(big.NewInt(int64(len(vars.txData)))) >= 0 {
				vm.stack.Push(ethutil.Big("0"))
			} else {
				vm.stack.Push(ethutil.Big(vars.txData[v.Uint64()]))
			}
		case oBLK_PREVHASH:
			vm.stack.Push(ethutil.BigD(vars.prevHash))
		case oBLK_COINBASE:
			vm.stack.Push(ethutil.BigD(vars.coinbase))
		case oBLK_TIMESTAMP:
			vm.stack.Push(big.NewInt(vars.time))
		case oBLK_NUMBER:
			vm.stack.Push(big.NewInt(int64(vars.blockNumber)))
		case oBLK_DIFFICULTY:
			vm.stack.Push(vars.diff)
		case oBASEFEE:
			// e = 10^21
			e := big.NewInt(0).Exp(big.NewInt(10), big.NewInt(21), big.NewInt(0))
			d := new(big.Rat)
			d.SetInt(vars.diff)
			c := new(big.Rat)
			c.SetFloat64(0.5)
			// d = diff / 0.5
			d.Quo(d, c)
			// base = floor(d)
			base.Div(d.Num(), d.Denom())

			x := new(big.Int)
			x.Div(e, base)

			// x = floor(10^21 / floor(diff^0.5))
			vm.stack.Push(x)
		case oSHA256, oSHA3, oRIPEMD160:
			// This is probably save
			// ceil(pop / 32)
			length := int(math.Ceil(float64(vm.stack.Pop().Uint64()) / 32.0))
			// New buffer which will contain the concatenated popped items
			data := new(bytes.Buffer)
			for i := 0; i < length; i++ {
				// Encode the number to bytes and have it 32bytes long
				num := ethutil.NumberToBytes(vm.stack.Pop().Bytes(), 256)
				data.WriteString(string(num))
			}

			if op == oSHA256 {
				vm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes())))
			} else if op == oSHA3 {
				vm.stack.Push(base.SetBytes(ethutil.Sha3Bin(data.Bytes())))
			} else {
				vm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes())))
			}
		case oECMUL:
			y := vm.stack.Pop()
			x := vm.stack.Pop()
			//n := vm.stack.Pop()

			//if ethutil.Big(x).Cmp(ethutil.Big(y)) {
			data := new(bytes.Buffer)
			data.WriteString(x.String())
			data.WriteString(y.String())
			if secp256k1.VerifyPubkeyValidity(data.Bytes()) == 1 {
				// TODO
			} else {
				// Invalid, push infinity
				vm.stack.Push(ethutil.Big("0"))
				vm.stack.Push(ethutil.Big("0"))
			}
			//} else {
			//	// Invalid, push infinity
			//	vm.stack.Push("0")
			//	vm.stack.Push("0")
			//}

		case oECADD:
		case oECSIGN:
		case oECRECOVER:
		case oECVALID:
		case oPUSH:
			pc++
			vm.stack.Push(contract.GetMem(pc).BigInt())
		case oPOP:
			// Pop current value of the stack
			vm.stack.Pop()
		case oDUP:
			// Dup top stack
			x := vm.stack.Pop()
			vm.stack.Push(x)
			vm.stack.Push(x)
		case oSWAP:
			// Swap two top most values
			x, y := vm.stack.Popn()
			vm.stack.Push(y)
			vm.stack.Push(x)
		case oMLOAD:
			x := vm.stack.Pop()
			vm.stack.Push(vm.mem[x.String()])
		case oMSTORE:
			x, y := vm.stack.Popn()
			vm.mem[x.String()] = y
		case oSLOAD:
			// Load the value in storage and push it on the stack
			x := vm.stack.Pop()
			// decode the object as a big integer
			decoder := contract.Addr(x.Bytes())
			if !decoder.IsNil() {
				vm.stack.Push(decoder.BigInt())
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oSSTORE:
			// Store Y at index X
			y, x := vm.stack.Popn()
			addr := ethutil.BigToBytes(x, 256)
			fmt.Printf(" => %x (%v) @ %v", y.Bytes(), y, ethutil.BigD(addr))
			contract.SetAddr(addr, y)
			//contract.State().Update(string(idx), string(y))
		case oJMP:
			x := int(vm.stack.Pop().Uint64())
			// Set pc to x - 1 (minus one so the incrementing at the end won't effect it)
			pc = x
			pc--
		case oJMPI:
			x := vm.stack.Pop()
			// Set pc to x if it's non zero
			if x.Cmp(ethutil.BigFalse) != 0 {
				pc = int(x.Uint64())
				pc--
			}
		case oIND:
			vm.stack.Push(big.NewInt(int64(pc)))
		case oEXTRO:
			memAddr := vm.stack.Pop()
			contractAddr := vm.stack.Pop().Bytes()

			// Push the contract's memory on to the stack
			vm.stack.Push(contractMemory(state, contractAddr, memAddr))
		case oBALANCE:
			// Pushes the balance of the popped value on to the stack
			account := state.GetAccount(vm.stack.Pop().Bytes())
			vm.stack.Push(account.Amount)
		case oMKTX:
			addr, value := vm.stack.Popn()
			from, length := vm.stack.Popn()

			makeInlineTx(addr.Bytes(), value, from, length, contract, state)
		case oSUICIDE:
			recAddr := vm.stack.Pop().Bytes()
			// Purge all memory
			deletedMemory := contract.state.Purge()
			// Add refunds to the pop'ed address
			refund := new(big.Int).Mul(StoreFee, big.NewInt(int64(deletedMemory)))
			account := state.GetAccount(recAddr)
			account.Amount.Add(account.Amount, refund)
			// Update the refunding address
			state.UpdateAccount(recAddr, account)
			// Delete the contract
			state.trie.Update(string(addr), "")

			ethutil.Config.Log.Debugf("(%d) => %x\n", deletedMemory, recAddr)
			break out
		default:
			fmt.Printf("Invalid OPCODE: %x\n", op)
		}
		ethutil.Config.Log.Debugln("")
		//vm.stack.Print()
		pc++
	}

	state.UpdateContract(addr, contract)
}
Beispiel #5
0
func FloatToRat(v float64) *big.Rat {
	rat := new(big.Rat)
	rat.SetFloat64(v)
	return rat
}
// Contract evaluation is done here.
func (bm *BlockManager) ProcContract(tx *ethutil.Transaction, block *ethutil.Block, cb TxCallback) {
	// Instruction pointer
	pc := 0
	blockInfo := bm.BlockInfo(block)

	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)
		o, _, _ := ethutil.Instr(contract.State().Get(string(nb)))
		op := OpCode(o)

		if !cb(0) {
			break
		}

		if Debug {
			//fmt.Printf("%-3d %-4s\n", pc, op.String())
		}

		switch op {
		case oSTOP:
			break out
		case oADD:
			x, y := bm.stack.Popn()
			// (x + y) % 2 ** 256
			base.Add(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oSUB:
			x, y := bm.stack.Popn()
			// (x - y) % 2 ** 256
			base.Sub(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oMUL:
			x, y := bm.stack.Popn()
			// (x * y) % 2 ** 256
			base.Mul(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oDIV:
			x, y := bm.stack.Popn()
			// floor(x / y)
			base.Div(x, y)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oSDIV:
			x, y := bm.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
			bm.stack.Push(z)
		case oMOD:
			x, y := bm.stack.Popn()
			base.Mod(x, y)
			bm.stack.Push(base)
		case oSMOD:
			x, y := bm.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
			bm.stack.Push(z)
		case oEXP:
			x, y := bm.stack.Popn()
			base.Exp(x, y, Pow256)

			bm.stack.Push(base)
		case oNEG:
			base.Sub(Pow256, bm.stack.Pop())
			bm.stack.Push(base)
		case oLT:
			x, y := bm.stack.Popn()
			// x < y
			if x.Cmp(y) < 0 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oLE:
			x, y := bm.stack.Popn()
			// x <= y
			if x.Cmp(y) < 1 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oGT:
			x, y := bm.stack.Popn()
			// x > y
			if x.Cmp(y) > 0 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oGE:
			x, y := bm.stack.Popn()
			// x >= y
			if x.Cmp(y) > -1 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oNOT:
			x, y := bm.stack.Popn()
			// x != y
			if x.Cmp(y) != 0 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}

		// Please note  that the  following code contains some
		// ugly string casting. This will have to change to big
		// ints. TODO :)
		case oMYADDRESS:
			bm.stack.Push(ethutil.BigD(tx.Hash()))
		case oTXSENDER:
			bm.stack.Push(ethutil.BigD(tx.Sender()))
		case oTXVALUE:
			bm.stack.Push(tx.Value)
		case oTXDATAN:
			bm.stack.Push(big.NewInt(int64(len(tx.Data))))
		case oTXDATA:
			v := bm.stack.Pop()
			// v >= len(data)
			if v.Cmp(big.NewInt(int64(len(tx.Data)))) >= 0 {
				bm.stack.Push(ethutil.Big("0"))
			} else {
				bm.stack.Push(ethutil.Big(tx.Data[v.Uint64()]))
			}
		case oBLK_PREVHASH:
			bm.stack.Push(ethutil.Big(block.PrevHash))
		case oBLK_COINBASE:
			bm.stack.Push(ethutil.Big(block.Coinbase))
		case oBLK_TIMESTAMP:
			bm.stack.Push(big.NewInt(block.Time))
		case oBLK_NUMBER:
			bm.stack.Push(blockInfo.Number)
		case oBLK_DIFFICULTY:
			bm.stack.Push(block.Difficulty)
		case oBASEFEE:
			// e = 10^21
			e := big.NewInt(0).Exp(big.NewInt(10), big.NewInt(21), big.NewInt(0))
			d := new(big.Rat)
			d.SetInt(block.Difficulty)
			c := new(big.Rat)
			c.SetFloat64(0.5)
			// d = diff / 0.5
			d.Quo(d, c)
			// base = floor(d)
			base.Div(d.Num(), d.Denom())

			x := new(big.Int)
			x.Div(e, base)

			// x = floor(10^21 / floor(diff^0.5))
			bm.stack.Push(x)
		case oSHA256, oSHA3, oRIPEMD160:
			// This is probably save
			// ceil(pop / 32)
			length := int(math.Ceil(float64(bm.stack.Pop().Uint64()) / 32.0))
			// New buffer which will contain the concatenated popped items
			data := new(bytes.Buffer)
			for i := 0; i < length; i++ {
				// Encode the number to bytes and have it 32bytes long
				num := ethutil.NumberToBytes(bm.stack.Pop().Bytes(), 256)
				data.WriteString(string(num))
			}

			if op == oSHA256 {
				bm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes())))
			} else if op == oSHA3 {
				bm.stack.Push(base.SetBytes(ethutil.Sha3Bin(data.Bytes())))
			} else {
				bm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes())))
			}
		case oECMUL:
			y := bm.stack.Pop()
			x := bm.stack.Pop()
			//n := bm.stack.Pop()

			//if ethutil.Big(x).Cmp(ethutil.Big(y)) {
			data := new(bytes.Buffer)
			data.WriteString(x.String())
			data.WriteString(y.String())
			if secp256k1.VerifyPubkeyValidity(data.Bytes()) == 1 {
				// TODO
			} else {
				// Invalid, push infinity
				bm.stack.Push(ethutil.Big("0"))
				bm.stack.Push(ethutil.Big("0"))
			}
			//} else {
			//	// Invalid, push infinity
			//	bm.stack.Push("0")
			//	bm.stack.Push("0")
			//}

		case oECADD:
		case oECSIGN:
		case oECRECOVER:
		case oECVALID:
		case oPUSH:
			pc++
			bm.stack.Push(bm.mem[strconv.Itoa(pc)])
		case oPOP:
			// Pop current value of the stack
			bm.stack.Pop()
		case oDUP:
			// Dup top stack
			x := bm.stack.Pop()
			bm.stack.Push(x)
			bm.stack.Push(x)
		case oSWAP:
			// Swap two top most values
			x, y := bm.stack.Popn()
			bm.stack.Push(y)
			bm.stack.Push(x)
		case oMLOAD:
			x := bm.stack.Pop()
			bm.stack.Push(bm.mem[x.String()])
		case oMSTORE:
			x, y := bm.stack.Popn()
			bm.mem[x.String()] = y
		case oSLOAD:
			// Load the value in storage and push it on the stack
			x := bm.stack.Pop()
			// decode the object as a big integer
			decoder := ethutil.NewRlpDecoder([]byte(contract.State().Get(x.String())))
			if !decoder.IsNil() {
				bm.stack.Push(decoder.AsBigInt())
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oSSTORE:
			// Store Y at index X
			x, y := bm.stack.Popn()
			contract.State().Update(x.String(), string(ethutil.Encode(y)))
		case oJMP:
			x := int(bm.stack.Pop().Uint64())
			// Set pc to x - 1 (minus one so the incrementing at the end won't effect it)
			pc = x
			pc--
		case oJMPI:
			x := bm.stack.Pop()
			// Set pc to x if it's non zero
			if x.Cmp(ethutil.BigFalse) != 0 {
				pc = int(x.Uint64())
				pc--
			}
		case oIND:
			bm.stack.Push(big.NewInt(int64(pc)))
		case oEXTRO:
			memAddr := bm.stack.Pop()
			contractAddr := bm.stack.Pop().Bytes()

			// Push the contract's memory on to the stack
			bm.stack.Push(getContractMemory(block, contractAddr, memAddr))
		case oBALANCE:
			// Pushes the balance of the popped value on to the stack
			d := block.State().Get(bm.stack.Pop().String())
			ether := ethutil.NewEtherFromData([]byte(d))
			bm.stack.Push(ether.Amount)
		case oMKTX:
			value, addr := bm.stack.Popn()
			from, length := bm.stack.Popn()

			j := 0
			dataItems := make([]string, int(length.Uint64()))
			for i := from.Uint64(); i < length.Uint64(); i++ {
				dataItems[j] = string(bm.mem[strconv.Itoa(int(i))].Bytes())
				j++
			}
			// TODO sign it?
			tx := ethutil.NewTransaction(string(addr.Bytes()), value, dataItems)
			// Add the transaction to the tx pool
			bm.server.txPool.QueueTransaction(tx)
		case oSUICIDE:
			//addr := bm.stack.Pop()
		}
		pc++
	}

	bm.stack.Print()
}