Starcoin-Framework 合约投票升级流程
- 1 简述
- 2 升级步骤
- 2.1 注意事项
- 2.2 一、准备升级包 (注意mpm release)
- 2.3 二、提交升级投票提案
- 2.4 三、执行两阶段升级
- 3 参考链接
简述
该文档描述了 Starcoin-Framework 两阶段升级流程,这里实际上分为了两步
第一步,产生了一个升级的投票提案,会将两阶段升级的动作作为投票的结果来执行。
第二步,从投票成功的提案中提取两阶段升级的plan,执行完该plan之后,就完成了整个升级流程。
升级步骤
注意事项
参考https://github.com/starcoinorg/starcoin-framework/blob/main/release/README.md 参考你此次升级是否需要有init_script function一般就是类似 StdlibUpgradeScripts::do_upgrade_from_v11_to_v12 这种函数
一、准备升级包 (注意mpm release)
从https://github.com/starcoinorg/starcoin-framework 找到对应的tag,签出该tag并执行以下命令编译打包
# 编译
$ ./scripts/build.sh
# 打包
$ mpm package build
# 在 release/ 目录下能找到对应的编译好的二进制包,并可以在控制台中找到对应的package hash
# 根据实际需要看看是否调用--function
mpm release --function 0x1::StdlibUpgradeScripts::upgrade_from_v11_to_v12
二、提交升级投票提案
调用ModuleUpgradeScripts::propose_module_upgrade_v2 方法来提交,将上面的打包出来的对应的hash作为参数传入。
starcoin% account execute-function --function 0x00000000000000000000000000000001::ModuleUpgradeScripts::propose_module_upgrade_v2 -s 0x8a47a41e0465d9a53b19bf858d990865 -t 0x00000000000000000000000000000001::STC::STC --arg 0x00000000000000000000000000000001 --arg x"e4cb45429ef1fb27c7271b446ce9b1222263c3c09315583de27d275ec098459e" --arg 12u64 --arg 0 --arg false -b # 命令返回 { "ok": { "dry_run_output": { "events": [ { "data": "0x01000000000000008a47a41e0465d9a53b19bf858d990865", "event_key": "0x120000000000000000000000000000000000000000000001", "event_seq_number": "1", "type_tag": "0x00000000000000000000000000000001::Dao::ProposalCreatedEvent" } ], "explained_status": "Executed", "gas_used": "173293", "status": "Executed", ... } ... }
检查提案投票状态,这里的状态为2(可投票)(状态定义参考Starcoin去中心化治理机制, 也可以参考Dao.move中的定义)
# 这里proposal_id为全局自增,是因为该账号之前投过一次票了,所以为1 starcoin% dev call --function 0x1::Dao::proposal_state -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 --arg 0x8a47a41e0465d9a53b19bf858d990865 --arg 2 # 命令返回 { "ok": [ 2 ] } # 若不确定这里是哪个proposal id,可以执行以下命令查看当前 proposal id 命令 starcoin% state get resource 0x8a47a41e0465d9a53b19bf858d990865 0x1::Dao::Proposal<0x1::STC::STC,0x1::UpgradeModuleDaoProposal::UpgradeModuleV2> { "ok": { "json": { "action": { "vec": [ { "enforced": false, "module_address": "0x00000000000000000000000000000001", "package_hash": "0xe4cb45429ef1fb27c7271b446ce9b1222263c3c09315583de27d275ec098459e", "version": 12 } ] }, "action_delay": 60000, "against_votes": 0, "end_time": 1682076798301, "eta": 0, "for_votes": 15925669899949605, "id": 2, // 当前proposal id "proposer": "0x8a47a41e0465d9a53b19bf858d990865", "quorum_votes": 3187142521908000, "start_time": 1682076198301 }, "raw": "0x02000000000000008a47a41e0465d9a53b19bf858d9908659de58da3870100005d0d97a387010000255632f94f943800000000000000000000000000000000000000000000000000000000000000000060ea00000000000020ebdd71b0520b000000000000000000010000000000000000000000000000000120e4cb45429ef1fb27c7271b446ce9b1222263c3c09315583de27d275ec098459e0c0000000000000000" } }
这里在console中使用基金会账号投票,一定能保证结果超过4%,
在console中如果没有基金会权限,参考Halley & Proxima & Barnard 基金会账号 ,使用如下命令得到基金会账号权限, 基金会STC有159256698999279320,取10分之一能保证一定成功
# 取到基金账户权限 starcoin% account import-multisig --addr 0xA550C18 -t 5 --prikey 0xd54a0330658e327c0baeeb84a50f6a0d563b84ab5f9cf60473ebf9adad851016 --prikey 0x371959788d3b3e93e7c08e101d91d7ed0f82558f432c6b02b3fdd1bb2cb55692 --prikey 0x0af1341a2917a9dd8ea8c0fe6a324a7bbed3ff6769fb5d35f80a3d3672b24efb --prikey 0x04c07cee94fecf8bb11f7ad1944af3f285d947763863ed0153e1b69ebed890a9 --prikey 0x5e953da3101c5225906b434947762e1f15090f3e4bfe57b298f4bd75f82c55b6 --pubkey 0x67cc9cb01386e9f5e321b078d4d3a2925b520f955cf7dfd9f6891de366c186ce --pubkey 0xc7a0004e0ca3e6b8e548c80d76eeb88e84a82f6b863a1346eabadfe4d5d9be86 --pubkey 0x068b8493d8c533fd08568429274e49639518a8517f6ab03a0f0cc37edcbdfdd0 --pubkey 0xc461fe9aca18df90ed31ee967fe49ed47756311eaa2a6042b7aff1422e48643d # 检查基金账户权限 starcoin% account show 0xA550C18 { "ok": { ..., "balances": { "0x00000000000000000000000000000001::STC::STC": 159256698999279320 }, "sequence_number": 5 } }
这里可以结合本地账号信息,使用如下脚本#!/bin/bash function usage() { echo -e "usage: astarcoin net" echo -e "net is main, barnard, proxima, halley" echo -e "to_dir like ~/.starcoin/main, ~/.starcoin/barnard, ~/.starcoin/proxima" } function connect_node() { net=$1 account_dir=$2 ws_url="ws://$net.seed.starcoin.org:9870" echo -e "starcoin --connect $ws_url --local-account-dir $account_dir console" starcoin --connect "$ws_url" --local-account-dir "$account_dir" console } if [ $# != 2 ]; then usage exit 1 fi net=$1 to_dir=$2 account_dir="$to_dir/account_vaults" case $net in "main" | "barnard" | "proxima" |"halley") connect_node "$net" "$account_dir" ;; *) echo "$net not supported" usage ;; esac
进行投票,并且查看投票信息
# 进行投票 starcoin% account execute-function -s 0x0000000000000000000000000a550c18 --function 0x1::DaoVoteScripts::cast_vote -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 --arg 0x8a47a41e0465d9a53b19bf858d990865 --arg 2 --arg true --arg 15925669899949605u128 -b # 查看基金账户投出的票 starcoin% state get resource 0x0000000000000000000000000a550c18 0x1::Dao::Vote<0x1::STC::STC> { "ok": { "json": { "agree": true, "id": 2, "proposer": "0x8a47a41e0465d9a53b19bf858d990865", "stake": { "value": 15925669899949605 } }, "raw": "0x8a47a41e0465d9a53b19bf858d9908650200000000000000255632f94f943800000000000000000001" } } # 查看投票信息 starcoin% dev call --function 0x1::Dao::proposal_info -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 --arg 0x8a47a41e0465d9a53b19bf858d990865 { "ok": [ 2, 1682076198301, 1682076798301, 15925669899949605, 0 ] }
返回分别是Proposal_id,投票开始时间,投票结束时间,赞成票数,反对票数 (这里时间使用的毫秒)
实际结束时间是
1682076198301 / 1000
=1682076798
, 使用 date -r1682076798
看到结束时间是Fri Apr 21 19:33:18 CST 2023
等到这个时间过后, 查看投票状态
starcoin% dev call --function 0x1::Dao::proposal_state -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 --arg 0x8a47a41e0465d9a53b19bf858d990865 --arg 2 { # 4是AGREE代表成功, 3是DEFEATED代表失败 "ok": [ 4 ] }
投票成功后将其加入执行队列(main使用poll.starcoin.org网页,这步会自动执行)
starcoin% account execute-function --function 0x1::Dao::queue_proposal_action -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 --arg 0x8a47a41e0465d9a53b19bf858d990865 --arg 2 # 使用查看投票状态命令直到变成6 EXECUTABLE可以执行下一步 starcoin% dev call --function 0x1::Dao::proposal_state -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 --arg 0x8a47a41e0465d9a53b19bf858d990865 --arg 2 { "ok": [ 6 ] }
执行提案,该函数会将投票通过的UpgradePlan动作提交给升级模块
starcoin% account execute-function -s 0x8a47a41e0465d9a53b19bf858d990865 --function 0x1::ModuleUpgradeScripts::execute_module_upgrade_plan_propose -t 0x1::STC::STC --arg 0x8a47a41e0465d9a53b19bf858d990865 --arg 2 # 执行完之后查看状态,发现状态为已执行(7) starcoin% dev call --function 0x1::Dao::proposal_state -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 --arg 0x8a47a41e0465d9a53b19bf858d990865 --arg 2 { "ok": [ 7 ] }
取回质押的Token并且完成清理提案
# 取回质押的Token starcoin% account execute-function -s 0x0000000000000000000000000a550c18 --function 0x1::DaoVoteScripts::unstake_vote -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 --arg 0x8a47a41e0465d9a53b19bf858d990865 --arg 2 -b # 完成并清理提案 starcoin% account execute-function --function 0x1::Dao::destroy_terminated_proposal -t 0x1::STC::STC -t 0x1::UpgradeModuleDaoProposal::UpgradeModuleV2 --arg 0x8a47a41e0465d9a53b19bf858d990865 --arg 2u64
三、执行两阶段升级
背景介绍
在介绍两阶段升级之前,先介绍一下升级策略,一共有以下几种:
const STRATEGY_ARBITRARY: u8 = 0; // 随便可以升
const STRATEGY_TWO_PHASE: u8 = 1; // 两阶段升级
const STRATEGY_NEW_MODULE: u8 = 2; // 只接受新模块
const STRATEGY_FREEZE: u8 = 3; // 冻结升级
两阶段升级,也就是当升级策略为 1 的时候,才可以进行两阶段升级。每个账户都会有一个模块的升级策略(0x1也不例外),可以执行以下命令进行查看:
starcoin% state get resource 0x1 0x1::PackageTxnManager::ModuleUpgradeStrategy
{
"ok": {
"json": {
"strategy": 1
},
"raw": "0x01"
}
}
这里的两阶段,将升级分为plan提交公示阶段和实际执行升级的阶段,故称为两阶段。
公示阶段,需要提交一个升级时的包对应的hash,以便第二阶段在真正升级的时候做检查,这里有个公示的时间,第二阶段必须要在这个时间之后才可以执行
提交阶段,需要提交跟hash对应的二进制包
上面说的投票升级,实际上是由于普通账户对0x1没有权限,所以需要通过Dao投票治理来决定的。如果用户对模块有权限,则可以直接通过调用 UpgradeModuleDaoProposal::submit_upgrade_plan 来提交升级提案。
通过阅读代码可以看到在UpgradeModuleDaoProposal::submit_upgrade_plan 中需要UpgradePlanCapability ,这个能力在调用update_module_upgrade_strategy
这个函数来赋予的。
升级流程
首先需要检查用户是否拥有 UpgradePlan,如果发现 plan 字段为空,则需要重新去跑一遍投票流程或者重新调用提交plan函数
starcoin% state get resource 0x1 0x1::PackageTxnManager::TwoPhaseUpgradeV2 { "ok": { "json": { "config": { "min_time_limit": 0 }, "plan": { "vec": { "active_after_time": 1682077868844, "enforced": false, "package_hash": "0xe4cb45429ef1fb27c7271b446ce9b1222263c3c09315583de27d275ec098459e", "version": 12 } }, "upgrade_event": { "counter": 0, "guid": "0x0b0000000000000000000000000000000000000000000001" }, "version_cap": { "account_address": "0x00000000000000000000000000000001", "events": { "counter": 0, "guid": "0x0a0000000000000000000000000000000000000000000001" } } }, "raw": "0x000000000000000000000000000000000000000000000000010000000000000000180a00000000000000000000000000000000000000000000010000000000000000180b0000000000000000000000000000000000000000000001" } }
如果有 Plan,则直接调用dev deploy部署之前打包出来的二进制模块,注意这个包需要跟前一步提交plan时传入的hash值对应,注意这里提交的时间应该在 UpgradePlan { active_after_time: “123456“ } 这个时间戳之后。
starcoin % dev deploy release/StarcoinFramework.v12.0.0.blob -s 0x8a47a41e0465d9a53b19bf858d990865 -b #确定输出结果为executed即可
至此升级模块完成。Enjoy it!