摘要

本文规定了 Cosmos SDK 的 Staking 模块,该模块最早于 2016 年 6 月在 Cosmos 白皮书中进行了说明。 该模块使基于 Cosmos SDK 的区块链能够支持高级的权益证明(PoS)系统。在该系统中,链的原生质押代币持有者可以成为验证者,也可以将代币委托给验证者,最终决定系统的有效验证者集合。 该模块已用于 Cosmos Hub,即 Cosmos 网络中的第一个 Hub。

目录

状态

资金池

资金池用于跟踪 bond denomination 的已绑定和未绑定代币供应量。

上一轮总权重

LastTotalPower 用于跟踪在上一个区块结束时记录的已绑定代币总量。 所有带有 Last 前缀的存储条目在 EndBlock 之前都必须保持不变。
  • LastTotalPower: 0x12 -> ProtocolBuffer(math.Int)

验证者更新

ValidatorUpdates 包含每个区块结束时返回给 ABCI 的验证者更新。 这些值会在每个区块中被覆盖。
  • ValidatorUpdates 0x61 -> []abci.ValidatorUpdate

解绑 ID

UnbondingID 存储最新一次解绑操作的 ID。它支持为解绑操作创建唯一 ID,也就是说,每当发起一次新的解绑操作(验证者解绑、解除委托、重新委托)时,UnbondingID 都会递增。
  • UnbondingID: 0x37 -> uint64

参数

staking 模块以 0x51 为前缀将其参数存储在状态中, 这些参数可以通过治理或由具有 authority 的地址进行更新。
  • Params: 0x51 | ProtocolBuffer(Params)
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L310-L333

验证者

验证者可以具有以下三种状态之一
  • Unbonded:验证者不在活跃集合中。他们不能签名区块,也不会获得 奖励。但他们可以接收委托。
  • Bonded:一旦验证者接收到足够的已绑定代币,他们会在 EndBlock 期间自动加入 活跃集合,并且其状态会更新为 Bonded。 他们会签名区块并获得奖励,也可以继续接收委托。 他们可能因不当行为而被惩罚。向该验证者委托的委托人在解除委托时 必须等待 UnbondingTime,这是一项链级参数;在这段时间内, 如果源验证者的违规行为发生在这些代币处于绑定状态的期间, 这些委托代币仍然可能被惩罚。
  • Unbonding:当验证者因主动退出,或因被惩罚、监禁或 tombstoning 而离开 活跃集合时,其所有委托都会开始解绑。随后所有委托都必须等待 UnbondingTime, 在此之后,其代币才会从 BondedPool 转入各自账户。
Tombstoning 是永久性的;一旦被 tombstoned,验证者的共识密钥就不能在发生 tombstoning 的同一条链中再次使用。
验证者对象应主要通过 OperatorAddr 进行存储和访问,OperatorAddr 是验证者运营者的 SDK 验证者地址。每个验证者对象还维护了两个附加索引,以满足惩罚和验证者集合更新所需的查询需求。另有第三个特殊索引(LastValidatorPower)也会被维护,但与前两个在区块内镜像验证者记录的索引不同,它在每个区块期间保持不变。
  • Validators: 0x21 | OperatorAddrLen (1 byte) | OperatorAddr -> ProtocolBuffer(validator)
  • ValidatorsByConsAddr: 0x22 | ConsAddrLen (1 byte) | ConsAddr -> OperatorAddr
  • ValidatorsByPower: 0x23 | BigEndian(ConsensusPower) | OperatorAddrLen (1 byte) | OperatorAddr -> OperatorAddr
  • LastValidatorsPower: 0x11 | OperatorAddrLen (1 byte) | OperatorAddr -> ProtocolBuffer(ConsensusPower)
  • ValidatorsByUnbondingID: 0x38 | UnbondingID -> 0x21 | OperatorAddrLen (1 byte) | OperatorAddr
Validators 是主索引,它确保每个运营者只能关联一个验证者,而该验证者的公钥未来可以发生变化。委托人可以引用验证者不可变的运营者标识,而无需关心公钥的变化。 ValidatorsByUnbondingID 是一个附加索引,用于根据与验证者当前解绑状态对应的解绑 ID 查询验证者。 ValidatorByConsAddr 是一个附加索引,用于支持惩罚查询。当 CometBFT 报告证据时,它提供的是验证者地址,因此需要这个映射来找到对应的运营者。请注意,ConsAddr 对应的地址可以从验证者的 ConsPubKey 推导出来。 ValidatorsByPower 是一个附加索引,它提供了按顺序排列的潜在验证者列表,以便快速确定当前活跃集合。这里的 ConsensusPower 默认等于 validator.Tokens/10^6。请注意,所有 Jailed 为 true 的验证者都不会存储在该索引中。 LastValidatorsPower 是一个特殊索引,它提供上一块中已绑定验证者的历史列表。该索引在一个区块期间保持不变,但会在 EndBlock 中执行的验证者集合更新过程中被更新。 每个验证者的状态都存储在一个 Validator 结构体中:
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L82-L138
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L26-L80

委托

委托通过组合 DelegatorAddr(委托人地址)和 ValidatorAddr 来标识。委托人在存储中的索引方式如下:
  • Delegation: 0x31 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValidatorAddrLen (1 byte) | ValidatorAddr -> ProtocolBuffer(delegation)
质押者可以将代币委托给验证者;在这种情况下,他们的资金会保存在 Delegation 数据结构中。它归属于单个委托人,并与某个验证者的份额相关联。交易发送方就是该 bond 的所有者。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L198-L216

委托人份额

当用户向某个验证者委托代币时,会基于一个动态兑换率获得一定数量的委托人份额。该兑换率根据委托给该验证者的代币总数以及目前已发行的份额数量按如下方式计算: Shares per Token = validator.TotalShares() / validator.Tokens() 在 DelegationEntry 上只会存储所获得的份额数量。随后,当委托人执行 Undelegate 时,他们收到的代币数量会根据其当前持有的份额数量以及反向兑换率来计算: Tokens per Share = validator.Tokens() / validatorShares() 这些 Shares 只是一个记账机制,并不是可流通资产。之所以采用这种机制,是为了简化与惩罚相关的记账过程。系统无需迭代地惩罚每一条委托记录中的代币,而是可以直接惩罚验证者的已绑定代币总量,从而实际降低每一份已发行委托人份额的价值。

UnbondingDelegation

Delegation 中的份额可以解除绑定,但在一段时间内它们必须以 UnbondingDelegation 的形式存在;如果检测到拜占庭行为,份额可能会被削减。 UnbondingDelegation 在存储中的索引方式如下:
  • UnbondingDelegation: 0x32 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValidatorAddrLen (1 byte) | ValidatorAddr -> ProtocolBuffer(unbondingDelegation)
  • UnbondingDelegationsFromValidator: 0x33 | ValidatorAddrLen (1 byte) | ValidatorAddr | DelegatorAddrLen (1 byte) | DelegatorAddr -> nil
  • UnbondingDelegationByUnbondingId: 0x38 | UnbondingId -> 0x32 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValidatorAddrLen (1 byte) | ValidatorAddr UnbondingDelegation 用于查询,以查找给定委托人对应的所有解除绑定委托。
UnbondingDelegationsFromValidator 用于惩罚,以查找与给定验证者关联且需要被惩罚的所有解除绑定委托。 UnbondingDelegationByUnbondingId 是一个额外索引,用于根据所包含的解除绑定委托条目的 unbonding ID 查找解除绑定委托。 每次发起解除绑定时,都会创建一个 UnbondingDelegation 对象。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L218-L261

Redelegation

Delegation 所对应的已绑定代币可以立即从源验证者重新委托给另一个验证者(目标验证者)。但发生这种情况时,必须在 Redelegation 对象中跟踪它们;如果这些代币曾对源验证者造成的拜占庭故障有贡献,那么其份额可能会被惩罚。 Redelegation 在存储中的索引方式如下:
  • Redelegations: 0x34 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValidatorAddrLen (1 byte) | ValidatorSrcAddr | ValidatorDstAddr -> ProtocolBuffer(redelegation)
  • RedelegationsBySrc: 0x35 | ValidatorSrcAddrLen (1 byte) | ValidatorSrcAddr | ValidatorDstAddrLen (1 byte) | ValidatorDstAddr | DelegatorAddrLen (1 byte) | DelegatorAddr -> nil
  • RedelegationsByDst: 0x36 | ValidatorDstAddrLen (1 byte) | ValidatorDstAddr | ValidatorSrcAddrLen (1 byte) | ValidatorSrcAddr | DelegatorAddrLen (1 byte) | DelegatorAddr -> nil
  • RedelegationByUnbondingId: 0x38 | UnbondingId -> 0x34 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValidatorAddrLen (1 byte) | ValidatorSrcAddr | ValidatorDstAddr
Redelegations 用于查询,以查找给定委托人的所有重新委托。 RedelegationsBySrc 用于基于 ValidatorSrcAddr 执行惩罚。 RedelegationsByDst 用于基于 ValidatorDstAddr 执行惩罚。 这里的第一张映射用于查询,以查找给定委托人的所有重新委托。第二张映射用于基于 ValidatorSrcAddr 执行惩罚,而第三张映射用于基于 ValidatorDstAddr 执行惩罚。 RedelegationByUnbondingId 是一个额外索引,用于根据所包含的重新委托条目的 unbonding ID 查找重新委托。 每次发生重新委托时,都会创建一个 redelegation 对象。为防止“重新委托跳转”,在以下情况下不允许发生重新委托:
  • (重新)委托人已经有另一笔尚未成熟、仍在进行中的重新委托,且其目标是某个验证者(记作 Validator X)
  • 并且,该(重新)委托人正尝试创建一笔新的重新委托,而这笔新重新委托的源验证者正是 Validator X。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L263-L308

Queues

所有队列对象都按时间戳排序。任何队列中使用的时间都会先转换为 UTC,四舍五入到最接近的纳秒,然后再排序。所使用的可排序时间格式是对 RFC3339Nano 的轻微修改,格式字符串为 "2006-01-02T15:04:05.000000000"。需要注意的是,这种格式:
  • 会在右侧补齐所有零
  • 会去掉时区信息(因为我们已经统一使用 UTC)
在所有情况下,存储的时间戳都表示队列元素的成熟时间。

UnbondingDelegationQueue

为跟踪解除绑定委托的进度,会维护解除绑定委托队列。
  • UnbondingDelegation: 0x41 | format(time) -> []DVPair
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L162-L172

RedelegationQueue

为跟踪重新委托的进度,会维护重新委托队列。
  • RedelegationQueue: 0x42 | format(time) -> []DVVTriplet
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L179-L191

ValidatorQueue

为跟踪解除绑定中的验证者进度,会维护验证者队列。
  • ValidatorQueueTime: 0x43 | format(time) -> []sdk.ValAddress
每个键存储的对象都是一个验证者操作员地址数组,可据此访问验证者对象。通常预期给定时间戳只会关联一条验证者记录,但也有可能同一位置的队列中存在多个验证者。

HistoricalInfo

HistoricalInfo 对象会在每个区块处被存储并裁剪,因此 staking keeper 会持久化由 staking 模块参数 HistoricalEntries 定义的最近 n 条 historical info。
syntax = "proto3";
package cosmos.staking.v1beta1;

import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";
import "amino/amino.proto";
import "tendermint/types/types.proto";
import "tendermint/abci/types.proto";

option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types";

// HistoricalInfo contains header and validator information for a given block.
// It is stored as part of staking module's state, which persists the `n` most
// recent HistoricalInfo
// (`n` is set by the staking module's `historical_entries` parameter).
message HistoricalInfo {
    tendermint.types.Header header = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  repeated Validator      valset = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// CommissionRates defines the initial commission rates to be used for creating
// a validator.
message CommissionRates {
    option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // rate is the commission rate charged to delegators, as a fraction.
  string rate = 1 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
  // max_rate defines the maximum commission rate which validator can ever charge, as a fraction.
  string max_rate = 2 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
  // max_change_rate defines the maximum daily increase of the validator commission, as a fraction.
  string max_change_rate = 3 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
}

// Commission defines commission parameters for a given validator.
message Commission {
    option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // commission_rates defines the initial commission rates to be used for creating a validator.
  CommissionRates commission_rates = 1
      [(gogoproto.embed) = true, (gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  // update_time is the last time the commission rate was changed.
  google.protobuf.Timestamp update_time = 2
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdtime) = true];
}

// Description defines a validator description.
message Description {
    option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // moniker defines a human-readable name for the validator.
  string moniker = 1;
  // identity defines an optional identity signature (ex. UPort or Keybase).
  string identity = 2;
  // website defines an optional website link.
  string website = 3;
  // security_contact defines an optional email for security contact.
  string security_contact = 4;
  // details define other optional details.
  string details = 5;
}

// Validator defines a validator, together with the total amount of the
// Validator's bond shares and their exchange rate to coins. Slashing results in
// a decrease in the exchange rate, allowing correct calculation of future
// undelegations without iterating over delegators. When coins are delegated to
// this validator, the validator is credited with a delegation whose number of
// bond shares is based on the amount of coins delegated divided by the current
// exchange rate. Voting power can be calculated as total bonded shares
// multiplied by exchange rate.
message Validator {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_stringer) = false;
  option (gogoproto.goproto_getters)  = false;

  // operator_address defines the address of the validator's operator; bech encoded in JSON.
  string operator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // consensus_pubkey is the consensus public key of the validator, as a Protobuf Any.
  google.protobuf.Any consensus_pubkey = 2 [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey"];
  // jailed defined whether the validator has been jailed from bonded status or not.
  bool jailed = 3;
  // status is the validator status (bonded/unbonding/unbonded).
  BondStatus status = 4;
  // tokens define the delegated tokens (incl. self-delegation).
  string tokens = 5 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];
  // delegator_shares defines total shares issued to a validator's delegators.
  string delegator_shares = 6 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
  // description defines the description terms for the validator.
  Description description = 7 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  // unbonding_height defines, if unbonding, the height at which this validator has begun unbonding.
  int64 unbonding_height = 8;
  // unbonding_time defines, if unbonding, the min time for the validator to complete unbonding.
  google.protobuf.Timestamp unbonding_time = 9
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdtime) = true];
  // commission defines the commission parameters.
  Commission commission = 10 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  // min_self_delegation is the validator's self declared minimum self delegation.
  //
  // Since: cosmos-sdk 0.46
  string min_self_delegation = 11 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];

  // strictly positive if this validator's unbonding has been stopped by external modules
  int64 unbonding_on_hold_ref_count = 12;

  // list of unbonding ids, each uniquely identifing an unbonding of this validator
  repeated uint64 unbonding_ids = 13;
}

// BondStatus is the status of a validator.
enum BondStatus {
    option (gogoproto.goproto_enum_prefix) = false;

  // UNSPECIFIED defines an invalid validator status.
  BOND_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "Unspecified"];
  // UNBONDED defines a validator that is not bonded.
  BOND_STATUS_UNBONDED = 1 [(gogoproto.enumvalue_customname) = "Unbonded"];
  // UNBONDING defines a validator that is unbonding.
  BOND_STATUS_UNBONDING = 2 [(gogoproto.enumvalue_customname) = "Unbonding"];
  // BONDED defines a validator that is bonded.
  BOND_STATUS_BONDED = 3 [(gogoproto.enumvalue_customname) = "Bonded"];
}

// ValAddresses defines a repeated set of validator addresses.
message ValAddresses {
    option (gogoproto.goproto_stringer) = false;
  option (gogoproto.stringer)         = true;

  repeated string addresses = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// DVPair is struct that just has a delegator-validator pair with no other data.
// It is intended to be used as a marshalable pointer. For example, a DVPair can
// be used to construct the key to getting an UnbondingDelegation from state.
message DVPair {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// DVPairs defines an array of DVPair objects.
message DVPairs {
    repeated DVPair pairs = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// DVVTriplet is struct that just has a delegator-validator-validator triplet
// with no other data. It is intended to be used as a marshalable pointer. For
// example, a DVVTriplet can be used to construct the key to getting a
// Redelegation from state.
message DVVTriplet {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  string delegator_address     = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  string validator_src_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  string validator_dst_address = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// DVVTriplets defines an array of DVVTriplet objects.
message DVVTriplets {
    repeated DVVTriplet triplets = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}
// Delegation 表示账户持有代币形成的委托关系。它归属于一个委托人,并与一个
// 验证者的投票权相关联。
message Delegation {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  // delegator_address 是委托人的 bech32 编码地址。
  string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // validator_address 是验证者的 bech32 编码地址。
  string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // shares 定义收到的委托份额。
  string shares = 3 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
}

// UnbondingDelegation 按时间顺序存储单个委托人针对单个验证者的所有
// 解除质押委托。
message UnbondingDelegation {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  // delegator_address 是委托人的 bech32 编码地址。
  string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // validator_address 是验证者的 bech32 编码地址。
  string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // entries 是解除质押委托条目。
  repeated UnbondingDelegationEntry entries = 3
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // 解除质押委托条目
}

// UnbondingDelegationEntry 定义一个包含相关元数据的解除质押对象。
message UnbondingDelegationEntry {
    option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // creation_height 是发生解除质押时的区块高度。
  int64 creation_height = 1;
  // completion_time 是解除质押完成时的 Unix 时间。
  google.protobuf.Timestamp completion_time = 2
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdtime) = true];
  // initial_balance 定义完成时最初计划接收的代币数量。
  string initial_balance = 3 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];
  // balance 定义完成时将接收的代币数量。
  string balance = 4 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];
  // 递增的 id,唯一标识此条目
  uint64 unbonding_id = 5;

  // 如果此条目的解除质押已被外部模块阻止,则该值严格大于 0
  int64 unbonding_on_hold_ref_count = 6;
}

// RedelegationEntry 定义一个包含相关元数据的再委托对象。
message RedelegationEntry {
    option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // creation_height 定义发生再委托时的区块高度。
  int64 creation_height = 1;
  // completion_time 定义再委托完成时的 Unix 时间。
  google.protobuf.Timestamp completion_time = 2
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdtime) = true];
  // initial_balance 定义再委托开始时的初始余额。
  string initial_balance = 3 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];
  // shares_dst 是通过再委托创建的目标验证者份额数量。
  string shares_dst = 4 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
  // 递增的 id,唯一标识此条目
  uint64 unbonding_id = 5;

  // 如果此条目的解除质押已被外部模块阻止,则该值严格大于 0
  int64 unbonding_on_hold_ref_count = 6;
}

// Redelegation 包含某个委托人从特定源验证者到特定目标验证者的
// 再委托债券列表。
message Redelegation {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  // delegator_address 是委托人的 bech32 编码地址。
  string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // validator_src_address 是验证者再委托源操作员地址。
  string validator_src_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // validator_dst_address 是验证者再委托目标操作员地址。
  string validator_dst_address = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // entries 是再委托条目。
  repeated RedelegationEntry entries = 4
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // 再委托条目
}

// Params 定义 x/staking 模块的参数。
message Params {
    option (amino.name)                 = "cosmos-sdk/x/staking/Params";
  option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // unbonding_time 是解除质押的持续时间。
  google.protobuf.Duration unbonding_time = 1
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdduration) = true];
  // max_validators 是验证者的最大数量。
  uint32 max_validators = 2;
  // max_entries 是解除质押委托或再委托的最大条目数(每对/每组三元关系)。
  uint32 max_entries = 3;
  // historical_entries 是要持久化保存的历史条目数量。
  uint32 historical_entries = 4;
  // bond_denom 定义可质押币种的面额。
  string bond_denom = 5;
  // min_commission_rate 是链范围内验证者可向其委托人收取的最低佣金率
  string min_commission_rate = 6 [
    (gogoproto.moretags)   = "yaml:\"min_commission_rate\"",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
}

// DelegationResponse 与 Delegation 等价,但除 shares 外还包含 balance,
// 更适合用于客户端响应。
message DelegationResponse {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_stringer) = false;

  Delegation delegation = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];

  cosmos.base.v1beta1.Coin balance = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// RedelegationEntryResponse 与 RedelegationEntry 等价,但除 shares 外还
// 包含 balance,更适合用于客户端响应。
message RedelegationEntryResponse {
    option (gogoproto.equal) = true;

  RedelegationEntry redelegation_entry = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  string            balance            = 4 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];
}

// RedelegationResponse 与 Redelegation 等价,但其条目除 shares 外还包含
// balance,更适合用于客户端响应。
message RedelegationResponse {
    option (gogoproto.equal) = false;

  Redelegation                       redelegation = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  repeated RedelegationEntryResponse entries      = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// Pool 用于跟踪质押币种面额下已质押和未质押的代币供应量。
message Pool {
    option (gogoproto.description) = true;
  option (gogoproto.equal)       = true;
  string not_bonded_tokens       = 1 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false,
    (gogoproto.jsontag)    = "not_bonded_tokens",
    (amino.dont_omitempty) = true
  ];
  string bonded_tokens = 2 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false,
    (gogoproto.jsontag)    = "bonded_tokens",
    (amino.dont_omitempty) = true
  ];
}

// Infraction 表示验证者犯下的违规行为。
enum Infraction {
  // UNSPECIFIED 定义空的违规类型。
  INFRACTION_UNSPECIFIED = 0;
  // DOUBLE_SIGN 定义验证者对同一区块进行了双签。
  INFRACTION_DOUBLE_SIGN = 1;
  // DOWNTIME 定义验证者错过了过多区块签名。
  INFRACTION_DOWNTIME = 2;
}

// ValidatorUpdates defines an array of abci.ValidatorUpdate objects.
// TODO: explore moving this to proto/cosmos/base to separate modules from tendermint dependence
message ValidatorUpdates {
    repeated tendermint.abci.ValidatorUpdate updates = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}
在每个 BeginBlock 时,staking keeper 都会将当前的 Header 以及提交当前区块的验证者持久化到一个 HistoricalInfo 对象中。验证者会按其地址排序,以确保顺序具有确定性。 最旧的 HistoricalEntries 会被修剪,以确保历史条目的数量始终不超过参数定义的值。

状态转换

验证者

验证者的状态转换会在每个 EndBlock 中执行,以检查活跃 ValidatorSet 是否发生变化。 验证者可以处于 Unbonded、Unbonding 或 Bonded 状态。Unbonded 和 Unbonding 统称为 Not Bonded。验证者可以在这些状态之间直接转换, 唯一例外是不能从 Bonded 直接转换到 Unbonded。

从未绑定到已绑定

当某个验证者在 ValidatorPowerIndex 中的排名超过 LastValidator 时, 会发生以下转换:
  • 将 validator.Status 设为 Bonded
  • 将 validator.Tokens 从 NotBondedTokens 转入 BondedPool ModuleAccount
  • 从 ValidatorByPowerIndex 中删除现有记录
  • 向 ValidatorByPowerIndex 添加一条新的更新记录
  • 更新该验证者对应的 Validator 对象
  • 如果存在,则删除该验证者对应的任何 ValidatorQueue 记录

从已绑定到解绑中

当验证者开始解绑流程时,会执行以下操作:
  • 将 validator.Tokens 从 BondedPool 转入 NotBondedTokens ModuleAccount
  • 将 validator.Status 设为 Unbonding
  • 从 ValidatorByPowerIndex 中删除现有记录
  • 向 ValidatorByPowerIndex 添加一条新的更新记录
  • 更新该验证者对应的 Validator 对象
  • 为该验证者向 ValidatorQueue 插入一条新记录

从解绑中到未绑定

当 ValidatorQueue 对象从已绑定转为未绑定时, 验证者会从解绑中状态转为未绑定状态
  • 更新该验证者对应的 Validator 对象
  • 将 validator.Status 设为 Unbonded

监禁/解除监禁

