github.com/btcsuite/btcd@v0.24.0/blockchain/example_test.go (about)

     1  // Copyright (c) 2014-2016 The btcsuite developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package blockchain_test
     6  
     7  import (
     8  	"fmt"
     9  	"math/big"
    10  	"os"
    11  	"path/filepath"
    12  
    13  	"github.com/btcsuite/btcd/blockchain"
    14  	"github.com/btcsuite/btcd/btcutil"
    15  	"github.com/btcsuite/btcd/chaincfg"
    16  	"github.com/btcsuite/btcd/database"
    17  	_ "github.com/btcsuite/btcd/database/ffldb"
    18  )
    19  
    20  // This example demonstrates how to create a new chain instance and use
    21  // ProcessBlock to attempt to add a block to the chain.  As the package
    22  // overview documentation describes, this includes all of the Bitcoin consensus
    23  // rules.  This example intentionally attempts to insert a duplicate genesis
    24  // block to illustrate how an invalid block is handled.
    25  func ExampleBlockChain_ProcessBlock() {
    26  	// Create a new database to store the accepted blocks into.  Typically
    27  	// this would be opening an existing database and would not be deleting
    28  	// and creating a new database like this, but it is done here so this is
    29  	// a complete working example and does not leave temporary files laying
    30  	// around.
    31  	dbPath := filepath.Join(os.TempDir(), "exampleprocessblock")
    32  	_ = os.RemoveAll(dbPath)
    33  	db, err := database.Create("ffldb", dbPath, chaincfg.MainNetParams.Net)
    34  	if err != nil {
    35  		fmt.Printf("Failed to create database: %v\n", err)
    36  		return
    37  	}
    38  	defer os.RemoveAll(dbPath)
    39  	defer db.Close()
    40  
    41  	// Create a new BlockChain instance using the underlying database for
    42  	// the main bitcoin network.  This example does not demonstrate some
    43  	// of the other available configuration options such as specifying a
    44  	// notification callback and signature cache.  Also, the caller would
    45  	// ordinarily keep a reference to the median time source and add time
    46  	// values obtained from other peers on the network so the local time is
    47  	// adjusted to be in agreement with other peers.
    48  	chain, err := blockchain.New(&blockchain.Config{
    49  		DB:          db,
    50  		ChainParams: &chaincfg.MainNetParams,
    51  		TimeSource:  blockchain.NewMedianTime(),
    52  	})
    53  	if err != nil {
    54  		fmt.Printf("Failed to create chain instance: %v\n", err)
    55  		return
    56  	}
    57  
    58  	// Process a block.  For this example, we are going to intentionally
    59  	// cause an error by trying to process the genesis block which already
    60  	// exists.
    61  	genesisBlock := btcutil.NewBlock(chaincfg.MainNetParams.GenesisBlock)
    62  	isMainChain, isOrphan, err := chain.ProcessBlock(genesisBlock,
    63  		blockchain.BFNone)
    64  	if err != nil {
    65  		fmt.Printf("Failed to process block: %v\n", err)
    66  		return
    67  	}
    68  	fmt.Printf("Block accepted. Is it on the main chain?: %v", isMainChain)
    69  	fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan)
    70  
    71  	// Output:
    72  	// Failed to process block: already have block 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
    73  }
    74  
    75  // This example demonstrates how to convert the compact "bits" in a block header
    76  // which represent the target difficulty to a big integer and display it using
    77  // the typical hex notation.
    78  func ExampleCompactToBig() {
    79  	// Convert the bits from block 300000 in the main block chain.
    80  	bits := uint32(419465580)
    81  	targetDifficulty := blockchain.CompactToBig(bits)
    82  
    83  	// Display it in hex.
    84  	fmt.Printf("%064x\n", targetDifficulty.Bytes())
    85  
    86  	// Output:
    87  	// 0000000000000000896c00000000000000000000000000000000000000000000
    88  }
    89  
    90  // This example demonstrates how to convert a target difficulty into the compact
    91  // "bits" in a block header which represent that target difficulty .
    92  func ExampleBigToCompact() {
    93  	// Convert the target difficulty from block 300000 in the main block
    94  	// chain to compact form.
    95  	t := "0000000000000000896c00000000000000000000000000000000000000000000"
    96  	targetDifficulty, success := new(big.Int).SetString(t, 16)
    97  	if !success {
    98  		fmt.Println("invalid target difficulty")
    99  		return
   100  	}
   101  	bits := blockchain.BigToCompact(targetDifficulty)
   102  
   103  	fmt.Println(bits)
   104  
   105  	// Output:
   106  	// 419465580
   107  }