Example #1
0
// Convert attempts to convert the constant x to a given type.
// If the attempt is successful, the result is the new constant;
// otherwise the result is invalid.
func (x Const) Convert(typ *Type) Const {
	// TODO(gri) implement this
	switch x := x.Val.(type) {
	//case bool:
	case *big.Int:
		switch Underlying(*typ) {
		case Float32, Float64:
			var z big.Rat
			z.SetInt(x)
			return Const{&z}
		case String:
			return Const{string(x.Int64())}
		case Complex64, Complex128:
			var z big.Rat
			z.SetInt(x)
			return Const{Cmplx{&z, &big.Rat{}}}
		}
	case *big.Rat:
		switch Underlying(*typ) {
		case Byte, Int, Uint, Int8, Uint8, Int16, Uint16, Int32, Uint32, Int64, Uint64:
			// Convert to an integer. Remove the fractional component.
			num, denom := x.Num(), x.Denom()
			var z big.Int
			z.Quo(num, denom)
			return Const{&z}
		}
		//case Cmplx:
		//case string:
	}
	//panic("unimplemented")
	return x
}
func (me *StatisticalAccumulator) PutInt(x *big.Int) {

	xx := new(big.Rat)
	xx.SetInt(x)

	me.PutRat(xx)
}
Example #3
0
// Float64 returns the numeric value of this literal truncated to fit
// a float64.
//
func (l *Literal) Float64() float64 {
	switch x := l.Value.(type) {
	case int64:
		return float64(x)
	case *big.Int:
		var r big.Rat
		f, _ := r.SetInt(x).Float64()
		return f
	case *big.Rat:
		f, _ := x.Float64()
		return f
	}
	panic(fmt.Sprintf("unexpected literal value: %T", l.Value))
}
func main() {
	ln2, _ := new(big.Rat).SetString("0.6931471805599453094172")
	h := big.NewRat(1, 2)
	h.Quo(h, ln2)
	var f big.Rat
	var w big.Int
	for i := int64(1); i <= 17; i++ {
		h.Quo(h.Mul(h, f.SetInt64(i)), ln2)
		w.Quo(h.Num(), h.Denom())
		f.Sub(h, f.SetInt(&w))
		y, _ := f.Float64()
		d := fmt.Sprintf("%.3f", y)
		fmt.Printf("n: %2d  h: %18d%s  Nearly integer: %t\n",
			i, &w, d[1:], d[2] == '0' || d[2] == '9')
	}
}
Example #5
0
// Match attempts to match the internal constant representations of x and y.
// If the attempt is successful, the result is the values of x and y,
// if necessary converted to have the same internal representation; otherwise
// the results are invalid.
func (x Const) Match(y Const) (u, v Const) {
	switch a := x.val.(type) {
	case bool:
		if _, ok := y.val.(bool); ok {
			u, v = x, y
		}
	case *big.Int:
		switch y.val.(type) {
		case *big.Int:
			u, v = x, y
		case *big.Rat:
			var z big.Rat
			z.SetInt(a)
			u, v = Const{&z}, y
		case cmplx:
			var z big.Rat
			z.SetInt(a)
			u, v = Const{cmplx{&z, big.NewRat(0, 1)}}, y
		}
	case *big.Rat:
		switch y.val.(type) {
		case *big.Int:
			v, u = y.Match(x)
		case *big.Rat:
			u, v = x, y
		case cmplx:
			u, v = Const{cmplx{a, big.NewRat(0, 0)}}, y
		}
	case cmplx:
		switch y.val.(type) {
		case *big.Int, *big.Rat:
			v, u = y.Match(x)
		case cmplx:
			u, v = x, y
		}
	case string:
		if _, ok := y.val.(string); ok {
			u, v = x, y
		}
	default:
		panic("unreachable")
	}
	return
}
Example #6
0
File: etc.go Project: pkf/ql
//TODO collate1 should return errors instead of panicing
func collate1(a, b interface{}) int {
	switch x := a.(type) {
	case nil:
		if b != nil {
			return -1
		}

		return 0
	case bool:
		switch y := b.(type) {
		case nil:
			return 1
		case bool:
			if !x && y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		default:
			// Make bool collate before anything except nil and
			// other bool for index seeking first non NULL value.
			return -1
		}
	case idealComplex:
		switch y := b.(type) {
		case nil:
			return 1
		case idealComplex:
			if x == y {
				return 0
			}

			if real(x) < real(y) {
				return -1
			}

			if real(x) > real(y) {
				return 1
			}

			if imag(x) < imag(y) {
				return -1
			}

			return 1
		case complex64:
			{
				x, y := complex64(x), complex64(y)
				if x == y {
					return 0
				}

				if real(x) < real(y) {
					return -1
				}

				if real(x) > real(y) {
					return 1
				}

				if imag(x) < imag(y) {
					return -1
				}

				return 1
			}
		case complex128:
			{
				x := complex128(x)
				if x == y {
					return 0
				}

				if real(x) < real(y) {
					return -1
				}

				if real(x) > real(y) {
					return 1
				}

				if imag(x) < imag(y) {
					return -1
				}

				return 1
			}
		default:
			panic("internal error 012")
		}
	case idealUint:
		switch y := b.(type) {
		case nil:
			return 1
		case idealUint:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case uint8:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case uint16:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case uint32:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case uint64:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case uint:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 013")
		}
	case idealRune:
		switch y := b.(type) {
		case nil:
			return 1
		case idealRune:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case int8:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case int16:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case int32:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case int64:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case int:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 014")
		}
	case idealInt:
		switch y := b.(type) {
		case nil:
			return 1
		case idealInt:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case int8:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case int16:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case int32:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case int64:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case int:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 015")
		}
	case idealFloat:
		switch y := b.(type) {
		case nil:
			return 1
		case idealFloat:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case float32:
			{
				x, y := float64(x), float64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case float64:
			{
				x, y := float64(x), float64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 016")
		}
	case complex64:
		switch y := b.(type) {
		case nil:
			return 1
		case complex64:
			if x == y {
				return 0
			}

			if real(x) < real(y) {
				return -1
			}

			if real(x) > real(y) {
				return 1
			}

			if imag(x) < imag(y) {
				return -1
			}

			return 1
		case idealComplex:
			{
				x, y := complex64(x), complex64(y)
				if x == y {
					return 0
				}

				if real(x) < real(y) {
					return -1
				}

				if real(x) > real(y) {
					return 1
				}

				if imag(x) < imag(y) {
					return -1
				}

				return 1
			}
		default:
			panic("internal error 017")
		}
	case complex128:
		switch y := b.(type) {
		case nil:
			return 1
		case complex128:
			if x == y {
				return 0
			}

			if real(x) < real(y) {
				return -1
			}

			if real(x) > real(y) {
				return 1
			}

			if imag(x) < imag(y) {
				return -1
			}

			return 1
		case idealComplex:
			{
				x, y := complex128(x), complex128(y)
				if x == y {
					return 0
				}

				if real(x) < real(y) {
					return -1
				}

				if real(x) > real(y) {
					return 1
				}

				if imag(x) < imag(y) {
					return -1
				}

				return 1
			}
		default:
			panic("internal error 018")
		}
	case float32:
		switch y := b.(type) {
		case nil:
			return 1
		case float32:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case idealFloat:
			{
				x, y := float32(x), float32(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 019")
		}
	case float64:
		switch y := b.(type) {
		case nil:
			return 1
		case float64:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case idealFloat:
			{
				x, y := float64(x), float64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 020")
		}
	case int8:
		switch y := b.(type) {
		case nil:
			return 1
		case int8:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case idealInt:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 021")
		}
	case int16:
		switch y := b.(type) {
		case nil:
			return 1
		case int16:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case idealInt:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 022")
		}
	case int32:
		switch y := b.(type) {
		case nil:
			return 1
		case int32:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case idealInt:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 023")
		}
	case int64:
		switch y := b.(type) {
		case nil:
			return 1
		case int64:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case idealInt:
			{
				x, y := int64(x), int64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			//dbg("%T(%#v)", b, b)
			panic("internal error 024")
		}
	case uint8:
		switch y := b.(type) {
		case nil:
			return 1
		case uint8:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case idealInt:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case idealUint:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 025")
		}
	case uint16:
		switch y := b.(type) {
		case nil:
			return 1
		case uint16:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case idealInt:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case idealUint:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 026")
		}
	case uint32:
		switch y := b.(type) {
		case nil:
			return 1
		case uint32:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case idealInt:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case idealUint:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 027")
		}
	case uint64:
		switch y := b.(type) {
		case nil:
			return 1
		case uint64:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		case idealInt:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		case idealUint:
			{
				x, y := uint64(x), uint64(y)
				if x < y {
					return -1
				}

				if x == y {
					return 0
				}

				return 1
			}
		default:
			panic("internal error 028")
		}
	case string:
		switch y := b.(type) {
		case nil:
			return 1
		case string:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		default:
			panic("internal error 029")
		}
	case []byte:
		switch y := b.(type) {
		case nil:
			return 1
		case []byte:
			return bytes.Compare(x, y)
		default:
			panic("internal error 030")
		}
	case *big.Int:
		switch y := b.(type) {
		case nil:
			return 1
		case *big.Int:
			return x.Cmp(y)
		case idealInt:
			{
				y := big.NewInt(int64(y))
				return x.Cmp(y)
			}
		case idealUint:
			{
				u := big.NewInt(0)
				u.SetUint64(uint64(y))
				return x.Cmp(u)
			}
		default:
			panic("internal error 031")
		}
	case *big.Rat:
		switch y := b.(type) {
		case nil:
			return 1
		case *big.Rat:
			return x.Cmp(y)
		case idealInt:
			{
				y := big.NewRat(int64(y), 1)
				return x.Cmp(y)
			}
		case idealUint:
			{
				u := big.NewInt(0)
				u.SetUint64(uint64(y))
				var y big.Rat
				y.SetInt(u)
				return x.Cmp(&y)
			}
		default:
			panic("internal error 032")
		}
	case time.Time:
		switch y := b.(type) {
		case nil:
			return 1
		case time.Time:
			if x.Before(y) {
				return -1
			}

			if x.Equal(y) {
				return 0
			}

			return 1
		default:
			panic("internal error 033")
		}
	case time.Duration:
		switch y := b.(type) {
		case nil:
			return 1
		case time.Duration:
			if x < y {
				return -1
			}

			if x == y {
				return 0
			}

			return 1
		default:
			panic("internal error 034")
		}
	case chunk:
		switch y := b.(type) {
		case nil:
			return 1
		case chunk:
			a, err := x.expand()
			if err != nil {
				log.Panic(err)
			}

			b, err := y.expand()
			if err != nil {
				log.Panic(err)
			}

			return collate1(a, b)
		default:
			panic("internal error 035")
		}
	default:
		panic("internal error 036")
	}
}
Example #7
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)
}
Example #8
0
// 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()
}