当验证者被监禁时,它会被有效地从 CometBFT 集合中移除。 这个过程也可以反向执行。会发生以下操作:
  • 设置 Validator.Jailed 并更新对象
  • 如果被监禁,则从 ValidatorByPowerIndex 删除记录
  • 如果解除监禁,则向 ValidatorByPowerIndex 添加记录
被监禁的验证者不会出现在以下任何存储中:
  • power store(从共识投票权到地址)

委托

委托

发生委托时,验证者对象和委托对象都会受到影响
  • 根据委托的 token 数量和验证者的兑换率确定委托人的 shares
  • 从发送账户中移除 token
  • 向委托对象中添加 shares,或者将其添加到新创建的验证者对象中
  • 添加新的委托人 shares 并更新 Validator 对象
  • 根据 validator.Status 是否为 Bonded,将 delegation.Amount 从委托人账户转入 BondedPool 或 NotBondedPool ModuleAccount
  • 从 ValidatorByPowerIndex 中删除现有记录
  • 向 ValidatorByPowerIndex 添加一条新的更新记录

开始解绑

作为 Undelegate 和 Complete Unbonding 状态转换的一部分, 可能会调用 Unbond Delegation。
  • 从委托人处扣减已解绑的 shares
  • 将已解绑的 token 添加到一个 UnbondingDelegationEntry
  • 更新该委托;如果已无剩余 shares,则移除该委托
  • 如果该委托属于验证者的 operator,且已无剩余 shares,则触发对验证者的监禁
  • 更新验证者,移除委托人的 shares 及其关联的 coins
  • 如果验证者状态为 Bonded,则将与已解绑 shares 对应价值的 Coins 从 BondedPool 转入 NotBondedPool ModuleAccount
  • 如果验证者为未绑定状态且已无剩余委托 shares,则移除该验证者。
  • 如果验证者为未绑定状态且已无剩余委托 shares,则移除该验证者
  • 获取一个唯一的 unbondingId,并在 UnbondingDelegationByUnbondingId 中将其映射到该 UnbondingDelegationEntry
  • 调用 AfterUnbondingInitiated(unbondingId) hook
  • 将该解绑委托添加到 UnbondingDelegationQueue,其完成时间设置为 UnbondingTime

取消一个 UnbondingDelegation 条目

当发生 cancel unbond delegation 时,validator、delegation 以及 UnbondingDelegationQueue 的状态都会被更新。
  • 如果取消解绑委托的数量等于 UnbondingDelegation 条目的 balance,则该 UnbondingDelegation 条目会从 UnbondingDelegationQueue 中删除。
  • 如果取消解绑委托的数量小于 UnbondingDelegation 条目的 balance,则该 UnbondingDelegation 条目会在 UnbondingDelegationQueue 中用新的余额进行更新。
  • 取消的 amount 会被重新委托回原始 validator。

完成解绑

对于不会立即完成的取消委托,当解绑委托队列元素到期时, 会执行以下操作:
  • 从 UnbondingDelegation 对象中移除该条目
  • 将 token 从 NotBondedPool ModuleAccount 转入委托人的 Account

开始重委托

重委托会影响委托对象、源验证者和目标验证者。
  • 从源验证者执行一次 unbond 委托,以取回与已解绑 shares 对应价值的 token
  • 使用这些已解绑的 token,将其 Delegate 到目标验证者
  • 如果 sourceValidator.Status 为 Bonded,而 destinationValidator 不是, 则将新委托的 token 从 BondedPool 转入 NotBondedPool ModuleAccount
  • 否则,如果 sourceValidator.Status 不是 Bonded,而 destinationValidator 是 Bonded,则将新委托的 token 从 NotBondedPool 转入 BondedPool ModuleAccount
  • 在相关的 Redelegation 中记录一条新条目,写入 token 数量
从重委托开始到完成之前,委托人都处于“伪解绑”状态,如果在重委托开始之前发生过违规行为,仍然可能因此被惩罚。

完成重委托

当重委托完成时,会发生以下操作:
  • 从 Redelegation 对象中移除该条目

惩罚

惩罚验证者

当验证者被惩罚时,会发生以下情况:
  • 总 slashAmount 会被计算为 slashFactor(链参数)乘以 TokensFromConsensusPower,即违规发生时绑定在该验证者上的 token 总数。
  • 所有满足以下条件的解绑委托和伪解绑重委托都会被按 slashFactor 对初始余额的比例进行惩罚:违规发生时间早于该验证者发起解绑或重委托的时间。
  • 从重委托和解绑委托中被惩罚的每一部分金额,都会从总惩罚金额中扣除。
  • 然后,remaingSlashAmount 会根据验证者的状态,从其 BondedPool 或 NonBondedPool 中的 token 继续扣减。这会减少 token 的总供应量。
如果某次惩罚源于需要提交证据的违规行为(例如双签),则惩罚发生在证据被纳入的区块,而不是违规实际发生的区块。 换句话说,验证者不会被追溯性地惩罚,而只会在被发现时受到惩罚。

惩罚解绑委托

当验证者被惩罚时,该验证者名下那些在违规发生之后才开始解绑的解绑委托也会被惩罚。该验证者每一笔解绑委托中的每个条目都会按 slashFactor 被惩罚。惩罚金额根据该委托的 InitialBalance 计算,并且会设置上限,以避免最终余额变为负数。已完成的(或已到期的)解绑不会被惩罚。

惩罚重委托

当验证者被惩罚时,该验证者名下所有在违规发生之后才开始的重委托也会被惩罚。 重委托会按 slashFactor 被惩罚。 在违规发生之前开始的重委托不会被惩罚。 惩罚金额根据该委托的 InitialBalance 计算,并设置上限, 以避免最终余额变为负数。 已成熟的重委托(即已完成伪解绑)不会被惩罚。

份额如何计算

在任意时刻,每个验证者都有一定数量的代币 T,并发行了一定数量的份额 S。 每个委托人 i 持有一定数量的份额 S_i。 代币数量等于委托给该验证者的所有代币之和,加上奖励,再减去罚没。 委托人有权获得底层代币中与其份额占比成比例的部分。 因此,委托人 i 有权获得该验证者 T * S_i / S 数量的代币。 当委托人向验证者新增委托代币时,他们会按其贡献比例获得相应数量的份额。 因此,当委托人 j 委托 T_j 个代币时,他们会获得 S_j = S * T_j / T 份额。 此时代币总数变为 T + T_j,份额总数变为 S + S_j。 j 的份额占比与其贡献的总代币占比相同:(S + S_j) / S = (T + T_j) / T。 一种特殊情况是初始委托,此时 T = 0 且 S = 0,因此 T_j / T 未定义。 对于初始委托,委托 T_j 个代币的委托人 j 会获得 S_j = T_j 份额。 因此,一个尚未获得任何奖励且未被罚没的验证者将满足 T = S。

消息

本节描述质押消息的处理方式,以及对状态的相应更新。每条消息创建或修改的状态对象都定义在 state 一节中。

MsgCreateValidator

使用 MsgCreateValidator 消息创建验证者。 创建验证者时,运营者必须提供初始自委托。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L20-L21
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L50-L73
在以下情况下,预期此消息会失败:
  • 已经存在使用该运营者地址注册的其他验证者
  • 已经存在使用该公钥注册的其他验证者
  • 初始自委托代币的 denom 不是指定的 bonding denom
  • 佣金参数有误,具体包括:
    • MaxRate 大于 1 或小于 0
    • 初始 Rate 为负数或大于 MaxRate
    • 初始 MaxChangeRate 为负数或大于 MaxRate
  • 描述字段过大
此消息会在适当的索引处创建并存储 Validator 对象。 此外,还会使用初始代币委托 Delegation 执行一次自委托。验证者初始状态始终为未绑定,但可能会在第一个 end-block 中变为已绑定。

MsgEditValidator

可以使用 MsgEditValidator 消息更新验证者的 Description 和 CommissionRate。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L23-L24
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L78-L97
在以下情况下,预期此消息会失败:
  • 初始 CommissionRate 为负数或大于 MaxRate
  • CommissionRate 在前 24 小时内已经更新过
  • CommissionRate 大于 MaxChangeRate
  • 描述字段过大
此消息会存储更新后的 Validator 对象。

MsgDelegate

在此消息中,委托人提供代币,作为回报会收到其验证者的部分(新创建的)delegator-shares,并分配到 Delegation.Shares。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L26-L28
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L102-L114
在以下情况下,预期此消息会失败:
  • 验证者不存在
  • Amount Coin 的 denom 与 params.BondDenom 定义的 denom 不同
  • 兑换率无效,即验证者没有代币(由于罚没)但仍有未清份额
  • 委托金额低于允许的最小委托额
如果针对所提供地址的 Delegation 对象尚不存在,则会作为此消息处理的一部分创建;否则会更新现有的 Delegation,将新获得的份额计入其中。 委托人会按照当前兑换率获得新铸造的份额。 兑换率等于验证者中现有份额数量除以当前已委托代币数量。 验证者会在 ValidatorByPower 索引中更新,而该委托会在 Validators 索引中的验证者对象里被跟踪。 可以向被 jailed 的验证者进行委托,唯一的区别是它在 unjailed 之前不会被加入 power 索引。 委托流程

MsgUndelegate

MsgUndelegate 消息允许委托人从验证者处解除委托其代币。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L34-L36
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L140-L152
此消息会返回一个响应,其中包含解除委托的完成时间:
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L154-L158
在以下情况下,预期此消息会失败:
  • 委托不存在
  • 验证者不存在
  • 该委托持有的份额少于 Amount 对应价值的份额
  • 现有 UnbondingDelegation 的条目数已达到 params.MaxEntries 定义的最大值
  • Amount 的 denom 与 params.BondDenom 定义的 denom 不同
处理此消息时,会发生以下操作:
  • 验证者的 DelegatorShares 和该委托的 Shares 都会按消息中的 SharesAmount 减少
  • 计算这些份额对应的代币价值,并从验证者持有的代币中移除相应数量的代币
  • 对于这些被移除的代币,如果验证者是:
    • Bonded - 将它们加入 UnbondingDelegation 中的一个条目(如果 UnbondingDelegation 不存在则创建),其完成时间为从当前时刻起完整的 unbonding 周期。更新池份额,减少 BondedTokens,并按份额对应的代币价值增加 NotBondedTokens。
    • Unbonding - 将它们加入 UnbondingDelegation 中的一个条目(如果 UnbondingDelegation 不存在则创建),完成时间与验证者相同(UnbondingMinTime)。
    • Unbonded - 直接将代币发送给消息中的 DelegatorAddr
  • 如果该委托中不再有 Shares,则从存储中移除该委托对象
    • 在这种情况下,如果该委托是验证者的自委托,还会将该验证者关押。
解除绑定流程

MsgCancelUnbondingDelegation

MsgCancelUnbondingDelegation 消息允许委托人取消 unbondingDelegation 条目,并重新委托回之前的验证者。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L38-L42
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L160-L175
在以下情况下,预期此消息会失败:
  • unbondingDelegation 条目已经处理完毕。
  • cancel unbonding delegation 的金额大于该 unbondingDelegation 条目的余额。
  • 该 cancel unbonding delegation 的高度在委托人的 unbondingDelegationQueue 中不存在。
处理此消息时,会发生以下操作:
  • 如果 unbondingDelegation 条目的余额为零
    • 在这种情况下,会从 unbondingDelegationQueue 中移除该 unbondingDelegation 条目。
    • 否则,会使用新的 unbondingDelegation 条目余额和初始余额更新 unbondingDelegationQueue
  • 验证者的 DelegatorShares 和该委托的 Shares 都会按消息中的 Amount 增加。

MsgBeginRedelegate

重新委托命令允许委托人即时切换验证者。一旦解绑期结束,重新委托会在 EndBlocker 中自动完成。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L30-L32
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L119-L132
该消息会返回一个响应,其中包含重新委托的完成时间:
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L133-L138
在以下情况下,预期该消息会失败:
  • 委托不存在
  • 源验证者或目标验证者不存在
  • 该委托的份额少于 Amount 对应的份额数量
  • 源验证者存在一笔尚未成熟的接收中重新委托(即该重新委托可能是传递性的)
  • 现有 Redelegation 的条目数已达到 params.MaxEntries 定义的最大值
  • Amount 中 Coin 的面额与 params.BondDenom 定义的面额不同
处理该消息时会发生以下操作:
  • 源验证者的 DelegatorShares 和该委托的 Shares 都会按消息中的 SharesAmount 减少
  • 计算这些份额对应的 token 数量,并从源验证者持有的 token 中移除该数量
  • 如果源验证者处于以下状态:
    • Bonded - 向 Redelegation 添加一个条目(如果 Redelegation 不存在则创建),其完成时间为从当前时间起完整的一个解绑期之后。更新池份额,将 BondedTokens 按这些份额对应的 token 数量减少,并将 NotBondedTokens 增加相同数量(不过这可能会在下一步中被实际逆转)
    • Unbonding - 向 Redelegation 添加一个条目(如果 Redelegation 不存在则创建),其完成时间与该验证者相同(UnbondingMinTime)
    • Unbonded - 此步骤无需执行任何操作
  • 将这些份额对应的 token 委托给目标验证者,这可能会把 token 移回已绑定状态
  • 如果源委托中不再有 Shares,则从存储中移除该源委托对象
    • 在这种情况下,如果该委托是验证者的自委托,还会同时将该验证者关押
开始重新委托时序图

MsgUpdateParams

MsgUpdateParams 用于更新 staking 模块参数。 参数通过治理提案更新,签名者为 gov 模块账户地址。
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L182-L195
在以下情况下,消息处理可能失败:
  • 签名者不是 staking keeper 中定义的 authority(通常为 gov 模块账户)。
  • 更新后参数中的 bond_denom 在 bank 模块中供应量为 0(即该 denom 在链上不存在)。

Begin-Block

每次 abci begin block 调用时,历史信息都会按照 HistoricalEntries 参数进行存储和裁剪。

历史信息跟踪

如果 HistoricalEntries 参数为 0,则 BeginBlock 不执行任何操作。 否则,最新的历史信息会存储在键 historicalInfoKey|height 下,而所有早于 height - HistoricalEntries 的条目都会被删除。 在大多数情况下,这会导致每个区块只裁剪一个条目。 不过,如果 HistoricalEntries 参数被调低,存储中就会有多个必须裁剪的条目。

End-Block

每次 abci end block 调用时,都会执行用于更新队列和验证者集合变更的操作。

验证者集合变更

在该过程中,staking 验证者集合会通过每个区块结束时运行的状态转换进行更新。作为此过程的一部分,任何已更新的验证者也会返回给 CometBFT,以纳入 CometBFT 验证者集合,该集合负责在共识层验证 CometBFT 消息。具体操作如下:
  • 新的验证者集合取自 ValidatorsByPower 索引中检索到的前 params.MaxValidators 个验证者
  • 将前一个验证者集合与新的验证者集合进行比较:
    • 缺失的验证者开始解绑,其 Tokens 会从 BondedPool 转移到 NotBondedPool ModuleAccount
    • 新的验证者会立即绑定,其 Tokens 会从 NotBondedPool 转移到 BondedPool ModuleAccount
在所有情况下,任何离开或进入已绑定验证者集合的验证者,或余额发生变化但仍留在已绑定验证者集合中的验证者,都会触发一条更新消息,报告其新的共识权重,并将其传回 CometBFT。 LastTotalPower 和 LastValidatorsPower 保存了上一个区块结束时的总权重和验证者权重状态,并用于检查 ValidatorsByPower 以及新的总权重中发生的变化;新的总权重是在 EndBlock 期间计算的。

队列

在 staking 中,某些状态转换并不是即时完成的,而是会持续一段时间(通常是解绑期)。当这些转换成熟后,必须执行某些操作来完成该状态变更。这是通过使用队列来实现的,这些队列会在每个区块结束时被检查和处理。

解绑中的验证者

当某个验证者被踢出已绑定验证者集合时(无论是因为被关押,还是因为没有足够的已绑定 token),它会开始解绑流程,同时它的所有委托也会开始解绑(但仍然委托给该验证者)。此时,该验证者被称为“解绑中的验证者”,在解绑期结束后,它会成熟为“未绑定验证者”。 每个区块都会检查验证者队列中是否存在已成熟的解绑中验证者(即完成时间 <= 当前时间,且完成高度 <= 当前区块高度)。此时,任何已成熟且没有剩余委托的验证者都会从状态中删除。对于所有其他仍有剩余委托的已成熟解绑中验证者,其 validator.Status 会从 types.Unbonding 切换为 types.Unbonded。 外部模块可以通过 PutUnbondingOnHold(unbondingId) 方法暂停解绑操作。 因此,处于暂停状态的解绑操作(例如解绑委托)即使已经成熟,也无法完成。 对于具有 unbondingId 的解绑操作,若要最终完成(在其成熟之后),每一次对 PutUnbondingOnHold(unbondingId) 的调用都必须对应一次对 UnbondingCanComplete(unbondingId) 的调用。

解绑委托

通过以下流程,完成 UnbondingDelegations 队列中所有已成熟 UnbondingDelegations.Entries 的解绑:
  • 将余额中的 coin 转入委托人的钱包地址
  • 从 UnbondingDelegation.Entries 中移除已成熟条目
  • 如果没有剩余条目,则从存储中移除 UnbondingDelegation 对象

重新委托

通过以下流程,完成 Redelegations 队列中所有已成熟 Redelegation.Entries 的解绑:
  • 从 Redelegation.Entries 中移除已成熟条目
  • 如果没有剩余条目,则从存储中移除 Redelegation 对象

Hooks

其他模块可以注册操作,以便在 staking 中发生某个事件时执行。这些事件可以注册为在 staking 事件 Before 或 After 执行(与 hook 名称一致)。staking 可注册以下 hooks:
  • AfterValidatorCreated(Context, ValAddress) error
    • 在验证者创建时调用
  • BeforeValidatorModified(Context, ValAddress) error
    • 在验证者状态变更时调用
  • AfterValidatorRemoved(Context, ConsAddress, ValAddress) error
    • 在验证者被删除时调用
  • AfterValidatorBonded(Context, ConsAddress, ValAddress) error
    • 在验证者完成绑定时调用
  • AfterValidatorBeginUnbonding(Context, ConsAddress, ValAddress) error
    • 在验证者开始解绑时调用
  • BeforeDelegationCreated(Context, AccAddress, ValAddress) error
    • 在委托创建时调用
  • BeforeDelegationSharesModified(Context, AccAddress, ValAddress) error
    • 在委托份额被修改时调用
  • AfterDelegationModified(Context, AccAddress, ValAddress) error
    • 在委托被创建或修改时调用
  • BeforeDelegationRemoved(Context, AccAddress, ValAddress) error
    • 在委托被移除时调用
  • AfterUnbondingInitiated(Context, UnbondingID)
    • 在解绑操作(验证者解绑、解绑委托、重新委托)启动时调用

事件

staking 模块会触发以下事件:

EndBlocker

类型属性键属性值
complete_unbondingamount{totalUnbondingAmount}
complete_unbondingvalidator{validatorAddress}
complete_unbondingdelegator{delegatorAddress}
complete_redelegationamount{totalRedelegationAmount}
complete_redelegationsource_validator{srcValidatorAddress}
complete_redelegationdestination_validator{dstValidatorAddress}
complete_redelegationdelegator{delegatorAddress}

消息

MsgCreateValidator

类型属性键属性值
create_validatorvalidator{validatorAddress}
create_validatoramount{delegationAmount}
messagemodulestaking
messageactioncreate_validator
messagesender{senderAddress}

MsgEditValidator

类型属性键属性值
edit_validatorcommission_rate{commissionRate}
edit_validatormin_self_delegation{minSelfDelegation}
messagemodulestaking
messageactionedit_validator
messagesender{senderAddress}

MsgDelegate

类型属性键属性值
delegatevalidator{validatorAddress}
delegateamount{delegationAmount}
messagemodulestaking
messageactiondelegate
messagesender{senderAddress}

MsgUndelegate

类型属性键属性值
unbondvalidator{validatorAddress}
unbondamount{unbondAmount}
unbondcompletion_time [0]{completionTime}
messagemodulestaking
messageactionbegin_unbonding
messagesender{senderAddress}
  • [0] 时间按 RFC3339 标准格式化

MsgCancelUnbondingDelegation

类型属性键属性值
cancel_unbonding_delegationvalidator{validatorAddress}
cancel_unbonding_delegationdelegator{delegatorAddress}
cancel_unbonding_delegationamount{cancelUnbondingDelegationAmount}
cancel_unbonding_delegationcreation_height{unbondingCreationHeight}
messagemodulestaking
messageactioncancel_unbond
messagesender{senderAddress}

MsgBeginRedelegate

类型属性键属性值
redelegatesource_validator{srcValidatorAddress}
redelegatedestination_validator{dstValidatorAddress}
redelegateamount{unbondAmount}
redelegatecompletion_time [0]{completionTime}
messagemodulestaking
messageactionbegin_redelegate
messagesender{senderAddress}
  • [0] 时间按 RFC3339 标准格式化

参数

staking 模块包含以下参数:
键类型示例
UnbondingTimestring(时间 ns)“259200000000000”
MaxValidatorsuint16100
KeyMaxEntriesuint167
HistoricalEntriesuint163
BondDenomstring”stake”
MinCommissionRatestring”0.000000000000000000”

客户端

CLI

用户可以使用 CLI 查询并与 staking 模块交互。

查询

query 命令允许用户查询 staking 状态。
simd query staking --help
delegation
delegation 命令允许用户查询单个委托人在单个验证者上的委托。 用法:
simd query staking delegation [delegator-addr] [validator-addr] [flags]
示例:
simd query staking delegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
示例输出:
balance:
  amount: "10000000000"
  denom: stake
delegation:
  delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
  shares: "10000000000.000000000000000000"
  validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
delegations
delegations 命令允许用户查询单个委托人在所有验证者上的委托。 用法:
simd query staking delegations [delegator-addr] [flags]
示例:
simd query staking delegations cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
示例输出:
delegation_responses:
- balance:
    amount: "10000000000"
    denom: stake
  delegation:
    delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
    shares: "10000000000.000000000000000000"
    validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
- balance:
    amount: "10000000000"
    denom: stake
  delegation:
    delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
    shares: "10000000000.000000000000000000"
    validator_address: cosmosvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqfyqnp
pagination:
  next_key: null
  total: "0"
delegations-to
delegations-to 命令允许用户查询单个验证者上的委托。 用法:
simd query staking delegations-to [validator-addr] [flags]
示例:
simd query staking delegations-to cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
示例输出:
- balance:
    amount: "504000000"
    denom: stake
  delegation:
    delegator_address: cosmos1q2qwwynhv8kh3lu5fkeex4awau9x8fwt45f5cp
    shares: "504000000.000000000000000000"
    validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
- balance:
    amount: "78125000000"
    denom: uixo
  delegation:
    delegator_address: cosmos1qvppl3479hw4clahe0kwdlfvf8uvjtcd99m2ca
    shares: "78125000000.000000000000000000"
    validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
pagination:
  next_key: null
  total: "0"
historical-info
historical-info 命令允许用户查询指定高度的历史信息。 用法:
simd query staking historical-info [height] [flags]
示例:
simd query staking historical-info 10
示例输出:
header:
  app_hash: Lbx8cXpI868wz8sgp4qPYVrlaKjevR5WP/IjUxwp3oo=
  chain_id: testnet
  consensus_hash: BICRvH3cKD93v7+R1zxE2ljD34qcvIZ0Bdi389qtoi8=
  data_hash: 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
  evidence_hash: 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
  height: "10"
  last_block_id:
    hash: RFbkpu6pWfSThXxKKl6EZVDnBSm16+U0l0xVjTX08Fk=
    part_set_header:
      hash: vpIvXD4rxD5GM4MXGz0Sad9I7//iVYLzZsEU4BVgWIU=
      total: 1
  last_commit_hash: Ne4uXyx4QtNp4Zx89kf9UK7oG9QVbdB6e7ZwZkhy8K0=
  last_results_hash: 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
  next_validators_hash: nGBgKeWBjoxeKFti00CxHsnULORgKY4LiuQwBuUrhCs=
  proposer_address: mMEP2c2IRPLr99LedSRtBg9eONM=
  time: "2021-10-01T06:00:49.785790894Z"
  validators_hash: nGBgKeWBjoxeKFti00CxHsnULORgKY4LiuQwBuUrhCs=
  version:
    app: "0"
    block: "11"
