15 KiB
创世(Genesis)文件
本文档解释了 Cosmos Hub 主网的 genesis 文件是如何构建的。 它还解释了如何为自己的gaia
testnet 创建一个 genesis 文件。
请注意,您可以通过运行以下命令为您自己的 testnet 生成默认的 genesis 文件:
gaiad init <moniker> --chain-id <chain-id>
genesis 文件存储在 ~/.gaiad/config/genesis.toml
.
什么是创世文件
genesis 文件是一个 JSON 文件,用于定义区块链的初始状态。 它可以看作是区块链的高度“0”。 高度为“1”的第一个块将引用 genesis 文件作为其父级。
genesis 文件中定义的状态包含所有必要的信息,如初始令牌分配、创建时间、默认参数等。 我们来分别描述这些信息。
Genesis 时间和链ID
genesis_time
定义在 genesis 文件的顶部。 它是一个“UTC”时间戳,指示区块链何时启动。 此时,创世记验证人应该上线并开始参与共识过程。 当超过2/3的生成验证人(通过投票权加权)在线时,区块链启动。
"genesis_time": "2019-03-13T17:00:00.000000000Z",
chain_id
是您的链的唯一标识符。 它有助于区分使用相同版本的软件的不同链。
"chain_id": "cosmoshub-1",
共识参数
接下来,创世文件定义共识参数。 共识参数覆盖与共识层相关的所有参数,gaia
的共识层是 Tendermint
。 我们来看看这些参数:
block
max_bytes
: 每个块的最大字节数。max_gas
: 每个块的最大 gas 数量。 该区块中包含的每笔交易都会消耗一些 gas,包含在一个区块内的交易所使用的总 gas 不能超出。
evidence
max_age
: 证据(evidence)是一种证明,表明验证者在同一高度(同一轮)签署了两个不同的区块。 这是一种明显的恶意行为,会在状态机层受到惩罚。max_age
定义块的最大数量,在经过max_age
块之后证据不再有效。
validator
pub_key_types
: 可被验证人接受的公钥类型 (例如ed25519
,secp256k1
, ...) ,目前仅支持ed25519
。
"consensus_params": {
"block_size": {
"max_bytes": "150000",
"max_gas": "1500000"
},
"evidence": {
"max_age": "1000000"
},
"validator": {
"pub_key_types": [
"ed25519"
]
}
},
应用程序状态
应用程序状态定义了状态机的初始状态。
创世账号
在本节中,定义了初始分配的 Token。 可以通过直接编辑 genesis 文件手动添加帐户,但也可以使用以下命令:
// Example: gaiad add-genesis-account cosmos1qs8tnw2t8l6amtzvdemnnsq9dzk0ag0z37gh3h 10000000uatom
gaiad add-genesis-account <account-address> <amount><denom>
这个命令在 app_state.accounts
下创建一个条目。
"accounts": [
{
"address": "cosmos1qs8tnw2t8l6amtzvdemnnsq9dzk0ag0z37gh3h",
"coins": [
{
"denom": "uatom",
"amount": "10000000"
}
],
"sequence_number": "0",
"account_number": "0",
"original_vesting": [
{
"denom": "uatom",
"amount": "26306000000"
}
],
"delegated_free": null,
"delegated_vesting": null,
"start_time": "0",
"end_time": "10000"
}
]
让我们来分别解读这些参数:
sequence_number
: 此编号用于计算此帐户发送的交易数。 每次事务包含在块中时它都会递增,并用于防止重放攻击,初始值为“0”。account_number
: 帐户的唯一标识符,它在包含此帐户的首次被打包到块的交易中生成。original_vesting
: 锁仓(Vesting) 由gaia
原生支持。 您可以定义帐户需要锁仓 token 数量,这些 token 在一定时间之后才能流通。 锁仓中的 token 可用于委托。 默认值为“null”。delegated_free
: 在 vest 过期后可转让的委托 token 数量。在创世文件中,大部分情况是null
。delegated_vesting
: 锁仓中的 token 数量。在创世文件中,大部分情况是null
。start_time
: vesting 期开始区块高度。创世文件中,大部分情况是0
。end_time
: vesting 期结束区块高度。如果没有 token 在 vesting 期,这个值是0
。
银行(Bank)
bank
模块负责 token。在本节中唯一 需要定义的参数是“转账”是否在创世文件启用。
"bank": {
"send_enabled": false
}
权益(Staking)
staking
模块处理状态机中的大多数 POS 逻辑。 此部分应如下所示:
"staking": {
"pool": {
"not_bonded_tokens": "10000000",
"bonded_tokens": "0"
},
"params": {
"unbonding_time": "1814400000000000",
"max_validators": 100,
"max_entries": 7,
"bond_denom": "uatom"
},
"last_total_power": "0",
"last_validator_powers": null,
"validators": null,
"bonds": null,
"unbonding_delegations": null,
"redelegations": null,
"exported": false
}
让我们来分别解读这些参数:
pool
not_bonded_tokens
: 在创世文件中没有绑定(即委托)的 token 数量。 通常情况下,它与权益 token (本例中是uatom
)的总供应量相等。bonded_tokens
: 在创世文件中绑定的 token 数量,通常是0。
params
unbonding_time
: 以纳秒为单位的解绑延迟时间。max_validators
: 最大验证人节点数量。max_entries
: 每对验证人和委托人之间可进行解委托、重新委托的最大条目数。bond_denom
: 权益代币符号。
last_total_power
: 总投票权重。在创世文件通常是0(除非创世文件使用了之前的状态)。last_validator_powers
: 最后一个区块的状态中每个验证人的投票权重。在创世文件中通常是 null(除非创世文件使用了之前的状态)。validators
: 最后一个区块中的验证人列表。在创世文件中通常是 null(除非创世文件使用了之前的状态)。bonds
: 最后一个区块中的委托列表。在创世文件中通常是 null(除非创世文件使用了之前的状态)。unbonding_delegations
: 最后一个区块中的解绑委托列表。在创世文件中通常是 null(除非创世文件使用了之前的状态)。redelegations
: 最后一个区块中的重新委托列表。在创世文件中通常是 null(除非创世文件使用了之前的状态)。exported
: 创世文件是否是从之前的状态导出得到的。
挖矿(Mint)
mint
模块管理 token 供应的通胀逻辑。 创世文件中的mint
部分如下所示:
"mint": {
"minter": {
"inflation": "0.070000000000000000",
"annual_provisions": "0.000000000000000000"
},
"params": {
"mint_denom": "uatom",
"inflation_rate_change": "0.130000000000000000",
"inflation_max": "0.200000000000000000",
"inflation_min": "0.070000000000000000",
"goal_bonded": "0.670000000000000000",
"blocks_per_year": "6311520"
}
}
让我们来分别解读这些参数:
minter
inflation
:总 token 供应量的年化通胀百分比,每周更新。值 “0.070000000000000000” 意味着目标是每年通货膨胀率为“7%”,每周重新计算一次。annual_provisions
: 每块重新计算。初始值是0.000000000000000000
。
params
mint_denom
: 增发权益代币面值,此处是uatom
。inflation_rate_change
: 通胀每年最大变化。inflation_max
: 最高通胀水平。inflation_min
: 最低通胀水平。goal_bonded
: 目标绑定量占总供应量百分比。如果委托 token 的百分比低于此目标,则通胀率会增加(在inflation_rate_change
之后),直至达到inflation_max
。 如果委托 token 的百分比高于此目标,则通胀率会下降(在inflation_rate_change
之后),直至达到inflation_min
。blocks_per_year
: 每年出块量估算。用于计算出块收益中权益 token 的通胀部分(称之为块供给)。
分配(Distribution)
distr
模块处理每个块中发给验证人和委托人的挖矿及手续费的分配逻辑。 创世文件中的distr
部分如下所示:
"distr": {
"fee_pool": {
"community_pool": null
},
"community_tax": "0.020000000000000000",
"base_proposer_reward": "0.010000000000000000",
"bonus_proposer_reward": "0.040000000000000000",
"withdraw_addr_enabled": false,
"delegator_withdraw_infos": null,
"previous_proposer": "",
"outstanding_rewards": null,
"validator_accumulated_commissions": null,
"validator_historical_rewards": null,
"validator_current_rewards": null,
"delegator_starting_infos": null,
"validator_slash_events": null
}
让我们来分别解读这些参数:
fee_pool
community_pool
: 用于支付奖励的 token 放在公共池中,它通过治理提案分配。在创世文件中通常是 null。
community_tax
: 税率,即交易费和出块收益中需要放入公共池部分的百分比。base_proposer_reward
: 区块提议者在有效区块中收取的交易费用奖励的基础部分。 如果值为0.010000000000000000
,则1%的费用将转给提议者。bonus_proposer_reward
: 如果区块提议者收集了 2/3 (该块有效的最小值)加权投票的预提交,则获得base_proposer_reward
奖励。 如果区块提议者收集了100%加权投票的预提交,则奖励会再线性增加bonus_proposer_reward
。withdraw_addr_enabled
: 如果是true
,委托人可以设置不同的地址来取回他们的奖励。 如果要在创世时禁用转账,则要设置为false
,因为它可以绕过转账限制。delegator_withdraw_infos
: 委托人收益地址列表。 如果没有从之前的状态导出,一般是null
。previous_proposer
: 上一个块的提议者, 如果没有从之前的状态导出,则设置为""。outstanding_rewards
: 未付(未提取)奖励。如果没有从之前的状态导出,设置为null
。validator_accumulated_commission
: 未付(未提取)验证人佣金。如果没有从之前的状态导出,设置为null
。validator_historical_rewards
: 验证人的历史奖励相关的信息,由distr
模块用于各种计算。 如果没有从之前的状态导出,设置为null
。validators_current_rewards
: 验证人的当前奖励相关的信息,由distr
模块用于各种计算。 如果没有从之前的状态导出,设置为null
。delegator_starting_infos
: Tracks the previous validator period, the delegation's amount of staking token, and the creation height (to check later on if any slashes have occurred). 跟踪先前的验证人时期,委托的 token 数量和创建高度(稍后检查是否发生了需要惩罚的事件)。 如果没有从之前的状态导出,设置为null
。validator_slash_events
: Set of information related to the past slashing of validators. Set tonull
if genesis was not exported from previous state. 过往验证人惩罚事件相关的信息集。 如果没有从之前的状态导出,设置为null
。
治理(Governance)
gov
模块处理所有与治理相关的事务。 gov
部分的初始状态如下所示:
"gov": {
"starting_proposal_id": "1",
"deposits": null,
"votes": null,
"proposals": null,
"deposit_params": {
"min_deposit": [
{
"denom": "uatom",
"amount": "512000000"
}
],
"max_deposit_period": "1209600000000000"
},
"voting_params": {
"voting_period": "1209600000000000"
},
"tally_params": {
"quorum": "0.4",
"threshold": "0.5",
"veto": "0.334",
"governance_penalty": "0.0"
}
}
让我们来分别解读这些参数:
starting_proposal_id
: 此参数定义第一个提案的ID,每个提案都由唯一ID标识。deposits
: 每个提案 ID 的保证金列表。如果没有从之前的状态导出,设置为null
。votes
: 每个提案 ID 的投票列表。 如果没有从之前的状态导出,设置为null
。proposals
: 所有提案列表。如果没有从之前的状态导出,设置为null
。deposit_params
min_deposit
: 使提案进入投票期的最小抵押数量,如果提供了多种面值,满足其一即可。max_deposit_period
: 最长抵押等待时间(单位纳秒),之后就不能再进行抵押了。
voting_params
voting_period
: 投票期时长(单位纳秒)。
tally_params
quorum
: 提议生效所需的投票数占总抵押数的最小百分比。threshold
: 提议生效所需YES
票占总投票数的最小百分比。veto
: 提议生效所需NO_WITH_VETO
票占总投票数的最大百分比.governance_penalty
: 对未给特定提案进行投票的验证人的处罚。
惩罚(Slashing )
The slashing
module handles the logic to slash delegators if their validator misbehave. The slashing
section in genesis looks as follows:
slashing
模块处理对验证人行为不当的惩罚逻辑。 创世文件中的slashing
部分如下:
"slashing": {
"params": {
"max_evidence_age": "1814400000000000",
"signed_blocks_window": "10000",
"min_signed_per_window": "0.050000000000000000",
"downtime_jail_duration": "600000000000",
"slash_fraction_double_sign": "0.050000000000000000",
"slash_fraction_downtime": "0.000100000000000000"
},
"signing_infos": {},
"missed_blocks": {}
}
让我们来分别解读这些参数:
params
max_evidence_age
: 证据最长有效期,单位 纳秒。signed_blocks_window
: 用于检验验证人节点可用性的滑动窗口,(单位块)。min_signed_per_window
: 在滑动窗口中预提交的数量少于此值,认为验证人节点可用性差。downtime_jail_duration
: 验证人节点因可用性差被关监狱后,在监狱中被关的时间(纳秒)。slash_fraction_double_sign
: 验证人节点双签时,需缴纳罚金占总委托数量的百分比。slash_fraction_downtime
: 验证人节点可用性差时,需缴纳罚金占总委托数量的百分比。
signing_infos
:slashing
模块所需的每个验证人节点的各种信息。如果没有从之前的状态导出,设置为{}
。missed_blocks
:slashing
模块所需的与丢块相关的各种信息。如果没有从之前的状态导出,设置为{}
。
创世交易(Genesis Transactions)
默认情况下,genesis文件不包含任何gentxs
。 gentx
是一种交易,在创世文件中的将accounts
下的 token 委托给验证人节点,本质上就是在创世时创建验证人。 在genesis_time
之后,一旦有超过 2/3 的验证人(加权投票)作为有效gentx
的接收者上线,该链就会启动。
可以手动将gentx
添加到genesis文件,或通过以下命令:
gaiad collect-gentxs
此命令将存储在~/.gaiad/config/gentx
中的所有gentxs
添加到genesis文件中。 要创建创世纪交易,请单击此处。