func (dag *Dagger) Search(hash, diff *big.Int) *big.Int { // TODO fix multi threading. Somehow it results in the wrong nonce amountOfRoutines := 1 dag.hash = hash obj := ethutil.BigPow(2, 256) obj = obj.Div(obj, diff) Found = false resChan := make(chan int64, 3) var res int64 for k := 0; k < amountOfRoutines; k++ { go dag.Find(obj, resChan) } // Wait for each go routine to finish for k := 0; k < amountOfRoutines; k++ { // Get the result from the channel. 0 = quit if r := <-resChan; r != 0 { res = r } } return big.NewInt(res) }
func (dag *Dagger) Eval(N *big.Int) *big.Int { pow := ethutil.BigPow(2, 26) dag.xn = pow.Div(N, pow) sha := sha3.NewKeccak256() sha.Reset() ret := new(big.Int) for k := 0; k < 4; k++ { d := sha3.NewKeccak256() b := new(big.Int) d.Reset() d.Write(dag.hash.Bytes()) d.Write(dag.xn.Bytes()) d.Write(N.Bytes()) d.Write(big.NewInt(int64(k)).Bytes()) b.SetBytes(Sum(d)) pk := (b.Uint64() & 0x1ffffff) sha.Write(dag.Node(9, pk).Bytes()) } return ret.SetBytes(Sum(sha)) }
func (dag *Dagger) Verify(hash, diff, nonce *big.Int) bool { dag.hash = hash obj := ethutil.BigPow(2, 256) obj = obj.Div(obj, diff) return dag.Eval(nonce).Cmp(obj) < 0 }
func BenchmarkDaggerSearch(b *testing.B) { hash := big.NewInt(0) diff := ethutil.BigPow(2, 36) o := big.NewInt(0) // nonce doesn't matter. We're only testing against speed, not validity // Reset timer so the big generation isn't included in the benchmark b.ResetTimer() // Validate DaggerVerify(hash, diff, o) }
func AddTestNetFunds(block *Block) { for _, addr := range []string{ "8a40bfaa73256b60764c1bf40675a99083efb075", // Gavin "e6716f9544a56c530d868e4bfbacb172315bdead", // Jeffrey "1e12515ce3e0f817a4ddef9ca55788a1d66bd2df", // Vit "1a26338f0d905e295fccb71fa9ea849ffa12aaf4", // Alex } { //log.Println("2^200 Wei to", addr) codedAddr := ethutil.FromHex(addr) addr := block.state.GetAccount(codedAddr) addr.Amount = ethutil.BigPow(2, 200) block.state.UpdateAccount(codedAddr, addr) } }
func (pow *EasyPow) Verify(hash []byte, diff *big.Int, nonce []byte) bool { sha := sha3.NewKeccak256() d := append(hash, nonce...) sha.Write(d) v := ethutil.BigPow(2, 256) ret := new(big.Int).Div(v, diff) res := new(big.Int) res.SetBytes(sha.Sum(nil)) return res.Cmp(ret) == -1 }
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 (bc *BlockChain) NewBlock(coinbase []byte) *Block { var root interface{} var lastBlockTime int64 hash := ZeroHash256 if bc.CurrentBlock != nil { root = bc.CurrentBlock.state.Trie.Root hash = bc.LastBlockHash lastBlockTime = bc.CurrentBlock.Time } block := CreateBlock( root, hash, coinbase, ethutil.BigPow(2, 32), nil, "") block.MinGasPrice = big.NewInt(10000000000000) if bc.CurrentBlock != nil { var mul *big.Int if block.Time < lastBlockTime+42 { mul = big.NewInt(1) } else { mul = big.NewInt(-1) } diff := new(big.Int) diff.Add(diff, bc.CurrentBlock.Difficulty) diff.Div(diff, big.NewInt(1024)) diff.Mul(diff, mul) diff.Add(diff, bc.CurrentBlock.Difficulty) block.Difficulty = diff block.Number = new(big.Int).Add(bc.CurrentBlock.Number, ethutil.Big1) block.GasLimit = block.CalcGasLimit(bc.CurrentBlock) } return block }
func (bc *BlockChain) NewBlock(coinbase []byte, txs []*Transaction) *Block { var root interface{} var lastBlockTime int64 hash := ZeroHash256 if bc.CurrentBlock != nil { root = bc.CurrentBlock.state.trie.Root hash = bc.LastBlockHash lastBlockTime = bc.CurrentBlock.Time } block := CreateBlock( root, hash, coinbase, ethutil.BigPow(2, 32), nil, "", txs) if bc.CurrentBlock != nil { var mul *big.Int if block.Time < lastBlockTime+42 { mul = big.NewInt(1) } else { mul = big.NewInt(-1) } diff := new(big.Int) diff.Add(diff, bc.CurrentBlock.Difficulty) diff.Div(diff, big.NewInt(1024)) diff.Mul(diff, mul) diff.Add(diff, bc.CurrentBlock.Difficulty) block.Difficulty = diff } return block }
func (i *Console) ParseInput(input string) bool { scanner := bufio.NewScanner(strings.NewReader(input)) scanner.Split(bufio.ScanWords) count := 0 var tokens []string for scanner.Scan() { count++ tokens = append(tokens, scanner.Text()) } if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "reading input:", err) } if len(tokens) == 0 { return true } err := i.ValidateInput(tokens[0], count-1) if err != nil { fmt.Println(err) } else { switch tokens[0] { case "update": i.trie.Update(tokens[1], tokens[2]) i.PrintRoot() case "get": fmt.Println(i.trie.Get(tokens[1])) case "root": i.PrintRoot() case "rawroot": fmt.Println(i.trie.Root) case "print": i.db.Print() case "dag": fmt.Println(ethchain.DaggerVerify(ethutil.Big(tokens[1]), // hash ethutil.BigPow(2, 36), // diff ethutil.Big(tokens[2]))) // nonce case "decode": value := ethutil.NewValueFromBytes([]byte(tokens[1])) fmt.Println(value) case "getaddr": encoded, _ := hex.DecodeString(tokens[1]) addr := i.ethereum.BlockManager.BlockChain().CurrentBlock.GetAddr(encoded) fmt.Println("addr:", addr) case "block": encoded, _ := hex.DecodeString(tokens[1]) block := i.ethereum.BlockManager.BlockChain().GetBlock(encoded) fmt.Println(block) case "say": i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]}) case "addp": i.ethereum.ConnectToPeer(tokens[1]) case "pcount": fmt.Println("peers:", i.ethereum.Peers().Len()) case "encode": fmt.Printf("%q\n", ethutil.Encode(tokens[1])) case "tx": recipient, err := hex.DecodeString(tokens[1]) if err != nil { fmt.Println("recipient err:", err) } else { tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) keyRing := ethutil.NewValueFromBytes(data) tx.Sign(keyRing.Get(0).Bytes()) fmt.Printf("%x\n", tx.Hash()) i.ethereum.TxPool.QueueTransaction(tx) } case "gettx": addr, _ := hex.DecodeString(tokens[1]) data, _ := ethutil.Config.Db.Get(addr) if len(data) != 0 { decoder := ethutil.NewValueFromBytes(data) fmt.Println(decoder) } else { fmt.Println("gettx: tx not found") } case "contract": contract := ethchain.NewTransaction([]byte{}, ethutil.Big(tokens[1]), []string{"PUSH", "1234"}) fmt.Printf("%x\n", contract.Hash()) i.ethereum.TxPool.QueueTransaction(contract) case "exit", "quit", "q": return false case "help": fmt.Printf("COMMANDS:\n" + "\033[1m= DB =\033[0m\n" + "update KEY VALUE - Updates/Creates a new value for the given key\n" + "get KEY - Retrieves the given key\n" + "root - Prints the hex encoded merkle root\n" + "rawroot - Prints the raw merkle root\n" + "block HASH - Prints the block\n" + "getaddr ADDR - Prints the account associated with the address\n" + "\033[1m= Dagger =\033[0m\n" + "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" + "\033[1m= Encoding =\033[0m\n" + "decode STR\n" + "encode STR\n" + "\033[1m= Other =\033[0m\n" + "addp HOST:PORT\n" + "tx TO AMOUNT\n" + "contract AMOUNT\n") default: fmt.Println("Unknown command:", tokens[0]) } } return true }
package ethvm import ( "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethutil" "math/big" ) var vmlogger = ethlog.NewLogger("VM") var ( GasStep = big.NewInt(1) GasSha = big.NewInt(20) GasSLoad = big.NewInt(20) GasSStore = big.NewInt(100) GasBalance = big.NewInt(20) GasCreate = big.NewInt(100) GasCall = big.NewInt(20) GasMemory = big.NewInt(1) GasData = big.NewInt(5) GasTx = big.NewInt(500) Pow256 = ethutil.BigPow(2, 256) LogTyPretty byte = 0x1 LogTyDiff byte = 0x2 )
*/ var ZeroHash256 = make([]byte, 32) var ZeroHash160 = make([]byte, 20) var EmptyShaList = ethutil.Sha3Bin(ethutil.Encode([]interface{}{})) var GenesisHeader = []interface{}{ // Previous hash (none) //"", ZeroHash256, // Sha of uncles ethutil.Sha3Bin(ethutil.Encode([]interface{}{})), // Coinbase ZeroHash160, // Root state "", // Sha of transactions //EmptyShaList, ethutil.Sha3Bin(ethutil.Encode([]interface{}{})), // Difficulty ethutil.BigPow(2, 22), // Time int64(0), // Extra "", // Nonce ethutil.Sha3Bin(big.NewInt(42).Bytes()), } var Genesis = []interface{}{GenesisHeader, []interface{}{}, []interface{}{}}
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) }