【猫翻】Casper大纲

in #cn6 years ago

原文链接:https://github.com/ethereum/casper/blob/master/VALIDATOR_GUIDE.md
翻译:OKCOIN区块链工程院许乾

本文档概述了实施FFG验证器的组件。这些包括:

  • 验证工作流程概述
  • 验证器状态
  • 验证码
  • 选票格式和生成
  • 注销格式
  • simple_casper 合约概述
  • Casper交易gas返还
  • 简单的验证器投票逻辑

验证工作流程概述

  1. 创建 valcode:
    • 部署用于验证验证者签名的新合同.
  2. 提交保证金:
    • 调用 casper.deposit(validation_addr, withdrawal_addr)
      传入步骤(1)中的智能合约地址和你的提现地址。
  3. [每个Epoch] 提交新选票内容:
    • 等待投票,直到检查点在主链中至少有 EPOCH_LENGTH/4区块深度为止。
      这确保所有验证器在同一个块上投票。
    • 根据你的链的当前头部生成未签名的投票消息。
    • 将未签名的投票交易广播给网络。
  4. 注销:
    • 提交注销消息。
    • 调用 casper.logout(logout_msg) 传入新生成的logout_msg.
  5. 提现:
    • 调用 casper.withdraw(validator_index) 你的资金将被发送到在步骤(2)中指定的验证人提现地址。

验证器状态

验证器的状态很复杂。他们必须处理valcode创建,提交保证金,投票和注销。每个阶段还需要等待交易确认。由于这种复杂性,使用了状态到处理程序的映射。

在pyethapp中实现 的验证器状态映射如下所示::

uninitiated: self.check_status,
waiting_for_valcode: self.check_valcode,
waiting_for_login: self.check_status,
voting: self.vote,
waiting_for_log_out: self.vote_then_logout,
waiting_for_withdrawable: self.check_withdrawable,
waiting_for_withdrawn: self.check_withdrawn,
logged_out: self.check_status

验证器状态转换图

ffg-validator
箭头是在给定状态下接收新块时遵循的逻辑。例如,如果验证程序处于状态voting并接收到一个高度为in_first_quarter_of_epoch的新块,则验证程序将按照箭头保持该状态voting

验证码

验证人必须部署他们自己的签名验证合约。这将用于检查附在他们投票上的签名。此验证代码必须是纯函数。这意味着不允许存储读取/写入,环境变量读取或外部调用(除了已经通过纯度验证或预编译的其他合同)。

对于基本签名验证,ecdsa签名目前正在使用。这些ecdsa签名的验证码可以在这里找到。请注意,此LLL代码使用椭圆曲线公钥恢复预编译。

验证代码合约当前正在作为此处找到的induct_validator()函数的一部分进行部署:

def induct_validator(chain, casper, key, value):
    sender = utils.privtoaddr(key)
    valcode_addr = chain.tx(key, "", 0, mk_validation_code(sender))  # Create a new validation code contract based on the validator's Ethereum address
    assert utils.big_endian_to_int(chain.tx(key, purity_checker_address, 0, purity_translator.encode('submit', [valcode_addr]))) == 1
    casper.deposit(valcode_addr, sender, value=value)  # Submit deposit specifying the validation code contract address

Casper选票格式

Casper选票是一个RLP编码列表,包含以下元素::

[
  validator_index: number,  # Index of the validator sending this vote
  target_hash: bytes32,  # Hash of the target checkpoint block for this vote
  target_epoch: number,  # Epoch number of the target checkpoint
  source_epoch: number,  # Epoch number of the source checkpoint
  signature  # A signed hash of the first four elements in this list, RLP encoded. (ie. RLP([validator_index, target_hash, target_epoch, source_epoch])
]

Casper选票信息仅包含在发送给Casper合约casper.vote(vote_msg)函数的普通交易中。

生成Casper选票

为了获得投票消息内容,使用Casper合约调用:

  • casper.validator_indexes(WITHDRAWAL_ADDRESS) for the validator_index
  • casper.recommended_target_hash() for the target_hash
  • casper.current_epoch() for the target_epoch
  • casper.recommended_source_epoch() for the source_epoch

接下来,RLP编码所有这些元素。要计算您的签名,对投票的RLP编码列表的进行sha3计算,并签名hash。您的签名必须与您的验证器的“validation_code”合同进行核对时有效。最后,将签名附加到投票信息内容的末尾。

