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.

Image for post
Image for post
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.


Image for post
Image for post
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 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 . 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 in customChainConfig.json to make the demo work. The master address can be obtained by:

thor master-key --config-dir < 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;

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;


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.1 To deploy the voting contract (deployVotingContract)

1.2 To propose a proposal of attaching the voting contract (proposeAttachingVotingContract);

1.3 To approve the proposal (approveProposal);

1.4 To execute the proposal (executeProposal);

2. To make a decision through on-chain voting:

2.1 To initialize a vote (initVote);

2.2 To tally the vote (tallyVote);

2.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

Originally published at https://bbs.vechainworld.io on October 22, 2019.

Written by

Chief Scientist @ VeChain

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store