以太坊学习备忘录-dev开发模式

dev模式简要说明

主要用来给开发人员提供一个方便的开发测试环境。在dev模式下,可以轻松的获得以太币,方便发起交易,交易也会被快速的打包,节省时间方便验证。在启动命令里面加一个 --dev 即可启动该开发模式。

启动命令

下面提供一条使用dev模式启动的常用命令

geth --datadir ./data --networkid 1337 --nodiscover --http --http.corsdomain * --http.addr 0.0.0.0 --http.port 41230 --http.api eth,net,web3,personal,admin,miner,txpool,clique,debug --log.debug --verbosity 5 --dev --dev.period 0 --allow-insecure-unlock --log.debug --mine --miner.threads 1 console

dev 模式下面涉及到的一些参数单独说一下:

  • --dev 以dev模式启动启动链
  • --http.api 增加了一个 clique 的接口。这个接口用来动态调整出块人。
  • --dev.period 0 出块时间,如果设置为 0, 那么只有有交易发送到链上的时候才触发出块(也就是说不出空快)。如果非0,则是出块的间隔时间。

相关知识点

  • dev模式下面使用的共识算法是clique(即PoA)
  • dev模式下面,如果keystore下面没有账号,会帮我们创建一个账号,这个账号默认密码为空。如果有账号或者指定挖矿账号(即出块人的账号),那么你必须将这个账号的密码在启动命令里面传进去,否则账号无法解锁则会启动失败。
  • dev模式会打一大笔eth到出块人的账号下面,方便调试。

相关代码

  • 账号创建
    
    if list := MakePasswordList(ctx); len(list) > 0 {
    // Just take the first value. Although the function returns a possible multiple values and
    // some usages iterate through them as attempts, that doesn't make sense in this setting,
    // when we're definitely concerned with only one account.
    passphrase = list[0]
    }
    // setEtherbase has been called above, configuring the miner address from command line flags.
    if cfg.Miner.Etherbase != (common.Address{}) {
    developer = accounts.Account{Address: cfg.Miner.Etherbase}
    } else if accs := ks.Accounts(); len(accs) > 0 {
    developer = ks.Accounts()[0]
    } else {
    developer, err = ks.NewAccount(passphrase)
    if err != nil {
    Fatalf("Failed to create developer account: %v", err)
    }
    }
    if err := ks.Unlock(developer, passphrase); err != nil {
    Fatalf("Failed to unlock developer account: %v", err)
    }
    log.Info("Using developer account", "address", developer.Address)

// Create a new developer genesis block or reuse existing one
cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address)


* 创世块的设置
```go
func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
    // Override the default period to the user requested one
    config := *params.AllCliqueProtocolChanges
    config.Clique = &params.CliqueConfig{
        Period: period,
        Epoch:  config.Clique.Epoch,
    }

    // Assemble and return the genesis with the precompiles and faucet pre-funded
    return &Genesis{
        Config:     &config,
        ExtraData:  append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...),
        GasLimit:   11500000,
        BaseFee:    big.NewInt(params.InitialBaseFee),
        Difficulty: big.NewInt(1),
        Alloc: map[common.Address]GenesisAccount{
            common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
            common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256
            common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD
            common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity
            common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp
            common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd
            common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
            common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
            common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b
            faucet:                           {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
        },
    }
}
  • 出块间隔

    func (c *Clique) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
    header := block.Header()
    
    // Sealing the genesis block is not supported
    number := header.Number.Uint64()
    if number == 0 {
        return errUnknownBlock
    }
    // For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
    if c.config.Period == 0 && len(block.Transactions()) == 0 {
        log.Info("Sealing paused, waiting for transactions")
        return nil
    }

搭建一个基于PoA的四节点

dev模式下面只有一个节点,无法验证节点之间的交互。如果有需要,那么可以搭建一个基于PoA共识算法的多节点,大概步骤如下。

创建挖矿账号

使用命令geth --datadir node1 account new依次创建需要挖矿的账号,想要多少个节点就创建多少个节点。

创建genesis.json文件

使用交互式命令puppeth(自己编译一下cmd/puppeth下面的代码),根据提示创建一个genesis.json文件。创建出来的genesis.json文件内容类似如下:

{
  "config": {
    "chainId": 1205,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "istanbulBlock": 0,
    "clique": {
      "period": 15,
      "epoch": 30000
    }
  },
  "nonce": "0x0",
  "timestamp": "0x60de826f",
  "extraData": "0x000000000000000000000000000000000000000000000000000000000000000023893ab711b8a31f166e5977191a9acb737d49089ae5c0f24355ca814c0c99d7ee9637ec005fae18b3b1a10f515740ecf805c31c5c612935d60ba5eb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "gasLimit": "0x47b7600000",
  "difficulty": "0x1",
  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "alloc": {
    "23893ab711b8a31f166e5977191a9acb737d4908": {
      "balance": "0x200000000000000000000000000000000000000000000000000000000000000"
    },
    "9ae5c0f24355ca814c0c99d7ee9637ec005fae18": {
      "balance": "0x200000000000000000000000000000000000000000000000000000000000000"
    },
    "b3b1a10f515740ecf805c31c5c612935d60ba5eb": {
      "balance": "0x200000000000000000000000000000000000000000000000000000000000000"
    }
  },
  "number": "0x0",
  "gasUsed": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "baseFeePerGas": null
}

其中extraData里面有初始的出块人列表。alloc里面是默认账号的初始金额。

创建创世块

使用命令geth --datadir node1 init genesis.json依次创建创世块

启动节点

使用命令./geth --datadir ./node1 --ipcdisable --port 30001 --nodiscover --http --http.corsdomain "*" --http.addr 0.0.0.0 --http.port 41231 --http.api eth,net,web3,personal,admin,miner,txpool,clique --log.debug --verbosity 5 --allow-insecure-unlock console 启动链。参数根据自己需求进行增删。注意这个时候不要加 --dev 参数

解锁账号并开启挖矿

最好是在启动节点的时候将密码传进去直接解锁。

节点互连

由于启动的节点使用了 --nodiscover 参数。所以启动之后还没有链接起来,可以使用 RPC 接口 admin_addPeer 将节点互联起来。每次启动这么弄都很麻烦。可以在节点的数据库里面放一个 static-nodes.json 文件,跟目录 geth 同级即可。 static-nodes.json 文件内容大概如下:

[
    "enode://4d87f6cd87680adb4b51a80ed6bc7125640a29a953b7fd9a3e4ab21009a99436faa16bbb359994bcc9b89e52869abd3b0dc3908e2a368f49eb553609276836b2@127.0.0.1:30001",
    "enode://a3c958413831b2561273b6d2cc21c818e2675443872ba2077a66264d253d7525eb5b895647c37d3249439608506eb0fb99987fe0fbac1c174acb2bf996e658dc@127.0.0.1:30002",
    "enode://d581f48b7c4902b91f9709b7fa8149d10a5f11a1078e196f0d4bdaf89e4b1be43b7c5115e61976384ea96a2dd6f7ca96e500e571221302094c0b18b31caddea6@127.0.0.1:30003",
    "enode://430b1342533e9f0db719bd0eedd46cf5f4b163786e7a0238afccce771869a16604eb67106d288a152b5c814b7fb4cd184ac5cf330761a8f6e624fe2e554eb89c@127.0.0.1:30004"
]
暂无评论

发送评论 编辑评论


				
上一篇
下一篇