valset:
- commission:
    commission_rates:
      max_change_rate: "0.010000000000000000"
      max_rate: "0.200000000000000000"
      rate: "0.100000000000000000"
    update_time: "2021-10-01T05:52:50.380144238Z"
  consensus_pubkey:
    '@type': /cosmos.crypto.ed25519.PubKey
    key: Auxs3865HpB/EfssYOzfqNhEJjzys2Fo6jD5B8tPgC8=
  delegator_shares: "10000000.000000000000000000"
  description:
    details: ""
    identity: ""
    moniker: myvalidator
    security_contact: ""
    website: ""
  jailed: false
  min_self_delegation: "1"
  operator_address: cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc
  status: BOND_STATUS_BONDED
  tokens: "10000000"
  unbonding_height: "0"
  unbonding_time: "1970-01-01T00:00:00Z"
params
params 命令允许用户查询设置为质押参数的值。 用法:
simd query staking params [flags]
示例:
simd query staking params
示例输出:
bond_denom: stake
historical_entries: 10000
max_entries: 7
max_validators: 50
unbonding_time: 1814400s
pool
pool 命令允许用户查询存储在质押池中的金额数值。 用法:
simd q staking pool [flags]
示例:
simd q staking pool
示例输出:
bonded_tokens: "10000000"
not_bonded_tokens: "0"
redelegation
redelegation 命令允许用户根据委托人地址以及源验证者和目标验证者地址查询一条重新委托记录。 用法:
simd query staking redelegation [delegator-addr] [src-validator-addr] [dst-validator-addr] [flags]
示例:
simd query staking redelegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
示例输出:
pagination: null
redelegation_responses:
- entries:
  - balance: "50000000"
    redelegation_entry:
      completion_time: "2021-10-24T20:33:21.960084845Z"
      creation_height: 2.382847e+06
      initial_balance: "50000000"
      shares_dst: "50000000.000000000000000000"
  - balance: "5000000000"
    redelegation_entry:
      completion_time: "2021-10-25T21:33:54.446846862Z"
      creation_height: 2.397271e+06
      initial_balance: "5000000000"
      shares_dst: "5000000000.000000000000000000"
  redelegation:
    delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
    entries: null
    validator_dst_address: cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm
    validator_src_address: cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm
redelegations
redelegations 命令允许用户查询某个委托人的全部重新委托记录。 用法:
simd query staking redelegations [delegator-addr] [flags]
示例:
simd query staking redelegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
示例输出:
pagination:
  next_key: null
  total: "0"
redelegation_responses:
- entries:
  - balance: "50000000"
    redelegation_entry:
      completion_time: "2021-10-24T20:33:21.960084845Z"
      creation_height: 2.382847e+06
      initial_balance: "50000000"
      shares_dst: "50000000.000000000000000000"
  - balance: "5000000000"
    redelegation_entry:
      completion_time: "2021-10-25T21:33:54.446846862Z"
      creation_height: 2.397271e+06
      initial_balance: "5000000000"
      shares_dst: "5000000000.000000000000000000"
  redelegation:
    delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
    entries: null
    validator_dst_address: cosmosvaloper1uccl5ugxrm7vqlzwqr04pjd320d2fz0z3hc6vm
    validator_src_address: cosmosvaloper1zppjyal5emta5cquje8ndkpz0rs046m7zqxrpp
- entries:
  - balance: "562770000000"
    redelegation_entry:
      completion_time: "2021-10-25T21:42:07.336911677Z"
      creation_height: 2.39735e+06
      initial_balance: "562770000000"
      shares_dst: "562770000000.000000000000000000"
  redelegation:
    delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
    entries: null
    validator_dst_address: cosmosvaloper1uccl5ugxrm7vqlzwqr04pjd320d2fz0z3hc6vm
    validator_src_address: cosmosvaloper1zppjyal5emta5cquje8ndkpz0rs046m7zqxrpp
redelegations-from
redelegations-from 命令允许用户查询正在从某个验证者重新委托出去的委托记录。 用法:
simd query staking redelegations-from [validator-addr] [flags]
示例:
simd query staking redelegations-from cosmosvaloper1y4rzzrgl66eyhzt6gse2k7ej3zgwmngeleucjy
示例输出:
pagination:
  next_key: null
  total: "0"
redelegation_responses:
- entries:
  - balance: "50000000"
    redelegation_entry:
      completion_time: "2021-10-24T20:33:21.960084845Z"
      creation_height: 2.382847e+06
      initial_balance: "50000000"
      shares_dst: "50000000.000000000000000000"
  - balance: "5000000000"
    redelegation_entry:
      completion_time: "2021-10-25T21:33:54.446846862Z"
      creation_height: 2.397271e+06
      initial_balance: "5000000000"
      shares_dst: "5000000000.000000000000000000"
  redelegation:
    delegator_address: cosmos1pm6e78p4pgn0da365plzl4t56pxy8hwtqp2mph
    entries: null
    validator_dst_address: cosmosvaloper1uccl5ugxrm7vqlzwqr04pjd320d2fz0z3hc6vm
    validator_src_address: cosmosvaloper1y4rzzrgl66eyhzt6gse2k7ej3zgwmngeleucjy
- entries:
  - balance: "221000000"
    redelegation_entry:
      completion_time: "2021-10-05T21:05:45.669420544Z"
      creation_height: 2.120693e+06
      initial_balance: "221000000"
      shares_dst: "221000000.000000000000000000"
  redelegation:
    delegator_address: cosmos1zqv8qxy2zgn4c58fz8jt8jmhs3d0attcussrf6
    entries: null
    validator_dst_address: cosmosvaloper10mseqwnwtjaqfrwwp2nyrruwmjp6u5jhah4c3y
    validator_src_address: cosmosvaloper1y4rzzrgl66eyhzt6gse2k7ej3zgwmngeleucjy
unbonding-delegation
unbonding-delegation 命令允许用户查询某个委托人在某个验证者上的解绑委托。 用法:
simd query staking unbonding-delegation [delegator-addr] [validator-addr] [flags]
示例:
simd query staking unbonding-delegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
示例输出:
delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
entries:
- balance: "52000000"
  completion_time: "2021-11-02T11:35:55.391594709Z"
  creation_height: "55078"
  initial_balance: "52000000"
validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
unbonding-delegations
unbonding-delegations 命令允许用户查询某个委托人的全部解绑委托记录。 用法:
simd query staking unbonding-delegations [delegator-addr] [flags]
示例:
simd query staking unbonding-delegations cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
示例输出:
pagination:
  next_key: null
  total: "0"
unbonding_responses:
- delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
  entries:
  - balance: "52000000"
    completion_time: "2021-11-02T11:35:55.391594709Z"
    creation_height: "55078"
    initial_balance: "52000000"
  validator_address: cosmosvaloper1t8ehvswxjfn3ejzkjtntcyrqwvmvuknzmvtaaa

unbonding-delegations-from
unbonding-delegations-from 命令允许用户查询从某个验证者 发起解绑 的委托。 用法:
simd query staking unbonding-delegations-from [validator-addr] [flags]
示例:
simd query staking unbonding-delegations-from cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
示例输出:
pagination:
  next_key: null
  total: "0"
unbonding_responses:
- delegator_address: cosmos1qqq9txnw4c77sdvzx0tkedsafl5s3vk7hn53fn
  entries:
  - balance: "150000000"
    completion_time: "2021-11-01T21:41:13.098141574Z"
    creation_height: "46823"
    initial_balance: "150000000"
  validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
- delegator_address: cosmos1peteje73eklqau66mr7h7rmewmt2vt99y24f5z
  entries:
  - balance: "24000000"
    completion_time: "2021-10-31T02:57:18.192280361Z"
    creation_height: "21516"
    initial_balance: "24000000"
  validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
validator
validator 命令允许用户查询单个验证者的详细信息。 用法:
simd query staking validator [validator-addr] [flags]
示例:
simd query staking validator cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
示例输出:
commission:
  commission_rates:
    max_change_rate: "0.020000000000000000"
    max_rate: "0.200000000000000000"
    rate: "0.050000000000000000"
  update_time: "2021-10-01T19:24:52.663191049Z"
consensus_pubkey:
  '@type': /cosmos.crypto.ed25519.PubKey
  key: sIiexdJdYWn27+7iUHQJDnkp63gq/rzUq1Y+fxoGjXc=
delegator_shares: "32948270000.000000000000000000"
description:
  details: Witval is the validator arm from Vitwit. Vitwit is into software consulting
    and services business since 2015. We are working closely with Cosmos ecosystem
    since 2018. We are also building tools for the ecosystem, Aneka is our explorer
    for the cosmos ecosystem.
  identity: 51468B615127273A
  moniker: Witval
  security_contact: ""
  website: ""
jailed: false
min_self_delegation: "1"
operator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
status: BOND_STATUS_BONDED
tokens: "32948270000"
unbonding_height: "0"
unbonding_time: "1970-01-01T00:00:00Z"
validators
validators 命令允许用户查询网络中所有验证者的详细信息。 用法:
simd query staking validators [flags]
示例:
simd query staking validators
示例输出:
pagination:
  next_key: FPTi7TKAjN63QqZh+BaXn6gBmD5/
  total: "0"
validators:
commission:
  commission_rates:
    max_change_rate: "0.020000000000000000"
    max_rate: "0.200000000000000000"
    rate: "0.050000000000000000"
  update_time: "2021-10-01T19:24:52.663191049Z"
consensus_pubkey:
  '@type': /cosmos.crypto.ed25519.PubKey
  key: sIiexdJdYWn27+7iUHQJDnkp63gq/rzUq1Y+fxoGjXc=
delegator_shares: "32948270000.000000000000000000"
description:
    details: Witval is the validator arm from Vitwit. Vitwit is into software consulting
      and services business since 2015. We are working closely with Cosmos ecosystem
      since 2018. We are also building tools for the ecosystem, Aneka is our explorer
      for the cosmos ecosystem.
    identity: 51468B615127273A
    moniker: Witval
    security_contact: ""
    website: ""
  jailed: false
  min_self_delegation: "1"
  operator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
  status: BOND_STATUS_BONDED
  tokens: "32948270000"
  unbonding_height: "0"
  unbonding_time: "1970-01-01T00:00:00Z"
- commission:
    commission_rates:
      max_change_rate: "0.100000000000000000"
      max_rate: "0.200000000000000000"
      rate: "0.050000000000000000"
    update_time: "2021-10-04T18:02:21.446645619Z"
  consensus_pubkey:
    '@type': /cosmos.crypto.ed25519.PubKey
    key: GDNpuKDmCg9GnhnsiU4fCWktuGUemjNfvpCZiqoRIYA=
  delegator_shares: "559343421.000000000000000000"
  description:
    details: Noderunners is a professional validator in POS networks. We have a huge
      node running experience, reliable soft and hardware. Our commissions are always
      low, our support to delegators is always full. Stake with us and start receiving
      your Cosmos rewards now!
    identity: 812E82D12FEA3493
    moniker: Noderunners
    security_contact: [email protected]
    website: http://noderunners.biz
  jailed: false
  min_self_delegation: "1"
  operator_address: cosmosvaloper1q5ku90atkhktze83j9xjaks2p7uruag5zp6wt7
  status: BOND_STATUS_BONDED
  tokens: "559343421"
  unbonding_height: "0"
  unbonding_time: "1970-01-01T00:00:00Z"

交易

tx 命令允许用户与 staking 模块交互。
simd tx staking --help
create-validator
create-validator 命令允许用户创建新的验证者,并在创建时为其初始化一笔自委托。 用法:
simd tx staking create-validator [path/to/validator.json] [flags]
示例:
simd tx staking create-validator /path/to/validator.json \
  --chain-id="name_of_chain_id" \
  --gas="auto" \
  --gas-adjustment="1.2" \
  --gas-prices="0.025stake" \
  --from=mykey
其中,validator.json 包含:
{
  "pubkey": {
    "@type": "/cosmos.crypto.ed25519.PubKey",
    "key": "BnbwFpeONLqvWqJb3qaUbL5aoIcW3fSuAp9nT3z5f20="
  },
  "amount": "1000000stake",
  "moniker": "my-moniker",
  "website": "https://myweb.site",
  "security": "[email protected]",
  "details": "description of your validator",
  "commission-rate": "0.10",
  "commission-max-rate": "0.20",
  "commission-max-change-rate": "0.01",
  "min-self-delegation": "1"
}
公钥可以通过 simd tendermint show-validator 命令获取。
delegate
delegate 命令允许用户将流动代币委托给某个验证者。 用法:
simd tx staking delegate [validator-addr] [amount] [flags]
示例:
simd tx staking delegate cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm 1000stake --from mykey
edit-validator
edit-validator 命令允许用户编辑现有的验证者账户。 用法:
simd tx staking edit-validator [flags]
示例:
simd tx staking edit-validator --moniker "new_moniker_name" --website "new_webiste_url" --from mykey
redelegate
redelegate 命令允许用户将非流动代币从一个验证者重新委托给另一个验证者。 用法:
simd tx staking redelegate [src-validator-addr] [dst-validator-addr] [amount] [flags]
示例:
simd tx staking redelegate cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm 100stake --from mykey
unbond
unbond 命令允许用户从某个验证者处解绑份额。 用法:
simd tx staking unbond [validator-addr] [amount] [flags]
示例:
simd tx staking unbond cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 100stake --from mykey
cancel unbond
cancel-unbond 命令允许用户取消正在解绑的委托条目,并重新委托回原始验证者。 用法:
simd tx staking cancel-unbond [validator-addr] [amount] [creation-height]
示例:
simd tx staking cancel-unbond cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 100stake 123123 --from mykey

gRPC

用户可以使用 gRPC 端点查询 staking 模块。

Validators

Validators 端点用于查询所有符合给定状态的验证者。
cosmos.staking.v1beta1.Query/Validators
示例:
grpcurl -plaintext localhost:9090 cosmos.staking.v1beta1.Query/Validators
示例输出:
{
  "validators": [
    {
      "operatorAddress": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
      "consensusPubkey": {"@type":"/cosmos.crypto.ed25519.PubKey","key":"Auxs3865HpB/EfssYOzfqNhEJjzys2Fo6jD5B8tPgC8="},
      "status": "BOND_STATUS_BONDED",
      "tokens": "10000000",
      "delegatorShares": "10000000000000000000000000",
      "description": {
        "moniker": "myvalidator"
      },
      "unbondingTime": "1970-01-01T00:00:00Z",
      "commission": {
        "commissionRates": {
          "rate": "100000000000000000",
          "maxRate": "200000000000000000",
          "maxChangeRate": "10000000000000000"
        },
        "updateTime": "2021-10-01T05:52:50.380144238Z"
      },
      "minSelfDelegation": "1"
    }
  ],
  "pagination": {
    "total": "1"
  }
}

Validator

Validator 端点用于查询给定验证者地址的验证者信息。
cosmos.staking.v1beta1.Query/Validator
示例:
grpcurl -plaintext -d '{"validator_addr":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc"}' \
localhost:9090 cosmos.staking.v1beta1.Query/Validator
示例输出:
{
  "validator": {
    "operatorAddress": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
    "consensusPubkey": {"@type":"/cosmos.crypto.ed25519.PubKey","key":"Auxs3865HpB/EfssYOzfqNhEJjzys2Fo6jD5B8tPgC8="},
    "status": "BOND_STATUS_BONDED",
    "tokens": "10000000",
    "delegatorShares": "10000000000000000000000000",
    "description": {
      "moniker": "myvalidator"
    },
    "unbondingTime": "1970-01-01T00:00:00Z",
    "commission": {
      "commissionRates": {
        "rate": "100000000000000000",
        "maxRate": "200000000000000000",
        "maxChangeRate": "10000000000000000"
      },
      "updateTime": "2021-10-01T05:52:50.380144238Z"
    },
    "minSelfDelegation": "1"
  }
}

ValidatorDelegations

ValidatorDelegations 端点用于查询给定验证者的委托信息。
cosmos.staking.v1beta1.Query/ValidatorDelegations
示例:
grpcurl -plaintext -d '{"validator_addr":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc"}' \
localhost:9090 cosmos.staking.v1beta1.Query/ValidatorDelegations
示例输出:
{
  "delegationResponses": [
    {
      "delegation": {
        "delegatorAddress": "cosmos1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgy3ua5t",
        "validatorAddress": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
        "shares": "10000000000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "10000000"
      }
    }
  ],
  "pagination": {
    "total": "1"
  }
}

ValidatorUnbondingDelegations

ValidatorUnbondingDelegations 端点用于查询给定验证者的委托信息。
cosmos.staking.v1beta1.Query/ValidatorUnbondingDelegations
示例:
grpcurl -plaintext -d '{"validator_addr":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc"}' \
localhost:9090 cosmos.staking.v1beta1.Query/ValidatorUnbondingDelegations
示例输出:
{
  "unbonding_responses": [
    {
      "delegator_address": "cosmos1z3pzzw84d6xn00pw9dy3yapqypfde7vg6965fy",
      "validator_address": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
      "entries": [
        {
          "creation_height": "25325",
          "completion_time": "2021-10-31T09:24:36.797320636Z",
          "initial_balance": "20000000",
          "balance": "20000000"
        }
      ]
    },
    {
      "delegator_address": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77",
      "validator_address": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
      "entries": [
        {
          "creation_height": "13100",
          "completion_time": "2021-10-30T12:53:02.272266791Z",
          "initial_balance": "1000000",
          "balance": "1000000"
        }
      ]
    },
  ],
  "pagination": {
    "next_key": null,
    "total": "8"
  }
}

Delegation

Delegation 端点用于查询给定验证者与委托人组合的委托信息。
cosmos.staking.v1beta1.Query/Delegation
示例:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77", validator_addr":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc"}' \
localhost:9090 cosmos.staking.v1beta1.Query/Delegation
示例输出:
{
  "delegation_response":
  {
    "delegation":
      {
        "delegator_address":"cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77",
        "validator_address":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
        "shares":"25083119936.000000000000000000"
      },
    "balance":
      {
        "denom":"stake",
        "amount":"25083119936"
      }
  }
}

UnbondingDelegation

UnbondingDelegation 端点用于查询给定验证者与委托人的解绑委托信息。
cosmos.staking.v1beta1.Query/UnbondingDelegation
示例:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77", validator_addr":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc"}' \
localhost:9090 cosmos.staking.v1beta1.Query/UnbondingDelegation
示例输出:
{
  "unbond": {
    "delegator_address": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77",
    "validator_address": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
    "entries": [
      {
        "creation_height": "136984",
        "completion_time": "2021-11-08T05:38:47.505593891Z",
        "initial_balance": "400000000",
        "balance": "400000000"
      },
      {
        "creation_height": "137005",
        "completion_time": "2021-11-08T05:40:53.526196312Z",
        "initial_balance": "385000000",
        "balance": "385000000"
      }
    ]
  }
}

DelegatorDelegations

