func floor(n *big.Rat) *big.Rat { f := &big.Rat{} z := new(big.Int) z.Div(n.Num(), n.Denom()) f.SetInt(z) return f }
// hostconfigcmd is the handler for the command `siac host config [setting] [value]`. // Modifies host settings. func hostconfigcmd(param, value string) { switch param { case "price": // convert price to hastings/byte/block p, ok := new(big.Rat).SetString(value) if !ok { die("Could not parse price") } p.Mul(p, big.NewRat(1e24/1e9, 4320)) value = new(big.Int).Div(p.Num(), p.Denom()).String() case "totalstorage": // parse sizes of form 10GB, 10TB, 1TiB etc var err error value, err = parseSize(value) if err != nil { die("Could not parse totalstorage:", err) } case "minduration", "maxduration", "windowsize", "acceptingcontracts": // Other valid settings. default: // Reject invalid host config commands. die("\"" + param + "\" is not a host setting") } err := post("/host", param+"="+value) if err != nil { die("Could not update host settings:", err) } fmt.Println("Host settings updated.") }
func hostconfigcmd(param, value string) { // convert price to hastings/byte/block if param == "price" { p, ok := new(big.Rat).SetString(value) if !ok { fmt.Println("could not parse price") return } p.Mul(p, big.NewRat(1e24/1e9, 4320)) value = new(big.Int).Div(p.Num(), p.Denom()).String() } // parse sizes of form 10GB, 10TB, 1TiB etc if param == "totalstorage" { var err error value, err = parseSize(value) if err != nil { fmt.Println("could not parse " + param) } } err := post("/host", param+"="+value) if err != nil { fmt.Println("Could not update host settings:", err) return } fmt.Println("Host settings updated.") }
// MulRat returns a new Currency value c = x * y, where y is a big.Rat. func (x Currency) MulRat(y *big.Rat) (c Currency) { if y.Sign() < 0 { build.Critical(ErrNegativeCurrency) } else { c.i.Mul(&x.i, y.Num()) c.i.Div(&c.i, y.Denom()) } return }
// Returns a new big.Int set to the ceiling of x. func ratCeil(x *big.Rat) *big.Int { z := new(big.Int) m := new(big.Int) z.DivMod(x.Num(), x.Denom(), m) if m.Cmp(intZero) == 1 { z.Add(z, intOne) } return z }
func CalcGasLimit(parent *types.Block) *big.Int { // ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024 previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit()) current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed()), big.NewRat(6, 5)) curInt := new(big.Int).Div(current.Num(), current.Denom()) result := new(big.Int).Add(previous, curInt) result.Div(result, big.NewInt(1024)) return common.BigMax(params.GenesisGasLimit, result) }
func Round(r *big.Rat) *big.Rat { d := new(big.Int).Set(r.Denom()) n := new(big.Int).Set(r.Num()) n.Mod(n, d) if new(big.Int).Mul(n, big.NewInt(2)).Cmp(d) >= 0 { r.Add(r, new(big.Rat).SetInt64(1)) } r.Sub(r, new(big.Rat).SetFrac(n, d)) return r }
// RatToTarget converts a big.Rat to a Target. func RatToTarget(r *big.Rat) (t Target) { if r.Num().Sign() < 0 { if build.DEBUG { panic(ErrNegativeTarget) } } else { i := new(big.Int).Div(r.Num(), r.Denom()) t = IntToTarget(i) } return }
func (sqe scaleQuoExact) Scale(x, y *Dec) Scale { rem := new(big.Rat).SetFrac(x.UnscaledBig(), y.UnscaledBig()) f2, f5 := factor2(rem.Denom()), factor(rem.Denom(), bigInt[5]) var f10 Scale if f2 > f5 { f10 = Scale(f2) } else { f10 = Scale(f5) } return x.Scale() - y.Scale() + f10 }
// MulRat returns a new Currency value c = x * y, where y is a big.Rat. func (x Currency) MulRat(y *big.Rat) (c Currency) { if y.Sign() < 0 { if build.DEBUG { panic(ErrNegativeCurrency) } } else { c.i.Mul(&x.i, y.Num()) c.i.Div(&c.i, y.Denom()) } return }
// Do the numerator and denominator of r provide a solution to the equation // x**2 - D*(y**2) = 1? func isSolution(D int, r *big.Rat) bool { S := big.NewInt(int64(D)) x := r.Num() y := r.Denom() one := big.NewInt(1) two := big.NewInt(2) a := new(big.Int).Exp(x, two, nil) b := new(big.Int).Exp(y, two, nil) return new(big.Int).Sub(a, new(big.Int).Mul(S, b)).Cmp(one) == 0 }
// COMPATv0.4.0 - until the first 10e3 blocks have been archived, MulFloat is // needed while verifying the first set of blocks. // // MulFloat returns a new Currency value y = c * x, where x is a float64. // Behavior is undefined when x is negative. func (x Currency) MulFloat(y float64) (c Currency) { if y < 0 { build.Critical(ErrNegativeCurrency) } else { cRat := new(big.Rat).Mul( new(big.Rat).SetInt(&x.i), new(big.Rat).SetFloat64(y), ) c.i.Div(cRat.Num(), cRat.Denom()) } return }
func makeRat(x *big.Rat) Value { a := x.Num() b := x.Denom() if a.BitLen() < maxExp && b.BitLen() < maxExp { // ok to remain fraction return ratVal{x} } // components too large => switch to float fa := newFloat().SetInt(a) fb := newFloat().SetInt(b) return floatVal{fa.Quo(fa, fb)} }
func (v value) toInt() *big.Int { switch v := v.v.(type) { case *big.Int: return v case *big.Rat: // TODO rounding? return new(big.Int).Quo(v.Num(), v.Denom()) case float64: r := new(big.Rat).SetFloat64(v) if r == nil { fatalf("cannot convert %v to float64", v) } // TODO rounding? return new(big.Int).Quo(r.Num(), r.Denom()) } panic(fmt.Errorf("unexpected type %T", v.v)) }
func (block *Block) CalcGasLimit(parent *Block) *big.Int { if block.Number.Cmp(big.NewInt(0)) == 0 { return ethutil.BigPow(10, 6) } // ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024 previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit) current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed), big.NewRat(6, 5)) curInt := new(big.Int).Div(current.Num(), current.Denom()) result := new(big.Int).Add(previous, curInt) result.Div(result, big.NewInt(1024)) min := big.NewInt(125000) return ethutil.BigMax(min, result) }
func hostconfigcmd(param, value string) { // convert price to hastings/byte/block if param == "price" { p, ok := new(big.Rat).SetString(value) if !ok { fmt.Println("could not parse price") return } p.Mul(p, big.NewRat(1e24/1e9, 4320)) value = new(big.Int).Div(p.Num(), p.Denom()).String() } err := post("/host/configure", param+"="+value) if err != nil { fmt.Println("Could not update host settings:", err) return } fmt.Println("Host settings updated.") }
// bigRatToValue converts 'number' to an SQL value with SQL type: valueType. // If valueType is integral it truncates 'number' to the integer part according to the // semantics of the big.Rat.Int method. func bigRatToValue(number *big.Rat, valueType querypb.Type) sqltypes.Value { var numberAsBytes []byte switch { case sqltypes.IsIntegral(valueType): // 'number.Num()' returns a reference to the numerator of 'number'. // We copy it here to avoid changing 'number'. truncatedNumber := new(big.Int).Set(number.Num()) truncatedNumber.Quo(truncatedNumber, number.Denom()) numberAsBytes = bigIntToSliceOfBytes(truncatedNumber) case sqltypes.IsFloat(valueType): // Truncate to the closest 'float'. // There's not much we can do if there isn't an exact representation. numberAsFloat64, _ := number.Float64() numberAsBytes = strconv.AppendFloat([]byte{}, numberAsFloat64, 'f', -1, 64) default: panic(fmt.Sprintf("Unsupported type: %v", valueType)) } result, err := sqltypes.ValueFromBytes(valueType, numberAsBytes) if err != nil { panic(fmt.Sprintf("sqltypes.ValueFromBytes failed with: %v", err)) } return result }
// ratExponent returns the power of ten that x would display in scientific notation. func ratExponent(x *big.Rat) int { if x.Sign() < 0 { x.Neg(x) } e := 0 invert := false if x.Num().Cmp(x.Denom()) < 0 { invert = true x.Inv(x) e++ } for x.Cmp(bigRatBillion) >= 0 { e += 9 x.Quo(x, bigRatBillion) } for x.Cmp(bigRatTen) > 0 { e++ x.Quo(x, bigRatTen) } if invert { return -e } return e }
// See https://en.wikipedia.org/wiki/Farey_sequence // The value of the new term in between neighbours 2/5 and 3/7 is found by // computing the mediant of those neighbours. We can take result to be the next // left-hand neighbour of 3/7 iteratively until the denominator reaches 1e6. func mediant(x, y *big.Rat) *big.Rat { num := new(big.Int).Add(x.Num(), y.Num()) denom := new(big.Int).Add(x.Denom(), y.Denom()) return new(big.Rat).SetFrac(num, denom) }
// 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() }
// Creates a new fraction from a rational number (big.Rat) func NewFractionFromRat(rat *big.Rat) *Fraction { // Ignore error since *big.Rat denom can't be 0 frac, _ := NewFraction(rat.Num().Int64(), rat.Denom().Int64()) return frac }
func checkNumerator(x *big.Rat) bool { num, denom := x.Num(), x.Denom() return numDigits(num) > numDigits(denom) }
func savePiState(iteration int, sum *big.Rat) { file, _ := os.OpenFile("pi_cache", os.O_WRONLY|os.O_CREATE, 400) enc := json.NewEncoder(file) enc.Encode(PiState{iteration, sum.Num().String(), sum.Denom().String()}) file.Close() }
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) }
// Sqrt returns a new Currency value y = sqrt(c). Result is rounded down to the // nearest integer. func (x Currency) Sqrt() (c Currency) { f, _ := new(big.Rat).SetInt(&x.i).Float64() sqrt := new(big.Rat).SetFloat64(math.Sqrt(f)) c.i.Div(sqrt.Num(), sqrt.Denom()) return }
func (x *exporter) exportName(t interface{}) { switch t := t.(type) { case *types.Var: if t.Anonymous() || t.Name() == "" { x.write("? ") } else { x.write("%s ", t.Name()) } x.exportName(t.Type()) case exact.Value: switch t.Kind() { case exact.Float: x.exportName(&ast.BasicLit{Value: t.String()}) default: x.write(t.String()) } case *types.Basic: if t.Kind() == types.UnsafePointer { x.write("@\"unsafe\".Pointer") } else if t.Info()&types.IsUntyped == 0 { x.write(t.String()) } case *types.TypeName: if t.Pkg() == nil { switch t.Name() { case "error": x.write("error") return case "Pointer": x.write("@\"unsafe\".Pointer") return } } if t.Pkg() == x.pkg || t.Pkg() == nil { x.write("@\"\".") } else { x.write("@\"%s\".", t.Pkg().Path()) } x.write(t.Name()) case *types.Named: x.exportName(t.Obj()) case *types.Slice: x.write("[]") x.exportName(t.Elem()) case *types.Pointer: x.write("*") x.exportName(t.Elem()) case *types.Map: x.write("map[") x.exportName(t.Key()) x.write("]") x.exportName(t.Elem()) case *types.Chan: if t.Dir() == types.RecvOnly { x.write("<-") } x.write("chan") if t.Dir() == types.SendOnly { x.write("<-") } x.write(" ") x.exportName(t.Elem()) case *ast.BasicLit: var b big.Rat fmt.Sscan(t.Value, &b) num, denom := b.Num(), b.Denom() if denom.Int64() == 1 { x.write("%d", num.Int64()) return } // So yeah, this bit deserves a comment. We have a big.Rat number represented by its // numerator and denominator, and we want to turn this into a base 2 exponent form // where: // // num / denom = x * 2^exp // (num / denum) / x = 2^exp // log2((num / denum) / x) = exp // // x and exp need to be integers as gc export data parses fractional numbers in the form of // // int_lit [ "p" int_lit ] // // Initially we just set x = 1 / denum turning the equation to // // log2(num) = exp // // But we want exp to be an integer so it's rounded up, which is just the number of bits // needed to represent num. // // After this rounding however, x != 1 / denum, but we have the exact value of everything // else so we could just plug every known variable in: // // num / denom = x * 2^exp // // But as exp is currently a positive value, x must be a fractional number which is // what we were trying to get rid of in the first place! // // So instead, we make x a large number that is divided by 2^exp which allows us to do this: // // num / denom = x / 2^exp // num / denom = x * 2^-exp // // And solving for x we get: // // (num / denom) / 2^-exp = x // (2^exp * num) / denom = x // // There's still a division in there though leading to a precision loss due to x and exp being constrained // to integer values. By making exp large enough we can add in precision that way. It needs to be at // least big enough to fit // // newexp = log2(2^exp * denom) = log2(num) + log2(denom) // // and as it needs to be an integer value it also needs to be adjusted up to allow more fractional precision. // // I have no specific theoretical reason for choosing the fractional precision bits here, and it can be // changed if needed. One could say that the fractional accuracy in the final x number would be // // 1/(2^fractional_accuracy_bits) // // and 23 is the number of fractional bits used by the IEEE_754-2008 binary32 format. const fractional_accuracy_bits = 23 exp := num.BitLen() + denom.BitLen() + fractional_accuracy_bits exporter := x x := big.NewInt(2) x.Exp(x, big.NewInt(int64(exp)), nil) x.Mul(x, num) x.Div(x, denom) exporter.write("%dp-%d", x, exp) case *types.Tuple: for i := 0; i < t.Len(); i++ { if i > 0 { x.write(", ") } ta := t.At(i) n := ta.Name() if n == "" { n = "?" } else { n = `@"".` + n } x.write(n) x.write(" ") x.exportName(ta.Type()) } case *types.Signature: if x.writeFunc { x.write("func") } else { x.writeFunc = true } x.write("(") if p := t.Params(); p != nil { if t.IsVariadic() { for i := 0; i < p.Len(); i++ { if i > 0 { x.write(", ") } ta := p.At(i) n := ta.Name() if n == "" { n = "?" } else { n = `@"".` + n } x.write(n) x.write(" ") ty := ta.Type() if i+1 == p.Len() { x.write("...") ty = ty.(*types.Slice).Elem() } x.exportName(ty) } } else { x.exportName(p) } } x.write(")") if r := t.Results(); r != nil { x.write("(") x.exportName(r) x.write(")") } case *types.Struct: x.write("struct { ") for i := 0; i < t.NumFields(); i++ { if i > 0 { x.write("; ") } f := t.Field(i) x.exportName(f) } x.write(" }") case *types.Array: x.write("[%d]", t.Len()) x.exportName(t.Elem()) case *types.Interface: x.write("interface { ") for i := 0; i < t.NumMethods(); i++ { if i > 0 { x.write("; ") } m := t.Method(i) x.write(m.Name()) x.writeFunc = false x.exportName(m.Type()) } x.write(" }") default: panic(fmt.Sprintf("UNHANDLED %T", t)) } }
func (f *frac) fromRat(r *big.Rat) { *f.Numerator = int32(r.Num().Int64()) *f.Denominator = int32(r.Denom().Int64()) }