What you might not know about VeChainThor yet (Part VI) - On-Chain Governance

  • What you might not know about VeChainThor yet (Part VI) - On-Chain Governance

    This is the 6'th article of the "What you might not know about VeChainThor yet" series. You can find the links of the previous articles at the end.

    VeChainThor's on-chain governance is about stakeholders or its governing body making decisions on some critical on-chain actions and executing those actions. (The governing body of the main-net is the steering committee of VeChain Foundation.) The actions can, for instance, be authorizing or revoking consensus validators (i.e., the Authority Masternodes), changing network parameters, such as the base gas price and block reward ratio, or any on-chain activity embodied by a smart contract deployed on VeChainThor.

    Fig. 1. Process of on-chain governance.

    As illustrated in Fig.1, on-chain governance consists of three phases: decision making, authorization and execution.

    • Decision making is the first phase where decisions on executing certain on-chain actions are made. Decisions are obtained through voting. Voting can be conducted either on chain via a voting contract or off chain within the governing body. The former provides maximal transparency and often involves all stakeholder, while the latter complements the former to offer efficiency and agility.

    • Authorization is the second phase where a voted on-chain action is proposed to the governing body for final approval. Each proposal has to be approved by a majority of the members of the governing body. It is an extra security measure put in place to safeguard on-chain governance against malicious activities (e.g., exploitation of voting-contract vulnerabilities).

    • Execution is the final phase of on-chain governance. Once a proposal has been approved by the required majority, anyone can trigger the execution of the on-chain action defined in the proposal.


    Fig. 2 Framework for on-chain governance.

    VeChainThor provides a flexible framework for implementing the described on-chain governance, as illustrated in Fig. 2. At the center of the framework is contract Executor that is deployed at address

    // Convert "Executor" to bytes and left pad zeros

    on the main-net and test-net. However, the address can be set arbitrarily for a customized version of VeChainThor.

    Phase - Authorization

    Contract Executor provides functions propose and approve to carry out the authorization phase. Only authorized voting contracts or members of the governing body can invoke function

    propose(target_contract_address, encoded_data)

    (marked by "1" in Fig. 2) to log a proposal in Executor. The two function arguments define an on-chain action, i.e., invoking a specific function at a specific target contract address. Argument encoded_data can be computed by

    // solidity
    abi.encodeWithSignature(func_signature, arg1, arg2, ...);

    A proposal is an instance of struct proposal stored in Executor and is created by function propose. A unique propsalID is generated to index the proposal after a successful call of the function. Once a proposal is logged in Executor, members of the governing body are given one-week time to authorize it. Each member can invoke function approve (marked by "2" in Fig. 2) to complete his/her authorization.

    Phase - Execution

    The execution phase is implemented simply by function execute of contract Executor. Once a proposal has been approved by the required majority (two thirds by default) of members of the governing body, ANYONE can invoke function execute to trigger the execution of the on-chain action defined in the proposal using low-level call function:

    // solidty

    Note that it is a safety practice that we code the target function of the target contract such that it can only be invoked by Executor. In this way, we are guaranteed that the action can only be executed after going through the process of on-chain governance. An example is function add of the built-in contract Authority. The function is used to authorize a new consensus validator. The following line inside the function body

    // solidity
    require(msg.sender == executor(), "builtin: executor required");

    ensures that only Executor can invoke the function.

    Management of Voting Contracts

    I have mentioned that a voting contract must be authorized before it can invoke function propose to submit proposals. Contract Executor provides functions attachVotingContract and detachVotingContract to manage the list of authorized voting contracts.

    Note that both functions have been coded such that they can only be invoked by Executor itself, indicating that any change to the list has to be done through on-chain governance. It makes sure that the management of voting contracts are conducted securely and transparently.


    I have made two demos to demonstrate the use of tools provided by VeChainThor to conduct on-chain governance. Source code can be found at DemoCode1 and DemoCode2.

    The demos need to be run on a customized VeChainThor so that we can have access to accounts of the members of the governing body. The configuration of the blockchain network can be found in file customChainConfig.json. The following lines are added to customChainConfig.json for the second demo to allow the customized VeChainThor to be compatible with the latest version of EVM released in Ethereum Constantinople.

    "ForkConfig": {
        "ETH_CONST": 0

    Basically, it tells the system from what height it has to switch to the latest version of EVM.

    YOU MUST REPLACE all the authorityAddress with the master addresses of the Thor nodes launched locally to make the demo work. The master address can be obtained by:

    thor master-key --config-dir <KEY_DIR>

    Commands to launch nodes can be found in file nodeLaunchCmd. Please refer to my previous article 'What you might not know about VeChainThor yet (Part V) - Customizing Your Own VeChainThor' for details.

    Tools Used in Demos

    Terminology in Code

    • approver / approvers - member(s) of the governing body;
    • authority - built-in contract Authority that manages the list of validators;
    • executor - built-in contact Executor;
    • dummyVotingContract - registered voting contract;
    • voters - accounts conducting operations of the dummy on-chain voting.

    Demo1 - Authorization of a New Validator

    This demo simulates the on-chain governance that authorizes a new validator (i.e., a new authority masternode). Regarding the three phases of on-chain governance, it assumes that decision making is carried out off-chain by members of the governing body. The on-chain action is defined as to call function add of the built-in contract Authority deployed at

    // Convert "Authority" to bytes and left pad zeros

    Operations carried out in the demo:

    1. To propose the authorization of a new validator;
    2. To approve the proposal (by members of the governing body);
    3. To execute the proposed on-chain action.


    0. Check existence of new validator
    	address: 0x2a49980921dd25babbee592a685a54cb75acea35
    	listed: false
    	endorsor: 0x0000000000000000000000000000000000000000
    	identity: 0x0000000000000000000000000000000000000000000000000000000000000000
    	active: false
    I. Propose proposoal of adding validator 0x2a49980921dd25babbee592a685a54cb75acea35
    	Tx Sender: 0xcb43d5d874893a67d94cdb0c28e2a93285f56ff0
    	txid: 0xf90d9695ef8fc8cdaaa22ff962ed90ad7c6944099d245b12cf24df0ada82fed0
    	proposalID: 0x1596231d71a49eb11cd1ac38332ab83cb5ba22bae26810f89b9f7241aa76f379
    II. Approve proposal
    	Approver: 0xcb43d5d874893a67d94cdb0c28e2a93285f56ff0
    	txid: 0x3979bb4a0d9bf595092363609d366518b57842a9b4e4ad3b062ade6a380043a7
    	Approver: 0x7d350a72ea46d0927139e57dfe2174d7acaa9d30
    	txid: 0x43f84dfc5b160e5059ecf4bb2934949fdd3c9b88b9f9631ab7222786e31b67be
    	Approver: 0x62fa853cefc28aca2c225e66da96a692171d86e7
    	txid: 0x1e2e389caa674a3ade32232574466538cd33710781d8bf75a1b744ecaec641e5
    III. Execute proposal
    	TX Sender: 0x7d350a72ea46d0927139e57dfe2174d7acaa9d30
    	txid: 0x1f8a44ba88a135c8ab3de2c2acfe3678cc2e671751f2d99a29e8c80d98d56a70
    IV. Check new validator status
    	address: 0x2a49980921dd25babbee592a685a54cb75acea35
    	listed: true
    	endorsor: 0x5e4abda5cced44f70c9d2e1be4fda08c4291945b
    	identity: 0x000000000000000000000000000000000000004e65772056616c696461746f72
    	active: true

    Demo2 - Modification of Reward Ratio

    This demo simulates the on-chain governance that change the network parameter reward ratio. Regarding the three phases of on-chain governance, I made and deployed a dummy voting contract DummnyVotingContract to demonstrate the procedures where decision making is made on-chain via a voting contract. The on-chain action is defined as to call function set of the built-in contract Params deployed at

    // Convert "Params" to bytes and left pad zeros

    Operations carried out in the demo (functions that implement the operations are listed in brackets):

    1. To register the voting contract to the built-in contract Executor:

      1. To deploy the voting contract (deployVotingContract)
      2. To propose a proposal of attaching the voting contract (proposeAttachingVotingContract);
      3. To approve the proposal (approveProposal);
      4. To execute the proposal (executeProposal);
    2. To make a decision through on-chain voting:

      1. To initialize a vote (initVote);
      2. To tally the vote (tallyVote);
      3. To submit a proposal for changing reward ratio to Executor (executeVote);
    3. To authorize the voted action (approveProposal);

    4. To execute the voted action (executeProposal).


    executor address: 0x0000000000000000000000004578656375746f72
    0. Check current reward ratio
        Reward ratio: 30%
    I. Register deplyed voting contract
    I.1. Deploy voting contract
        TX Sender: 0xcb43d5d874893a67d94cdb0c28e2a93285f56ff0
    	txid: 0x4acbdb3ddf094dcaa4178c173ab4b586b688fb39a89a3dae78d627aab9c9a14a
    I.2. Propose to attach deployed dummny voting contract
        TX Sender: 0x7d350a72ea46d0927139e57dfe2174d7acaa9d30
    	txid: 0x70fd5498354d5b8640afbccde15f60da20559bb8e61125b2a09cd5db3c3c2419
    	proposalID: 0xbf04e4cf2b6e208e965007f9add1b0937b46199e033100556772ccc239ef9164
    I.3. Approve proposal
        Approver: 0xcb43d5d874893a67d94cdb0c28e2a93285f56ff0
    	txid: 0x26dde198e6eeb5fb43f4c8ce402c9e8201446853ddd3b63f7ffcf860c985b64d
    	Approver: 0x7d350a72ea46d0927139e57dfe2174d7acaa9d30
    	txid: 0xe206405d21728a67d93cfd5222770f465ceb179f21e1274fc959a5c3a94b1a46
    	Approver: 0x62fa853cefc28aca2c225e66da96a692171d86e7
    	txid: 0x8e79ece9b96d8824d3ff80ee4f91663376f32b1043a761deec7ce132b95f7a11
    I.4. Execute proposal
        TX Sender: 0x62fa853cefc28aca2c225e66da96a692171d86e7
    	txid: 0x315c8ca567b42f9bd781d16c85e7cc3c1204b95d3b43e5e34ba440c2728538be
    I.5. Check whether voting contract has been attached
    II. Make a decision through on-chain voting
    II.1. Init vote to change reward ratio from 30% to 40%
        TX Sender: 0xfa580a85722b39c500a514c7292e9e5710a73974
    	txid: 0x5ed03f252ee84f4d1c82eff4885e8be4a90b4c9d5fd9ebaad7d1a2e1257bbebf
    	voteID: 0xe5dd8e896836f357347fd8a0a158529f922d2ad4a8e398661cff3e2c467186e0
    II.2 Tally
        TX Sender: 0xfa580a85722b39c500a514c7292e9e5710a73974
    	txid: 0xb3808ba8882c66716085e8fa4342de69f1f780af98ed77abf107aad348c4bd1e
    II.3. Submit a proposal of executing the voted action for final approval
        TX Sender: 0xfa580a85722b39c500a514c7292e9e5710a73974
    	txid: 0x4799c33027a811fe5a5bc6f53ac521639e5e97fa2e7aa659b12116e6ebf5f918
    	ProposalID: 0xe3fa889f277820e9949c483d99bdd4fedd3847d02d6ba2ddcb51a966d4820503
    III. Authorize voted action
        Approver: 0xcb43d5d874893a67d94cdb0c28e2a93285f56ff0
    	txid: 0xfc392ec5549b5c90d2947a01d64376400449a2b998c0458a054751e3f9154aea
    	Approver: 0x7d350a72ea46d0927139e57dfe2174d7acaa9d30
    	txid: 0xd02115e7a5088613cf20ec8fb017c560fcc96cbd4c034b5f5d8e48cf92a16787
    	Approver: 0x62fa853cefc28aca2c225e66da96a692171d86e7
    	txid: 0x7e860c286b33ebea2347ca7359077b6419086784b77a022c322d22b91561291e
    IV. Execute voted action
        TX Sender: 0xfa580a85722b39c500a514c7292e9e5710a73974
    	txid: 0x77c7184cc19ccac557ce39ff31d4a60cb999031127b32d152d873d69ccfce30d
    V. Check new reward ratio
        Reward ratio: 40%

    Previous Articles

    What you might not know about VeChainThor yet (Part I) - Transaction Uniqueness

    What you might not know about VeChainThor yet (Part II) - Forcible Transaction Dependency

    What you might not know about VeChainThor yet (Part III) - Transaction Fee Delegation (VIP-191)

    What you might not know about VeChainThor yet (Part IV) — Mining gas price

    What you might not know about VeChainThor yet (Part V) - Customizing Your Own VeChainThor

Log in to reply