DelegatorDelegations 端点用于查询给定委托人地址的全部委托。
cosmos.staking.v1beta1.Query/DelegatorDelegations
示例:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77"}' \
localhost:9090 cosmos.staking.v1beta1.Query/DelegatorDelegations
示例输出:
{
  "delegation_responses": [
    {"delegation":{"delegator_address":"cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77","validator_address":"cosmosvaloper1eh5mwu044gd5ntkkc2xgfg8247mgc56fww3vc8","shares":"25083339023.000000000000000000"},"balance":{"denom":"stake","amount":"25083339023"}}
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

DelegatorUnbondingDelegations

DelegatorUnbondingDelegations 端点用于查询给定委托人地址的全部解绑委托。
cosmos.staking.v1beta1.Query/DelegatorUnbondingDelegations
示例:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77"}' \
localhost:9090 cosmos.staking.v1beta1.Query/DelegatorUnbondingDelegations
示例输出:
{
  "unbonding_responses": [
    {
      "delegator_address": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77",
      "validator_address": "cosmosvaloper1sjllsnramtg3ewxqwwrwjxfgc4n4ef9uxyejze",
      "entries": [
        {
          "creation_height": "136984",
          "completion_time": "2021-11-08T05:38:47.505593891Z",
          "initial_balance": "400000000",
          "balance": "400000000"
        },
        {
          "creation_height": "137005",
          "completion_time": "2021-11-08T05:40:53.526196312Z",
          "initial_balance": "385000000",
          "balance": "385000000"
        }
      ]
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

Redelegations

Redelegations 端点用于查询给定地址的重新委托信息。
cosmos.staking.v1beta1.Query/Redelegations
示例:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1ld5p7hn43yuh8ht28gm9pfjgj2fctujp2tgwvf", "src_validator_addr" : "cosmosvaloper1j7euyj85fv2jugejrktj540emh9353ltgppc3g", "dst_validator_addr" : "cosmosvaloper1yy3tnegzmkdcm7czzcy3flw5z0zyr9vkkxrfse"}' \
localhost:9090 cosmos.staking.v1beta1.Query/Redelegations
示例输出:
{
  "redelegation_responses": [
    {
      "redelegation": {
        "delegator_address": "cosmos1ld5p7hn43yuh8ht28gm9pfjgj2fctujp2tgwvf",
        "validator_src_address": "cosmosvaloper1j7euyj85fv2jugejrktj540emh9353ltgppc3g",
        "validator_dst_address": "cosmosvaloper1yy3tnegzmkdcm7czzcy3flw5z0zyr9vkkxrfse",
        "entries": null
      },
      "entries": [
        {
          "redelegation_entry": {
            "creation_height": 135932,
            "completion_time": "2021-11-08T03:52:55.299147901Z",
            "initial_balance": "2900000",
            "shares_dst": "2900000.000000000000000000"
          },
          "balance": "2900000"
        }
      ]
    }
  ],
  "pagination": null
}

DelegatorValidators

DelegatorValidators 端点用于查询给定委托人的所有验证者信息。
cosmos.staking.v1beta1.Query/DelegatorValidators
示例:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1ld5p7hn43yuh8ht28gm9pfjgj2fctujp2tgwvf"}' \
localhost:9090 cosmos.staking.v1beta1.Query/DelegatorValidators
示例输出:
{
  "validators": [
    {
      "operator_address": "cosmosvaloper1eh5mwu044gd5ntkkc2xgfg8247mgc56fww3vc8",
      "consensus_pubkey": {
        "@type": "/cosmos.crypto.ed25519.PubKey",
        "key": "UPwHWxH1zHJWGOa/m6JB3f5YjHMvPQPkVbDqqi+U7Uw="
      },
      "jailed": false,
      "status": "BOND_STATUS_BONDED",
      "tokens": "347260647559",
      "delegator_shares": "347260647559.000000000000000000",
      "description": {
        "moniker": "BouBouNode",
        "identity": "",
        "website": "https://boubounode.com",
        "security_contact": "",
        "details": "AI-based Validator. #1 AI Validator on Game of Stakes. Fairly priced. Don't trust (humans), verify. Made with BouBou love."
      },
      "unbonding_height": "0",
      "unbonding_time": "1970-01-01T00:00:00Z",
      "commission": {
        "commission_rates": {
          "rate": "0.061000000000000000",
          "max_rate": "0.300000000000000000",
          "max_change_rate": "0.150000000000000000"
        },
        "update_time": "2021-10-01T15:00:00Z"
      },
      "min_self_delegation": "1"
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

DelegatorValidator

DelegatorValidator 端点用于查询给定委托人与验证者对应的验证者信息。
cosmos.staking.v1beta1.Query/DelegatorValidator
示例:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1eh5mwu044gd5ntkkc2xgfg8247mgc56f3n8rr7", "validator_addr": "cosmosvaloper1eh5mwu044gd5ntkkc2xgfg8247mgc56fww3vc8"}' \
localhost:9090 cosmos.staking.v1beta1.Query/DelegatorValidator
示例输出:
{
  "validator": {
    "operator_address": "cosmosvaloper1eh5mwu044gd5ntkkc2xgfg8247mgc56fww3vc8",
    "consensus_pubkey": {
      "@type": "/cosmos.crypto.ed25519.PubKey",
      "key": "UPwHWxH1zHJWGOa/m6JB3f5YjHMvPQPkVbDqqi+U7Uw="
    },
    "jailed": false,
    "status": "BOND_STATUS_BONDED",
    "tokens": "347262754841",
    "delegator_shares": "347262754841.000000000000000000",
    "description": {
      "moniker": "BouBouNode",
      "identity": "",
      "website": "https://boubounode.com",
      "security_contact": "",
      "details": "AI-based Validator. #1 AI Validator on Game of Stakes. Fairly priced. Don't trust (humans), verify. Made with BouBou love."
    },
    "unbonding_height": "0",
    "unbonding_time": "1970-01-01T00:00:00Z",
    "commission": {
      "commission_rates": {
        "rate": "0.061000000000000000",
        "max_rate": "0.300000000000000000",
        "max_change_rate": "0.150000000000000000"
      },
      "update_time": "2021-10-01T15:00:00Z"
    },
    "min_self_delegation": "1"
  }
}

HistoricalInfo

cosmos.staking.v1beta1.Query/HistoricalInfo
示例:
grpcurl -plaintext -d '{"height" : 1}' localhost:9090 cosmos.staking.v1beta1.Query/HistoricalInfo
示例输出:
{
  "hist": {
    "header": {
      "version": {
        "block": "11",
        "app": "0"
      },
      "chain_id": "simd-1",
      "height": "140142",
      "time": "2021-10-11T10:56:29.720079569Z",
      "last_block_id": {
        "hash": "9gri/4LLJUBFqioQ3NzZIP9/7YHR9QqaM6B2aJNQA7o=",
        "part_set_header": {
          "total": 1,
          "hash": "Hk1+C864uQkl9+I6Zn7IurBZBKUevqlVtU7VqaZl1tc="
        }
      },
      "last_commit_hash": "VxrcS27GtvGruS3I9+AlpT7udxIT1F0OrRklrVFSSKc=",
      "data_hash": "80BjOrqNYUOkTnmgWyz9AQ8n7SoEmPVi4QmAe8RbQBY=",
      "validators_hash": "95W49n2hw8RWpr1GPTAO5MSPi6w6Wjr3JjjS7AjpBho=",
      "next_validators_hash": "95W49n2hw8RWpr1GPTAO5MSPi6w6Wjr3JjjS7AjpBho=",
      "consensus_hash": "BICRvH3cKD93v7+R1zxE2ljD34qcvIZ0Bdi389qtoi8=",
      "app_hash": "ZZaxnSY3E6Ex5Bvkm+RigYCK82g8SSUL53NymPITeOE=",
      "last_results_hash": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
      "evidence_hash": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
      "proposer_address": "aH6dO428B+ItuoqPq70efFHrSMY="
    },
  "valset": [
      {
        "operator_address": "cosmosvaloper196ax4vc0lwpxndu9dyhvca7jhxp70rmcqcnylw",
        "consensus_pubkey": {
          "@type": "/cosmos.crypto.ed25519.PubKey",
          "key": "/O7BtNW0pafwfvomgR4ZnfldwPXiFfJs9mHg3gwfv5Q="
        },
        "jailed": false,
        "status": "BOND_STATUS_BONDED",
        "tokens": "1426045203613",
        "delegator_shares": "1426045203613.000000000000000000",
        "description": {
          "moniker": "SG-1",
          "identity": "48608633F99D1B60",
          "website": "https://sg-1.online",
          "security_contact": "",
          "details": "SG-1 - your favorite validator on Witval. We offer 100% Soft Slash protection."
        },
        "unbonding_height": "0",
        "unbonding_time": "1970-01-01T00:00:00Z",
        "commission": {
          "commission_rates": {
            "rate": "0.037500000000000000",
            "max_rate": "0.200000000000000000",
            "max_change_rate": "0.030000000000000000"
          },
          "update_time": "2021-10-01T15:00:00Z"
        },
        "min_self_delegation": "1"
      }
    ]
  }
}

Pool

Pool 端点用于查询池信息。
cosmos.staking.v1beta1.Query/Pool
示例:
grpcurl -plaintext -d localhost:9090 cosmos.staking.v1beta1.Query/Pool
示例输出:
{
  "pool": {
    "not_bonded_tokens": "369054400189",
    "bonded_tokens": "15657192425623"
  }
}

Params

Params 端点用于查询池信息。
cosmos.staking.v1beta1.Query/Params
示例:
grpcurl -plaintext localhost:9090 cosmos.staking.v1beta1.Query/Params
示例输出:
{
  "params": {
    "unbondingTime": "1814400s",
    "maxValidators": 100,
    "maxEntries": 7,
    "historicalEntries": 10000,
    "bondDenom": "stake"
  }
}

REST

用户可以使用 REST 端点查询 staking 模块。

DelegatorDelegations

DelegtaorDelegations REST 端点用于查询给定委托人地址的所有委托。
/cosmos/staking/v1beta1/delegations/{delegatorAddr}
示例:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/delegations/cosmos1vcs68xf2tnqes5tg0khr0vyevm40ff6zdxatp5" -H  "accept: application/json"
示例输出:
{
  "delegation_responses": [
    {
      "delegation": {
        "delegator_address": "cosmos1vcs68xf2tnqes5tg0khr0vyevm40ff6zdxatp5",
        "validator_address": "cosmosvaloper1quqxfrxkycr0uzt4yk0d57tcq3zk7srm7sm6r8",
        "shares": "256250000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "256250000"
      }
    },
    {
      "delegation": {
        "delegator_address": "cosmos1vcs68xf2tnqes5tg0khr0vyevm40ff6zdxatp5",
        "validator_address": "cosmosvaloper194v8uwee2fvs2s8fa5k7j03ktwc87h5ym39jfv",
        "shares": "255150000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "255150000"
      }
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "2"
  }
}

Redelegations

Redelegations REST 端点用于查询给定地址的再委托。
/cosmos/staking/v1beta1/delegators/{delegatorAddr}/redelegations
示例:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/delegators/cosmos1thfntksw0d35n2tkr0k8v54fr8wxtxwxl2c56e/redelegations?srcValidatorAddr=cosmosvaloper1lzhlnpahvznwfv4jmay2tgaha5kmz5qx4cuznf&dstValidatorAddr=cosmosvaloper1vq8tw77kp8lvxq9u3c8eeln9zymn68rng8pgt4" \
-H  "accept: application/json"
示例输出:
{
  "redelegation_responses": [
    {
      "redelegation": {
        "delegator_address": "cosmos1thfntksw0d35n2tkr0k8v54fr8wxtxwxl2c56e",
        "validator_src_address": "cosmosvaloper1lzhlnpahvznwfv4jmay2tgaha5kmz5qx4cuznf",
        "validator_dst_address": "cosmosvaloper1vq8tw77kp8lvxq9u3c8eeln9zymn68rng8pgt4",
        "entries": null
      },
      "entries": [
        {
          "redelegation_entry": {
            "creation_height": 151523,
            "completion_time": "2021-11-09T06:03:25.640682116Z",
            "initial_balance": "200000000",
            "shares_dst": "200000000.000000000000000000"
          },
          "balance": "200000000"
        }
      ]
    }
  ],
  "pagination": null
}

DelegatorUnbondingDelegations

DelegatorUnbondingDelegations REST 端点用于查询给定委托人地址的所有解绑中委托。
/cosmos/staking/v1beta1/delegators/{delegatorAddr}/unbonding_delegations
示例:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/delegators/cosmos1nxv42u3lv642q0fuzu2qmrku27zgut3n3z7lll/unbonding_delegations" \
-H  "accept: application/json"
示例输出:
{
  "unbonding_responses": [
    {
      "delegator_address": "cosmos1nxv42u3lv642q0fuzu2qmrku27zgut3n3z7lll",
      "validator_address": "cosmosvaloper1e7mvqlz50ch6gw4yjfemsc069wfre4qwmw53kq",
      "entries": [
        {
          "creation_height": "2442278",
          "completion_time": "2021-10-12T10:59:03.797335857Z",
          "initial_balance": "50000000000",
          "balance": "50000000000"
        }
      ]
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

DelegatorValidators

DelegatorValidators REST 端点用于查询给定委托人地址对应的所有验证者信息。
/cosmos/staking/v1beta1/delegators/{delegatorAddr}/validators
示例:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/delegators/cosmos1xwazl8ftks4gn00y5x3c47auquc62ssune9ppv/validators" \
-H  "accept: application/json"
示例输出:
{
  "validators": [
    {
      "operator_address": "cosmosvaloper1xwazl8ftks4gn00y5x3c47auquc62ssuvynw64",
      "consensus_pubkey": {
        "@type": "/cosmos.crypto.ed25519.PubKey",
        "key": "5v4n3px3PkfNnKflSgepDnsMQR1hiNXnqOC11Y72/PQ="
      },
      "jailed": false,
      "status": "BOND_STATUS_BONDED",
      "tokens": "21592843799",
      "delegator_shares": "21592843799.000000000000000000",
      "description": {
        "moniker": "jabbey",
        "identity": "",
        "website": "https://twitter.com/JoeAbbey",
        "security_contact": "",
        "details": "just another dad in the cosmos"
      },
      "unbonding_height": "0",
      "unbonding_time": "1970-01-01T00:00:00Z",
      "commission": {
        "commission_rates": {
          "rate": "0.100000000000000000",
          "max_rate": "0.200000000000000000",
          "max_change_rate": "0.100000000000000000"
        },
        "update_time": "2021-10-09T19:03:54.984821705Z"
      },
      "min_self_delegation": "1"
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

DelegatorValidator

DelegatorValidator REST 端点用于查询给定委托人和验证者配对的信息。
/cosmos/staking/v1beta1/delegators/{delegatorAddr}/validators/{validatorAddr}
示例:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/delegators/cosmos1xwazl8ftks4gn00y5x3c47auquc62ssune9ppv/validators/cosmosvaloper1xwazl8ftks4gn00y5x3c47auquc62ssuvynw64" \
-H  "accept: application/json"
示例输出:
{
  "validator": {
    "operator_address": "cosmosvaloper1xwazl8ftks4gn00y5x3c47auquc62ssuvynw64",
    "consensus_pubkey": {
      "@type": "/cosmos.crypto.ed25519.PubKey",
      "key": "5v4n3px3PkfNnKflSgepDnsMQR1hiNXnqOC11Y72/PQ="
    },
    "jailed": false,
    "status": "BOND_STATUS_BONDED",
    "tokens": "21592843799",
    "delegator_shares": "21592843799.000000000000000000",
    "description": {
      "moniker": "jabbey",
      "identity": "",
      "website": "https://twitter.com/JoeAbbey",
      "security_contact": "",
      "details": "just another dad in the cosmos"
    },
    "unbonding_height": "0",
    "unbonding_time": "1970-01-01T00:00:00Z",
    "commission": {
      "commission_rates": {
        "rate": "0.100000000000000000",
        "max_rate": "0.200000000000000000",
        "max_change_rate": "0.100000000000000000"
      },
      "update_time": "2021-10-09T19:03:54.984821705Z"
    },
    "min_self_delegation": "1"
  }
}

HistoricalInfo

HistoricalInfo REST 端点用于查询给定高度的历史信息。
/cosmos/staking/v1beta1/historical_info/{height}
示例:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/historical_info/153332" -H  "accept: application/json"
示例输出:
{
  "hist": {
    "header": {
      "version": {
        "block": "11",
        "app": "0"
      },
      "chain_id": "cosmos-1",
      "height": "153332",
      "time": "2021-10-12T09:05:35.062230221Z",
      "last_block_id": {
        "hash": "NX8HevR5khb7H6NGKva+jVz7cyf0skF1CrcY9A0s+d8=",
        "part_set_header": {
          "total": 1,
          "hash": "zLQ2FiKM5tooL3BInt+VVfgzjlBXfq0Hc8Iux/xrhdg="
        }
      },
      "last_commit_hash": "P6IJrK8vSqU3dGEyRHnAFocoDGja0bn9euLuy09s350=",
      "data_hash": "eUd+6acHWrNXYju8Js449RJ99lOYOs16KpqQl4SMrEM=",
      "validators_hash": "mB4pravvMsJKgi+g8aYdSeNlt0kPjnRFyvtAQtaxcfw=",
      "next_validators_hash": "mB4pravvMsJKgi+g8aYdSeNlt0kPjnRFyvtAQtaxcfw=",
      "consensus_hash": "BICRvH3cKD93v7+R1zxE2ljD34qcvIZ0Bdi389qtoi8=",
      "app_hash": "fuELArKRK+CptnZ8tu54h6xEleSWenHNmqC84W866fU=",
      "last_results_hash": "p/BPexV4LxAzlVcPRvW+lomgXb6Yze8YLIQUo/4Kdgc=",
      "evidence_hash": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
      "proposer_address": "G0MeY8xQx7ooOsni8KE/3R/Ib3Q="
    },
    "valset": [
      {
        "operator_address": "cosmosvaloper196ax4vc0lwpxndu9dyhvca7jhxp70rmcqcnylw",
        "consensus_pubkey": {
          "@type": "/cosmos.crypto.ed25519.PubKey",
          "key": "/O7BtNW0pafwfvomgR4ZnfldwPXiFfJs9mHg3gwfv5Q="
        },
        "jailed": false,
        "status": "BOND_STATUS_BONDED",
        "tokens": "1416521659632",
        "delegator_shares": "1416521659632.000000000000000000",
        "description": {
          "moniker": "SG-1",
          "identity": "48608633F99D1B60",
          "website": "https://sg-1.online",
          "security_contact": "",
          "details": "SG-1 - your favorite validator on cosmos. We offer 100% Soft Slash protection."
        },
        "unbonding_height": "0",
        "unbonding_time": "1970-01-01T00:00:00Z",
        "commission": {
          "commission_rates": {
            "rate": "0.037500000000000000",
            "max_rate": "0.200000000000000000",
            "max_change_rate": "0.030000000000000000"
          },
          "update_time": "2021-10-01T15:00:00Z"
        },
        "min_self_delegation": "1"
      },
      {
        "operator_address": "cosmosvaloper1t8ehvswxjfn3ejzkjtntcyrqwvmvuknzmvtaaa",
        "consensus_pubkey": {
          "@type": "/cosmos.crypto.ed25519.PubKey",
          "key": "uExZyjNLtr2+FFIhNDAMcQ8+yTrqE7ygYTsI7khkA5Y="
        },
        "jailed": false,
        "status": "BOND_STATUS_BONDED",
        "tokens": "1348298958808",
        "delegator_shares": "1348298958808.000000000000000000",
        "description": {
          "moniker": "Cosmostation",
          "identity": "AE4C403A6E7AA1AC",
          "website": "https://www.cosmostation.io",
          "security_contact": "[email protected]",
          "details": "Cosmostation validator node. Delegate your tokens and Start Earning Staking Rewards"
        },
        "unbonding_height": "0",
        "unbonding_time": "1970-01-01T00:00:00Z",
        "commission": {
          "commission_rates": {
            "rate": "0.050000000000000000",
            "max_rate": "1.000000000000000000",
            "max_change_rate": "0.200000000000000000"
          },
          "update_time": "2021-10-01T15:06:38.821314287Z"
        },
        "min_self_delegation": "1"
      }
    ]
  }
}

Parameters

Parameters REST 端点用于查询质押参数。
/cosmos/staking/v1beta1/params
示例:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/params" -H  "accept: application/json"
示例输出:
{
  "params": {
    "unbonding_time": "2419200s",
    "max_validators": 100,
    "max_entries": 7,
    "historical_entries": 10000,
    "bond_denom": "stake"
  }
}

Pool

Pool REST 端点用于查询资金池信息。
/cosmos/staking/v1beta1/pool
示例:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/pool" -H  "accept: application/json"
示例输出:
{
  "pool": {
    "not_bonded_tokens": "432805737458",
    "bonded_tokens": "15783637712645"
  }
}

验证人

Validators REST 端点会查询所有与给定状态匹配的验证人。
/cosmos/staking/v1beta1/validators
示例:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/validators" -H  "accept: application/json"
示例输出:
{
  "validators": [
    {
      "operator_address": "cosmosvaloper1q3jsx9dpfhtyqqgetwpe5tmk8f0ms5qywje8tw",
      "consensus_pubkey": {
        "@type": "/cosmos.crypto.ed25519.PubKey",
        "key": "N7BPyek2aKuNZ0N/8YsrqSDhGZmgVaYUBuddY8pwKaE="
      },
      "jailed": false,
      "status": "BOND_STATUS_BONDED",
      "tokens": "383301887799",
      "delegator_shares": "383301887799.000000000000000000",
      "description": {
        "moniker": "SmartNodes",
        "identity": "D372724899D1EDC8",
        "website": "https://smartnodes.co",
        "security_contact": "",
        "details": "Earn Rewards with Crypto Staking & Node Deployment"
      },
      "unbonding_height": "0",
      "unbonding_time": "1970-01-01T00:00:00Z",
      "commission": {
        "commission_rates": {
          "rate": "0.050000000000000000",
          "max_rate": "0.200000000000000000",
          "max_change_rate": "0.100000000000000000"
        },
        "update_time": "2021-10-01T15:51:31.596618510Z"
      },
      "min_self_delegation": "1"
    },
    {
      "operator_address": "cosmosvaloper1q5ku90atkhktze83j9xjaks2p7uruag5zp6wt7",
      "consensus_pubkey": {
        "@type": "/cosmos.crypto.ed25519.PubKey",
        "key": "GDNpuKDmCg9GnhnsiU4fCWktuGUemjNfvpCZiqoRIYA="
      },
      "jailed": false,
      "status": "BOND_STATUS_UNBONDING",
      "tokens": "1017819654",
      "delegator_shares": "1017819654.000000000000000000",
      "description": {
        "moniker": "Noderunners",
        "identity": "812E82D12FEA3493",
        "website": "http://noderunners.biz",
        "security_contact": "[email protected]",
        "details": "Noderunners is a professional validator in POS networks. We have a huge node running experience, reliable soft and hardware. Our commissions are always low, our support to delegators is always full. Stake with us and start receiving your cosmos rewards now!"
      },
      "unbonding_height": "147302",
      "unbonding_time": "2021-11-08T22:58:53.718662452Z",
      "commission": {
        "commission_rates": {
          "rate": "0.050000000000000000",
          "max_rate": "0.200000000000000000",
          "max_change_rate": "0.100000000000000000"
        },
        "update_time": "2021-10-04T18:02:21.446645619Z"
      },
      "min_self_delegation": "1"
    }
  ],
  "pagination": {
    "next_key": "FONDBFkE4tEEf7yxWWKOD49jC2NK",
    "total": "2"
  }
}

验证人

Validator REST 端点会查询给定验证人地址的验证人信息。
/cosmos/staking/v1beta1/validators/{validatorAddr}
示例:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/validators/cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q" \
-H  "accept: application/json"
示例输出:
{
  "validator": {
    "operator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
    "consensus_pubkey": {
      "@type": "/cosmos.crypto.ed25519.PubKey",
      "key": "sIiexdJdYWn27+7iUHQJDnkp63gq/rzUq1Y+fxoGjXc="
    },
    "jailed": false,
    "status": "BOND_STATUS_BONDED",
    "tokens": "33027900000",
    "delegator_shares": "33027900000.000000000000000000",
    "description": {
      "moniker": "Witval",
      "identity": "51468B615127273A",
      "website": "",
      "security_contact": "",
      "details": "Witval is the validator arm from Vitwit. Vitwit is into software consulting and services business since 2015. We are working closely with Cosmos ecosystem since 2018. We are also building tools for the ecosystem, Aneka is our explorer for the cosmos ecosystem."
    },
    "unbonding_height": "0",
    "unbonding_time": "1970-01-01T00:00:00Z",
    "commission": {
      "commission_rates": {
        "rate": "0.050000000000000000",
        "max_rate": "0.200000000000000000",
        "max_change_rate": "0.020000000000000000"
      },
      "update_time": "2021-10-01T19:24:52.663191049Z"
    },
    "min_self_delegation": "1"
  }
}

ValidatorDelegations

ValidatorDelegations REST 端点会查询给定验证人的委托信息。
/cosmos/staking/v1beta1/validators/{validatorAddr}/delegations
示例:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/validators/cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q/delegations" -H  "accept: application/json"
示例输出:
{
  "delegation_responses": [
    {
      "delegation": {
        "delegator_address": "cosmos190g5j8aszqhvtg7cprmev8xcxs6csra7xnk3n3",
        "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
        "shares": "31000000000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "31000000000"
      }
    },
    {
      "delegation": {
        "delegator_address": "cosmos1ddle9tczl87gsvmeva3c48nenyng4n56qwq4ee",
        "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
        "shares": "628470000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "628470000"
      }
    },
    {
      "delegation": {
        "delegator_address": "cosmos10fdvkczl76m040smd33lh9xn9j0cf26kk4s2nw",
        "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
        "shares": "838120000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "838120000"
      }
    },
    {
      "delegation": {
        "delegator_address": "cosmos1n8f5fknsv2yt7a8u6nrx30zqy7lu9jfm0t5lq8",
        "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
        "shares": "500000000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "500000000"
      }
    },
    {
      "delegation": {
        "delegator_address": "cosmos16msryt3fqlxtvsy8u5ay7wv2p8mglfg9hrek2e",
        "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
        "shares": "61310000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "61310000"
      }
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "5"
  }
}

委托

Delegation REST 端点会查询给定验证人和委托人地址对的委托信息。
/cosmos/staking/v1beta1/validators/{validatorAddr}/delegations/{delegatorAddr}
示例:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/validators/cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q/delegations/cosmos1n8f5fknsv2yt7a8u6nrx30zqy7lu9jfm0t5lq8" \
-H  "accept: application/json"
示例输出:
{
  "delegation_response": {
    "delegation": {
      "delegator_address": "cosmos1n8f5fknsv2yt7a8u6nrx30zqy7lu9jfm0t5lq8",
      "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
      "shares": "500000000.000000000000000000"
    },
    "balance": {
      "denom": "stake",
      "amount": "500000000"
    }
  }
}

解除绑定委托

UnbondingDelegation REST 端点会查询给定验证人和委托人地址对的解除绑定信息。
/cosmos/staking/v1beta1/validators/{validatorAddr}/delegations/{delegatorAddr}/unbonding_delegation
示例:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/validators/cosmosvaloper13v4spsah85ps4vtrw07vzea37gq5la5gktlkeu/delegations/cosmos1ze2ye5u5k3qdlexvt2e0nn0508p04094ya0qpm/unbonding_delegation" \
-H  "accept: application/json"
示例输出:
{
  "unbond": {
    "delegator_address": "cosmos1ze2ye5u5k3qdlexvt2e0nn0508p04094ya0qpm",
    "validator_address": "cosmosvaloper13v4spsah85ps4vtrw07vzea37gq5la5gktlkeu",
    "entries": [
      {
        "creation_height": "153687",
        "completion_time": "2021-11-09T09:41:18.352401903Z",
        "initial_balance": "525111",
        "balance": "525111"
      }
    ]
  }
}

ValidatorUnbondingDelegations

ValidatorUnbondingDelegations REST 端点用于查询某个验证者的解除委托中的委托。
/cosmos/staking/v1beta1/validators/{validatorAddr}/unbonding_delegations
示例:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/validators/cosmosvaloper13v4spsah85ps4vtrw07vzea37gq5la5gktlkeu/unbonding_delegations" \
-H  "accept: application/json"
示例输出:
{
  "unbonding_responses": [
    {
      "delegator_address": "cosmos1q9snn84jfrd9ge8t46kdcggpe58dua82vnj7uy",
      "validator_address": "cosmosvaloper13v4spsah85ps4vtrw07vzea37gq5la5gktlkeu",
      "entries": [
        {
          "creation_height": "90998",
          "completion_time": "2021-11-05T00:14:37.005841058Z",
          "initial_balance": "24000000",
          "balance": "24000000"
        }
      ]
    },
    {
      "delegator_address": "cosmos1qf36e6wmq9h4twhdvs6pyq9qcaeu7ye0s3dqq2",
      "validator_address": "cosmosvaloper13v4spsah85ps4vtrw07vzea37gq5la5gktlkeu",
      "entries": [
        {
          "creation_height": "47478",
          "completion_time": "2021-11-01T22:47:26.714116854Z",
          "initial_balance": "8000000",
          "balance": "8000000"
        }
      ]
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "2"
  }
}

Abstract

This paper specifies the Staking module of the Cosmos SDK that was first described in the Cosmos Whitepaper in June 2016. The module enables Cosmos SDK-based blockchain to support an advanced Proof-of-Stake (PoS) system. In this system, holders of the native staking token of the chain can become validators and can delegate tokens to validators, ultimately determining the effective validator set for the system. This module is used in the Cosmos Hub, the first Hub in the Cosmos network.

Contents

State

Pool

Pool is used for tracking bonded and not-bonded token supply of the bond denomination.

LastTotalPower

LastTotalPower tracks the total amounts of bonded tokens recorded during the previous end block. Store entries prefixed with “Last” must remain unchanged until EndBlock.
  • LastTotalPower: 0x12 -> ProtocolBuffer(math.Int)

ValidatorUpdates

ValidatorUpdates contains the validator updates returned to ABCI at the end of every block. The values are overwritten in every block.
  • ValidatorUpdates 0x61 -> []abci.ValidatorUpdate

UnbondingID

UnbondingID stores the ID of the latest unbonding operation. It enables creating unique IDs for unbonding operations, i.e., UnbondingID is incremented every time a new unbonding operation (validator unbonding, unbonding delegation, redelegation) is initiated.
  • UnbondingID: 0x37 -> uint64

Params

The staking module stores its params in state with the prefix of 0x51, it can be updated with governance or the address with authority.
  • Params: 0x51 | ProtocolBuffer(Params)
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L310-L333

Validator

Validators can have one of three statuses
  • Unbonded: The validator is not in the active set. They cannot sign blocks and do not earn rewards. They can receive delegations.
  • Bonded: Once the validator receives sufficient bonded tokens they automatically join the active set during EndBlock and their status is updated to Bonded. They are signing blocks and receiving rewards. They can receive further delegations. They can be slashed for misbehavior. Delegators to this validator who unbond their delegation must wait the duration of the UnbondingTime, a chain-specific param, during which time they are still slashable for offences of the source validator if those offences were committed during the period of time that the tokens were bonded.
  • Unbonding: When a validator leaves the active set, either by choice or due to slashing, jailing or tombstoning, an unbonding of all their delegations begins. All delegations must then wait the UnbondingTime before their tokens are moved to their accounts from the BondedPool.
Tombstoning is permanent, once tombstoned a validator’s consensus key can not be reused within the chain where the tombstoning happened.
Validators objects should be primarily stored and accessed by the OperatorAddr, an SDK validator address for the operator of the validator. Two additional indices are maintained per validator object in order to fulfill required lookups for slashing and validator-set updates. A third special index (LastValidatorPower) is also maintained which however remains constant throughout each block, unlike the first two indices which mirror the validator records within a block.
  • Validators: 0x21 | OperatorAddrLen (1 byte) | OperatorAddr -> ProtocolBuffer(validator)
  • ValidatorsByConsAddr: 0x22 | ConsAddrLen (1 byte) | ConsAddr -> OperatorAddr
  • ValidatorsByPower: 0x23 | BigEndian(ConsensusPower) | OperatorAddrLen (1 byte) | OperatorAddr -> OperatorAddr
  • LastValidatorsPower: 0x11 | OperatorAddrLen (1 byte) | OperatorAddr -> ProtocolBuffer(ConsensusPower)
  • ValidatorsByUnbondingID: 0x38 | UnbondingID -> 0x21 | OperatorAddrLen (1 byte) | OperatorAddr
Validators is the primary index - it ensures that each operator can have only one associated validator, where the public key of that validator can change in the future. Delegators can refer to the immutable operator of the validator, without concern for the changing public key. ValidatorsByUnbondingID is an additional index that enables lookups for validators by the unbonding IDs corresponding to their current unbonding. ValidatorByConsAddr is an additional index that enables lookups for slashing. When CometBFT reports evidence, it provides the validator address, so this map is needed to find the operator. Note that the ConsAddr corresponds to the address which can be derived from the validator’s ConsPubKey. ValidatorsByPower is an additional index that provides a sorted list of potential validators to quickly determine the current active set. Here ConsensusPower is validator.Tokens/10^6 by default. Note that all validators where Jailed is true are not stored within this index. LastValidatorsPower is a special index that provides a historical list of the last-block’s bonded validators. This index remains constant during a block but is updated during the validator set update process which takes place in EndBlock. Each validator’s state is stored in a Validator struct:
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L82-L138
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L26-L80

Delegation

Delegations are identified by combining DelegatorAddr (the address of the delegator) with the ValidatorAddr Delegators are indexed in the store as follows:
  • Delegation: 0x31 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValidatorAddrLen (1 byte) | ValidatorAddr -> ProtocolBuffer(delegation)
Stake holders may delegate coins to validators; under this circumstance their funds are held in a Delegation data structure. It is owned by one delegator, and is associated with the shares for one validator. The sender of the transaction is the owner of the bond.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L198-L216

Delegator Shares

When one delegates tokens to a Validator, they are issued a number of delegator shares based on a dynamic exchange rate, calculated as follows from the total number of tokens delegated to the validator and the number of shares issued so far: Shares per Token = validator.TotalShares() / validator.Tokens() Only the number of shares received is stored on the DelegationEntry. When a delegator then Undelegates, the token amount they receive is calculated from the number of shares they currently hold and the inverse exchange rate: Tokens per Share = validator.Tokens() / validatorShares() These Shares are simply an accounting mechanism. They are not a fungible asset. The reason for this mechanism is to simplify the accounting around slashing. Rather than iteratively slashing the tokens of every delegation entry, instead the Validator’s total bonded tokens can be slashed, effectively reducing the value of each issued delegator share.

UnbondingDelegation

Shares in a Delegation can be unbonded, but they must for some time exist as an UnbondingDelegation, where shares can be reduced if Byzantine behavior is detected. UnbondingDelegation are indexed in the store as:
  • UnbondingDelegation: 0x32 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValidatorAddrLen (1 byte) | ValidatorAddr -> ProtocolBuffer(unbondingDelegation)
  • UnbondingDelegationsFromValidator: 0x33 | ValidatorAddrLen (1 byte) | ValidatorAddr | DelegatorAddrLen (1 byte) | DelegatorAddr -> nil
  • UnbondingDelegationByUnbondingId: 0x38 | UnbondingId -> 0x32 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValidatorAddrLen (1 byte) | ValidatorAddr UnbondingDelegation is used in queries, to lookup all unbonding delegations for a given delegator.
UnbondingDelegationsFromValidator is used in slashing, to lookup all unbonding delegations associated with a given validator that need to be slashed. UnbondingDelegationByUnbondingId is an additional index that enables lookups for unbonding delegations by the unbonding IDs of the containing unbonding delegation entries. A UnbondingDelegation object is created every time an unbonding is initiated.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L218-L261

Redelegation

The bonded tokens worth of a Delegation may be instantly redelegated from a source validator to a different validator (destination validator). However when this occurs they must be tracked in a Redelegation object, whereby their shares can be slashed if their tokens have contributed to a Byzantine fault committed by the source validator. Redelegation are indexed in the store as:
  • Redelegations: 0x34 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValidatorAddrLen (1 byte) | ValidatorSrcAddr | ValidatorDstAddr -> ProtocolBuffer(redelegation)
  • RedelegationsBySrc: 0x35 | ValidatorSrcAddrLen (1 byte) | ValidatorSrcAddr | ValidatorDstAddrLen (1 byte) | ValidatorDstAddr | DelegatorAddrLen (1 byte) | DelegatorAddr -> nil
  • RedelegationsByDst: 0x36 | ValidatorDstAddrLen (1 byte) | ValidatorDstAddr | ValidatorSrcAddrLen (1 byte) | ValidatorSrcAddr | DelegatorAddrLen (1 byte) | DelegatorAddr -> nil
  • RedelegationByUnbondingId: 0x38 | UnbondingId -> 0x34 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValidatorAddrLen (1 byte) | ValidatorSrcAddr | ValidatorDstAddr
Redelegations is used for queries, to lookup all redelegations for a given delegator. RedelegationsBySrc is used for slashing based on the ValidatorSrcAddr. RedelegationsByDst is used for slashing based on the ValidatorDstAddr The first map here is used for queries, to lookup all redelegations for a given delegator. The second map is used for slashing based on the ValidatorSrcAddr, while the third map is for slashing based on the ValidatorDstAddr. RedelegationByUnbondingId is an additional index that enables lookups for redelegations by the unbonding IDs of the containing redelegation entries. A redelegation object is created every time a redelegation occurs. To prevent “redelegation hopping” redelegations may not occur under the situation that:
  • the (re)delegator already has another immature redelegation in progress with a destination to a validator (let’s call it Validator X)
  • and, the (re)delegator is attempting to create a new redelegation where the source validator for this new redelegation is Validator X.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L263-L308

Queues

All queue objects are sorted by timestamp. The time used within any queue is firstly converted to UTC, rounded to the nearest nanosecond then sorted. The sortable time format used is a slight modification of the RFC3339Nano and uses the format string "2006-01-02T15:04:05.000000000". Notably this format:
  • right pads all zeros
  • drops the time zone info (we already use UTC)
In all cases, the stored timestamp represents the maturation time of the queue element.

UnbondingDelegationQueue

For the purpose of tracking progress of unbonding delegations the unbonding delegations queue is kept.
  • UnbondingDelegation: 0x41 | format(time) -> []DVPair
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L162-L172

RedelegationQueue

For the purpose of tracking progress of redelegations the redelegation queue is kept.
  • RedelegationQueue: 0x42 | format(time) -> []DVVTriplet
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/staking.proto#L179-L191

ValidatorQueue

For the purpose of tracking progress of unbonding validators the validator queue is kept.
  • ValidatorQueueTime: 0x43 | format(time) -> []sdk.ValAddress
The stored object by each key is an array of validator operator addresses from which the validator object can be accessed. Typically it is expected that only a single validator record will be associated with a given timestamp however it is possible that multiple validators exist in the queue at the same location.

HistoricalInfo

HistoricalInfo objects are stored and pruned at each block such that the staking keeper persists the n most recent historical info defined by staking module parameter: HistoricalEntries.
syntax = "proto3";
package cosmos.staking.v1beta1;

import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";
import "amino/amino.proto";
import "tendermint/types/types.proto";
import "tendermint/abci/types.proto";

option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types";

// HistoricalInfo contains header and validator information for a given block.
// It is stored as part of staking module's state, which persists the `n` most
// recent HistoricalInfo
// (`n` is set by the staking module's `historical_entries` parameter).
message HistoricalInfo {
    tendermint.types.Header header = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  repeated Validator      valset = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// CommissionRates defines the initial commission rates to be used for creating
// a validator.
message CommissionRates {
    option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // rate is the commission rate charged to delegators, as a fraction.
  string rate = 1 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
  // max_rate defines the maximum commission rate which validator can ever charge, as a fraction.
  string max_rate = 2 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
  // max_change_rate defines the maximum daily increase of the validator commission, as a fraction.
  string max_change_rate = 3 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
}

// Commission defines commission parameters for a given validator.
message Commission {
    option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // commission_rates defines the initial commission rates to be used for creating a validator.
  CommissionRates commission_rates = 1
      [(gogoproto.embed) = true, (gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  // update_time is the last time the commission rate was changed.
  google.protobuf.Timestamp update_time = 2
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdtime) = true];
}

// Description defines a validator description.
message Description {
    option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // moniker defines a human-readable name for the validator.
  string moniker = 1;
  // identity defines an optional identity signature (ex. UPort or Keybase).
  string identity = 2;
  // website defines an optional website link.
  string website = 3;
  // security_contact defines an optional email for security contact.
  string security_contact = 4;
  // details define other optional details.
  string details = 5;
}

// Validator defines a validator, together with the total amount of the
// Validator's bond shares and their exchange rate to coins. Slashing results in
// a decrease in the exchange rate, allowing correct calculation of future
// undelegations without iterating over delegators. When coins are delegated to
// this validator, the validator is credited with a delegation whose number of
// bond shares is based on the amount of coins delegated divided by the current
// exchange rate. Voting power can be calculated as total bonded shares
// multiplied by exchange rate.
message Validator {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_stringer) = false;
  option (gogoproto.goproto_getters)  = false;

  // operator_address defines the address of the validator's operator; bech encoded in JSON.
  string operator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // consensus_pubkey is the consensus public key of the validator, as a Protobuf Any.
  google.protobuf.Any consensus_pubkey = 2 [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey"];
  // jailed defined whether the validator has been jailed from bonded status or not.
  bool jailed = 3;
  // status is the validator status (bonded/unbonding/unbonded).
  BondStatus status = 4;
  // tokens define the delegated tokens (incl. self-delegation).
  string tokens = 5 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];
  // delegator_shares defines total shares issued to a validator's delegators.
  string delegator_shares = 6 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
  // description defines the description terms for the validator.
  Description description = 7 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  // unbonding_height defines, if unbonding, the height at which this validator has begun unbonding.
  int64 unbonding_height = 8;
  // unbonding_time defines, if unbonding, the min time for the validator to complete unbonding.
  google.protobuf.Timestamp unbonding_time = 9
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdtime) = true];
  // commission defines the commission parameters.
  Commission commission = 10 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  // min_self_delegation is the validator's self declared minimum self delegation.
  //
  // Since: cosmos-sdk 0.46
  string min_self_delegation = 11 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];

  // strictly positive if this validator's unbonding has been stopped by external modules
  int64 unbonding_on_hold_ref_count = 12;

  // list of unbonding ids, each uniquely identifing an unbonding of this validator
  repeated uint64 unbonding_ids = 13;
}

// BondStatus is the status of a validator.
enum BondStatus {
    option (gogoproto.goproto_enum_prefix) = false;

  // UNSPECIFIED defines an invalid validator status.
  BOND_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "Unspecified"];
  // UNBONDED defines a validator that is not bonded.
  BOND_STATUS_UNBONDED = 1 [(gogoproto.enumvalue_customname) = "Unbonded"];
  // UNBONDING defines a validator that is unbonding.
  BOND_STATUS_UNBONDING = 2 [(gogoproto.enumvalue_customname) = "Unbonding"];
  // BONDED defines a validator that is bonded.
  BOND_STATUS_BONDED = 3 [(gogoproto.enumvalue_customname) = "Bonded"];
}

// ValAddresses defines a repeated set of validator addresses.
message ValAddresses {
    option (gogoproto.goproto_stringer) = false;
  option (gogoproto.stringer)         = true;

  repeated string addresses = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// DVPair is struct that just has a delegator-validator pair with no other data.
// It is intended to be used as a marshalable pointer. For example, a DVPair can
// be used to construct the key to getting an UnbondingDelegation from state.
message DVPair {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// DVPairs defines an array of DVPair objects.
message DVPairs {
    repeated DVPair pairs = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// DVVTriplet is struct that just has a delegator-validator-validator triplet
// with no other data. It is intended to be used as a marshalable pointer. For
// example, a DVVTriplet can be used to construct the key to getting a
// Redelegation from state.
message DVVTriplet {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  string delegator_address     = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  string validator_src_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  string validator_dst_address = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// DVVTriplets defines an array of DVVTriplet objects.
message DVVTriplets {
    repeated DVVTriplet triplets = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// Delegation represents the bond with tokens held by an account. It is
// owned by one delegator, and is associated with the voting power of one
// validator.
message Delegation {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  // delegator_address is the bech32-encoded address of the delegator.
  string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // validator_address is the bech32-encoded address of the validator.
  string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // shares define the delegation shares received.
  string shares = 3 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
}

// UnbondingDelegation stores all of a single delegator's unbonding bonds
// for a single validator in an time-ordered list.
message UnbondingDelegation {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  // delegator_address is the bech32-encoded address of the delegator.
  string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // validator_address is the bech32-encoded address of the validator.
  string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // entries are the unbonding delegation entries.
  repeated UnbondingDelegationEntry entries = 3
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // unbonding delegation entries
}

// UnbondingDelegationEntry defines an unbonding object with relevant metadata.
message UnbondingDelegationEntry {
    option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // creation_height is the height which the unbonding took place.
  int64 creation_height = 1;
  // completion_time is the unix time for unbonding completion.
  google.protobuf.Timestamp completion_time = 2
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdtime) = true];
  // initial_balance defines the tokens initially scheduled to receive at completion.
  string initial_balance = 3 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];
  // balance defines the tokens to receive at completion.
  string balance = 4 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];
  // Incrementing id that uniquely identifies this entry
  uint64 unbonding_id = 5;

  // Strictly positive if this entry's unbonding has been stopped by external modules
  int64 unbonding_on_hold_ref_count = 6;
}

// RedelegationEntry defines a redelegation object with relevant metadata.
message RedelegationEntry {
    option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // creation_height  defines the height which the redelegation took place.
  int64 creation_height = 1;
  // completion_time defines the unix time for redelegation completion.
  google.protobuf.Timestamp completion_time = 2
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdtime) = true];
  // initial_balance defines the initial balance when redelegation started.
  string initial_balance = 3 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];
  // shares_dst is the amount of destination-validator shares created by redelegation.
  string shares_dst = 4 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
  // Incrementing id that uniquely identifies this entry
  uint64 unbonding_id = 5;

  // Strictly positive if this entry's unbonding has been stopped by external modules
  int64 unbonding_on_hold_ref_count = 6;
}

// Redelegation contains the list of a particular delegator's redelegating bonds
// from a particular source validator to a particular destination validator.
message Redelegation {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  // delegator_address is the bech32-encoded address of the delegator.
  string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // validator_src_address is the validator redelegation source operator address.
  string validator_src_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // validator_dst_address is the validator redelegation destination operator address.
  string validator_dst_address = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  // entries are the redelegation entries.
  repeated RedelegationEntry entries = 4
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // redelegation entries
}

// Params defines the parameters for the x/staking module.
message Params {
    option (amino.name)                 = "cosmos-sdk/x/staking/Params";
  option (gogoproto.equal)            = true;
  option (gogoproto.goproto_stringer) = false;

  // unbonding_time is the time duration of unbonding.
  google.protobuf.Duration unbonding_time = 1
      [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdduration) = true];
  // max_validators is the maximum number of validators.
  uint32 max_validators = 2;
  // max_entries is the max entries for either unbonding delegation or redelegation (per pair/trio).
  uint32 max_entries = 3;
  // historical_entries is the number of historical entries to persist.
  uint32 historical_entries = 4;
  // bond_denom defines the bondable coin denomination.
  string bond_denom = 5;
  // min_commission_rate is the chain-wide minimum commission rate that a validator can charge their delegators
  string min_commission_rate = 6 [
    (gogoproto.moretags)   = "yaml:\"min_commission_rate\"",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
}

// DelegationResponse is equivalent to Delegation except that it contains a
// balance in addition to shares which is more suitable for client responses.
message DelegationResponse {
    option (gogoproto.equal)            = false;
  option (gogoproto.goproto_stringer) = false;

  Delegation delegation = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];

  cosmos.base.v1beta1.Coin balance = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// RedelegationEntryResponse is equivalent to a RedelegationEntry except that it
// contains a balance in addition to shares which is more suitable for client
// responses.
message RedelegationEntryResponse {
    option (gogoproto.equal) = true;

  RedelegationEntry redelegation_entry = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  string            balance            = 4 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false
  ];
}

// RedelegationResponse is equivalent to a Redelegation except that its entries
// contain a balance in addition to shares which is more suitable for client
// responses.
message RedelegationResponse {
    option (gogoproto.equal) = false;

  Redelegation                       redelegation = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
  repeated RedelegationEntryResponse entries      = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// Pool is used for tracking bonded and not-bonded token supply of the bond
// denomination.
message Pool {
    option (gogoproto.description) = true;
  option (gogoproto.equal)       = true;
  string not_bonded_tokens       = 1 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false,
    (gogoproto.jsontag)    = "not_bonded_tokens",
    (amino.dont_omitempty) = true
  ];
  string bonded_tokens = 2 [
    (cosmos_proto.scalar)  = "cosmos.Int",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.nullable)   = false,
    (gogoproto.jsontag)    = "bonded_tokens",
    (amino.dont_omitempty) = true
  ];
}

// Infraction indicates the infraction a validator committed.
enum Infraction {
  // UNSPECIFIED defines an empty infraction.
  INFRACTION_UNSPECIFIED = 0;
  // DOUBLE_SIGN defines a validator that double-signs a block.
  INFRACTION_DOUBLE_SIGN = 1;
  // DOWNTIME defines a validator that missed signing too many blocks.
  INFRACTION_DOWNTIME = 2;
}

// ValidatorUpdates defines an array of abci.ValidatorUpdate objects.
// TODO: explore moving this to proto/cosmos/base to separate modules from tendermint dependence
message ValidatorUpdates {
    repeated tendermint.abci.ValidatorUpdate updates = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}
At each BeginBlock, the staking keeper will persist the current Header and the Validators that committed the current block in a HistoricalInfo object. The Validators are sorted on their address to ensure that they are in a deterministic order. The oldest HistoricalEntries will be pruned to ensure that there only exist the parameter-defined number of historical entries.

State Transitions

Validators

State transitions in validators are performed on every EndBlock in order to check for changes in the active ValidatorSet. A validator can be Unbonded, Unbonding or Bonded. Unbonded and Unbonding are collectively called Not Bonded. A validator can move directly between all the states, except for from Bonded to Unbonded.

Not bonded to Bonded

The following transition occurs when a validator’s ranking in the ValidatorPowerIndex surpasses that of the LastValidator.
  • set validator.Status to Bonded
  • send the validator.Tokens from the NotBondedTokens to the BondedPool ModuleAccount
  • delete the existing record from ValidatorByPowerIndex
  • add a new updated record to the ValidatorByPowerIndex
  • update the Validator object for this validator
  • if it exists, delete any ValidatorQueue record for this validator

Bonded to Unbonding

When a validator begins the unbonding process the following operations occur:
  • send the validator.Tokens from the BondedPool to the NotBondedTokens ModuleAccount
  • set validator.Status to Unbonding
  • delete the existing record from ValidatorByPowerIndex
  • add a new updated record to the ValidatorByPowerIndex
  • update the Validator object for this validator
  • insert a new record into the ValidatorQueue for this validator

Unbonding to Unbonded

A validator moves from unbonding to unbonded when the ValidatorQueue object moves from bonded to unbonded
  • update the Validator object for this validator
  • set validator.Status to Unbonded

Jail/Unjail

when a validator is jailed it is effectively removed from the CometBFT set. this process may be also be reversed. the following operations occur:
  • set Validator.Jailed and update object
  • if jailed delete record from ValidatorByPowerIndex
  • if unjailed add record to ValidatorByPowerIndex
Jailed validators are not present in any of the following stores:
  • the power store (from consensus power to address)

Delegations

Delegate

When a delegation occurs both the validator and the delegation objects are affected
  • determine the delegators shares based on tokens delegated and the validator’s exchange rate
  • remove tokens from the sending account
  • add shares the delegation object or add them to a created validator object
  • add new delegator shares and update the Validator object
  • transfer the delegation.Amount from the delegator’s account to the BondedPool or the NotBondedPool ModuleAccount depending if the validator.Status is Bonded or not
  • delete the existing record from ValidatorByPowerIndex
  • add an new updated record to the ValidatorByPowerIndex

Begin Unbonding

As a part of the Undelegate and Complete Unbonding state transitions Unbond Delegation may be called.
  • subtract the unbonded shares from delegator
  • add the unbonded tokens to an UnbondingDelegationEntry
  • update the delegation or remove the delegation if there are no more shares
  • if the delegation is the operator of the validator and no more shares exist then trigger a jail validator
  • update the validator with removed the delegator shares and associated coins
  • if the validator state is Bonded, transfer the Coins worth of the unbonded shares from the BondedPool to the NotBondedPool ModuleAccount
  • remove the validator if it is unbonded and there are no more delegation shares.
  • remove the validator if it is unbonded and there are no more delegation shares
  • get a unique unbondingId and map it to the UnbondingDelegationEntry in UnbondingDelegationByUnbondingId
  • call the AfterUnbondingInitiated(unbondingId) hook
  • add the unbonding delegation to UnbondingDelegationQueue with the completion time set to UnbondingTime

Cancel an UnbondingDelegation Entry

When a cancel unbond delegation occurs both the validator, the delegation and an UnbondingDelegationQueue state will be updated.
  • if cancel unbonding delegation amount equals to the UnbondingDelegation entry balance, then the UnbondingDelegation entry deleted from UnbondingDelegationQueue.
  • if the cancel unbonding delegation amount is less than the UnbondingDelegationentry balance, then theUnbondingDelegationentry will be updated with new balance in theUnbondingDelegationQueue`.
  • cancel amount is Delegated back to the original validator.

Complete Unbonding

For undelegations which do not complete immediately, the following operations occur when the unbonding delegation queue element matures:
  • remove the entry from the UnbondingDelegation object
  • transfer the tokens from the NotBondedPool ModuleAccount to the delegator Account

Begin Redelegation

Redelegations affect the delegation, source and destination validators.
  • perform an unbond delegation from the source validator to retrieve the tokens worth of the unbonded shares
  • using the unbonded tokens, Delegate them to the destination validator
  • if the sourceValidator.Status is Bonded, and the destinationValidator is not, transfer the newly delegated tokens from the BondedPool to the NotBondedPool ModuleAccount
  • otherwise, if the sourceValidator.Status is not Bonded, and the destinationValidator is Bonded, transfer the newly delegated tokens from the NotBondedPool to the BondedPool ModuleAccount
  • record the token amount in an new entry in the relevant Redelegation
From when a redelegation begins until it completes, the delegator is in a state of “pseudo-unbonding”, and can still be slashed for infractions that occurred before the redelegation began.

Complete Redelegation

When a redelegations complete the following occurs:
  • remove the entry from the Redelegation object

Slashing

Slash Validator

When a Validator is slashed, the following occurs:
  • The total slashAmount is calculated as the slashFactor (a chain parameter) * TokensFromConsensusPower, the total number of tokens bonded to the validator at the time of the infraction.
  • Every unbonding delegation and pseudo-unbonding redelegation such that the infraction occurred before the unbonding or redelegation began from the validator are slashed by the slashFactor percentage of the initialBalance.
  • Each amount slashed from redelegations and unbonding delegations is subtracted from the total slash amount.
  • The remaingSlashAmount is then slashed from the validator’s tokens in the BondedPool or NonBondedPool depending on the validator’s status. This reduces the total supply of tokens.
In the case of a slash due to any infraction that requires evidence to submitted (for example double-sign), the slash occurs at the block where the evidence is included, not at the block where the infraction occurred. Put otherwise, validators are not slashed retroactively, only when they are caught.

Slash Unbonding Delegation

When a validator is slashed, so are those unbonding delegations from the validator that began unbonding after the time of the infraction. Every entry in every unbonding delegation from the validator is slashed by slashFactor. The amount slashed is calculated from the InitialBalance of the delegation and is capped to prevent a resulting negative balance. Completed (or mature) unbondings are not slashed.

Slash Redelegation

When a validator is slashed, so are all redelegations from the validator that began after the infraction. Redelegations are slashed by slashFactor. Redelegations that began before the infraction are not slashed. The amount slashed is calculated from the InitialBalance of the delegation and is capped to prevent a resulting negative balance. Mature redelegations (that have completed pseudo-unbonding) are not slashed.

How Shares are calculated

At any given point in time, each validator has a number of tokens, T, and has a number of shares issued, S. Each delegator, i, holds a number of shares, S_i. The number of tokens is the sum of all tokens delegated to the validator, plus the rewards, minus the slashes. The delegator is entitled to a portion of the underlying tokens proportional to their proportion of shares. So delegator i is entitled to T * S_i / S of the validator’s tokens. When a delegator delegates new tokens to the validator, they receive a number of shares proportional to their contribution. So when delegator j delegates T_j tokens, they receive S_j = S * T_j / T shares. The total number of tokens is now T + T_j, and the total number of shares is S + S_j. js proportion of the shares is the same as their proportion of the total tokens contributed: (S + S_j) / S = (T + T_j) / T. A special case is the initial delegation, when T = 0 and S = 0, so T_j / T is undefined. For the initial delegation, delegator j who delegates T_j tokens receive S_j = T_j shares. So a validator that hasn’t received any rewards and has not been slashed will have T = S.

Messages

In this section we describe the processing of the staking messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the state section.

MsgCreateValidator

A validator is created using the MsgCreateValidator message. The validator must be created with an initial delegation from the operator.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L20-L21
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L50-L73
This message is expected to fail if:
  • another validator with this operator address is already registered
  • another validator with this pubkey is already registered
  • the initial self-delegation tokens are of a denom not specified as the bonding denom
  • the commission parameters are faulty, namely:
    • MaxRate is either > 1 or < 0
    • the initial Rate is either negative or > MaxRate
    • the initial MaxChangeRate is either negative or > MaxRate
  • the description fields are too large
This message creates and stores the Validator object at appropriate indexes. Additionally a self-delegation is made with the initial tokens delegation tokens Delegation. The validator always starts as unbonded but may be bonded in the first end-block.

MsgEditValidator

The Description, CommissionRate of a validator can be updated using the MsgEditValidator message.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L23-L24
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L78-L97
This message is expected to fail if:
  • the initial CommissionRate is either negative or > MaxRate
  • the CommissionRate has already been updated within the previous 24 hours
  • the CommissionRate is > MaxChangeRate
  • the description fields are too large
This message stores the updated Validator object.

MsgDelegate

Within this message the delegator provides coins, and in return receives some amount of their validator’s (newly created) delegator-shares that are assigned to Delegation.Shares.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L26-L28
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L102-L114
This message is expected to fail if:
  • the validator does not exist
  • the Amount Coin has a denomination different than one defined by params.BondDenom
  • the exchange rate is invalid, meaning the validator has no tokens (due to slashing) but there are outstanding shares
  • the amount delegated is less than the minimum allowed delegation
If an existing Delegation object for provided addresses does not already exist then it is created as part of this message otherwise the existing Delegation is updated to include the newly received shares. The delegator receives newly minted shares at the current exchange rate. The exchange rate is the number of existing shares in the validator divided by the number of currently delegated tokens. The validator is updated in the ValidatorByPower index, and the delegation is tracked in validator object in the Validators index. It is possible to delegate to a jailed validator, the only difference being it will not be added to the power index until it is unjailed. Delegation sequence

MsgUndelegate

The MsgUndelegate message allows delegators to undelegate their tokens from validator.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L34-L36
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L140-L152
This message returns a response containing the completion time of the undelegation:
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L154-L158
This message is expected to fail if:
  • the delegation doesn’t exist
  • the validator doesn’t exist
  • the delegation has less shares than the ones worth of Amount
  • existing UnbondingDelegation has maximum entries as defined by params.MaxEntries
  • the Amount has a denomination different than one defined by params.BondDenom
When this message is processed the following actions occur:
  • validator’s DelegatorShares and the delegation’s Shares are both reduced by the message SharesAmount
  • calculate the token worth of the shares remove that amount tokens held within the validator
  • with those removed tokens, if the validator is:
    • Bonded - add them to an entry in UnbondingDelegation (create UnbondingDelegation if it doesn’t exist) with a completion time a full unbonding period from the current time. Update pool shares to reduce BondedTokens and increase NotBondedTokens by token worth of the shares.
    • Unbonding - add them to an entry in UnbondingDelegation (create UnbondingDelegation if it doesn’t exist) with the same completion time as the validator (UnbondingMinTime).
    • Unbonded - then send the coins the message DelegatorAddr
  • if there are no more Shares in the delegation, then the delegation object is removed from the store
    • under this situation if the delegation is the validator’s self-delegation then also jail the validator.
Unbond sequence

MsgCancelUnbondingDelegation

The MsgCancelUnbondingDelegation message allows delegators to cancel the unbondingDelegation entry and delegate back to a previous validator.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L38-L42
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L160-L175
This message is expected to fail if:
  • the unbondingDelegation entry is already processed.
  • the cancel unbonding delegation amount is greater than the unbondingDelegation entry balance.
  • the cancel unbonding delegation height doesn’t exist in the unbondingDelegationQueue of the delegator.
When this message is processed the following actions occur:
  • if the unbondingDelegation Entry balance is zero
    • in this condition unbondingDelegation entry will be removed from unbondingDelegationQueue.
    • otherwise unbondingDelegationQueue will be updated with new unbondingDelegation entry balance and initial balance
  • the validator’s DelegatorShares and the delegation’s Shares are both increased by the message Amount.

MsgBeginRedelegate

The redelegation command allows delegators to instantly switch validators. Once the unbonding period has passed, the redelegation is automatically completed in the EndBlocker.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L30-L32
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L119-L132
This message returns a response containing the completion time of the redelegation:
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L133-L138
This message is expected to fail if:
  • the delegation doesn’t exist
  • the source or destination validators don’t exist
  • the delegation has less shares than the ones worth of Amount
  • the source validator has a receiving redelegation which is not matured (aka. the redelegation may be transitive)
  • existing Redelegation has maximum entries as defined by params.MaxEntries
  • the Amount Coin has a denomination different than one defined by params.BondDenom
When this message is processed the following actions occur:
  • the source validator’s DelegatorShares and the delegations Shares are both reduced by the message SharesAmount
  • calculate the token worth of the shares remove that amount tokens held within the source validator.
  • if the source validator is:
    • Bonded - add an entry to the Redelegation (create Redelegation if it doesn’t exist) with a completion time a full unbonding period from the current time. Update pool shares to reduce BondedTokens and increase NotBondedTokens by token worth of the shares (this may be effectively reversed in the next step however).
    • Unbonding - add an entry to the Redelegation (create Redelegation if it doesn’t exist) with the same completion time as the validator (UnbondingMinTime).
    • Unbonded - no action required in this step
  • Delegate the token worth to the destination validator, possibly moving tokens back to the bonded state.
  • if there are no more Shares in the source delegation, then the source delegation object is removed from the store
    • under this situation if the delegation is the validator’s self-delegation then also jail the validator.
Begin redelegation sequence

MsgUpdateParams

The MsgUpdateParams update the staking module parameters. The params are updated through a governance proposal where the signer is the gov module account address.
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/tx.proto#L182-L195
The message handling can fail if:
  • signer is not the authority defined in the staking keeper (usually the gov module account).
  • the bond_denom in the updated params has zero supply in the bank module (i.e., the denom does not exist on-chain).

Begin-Block

Each abci begin block call, the historical info will get stored and pruned according to the HistoricalEntries parameter.

Historical Info Tracking

If the HistoricalEntries parameter is 0, then the BeginBlock performs a no-op. Otherwise, the latest historical info is stored under the key historicalInfoKey|height, while any entries older than height - HistoricalEntries is deleted. In most cases, this results in a single entry being pruned per block. However, if the parameter HistoricalEntries has changed to a lower value there will be multiple entries in the store that must be pruned.

End-Block

Each abci end block call, the operations to update queues and validator set changes are specified to execute.

Validator Set Changes

The staking validator set is updated during this process by state transitions that run at the end of every block. As a part of this process any updated validators are also returned back to CometBFT for inclusion in the CometBFT validator set which is responsible for validating CometBFT messages at the consensus layer. Operations are as following:
  • the new validator set is taken as the top params.MaxValidators number of validators retrieved from the ValidatorsByPower index
  • the previous validator set is compared with the new validator set:
    • missing validators begin unbonding and their Tokens are transferred from the BondedPool to the NotBondedPool ModuleAccount
    • new validators are instantly bonded and their Tokens are transferred from the NotBondedPool to the BondedPool ModuleAccount
In all cases, any validators leaving or entering the bonded validator set or changing balances and staying within the bonded validator set incur an update message reporting their new consensus power which is passed back to CometBFT. The LastTotalPower and LastValidatorsPower hold the state of the total power and validator power from the end of the last block, and are used to check for changes that have occurred in ValidatorsByPower and the total new power, which is calculated during EndBlock.

Queues

Within staking, certain state-transitions are not instantaneous but take place over a duration of time (typically the unbonding period). When these transitions are mature certain operations must take place in order to complete the state operation. This is achieved through the use of queues which are checked/processed at the end of each block.

Unbonding Validators

When a validator is kicked out of the bonded validator set (either through being jailed, or not having sufficient bonded tokens) it begins the unbonding process along with all its delegations begin unbonding (while still being delegated to this validator). At this point the validator is said to be an “unbonding validator”, whereby it will mature to become an “unbonded validator” after the unbonding period has passed. Each block the validator queue is to be checked for mature unbonding validators (namely with a completion time <= current time and completion height <= current block height). At this point any mature validators which do not have any delegations remaining are deleted from state. For all other mature unbonding validators that still have remaining delegations, the validator.Status is switched from types.Unbonding to types.Unbonded. Unbonding operations can be put on hold by external modules via the PutUnbondingOnHold(unbondingId) method. As a result, an unbonding operation (e.g., an unbonding delegation) that is on hold, cannot complete even if it reaches maturity. For an unbonding operation with unbondingId to eventually complete (after it reaches maturity), every call to PutUnbondingOnHold(unbondingId) must be matched by a call to UnbondingCanComplete(unbondingId).

Unbonding Delegations

Complete the unbonding of all mature UnbondingDelegations.Entries within the UnbondingDelegations queue with the following procedure:
  • transfer the balance coins to the delegator’s wallet address
  • remove the mature entry from UnbondingDelegation.Entries
  • remove the UnbondingDelegation object from the store if there are no remaining entries.

Redelegations

Complete the unbonding of all mature Redelegation.Entries within the Redelegations queue with the following procedure:
  • remove the mature entry from Redelegation.Entries
  • remove the Redelegation object from the store if there are no remaining entries.

Hooks

Other modules may register operations to execute when a certain event has occurred within staking. These events can be registered to execute either right Before or After the staking event (as per the hook name). The following hooks can registered with staking:
  • AfterValidatorCreated(Context, ValAddress) error
    • called when a validator is created
  • BeforeValidatorModified(Context, ValAddress) error
    • called when a validator’s state is changed
  • AfterValidatorRemoved(Context, ConsAddress, ValAddress) error
    • called when a validator is deleted
  • AfterValidatorBonded(Context, ConsAddress, ValAddress) error
    • called when a validator is bonded
  • AfterValidatorBeginUnbonding(Context, ConsAddress, ValAddress) error
    • called when a validator begins unbonding
  • BeforeDelegationCreated(Context, AccAddress, ValAddress) error
    • called when a delegation is created
  • BeforeDelegationSharesModified(Context, AccAddress, ValAddress) error
    • called when a delegation’s shares are modified
  • AfterDelegationModified(Context, AccAddress, ValAddress) error
    • called when a delegation is created or modified
  • BeforeDelegationRemoved(Context, AccAddress, ValAddress) error
    • called when a delegation is removed
  • AfterUnbondingInitiated(Context, UnbondingID)
    • called when an unbonding operation (validator unbonding, unbonding delegation, redelegation) was initiated

Events

The staking module emits the following events:

EndBlocker

TypeAttribute KeyAttribute Value
complete_unbondingamount{totalUnbondingAmount}
complete_unbondingvalidator{validatorAddress}
complete_unbondingdelegator{delegatorAddress}
complete_redelegationamount{totalRedelegationAmount}
complete_redelegationsource_validator{srcValidatorAddress}
complete_redelegationdestination_validator{dstValidatorAddress}
complete_redelegationdelegator{delegatorAddress}

Msg’s

MsgCreateValidator

TypeAttribute KeyAttribute Value
create_validatorvalidator{validatorAddress}
create_validatoramount{delegationAmount}
messagemodulestaking
messageactioncreate_validator
messagesender{senderAddress}

MsgEditValidator

TypeAttribute KeyAttribute Value
edit_validatorcommission_rate{commissionRate}
edit_validatormin_self_delegation{minSelfDelegation}
messagemodulestaking
messageactionedit_validator
messagesender{senderAddress}

MsgDelegate

TypeAttribute KeyAttribute Value
delegatevalidator{validatorAddress}
delegateamount{delegationAmount}
messagemodulestaking
messageactiondelegate
messagesender{senderAddress}

MsgUndelegate

TypeAttribute KeyAttribute Value
unbondvalidator{validatorAddress}
unbondamount{unbondAmount}
unbondcompletion_time [0]{completionTime}
messagemodulestaking
messageactionbegin_unbonding
messagesender{senderAddress}
  • [0] Time is formatted in the RFC3339 standard

MsgCancelUnbondingDelegation

TypeAttribute KeyAttribute Value
cancel_unbonding_delegationvalidator{validatorAddress}
cancel_unbonding_delegationdelegator{delegatorAddress}
cancel_unbonding_delegationamount{cancelUnbondingDelegationAmount}
cancel_unbonding_delegationcreation_height{unbondingCreationHeight}
messagemodulestaking
messageactioncancel_unbond
messagesender{senderAddress}

MsgBeginRedelegate

TypeAttribute KeyAttribute Value
redelegatesource_validator{srcValidatorAddress}
redelegatedestination_validator{dstValidatorAddress}
redelegateamount{unbondAmount}
redelegatecompletion_time [0]{completionTime}
messagemodulestaking
messageactionbegin_redelegate
messagesender{senderAddress}
  • [0] Time is formatted in the RFC3339 standard

Parameters

The staking module contains the following parameters:
KeyTypeExample
UnbondingTimestring (time ns)“259200000000000”
MaxValidatorsuint16100
KeyMaxEntriesuint167
HistoricalEntriesuint163
BondDenomstring”stake”
MinCommissionRatestring”0.000000000000000000”

Client

CLI

A user can query and interact with the staking module using the CLI.

Query

The query commands allows users to query staking state.
simd query staking --help
delegation
The delegation command allows users to query delegations for an individual delegator on an individual validator. Usage:
simd query staking delegation [delegator-addr] [validator-addr] [flags]
Example:
simd query staking delegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
Example Output:
balance:
  amount: "10000000000"
  denom: stake
delegation:
  delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
  shares: "10000000000.000000000000000000"
  validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
delegations
The delegations command allows users to query delegations for an individual delegator on all validators. Usage:
simd query staking delegations [delegator-addr] [flags]
Example:
simd query staking delegations cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
Example Output:
delegation_responses:
- balance:
    amount: "10000000000"
    denom: stake
  delegation:
    delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
    shares: "10000000000.000000000000000000"
    validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
- balance:
    amount: "10000000000"
    denom: stake
  delegation:
    delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
    shares: "10000000000.000000000000000000"
    validator_address: cosmosvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqfyqnp
pagination:
  next_key: null
  total: "0"
delegations-to
The delegations-to command allows users to query delegations on an individual validator. Usage:
simd query staking delegations-to [validator-addr] [flags]
Example:
simd query staking delegations-to cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
Example Output:
- balance:
    amount: "504000000"
    denom: stake
  delegation:
    delegator_address: cosmos1q2qwwynhv8kh3lu5fkeex4awau9x8fwt45f5cp
    shares: "504000000.000000000000000000"
    validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
- balance:
    amount: "78125000000"
    denom: uixo
  delegation:
    delegator_address: cosmos1qvppl3479hw4clahe0kwdlfvf8uvjtcd99m2ca
    shares: "78125000000.000000000000000000"
    validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
pagination:
  next_key: null
  total: "0"
historical-info
The historical-info command allows users to query historical information at given height. Usage:
simd query staking historical-info [height] [flags]
Example:
simd query staking historical-info 10
Example Output:
header:
  app_hash: Lbx8cXpI868wz8sgp4qPYVrlaKjevR5WP/IjUxwp3oo=
  chain_id: testnet
  consensus_hash: BICRvH3cKD93v7+R1zxE2ljD34qcvIZ0Bdi389qtoi8=
  data_hash: 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
  evidence_hash: 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
  height: "10"
  last_block_id:
    hash: RFbkpu6pWfSThXxKKl6EZVDnBSm16+U0l0xVjTX08Fk=
    part_set_header:
      hash: vpIvXD4rxD5GM4MXGz0Sad9I7//iVYLzZsEU4BVgWIU=
      total: 1
  last_commit_hash: Ne4uXyx4QtNp4Zx89kf9UK7oG9QVbdB6e7ZwZkhy8K0=
  last_results_hash: 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
  next_validators_hash: nGBgKeWBjoxeKFti00CxHsnULORgKY4LiuQwBuUrhCs=
  proposer_address: mMEP2c2IRPLr99LedSRtBg9eONM=
  time: "2021-10-01T06:00:49.785790894Z"
  validators_hash: nGBgKeWBjoxeKFti00CxHsnULORgKY4LiuQwBuUrhCs=
  version:
    app: "0"
    block: "11"
valset:
- commission:
    commission_rates:
      max_change_rate: "0.010000000000000000"
      max_rate: "0.200000000000000000"
      rate: "0.100000000000000000"
    update_time: "2021-10-01T05:52:50.380144238Z"
  consensus_pubkey:
    '@type': /cosmos.crypto.ed25519.PubKey
    key: Auxs3865HpB/EfssYOzfqNhEJjzys2Fo6jD5B8tPgC8=
  delegator_shares: "10000000.000000000000000000"
  description:
    details: ""
    identity: ""
    moniker: myvalidator
    security_contact: ""
    website: ""
  jailed: false
  min_self_delegation: "1"
  operator_address: cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc
  status: BOND_STATUS_BONDED
  tokens: "10000000"
  unbonding_height: "0"
  unbonding_time: "1970-01-01T00:00:00Z"
params
The params command allows users to query values set as staking parameters. Usage:
simd query staking params [flags]
Example:
simd query staking params
Example Output:
bond_denom: stake
historical_entries: 10000
max_entries: 7
max_validators: 50
unbonding_time: 1814400s
pool
The pool command allows users to query values for amounts stored in the staking pool. Usage:
simd q staking pool [flags]
Example:
simd q staking pool
Example Output:
bonded_tokens: "10000000"
not_bonded_tokens: "0"
redelegation
The redelegation command allows users to query a redelegation record based on delegator and a source and destination validator address. Usage:
simd query staking redelegation [delegator-addr] [src-validator-addr] [dst-validator-addr] [flags]
Example:
simd query staking redelegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
Example Output:
pagination: null
redelegation_responses:
- entries:
  - balance: "50000000"
    redelegation_entry:
      completion_time: "2021-10-24T20:33:21.960084845Z"
      creation_height: 2.382847e+06
      initial_balance: "50000000"
      shares_dst: "50000000.000000000000000000"
  - balance: "5000000000"
    redelegation_entry:
      completion_time: "2021-10-25T21:33:54.446846862Z"
      creation_height: 2.397271e+06
      initial_balance: "5000000000"
      shares_dst: "5000000000.000000000000000000"
  redelegation:
    delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
    entries: null
    validator_dst_address: cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm
    validator_src_address: cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm
redelegations
The redelegations command allows users to query all redelegation records for an individual delegator. Usage:
simd query staking redelegations [delegator-addr] [flags]
Example:
simd query staking redelegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
Example Output:
pagination:
  next_key: null
  total: "0"
redelegation_responses:
- entries:
  - balance: "50000000"
    redelegation_entry:
      completion_time: "2021-10-24T20:33:21.960084845Z"
      creation_height: 2.382847e+06
      initial_balance: "50000000"
      shares_dst: "50000000.000000000000000000"
  - balance: "5000000000"
    redelegation_entry:
      completion_time: "2021-10-25T21:33:54.446846862Z"
      creation_height: 2.397271e+06
      initial_balance: "5000000000"
      shares_dst: "5000000000.000000000000000000"
  redelegation:
    delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
    entries: null
    validator_dst_address: cosmosvaloper1uccl5ugxrm7vqlzwqr04pjd320d2fz0z3hc6vm
    validator_src_address: cosmosvaloper1zppjyal5emta5cquje8ndkpz0rs046m7zqxrpp
- entries:
  - balance: "562770000000"
    redelegation_entry:
      completion_time: "2021-10-25T21:42:07.336911677Z"
      creation_height: 2.39735e+06
      initial_balance: "562770000000"
      shares_dst: "562770000000.000000000000000000"
  redelegation:
    delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
    entries: null
    validator_dst_address: cosmosvaloper1uccl5ugxrm7vqlzwqr04pjd320d2fz0z3hc6vm
    validator_src_address: cosmosvaloper1zppjyal5emta5cquje8ndkpz0rs046m7zqxrpp
redelegations-from
The redelegations-from command allows users to query delegations that are redelegating from a validator. Usage:
simd query staking redelegations-from [validator-addr] [flags]
Example:
simd query staking redelegations-from cosmosvaloper1y4rzzrgl66eyhzt6gse2k7ej3zgwmngeleucjy
Example Output:
pagination:
  next_key: null
  total: "0"
redelegation_responses:
- entries:
  - balance: "50000000"
    redelegation_entry:
      completion_time: "2021-10-24T20:33:21.960084845Z"
      creation_height: 2.382847e+06
      initial_balance: "50000000"
      shares_dst: "50000000.000000000000000000"
  - balance: "5000000000"
    redelegation_entry:
      completion_time: "2021-10-25T21:33:54.446846862Z"
      creation_height: 2.397271e+06
      initial_balance: "5000000000"
      shares_dst: "5000000000.000000000000000000"
  redelegation:
    delegator_address: cosmos1pm6e78p4pgn0da365plzl4t56pxy8hwtqp2mph
    entries: null
    validator_dst_address: cosmosvaloper1uccl5ugxrm7vqlzwqr04pjd320d2fz0z3hc6vm
    validator_src_address: cosmosvaloper1y4rzzrgl66eyhzt6gse2k7ej3zgwmngeleucjy
- entries:
  - balance: "221000000"
    redelegation_entry:
      completion_time: "2021-10-05T21:05:45.669420544Z"
      creation_height: 2.120693e+06
      initial_balance: "221000000"
      shares_dst: "221000000.000000000000000000"
  redelegation:
    delegator_address: cosmos1zqv8qxy2zgn4c58fz8jt8jmhs3d0attcussrf6
    entries: null
    validator_dst_address: cosmosvaloper10mseqwnwtjaqfrwwp2nyrruwmjp6u5jhah4c3y
    validator_src_address: cosmosvaloper1y4rzzrgl66eyhzt6gse2k7ej3zgwmngeleucjy
unbonding-delegation
The unbonding-delegation command allows users to query unbonding delegations for an individual delegator on an individual validator. Usage:
simd query staking unbonding-delegation [delegator-addr] [validator-addr] [flags]
Example:
simd query staking unbonding-delegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
Example Output:
delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
entries:
- balance: "52000000"
  completion_time: "2021-11-02T11:35:55.391594709Z"
  creation_height: "55078"
  initial_balance: "52000000"
validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
unbonding-delegations
The unbonding-delegations command allows users to query all unbonding-delegations records for one delegator. Usage:
simd query staking unbonding-delegations [delegator-addr] [flags]
Example:
simd query staking unbonding-delegations cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
Example Output:
pagination:
  next_key: null
  total: "0"
unbonding_responses:
- delegator_address: cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p
  entries:
  - balance: "52000000"
    completion_time: "2021-11-02T11:35:55.391594709Z"
    creation_height: "55078"
    initial_balance: "52000000"
  validator_address: cosmosvaloper1t8ehvswxjfn3ejzkjtntcyrqwvmvuknzmvtaaa

unbonding-delegations-from
The unbonding-delegations-from command allows users to query delegations that are unbonding from a validator. Usage:
simd query staking unbonding-delegations-from [validator-addr] [flags]
Example:
simd query staking unbonding-delegations-from cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
Example Output:
pagination:
  next_key: null
  total: "0"
unbonding_responses:
- delegator_address: cosmos1qqq9txnw4c77sdvzx0tkedsafl5s3vk7hn53fn
  entries:
  - balance: "150000000"
    completion_time: "2021-11-01T21:41:13.098141574Z"
    creation_height: "46823"
    initial_balance: "150000000"
  validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
- delegator_address: cosmos1peteje73eklqau66mr7h7rmewmt2vt99y24f5z
  entries:
  - balance: "24000000"
    completion_time: "2021-10-31T02:57:18.192280361Z"
    creation_height: "21516"
    initial_balance: "24000000"
  validator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
validator
The validator command allows users to query details about an individual validator. Usage:
simd query staking validator [validator-addr] [flags]
Example:
simd query staking validator cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
Example Output:
commission:
  commission_rates:
    max_change_rate: "0.020000000000000000"
    max_rate: "0.200000000000000000"
    rate: "0.050000000000000000"
  update_time: "2021-10-01T19:24:52.663191049Z"
consensus_pubkey:
  '@type': /cosmos.crypto.ed25519.PubKey
  key: sIiexdJdYWn27+7iUHQJDnkp63gq/rzUq1Y+fxoGjXc=
delegator_shares: "32948270000.000000000000000000"
description:
  details: Witval is the validator arm from Vitwit. Vitwit is into software consulting
    and services business since 2015. We are working closely with Cosmos ecosystem
    since 2018. We are also building tools for the ecosystem, Aneka is our explorer
    for the cosmos ecosystem.
  identity: 51468B615127273A
  moniker: Witval
  security_contact: ""
  website: ""
jailed: false
min_self_delegation: "1"
operator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
status: BOND_STATUS_BONDED
tokens: "32948270000"
unbonding_height: "0"
unbonding_time: "1970-01-01T00:00:00Z"
validators
The validators command allows users to query details about all validators on a network. Usage:
simd query staking validators [flags]
Example:
simd query staking validators
Example Output:
pagination:
  next_key: FPTi7TKAjN63QqZh+BaXn6gBmD5/
  total: "0"
validators:
commission:
  commission_rates:
    max_change_rate: "0.020000000000000000"
    max_rate: "0.200000000000000000"
    rate: "0.050000000000000000"
  update_time: "2021-10-01T19:24:52.663191049Z"
consensus_pubkey:
  '@type': /cosmos.crypto.ed25519.PubKey
  key: sIiexdJdYWn27+7iUHQJDnkp63gq/rzUq1Y+fxoGjXc=
delegator_shares: "32948270000.000000000000000000"
description:
    details: Witval is the validator arm from Vitwit. Vitwit is into software consulting
      and services business since 2015. We are working closely with Cosmos ecosystem
      since 2018. We are also building tools for the ecosystem, Aneka is our explorer
      for the cosmos ecosystem.
    identity: 51468B615127273A
    moniker: Witval
    security_contact: ""
    website: ""
  jailed: false
  min_self_delegation: "1"
  operator_address: cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj
  status: BOND_STATUS_BONDED
  tokens: "32948270000"
  unbonding_height: "0"
  unbonding_time: "1970-01-01T00:00:00Z"
- commission:
    commission_rates:
      max_change_rate: "0.100000000000000000"
      max_rate: "0.200000000000000000"
      rate: "0.050000000000000000"
    update_time: "2021-10-04T18:02:21.446645619Z"
  consensus_pubkey:
    '@type': /cosmos.crypto.ed25519.PubKey
    key: GDNpuKDmCg9GnhnsiU4fCWktuGUemjNfvpCZiqoRIYA=
  delegator_shares: "559343421.000000000000000000"
  description:
    details: Noderunners is a professional validator in POS networks. We have a huge
      node running experience, reliable soft and hardware. Our commissions are always
      low, our support to delegators is always full. Stake with us and start receiving
      your Cosmos rewards now!
    identity: 812E82D12FEA3493
    moniker: Noderunners
    security_contact: [email protected]
    website: http://noderunners.biz
  jailed: false
  min_self_delegation: "1"
  operator_address: cosmosvaloper1q5ku90atkhktze83j9xjaks2p7uruag5zp6wt7
  status: BOND_STATUS_BONDED
  tokens: "559343421"
  unbonding_height: "0"
  unbonding_time: "1970-01-01T00:00:00Z"

Transactions

The tx commands allows users to interact with the staking module.
simd tx staking --help
create-validator
The command create-validator allows users to create new validator initialized with a self-delegation to it. Usage:
simd tx staking create-validator [path/to/validator.json] [flags]
Example:
simd tx staking create-validator /path/to/validator.json \
  --chain-id="name_of_chain_id" \
  --gas="auto" \
  --gas-adjustment="1.2" \
  --gas-prices="0.025stake" \
  --from=mykey
where validator.json contains:
{
  "pubkey": {
    "@type": "/cosmos.crypto.ed25519.PubKey",
    "key": "BnbwFpeONLqvWqJb3qaUbL5aoIcW3fSuAp9nT3z5f20="
  },
  "amount": "1000000stake",
  "moniker": "my-moniker",
  "website": "https://myweb.site",
  "security": "[email protected]",
  "details": "description of your validator",
  "commission-rate": "0.10",
  "commission-max-rate": "0.20",
  "commission-max-change-rate": "0.01",
  "min-self-delegation": "1"
}
and pubkey can be obtained by using simd tendermint show-validator command.
delegate
The command delegate allows users to delegate liquid tokens to a validator. Usage:
simd tx staking delegate [validator-addr] [amount] [flags]
Example:
simd tx staking delegate cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm 1000stake --from mykey
edit-validator
The command edit-validator allows users to edit an existing validator account. Usage:
simd tx staking edit-validator [flags]
Example:
simd tx staking edit-validator --moniker "new_moniker_name" --website "new_webiste_url" --from mykey
redelegate
The command redelegate allows users to redelegate illiquid tokens from one validator to another. Usage:
simd tx staking redelegate [src-validator-addr] [dst-validator-addr] [amount] [flags]
Example:
simd tx staking redelegate cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm 100stake --from mykey
unbond
The command unbond allows users to unbond shares from a validator. Usage:
simd tx staking unbond [validator-addr] [amount] [flags]
Example:
simd tx staking unbond cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 100stake --from mykey
cancel unbond
The command cancel-unbond allow users to cancel the unbonding delegation entry and delegate back to the original validator. Usage:
simd tx staking cancel-unbond [validator-addr] [amount] [creation-height]
Example:
simd tx staking cancel-unbond cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 100stake 123123 --from mykey

gRPC

A user can query the staking module using gRPC endpoints.

Validators

The Validators endpoint queries all validators that match the given status.
cosmos.staking.v1beta1.Query/Validators
Example:
grpcurl -plaintext localhost:9090 cosmos.staking.v1beta1.Query/Validators
Example Output:
{
  "validators": [
    {
      "operatorAddress": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
      "consensusPubkey": {"@type":"/cosmos.crypto.ed25519.PubKey","key":"Auxs3865HpB/EfssYOzfqNhEJjzys2Fo6jD5B8tPgC8="},
      "status": "BOND_STATUS_BONDED",
      "tokens": "10000000",
      "delegatorShares": "10000000000000000000000000",
      "description": {
        "moniker": "myvalidator"
      },
      "unbondingTime": "1970-01-01T00:00:00Z",
      "commission": {
        "commissionRates": {
          "rate": "100000000000000000",
          "maxRate": "200000000000000000",
          "maxChangeRate": "10000000000000000"
        },
        "updateTime": "2021-10-01T05:52:50.380144238Z"
      },
      "minSelfDelegation": "1"
    }
  ],
  "pagination": {
    "total": "1"
  }
}

Validator

The Validator endpoint queries validator information for given validator address.
cosmos.staking.v1beta1.Query/Validator
Example:
grpcurl -plaintext -d '{"validator_addr":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc"}' \
localhost:9090 cosmos.staking.v1beta1.Query/Validator
Example Output:
{
  "validator": {
    "operatorAddress": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
    "consensusPubkey": {"@type":"/cosmos.crypto.ed25519.PubKey","key":"Auxs3865HpB/EfssYOzfqNhEJjzys2Fo6jD5B8tPgC8="},
    "status": "BOND_STATUS_BONDED",
    "tokens": "10000000",
    "delegatorShares": "10000000000000000000000000",
    "description": {
      "moniker": "myvalidator"
    },
    "unbondingTime": "1970-01-01T00:00:00Z",
    "commission": {
      "commissionRates": {
        "rate": "100000000000000000",
        "maxRate": "200000000000000000",
        "maxChangeRate": "10000000000000000"
      },
      "updateTime": "2021-10-01T05:52:50.380144238Z"
    },
    "minSelfDelegation": "1"
  }
}

ValidatorDelegations

The ValidatorDelegations endpoint queries delegate information for given validator.
cosmos.staking.v1beta1.Query/ValidatorDelegations
Example:
grpcurl -plaintext -d '{"validator_addr":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc"}' \
localhost:9090 cosmos.staking.v1beta1.Query/ValidatorDelegations
Example Output:
{
  "delegationResponses": [
    {
      "delegation": {
        "delegatorAddress": "cosmos1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgy3ua5t",
        "validatorAddress": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
        "shares": "10000000000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "10000000"
      }
    }
  ],
  "pagination": {
    "total": "1"
  }
}

ValidatorUnbondingDelegations

The ValidatorUnbondingDelegations endpoint queries delegate information for given validator.
cosmos.staking.v1beta1.Query/ValidatorUnbondingDelegations
Example:
grpcurl -plaintext -d '{"validator_addr":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc"}' \
localhost:9090 cosmos.staking.v1beta1.Query/ValidatorUnbondingDelegations
Example Output:
{
  "unbonding_responses": [
    {
      "delegator_address": "cosmos1z3pzzw84d6xn00pw9dy3yapqypfde7vg6965fy",
      "validator_address": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
      "entries": [
        {
          "creation_height": "25325",
          "completion_time": "2021-10-31T09:24:36.797320636Z",
          "initial_balance": "20000000",
          "balance": "20000000"
        }
      ]
    },
    {
      "delegator_address": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77",
      "validator_address": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
      "entries": [
        {
          "creation_height": "13100",
          "completion_time": "2021-10-30T12:53:02.272266791Z",
          "initial_balance": "1000000",
          "balance": "1000000"
        }
      ]
    },
  ],
  "pagination": {
    "next_key": null,
    "total": "8"
  }
}

Delegation

The Delegation endpoint queries delegate information for given validator delegator pair.
cosmos.staking.v1beta1.Query/Delegation
Example:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77", validator_addr":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc"}' \
localhost:9090 cosmos.staking.v1beta1.Query/Delegation
Example Output:
{
  "delegation_response":
  {
    "delegation":
      {
        "delegator_address":"cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77",
        "validator_address":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
        "shares":"25083119936.000000000000000000"
      },
    "balance":
      {
        "denom":"stake",
        "amount":"25083119936"
      }
  }
}

UnbondingDelegation

The UnbondingDelegation endpoint queries unbonding information for given validator delegator.
cosmos.staking.v1beta1.Query/UnbondingDelegation
Example:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77", validator_addr":"cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc"}' \
localhost:9090 cosmos.staking.v1beta1.Query/UnbondingDelegation
Example Output:
{
  "unbond": {
    "delegator_address": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77",
    "validator_address": "cosmosvaloper1rne8lgs98p0jqe82sgt0qr4rdn4hgvmgp9ggcc",
    "entries": [
      {
        "creation_height": "136984",
        "completion_time": "2021-11-08T05:38:47.505593891Z",
        "initial_balance": "400000000",
        "balance": "400000000"
      },
      {
        "creation_height": "137005",
        "completion_time": "2021-11-08T05:40:53.526196312Z",
        "initial_balance": "385000000",
        "balance": "385000000"
      }
    ]
  }
}

DelegatorDelegations

The DelegatorDelegations endpoint queries all delegations of a given delegator address.
cosmos.staking.v1beta1.Query/DelegatorDelegations
Example:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77"}' \
localhost:9090 cosmos.staking.v1beta1.Query/DelegatorDelegations
Example Output:
{
  "delegation_responses": [
    {"delegation":{"delegator_address":"cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77","validator_address":"cosmosvaloper1eh5mwu044gd5ntkkc2xgfg8247mgc56fww3vc8","shares":"25083339023.000000000000000000"},"balance":{"denom":"stake","amount":"25083339023"}}
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

DelegatorUnbondingDelegations

The DelegatorUnbondingDelegations endpoint queries all unbonding delegations of a given delegator address.
cosmos.staking.v1beta1.Query/DelegatorUnbondingDelegations
Example:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77"}' \
localhost:9090 cosmos.staking.v1beta1.Query/DelegatorUnbondingDelegations
Example Output:
{
  "unbonding_responses": [
    {
      "delegator_address": "cosmos1y8nyfvmqh50p6ldpzljk3yrglppdv3t8phju77",
      "validator_address": "cosmosvaloper1sjllsnramtg3ewxqwwrwjxfgc4n4ef9uxyejze",
      "entries": [
        {
          "creation_height": "136984",
          "completion_time": "2021-11-08T05:38:47.505593891Z",
          "initial_balance": "400000000",
          "balance": "400000000"
        },
        {
          "creation_height": "137005",
          "completion_time": "2021-11-08T05:40:53.526196312Z",
          "initial_balance": "385000000",
          "balance": "385000000"
        }
      ]
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

Redelegations

The Redelegations endpoint queries redelegations of given address.
cosmos.staking.v1beta1.Query/Redelegations
Example:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1ld5p7hn43yuh8ht28gm9pfjgj2fctujp2tgwvf", "src_validator_addr" : "cosmosvaloper1j7euyj85fv2jugejrktj540emh9353ltgppc3g", "dst_validator_addr" : "cosmosvaloper1yy3tnegzmkdcm7czzcy3flw5z0zyr9vkkxrfse"}' \
localhost:9090 cosmos.staking.v1beta1.Query/Redelegations
Example Output:
{
  "redelegation_responses": [
    {
      "redelegation": {
        "delegator_address": "cosmos1ld5p7hn43yuh8ht28gm9pfjgj2fctujp2tgwvf",
        "validator_src_address": "cosmosvaloper1j7euyj85fv2jugejrktj540emh9353ltgppc3g",
        "validator_dst_address": "cosmosvaloper1yy3tnegzmkdcm7czzcy3flw5z0zyr9vkkxrfse",
        "entries": null
      },
      "entries": [
        {
          "redelegation_entry": {
            "creation_height": 135932,
            "completion_time": "2021-11-08T03:52:55.299147901Z",
            "initial_balance": "2900000",
            "shares_dst": "2900000.000000000000000000"
          },
          "balance": "2900000"
        }
      ]
    }
  ],
  "pagination": null
}

DelegatorValidators

The DelegatorValidators endpoint queries all validators information for given delegator.
cosmos.staking.v1beta1.Query/DelegatorValidators
Example:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1ld5p7hn43yuh8ht28gm9pfjgj2fctujp2tgwvf"}' \
localhost:9090 cosmos.staking.v1beta1.Query/DelegatorValidators
Example Output:
{
  "validators": [
    {
      "operator_address": "cosmosvaloper1eh5mwu044gd5ntkkc2xgfg8247mgc56fww3vc8",
      "consensus_pubkey": {
        "@type": "/cosmos.crypto.ed25519.PubKey",
        "key": "UPwHWxH1zHJWGOa/m6JB3f5YjHMvPQPkVbDqqi+U7Uw="
      },
      "jailed": false,
      "status": "BOND_STATUS_BONDED",
      "tokens": "347260647559",
      "delegator_shares": "347260647559.000000000000000000",
      "description": {
        "moniker": "BouBouNode",
        "identity": "",
        "website": "https://boubounode.com",
        "security_contact": "",
        "details": "AI-based Validator. #1 AI Validator on Game of Stakes. Fairly priced. Don't trust (humans), verify. Made with BouBou love."
      },
      "unbonding_height": "0",
      "unbonding_time": "1970-01-01T00:00:00Z",
      "commission": {
        "commission_rates": {
          "rate": "0.061000000000000000",
          "max_rate": "0.300000000000000000",
          "max_change_rate": "0.150000000000000000"
        },
        "update_time": "2021-10-01T15:00:00Z"
      },
      "min_self_delegation": "1"
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

DelegatorValidator

The DelegatorValidator endpoint queries validator information for given delegator validator
cosmos.staking.v1beta1.Query/DelegatorValidator
Example:
grpcurl -plaintext \
-d '{"delegator_addr": "cosmos1eh5mwu044gd5ntkkc2xgfg8247mgc56f3n8rr7", "validator_addr": "cosmosvaloper1eh5mwu044gd5ntkkc2xgfg8247mgc56fww3vc8"}' \
localhost:9090 cosmos.staking.v1beta1.Query/DelegatorValidator
Example Output:
{
  "validator": {
    "operator_address": "cosmosvaloper1eh5mwu044gd5ntkkc2xgfg8247mgc56fww3vc8",
    "consensus_pubkey": {
      "@type": "/cosmos.crypto.ed25519.PubKey",
      "key": "UPwHWxH1zHJWGOa/m6JB3f5YjHMvPQPkVbDqqi+U7Uw="
    },
    "jailed": false,
    "status": "BOND_STATUS_BONDED",
    "tokens": "347262754841",
    "delegator_shares": "347262754841.000000000000000000",
    "description": {
      "moniker": "BouBouNode",
      "identity": "",
      "website": "https://boubounode.com",
      "security_contact": "",
      "details": "AI-based Validator. #1 AI Validator on Game of Stakes. Fairly priced. Don't trust (humans), verify. Made with BouBou love."
    },
    "unbonding_height": "0",
    "unbonding_time": "1970-01-01T00:00:00Z",
    "commission": {
      "commission_rates": {
        "rate": "0.061000000000000000",
        "max_rate": "0.300000000000000000",
        "max_change_rate": "0.150000000000000000"
      },
      "update_time": "2021-10-01T15:00:00Z"
    },
    "min_self_delegation": "1"
  }
}

HistoricalInfo

cosmos.staking.v1beta1.Query/HistoricalInfo
Example:
grpcurl -plaintext -d '{"height" : 1}' localhost:9090 cosmos.staking.v1beta1.Query/HistoricalInfo
Example Output:
{
  "hist": {
    "header": {
      "version": {
        "block": "11",
        "app": "0"
      },
      "chain_id": "simd-1",
      "height": "140142",
      "time": "2021-10-11T10:56:29.720079569Z",
      "last_block_id": {
        "hash": "9gri/4LLJUBFqioQ3NzZIP9/7YHR9QqaM6B2aJNQA7o=",
        "part_set_header": {
          "total": 1,
          "hash": "Hk1+C864uQkl9+I6Zn7IurBZBKUevqlVtU7VqaZl1tc="
        }
      },
      "last_commit_hash": "VxrcS27GtvGruS3I9+AlpT7udxIT1F0OrRklrVFSSKc=",
      "data_hash": "80BjOrqNYUOkTnmgWyz9AQ8n7SoEmPVi4QmAe8RbQBY=",
      "validators_hash": "95W49n2hw8RWpr1GPTAO5MSPi6w6Wjr3JjjS7AjpBho=",
      "next_validators_hash": "95W49n2hw8RWpr1GPTAO5MSPi6w6Wjr3JjjS7AjpBho=",
      "consensus_hash": "BICRvH3cKD93v7+R1zxE2ljD34qcvIZ0Bdi389qtoi8=",
      "app_hash": "ZZaxnSY3E6Ex5Bvkm+RigYCK82g8SSUL53NymPITeOE=",
      "last_results_hash": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
      "evidence_hash": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
      "proposer_address": "aH6dO428B+ItuoqPq70efFHrSMY="
    },
  "valset": [
      {
        "operator_address": "cosmosvaloper196ax4vc0lwpxndu9dyhvca7jhxp70rmcqcnylw",
        "consensus_pubkey": {
          "@type": "/cosmos.crypto.ed25519.PubKey",
          "key": "/O7BtNW0pafwfvomgR4ZnfldwPXiFfJs9mHg3gwfv5Q="
        },
        "jailed": false,
        "status": "BOND_STATUS_BONDED",
        "tokens": "1426045203613",
        "delegator_shares": "1426045203613.000000000000000000",
        "description": {
          "moniker": "SG-1",
          "identity": "48608633F99D1B60",
          "website": "https://sg-1.online",
          "security_contact": "",
          "details": "SG-1 - your favorite validator on Witval. We offer 100% Soft Slash protection."
        },
        "unbonding_height": "0",
        "unbonding_time": "1970-01-01T00:00:00Z",
        "commission": {
          "commission_rates": {
            "rate": "0.037500000000000000",
            "max_rate": "0.200000000000000000",
            "max_change_rate": "0.030000000000000000"
          },
          "update_time": "2021-10-01T15:00:00Z"
        },
        "min_self_delegation": "1"
      }
    ]
  }
}

Pool

The Pool endpoint queries the pool information.
cosmos.staking.v1beta1.Query/Pool
Example:
grpcurl -plaintext -d localhost:9090 cosmos.staking.v1beta1.Query/Pool
Example Output:
{
  "pool": {
    "not_bonded_tokens": "369054400189",
    "bonded_tokens": "15657192425623"
  }
}

Params

The Params endpoint queries the pool information.
cosmos.staking.v1beta1.Query/Params
Example:
grpcurl -plaintext localhost:9090 cosmos.staking.v1beta1.Query/Params
Example Output:
{
  "params": {
    "unbondingTime": "1814400s",
    "maxValidators": 100,
    "maxEntries": 7,
    "historicalEntries": 10000,
    "bondDenom": "stake"
  }
}

REST

A user can query the staking module using REST endpoints.

DelegatorDelegations

The DelegtaorDelegations REST endpoint queries all delegations of a given delegator address.
/cosmos/staking/v1beta1/delegations/{delegatorAddr}
Example:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/delegations/cosmos1vcs68xf2tnqes5tg0khr0vyevm40ff6zdxatp5" -H  "accept: application/json"
Example Output:
{
  "delegation_responses": [
    {
      "delegation": {
        "delegator_address": "cosmos1vcs68xf2tnqes5tg0khr0vyevm40ff6zdxatp5",
        "validator_address": "cosmosvaloper1quqxfrxkycr0uzt4yk0d57tcq3zk7srm7sm6r8",
        "shares": "256250000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "256250000"
      }
    },
    {
      "delegation": {
        "delegator_address": "cosmos1vcs68xf2tnqes5tg0khr0vyevm40ff6zdxatp5",
        "validator_address": "cosmosvaloper194v8uwee2fvs2s8fa5k7j03ktwc87h5ym39jfv",
        "shares": "255150000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "255150000"
      }
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "2"
  }
}

Redelegations

The Redelegations REST endpoint queries redelegations of given address.
/cosmos/staking/v1beta1/delegators/{delegatorAddr}/redelegations
Example:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/delegators/cosmos1thfntksw0d35n2tkr0k8v54fr8wxtxwxl2c56e/redelegations?srcValidatorAddr=cosmosvaloper1lzhlnpahvznwfv4jmay2tgaha5kmz5qx4cuznf&dstValidatorAddr=cosmosvaloper1vq8tw77kp8lvxq9u3c8eeln9zymn68rng8pgt4" \
-H  "accept: application/json"
Example Output:
{
  "redelegation_responses": [
    {
      "redelegation": {
        "delegator_address": "cosmos1thfntksw0d35n2tkr0k8v54fr8wxtxwxl2c56e",
        "validator_src_address": "cosmosvaloper1lzhlnpahvznwfv4jmay2tgaha5kmz5qx4cuznf",
        "validator_dst_address": "cosmosvaloper1vq8tw77kp8lvxq9u3c8eeln9zymn68rng8pgt4",
        "entries": null
      },
      "entries": [
        {
          "redelegation_entry": {
            "creation_height": 151523,
            "completion_time": "2021-11-09T06:03:25.640682116Z",
            "initial_balance": "200000000",
            "shares_dst": "200000000.000000000000000000"
          },
          "balance": "200000000"
        }
      ]
    }
  ],
  "pagination": null
}

DelegatorUnbondingDelegations

The DelegatorUnbondingDelegations REST endpoint queries all unbonding delegations of a given delegator address.
/cosmos/staking/v1beta1/delegators/{delegatorAddr}/unbonding_delegations
Example:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/delegators/cosmos1nxv42u3lv642q0fuzu2qmrku27zgut3n3z7lll/unbonding_delegations" \
-H  "accept: application/json"
Example Output:
{
  "unbonding_responses": [
    {
      "delegator_address": "cosmos1nxv42u3lv642q0fuzu2qmrku27zgut3n3z7lll",
      "validator_address": "cosmosvaloper1e7mvqlz50ch6gw4yjfemsc069wfre4qwmw53kq",
      "entries": [
        {
          "creation_height": "2442278",
          "completion_time": "2021-10-12T10:59:03.797335857Z",
          "initial_balance": "50000000000",
          "balance": "50000000000"
        }
      ]
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

DelegatorValidators

The DelegatorValidators REST endpoint queries all validators information for given delegator address.
/cosmos/staking/v1beta1/delegators/{delegatorAddr}/validators
Example:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/delegators/cosmos1xwazl8ftks4gn00y5x3c47auquc62ssune9ppv/validators" \
-H  "accept: application/json"
Example Output:
{
  "validators": [
    {
      "operator_address": "cosmosvaloper1xwazl8ftks4gn00y5x3c47auquc62ssuvynw64",
      "consensus_pubkey": {
        "@type": "/cosmos.crypto.ed25519.PubKey",
        "key": "5v4n3px3PkfNnKflSgepDnsMQR1hiNXnqOC11Y72/PQ="
      },
      "jailed": false,
      "status": "BOND_STATUS_BONDED",
      "tokens": "21592843799",
      "delegator_shares": "21592843799.000000000000000000",
      "description": {
        "moniker": "jabbey",
        "identity": "",
        "website": "https://twitter.com/JoeAbbey",
        "security_contact": "",
        "details": "just another dad in the cosmos"
      },
      "unbonding_height": "0",
      "unbonding_time": "1970-01-01T00:00:00Z",
      "commission": {
        "commission_rates": {
          "rate": "0.100000000000000000",
          "max_rate": "0.200000000000000000",
          "max_change_rate": "0.100000000000000000"
        },
        "update_time": "2021-10-09T19:03:54.984821705Z"
      },
      "min_self_delegation": "1"
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "1"
  }
}

DelegatorValidator

The DelegatorValidator REST endpoint queries validator information for given delegator validator pair.
/cosmos/staking/v1beta1/delegators/{delegatorAddr}/validators/{validatorAddr}
Example:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/delegators/cosmos1xwazl8ftks4gn00y5x3c47auquc62ssune9ppv/validators/cosmosvaloper1xwazl8ftks4gn00y5x3c47auquc62ssuvynw64" \
-H  "accept: application/json"
Example Output:
{
  "validator": {
    "operator_address": "cosmosvaloper1xwazl8ftks4gn00y5x3c47auquc62ssuvynw64",
    "consensus_pubkey": {
      "@type": "/cosmos.crypto.ed25519.PubKey",
      "key": "5v4n3px3PkfNnKflSgepDnsMQR1hiNXnqOC11Y72/PQ="
    },
    "jailed": false,
    "status": "BOND_STATUS_BONDED",
    "tokens": "21592843799",
    "delegator_shares": "21592843799.000000000000000000",
    "description": {
      "moniker": "jabbey",
      "identity": "",
      "website": "https://twitter.com/JoeAbbey",
      "security_contact": "",
      "details": "just another dad in the cosmos"
    },
    "unbonding_height": "0",
    "unbonding_time": "1970-01-01T00:00:00Z",
    "commission": {
      "commission_rates": {
        "rate": "0.100000000000000000",
        "max_rate": "0.200000000000000000",
        "max_change_rate": "0.100000000000000000"
      },
      "update_time": "2021-10-09T19:03:54.984821705Z"
    },
    "min_self_delegation": "1"
  }
}

HistoricalInfo

The HistoricalInfo REST endpoint queries the historical information for given height.
/cosmos/staking/v1beta1/historical_info/{height}
Example:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/historical_info/153332" -H  "accept: application/json"
Example Output:
{
  "hist": {
    "header": {
      "version": {
        "block": "11",
        "app": "0"
      },
      "chain_id": "cosmos-1",
      "height": "153332",
      "time": "2021-10-12T09:05:35.062230221Z",
      "last_block_id": {
        "hash": "NX8HevR5khb7H6NGKva+jVz7cyf0skF1CrcY9A0s+d8=",
        "part_set_header": {
          "total": 1,
          "hash": "zLQ2FiKM5tooL3BInt+VVfgzjlBXfq0Hc8Iux/xrhdg="
        }
      },
      "last_commit_hash": "P6IJrK8vSqU3dGEyRHnAFocoDGja0bn9euLuy09s350=",
      "data_hash": "eUd+6acHWrNXYju8Js449RJ99lOYOs16KpqQl4SMrEM=",
      "validators_hash": "mB4pravvMsJKgi+g8aYdSeNlt0kPjnRFyvtAQtaxcfw=",
      "next_validators_hash": "mB4pravvMsJKgi+g8aYdSeNlt0kPjnRFyvtAQtaxcfw=",
      "consensus_hash": "BICRvH3cKD93v7+R1zxE2ljD34qcvIZ0Bdi389qtoi8=",
      "app_hash": "fuELArKRK+CptnZ8tu54h6xEleSWenHNmqC84W866fU=",
      "last_results_hash": "p/BPexV4LxAzlVcPRvW+lomgXb6Yze8YLIQUo/4Kdgc=",
      "evidence_hash": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
      "proposer_address": "G0MeY8xQx7ooOsni8KE/3R/Ib3Q="
    },
    "valset": [
      {
        "operator_address": "cosmosvaloper196ax4vc0lwpxndu9dyhvca7jhxp70rmcqcnylw",
        "consensus_pubkey": {
          "@type": "/cosmos.crypto.ed25519.PubKey",
          "key": "/O7BtNW0pafwfvomgR4ZnfldwPXiFfJs9mHg3gwfv5Q="
        },
        "jailed": false,
        "status": "BOND_STATUS_BONDED",
        "tokens": "1416521659632",
        "delegator_shares": "1416521659632.000000000000000000",
        "description": {
          "moniker": "SG-1",
          "identity": "48608633F99D1B60",
          "website": "https://sg-1.online",
          "security_contact": "",
          "details": "SG-1 - your favorite validator on cosmos. We offer 100% Soft Slash protection."
        },
        "unbonding_height": "0",
        "unbonding_time": "1970-01-01T00:00:00Z",
        "commission": {
          "commission_rates": {
            "rate": "0.037500000000000000",
            "max_rate": "0.200000000000000000",
            "max_change_rate": "0.030000000000000000"
          },
          "update_time": "2021-10-01T15:00:00Z"
        },
        "min_self_delegation": "1"
      },
      {
        "operator_address": "cosmosvaloper1t8ehvswxjfn3ejzkjtntcyrqwvmvuknzmvtaaa",
        "consensus_pubkey": {
          "@type": "/cosmos.crypto.ed25519.PubKey",
          "key": "uExZyjNLtr2+FFIhNDAMcQ8+yTrqE7ygYTsI7khkA5Y="
        },
        "jailed": false,
        "status": "BOND_STATUS_BONDED",
        "tokens": "1348298958808",
        "delegator_shares": "1348298958808.000000000000000000",
        "description": {
          "moniker": "Cosmostation",
          "identity": "AE4C403A6E7AA1AC",
          "website": "https://www.cosmostation.io",
          "security_contact": "[email protected]",
          "details": "Cosmostation validator node. Delegate your tokens and Start Earning Staking Rewards"
        },
        "unbonding_height": "0",
        "unbonding_time": "1970-01-01T00:00:00Z",
        "commission": {
          "commission_rates": {
            "rate": "0.050000000000000000",
            "max_rate": "1.000000000000000000",
            "max_change_rate": "0.200000000000000000"
          },
          "update_time": "2021-10-01T15:06:38.821314287Z"
        },
        "min_self_delegation": "1"
      }
    ]
  }
}

Parameters

The Parameters REST endpoint queries the staking parameters.
/cosmos/staking/v1beta1/params
Example:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/params" -H  "accept: application/json"
Example Output:
{
  "params": {
    "unbonding_time": "2419200s",
    "max_validators": 100,
    "max_entries": 7,
    "historical_entries": 10000,
    "bond_denom": "stake"
  }
}

Pool

The Pool REST endpoint queries the pool information.
/cosmos/staking/v1beta1/pool
Example:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/pool" -H  "accept: application/json"
Example Output:
{
  "pool": {
    "not_bonded_tokens": "432805737458",
    "bonded_tokens": "15783637712645"
  }
}

Validators

The Validators REST endpoint queries all validators that match the given status.
/cosmos/staking/v1beta1/validators
Example:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/validators" -H  "accept: application/json"
Example Output:
{
  "validators": [
    {
      "operator_address": "cosmosvaloper1q3jsx9dpfhtyqqgetwpe5tmk8f0ms5qywje8tw",
      "consensus_pubkey": {
        "@type": "/cosmos.crypto.ed25519.PubKey",
        "key": "N7BPyek2aKuNZ0N/8YsrqSDhGZmgVaYUBuddY8pwKaE="
      },
      "jailed": false,
      "status": "BOND_STATUS_BONDED",
      "tokens": "383301887799",
      "delegator_shares": "383301887799.000000000000000000",
      "description": {
        "moniker": "SmartNodes",
        "identity": "D372724899D1EDC8",
        "website": "https://smartnodes.co",
        "security_contact": "",
        "details": "Earn Rewards with Crypto Staking & Node Deployment"
      },
      "unbonding_height": "0",
      "unbonding_time": "1970-01-01T00:00:00Z",
      "commission": {
        "commission_rates": {
          "rate": "0.050000000000000000",
          "max_rate": "0.200000000000000000",
          "max_change_rate": "0.100000000000000000"
        },
        "update_time": "2021-10-01T15:51:31.596618510Z"
      },
      "min_self_delegation": "1"
    },
    {
      "operator_address": "cosmosvaloper1q5ku90atkhktze83j9xjaks2p7uruag5zp6wt7",
      "consensus_pubkey": {
        "@type": "/cosmos.crypto.ed25519.PubKey",
        "key": "GDNpuKDmCg9GnhnsiU4fCWktuGUemjNfvpCZiqoRIYA="
      },
      "jailed": false,
      "status": "BOND_STATUS_UNBONDING",
      "tokens": "1017819654",
      "delegator_shares": "1017819654.000000000000000000",
      "description": {
        "moniker": "Noderunners",
        "identity": "812E82D12FEA3493",
        "website": "http://noderunners.biz",
        "security_contact": "[email protected]",
        "details": "Noderunners is a professional validator in POS networks. We have a huge node running experience, reliable soft and hardware. Our commissions are always low, our support to delegators is always full. Stake with us and start receiving your cosmos rewards now!"
      },
      "unbonding_height": "147302",
      "unbonding_time": "2021-11-08T22:58:53.718662452Z",
      "commission": {
        "commission_rates": {
          "rate": "0.050000000000000000",
          "max_rate": "0.200000000000000000",
          "max_change_rate": "0.100000000000000000"
        },
        "update_time": "2021-10-04T18:02:21.446645619Z"
      },
      "min_self_delegation": "1"
    }
  ],
  "pagination": {
    "next_key": "FONDBFkE4tEEf7yxWWKOD49jC2NK",
    "total": "2"
  }
}

Validator

The Validator REST endpoint queries validator information for given validator address.
/cosmos/staking/v1beta1/validators/{validatorAddr}
Example:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/validators/cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q" \
-H  "accept: application/json"
Example Output:
{
  "validator": {
    "operator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
    "consensus_pubkey": {
      "@type": "/cosmos.crypto.ed25519.PubKey",
      "key": "sIiexdJdYWn27+7iUHQJDnkp63gq/rzUq1Y+fxoGjXc="
    },
    "jailed": false,
    "status": "BOND_STATUS_BONDED",
    "tokens": "33027900000",
    "delegator_shares": "33027900000.000000000000000000",
    "description": {
      "moniker": "Witval",
      "identity": "51468B615127273A",
      "website": "",
      "security_contact": "",
      "details": "Witval is the validator arm from Vitwit. Vitwit is into software consulting and services business since 2015. We are working closely with Cosmos ecosystem since 2018. We are also building tools for the ecosystem, Aneka is our explorer for the cosmos ecosystem."
    },
    "unbonding_height": "0",
    "unbonding_time": "1970-01-01T00:00:00Z",
    "commission": {
      "commission_rates": {
        "rate": "0.050000000000000000",
        "max_rate": "0.200000000000000000",
        "max_change_rate": "0.020000000000000000"
      },
      "update_time": "2021-10-01T19:24:52.663191049Z"
    },
    "min_self_delegation": "1"
  }
}

ValidatorDelegations

The ValidatorDelegations REST endpoint queries delegate information for given validator.
/cosmos/staking/v1beta1/validators/{validatorAddr}/delegations
Example:
curl -X GET "http://localhost:1317/cosmos/staking/v1beta1/validators/cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q/delegations" -H  "accept: application/json"
Example Output:
{
  "delegation_responses": [
    {
      "delegation": {
        "delegator_address": "cosmos190g5j8aszqhvtg7cprmev8xcxs6csra7xnk3n3",
        "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
        "shares": "31000000000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "31000000000"
      }
    },
    {
      "delegation": {
        "delegator_address": "cosmos1ddle9tczl87gsvmeva3c48nenyng4n56qwq4ee",
        "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
        "shares": "628470000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "628470000"
      }
    },
    {
      "delegation": {
        "delegator_address": "cosmos10fdvkczl76m040smd33lh9xn9j0cf26kk4s2nw",
        "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
        "shares": "838120000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "838120000"
      }
    },
    {
      "delegation": {
        "delegator_address": "cosmos1n8f5fknsv2yt7a8u6nrx30zqy7lu9jfm0t5lq8",
        "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
        "shares": "500000000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "500000000"
      }
    },
    {
      "delegation": {
        "delegator_address": "cosmos16msryt3fqlxtvsy8u5ay7wv2p8mglfg9hrek2e",
        "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
        "shares": "61310000.000000000000000000"
      },
      "balance": {
        "denom": "stake",
        "amount": "61310000"
      }
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "5"
  }
}

Delegation

The Delegation REST endpoint queries delegate information for given validator delegator pair.
/cosmos/staking/v1beta1/validators/{validatorAddr}/delegations/{delegatorAddr}
Example:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/validators/cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q/delegations/cosmos1n8f5fknsv2yt7a8u6nrx30zqy7lu9jfm0t5lq8" \
-H  "accept: application/json"
Example Output:
{
  "delegation_response": {
    "delegation": {
      "delegator_address": "cosmos1n8f5fknsv2yt7a8u6nrx30zqy7lu9jfm0t5lq8",
      "validator_address": "cosmosvaloper16msryt3fqlxtvsy8u5ay7wv2p8mglfg9g70e3q",
      "shares": "500000000.000000000000000000"
    },
    "balance": {
      "denom": "stake",
      "amount": "500000000"
    }
  }
}

UnbondingDelegation

The UnbondingDelegation REST endpoint queries unbonding information for given validator delegator pair.
/cosmos/staking/v1beta1/validators/{validatorAddr}/delegations/{delegatorAddr}/unbonding_delegation
Example:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/validators/cosmosvaloper13v4spsah85ps4vtrw07vzea37gq5la5gktlkeu/delegations/cosmos1ze2ye5u5k3qdlexvt2e0nn0508p04094ya0qpm/unbonding_delegation" \
-H  "accept: application/json"
Example Output:
{
  "unbond": {
    "delegator_address": "cosmos1ze2ye5u5k3qdlexvt2e0nn0508p04094ya0qpm",
    "validator_address": "cosmosvaloper13v4spsah85ps4vtrw07vzea37gq5la5gktlkeu",
    "entries": [
      {
        "creation_height": "153687",
        "completion_time": "2021-11-09T09:41:18.352401903Z",
        "initial_balance": "525111",
        "balance": "525111"
      }
    ]
  }
}

ValidatorUnbondingDelegations

The ValidatorUnbondingDelegations REST endpoint queries unbonding delegations of a validator.
/cosmos/staking/v1beta1/validators/{validatorAddr}/unbonding_delegations
Example:
curl -X GET \
"http://localhost:1317/cosmos/staking/v1beta1/validators/cosmosvaloper13v4spsah85ps4vtrw07vzea37gq5la5gktlkeu/unbonding_delegations" \
-H  "accept: application/json"
Example Output:
{
  "unbonding_responses": [
    {
      "delegator_address": "cosmos1q9snn84jfrd9ge8t46kdcggpe58dua82vnj7uy",
      "validator_address": "cosmosvaloper13v4spsah85ps4vtrw07vzea37gq5la5gktlkeu",
      "entries": [
        {
          "creation_height": "90998",
          "completion_time": "2021-11-05T00:14:37.005841058Z",
          "initial_balance": "24000000",
          "balance": "24000000"
        }
      ]
    },
    {
      "delegator_address": "cosmos1qf36e6wmq9h4twhdvs6pyq9qcaeu7ye0s3dqq2",
      "validator_address": "cosmosvaloper13v4spsah85ps4vtrw07vzea37gq5la5gktlkeu",
      "entries": [
        {
          "creation_height": "47478",
          "completion_time": "2021-11-01T22:47:26.714116854Z",
          "initial_balance": "8000000",
          "balance": "8000000"
        }
      ]
    }
  ],
  "pagination": {
    "next_key": null,
    "total": "2"
  }
}