VeChain Modifications

A developers guide to the main modifications implemented in VeChain when compared to Ethereum.

Introduction

The purpose of this document is to explore and explain the main modifications implemented in VeChain when compared to Ethereum.

Some quick notes;

  • VeChainThor is a modified and independent fork of Go-Ethereum

  • EVM compatible since the first block

  • Target Solidity compiler is Paris

Two Token Design

VeChain has a two token design in comparison to Ethereum's single token design. The primary motivation behind the two token design is to provide a predictable economic model.

VeChain Token or VET is the primary token, which is as the medium of exchange for on-chain goods and services. VeThor Token or VTHO is the secondary token used to pay gas, which is used to pay transaction fees. VTHO is automatically generated by holding VET. The current VTHO generation rate is 0.000432VTHO per unit of VET.

Ethereum has a single token, Ether (ETH), which acts both as the medium of exchange and the gas token. To perform transactions on Ethereum the user needs to hold and spend ETH. As the price of ETH accrues value it becomes more costly to perform transactions and as the blockchain becomes more popular, congestion results in higher transaction fees. This results in the cost of using the Ethereum being unpredictable and often, costly.

In comparison, when performing a transaction on VeChain the user only requires the gas token VTHO.

Fee Delegation

Fee delegation is a feature which allows users to make transactions without having any cryptocurrency. This feature allows a user to have his/her transaction fees (required when using a blockchain) sponsored by another (gas payer).

The feature is supported natively, and well integrated within the official tooling of the ecosystem.

Transaction Differences

There are six main differences in terms of transactions between VeChain and Ethereum.

Transaction Fields

The structure of a VeChain transaction can be seen below and a more detailed explanation of each field here.

// transaction.go
type Transaction struct {
	body body
}

type body struct {
	ChainTag     byte			
	BlockRef     uint64
	Expiration   uint32
	Clauses      []*Clause
	GasPriceCoef uint8
	Gas          uint64
	DependsOn    *thor.Bytes32 `rlp:"nil"`
	Nonce        uint64
	Reserved     reserved
	Signature    []byte
}

Transaction Clauses

In VeChain a single transaction can have multiple tasks / clauses. This feature essentially enables a VeChain transaction to have multiple recipients or multiple contract calls or a mixture of the two. This enables batching multiple operations into one larger transaction with multiple clauses. A detailed view of a clause structure can be found here.

The following code is an example of that, where to send the multi-clause transaction we have used the JSON API transactions end-point of a public node.

Transaction Dependency

Transaction dependency is a feature of VeChain that enables the ordering of transactions at the consensus level.

To use this feature, specify a transaction id in the DependsOn field when making a new transaction. This will create a dependency.

Note that the transaction Id specified in DependsOn has to be included in a block in order for the new transaction to be executed, which is what enforces the ordering of transactions.

An example of how to use transaction dependency is available here.

Transaction life-cycle Control

VeChain transactions have another characteristic, which is that a user can specify the earliest time a transaction can be processed using the blockRef field which represents the earliest block that transaction can be included in. Users are also able to set the opposite, i.e. the latest time a transaction is allowed to be processed using the expiration field.

These fields were conceived to be used in combination since the sum of expiration and the first four bytes of blockRef define the last block the transaction is allowed to be included in.

If you wish to use only the expiration, you must set blockRef to '0x0000000000000000'.

Hash Function

Another notable difference in design between VeChain and Ethereum is the use of different hash functions. VeChain uses blake2b for hashing whereas Ethereum uses keccak-256.

This means that developers should be aware that while VeChain has lots of similarities to Ethereum, anything that requires the use of a hash function like deriving contract addresses or transaction IDs will be different across the two chains even if the input data is identical.

Nonce

VeChain uses a hash approach to compute an unsigned transaction nonce which is determined by the transaction sender. Transaction uniqueness is achieved by defining the transaction nonce as a 64-bit unsigned integer that is determined by the transaction sender. Given a transaction, it computes two hashes, the hash of the recursive length prefix (RLP) encoded transaction data without the signature and the hash of the previously computed hash concatenated with the sender's account address. Whereas, Ethereum uses an incrementing nonce, which is determined by the number of transactions the account has sent so far.

This minor difference has a big impact. The uniqueness of a transaction is completely dependent on its content and whether it will be processed by the network is purely determined by whether the transaction id has existed on-chain, rather than by the state status of the sender's account, it's nonce, as well as all the pending transactions from that account. This greatly simplifies the developers job for interacting with the blockchain and handling transaction failures.

Getting Started: VeChain Testnet

  • Get the latest VeChain browser based wallet, VeWorld.

  • Get some testnet assets, VET and VTHO, through the faucet.

  • Use the energy station if you need to convert VET to VTHO or vice verse.

Last updated

Was this helpful?