package main
import (
"crypto/rand"
"fmt"
"github.com/ava-labs/coreth"
"github.com/ava-labs/coreth/core"
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/eth"
"github.com/ava-labs/coreth/params"
"github.com/ava-labs/go-ethereum/common"
"github.com/ava-labs/go-ethereum/common/hexutil"
"github.com/ava-labs/go-ethereum/log"
"math/big"
)
func checkError(err error) {
if err != nil {
panic(err)
}
}
func main() {
// configure the chain
config := eth.DefaultConfig
config.ManualCanonical = true
chainConfig := ¶ms.ChainConfig{
ChainID: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
DAOForkBlock: big.NewInt(0),
DAOForkSupport: true,
EIP150Block: big.NewInt(0),
EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: nil,
Ethash: nil,
}
// configure the genesis block
genBalance := big.NewInt(100000000000000000)
genKey, _ := coreth.NewKey(rand.Reader)
config.Genesis = &core.Genesis{
Config: chainConfig,
Nonce: 0,
Number: 0,
ExtraData: hexutil.MustDecode("0x00"),
GasLimit: 100000000,
Difficulty: big.NewInt(0),
Alloc: core.GenesisAlloc{genKey.Address: {Balance: genBalance}},
}
// grab the control of block generation and disable auto uncle
config.Miner.ManualMining = true
config.Miner.DisableUncle = true
// info required to generate a transaction
chainID := chainConfig.ChainID
nonce := uint64(0)
value := big.NewInt(1000000000000)
gasLimit := 21000
gasPrice := big.NewInt(1000000000)
bob, err := coreth.NewKey(rand.Reader)
checkError(err)
chain := coreth.NewETHChain(&config, nil, nil, nil)
showBalance := func() {
state, err := chain.CurrentState()
checkError(err)
log.Info(fmt.Sprintf("genesis balance = %s", state.GetBalance(genKey.Address)))
log.Info(fmt.Sprintf("bob's balance = %s", state.GetBalance(bob.Address)))
}
chain.SetOnHeaderNew(func(header *types.Header) {
hid := make([]byte, 32)
_, err := rand.Read(hid)
if err != nil {
panic("cannot generate hid")
}
header.Extra = append(header.Extra, hid...)
})
newBlockChan := make(chan *types.Block)
newTxPoolHeadChan := make(chan core.NewTxPoolHeadEvent, 1)
chain.SetOnSealFinish(func(block *types.Block) error {
newBlockChan <- block
return nil
})
chain.GetTxPool().SubscribeNewHeadEvent(newTxPoolHeadChan)
// start the chain
chain.Start()
for i := 0; i < 42; i++ {
tx := types.NewTransaction(nonce, bob.Address, value, uint64(gasLimit), gasPrice, nil)
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), genKey.PrivateKey)
checkError(err)
chain.AddRemoteTxs([]*types.Transaction{signedTx})
nonce++
chain.GenBlock()
block := <-newBlockChan
<-newTxPoolHeadChan
log.Info("finished generating block, starting the next iteration", "height", block.Number())
}
showBalance()
chain.Stop()
}