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.

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

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.

Implementation

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

0x0000000000000000000000004578656375746f72

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

target_contract_address.call(encoded_data)

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.

Demos

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;

/ - member(s) of the governing body; authority - built-in contract Authority that manages the list of validators;

- built-in contract that manages the list of validators; executor - built-in contact Executor ;

- built-in contact ; dummyVotingContract - registered voting contract;

- 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

0x0000000000000000000000417574686f72697479

Operations carried out in the demo:

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

Output

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

0x0000000000000000000000000000506172616d73

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

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

Output

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

Address:0x69da604675b7ad6249cc5e7093ced212ded74eec

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

success

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