这里以halley的版本号从v4升级到v6为例
背景介绍
starcoin中starcoin-framework中有两个比较重要的版本号,一个是LanguageVersion这里就是Move字节码的版本号,新的字节码版本号一般会添加新的字节码 参考这里https://github.com/starcoinorg/move/blob/dev_v6/language/move-binary-format/src/file_format_common.rs#L404-#L407
一个是StdlibVersion这里代表使用的不同版本的starcoin-framework标准库,提供了不同的内容
这里有两个相关的release版本https://github.com/starcoinorg/starcoin/releases/tag/halley-v1.13.1-alpha 和https://github.com/starcoinorg/starcoin/releases/tag/v1.13.0-alpha
halley每次会使用最新版本的StdlibVersion, 参考
pub static G_HALLEY_CONFIG: Lazy<GenesisConfig> = Lazy::new(|| { let stdlib_version = StdlibVersion::Latest;
由于要模拟从v4到v6升级所以这里使用starcoin-framework的v11,也就是
starcoin-framework = { git = "https://github.com/starcoinorg/starcoin-framework", rev = "cf1deda180af40a8b3e26c0c7b548c4c290cd7e7" }
而v1.13.0-alpha使用的是
starcoin-framework = { git = "https://github.com/starcoinorg/starcoin-framework", rev = "a7eff4fa3e08cecfed09edf3dbf9d216832d7414" }
后者与前者之间的区别就是https://github.com/starcoinorg/starcoin-framework/commit/a7eff4fa3e08cecfed09edf3dbf9d216832d7414
StdlibUpgradeScripts::do_upgrade_from_v6_to_v7_with_language_version(&genesis_account, 6);
相关操作
1.查看当前move字节码版本
starcoin% state get resource 0x1 0x1::Config::Config<0x1::LanguageVersion::LanguageVersion> { "ok": { "json": { "payload": { "major": 4 } }, } }
2.发起升级提案
在console下使用如下命令
account execute-function --function 0x00000000000000000000000000000001::OnChainConfigScripts::propose_update_move_language_version -s 0xed9ea1f3533c14e1b52d9ff6475776ba --arg 6u64 --arg 0u64 -b
这里0xed9ea1f3533c14e1b52d9ff6475776ba
是提案的发起者,这里实际上调用了starcoin-framework的OnchainConfigScripts.move里面的函数
public(script) fun propose_update_move_language_version(account: signer, new_version: u64, exec_delay: u64) {
这里指升级版本为6
返回类似这样
{ "block_hash": "0xaea1ab93dfa8fd0572a4a4e966fdf3b562fdc5b4106a6ce0d45addc3bf2e9762", "block_number": "140", "data": "0x0000000000000000ed9ea1f3533c14e1b52d9ff6475776ba", "decode_event_data": { "proposal_id": 0, "proposer": "0xed9ea1f3533c14e1b52d9ff6475776ba" }, "event_index": 0, "event_key": "0x120000000000000000000000000000000000000000000001", "event_seq_number": "0", "transaction_global_index": "144", "transaction_hash": "0x0dcf75f76275a8191fa686ba9fc2b11df27f6d647ccf7085c8db89cba3347fe9", "transaction_index": 1, "type_tag": "0x00000000000000000000000000000001::Dao::ProposalCreatedEvent" }
这里返回proposal_id为0,代表这是第1个提案(提案号从0开始)。实际上可以看到proposal_id生成是来自starcoin-framework的Dao.move的DaoGlobalInfo
/// global DAO info of the specified token type `Token`. struct DaoGlobalInfo<phantom Token: store> has key { /// next proposal id. next_proposal_id: u64, /// proposal creating event. proposal_create_event: Event::EventHandle<ProposalCreatedEvent>, /// voting event. vote_changed_event: Event::EventHandle<VoteChangedEvent>, }
3.查看投票状态
使用如下命令
dev call --function 0x1::Dao::proposal_state -t 0x1::STC::STC -t 0x1::OnChainConfigDao::OnChainConfigUpdate<0x1::LanguageVersion::LanguageVersion> --arg 0xed9ea1f3533c14e1b52d9ff6475776ba --arg 0
这里返回是这样
{ "ok": [ 2 ] }
返回2是ACTIVE定义在Dao.move的
/// Proposal state const PENDING: u8 = 1; const ACTIVE: u8 = 2; const DEFEATED: u8 = 3; const AGREED: u8 = 4; const QUEUED: u8 = 5; const EXECUTABLE: u8 = 6; const EXTRACTED: u8 = 7;
这里代表投票已经开启
这里实际上调用了Dao.move下面的函数
public fun proposal_state<TokenT: copy + drop + store, ActionT: copy + drop + store>( proposer_address: address, proposal_id: u64, )
上面提到的各种Proposal state的状态变化需要使用查看投票状态命令手动触发
这里在starcoin的config/genesis_config.rs里面可以看到 DaoConfig的几个参数
pub static G_HALLEY_CONFIG: Lazy<GenesisConfig> = Lazy::new(|| { let stdlib_version = StdlibVersion::Latest; dao_config: DaoConfig { voting_delay: 60_000, // 1min voting_period: 60 * 60 * 1000, // 1h voting_quorum_rate: 4, min_action_delay: 60 * 60 * 1000, // 1h }, } });
voting_delay 提案开始后多长时间可以投票,voting_period 投票窗口期多长,
min_action_delay投票通过后多长时间后可以执行交易, voting_quorum_rate 投票赞成超过多少百分比代表成功
,后面回提到这些和状态转换有些关系
4.投票
这里在console中使用基金会账号投票,一定能保证结果超过%4,
在console中如果没有基金会权限,参考/wiki/spaces/WESTAR/pages/1933320 ,使用如下命令得到基金会账号权限
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 } }
基金会STC有159256698999279320
,取10分之一能保证一定成功
投票使用如下命令
account execute-function -b -s 0x0000000000000000000000000a550c18 --function 0x1::DaoVoteScripts::cast_vote -t 0x1::STC::STC -t 0x1::OnChainConfigDao::OnChainConfigUpdate<0x1::LanguageVersion::LanguageVersion> --arg 0xed9ea1f3533c14e1b52d9ff6475776ba --arg 0 --arg true --arg 15925669899949605u128
这里调用了DaoVoteScripts.move的如下函数
public ( script ) fun cast_vote<Token: copy + drop + store, ActionT: copy + drop + store>( signer: signer, proposer_address: address, proposal_id: u64, agree: bool, votes: u128, )
5. 查看投票结果
使用命令
dev call --function 0x1::Dao::proposal_info -t 0x1::STC::STC -t 0x1::OnChainConfigDao::OnChainConfigUpdate<0x1::LanguageVersion::LanguageVersion> --arg 0xed9ea1f3533c14e1b52d9ff6475776ba
这里调用了Dao.move的
public fun proposal_info<TokenT: copy + drop + store, ActionT: copy + drop + store>( proposer_address: address, ): (u64, u64, u64, u128, u128) acquires Proposal
返回结果如下
{ "ok": [ 0, 1676304887775, 1676308487775, 15925669899949605, 0 ] }
返回分别是Proposal_id,投票开始时间,投票结束时间,赞成票数,反对票数 (这里时间使用的毫秒)
实际结束时间是1676308487775
/ 1000 = 1676308487
, 使用date -r 1676308487
看到结束时间是
Tue Feb 14 01:14:47 CST 2023
等到这个时间过后, 查看投票状态
dev call --function 0x1::Dao::proposal_state -t 0x1::STC::STC -t 0x1::OnChainConfigDao::OnChainConfigUpdate<0x1::LanguageVersion::LanguageVersion> --arg 0xed9ea1f3533c14e1b52d9ff6475776ba --arg 0
返回如下
{ "ok": [ 4 ] }
4是AGREE代表成功, 3是DEFEATED
代表失败
6.投票成功后将提案加入执行队列
命令如下
account execute-function --function 0x1::Dao::queue_proposal_action -t 0x1::STC::STC -t 0x1::OnChainConfigDao::OnChainConfigUpdate<0x1::LanguageVersion::LanguageVersion> --arg 0xed9ea1f3533c14e1b52d9ff6475776ba --arg 0
这里调用的是Dao.move的
/// queue agreed proposal to execute. public(script) fun queue_proposal_action<TokenT: copy + drop + store, ActionT: copy + drop + store>( proposer_address: address, proposal_id: u64, )
使用查看投票状态命令可以看到状态变成5 QUEUE,
这里状态变化都是之前提到Dao.move的proposal_state驱动,具体如下
fun do_proposal_state<TokenT: copy + drop + store, ActionT: copy + drop + store>( proposal: &Proposal<TokenT, ActionT>, current_time: u64, ): u8 { if (current_time < proposal.start_time) { // Pending PENDING } else if (current_time <= proposal.end_time) { // Active ACTIVE } else if (proposal.for_votes <= proposal.against_votes || proposal.for_votes < proposal.quorum_votes) { // Defeated DEFEATED } else if (proposal.eta == 0) { // Agreed. AGREED } else if (current_time < proposal.eta) { // Queued, waiting to execute QUEUED } else if (Option::is_some(&proposal.action)) { EXECUTABLE } else { EXTRACTED } }
使用查看投票状态命令直到变成6 EXECUTABLE可以执行下一步
7.执行提案
使用命令
account execute-function -s 0xed9ea1f3533c14e1b52d9ff6475776ba --function 0x1::OnChainConfigScripts::execute_on_chain_config_proposal -t 0x1::LanguageVersion::LanguageVersion --arg 0
这里调用的是OnChainConfigScripts.move的
public ( script ) fun execute_on_chain_config_proposal<ConfigT: copy + drop + store>(account: signer, proposal_id: u64) {
8.取回质押的Token
使用下面命令
account execute-function -s 0x0000000000000000000000000a550c18 --function 0x1::DaoVoteScripts::unstake_vote -t 0x1::STC::STC -t 0x1::OnChainConfigDao::OnChainConfigUpdate<0x1::LanguageVersion::LanguageVersion> --arg 0xed9ea1f3533c14e1b52d9ff6475776ba --arg 0
9.清理完成提案
account execute-function --function 0x1::Dao::destroy_terminated_proposal -t 0x1::STC::STC -t 0x1::OnChainConfigDao::OnChainConfigUpdate<0x1::LanguageVersion::LanguageVersion> --arg 0xed9ea1f3533c14e1b52d9ff6475776ba --arg 0u64
10.查看move版本字节码
starcoin% state get resource 0x1 0x1::Config::Config<0x1::LanguageVersion::LanguageVersion> { "ok": { "json": { "payload": { "major": 6 } }, "raw": "0x0600000000000000" } }
参考文档
https://starcoin.org/zh/developer/cli/modify_onchain_config/