github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/core/chain_makers_test.go (about)

     1  package core
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  
     7  	"github.com/quickchainproject/quickchain/consensus/qcthash"
     8  	"github.com/quickchainproject/quickchain/core/types"
     9  	"github.com/quickchainproject/quickchain/core/vm"
    10  	"github.com/quickchainproject/quickchain/crypto"
    11  	"github.com/quickchainproject/quickchain/qctdb"
    12  	"github.com/quickchainproject/quickchain/params"
    13  )
    14  
    15  func ExampleGenerateChain() {
    16  	var (
    17  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
    18  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
    19  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
    20  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
    21  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
    22  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
    23  		db, _   = qctdb.NewMemDatabase()
    24  	)
    25  
    26  	// Ensure that key1 has some funds in the genesis block.
    27  	gspec := &Genesis{
    28  		Config: &params.ChainConfig{HomesteadBlock: new(big.Int)},
    29  		Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}},
    30  	}
    31  	genesis := gspec.MustCommit(db)
    32  
    33  	// This call generates a chain of 5 blocks. The function runs for
    34  	// each block and adds different features to gen based on the
    35  	// block index.
    36  	signer := types.HomesteadSigner{}
    37  	chain, _ := GenerateChain(gspec.Config, genesis, qcthash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
    38  		switch i {
    39  		case 0:
    40  			// In block 1, addr1 sends addr2 some ether.
    41  			tx, _ := types.SignTx(types.NewTransaction(types.Binary, gen.TxNonce(addr1), addr2, big.NewInt(10000), params.TxGas, nil, nil), signer, key1)
    42  			gen.AddTx(tx)
    43  		case 1:
    44  			// In block 2, addr1 sends some more ether to addr2.
    45  			// addr2 passes it on to addr3.
    46  			tx1, _ := types.SignTx(types.NewTransaction(types.Binary, gen.TxNonce(addr1), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
    47  			tx2, _ := types.SignTx(types.NewTransaction(types.Binary, gen.TxNonce(addr2), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
    48  			gen.AddTx(tx1)
    49  			gen.AddTx(tx2)
    50  		case 2:
    51  			// Block 3 is empty but was mined by addr3.
    52  			gen.SetCoinbase(addr3)
    53  			gen.SetExtra([]byte("yeehaw"))
    54  		case 3:
    55  			// Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data).
    56  			b2 := gen.PrevBlock(1).Header()
    57  			b2.Extra = []byte("foo")
    58  			gen.AddUncle(b2)
    59  			b3 := gen.PrevBlock(2).Header()
    60  			b3.Extra = []byte("foo")
    61  			gen.AddUncle(b3)
    62  		}
    63  	})
    64  
    65  	// Import the chain. This runs all block validation rules.
    66  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, qcthash.NewFaker(), vm.Config{})
    67  	defer blockchain.Stop()
    68  
    69  	if i, err := blockchain.InsertChain(chain); err != nil {
    70  		fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
    71  		return
    72  	}
    73  
    74  	state, _ := blockchain.State()
    75  	fmt.Printf("last block: #%d\n", blockchain.CurrentBlock().Number())
    76  	fmt.Println("balance of addr1:", state.GetBalance(addr1))
    77  	fmt.Println("balance of addr2:", state.GetBalance(addr2))
    78  	fmt.Println("balance of addr3:", state.GetBalance(addr3))
    79  	// Output:
    80  	// last block: #5
    81  	// balance of addr1: 989000
    82  	// balance of addr2: 10000
    83  	// balance of addr3: 19687500000000001000
    84  }