-
合约地址: https://etherscan.io/address/0x6b3595068778dd592e39a122f4f5a5cf09c90fe2
-
交易hash https://etherscan.io/tx/0x5489c98aa634078471646e32a3a846c8d413f055ce10d06bd2260f4e71d1bc63
- checkpoints(address 用户地址, uint32 索引) 返回检查点构造体
- numCheckpoints(address 用户地址) 每个帐户的
检查点数
映射,地址=>数额 - DOMAIN_TYPEHASH() EIP-712的合约域hash
- DELEGATION_TYPEHASH() EIP-712的代理人构造体的hash
- nonces(address 用户地址) 返回用于签名/验证签名的状态记录(nonce值)
- delegates(address 被委托的地址) 查询被委托的地址的委托人
- 一个检查点,用于标记给定块中的投票数
struct Checkpoint {
uint32 fromBlock; // 开始区块号
uint256 votes; // 票数
}
- 账户地址 => 检查点的数量
检查点数
映射,用于记录检查点
映射中用户有多少个检查点检查点数
映射中的数量从1开始
,检查点
映射中用户的检查点索引值从0开始
mapping (address => uint32) public numCheckpoints
- 账户地址 => 检查点索引 => 检查点构造体
检查点
映射,用于保存用户的每一个检查点构造体
检查点
映射中用户的检查点索引值从0开始
mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;
下文中注意区别
检查点
映射和检查点数
映射,还有检查点构造体
- 只能由所有者(主厨合约)调用
参数
address _to //接收地址
uint256 _amount //数额
- 调用ERC20的铸造方法
- 调用移动委托方法,将铸造出来的数量添加到委托人的票数中
参数
address delegatee //委托人地址
- 调用私有的转移委托人方法,参数为调用者账户和委托人地址
- 这个方法和delegate方法的区别是:delegate将修改调用者的委托人,delegateBySig方法可以让一个用户通过签名的方法让另一个账户修改自己的委托人
参数
address delegatee //委托人地址
uint nonce //nonce值,匹配签名所需的合同状态
uint expiry //签名到期的时间
uint8 v //签名的恢复字节
bytes32 r //ECDSA签名对的一半
bytes32 s //ECDSA签名对的一半
- 将域hash + 名字hash + chainId + 当前合约地址打包哈希得到域分割
- 将构造体的hash + 委托人地址 + nonce值 + 过期时间打包哈希得到构造体hash
- 将域分割 + 构造体hash打包哈希得到签名前数据
- 通过v,r,s和签名前数据使用ecrecover方法恢复签名地址
- 验证签名地址和nonce值,过期时间都正确
- 调用并返回更换委托人方法
- 这个方法返回
检查点
映射中用户最后一个检查点的票数
参数
address account //账户地址
- 通过
检查点数
映射查询账户地址的检查点 - 如果检查点数量大于0
- 返回选票
检查点
映射中账户地址最后一个检查点的票数
- 返回选票
- 否则返回0
- 账户在指定区块的票数保存在
检查点
映射中 - 判断如果
检查点数量
为0,返回0 - 如果
检查点
映射中最后一个检查点构造体
中的区块号比给入区块号小,则返回检查点
映射中最后一个检查点构造体
中的票数 - 如果
检查点
映射中第一个检查点构造体
中的区块号比给入区块号大,则返回0 - 其他情况:
检查点
映射中最后一个检查点构造体
中的区块号大于给入区块号,并且检查点数量
不为0 - 则找到
检查点
映射中from区块为给入区块号的检查点构造体
- 如果没有则返回
检查点
映射中给定区块之前最后一个有记录的检查点构造体
中的票数
参数
address account //账户地址
uint blockNumber //区块号
- 确认区块号小于当前区块号
- 通过
检查点数
映射查询账户地址的检查点数量
- 如果
检查点数量
== 0 返回 0(终止运行) - 如果
检查点
映射中账户地址最后一个记录中from块号小于等于区块号- 返回
检查点
映射中账户地址最后一格记录中的票数(终止运行)
- 返回
- 如果
检查点
映射中账户地址第一个记录中from块号大于给入区块号,则返回0(终止运行) - 通过二分查找找到
检查点
映射中from区块为给入区块号的检查点构造体
中的票数(终止运行) - 如果没有则返回给入区块号之前最临近区块的
检查点构造体
的检查点索引
- 返回
检查点
映射中用户索引值
为检查点索引
的检查点构造体
中的票数
- 内部方法,由内部调用
- 这个方法除了修改委托人映射以外,还要将被委托人的余额对应的票数转移给新委托人
参数
address delegator //被委托人
address delegator //新委托人
- 获取被委托人的当前委托人
- 获取被委托人当前的sushi余额
- 修改委托人映射,将被委托人的委托人替换成新委托人
- 触发委托人更改事件
- 调用转移投票数方法,将被委托人的余额数量的票数转移到新委托人
- 这个方法是将源地址的
检查点
映射中的票数减去转移的票数,目标地址的检查点
映射中的票数加上转移的票数
参数
address srcRep //源地址
address dstRep //目标地址
uint256 amount //转移的票数
- 首先确认源地址和目标地址不能一致,并且转移的数额不能为0
- 如果源地址不为零的情况,即说明不是铸造方法
- 查询源地址的
检查点数
- 判断源地址的
检查点数
如果大于0- 源地址的旧票数等于
检查点
映射中最后一个检查点
的票数 - 否则源地址的旧票等于0
- 源地址的旧票数等于
- 源地址新的票数等于源地址旧票数减去这次转移的票数
- 写入
检查点
- 查询源地址的
- 如果目标地址不为零的情况,即说明不是销毁方法
- 查询目标地址的
检查点数
- 判断目标地址的
检查点数
如果大于0- 目标地址的旧票数等于
检查点
映射中最后一个检查点
的票数 - 否则目标地址的旧票等于0
- 目标地址的旧票数等于
- 目标地址新的票数等于目标地址旧票数加上这次转移的票数
- 写入
检查点
- 查询目标地址的
参数
address delegatee //委托人地址
uint32 nCheckpoints //检查点
uint256 oldVotes //旧票数
uint256 newVotes //新票数
- 将区块号限制在32位2进制之内(防止溢出)
- 如果
检查点数
大于零,并且检查点
映射委托人最后一个
检查点中的检查点构造体
中的from块号等于当前区块号- 修改
检查点
映射中委托人最后一个
检查点中的检查点构造体
中的票数为新票数
- 修改
- 否则
- 定义
检查点
映射中委托人给入的
检查点中的检查点构造体
为新建检查点构造体
,参数为当前区块号和新票数 - 委托人
检查点数
映射中将检查点数量
加1
- 定义