func searchHandler(w http.ResponseWriter, r *http.Request) { bchain.Lock() matches := make(map[coin.Hash]coin.Block) iter := bchain.db.NewIterator(util.BytesPrefix([]byte(BlockBucket)), nil) for iter.Next() { contents := string(iter.Value()) if !strings.Contains(contents, r.URL.Path) { continue } hex := hex.EncodeToString(iter.Key()[6:]) hash, err := coin.NewHash(hex) if err != nil { bchain.Unlock() httpError(w, http.StatusInternalServerError, "failed to make hash: %s", err) return } matches[hash] = coin.Block(contents) } blocks := make([]exploreBlock, len(matches)) i := 0 for id, b := range matches { pheader, err := bchain.getHeader(id) if err != nil { bchain.Unlock() httpError(w, http.StatusInternalServerError, "failed to load block header: %s", err) return } blocks[i] = exploreBlock{ ID: pheader.Header.Sum(), Header: pheader.Header, Block: b, BlockHeight: pheader.BlockHeight, IsMainChain: pheader.IsMainChain, EverMainChain: pheader.EverMainChain, TotalDifficulty: pheader.TotalDifficulty, Timestamp: time.Unix(0, pheader.Header.Timestamp), } i++ } bchain.Unlock() j, err := json.MarshalIndent(blocks, "", " ") if err != nil { httpError(w, http.StatusInternalServerError, "json encoding err: %s", err) return } w.Write(j) }
func (bc *blockchain) mineGenesisBlock() error { msg := "Never roll your own crypto" b := coin.Block(msg) genesisHeader = coin.Header{ MerkleRoot: sha256.Sum256([]byte(msg)), Difficulty: MinimumDifficulty, } // Calculate modulus dInt := new(big.Int).SetUint64(genesisHeader.Difficulty) mInt := new(big.Int).SetUint64(2) mInt.Exp(mInt, dInt, nil) ticker := time.NewTicker(90 * time.Second) getblocktemplate: genesisHeader.Timestamp = time.Now().UnixNano() hashMap := make(map[uint64][]uint64) i := uint64(0) for { select { case <-ticker.C: goto getblocktemplate default: break } genesisHeader.Nonces[0] = i aHash := genesisHeader.SumNonce(0) aInt := new(big.Int).SetBytes(aHash[:]) aInt.Mod(aInt, mInt) a := aInt.Uint64() if ns, ok := hashMap[a]; ok { if len(ns) == 2 { genesisHeader.Nonces[0] = ns[0] genesisHeader.Nonces[1] = ns[1] genesisHeader.Nonces[2] = i return bc.AddBlock(genesisHeader, b) } hashMap[a] = append(ns, i) } else { hashMap[a] = []uint64{i} } i++ } }
func blockHandler(w http.ResponseWriter, r *http.Request) { h, err := coin.NewHash(r.URL.Path) if err != nil { httpError(w, http.StatusBadRequest, "error reading hash: %s", err) return } // Lock and load header, then block bchain.Lock() ph, err := bchain.getHeader(h) if err != nil { bchain.Unlock() httpError(w, http.StatusNotFound, "header not found: %x", h[:]) return } blockBytes, err := bchain.getBlock(h) if err != nil { bchain.Unlock() httpError(w, http.StatusNotFound, "block not found: %x", h[:]) return } bchain.Unlock() fullBlock := exploreBlock{ ID: ph.Header.Sum(), Header: ph.Header, Block: coin.Block(blockBytes), BlockHeight: ph.BlockHeight, IsMainChain: ph.IsMainChain, EverMainChain: ph.EverMainChain, TotalDifficulty: ph.TotalDifficulty, Timestamp: time.Unix(0, ph.Header.Timestamp), } j, err := json.MarshalIndent(fullBlock, "", " ") if err != nil { httpError(w, http.StatusInternalServerError, "json encoding error: %s", err) return } w.Write(j) }