Pyethereum中的实现 如下:

def mk_vote(validator_index, target_hash, target_epoch, source_epoch, key):
    msg_hash = utils.sha3(rlp.encode([validator_index, target_hash, target_epoch, source_epoch]))
    v, r, s = utils.ecdsa_raw_sign(msg_hash, key)
    sig = utils.encode_int32(v) + utils.encode_int32(r) + utils.encode_int32(s)
    return rlp.encode([validator_index, target_hash, target_epoch, source_epoch, sig])

生成Logout Message

像Casper选票消息一样,Logout Message是RLP编码列表,其中最后一个元素是验证者的签名。包括未签名的validator_indexepoch其中epoch是当前epoch。签名的生成方式与上述投票方式相同。

在Pyethereum中实现如下:

def mk_logout(validator_index, epoch, key):
    msg_hash = utils.sha3(rlp.encode([validator_index, epoch]))
    v, r, s = utils.ecdsa_raw_sign(msg_hash, key)
    sig = utils.encode_int32(v) + utils.encode_int32(r) + utils.encode_int32(s)
    return rlp.encode([validator_index, epoch, sig])

simple_casper 合约概述

Simple Casper Contract包含casper的核心逻辑,它是用 Vyper 编写的,可以像任何其他合约一样部署到区块链中CASPER_ADDR
然后通过vote(vote_msg)将Casper消息发送到合约,其中vote_msg的结构参见Casper选票格式

[Contract Source]

####构造函数

def init(epoch_length: int128, warm_up_period: int128,
         withdrawal_delay: int128, dynasty_logout_delay: int128,
         msg_hasher: address, purity_checker: address,
         base_interest_factor: decimal, base_penalty_factor: decimal,
         min_deposit_size: wei_value)

下面的参数部署后不能更改

  • epoch_length
  • withdrawal_delay
  • dynasty_logout_delay
  • min_deposit_size
  • base_interest_factor
  • base_penalty_factor

####初始化epoch

def initialize_epoch(epoch: int128) 

根据finality的时间计算此epoch的利率和惩罚因子。
一旦新epoch开始,这个函数立即被称为应用于该状态的第一个交易。

####保证金

def deposit(validation_addr: address, withdrawal_addr: address)

接受预期验证人的存款并将其添加到下一个验证人set中。

####注销

def logout(logout_msg: bytes <= 1024)

启动验证程序注销。在进入withdrawal_delay等待期之前,验证人必须继续验证dynasty_logout_delay朝代。

####提现

def withdraw(validator_index: int128)

如果验证人等待的时间超过他们的withdrawal_delayepoch的end_dynastyepoch,则将他们的ETH发送给他们的存款。

####投票

def vote(vote_msg)

每个验证者每个epoch调用一次。投票信息包含Casper投票格式中显示的字段。

####惩罚

def slash(vote_msg_1, vote_msg_2)

任何检测到违规情况的人都可以调用。作为发现者的费用,向调用者发送削减验证者资金的4%,并烧掉剩下的96%。

Casper交易gas返还

如果成功Casper选票不花费gas,并且将被视为无效交易,如果失败则不被包括在该区块中。这避免了验证器上的大量gas负担。

简单的验证器投票逻辑

验证人登录后,他们可以使用以下逻辑来确定何时发送投票:

  1. 当接收到一个新块并替换我们链的当前head时,请调用validate(block)
  2. 内部 validate(block) 检查:
    1. 该区块至少有EPOCH_LENGTH/4 blocks deep以确保检查点hash可以安全地投票。
    2. [NO_DBL_VOTE] 该区块的epoch没有被投票.
    3. [NO_SURROUND] 该区块的 target_epoch >= self.latest_target_epoch 并且 source_epoch >= self.latest_source_epoch.
      NOTE: 这项检查非常简单,但它排除了可以安全投票的情况。
  3. 如果所有检查都通过,则生成并发送新的选票!

NOTE: 要检查验证程序是否已注册,可以使用:

return casper.validators__start_dynasty(validator_index) >= casper.dynasty()

有关更多信息,请参阅当前的验证器实现。

Sort:  

Congratulations @lanzhizhuxia! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

Click here to view your Board

Support SteemitBoard's project! Vote for its witness and get one more award!

Congratulations @lanzhizhuxia! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Vote for @Steemitboard as a witness to get one more award and increased upvotes!