# Welcome to VeChain

VeChain, a sustainable, public and enterprise-grade blockchain

## Begin your journey with VeChain

<table data-card-size="large" data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Blockchain Basics</td><td><a href="/pages/jqGPn4ycMHe1iNieqsJM">/pages/jqGPn4ycMHe1iNieqsJM</a></td></tr><tr><td align="center">VeChain Intro</td><td><a href="/pages/1DsWd0QbuSBdJ3dRyqQM">/pages/1DsWd0QbuSBdJ3dRyqQM</a></td></tr><tr><td align="center">Core Concepts</td><td><a href="/pages/VP49ZPehkwIGsy27bFN8">/pages/VP49ZPehkwIGsy27bFN8</a></td></tr><tr><td align="center">How to run a node</td><td><a href="/pages/mY5dYcJPvdsrq17u5Dph">/pages/mY5dYcJPvdsrq17u5Dph</a></td></tr><tr><td align="center">Developer Resources</td><td><a href="/pages/B3zrMe4vf05YljrMkFLb">/pages/B3zrMe4vf05YljrMkFLb</a></td></tr><tr><td align="center">How to Contribute</td><td><a href="/pages/bBIMueZw2oiYKfU46KLq">/pages/bBIMueZw2oiYKfU46KLq</a></td></tr></tbody></table>

## Blockchain Basics

Start by learning the basics with our blockchain primer content.

<table data-card-size="large" data-view="cards" data-full-width="false"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Introduction to blockchain</td><td><a href="/pages/jqGPn4ycMHe1iNieqsJM">/pages/jqGPn4ycMHe1iNieqsJM</a></td></tr><tr><td align="center">Introduction to digital property</td><td><a href="/pages/6M7xqQFE7HxLt3YAwHFg">/pages/6M7xqQFE7HxLt3YAwHFg</a></td></tr><tr><td align="center">The evolution of the internet</td><td><a href="/pages/hJfb156OinTjTzNcTV8y">/pages/hJfb156OinTjTzNcTV8y</a></td></tr></tbody></table>

## VeChain Introduction

Explore and learn all about VeChain.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">About VeChain</td><td><a href="/pages/0Ty3OP2LRSEAXMYL7pJu">/pages/0Ty3OP2LRSEAXMYL7pJu</a></td></tr><tr><td align="center">Dual Token Model</td><td><a href="/pages/sFLP53uo1oRduYqEsMFv">/pages/sFLP53uo1oRduYqEsMFv</a></td></tr><tr><td align="center">Acquire VeChain Assets</td><td><a href="/pages/o0ZNwG3CfSCdsh2lwsyt">/pages/o0ZNwG3CfSCdsh2lwsyt</a></td></tr><tr><td align="center">Sustainability</td><td><a href="/pages/2BsO34oKPe4UyLGKc3yL">/pages/2BsO34oKPe4UyLGKc3yL</a></td></tr></tbody></table>

## Core Concepts

Some core blockchain concepts with specific details and information relating to VeChain.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Networks</td><td><a href="/pages/0LqHzv2JQuVkPUzBIP8w">/pages/0LqHzv2JQuVkPUzBIP8w</a></td></tr><tr><td align="center">Nodes</td><td><a href="/pages/GthyMt3K6uxt9ouO694C">/pages/GthyMt3K6uxt9ouO694C</a></td></tr><tr><td align="center">Blocks</td><td><a href="/pages/ml4WNQnMltmA5wwtrjSG">/pages/ml4WNQnMltmA5wwtrjSG</a></td></tr><tr><td align="center">Transactions</td><td><a href="/pages/msPjqh0u7Eg2IrBPdCdU">/pages/msPjqh0u7Eg2IrBPdCdU</a></td></tr><tr><td align="center">Block Explorers</td><td><a href="/pages/P6vWe8Rve7F6ugGXtxx8">/pages/P6vWe8Rve7F6ugGXtxx8</a></td></tr><tr><td align="center">Fee Delegation</td><td><a href="/pages/dCPsItqNSepAOfvmdEc8">/pages/dCPsItqNSepAOfvmdEc8</a></td></tr><tr><td align="center">Wallets</td><td><a href="/pages/dGjd3X0eLgpKzie4Ukvp">/pages/dGjd3X0eLgpKzie4Ukvp</a></td></tr><tr><td align="center">EVM Compatibility</td><td><a href="/pages/1lOq6Ht1iWzdydWlpJ15">/pages/1lOq6Ht1iWzdydWlpJ15</a></td></tr></tbody></table>

## How to run a node

A collection of tutorials and guides to get you started with running nodes on the VeChainThor blockchain.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Nodes</td><td><a href="/pages/nEbT7UlG5FLtTolT39UD">/pages/nEbT7UlG5FLtTolT39UD</a></td></tr><tr><td align="center">How to run a Thor Solo Node</td><td><a href="/pages/ZHvJ6XdHITFdApJKvR43">/pages/ZHvJ6XdHITFdApJKvR43</a></td></tr><tr><td align="center">Custom Network</td><td><a href="/pages/Iy3WQZlzkPvvyRPkOIns">/pages/Iy3WQZlzkPvvyRPkOIns</a></td></tr><tr><td align="center">Connect Sync2 to a Thor Solo Node</td><td><a href="/pages/XfLSZ4vTJCJPhxEP77Os">/pages/XfLSZ4vTJCJPhxEP77Os</a></td></tr></tbody></table>

## Developer Resources

A collection of resources aimed to educate developers who are building on the VeChainThor blockchain.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Getting Started</td><td><a href="/pages/HAd4LsZ73MogGs3cDXwL">/pages/HAd4LsZ73MogGs3cDXwL</a></td></tr><tr><td align="center">How to build on VeChain</td><td><a href="/pages/JEBeVZPapzDGB4cGDu01">/pages/JEBeVZPapzDGB4cGDu01</a></td></tr><tr><td align="center">Example dApps</td><td><a href="/pages/5bK4ipLMbTCYG98Devfu">/pages/5bK4ipLMbTCYG98Devfu</a></td></tr><tr><td align="center">How to verify Address-Ownership</td><td><a href="/pages/3izwwgAE8LIC0sBPgdFO">/pages/3izwwgAE8LIC0sBPgdFO</a></td></tr><tr><td align="center">Debug Reverted Transactions</td><td><a href="/pages/zxbKJEQMISKz5yfMEU69">/pages/zxbKJEQMISKz5yfMEU69</a></td></tr><tr><td align="center">Account Abstraction</td><td><a href="/pages/g2QfrWYbVdP6AT9jFTP9">/pages/g2QfrWYbVdP6AT9jFTP9</a></td></tr><tr><td align="center">VIP-191: Designated Gas Payer</td><td><a href="/pages/39Nl6dnc6ZivjrrYbg1y">/pages/39Nl6dnc6ZivjrrYbg1y</a></td></tr><tr><td align="center">SDKs &#x26; Providers</td><td><a href="/pages/0B8hJiENMBrUiUk6o2hl">/pages/0B8hJiENMBrUiUk6o2hl</a></td></tr><tr><td align="center">Frameworks &#x26; IDEs</td><td><a href="/pages/qfyygFhaDqF1M6Vra6JB">/pages/qfyygFhaDqF1M6Vra6JB</a></td></tr><tr><td align="center">Built-in Contracts</td><td><a href="/pages/iCjhEg7w5cwFaeQ2XLbC">/pages/iCjhEg7w5cwFaeQ2XLbC</a></td></tr><tr><td align="center">VORJ</td><td><a href="/pages/hjAgvMPe3sMJJpSsPXFq">/pages/hjAgvMPe3sMJJpSsPXFq</a></td></tr><tr><td align="center">Useful Links</td><td><a href="/pages/opQrpGhGcEWMfclsBrei">/pages/opQrpGhGcEWMfclsBrei</a></td></tr></tbody></table>

## How to Contribute

See the following instructions on how best to contribute to the vechain documentation or VeChain via a VeChain Improvement Proposal (VIP):

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Documentation</td><td><a href="/pages/bBIMueZw2oiYKfU46KLq#create-issues">/pages/bBIMueZw2oiYKfU46KLq#create-issues</a></td></tr><tr><td align="center">VIPs</td><td><a href="https://github.com/vechain/VIPs">https://github.com/vechain/VIPs</a></td></tr></tbody></table>


# Blockchain Basics

A basic introduction and overview of blockchains.

Blockchain is a vast and complex subject. Depending on the depth of explanation desired, it can range from a brief overview taking just minutes to an in-depth study requiring months to fully grasp its intricacies and implications. With a short introduction, we would like to scratch the surface of the transformative world of blockchain technology and mention why we speak of Web3. Even if groundbreaking applications are a reality, and distributed ledger system are reshaping our digital landscape, we want to enroll you to become a pioneer of what still remains uncovered, hoping that you will choose VeChain as your home.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Introduction to blockchain</td><td><a href="/pages/jqGPn4ycMHe1iNieqsJM">/pages/jqGPn4ycMHe1iNieqsJM</a></td></tr><tr><td align="center">Introduction to digital property</td><td><a href="/pages/6M7xqQFE7HxLt3YAwHFg">/pages/6M7xqQFE7HxLt3YAwHFg</a></td></tr><tr><td align="center">The evolution of the internet</td><td><a href="/pages/hJfb156OinTjTzNcTV8y">/pages/hJfb156OinTjTzNcTV8y</a></td></tr></tbody></table>


# Introduction to blockchain

A concise guide to the essence, mechanics, applications, and significance of blockchain technology.

## Defining Blockchain

Imagine a digital ledger, infinitely copied and instantly updated across a vast network of computers. This is blockchain: a revolutionary system that securely records transactions without central oversight. It's a chain of data blocks, each linked to the previous, creating an unbreakable record of trust.

## The Inner Workings

At its core, blockchain is a symphony of cryptography, consensus, and computing power. Each block contains encrypted transaction data and a unique "fingerprint" called a hash. Network participants, or nodes, validate new blocks through complex algorithms. Once verified, these blocks join the chain permanently, forming an immutable history.

## Real-World Impact

Blockchain's reach extends far beyond its cryptocurrency roots. Today, it's reshaping industries:

* Finance: Enabling borderless, instant transactions.
* Supply Chain: Tracking products from source to shelf.
* Healthcare: Securing patient data and medical records.
* Voting Systems: Ensuring tamper-proof elections.
* Digital Identity: Putting personal data back in users' hands.

As innovation accelerates, we're only scratching the surface of blockchain's potential.

## The Decentralized Orchestra

There's no conductor in the blockchain symphony. Instead, a distributed network of users collectively maintains and validates the system. This peer-to-peer approach eliminates single points of failure and democratizes data control.

## The Blockchain Advantage

Why is blockchain causing such a stir? It offers:

* **Decentralization**: Resilience against attacks and failures.
* **Transparency**: A verifiable, public record of all activities.
* **Immutability**: Tamper-proof data that stands the test of time.
* **Enhanced Security**: Military-grade encryption protecting transactions.
* **Efficiency**: Streamlined processes cutting out middlemen.

By reimagining trust in the digital age, blockchain is laying the foundation for a more secure, transparent, and equitable future.


# Introduction to digital property

An overview of digital property types and their blockchain implementation.

## Redefining Property in the Digital Age

Digital property represents a paradigm shift in how we conceive ownership. Stored on blockchain technology, it primarily encompasses fungible tokens (like cryptocurrencies) and non-fungible tokens (NFTs), revolutionizing our understanding of assets in the digital realm.

## Fungible Tokens: The Digital Currency Revolution

Imagine digital coins that are identical and interchangeable, much like traditional currency. These are fungible tokens. Each unit holds equal value and utility, enabling frictionless exchange. Cryptocurrencies stand as the quintessential example, reshaping global finance.

## NFTs: Unique Digital Treasures

Non-fungible tokens (NFTs) are the digital world's answer to one-of-a-kind collectibles. Unlike their fungible counterparts, each NFT is distinct and irreplaceable. They can represent a vast array of digital assets - from breathtaking artwork and soul-stirring music to groundbreaking videos and verifiable certificates.

## Creating Digital Property: Democratizing Asset Generation

The blockchain has democratized asset creation. With the right technical know-how, anyone can mint digital property as fungible or non-fungible tokens. This process adds a unique digital token to the blockchain, integrating it into a vast network of tradable assets. Each transaction is indelibly recorded, ensuring authenticity and security.

The beauty of blockchain-based digital property lies in its transparent, decentralized nature. It eliminates the need for intermediaries, allowing direct peer-to-peer transfers of ownership.

## Storing Digital Riches

Digital property exists as data within blockchain transactions. Each token carries crucial metadata - information about ownership, value, and other pertinent details. This data is distributed across the blockchain network, ensuring robust security and accessibility.

## Fortifying Digital Assets

The inherent security of blockchain technology safeguards digital property. As a distributed ledger replicated across numerous computers, it eliminates single points of failure. This decentralized structure makes the stored data highly resistant to tampering, hacking, or unauthorized access.

## The Digital Property Advantage

Blockchain-based digital property offers a trifecta of benefits: security, transparency, and decentralization. It provides immutable proof of ownership and facilitates direct peer-to-peer transactions, marking a new era in asset management and transfer.

## Types of Digital Property

Digital property comes in various forms, each serving unique purposes:

* **Cryptocurrencies**: The pioneers of digital assets, serving as stores of value and mediums of exchange.
* **Platform Tokens**: Powering blockchain ecosystems and enabling decentralized application (dApp) development.
* **Utility Tokens**: Granting access to specific services, often with additional perks like voting rights.
* **Transaction Fee/Gas Tokens**: Covering the costs of blockchain operations.
* **Security Tokens**: Digital representations of traditional securities.
* **NFTs**: Unique digital assets representing ownership of specific items or rights.
* **Stablecoins**: Designed to maintain steady value, often pegged to traditional currencies or assets.

Each type of digital property operates on various blockchain networks, from Bitcoin and Ethereum to emerging platforms like Cardano and Polkadot. As this technology evolves, we can expect even more innovative forms of digital property to emerge, further blurring the lines between the physical and digital worlds of ownership and value.


# The evolution of the internet

The evolution from Web1 to Web3, a paradigm shift in internet technology.

## Journey of the Web

| Era    | Web 1.0                       | Web 2.0                             | Web 3.0                                  |
| ------ | ----------------------------- | ----------------------------------- | ---------------------------------------- |
| Focus  | Read-only: Information Access | Read-write: Social Interaction      | Read-write-own: User Empowerment         |
| Design | Static websites               | Dynamic Web Applications            | Decentralized Applications (dApps)       |
| Model  | One-way Information Flow      | Cloud Computing, User Participation | Blockchain Integration, Decentralization |
| Access | Desktop-centric               | Mobile-first                        | VR & Metaverse Integration               |

## Web1: The Dawn of Digital Information

Web1, the internet's inaugural phase, introduced a world of static web pages and limited interactivity. It served primarily as a vast digital library, where a select few created content for a largely passive audience. This era laid the foundation for global information sharing, despite its technical limitations.

## Web2: The Social Web Revolution

Our current internet generation, Web2, ushered in an era of dynamic, interactive web applications. It democratized content creation, enabling real-time collaboration and widespread participation. Social media platforms, e-commerce giants, and cloud computing services epitomize Web2's capabilities. However, this accessibility came with a trade-off: centralization of user data and content under the control of tech behemoths.

## Web3: Ushering in Digital Autonomy

Web3 represents the next frontier of internet evolution, built on the pillars of decentralization, blockchain technology, and user empowerment. It promises a digital landscape where users control their data, interact directly without intermediaries, and truly own their digital assets. Web3 encompasses revolutionary concepts like decentralized finance (DeFi), non-fungible tokens (NFTs), and integrates cutting-edge technologies such as artificial intelligence (AI) and the Internet of Things (IoT).

## The Web3 Advantage

Web3 offers a paradigm shift in how we interact with the digital world:

* **Decentralization**: Eliminates single points of failure, enhancing resilience against censorship and cyber attacks.
* **Trust and Transparency**: Leverages blockchain and smart contracts to ensure data integrity without relying on central authorities.
* **Interoperability**: Enables seamless interaction between different blockchain networks, fostering innovation and collaboration.
* **True Digital Ownership**: Grants users unprecedented control over their digital assets and personal data.
* **Community-Driven Governance**: Encourages active participation in shaping the digital ecosystem through incentivized structures.

## Navigating Web3's Growing Pains

Despite its transformative potential, Web3 faces several hurdles:

* **Technical Complexity**: The steep learning curve of Web3 technologies may slow widespread adoption.
* **Regulatory Ambiguity**: The lack of clear regulatory frameworks creates uncertainty for users and developers alike.
* **Scalability Challenges**: Many Web3 platforms struggle with transaction speeds and costs, hindering mass adoption.
* **User Experience Gaps**: The complexity of Web3 interfaces often alienates average users accustomed to sleek Web2 designs.
* **Environmental Concerns**: Some blockchain technologies underpinning Web3 face criticism for their energy consumption.

As Web3 matures, addressing these challenges will be crucial in realizing its full potential. The journey from information access to social interaction, and now to true digital ownership, marks a significant evolution in our digital lives. Web3 promises a more open, transparent, and user-centric internet, potentially reshaping how we interact, transact, and create value in the digital realm.

The future of the internet is being written now, with Web3 at the forefront of this digital renaissance. As we navigate this transition, it's clear that the potential for innovation, empowerment, and decentralization is immense, heralding a new era of digital interaction and ownership.


# Introduction to VeChain

An introduction to VeChain and the VeChainThor blockchain ecosystem.

## What is VeChain?

VeChain, headquartered in San Marino, Europe, is a pioneering blockchain ecosystem and creator of VeChainThor, a world-class smart contract platform driving real-world blockchain adoption. Founded in 2015 by Sunny Lu, VeChain has consistently worked to deliver a transparent, efficient, scalable, and adaptable blockchain solution.

Since its inception, VeChain has established itself as a leader in the blockchain space, forging partnerships with renowned organizations such as Walmart China, BMW, DNV, and the government of San Marino. VeChain's current mission is to build digital ecosystems that drive global sustainability and digital transformation.

## Why choose VeChain?

The VeChainThor blockchain is engineered for mass adoption, offering several key advantages:

* **Scalability**: Innovative transaction model supporting asynchronous operations and transaction lifecycle dependencies.
* **Cost Predictability**: Unique dual-token model ensures stable transaction fees during high-demand periods.
* **Sustainable Consensus**: Proof of Authority (PoA) mechanism provides security and scalability with a minimal carbon footprint.
* **Fee Delegation**: Enables sponsor accounts to cover transaction fees, lowering barriers to entry for new users.
* **Robust Security**: Zero reported hacks of the PoA consensus mechanism since inception.
* **High Reliability**: Uninterrupted operation since the genesis block in 2018.
* **Interoperability**: Compatible with other leading blockchain platforms.

## VeChain Governance

VeChain embodies true decentralization, operating as an open, public network without centralized control. The ecosystem thrives on community support and promotion. Strategic direction is provided by a steering committee and the VeChain Foundation, ensuring the network's growth aligns with its core mission and values.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">About VeChain</td><td><a href="/pages/0Ty3OP2LRSEAXMYL7pJu">/pages/0Ty3OP2LRSEAXMYL7pJu</a></td></tr><tr><td align="center">Dual-Token Model</td><td><a href="/pages/sFLP53uo1oRduYqEsMFv">/pages/sFLP53uo1oRduYqEsMFv</a></td></tr><tr><td align="center">Acquire VeChain Assets</td><td><a href="/pages/o0ZNwG3CfSCdsh2lwsyt">/pages/o0ZNwG3CfSCdsh2lwsyt</a></td></tr><tr><td align="center">Sustainability</td><td><a href="/pages/2BsO34oKPe4UyLGKc3yL">/pages/2BsO34oKPe4UyLGKc3yL</a></td></tr></tbody></table>


# About the VeChain blockchain

An in-depth look at the VeChainThor blockchain powering the VeChain ecosystem.

## VeChainThor: A Layer 1 Blockchain for Enterprise Adoption

VeChainThor is the layer 1 blockchain which powers the VeChain ecosystem. VeChainThor is a public blockchain that is designed for mass adoption and is intended to serve as a foundation for a sustainable and scalable blockchain ecosystem.

Since it went live, the time when the genesis block was mined, in June 2018, the blockchain has been 100% online with zero downtime. VeChainThor is an extremely fast and efficient blockchain, producing blocks, on average, every 10 seconds and all the while only consuming a fraction of the energy other blockchains require to complete the same task. In fact, VeChain’s energy consumption is equal to just 0.04% of other blockchains.

The VeChainThor blockchain is not built from scratch. It expands upon some of the essential building blocks of the Ethereum blockchain and provides innovative technical solutions that are powered by our novel governance and economic models, which, we believe, will push forward broader blockchain adoption and the creation of new business ecosystems with more efficiency and trust. VeChainThor is packed with technical features that are tailor-made to meet the needs of individuals and enterprises.

## VeChainThor's Consensus Mechanism: Proof of Authority (PoA)

Consensus is the process by which a blockchain network agrees on the validity of a transaction or block. In a blockchain network, transactions are grouped together in blocks, and these blocks are linked together in a blockchain. Consensus is needed to ensure that all participants in the network agree on the current state of the blockchain. Consensus occurs each time a new block gets appended to the blockchain.

VeChainThor's Proof of Authority (PoA) consensus algorithm is powered by 101 Authority Masternodes who are tasked with producing blocks for the VeChain blockchain. In order to become an Authority Masternode, an individual or entity has to voluntarily disclose their identity to the foundation and undergo a strict know-your-customer (KYC) process, before being selected. Only a block produced by an Authorithy Masternode will be viewed as a valid block by the VeChainThor blockchain.

## The Rationale Behind PoA: Addressing the Blockchain Trilemma

There is a well known trade off in consensus algorithms which Vitalik Buterin, founder of the Ethereum blockchain, coined the "The Blockchain Trilemma". In essence, Buterin asserted peer-to-peer (P2P) decentralised networks cannot score highly on decentralisation, security and speed. Every blockchain network will be required to sacrifice one attribute to achieve the desired blockchain configuration. VeChain's aim is to be an enterprise grade, sustainable blockchain, and so the tradeoff was to reduce the amount of actors involved in block production in order to improve speed and security.

However, as all Authority Masternodes have their identities and reputations at stake, they are all held accountable and are incentivised to work in the best interest for the networks growth and security. Authorithy Masternode's also earn rewards for producing blocks, which further incentivises them to act in good faith and to the benefit of the VeChainThor blockchain.

## Future-Proofing VeChainThor

VeChain continuously evolves the VeChainThor blockchain to meet emerging needs:

* Regular protocol upgrades
* Research into scaling solutions
* Exploration of cross-chain interoperability
* Ongoing security enhancements

By combining enterprise-grade performance with innovative features and a focus on sustainability, VeChainThor positions itself as a leading blockchain solution for businesses and individuals alike. Its unique consensus mechanism and tailored features provide a robust foundation for the next generation of blockchain applications and ecosystem growth.


# Consensus Deep Dive

A deeper dive into our PoA consensus mechanism.

## Proof of Authority (PoA)

Designing a consensus algorithm for a public blockchain network is a critical decision that influences how participants agree on the blockchain's growth and embodies the governance model of the network. VeChainThor implements the PoA consensus algorithm, aligning with our governance philosophy:

> *"neither a total centralization nor a total decentralization would be the correct answer, but a compromise from and balance of both would*."

VeChainThor implements the PoA consensus algorithm which suits our governance model which states that there would not be anonymous block producer, but a fixed number of known validators (Authority Masternodes) authorized by the steering committee of the VeChain Foundation.

> “It takes twenty years to build a reputation and five minutes to ruin it. If you think about that, you’ll do things differently.” – Warren Buffett

To be an Authority Masternode (AM), the individual or entity voluntarily discloses who they are, identity and reputation by extension, to the VeChain Foundation in exchange for the right to validate and produce blocks. Their identity, reputation and financial investment is placed at stake and this acts as an incentive for the AMs to behave correctly and keep the network secure. In VeChainThor, each AM has to go through a strict know-your-customer (KYC) procedure and satisfy the minimum requirements set by the VeChain Foundation.

When discussing a consensus algorithm, we must answer the following questions:

* When is a new block produced?
* Who generates the block?
* How to choose the "trunk" from two legitimate blockchain branches?

## When <a href="#meta-transaction-features" id="meta-transaction-features"></a>

The VeChainThor blockchain schedules a new block to be generated once every $$\Delta$$ seconds. We set $$\Delta = 10$$, which is based on our estimation of the usage of VeChainThor. Let $$t\_{0}$$ be the timestamp of the genesis block. The timestamp of the block with height $$h > 0$$ and $$t\_{h}$$,must satisfy $$*h = t*{0} + m\Delta$$ where $$m \in \mathbb{N}^{+}$$ and $$\geqslant h$$.

## Who <a href="#meta-transaction-features" id="meta-transaction-features"></a>

PoA allows every available AM to have an equal opportunity to be selected to produce blocks. To do that, we introduce a Deterministic Pseudo-Random Process (DPRP) and the “active/inactive” AM status to decide whether a particular AM $$\alpha$$ is legitimate for producing a block $$(h,t)$$ with height $$h$$(uint32) and timestamp $$t$$(uint64). Here $$t$$ must satisfy $$(t - t\_{0})mod\Delta = 0$$. We first define the DPRP to generate a pseudo-random number $$\gamma(h,t)$$ as:

$$\gamma(h,t) = DPRP(h,t) =hash(h \circ t)$$

where $$\circ$$ denotes the operation that concatenates two byte arrays.

Let $$A\_{B}$$ denote the sorted set of AMs with the “active” status in the state associated with block $$B$$. Note that on the VeChainThor blockchain each AM is given a fixed index number and the numbers are used to sort elements in $$A\_{B}$$. To verify whether $$a$$ is the legitimate AM for producing $$B(h,t)$$, we first define

$$A^{a}*{B(h,t)} = sort(A*{PA(Bh,t))} ) \cup a$$

where $$PA(\cdot)$$ returns the parent block. We then compute index $$i^{a}(h,t)$$as:

$$i^{a}(h,t) = \gamma(h,t) mod \parallel A^{a}\_{B(h,t)} \parallel$$

AM $$a$$ is the legitimate producer of $$B(h,t)$$ if and only if $$A^{a}\_{B(h,t)} \[i^{a}(h,t)] = a$$. Note that we put double quotes around the word “active” to emphasize that the status does not directly reflect the physical condition of a certain AM, but merely a status derived from the incoming information from the network.

## AM Status Updating <a href="#meta-transaction-features" id="meta-transaction-features"></a>

Given the latest block $$B(h,t\_{1})$$ and its parent $$B(h - 1,t\_{0})$$, for any $$t\_{0} < t < t\_{1}$$ and $$(t - t\_{0}) mod \Delta = 0$$, the system computes AM $$a\_{t}$$ such that

$$A^{a\_{t}}*{B(h,t*{1})}\[i^{a\_{t}}(h,t)] = a\_{t}$$

and mark $$a\_{t}$$ as "inactive" in the state associated with $$B(h,t\_{1})$$. In addition, the system always sets the status of the AM that generates $$B(h,t\_1)$$ as "active". Note that we set all the AMs as "active" from the beginning.

## Trunk <a href="#meta-transaction-features" id="meta-transaction-features"></a>

The final question we need to answer is how to choose the “trunk” from two legitimate blockchain branches. Since there is no computational competition in PoA, the “longest chain” rule does not apply. Instead, we consider the better branch as the one witnessed by more AMs.

To do that, we compute the accumulated witness number (AWN), $$\pi$$, for block $$B(h, t)$$ as:

$$\pi\_{B(h,t)} = \pi\_{PA(B(h,t))} + \parallel A\_{B(h,t)} \parallel$$

with $$\pi\_{B\_{genesis}} = 0$$. Since $$\parallel A\_{B(h,t)} \parallel$$ computes the number of AMs with “active” status associated with $$B(h,t)$$, it can be viewed as the number of AMs that witness the generation of $$B(h,t)$$. Therefore, we select the branch with the larger AWN as the trunk. If the AWNs are the same, we choose the branch with less length. Note that the AWN is stored in the block header as `TotalScore`.

Formally, given two branches $$<\mathcal{B}*{1}$$ and $$\mathcal{B}*{2}$$ with their latest blocks $${B}*{1}(h*{1},t\_{1})$$ and $${B}*{2}(h*{2},t\_{2})$$, respectively, we first calculate their AWNs $$\pi\_{B\_{1}}$$ and $$\pi\_{B\_{2}}$$. The system then makes the following decision: choose $${B\_{1}}$$ as the trunk if $$\pi\_{B\_{1}} > \pi\_{B\_{2}}$$, or $$B\_{2}$$ if $$\pi\_{B\_{1}} < \pi\_{B\_{2}}$$. In case $$\pi\_{B\_{1}} = \pi\_{B\_{2}}$$, choose $$B\_{1}$$if $$h\_{1} < h\_{2}$$ or $$B\_{2}$$ if $$h\_{1} > h\_{2}$$. If $$h\_{1} = h\_{2}$$, keep the current trunk.


# Governance

Introduction to blockchain governance and VeChain's implementation.

## On-Chain Governance Overview

On-chain governance in blockchain refers to the process of making decisions in a decentralized and auditable way. This approach ensures transparency, allowing everyone to view proposals and audit outcomes.

## VeChain's On-Chain Governance Implementation

VeChain leverages on-chain governance to encourage VET holders to get involved and make decisions on critical on-chain actions. The outcome will always require a human action to propagate the change. These actions can, for instance, be activating or not a new network upgrade, changing token emission parameters, gas rules or block rewards, or any technical or economic mechanics that can be implemented on the VeChainThor blockchain. Formal execution will happen on-chain through a transaction that can carry a proof, meaning that all required actions have been completed.

VeChain's on-chain governance process consists of three phases:

* **Decision making:** creation of a Discourse discussion, and possibly also a VIP with all the details of the subject of a new voting.
* **Authorization:** actual creation of the proposal by whitelisted accounts to safeguard on-chain governance against malicious activities.
* **Execution:** off-chain mechanics to execute a proposal that has passed, ending in an on-chain transaction to track and notify that the change was executed.

## Voters

Voting power is available to all VeChainThor Validators, as well as StarGate NFT holders or managers. The number of votes, the voting power, is determined by all the node tiers owned and managed.

For more details, refer to the [VeVote documentation](https://docs.vevote.vechain.org).

More about staking can be found in the [StarGate docs](https://docs.stargate.vechain.org).

## Some History

The governing body of VeChain, was originally a steering committee, which represented the balanced interests of all VeChainThor blockchain stakeholders. The steering committee has been deprecated, and decisions are in the hands of Node holders and Validators casting their votes on VeVote.

{% hint style="info" %}
Explore VeChain's on-chain governance and view past or future proposals, visit [VeVote](https://vevote.vechain.org/), VeChain's voting platform. VeVote enhances ecosystem transparency and decentralization. Specific documentation and details about the new governance can be found here: [docs.vevote.vechain.org](https://github.com/vechain/vechain-docs/blob/main/introduction-to-vechain/about-the-vechain-blockchain/docs.vevote.vechain.org)
{% endhint %}


# Dual-Token Economic Model

Understanding VeChain's innovative dual-token economic model.

## Blockchain Token Economic Models: An Overview

Public blockchain networks rely on economic systems to govern token behavior and distribution. These models encompass the design, issuance, distribution, and management of tokens, as well as the incentives and mechanisms driving their value and utilization.

## The Importance of a Well-Designed Economic Model

The choice of economic model has far-reaching implications for a blockchain ecosystem:

* Proper incentives enhance network security
* Ethical distribution builds trust
* Open governance increases confidence
* Clever design improves overall robustness

VeChain's economic model has been carefully crafted with these principles in mind.

## VeChain's Innovative Dual-Token Approach

Through extensive collaboration with business partners, particularly corporations and enterprise owners, VeChain identified a major obstacle to blockchain adoption: the unpredictability of usage costs due to cryptocurrency volatility. To address this challenge, VeChain implemented a dual-token model:

* **VeChain Token (VET)**: Serves as a value-transfer medium (utility token)
* **VeThor Token (VTHO)**: Represents the cost of using VeChainThor blockchain resources (transaction/gas token)

This unique two-token design effectively separates the cost of using the blockchain from market speculation.

## Rationale Behind the Dual-Token Model

During cryptocurrency bull markets, token prices often inflate, leading to increased transaction costs on single-token networks. VeChain's dual-token model aims to mitigate this issue by:

* **Cost Predictability**: VTHO helps stabilize transaction fees, making it easier for enterprises and individuals to forecast network usage costs.
* **Decoupling from Market Volatility**: By separating the value-transfer token (VET) from the transaction cost token (VTHO), the model reduces the direct impact of market speculation on network usage costs.
* **Flexible Governance**: The two-token system allows for more nuanced economic governance, enabling adjustments to transaction costs without directly affecting the main value token.
* **Encouraging Long-term Holding**: VET holders generate VTHO over time, incentivizing long-term investment in the ecosystem.
* **Enterprise-friendly Design**: The predictable cost structure is particularly appealing to businesses that require stable operational expenses.

By implementing this dual-token model, VeChain addresses one of the key barriers to widespread blockchain adoption in enterprise environments. It offers a more stable and predictable cost structure, making it easier for businesses to integrate blockchain technology into their operations without the fear of unpredictable expenses due to market volatility.

This innovative approach positions VeChain as a blockchain solution that's not only technologically advanced but also economically designed for real-world, enterprise-level adoption.


# VeChain (VET)

Understanding VeChain's utility token, VET

| VET Characteristics | Details           |
| ------------------- | ----------------- |
| Type                | Native Coin       |
| Precision           | 18 decimal places |
| Total supply        | 86,712,634,466    |

## Native Coin: The Backbone of VeChainThor

A native coin is the primary cryptocurrency inherent to a specific blockchain network. As VeChainThor's native coin, VET serves as the fundamental unit of value and plays multiple crucial roles within the ecosystem:

* **Medium of Exchange**: Facilitates value transfer within the network.
* **Store of Value**: Acts as a digital asset that can appreciate or depreciate in value.
* **Utility Token**: Enables access to various features and services on the VeChainThor blockchain.
* **Governance Mechanism**: VET holders can participate in network governance decisions.

## VET's High Divisibility: 18 Decimal Places

VET's high divisibility, with 18 decimal places, offers several advantages:

* **Micropayments**: Enables extremely small transactions, crucial for many blockchain applications.
* **Precision**: Allows for exact value representation in various use cases.
* **Scalability**: Supports a wide range of transaction sizes, from tiny micropayments to large transfers.
* **Future-proofing**: Provides room for value appreciation without limiting usability.

The smallest unit of VET, similar to Bitcoin's Satoshi, and just like in Ethereum, is called 'wei': 1 VET = 1,000,000,000,000,000,000 wei (10^18 wei).

This high divisibility makes VET particularly suitable for:

* Internet of Things (IoT) applications
* Micro-incentivization in sustainability initiatives
* Precise value allocation in complex supply chain scenarios

## Total Supply: Fixed at 86,712,634,466 VET

The total supply of VET is fixed, meaning no new tokens will ever be created. This fixed supply model offers several benefits:

* **Scarcity**: Creates a deflationary aspect to the token economics.
* **Predictability**: Allows for more accurate long-term economic modeling.
* **Transparency**: Provides clarity to users and investors about the token's distribution.
* **Value Proposition**: Can potentially drive value appreciation as demand increases against a fixed supply.

## Implications of a Fixed Supply

* **Long-term Value**: As adoption grows, the fixed supply could lead to appreciation in VET's value.
* **Economic Stability**: Prevents inflationary pressures that come with an ever-increasing supply.
* **Trust**: Builds confidence among users and investors due to the predictable token economics.

By combining high divisibility with a fixed total supply, VET is designed to serve as a versatile and sustainable utility token within the VeChainThor ecosystem. This design supports a wide range of applications, from microtransactions in IoT devices to large-scale enterprise solutions, while maintaining a stable and predictable economic model.


# VeThor (VTHO)

Understanding VeChain's transaction/gas token, VTHO

<table><thead><tr><th width="258.27956989247315">VTHO Characteristics</th><th>Details</th></tr></thead><tbody><tr><td>Type</td><td><a href="https://github.com/vechain/VIPs/blob/master/vips/VIP-180.md">VIP180</a></td></tr><tr><td>Token contract address</td><td>0x0000000000000000000000000000456E65726779</td></tr><tr><td>Precision</td><td>18 decimal places</td></tr><tr><td>Supply</td><td>VTHO (also known as _energy_) is used to pay for a transfer or for executing a smart contract transaction on the VeChainThor blockchain.</td></tr><tr><td>Dynamic behaviour</td><td>VTHO is subject to the rules of a fee market, the _BaseFee_ of each transaction fee paid is burned and the remaining priority fee is rewarded to the Validator which has proposed the block.</td></tr></tbody></table>

## VIP180: VeChain's Fungible Token Standard

VeChain had implemented an improvement proposal defining a new fungible token standard, VIP180. It was a superset of Ethereum's ERC20 standard, now superseded. All VIP180 are compatible with the most used ERC20 fungible token standard across blockchains. VTHO, as a VIP180 token, powers the VeChainThor blockchain by:

* Serving as the fee for transactions and smart contract execution
* Rewarding Validators and Delegators for block production and network maintenance

## VTHO Supply Dynamics

Unlike VET, VTHO doesn't have a fixed maximum supply. Its supply is governed by [VIP-251](https://github.com/vechain/VIPs/blob/master/vips/VIP-251.md) a dynamic fee mechanism, inspired by Ethereum's EIP-1559. It introduces a fluctuating base fee set by the protocol, which is the minimum you have to pay for your transaction to be considered valid, and a priority fee a tip that you add to the base fee to make your transaction attractive to validators:

* Generation rate (pre Hayabusa fork): new VTHO is generated at every block by holding VET
* Generation rate: since the Hayabusa hardfork, new VTHO is generated at every block and it is a function of Total VET being locked
* Block rewards: VTHO is used for transaction fees which, since the Galactica hardfork, is split in two parts
  * Base fee - which gets burned
  * Priority fee - that goes to the Validator who proposed the block

This dynamic supply model allows VeChain to adapt to network demand and maintain economic stability.

## The Purpose of VTHO Burning

VTHO burning serves several crucial functions:

* **Supply Control**: Helps regulate the circulating supply of VTHO
* **Value Stability**: Aims to maintain a stable VTHO value for predictable transaction costs
* **Flexibility**: Allows VeChain to adjust parameters based on network adoption and demand

## Earning VTHO

In a Delegated Proof of Stake (DPoS) consensus, every VET staked does contribute in keeping the network secure and those who do it are eligible to VTHO generation. Before Hayabusa, every holder was generating VTHO just by holding VET. Incentive was diluted, and it was proven to provide a very weak incentive for the validators (responsible for keeping the network secure). How to start earning: To make the first step to start accumulating VTHO reward you can either:

* become a **delegator**: buying a StarGate NFTs and delegating it to a validator in StarGate.
* become a **validator**: running the node infrastructure to propose blocks and staking 25 M VET. More about staking can be found in the [StarGate docs](https://docs.stargate.vechain.org).

## VTHO generation formula

VTHO is generated for each block produced, the amount of VTHO generated is a function of total VET staked in the network. Mathematically it can be described with formula:

$$VTHO\_{gen} = 1200 \cdot 64 \cdot \sqrt{VET\_{staked}}$$

Where $$VTHO\_{gen}$$ denotes the amount of VTHO generated per year. The constants: $$1200$$ and $$64$$ are scaling factors that determine the base generation rate, and: $$VET\_{staked}$$

represents the total amount of VET staked across the network, by both validators and delegators at the point of block production.

The square root function ensures that VTHO generation scales sub-linearly with the amount of staked VET, meaning that as more VET is staked, the rate of VTHO generation per additional staked VET decreases. This design helps maintain economic balance by preventing excessive VTHO inflation while still rewarding network participation through staking.

An example would be, if the total amount of VET staked in the network is 2.525 billion VET, the network would generate approximately 3.86 billion VTHO annually. This dynamic model, introduced with the Hayabusa hardfork, replaces the previous linear generation model where VET holders automatically generated VTHO at a fixed rate, and instead ties VTHO generation directly to active staking participation.

## VTHO transaction cost formula

On the other hand, for each transaction, a transaction fee must be paid to pay for the computation on the network. Mathematically, we can write it as:

$$E\_{con} = p \cdot G$$

Where $$E\_{con}$$ is the price in VTHO for performing a transaction. $$G$$ denotes the amount of gas required to process the transaction and $$p$$ the gas price in VTHO, which is governed by the fee market.

This dual-token model, with staked VET generating VTHO and VTHO powering transactions, creates a flexible, scalable economic system for the VeChainThor blockchain. It allows for transaction cost stability while maintaining the potential for VET value appreciation, making it attractive for both enterprise use and individual investment.


# Acquire VeChain Assets

A comprehensive guide to acquiring VeChain assets.

## How to Purchase VET & VTHO

### Centralized Exchange

VeChain tokens (VET & VTHO) are available on several prominent centralized exchanges, including Coinbase, Binance, and Crypto.com. These exchanges act as intermediaries between buyers and sellers. To purchase VET/VTHO on a CEX:

* Create an account.
* Complete the KYC process.
* Enable 2FA.
* Deposit fiat funds via bank transfers or credit card payment.
* Choose the cryptocurrency to buy - VET or VTHO.
* Place a buy order.
* Withdraw funds to a personal wallet.

{% hint style="warning" %}
Always double check and confirm the CEX website address to ensure you are using the official website.
{% endhint %}

### Virtual Currency Platform

Another way to purchase tokens is directly from VeChain's flagship wallet, VeWorld.

By hitting "Buy" you can select among several on-ramp provides.

## The Importance of Self-Custody

A popular adage in the blockchain industry, coined by Andreas Antonopoulos, states: "Not your keys, not your coins." This principle applies to all cryptocurrencies, including VeChain assets.

### Why Self-Custody Matters

When you store your assets on a centralized exchange, you're exposed to counterparty risk. By entrusting a third party with your cryptocurrency, you're relying on their security measures and ethical practices. Self-custody, where you control your private keys, eliminates these risks.

Benefits of self-custody:

* Full control over your assets
* Reduced risk of exchange hacks or insolvency
* Privacy and anonymity
* Independence from third-party policies

{% hint style="danger" %}
VeChain and its affiliates will never ask for your private key.\
\
Never share your private key with anyone; doing so will likely result in loss of assets.
{% endhint %}

## Steps to Secure Your VeChain Assets

* Choose a reputable VeChain-compatible wallet (hardware or software)
* Set up your wallet following the provider's instructions
* Transfer your VET and VTHO from the exchange to your personal wallet
* Safely store your recovery phrase and private keys
* Regularly update your wallet software and follow the best security practices

By following these guidelines, you can securely acquire and manage your VeChain assets, minimizing risks and maximizing control over your investments in the VeChain ecosystem.


# Sustainability

VeChain's role in fostering global sustainability.

## VeChain's Approach to Global Sustainability

In addressing the world's most pressing sustainability challenges, VeChain recognizes the need for collective, global action. Our mission is to amplify individual efforts, creating a powerful synergy that can effectively combat climate change, environmental degradation, and social inequities.

We aim to empower individuals to engage with sustainability in their daily lives by providing tools and platforms that enable informed, impactful decisions. Our focus areas include access to healthy food, clean water, and fresh air - fundamental elements of human existence and well-being.

## VeChain: A Sustainable Blockchain Ecosystem

For our ecosystem to be sustainable, the infrastructure itself must first be sustainable. The VeChainThor blockchain offers an energy-efficient, user-friendly, open platform for collaboration.

VeChainThor features a new Proof of Authority mechanism – PoA 2.0, that strikes a much-desired balance between speed and security. The result? Scalability and lower energy consumption, making it the ideal blockchain to jumpstart sustainability initiatives.

Over the years, several assessments have demonstrated the network's energy efficiency, but we’ll let the numbers speak for themselves. The 2022 carbon footprint of VeChain’s network of 101 authorities masternodes was calculated to be 4.46 t CO2e/year, ranking VeChain as one of the most energy efficient blockchains, using just 0,000216 kWh of electricity per transaction, or roughly 0.04% of other blockchains.

We have and are continuing to engage with many businesses and industries to combine forces and create innovative solutions to promote sustainability in many different forms. Our ambition is to become the most sustainable blockchain networks and ecosystems.

{% hint style="info" %}
For a deeper understanding of our sustainability vision, please refer to our [Whitepaper 3.0](https://www.vechain.org/assets/whitepaper/whitepaper-3-0.pdf).
{% endhint %}

## Web3 and Blockchain: Catalysts for Sustainability

We have the vision and cutting edge technology to silently shape society in ways yet not imagined:

* **Collective Governance & Decision-Making**: Blockchain enables inclusive and transparent decision-making through decentralized autonomous organizations (DAOs). Instead of top down decisions, blockchains can offer more equitable decisions to questions that impact us all.
* **Tokenisation & Incentivization**: Web3 is a key driver of the sustainability transition will be a fundamental redefinition of “value” as a concept. Web3 technologies enable us to understand, qualify, quantify, and share the value of an action, including its societal, environmental, and economic factors.
* **Transparency & Accountability**: Web3 provides people with a basis to trust that enterprises and institutions will uphold their sustainability commitments, that corporate and governmental reports and communications on sustainability initiatives are substantiated, and that technology companies are tracking and selling user data properly.
* **Efficient Resource Management**: Optimizes resource allocation and usage through smart contracts and decentralized applications, reducing waste and improving efficiency.

By leveraging these capabilities, VeChain is at the forefront of integrating blockchain technology with sustainability initiatives, driving meaningful change on a global scale.

We imagine a future where our systems are interwoven in a way that creates trust, efficiency, and optimal decision making. Saving our planet is the most pressing challenge of our time.


# Core Concepts

Core concepts relating to blockchain systems and the VeChainThor blockchain.

A collection of articles to provide the reader with information on core blockchain concepts, specifically related to the VeChainThor blockchain.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Networks</td><td><a href="/pages/0LqHzv2JQuVkPUzBIP8w">/pages/0LqHzv2JQuVkPUzBIP8w</a></td></tr><tr><td align="center">Nodes</td><td><a href="/pages/GthyMt3K6uxt9ouO694C">/pages/GthyMt3K6uxt9ouO694C</a></td></tr><tr><td align="center">Blocks</td><td><a href="/pages/ml4WNQnMltmA5wwtrjSG">/pages/ml4WNQnMltmA5wwtrjSG</a></td></tr><tr><td align="center">Transactions</td><td><a href="/pages/msPjqh0u7Eg2IrBPdCdU">/pages/msPjqh0u7Eg2IrBPdCdU</a></td></tr><tr><td align="center">Block Explorers</td><td><a href="/pages/P6vWe8Rve7F6ugGXtxx8">/pages/P6vWe8Rve7F6ugGXtxx8</a></td></tr><tr><td align="center">Wallets</td><td><a href="/pages/dGjd3X0eLgpKzie4Ukvp">/pages/dGjd3X0eLgpKzie4Ukvp</a></td></tr><tr><td align="center">EVM Compatibility</td><td><a href="/pages/1lOq6Ht1iWzdydWlpJ15">/pages/1lOq6Ht1iWzdydWlpJ15</a></td></tr><tr><td align="center">Account Abstraction</td><td><a href="/pages/Bdx7mXjbZT70UuTcdSzI">/pages/Bdx7mXjbZT70UuTcdSzI</a></td></tr><tr><td align="center">Token Bound Accounts</td><td><a href="/pages/S9ZyCBwJYkFA5qSBTiad">/pages/S9ZyCBwJYkFA5qSBTiad</a></td></tr></tbody></table>


# Networks

A section dedicated to the VeChainThor network and supporting nodes.

This section introduces VeChain's networks and defines a list of public nodes to support connectivity to VeChainThor.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Thor Solo Node</td><td><a href="/pages/stIYQqz0KRqYZVhTO7cA">/pages/stIYQqz0KRqYZVhTO7cA</a></td></tr><tr><td align="center">Testnet</td><td><a href="/pages/lWVrsVnYSBKgFnIGTsl3">/pages/lWVrsVnYSBKgFnIGTsl3</a></td></tr><tr><td align="center">Mainnet</td><td><a href="/pages/ZisW44xaaMTUU3pz2IzC">/pages/ZisW44xaaMTUU3pz2IzC</a></td></tr></tbody></table>


# Thor Solo Node

An introduction to the Thor solo node and its purpose.

## What is Thor solo node?

Running a solo node refers to operating a new and independent blockchain locally. In other words, a solo node does not rely on other nodes for validation and verification of transactions and blocks. Instead, it performs all the necessary tasks on its own. Therefore, running a Thor solo node is essentially running the VeChainThor node software but not connecting it to other network participants in mainnet or testnet.

### When should I run a Thor solo node?

Developers are encouraged to run a Thor solo node when they are developing. Thor's nodes are useful in the sense you can initially validate the behaviour of smart contracts which will support decentralized applications (dApps) in a closed off environment. Initial tests on Thor solo nodes often don't need the entire history of the blockchain, and it makes setting up a test environment simpler and less time-consuming for the developer.

## What are the limitations to testing and validating on a Thor solo node?

As good as Thor solo nodes are for initial testing, we would always recommend that developers validate dApps on VeChainThor's testnet before going into production on mainnet. Thor solo nodes are great for validating the core functionality of smart contracts, but they do not simulate a real world peer-to-peer network. Here are some potential vulnerabilities that won't be discovered while using a Thor solo node:

* **Real world conditions:** Running a dApp on a Thor solo node means it is not exposed to real-world network conditions. In a decentralised network, various factors like latency, packet loss, and network congestion can affect the performance and reliability of the dApp.
* **Security vulnerabilities:** A Thor solo node setup does not adequately replicate the security measures and potential attack vectors that exist in a real-world network. Testnets provide an environment where you can identify and address security vulnerabilities.
* **Scalability & Performance:** Testing on a Thor solo node limits your ability to assess the scalability and performance of your dApp. In a decentralised network, the load is distributed among multiple nodes, and the performance of your dApp may vary depending on network size and activity.

{% hint style="info" %}
If you'd like to understand more about practically working with a Thor solo node, see [How to run a Thor Solo Node](/how-to-run-a-node/how-to-run-a-thor-solo-node)
{% endhint %}


# Testnet

Defining a blockchain testnet and it's purposes.

## What is a blockchain testnet?

A testnet is a specialized blockchain used as a testing environment where developers and users can experiment prior to deploying code to a production network (mainnet). Testnets are essentially separate blockchain networks that mirror the functionality of the mainnet but are isolated from it, with the additional difference that testnet assets are worth nothing.

Testnets in blockchain networks so usually have identical consensus mechanisms, network infrastructure, blockchain protocol and economic model.

## How can I access the testnet?

In order to interact with the testnet you either have to run a node yourself and send requests to the node to access the blockchain, or alternatively, you would need to identify a public node, who's job it is to add transactions to the network and return with data from the network, and direct requests there. There are several community run nodes as well as third party services who operate nodes.

{% hint style="info" %}
See a full list of the publicly available VeChainThor nodes in the Developer Resource article [Nodes](/how-to-run-a-node/nodes)
{% endhint %}

## What are some key characteristics of testnets?

**Tests Tokens:** As previously stated, the economic model should mirror mainnet. That means on the VeChain testnet, VET and VTHO will have identical max supply and generation/burn parameters. The major difference is that testnet tokens are never supposed to have real world value.

**Faucets:** A testnet faucet is essentially a wallet which holds vast amounts of testnet tokens. A developer/user can enter their wallet address and receive a specific amount of testnet funds to carry out tests. It is good practice and ethics to return testnet funds to the faucet once you have finished testing, so other developers can use the service.

{% hint style="info" %}
Need some testnet funds, use our faucet, <https://faucet.vecha.in>
{% endhint %}

{% hint style="info" %}
If you have testnet VET and need to convert some to testnet VTHO use <https://energy.outofgas.io/#/>
{% endhint %}

**Community support:** A key to a blockchain network functioning lies in incentivisation. Stakeholders, miners or nodes, support consensus and get rewarded for their time. Although the rewards paid to these stakeholders in the testnet should mirror mainnet, the rewards are worthless in a financial sense. Therefore, often the community support the maintenance of the testnet without directly receiving a reward. In the long run, the usability of a blockchain depends on having a well maintained testnet for builders.

## What can't I validate on testnet?

Deploying on testnet will validate much of your dApp, however there are some conditions testnet may not validate. An example of this may be network congestion, how does the dApp perform if transactions are not received at an expected time. The reality of mainnet is there will often be some congestion and transactions may take longer to propagate through the network.


# Mainnet

Public nodes which can be leveraged to interact with the VeChainThor blockchain.

## What is a blockchain mainnet?

A blockchain mainnet, also known as the production network, refers to the live, operational version of a blockchain network. It is the real, functioning blockchain network that is open to the public and used by participants to conduct actual transactions, store data, and execute smart contracts.

## How can I access the mainnet?

In order to interact with the mainnet you either have to run a node yourself and send requests to the node to access the blockchain, or alternatively, you would need to identify a public node, who's job it is to add transactions to the network and return with data from the network, and direct requests there. There are several community run nodes as well as third party services who operate nodes.

{% hint style="info" %}
See a full list of the publicly available VeChainThor nodes in the Developer Resource article [Nodes](/how-to-run-a-node/nodes)
{% endhint %}

{% hint style="info" %}
Interested in operating a public Thor node? Here's a link to the public repo <https://github.com/vechain/thor>, and a link to a tutorial on how to run a local Thor node [How to run a Thor Solo Node](/how-to-run-a-node/how-to-run-a-thor-solo-node).
{% endhint %}


# Nodes

Defining the different types of nodes who support the VeChain ecosystem.

## What are nodes in blockchain networks?

In blockchain networks, nodes are individual computers or devices that participate in maintaining the blockchain's network alive and secure by either

* validating
* storing
* relaying

transactions and blocks of data

As with any peer-to-peer network, nodes play a crucial role in the overall functioning and security of the network. The more nodes who contribute to the network, generally the more robust and secure the network will be.

## What are the different types of nodes that support the VeChainThor blockchain?

The VeChainThor network is supported by various different types of nodes, who all contribute to the ecosystem in a particular way.

### Validators (VeChainThor Validators)

Are responsible for maintaining consensus and producing blocks on the VeChain network (see [https://github.com/vechain/vechain-docs/blob/main/core-concepts/consensus/consensus.md](https://github.com/vechain/vechain-docs/blob/main/core-concepts/consensus/consensus.md "mention")). There are 101 active validators who are authorised to validate and propose new blocks. As a basic incentive, a validator gets the VTHO generation coming from their stake, plus 30% of the VTHO generated by the delegations (see the details of the latest [Tokenomics](https://github.com/vechain/VIPs/blob/master/vips/VIP-254.md)). Besides that, they receive the priority fees of the transactions in the blocks they produce, with the baseFee being burned (see [Transaction Fees](/core-concepts/transactions/transaction-fees)).

There's a big responsibility for validators, and so it's required that they:

* Stake 25M VETs as collateral
* Run and manage a server with the best possible level of performance and availability.

As the network will require 2/3+1 of the validators to reach consensus and finality.

### Economic & X-Nodes

Node programs have been shifted to StarGate (see [https://docs.stargate.vechain.org](https://docs.stargate.vechain.org "mention")). Both VeChain Economic and X-Node are encouraged to migrate to StarGate, where they will receive a new node of equivalent level, and become eligible of the additional rewards if they stake it.

{% hint style="info" %}
Please note only new nodes can participate in the network governance.
{% endhint %}

### Full Nodes

Full nodes can be deployed by anybody by running an instance of the VeChainThor node software, and they support the network in a few fundamental ways. Full nodes are configured to be interacted with and are constantly injecting new transactions into the network for AMs to build into blocks. Full nodes also enable people to query the VeChainThor blockchain and get the blockchain data from the chain to other systems to be processed. They also increase resiliency as they have a complete copy of the blockchain history stored.

{% hint style="info" %}
See a full list of the publicly available VeChainThor nodes in the Developer Resource article [https://github.com/vechain/vechain-docs/blob/main/core-concepts/how-to-run-a-node/nodes.md](https://github.com/vechain/vechain-docs/blob/main/core-concepts/how-to-run-a-node/nodes.md "mention")
{% endhint %}

{% hint style="info" %}
Interested in operating a public Thor node, here's a link to the public repo <https://github.com/vechain/thor>, and a link to a tutorial on how to run a local Thor node [https://github.com/vechain/vechain-docs/blob/main/core-concepts/how-to-run-a-node/how-to-run-a-thor-solo-node.md](https://github.com/vechain/vechain-docs/blob/main/core-concepts/how-to-run-a-node/how-to-run-a-thor-solo-node.md "mention").
{% endhint %}


# Node Rewards Programme

Economic and X-Node interactions with the official node rewards dApp.

{% hint style="info" %}
The original node rewards dApp is available at [app.rewards.vechain.org](https://app.rewards.vechain.org) Note: Rewards Programme enters sunset mode on 24th June 2025, replaced as per [Vechain Renaissance 2025](https://vechainofficial.medium.com/the-vechain-renaissance-2025-roadmap-evolving-greatness-d8eaf3cd5fea) As of 1st July 2025, rewards benefits will cease to be applied. As of 1st October 2025, rewards dApp will be withdrawn, along with Rewards API, Rewards Explorer, Rewards ThorPubAPI, and associated services.
{% endhint %}

In blockchain ecosystems the word node is a reserved word which is used to refer to a computer system which stores a copy of the blockchain transactions. In the VeChain ecosystem the word node can also be used to refer to a holder of a special non-fungible token (NFT) which is used to stake. They collectively can be called StarGate NFTs and were formerly called Economic and X-Nodes. Additional privileges are attributed to Economic and X-Node holders. StarGate NFTs can be staked to get VTHO rewards. Additionally, voting rights on VeChain governance proposals.

More about staking can be found in the [StarGate docs](https://docs.stargate.vechain.org).

{% hint style="info" %}
[vevote.vechain.org](https://vevote.vechain.org) VeChain governance proposal website.
{% endhint %}

StarGate Nodes have distinctive tiers which are determined by the following criteria:

* **Balance Requirement:** The quantity of VET to be held in your wallet for the acquisition, generation, and sustenance of your node.
* **Reward Multiplier:** The multiplier applied to the amount of VTHO generated by delegating your node.
* **Voting power:** Indicates the weight of your vote within VeChain's voting ecosystem, determined by the type of node you own.
* **Maturity Period:** The duration of time required for your node to upgrade from the current level to the next level.


# Blocks

Introduction to what a block represents and what block finality is.

## What is a block in a blockchain?

A block is a data structure that contains a set of transactions and other relevant information, linked together in a chain with preceding blocks through cryptographic hashes, forming the basis of a secure, transparent, and immutable blockchain network. A simple analogy would be to think of a blockchain as a notebook, where a transaction is a single line on a page of the notebook, think of a block as a page.

## How fast, on average, are blocks produced in the VeChain blockchain?

The VeChainThor blockchain is not only energy efficient to operate, it is also very fast. Blocks are created, on average, every ten seconds. The PoA consensus mechanism ensures that the blockchain is capable of producing blocks in a very efficient manner.

## What is block finality and how does it work?

Blockchains usually achieve probabilistic finality, meaning that the probability of a transaction being reversed decreases as more blocks are added to the network. With the introduction of [VIP-220](https://github.com/vechain/VIPs/blob/master/vips/VIP-220.md), VeChainThor's block finality mechanism grants qualified blocks an absolute safety guarantee. Once a block acquires it's finality, the consensus assures it cannot be modified, replaced or removed from the public ledger, even when the network encounters extremely asynchronous situations, such as being subject to large-scale network partitioning.


# Block Model

An introduction and overview of the VeChainThor blockchain block model.

VeChainThor defines a [block ](https://github.com/vechain/thor/blob/master/block/block.go)in Golang as:

```go
// block.go

type Block struct {
	header *Header
	txs    tx.Transactions
}

type Header struct {
	body headerBody
}

type headerBody struct {
	ParentID     thor.Bytes32
	Timestamp    uint64
	GasLimit     uint64
	Beneficiary  thor.Address
	GasUsed      uint64
	BaseFee      *big.Int
	TotalScore   uint64
	TxsRoot      thor.Bytes32
	StateRoot    thor.Bytes32
	ReceiptsRoot thor.Bytes32
	Signature    []byte
	Alpha        []byte
	COM          bool
}

type Transactions []*Transaction

```

Fields within the `headerBody`, $$\Gamma$$, are defined as:

* `ParentID` - the ID of the parent block
* `Timestamp` - the block time
* `GasLimit` - the maximum amount of gas that all transactions inside the block are allowed to consume
* `Beneficiary` - the address assigned by the block generator to receive reward (in VTHO)
* `GasUsed` - the actual amount of gas used within the block
* `BaseFee` - the mandatory minimum fee required for including a transaction within the block
* `TotalScore` - the accumulated witness number of the chain branch headed by the block. See [Consensus Deep Dive](/introduction-to-vechain/about-the-vechain-blockchain/consensus-deep-dive#meta-transaction-features-3) for more detail.
* `TxsRoot` - root hash of the transaction in the payload
* `StateRoot` - root hash for the global state after applying changes in this block
* `ReceiptsRoot` - hash of the transaction receipts trie
* `Signature` - signature of block builder
* `Alpha` - an input into the Verifiable Random Function (VRF)
* `COM` - a boolean indicating whether the packer votes commit

The block ID (`thor.Bytes32`) can be computed as:

$$BlkID = h \circ (hash(\Gamma - sig )\[4:]$$

where $$h$$ is the block number stored as a `uint32` and $$\[4:]$$ the operation that discards the first four bytes.


# Transactions

Learn about VeChain's novel transaction features.

## What is a transaction in VeChain?

A transaction, similar to any blockchain network, refers to an action or event that involves the transfer or modification of data within the blockchain.

By executing a transaction a blockchain can: transfer a digital token from one address to another; deploy a smart contract on the blockchain or trigger the execution of a smart contract.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Types</td><td><a href="https://github.com/vechain/vechain-docs/blob/main/core-concepts/transactions/transaction-types.md">https://github.com/vechain/vechain-docs/blob/main/core-concepts/transactions/transaction-types.md</a></td></tr><tr><td align="center">Model</td><td><a href="/pages/6UYWODJLNGxQ5sAuRZ49">/pages/6UYWODJLNGxQ5sAuRZ49</a></td></tr><tr><td align="center">Fees</td><td><a href="/pages/yz4FHhqJM9582qcgDGVY">/pages/yz4FHhqJM9582qcgDGVY</a></td></tr><tr><td align="center">Calculation</td><td><a href="/pages/9E5DI98G5baCN5LiXrZ3">/pages/9E5DI98G5baCN5LiXrZ3</a></td></tr><tr><td align="center">Meta Features</td><td><a href="/pages/xnt16042cSswGos1fgrx">/pages/xnt16042cSswGos1fgrx</a></td></tr></tbody></table>


# Transaction Model

An introduction and overview of the VeChainThor blockchain transaction model.

VeChainThor defines a [transaction ](https://github.com/vechain/thor/blob/master/tx/transaction.go)in Golang as:

```go
// transaction.go

type Transaction struct {
	body body
}

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

Fields within the transaction `body`, $$\Omega$$ , are defined as:

* `ChainTag` – last byte of the genesis block ID which is used to identify a blockchain to prevent the cross-chain replay attack
* `BlockRef` - reference to a specific block
* `Expiration` – how long, in terms of the number of blocks, the transaction will be allowed to be mined in VeChainThor
* `Clauses` – an array of *Clause* objects each of which contains fields `To`, `Value` and `Data` to enable a single transaction to carry multiple tasks issued by the transaction sender
* `GasPriceCoef` – coefficient used to calculate the gas price for legacy transactions
* `Gas` – maximum amount of gas allowed to pay for the transaction
* `MaxFeePerGas` - the absolute maximum to pay per unit of gas
* `MaxPriorityFeePerGas` - the absolute maximum tip to pay per unit of gas directly to the proposer
* `DependsOn` – ID of the transaction on which the current transaction depends
* `Nonce` – a random number set by the wallet / user
* `Reserved` - *reserved* Object contains two fields: `Features` and `Unused`
  * `Feature` as 32-bit unsigned integer and default set as `0`.For Designated Gas Payer (VIP-191) must be set as `1`
  * `Unused` an array of reserved field for backward compatibility, it **MUST** be set as an empty array for now otherwise the transaction will be considered invalid
* `Signature` - transaction signature, $$sig = sign(hash(rlp\lbrace\Omega - sig \rbrace), sk))$$, where $$sk$$ is the transaction sender's private key

{% hint style="info" %}
Refer to the [Meta Transaction Features](/core-concepts/transactions/meta-transaction-features) section for more detail on the unique aspects of transactions within the VeChainThor blockchain when compared to other blockchains.
{% endhint %}


# Transaction Fees

An introduction to transaction fees and why they are essential to all blockchains.

## Why do I need to pay fees for transactions?

Transaction fees for blockchain transactions are analogous to bank fees for bank transactions. All open, public blockchains will have one thing in common, a user will pay a fee in order to send a transaction. The main reason for is to give some incentive to the actors who add transactions to the blockchain. These actors are known as Validators, who operates a blockchain node of VeChainThor.

## How do transaction fees differ to banking fees?

There are several ways that blockchain fees differ to the fees traditional banking institutions charge for payments:

**Fee Calculation:** In blockchain networks, transaction fees are generally calculated based on the size of the transaction (in bytes), the type of transaction, the network congestion and the priority of the transaction. Whereas, traditional banking fees vary depending on the specific banking institution, the account type and what services were rendered by the bank to complete the transaction.

**Transparency:** Blockchain transaction fees are transparent and publicly visible on the blockchain. Users can check the current fee rates and observe the fees paid for specific transactions using blockchain explorers or wallets. This is not generally the case for banking transaction fees. Traditional banking fees are often not explicitly disclosed or transparent.

**Cross-Border Transactions:** Blockchain networks, by design, can facilitate cross-border transactions cheaper and faster than traditional banking institutions. The geographical location of the receiver is not taken into account during the calculation of the transactions fees. This is not the case for traditional banking fees, as cross-border payments require correspondent banking relationships, currency exchange fees, and wire transfer charges, all of which are passed to the customer in the form of transaction fees.

## What is fee delegation?

On the VeChainThor blockchain, a user is able to delegate the payment of the transaction fee to a separate entity. This powerful feature sets VeChain apart from other blockchains as a truly enterprise focused blockchain ecosystem. Removing the need to pay for a fee significantly reduces the barriers to entry for a user to use decentralized applications (dApps) that are built on the VeChainThor blockchain.

{% hint style="info" %}
Want to learn more about how fee delegation works under the hood, skip to the [Fee Delegation](/core-concepts/transactions/meta-transaction-features/fee-delegation) section.
{% endhint %}


# Transaction Calculation

The math behind gas fee calculation on the VeChainThor blockchain.

## What is gas? <a href="#intrinsic-gas-calculation" id="intrinsic-gas-calculation"></a>

Blockchain networks often refer to transaction fees as gas. Gas refers to the unit that measures the amount of computation effort required to execute operations on the blockchain network. This is a fee that is paid by the transaction sender and received by the blockchain network validator.

## Intrinsic Gas Calculation <a href="#intrinsic-gas-calculation" id="intrinsic-gas-calculation"></a>

The VeChainThor blockchain transaction model is capable of containing clauses which allows a single transaction to carry out multiple tasks. Therefore, the total gas cost of the transaction needs to include all the clauses gas costs in the transaction.

The total gas, $$g\_{total}$$, required for a transaction can be computed as:

$$g\_{total} = g0 + \sum\_i(g\_{type}^i+g\_{data}^i+g\_{vm}^i)$$

* where $$g\_0 = 5,000$$
* There are two types of $$g\_{type}$$
  * Regular transaction : 16,000
  * Contract creation : 48,000
* $$g\_{data}^i = 4 \cdot n\_z^i + 68 \cdot n\_{nz}^i$$
  * $$n\_z^i$$ is the number of bytes equal to zero within the data in the $$i^{th}$$ clause and $$n\_{nz}^i$$ the number of bytes not equal to zero
* $$g\_{vm}^i$$ is the gas cost returned by the virtual machine for executing the $$i^{th}$$ clause.

## Transaction Types

With the introduction of typed transactions, see [VIP-252](https://github.com/vechain/VIPs/blob/master/vips/VIP-252.md), the VeChainThor blockchain has become more extensible and forward compatible by enabling support for the introduction of new transaction types while ensuring backward compatibility with existing transactions. Currently there are two types of transaction on the VeChainThor blockchain. Transactions with a starting byte in the range \[`0x7f`, `0xfe`] are considered legacy transactions, which use the transaction format that existed before typed transactions. Dynamic fee transactions with a type `0x51` are dynamic fee transactions that are introduced with [VIP-251](https://github.com/vechain/VIPs/blob/master/vips/VIP-251.md). Both transactions has separate pricing mechanisms.

### Dynamic Fee Transactions

The dynamic fee transaction introduces a fluctuating base fee that is burned and a user-set priority fee that is paid directly to the proposer. This transaction model enhances network security and user experience by transitioning from a fixed-fee model to a dynamic fee model, adjusting fees based on network congestion.

Dynamic Fee Transactions don't specify `gasPrice` and instead use an in-protocol dynamically changing `baseFee` per gas. At each block, the base fee per gas is adjusted to address network congestion as measured by a gas target, see [VIP-251](https://github.com/vechain/VIPs/blob/master/vips/VIP-251.md) for more details. Dynamic Fee Transactions include a `maxPriorityFeePerGas` which specifies the maximum fee that a user is willing to pay per gas above the base fee in order to get their transaction prioritized; and a `maxFeePerGas` which specifies the absolute maximum a user is willing to pay per unit of gas, this is the sum of the `baseFee` and the `maxPriorityFeePerGas`.

A Dynamic Fee Transaction always pays the base fee of the block it's included in, and it pays a priority fee as priced by `maxPriorityFeePerGas` or if the base fee per gas plus `maxPriorityFeePerGas` exceeds `maxFeePerGas` it pays a priority fee as priced by `maxFeePerGas` minus the base fee per gas. Any unused portion is returned to the user. The base fee is burned, and the priority fee is paid to the miner that included the transaction. A transaction's priority fee per gas incentivizes validators to include the transaction over other transactions with lower priority fees per gas.

### Legacy Transactions

The legacy transaction model uses a fixed-fee model where the user sets a `gasPrice` that they are willing to pay. Transactions with a type \[`0xc0`, `0xfe`] are legacy transactions that use the transaction format that existed before typed transactions were introduced with [VIP-252](https://github.com/vechain/VIPs/blob/master/vips/VIP-252.md).

#### Proof of Work <a href="#proof-of-work" id="proof-of-work"></a>

The VeChainThor blockchain allows for transaction-level proof of work (PoW) on legacy transactions and converts the proved work into extra gas price that will be used by the system to generate more reward to the block generator, the Authority Masternode, that validates the transaction. In other words, users can utilize their local computational power to make their transactions more likely to be included in a new block.

In particular, the computational work can be proved through fields `Nonce` and `BlockRef` in the transaction model. Let $$n$$ and $$g$$ represent the values of the transaction fields `Nonce` and `Gas`, respectively. We use $$b$$ to denote the number of the block indexed by transaction field `BlockRef` and $$h$$ the number of the block that includes the transaction. Let $$\Omega$$ denote the transaction without fields `Nonce` and `Signature`, $$S$$ the transaction sender's account address, $$P$$ the base gas price, $$H$$ the hash function and $$E$$ the recursive length prefix (RLP) encoding function.

The PoW, $$w$$, is defined as:

$$w = min(2^{64}-1, \frac {{2^{256}-1}}{H(H(E(\Omega \parallel S))\parallel n)})$$

The extra gas price, $$\Delta$$, is computed as:

$$\Delta P = P\_0(\frac1{g}min\[g,\frac w{10^3}(\frac 1{1.04})^\frac {h-1}{3600\cdot24\cdot3}])$$

with the following constraint

$$\mid h - h\_0 \mid \leq 30$$

The VTHO reward for packing the transaction into a new block is computed as:

$$r = \frac3{10}g^\*(P\_0(1+\phi) + \Delta P)$$

where $$\phi \in \[0,1]$$ is the gas price coefficient and $$g^\*$$ the actual amount of gas used for executing the transaction.

From the above equations, we know that

1. Since $$h\_0$$ is a valid block number, `BlockRef` must refer to an existing block, that is, it's value must equal the first four bytes of an existing block ID;
2. The transaction must be packed into a block within the period of 30 blocks after block $$b$$, or otherwise, the PoW would not be recognized by the system;
3. The extra gas price $$\Delta P$$ can not be greater than base gas price P.

#### Total Gas Price <a href="#total-gas-price" id="total-gas-price"></a>

The total gas price for the a legacy transaction sender is computed as:

$$g^{total} = g^{base} + g^{base} \frac\phi{255}$$

and the total price for block generators as

$$g^{total} = g^{base} + g^{base} \frac\phi{255} + \Delta P$$

Where $$g^{base}$$ is the gas used by the transaction and $$\phi$$ is the value of field `GasPriceCoef`(a value between **0-255**) and $$\Delta P$$ the extra gas price converted from the proven local computational work.

It can be seen that the gas price used to calculate the transaction cost depends solely on the input gas-price coefficient while the reward for packing the transaction into a block varies due to the transaction-level proof-of-work mechanism.


# Meta Transaction Features

Overview of transaction features.

Meta-transaction features native to the VeChainThor blockchain network make the development more user-friendly for enterprise adoption.

* **Transaction uniqueness:** Every blockchain must have a way to uniquely identify each transaction otherwise it would be vulnerable to a transaction replay attack. VeChain has implemented a novel approach to transaction uniqueness.
* **Controllable transaction lifecycle:** With the BlockRef and Expiration fields within the transaction model, users can set the time when a transaction is processed or expired if it has not yet been included in a block.
* **Clauses (Multi-Task Transaction):** Clauses are an additional data structure within the VeChainThor transaction model which enables a transaction to carry multiple payloads within a single transaction.
* **Fee delegation:** VeChain supports two methods for implementing fee delegation Multi-party payment (MPP) and VIP-191 Designated gas payer both of which offer flexible transaction fee delegation schemes.
* **Transaction dependency:** Set dependencies on a transaction to ensure the execution order meets the business need, transactions that specify a dependency will not be executed until the required transaction is processed.


# Transaction Uniqueness

A unique transaction id for each transaction on the VeChainThor blockchain.

## Introduction

Every blockchain must have a way to uniquely identify each transaction otherwise it would be vulnerable to a transaction replay attack. For an unspent transaction output (UTXO) based blockchain like Bitcoin, transactions are linked and can be uniquely identified and verified by the associated spending history. However, such uniqueness no longer holds for an account-based blockchain like VeChain. For account-based blockchains we need to inject additional information into transactions to make them uniquely identifiable.

## VeChain's Approach to Transaction Uniqueness

In the VeChainThor blockchain every transaction has a unique transaction ID, $$TxID$$, which is calculated as:

$$TxID = hash(hash(rlp\lbrace\Omega - sig \rbrace)), signer\_address)$$

* $$\Omega$$ - represents a set that contains all fields within the transaction body.
* $$sig$$ - refers to the signature field in the transaction body.
* $$rlp$$ - recursive length prefix (RLP) encoding function.
* $$signer\_address$$ - refers to the sender's address.

The first element that contributes to transaction uniqueness is the presence of the `Nonce` within the transaction body, which is denoted by $$\Omega$$ in the formula above. The transaction `Nonce` is a 64-bit unsigned integer that is determined by the transaction sender.

The second element that contributes to transaction uniqueness is the use of hash functions. A hash function is any function that can be used to convert data of any size to a fixed size. The VeChainThor blockchain uses the blake2b hash function for hashing transaction data. So given a single transaction two hashes are computed. The first hash is of the RLP of the encoded transaction data without the signature, denoted by $$hash(rlp\lbrace\Omega - sig \rbrace)$$. The second hash takes the output of the previous hash concatenated with the sender's account address, $$signer\_address$$. The result of this second hash function is 256-bits long and is used as the $$TxID$$ which uniquely identifies the given transaction on the VeChainThor blockchain. Note that the calculation of the $$TxID$$ does not require a private key to sign the transaction.

When validating a given transaction, VeChainThor computes the $$TxID$$ and checks whether it has been used before. For any two transactions, so long as both transactions have a field in $$\Omega - sig$$ with different values, their transaction IDs would be different. The first element that we introduced which contributes to transaction uniqueness, the `Nonce`, contributes to the transaction body, $$\Omega$$, being different for each transaction.

## Comparison to Ethereum

Ethereum's approach to transaction uniqueness is to add the `AccountNonce` field to each transaction and set a rule that a pending transaction can only be processed when its `AccountNonce` value equals the latest `Nonce` value of the account that sends the transaction. Where the `Nonce` value is the number of transactions the account has sent so far. So in Ethereum a transaction is uniquely identifiable by combining the `AccountNonce` and the sender's account address.

The major downside of this approach is the limitation it places on the sender. Within this design transactions sent from the same account are forced to adhere to a transaction order based on the `Nonce` value of the transaction. An account with multiple transactions will have only one transaction processed at a time, the transaction which has a `Nonce` value the same as the `AccountNonce`. All other transactions sent by this account will be in a pending state waiting until the transaction `Nonce` equals the `AccountNonce`. Additionally, when a user has multiple pending transactions within an account and wants to send a new transaction, the user runs the risk of having the new transaction stuck in the transaction pool if any of the pending transactions fail. Overall, this is a poor user experience with the user occasionally having to resubmit transactions and overwrite the transaction `Nonce` to "unblock" their account.

## Conclusion

The Ethereum approach to transaction uniqueness has introduced a restriction on the Ethereum blockchain in the form of synchronous transaction processing, for transactions sent from a single account. The same restriction does not apply to the VeChainThor blockchain and transaction processing is asynchronous, for transactions sent from a single account.

{% hint style="info" %}
This [article](https://medium.com/vechain-foundation/what-you-might-not-know-about-vechainthor-yet-part-i-transaction-uniqueness-7a90146f2ace) provides additional information and a demonstration of transaction uniqueness on the VeChainThor blockchain.
{% endhint %}


# Controllable Transaction Lifecycle

Configure your transaction lifecycle on the VeChainThor blockchain.

## Introduction

Configure your transaction, which has not yet been included in a block, to be processed or expire at a set time by using the `BlockRef` and `Expiration` fields on the transaction model.

## BlockRef <a href="#blockref" id="blockref"></a>

`BlockRef` stores the reference to a particular block whose next block is the earliest block the current transaction can be included. In particular, the first four bytes of `BlockRef` contain the block height, while the second four bytes can be used to prove that the referred block is known before the transaction is assembled. If that is the case, the value of `BlockRef` should match the first eight bytes of the ID of the block at the required height.

## Expiration <a href="#expiration" id="expiration"></a>

`Expiration` stores a number that can be used, together with `BlockRef`, to specify when the transaction expires. Specifically, the sum of `Expiration` and the first four bytes of `BlockRef` defines the height of the last block that the transaction can be included.


# Clauses (Multi-Task Transaction)

A native approach to scale transaction throughput on the VeChainThor blockchain.

## Introduction <a href="#clauses" id="clauses"></a>

Most blockchain transactions models are limited to one payload and one recipient per transaction. The VeChainThor blockchain transaction model contains a native scaling solution called clauses which allows for the transfer of multiple payloads to different recipients.

## Clauses <a href="#clauses" id="clauses"></a>

Clauses are not transactions, but they do perform a similar function which is to deliver a payload on the VeChainThor blockchain. Clauses can be considered as an on-chain scaling mechanism which allows a user to send multiple payloads to different recipients in a single transaction. The `Clause` structure is defined in Golang as follows:

```go
type Clause struct {
	body clauseBody
}

type clauseBody struct {
	To    *thor.Address `rlp:"nil"`
	Value *big.Int
	Data  []byte
}
```

The three fields of a clause are:

* `To` – recipient’s address;
* `Value` – amount to be transferred to the recipient;
* `Data` – input data.

We then define `Clauses` as a `Clause` array in the transaction model to make it possible for a transaction to contain multiple tasks.

## Clause Attributes

Clauses have two interesting characteristics:

* Since clauses are included in a single transaction, their executions can be considered as atomic, meaning that, either they all succeed, or all fail.
* Clauses are processed one by one in the exact order defined in `Clauses`.

## Conclusion

Clauses are a unique feature to the VeChainThor blockchain and allows for a transaction to deliver multiple payloads to different recipients. Clauses are a form of on-chain scaling which allows for transaction throughput on the VeChainThor blockchain. When measuring the overall activity of the VeChainThor blockchain we must include clauses in the measurement.

{% hint style="info" %}
This [article](https://mirei83.medium.com/howto-vechain-blockchain-part-4-8c1e363da00f) provides additional information and a demonstration of clauses on the VeChainThor blockchain.
{% endhint %}


# Fee Delegation

VeChain provides two approaches for fee delegation on the VeChainThor blockchain.

## Introduction <a href="#multi-party-payment-prototype" id="multi-party-payment-prototype"></a>

Fee delegation is a feature on the VeChainThor blockchain which enables the transaction sender to request another entity, a sponsor, to pay for the transaction fee on the sender's behalf. Fee delegation greatly improves the user experience, especially in the case of onboarding new users by removing the necessity of the user having to first acquire cryptocurrency assets before being able to interact on-chain.

The purpose of this document is to provide a high-level introduction to both fee delegation protocols and to compare and contrast them. Further detail is provided on both fee delegation protocols in subsequent documents.

{% hint style="info" %}
Additional detail and documentation is provided in the supplementary sections:

* [Multi-Party Payment (MPP)](/core-concepts/transactions/meta-transaction-features/fee-delegation/multi-party-payment-mpp)
* [Designated Gas Payer (VIP-191)](/core-concepts/transactions/meta-transaction-features/fee-delegation/designated-gas-payer-vip-191)
  {% endhint %}

## Fee Delegation Protocols <a href="#multi-party-payment-prototype" id="multi-party-payment-prototype"></a>

The VeChainThor blockchain offers two protocols for implementing fee delegation, multi-party payment (MPP) and designated gas payer (VIP-191). Both fee delegation protocols achieve the same goal of delegating the transaction fee from the transaction sender to a designated sponsor. The difference between both protocols is the implementation and the use cases.

## Multi-Party Payment (MPP) <a href="#multi-party-payment-prototype" id="multi-party-payment-prototype"></a>

MPP is a native protocol on the VeChainThor blockchain. MPP enables the sender of a transaction to request that a sponsor or the receiver of the transaction pays the transaction fee on the senders' behalf. MPP is a fee delegation approach which is implemented on the smart contract level. This means that data must be written on-chain, which comes at a cost. It is more cost-effective to use the MPP protocol for frequent interactions between users and a decentralized application (dApp). An example of MPP implementation could be a marketplace or game which has opted to pay for all users transaction fees.

## Designated Gas Payer (VIP-191) <a href="#designated-gas-payer-vip191" id="designated-gas-payer-vip191"></a>

The designated gas payer is a standard which has been implemented on the VeChainThor blockchain, through VIP-191, which extends the MPP functionality in a more flexible way. VIP-191, allows a transaction sender to seek for an arbitrary party to pay the transaction fee on the sender's behalf. An example of VIP-191 implementation could be to implement a transaction fee sponsor for users that are performing a particular action such as minting an NFT at an event or awarding the highest points scorer on a game with sponsored transactions.

## Conclusion

Both fee delegation protocols achieve a common goal of allowing a transaction sender to delegate the transaction fee to a sponsor. However, both protocols are implemented in different ways.

The MPP implementation is at a smart contract level and thus comes with a cost. Including MPP within a smart contract will increase the size of the smart contract which will requires more space and thus will have a larger cost when it comes to deploying the smart contracts on the VeChainThor blockchain. The MPP approach to fee delegation is worthwhile if you intend to sponsor all user transactions for a set of smart contracts which form a decentralized application (dApp).

VIP-191 is a more flexible fee delegation approach which moves the fee delegation feature from the smart contract to the transaction itself. A user when sending a transaction can provide a sponsor who will sponsor the transaction fee on the sender's behalf. However, VIP-191 requires that both the transaction sender and sponsor are both online for the transaction to be completed. This is not the case for MPP as it is implemented at a smart contract level.

Both fee delegation protocols have their specific use cases, and it is up to the developer to determine which fee delegation protocol best suits their needs. Please read the following articles and subsequent documents for deeper information on both fee delegation protocols.

{% hint style="info" %}
Some useful articles to read on this subject include:

* [This MPP article](https://peter-zhou.medium.com/what-you-might-not-know-about-vechainthor-yet-part-iii-transaction-fee-delegation-vip-191-4ee71d690f1b)
* [This VIP-191 article](https://blog.vechain.energy/how-to-setup-fee-delegation-for-vechain-9ac9fef31455)
  {% endhint %}


# Multi-Party Payment (MPP)

The native VeChainThor fee delegation protocol.

## Introduction <a href="#multi-party-payment-prototype-2" id="multi-party-payment-prototype-2"></a>

MPP is a native protocol on the VeChainThor blockchain. MPP enables the sender of a transaction to request that the sponsor or receiver of the transaction pays the transaction fee on the senders' behalf. MPP is a fee delegation approach which is implemented on the smart contract level. This means that data must be written on-chain, which comes at a cost. It is more cost-effective to use the MPP protocol for frequent interactions between users and a decentralized application (dApp). An example of MPP implementation could be a marketplace or game which has opted to pay for all users transaction fees.

## Description and Flow

In practice, a dApp is most likely comprised of multiple smart contracts deployed on the VeChainThor blockchain. With MPP, a dApp owner can register its users' accounts as the user of the smart contracts such that all legitimate transactions from the dApp users can be paid by the smart contract owner. In this way, people can use the dApp almost in the same way they use other apps without dealing with crypto. Moreover, the owner can set up a single account to sponsor all the smart contracts which together make the dApp, which makes the maintenance a lot easier.

Before we continue lets define some entities and terminology that we will use as we continue our journey of understanding the MPP protocol:

* sender - account that signs the transaction;
* recipient - account to which the transaction is sent;
* sponsor - account that sponsors the recipient to pay for the transaction fee;
* user - VeChainThor allows any account to register other accounts as its users and conditionally pay for the cost of the transactions sent them;
* credit - available VTHO for paying for transaction cost for a particular user of a particular account.

<figure><img src="/files/AqVWhrUPj1kYlDOffdqQ" alt=""><figcaption><p>MPP fee delegation flow</p></figcaption></figure>

The above figure shows the decision-making flow within MPP. When it comes to the question of who pays for the transaction fees, the protocol first checks if the sender of the transaction is on the list of users and whether the contract being interacted with has a sponsor associated with the recipient. The protocol then tries to deduct the transaction fee from the corresponding account.

As an example, let's assume there is a marketplace which has enabled MPP and a user is making a purchase. The route of who is going to pay the transaction fee is such. If the user is on the list of user accounts whose fees can be delegated through MPP and the marketplace has a fee delegation sponsor in place, the protocol will first try to deduct the transaction fee from the sponsor’s balance, if it fails, from the recipient's balance, the marketplace in this instance, and if it fails again, from the sender’s balance.

## Credit Plan <a href="#credit-plan" id="credit-plan"></a>

To prevent MPP from being abused by malicious users, the owner of a smart contract can set a credit plan for the smart contract to set up rules on how to pay for a sender's transaction fee. A credit plan can be defined as:

```go
type creditPlan struct {
	Credit       *big.Int
	RecoveryRate *big.Int
}
```

Where `RecoveryRate` is the amount of VTHO (in Wei) accumulated per block to pay for transactions for each user and `Credit` is the maximum amount of VTHO (in Wei) that can be accumulated.

When the system checks whether an account's user has a sufficient amount of credit to pay for the transaction, it calculates the available credit as:

$$c = min(C, C - c\_{used} + r \cdot max(0,h-h\_0))$$

where $$C$$ denotes `Credit`, $$r$$`RecoverRate`, $$h$$ the current block height, $$h\_0$$ the block height when the user used credit last time and $$c\_{used}$$ the amount of credit consumed after the user's last transaction is paid by the account. Note that $$C - c\_{used}$$ is the remaining credit after the last transaction is paid.

## Master Account <a href="#master-account" id="master-account"></a>

In VeChainThor, we introduce the concept of the master account to make it easier for dApp owners to user MPP and manage their dApps. Every account, including a smart contract, can have a master account which is allowed by the system to register / remove users, set a credit plan and select the active sponsor for an account. Note that the account that deploys a smart contract becomes the master of the contract by default. A normal account can also set it's master by calling the function `setMaster` implemented in the built-in contract `Prototype`.

In practice, a dApp is often comprised of multiple smart contracts and not just a single smart contract. Each smart contract may have its own users and be sponsored by multiple sponsors. Managing these sponsor accounts suddenly becomes a challenging task for the dApp owner. With the master mechanism and built-in contract `Prototype`, the dApp owner does not have to implement anything on the contract code level to use MPP. The dApp owner can use a single master to manage all the contracts by calling functions of the smart contract `Prototype`.

## MPP Implementation <a href="#mpp-implementation" id="mpp-implementation"></a>

The multi-party payment protocol is implemented by the built-in smart contract `Prototype` deployed at `0x000000000000000000000050726f746f74797065` in the genesis block of the VeChainThor blockchain.

{% hint style="info" %}
The MPP implementation is available here [Built-in Contracts](/developer-resources/built-in-contracts#prototype-sol)
{% endhint %}

### **Functions related to user**

`isUser`

Check whether an account is a registered user of another account.

Input:

* `address _self`: account address
* `address _user`: *User* address

Return:

* `true` if `_user` is a *User* of `_self` or `false` otherwise

***

`addUser` / `removeUser`

Add / remove a user for an account. The transaction sender has to be the account itself or its current master.

Input:

* `address _self`: account address
* `address _user`: *User* address

### **Functions related to the credit plan**

`creditPlan`

Get the credit plan associated with an account.

Input:

* `address _self`: account address

Return:

* `uint256 credit`: maximum amount of credit (VTHO in wei) allowed for each user of the account
* `uint256 recoveryRate`: amount of credit (VTHO in wei) generated per block for each user of the account

***

`setCreditPlan`

Set a credit plan for an account. The transaction sender has to be either the account itself and its current master.

Input:

* `uint256 credit`: maximum amount of credit (VTHO in wei) allowed for each user of the account
* `uint256 recoveryRate`: amount of credit (VTHO in wei) generated per block for each user of the account

***

`userCredit`

Get the available credit for a particular user of an account.

Input:

* `address _self`: account address
* `address _user`: user address

Return:

* `uint256`: available credit (VTHO in wei) for the user

### **Functions related to master**

`master`

Get the master address of the given account address.

Input:

* `address _self`: account address

Return:

* `address`: address of the master of `_self`.

***

`setMaster`

Set the master for a particular account. The transaction sender has to be either the account itself or its current master.

Input:

* `address _self`: account address
* `address _newMaster`: address of the new master of `_self`

### **Functions related to sponsor**

`sponsor` / `unsponsor`

Sponsor / unsponsor an account. The transaction sender has to be the sponsor account.

Input:

* `address _self`: address of the account to be sponsored / unsponsored

***

`isSponsor`

Check whether an input account is a sponsor of another account.

Input:

* `address _self`: account address
* `address _sponsor`: sponsor address

Return:

* `true` if `_sponsor` is a sponsor of `_self`

***

`selectSponsor`

Select a sponsor. The transaction sender has to be either the sponsored account or its master.

Input:

* `address _self`: account address
* `address _sponsor`: sponsor address

***

`currentSponsor`

Get the current active sponsor.

Input:

* `address _self`: account address

Return:

* `address`: address of the current active sponsor of `_self`.


# Designated Gas Payer (VIP-191)

An extension of MPP which offers a more flexible version of fee delegation.

## Introduction <a href="#designated-gas-payer-vip191-2" id="designated-gas-payer-vip191-2"></a>

The designated gas payer is a standard which has been implemented on the VeChainThor blockchain, through VIP-191, which extends the MPP functionality in a more flexible way. VIP-191, allows a transaction sender to seek for an arbitrary party, the gas payer, to pay the transaction fee on the sender's behalf. An example of VIP-191 implementation could be to implement a transaction fee gas payer for users that are performing a particular action such as minting an NFT at an event or awarding the highest points scorer on a game with sponsored transactions.

{% hint style="info" %}
See [here](https://github.com/vechain/VIPs/blob/master/vips/VIP-191.md) for the VIP documentation and implementation relating to VIP-191.
{% endhint %}

## Description and Flow

The protocol requires that both the transaction sender and the fee delegation gas payer put their digital signatures in the transaction. In order for the fee delegation to be activated the sender needs to opt into using VIP-191. Once the transaction is accepted and executed, the transaction fee will be deducted from the gas payer's VTHO balance.

Before we continue let's define some entities and terminology that we will use as we continue our journey of understanding the VIP-191 standard:

* client - account that signs the transaction;
* gas payer - account that acts as the gas payer of the transaction fee;
* blockchain - the VeChainThor blockchain;

{% @mermaid/diagram content="sequenceDiagram
Sender->>Gas Payer: sends unsigned transaction and sender address
Gas Payer-->>Gas Payer: checks elegibility
Gas Payer-->>Gas Payer: hashes the transaction with sender's address
Gas Payer-->>Gas Payer: signs the hash obtained
Gas Payer-->>Sender: sends Gas Payer's signature
Sender->>Sender: creates signature
Sender->>Sender: appends own and Gas Payer's signatures to the transaction
Sender->>Blockchain: submits the transaction
Blockchain-->>Sender: confirms or rejects the transaction" %}

The above figure shows the decision-making flow within VIP-191. When it comes to the question of who pays for the transaction fees, first the client will send an unsigned transaction to the gas payer which will determine if the sender is permitted to avail of the gas payer's VTHO sponsorship. Gas payers are intended to be configurable to keep a gas payer's use under some rules, see the [VIP-191 standard](https://github.com/vechain/VIPs/blob/master/vips/VIP-191.md#example-usage) for further implementation detail. If the sender's transaction meets the gas payer's criteria, a signature will be returned to the sender who will then add the gas payer's signature and the sender's signature to the transaction. The sender will take care to submit the transaction to the blockchain and the fee will be paid by the gas payer.

As an example, let's assume there is a marketplace which has enabled VIP-191 and a user is making a purchase. The route of who is going to pay the transaction fee is such. If the user is on the list of user accounts whose fees can be delegated through the marketplace VIP-191 gas payer and the marketplace gas payer has a sufficient VTHO balance and is online the transaction fee will be paid by the gas payer. Otherwise, if the gas payer is offline or the gas payer has insufficient VTHO balance the transaction will fail.

### Transaction Model Extension <a href="#tx-model-extension" id="tx-model-extension"></a>

The field `Reserved` in the transaction body structure has been redefined to be an object as shown below:

```go
type reserved struct {
	Features Features
	Unused   []rlp.RawValue
}
```

Within the structure, we define the field `Features` as 32-bit unsigned integer. We can think of it as a bitmap. Each bit marks the status (1 for on and 0 for off) of a particular feature. For VIP-191, the least significant bit is used.

Recall that VIP-191 requires two valid signatures to be included in the transaction. In practice, the transaction sender's signature is concatenated with the gas-payer's signature and assigned to the field `Signature` as usual. Moreover, the protocol requires the gas-payer to sign the $$TxID$$ which is a unique identifier of the transaction.

### Gas Payer Deciding Logic <a href="#gas-payer-deciding-logic" id="gas-payer-deciding-logic"></a>

The gas payer deciding logic brought by VIP-191 is added in the function `BuyGas` in the Go source file `THORDIR/runtime/resolved_tx.go`.

```go
if r.Delegator != nil {
	if energy.Sub(*r.Delegator, prepaid) {
		return baseGasPrice, gasPrice, *r.Delegator, func(rgas uint64) { doReturnGas(rgas) }, nil
	}
	return nil, nil, thor.Address{}, nil, errors.New("insufficient energy")
}
```

It can be seen that the system first checks whether there is a designated gas payer (`r.Delegator`). If there is a gas payer, the system will try to deduct the transaction fee from the gas payer's VTHO balance. If the balance is too low, the system will stop processing the transaction and return an error. Otherwise, the system will mark the gas payer in the runtime context associated with the transaction and pass on the context to the code that executes individual clauses.

{% hint style="info" %}
Use the vechain.energy fee delegation service to easily create a gas payer, see [here](https://blog.vechain.energy/how-to-setup-fee-delegation-for-vechain-9ac9fef31455) for more information.
{% endhint %}

{% hint style="info" %}
A useful article with a demo implementation is available [here](https://peter-zhou.medium.com/what-you-might-not-know-about-vechainthor-yet-part-iii-transaction-fee-delegation-vip-191-4ee71d690f1b).
{% endhint %}


# Transaction Dependency

Enforce a transaction order on the VeChainThor blockchain.

## Introduction

Set dependencies on your transactions to ensure the execution order meets your business needs. Transactions that specify a dependency with the`DependOn` field in the transaction model will not be executed until the required transaction is processed.

## DependsOn <a href="#dependson" id="dependson"></a>

`DependsOn` stores the ID of the transaction on which the current transaction depends. In other words, the current transaction cannot be processed without the success of the transaction referred by `DependsOn`. Here by “success”, we mean that the referred transaction has been executed without state reversion.

## Implementation

The validation logic below ensures that the `DependsOn` field of a transaction is enforced when validating transactions within a block (see function verifyBlock in `$THORDIR/consensus/validator.go`).

```go
// check depended tx 
if dep := tx.DependsOn(); dep != nil { 
  found, reverted, err := findTx(*dep) 
  if err != nil { 
    return nil, nil, err 
  } 
  if !found { 
    return nil, nil, consensusError("tx dep broken") 
  } 
  if reverted { 
    return nil, nil, consensusError("tx dep reverted") 
  } 
}
```

Now let us have a close look at the code. According to its definition, `DependsOn` is a pointer pointing to the ID of the transaction it depends on. The first thing the code does is to get the value of the current transaction's `DependsOn` value via `dep := tx.DependsOn()`. If the field is set, it goes to check the status of the referred transaction using its $$TxID$$ through `found, reverted, err := findTx(*dep)`. The rest of the code checks whether the transaction exists and then whether it's been reverted. It rejects the current transaction if either check fails.

{% hint style="info" %}
This [article](https://peter-zhou.medium.com/what-you-might-not-know-about-vechainthor-yet-part-ii-forcible-transaction-dependency-ac3e98c4c955) provides additional information and a demonstration of `DependsOn` on the VeChainThor blockchain.
{% endhint %}


# Block Explorers

An essential tool which enhances the readability of the blockchain.

## What is a block explorer?

A block explorer is an online tool that enables you to search for real-time and historical information about a blockchain, including data related to blocks, transactions, addresses and more. It is commonplace for blockchain wallets to link to a reputable block explorer once a user transaction has been executed. This process provides a user with a second level of validation, where they can instantly validate the status of a transaction, executed from a wallet, on a trusted, independent tool.

It's not uncommon to have multiple tools satisfying the same requirement in blockchain ecosystems. In fact, as explorers play such a critical role in making blockchain data accessible to everyone, having multiple tools is actually a good thing.

## Why use a block explorer?

Block explorers are useful to many different types of actor for various reasons.

* Check the status of a transaction.
* Review previous transactions.
* View the contents of a wallet, such as transaction history or token balance.
* View the state of the blockchain via the current block height, transaction volume, transaction fees.
* View the market data associated with a token such as the circulating supply of a token, the max supply and market capitalization.

## VeChain block explorers?

### VeChainStats

Community project founded in 2017, VeChainStats is the leading blockchain data analytics platform on the VeChainThor Blockchain. VeChainStats provides the community and ecosystem an advanced data analytics platform and block explorer with real-time information regarding on-chain metrics over transactions, tokens, NFTs and more.

<https://vechainstats.com/>

### Insight

Insight is an open source, serverless VeChain explorer. It allows you to explore and search for blocks, transactions and accounts. Insight is a tool managed and deployed internally by VeChain.

<https://insight.vecha.in/#/main/>

### VeChain Explorer

VeChain Explorer is yet another tool which provides information on transactions, accounts, blocks and recent VeChainThor activity.

<https://explore.vechain.org/>


# Wallets

An intro and taxonomy of the different types of wallets.

### What are blockchain wallets?

A blockchain wallet, also known as a cryptocurrency wallet, is a software application or a physical hardware device used to store and manage cryptocurrency assets. It provides a way for individuals to interact with a blockchain network, enabling them to send, receive, and store digital assets such as VeChain, bitcoin, ethereum and many more.

### How does a blockchain wallet work?

A blockchain wallet consists of two primary components: a public address and a private key. The public address serves as the wallet's identifier and is used to receive funds. It is similar to a bank account number, and you can freely share it with others to receive payments or transactions.

On the other hand, the private key is a secret cryptographic code that grants ownership and access to the funds stored in the wallet. A private key is like the pin to your credit card, it should be kept secure and never shared with anyone, as it enables control over the associated cryptocurrency assets.

{% hint style="danger" %}
VeChain nor any of its affiliates will ever request you to share your private key.\
\
Never share your private key, this will most likely result in a loss of assets.
{% endhint %}

### What are the different types of wallets and what are their use cases?

Wallets come in a wide variety of different implementations, so it's important to research and choose a reputable wallet provider that aligns with your security preferences and cryptocurrency needs. Generally, a user makes a tradeoff between security and convenience when choosing a wallet.

In fact, its good practice to have multiple wallets for different use cases. We do this in the real world when dealing with fiat money, we have a wallet with some cash, a credit account in a bank to easily withdraw from and a savings account, which requires more effort and time to access funds. The below table defines some of the configurations a wallet can come in.

<table><thead><tr><th>Type</th><th width="326">Description</th><th width="139">Secure</th><th>Convenient</th></tr></thead><tbody><tr><td>Self-custody</td><td>Wallet provider doesn't manage PK.</td><td>High</td><td>Medium</td></tr><tr><td>Custodian</td><td>Manages PK for a user.</td><td>Low</td><td>High</td></tr><tr><td>Cold wallet</td><td>Wallet is not connected to the internet.</td><td>High</td><td>Low</td></tr><tr><td>Hot wallet</td><td>Wallet is connected to the internet.</td><td>Low</td><td>High</td></tr><tr><td>Web wallet</td><td>A wallet in a web browser.</td><td>Low</td><td>High</td></tr><tr><td>Software wallet</td><td>A downloadable application to use on laptop, phone or tablet.</td><td>Medium</td><td>Medium</td></tr><tr><td>Hardware wallet</td><td>A physical device designed to securely store PKs.</td><td>High</td><td>Low</td></tr><tr><td>Paper wallet</td><td>Printing a public address and PK on a physical piece of paper.</td><td>High</td><td>Low</td></tr></tbody></table>

**\*PK:** Private Key

The above entries are not mutually exclusive, for example, VeChain's new VeWorld wallet is a self-custody, hot, web wallet.

### What's a seed phrase and why should I never give it to anyone?

A seed phrase is private key encoded in a human-readable format which typically consists of 12 or 24 randomly chosen words from a predefined word list. The seed phrase is a backup mechanism that allows users to restore their wallet and access their funds by generating the private keys. These words are generated using cryptographic algorithms that ensure they are unique and provide sufficient entropy to secure the private keys.

It is crucial to keep the seed phrase secure and confidential because anyone who possesses it can regenerate the private keys and gain access to the associated funds, regardless of whether they are using the same wallet you currently use. It is recommended to store the seed phrase in a safe and offline location, such as writing it down on a piece of paper and keeping it in a secure place like a safe deposit box. Experts also advise storage in multiple locations, to protect yourself from a natural disaster destroying the paper the phrase is written on.

{% hint style="danger" %}
VeChain nor any of it's affliates will ever request you to share your seed phrase.\
\
Never share your seed phrase, this will most likely result in a loss of assets.
{% endhint %}

### VeChain Wallets

VeChain has a selection of wallets for you to use to securely and conveniently manage your VeChain based assets.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">VeWorld</td><td><a href="/pages/NdLwlzxTGlTzqkE7wmji">/pages/NdLwlzxTGlTzqkE7wmji</a></td></tr><tr><td align="center">Sync2</td><td><a href="/pages/Tguf1b0mde1d6WlH1HRo">/pages/Tguf1b0mde1d6WlH1HRo</a></td></tr><tr><td align="center">Sync</td><td><a href="/pages/cJkQHWzbwwMKtXGLfnbC">/pages/cJkQHWzbwwMKtXGLfnbC</a></td></tr></tbody></table>


# VeWorld

A browser plugin wallet

## **What is VeWorld?**

VeWorld is the latest VeChainThor browser plugin wallet that is designed to work with all mainstream web browsers and mobile devices.

## Installation Guide <a href="#install-sync-on-windows" id="install-sync-on-windows"></a>

### Supported Browsers <a href="#supported-browsers" id="supported-browsers"></a>

* Chrome
* Chromium
* Edge
* Brave
* Opera

### Download

You can download the latest desktop and mobile versions of VeWorld from the official VeWorld website, <https://www.veworld.net/>.


# User Guide

VeWorld user guide

The user guide is broken down into several sections:

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Setup</td><td><a href="/pages/3gQUMmbe4WIiXRwCOU1E">/pages/3gQUMmbe4WIiXRwCOU1E</a></td></tr><tr><td align="center">Wallet</td><td><a href="/pages/zagGpK6Mt71BgCZh0gnM">/pages/zagGpK6Mt71BgCZh0gnM</a></td></tr></tbody></table>


# Setup

How to setup VeWorld

## Install the application <a href="#install" id="install"></a>

{% tabs %}
{% tab title="Mobile" %}
You can install the app on your device by following these links:

* [VeWorld on Play Store](https://play.google.com/store/apps/details?id=org.vechain.veworld.app\&utm_source=docs_vechain\&utm_medium=website\&utm_campaign=vechain_communication)
* [VeWorld on Apple Store](https://apps.apple.com/us/app/veworld/id6446854569?campaign=docs_vechain)

If you cannot access a marketplace, you can find the latest APK on [veworld.com](https://www.veworld.com/)
{% endtab %}

{% tab title="Browser Extension" %}
For all Chromium-based Browsers, you can visit the [Chrome Web Store](https://chromewebstore.google.com/detail/veworld/ffondjhiilhjpmfakjbejdgbemolaaho?utm_source=docs_vechain\&utm_medium=website\&utm_campaign=vechain_communication)
{% endtab %}
{% endtabs %}


# Wallet

How to create, import and export wallets on VeWorld

## Create a new wallet

VeWorld is available as a mobile wallet and as a browser extension. The process to create a wallet is similar, the following sections will cover the differences

{% tabs %}
{% tab title="Mobile" %}

| Fresh Start                                                                                                                                                                                                                                      | Add a new one                                                                                                                                                                                                                                                                         |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>The first time you install the app you should:</p><ol><li>Tap the <strong>Get Started</strong> button</li><li>Follow the steps below</li><li>Protect your wallet by choosing your favorite method (FaceId, Fingerprint or password)</li></ol> | <p>If you already have a wallet on VeWorld, and you want to create a new one:</p><ol><li>From your dashboard tap the top-right wallet icon <img src="/files/gf9ZPdIBVLtKRzdFUsOe" alt=""></li><li>Tap the <strong>Add Wallet</strong> button</li><li>Follow the steps below</li></ol> |

**Steps for a new wallet:**

1. Tap the **Create new wallet** button
   {% endtab %}

{% tab title="Browser Extension" %}

| Fresh Start                                                                                                                                                                                                                                                      | Add a new one                                                                                                                                                                                                                                                                                                                          |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>The first time you install the extension you should:</p><ol><li>Follow and complete or skip the <em>welcome wizard</em></li><li>Type your favorite password twice and then click the <strong>CONFIRM</strong> button</li><li>Follow the steps below</li></ol> | <p>If you already have a wallet on VeWorld, and you want to create a new one:</p><ol><li>From your dashboard tap the top-right 3-dots icon <img src="/files/8M55LVRz6FDwsIIvicXT" alt=""></li><li>Select <strong>Manage Wallets</strong></li><li>Click the <strong>Add Wallet</strong> button</li><li>Follow the steps below</li></ol> |

**Steps for a new wallet:**

1. Click the **Create wallet** button
2. Follow and complete or skip the *security wizard*
3. Read and store your mnemonic
4. Mark the checkbox that states you saved your mnemonic safely
5. Pass the quiz with the 3 words from your mnemonic
6. Click the **GO TO HOMEPAGE** button
   {% endtab %}
   {% endtabs %}

{% hint style="warning" %}
Once the wallet is created, we recommend you backup it immediately.

The mnemonic words store all the information needed at any point in time to recover your wallet.

The mnemonic must be stored in a secure place, preferably offline. The mnemonic allows you to regain wallet access in a scenario where your device is lost, stolen, or unusable due to any reason.
{% endhint %}

## Import a wallet

### Import a local wallet

{% tabs %}
{% tab title="Mobile" %}

| Fresh Start                                                                                                                                                                                                                                      | Add a new one                                                                                                                                                                                                                                                                         |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>The first time you install the app you should:</p><ol><li>Tap the <strong>Get Started</strong> button</li><li>Follow the steps below</li><li>Protect your wallet by choosing your favorite method (FaceId, Fingerprint or password)</li></ol> | <p>If you already have a wallet on VeWorld, and you want to import a new one:</p><ol><li>From your dashboard tap the top-right wallet icon <img src="/files/gf9ZPdIBVLtKRzdFUsOe" alt=""></li><li>Tap the <strong>Add Wallet</strong> button</li><li>Follow the steps below</li></ol> |

Steps for importing a local wallet from **mnemonic**:

1. Tap the **Import Wallet** button
2. Tap **Local wallet**
3. Paste or type your saved mnemonic and then tap **VERIFY** button

Steps for importing a local wallet from **private key**:

1. Tap the **Import Wallet** button
2. Tap **Local wallet**
3. Paste your saved private key and then tap **VERIFY** button

Steps for importing a local wallet from a **keystore file**:

1. Tap the **Import Wallet** button
2. Tap **Local wallet**
3. Paste the content of your saved keystore file and then tap **VERIFY** button
   {% endtab %}

{% tab title="Browser Extension" %}

| Fresh Start                                                                                                                                                                                                                                                                                                                                               | Add a new one                                                                                                                                                                                                                                                                         |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>The first time you install the app you should:</p><ol><li>Follow and complete or skip the <em>welcome wizard</em></li><li>Type your favorite password twice and then click the <strong>CONFIRM</strong> button</li><li>Protect your wallet by choosing your favorite method (FaceId, Fingerprint or password)</li><li>Follow the steps below</li></ol> | <p>If you already have a wallet on VeWorld, and you want to create a new one:</p><ol><li>From your dashboard tap the top-right 3-dots icon <img src="/files/8M55LVRz6FDwsIIvicXT" alt=""></li><li>Tap the <strong>Add Wallet</strong> button</li><li>Follow the steps below</li></ol> |

Steps for importing a local wallet from **mnemonic**:

1. Click the **Import wallet** button
2. In the first section *Local Wallet* click the **Import Wallet** button
3. In the first section *Mnemonic* click the **Import from Mnemonic** button
4. Type or paste your mnemonic then click the **Verify** button
5. Type your wallet password

Steps for importing a local wallet from **private key**:

1. Click the **Import wallet** button
2. In the first section *Local Wallet* click the **Import Wallet** button
3. In the second section *Private Key or Keystore file* click the **Import from Private Key** button
4. Paste your privatekey then click the **Verify** button
5. Type your wallet password

Steps for importing a local wallet from **keystore file**:

1. Click the **Import wallet** button
2. In the first section *Local Wallet* click the **Import Wallet** button
3. In the second section *Private Key or Keystore file* click the **Import from keystore file** button
4. Upload your keystore file then click the **Decrypt** button
5. Type your wallet password
   {% endtab %}
   {% endtabs %}

### Import a Ledger wallet

{% tabs %}
{% tab title="Mobile" %}

| Fresh Start                                                                                                                                                                                                                                      | Add a new one                                                                                                                                                                                                                                                                         |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>The first time you install the app you should:</p><ol><li>Tap the <strong>Get Started</strong> button</li><li>Follow the steps below</li><li>Protect your wallet by choosing your favorite method (FaceId, Fingerprint or password)</li></ol> | <p>If you already have a wallet on VeWorld, and you want to import a new one:</p><ol><li>From your dashboard tap the top-right wallet icon <img src="/files/gf9ZPdIBVLtKRzdFUsOe" alt=""></li><li>Tap the <strong>Add Wallet</strong> button</li><li>Follow the steps below</li></ol> |

Steps for importing a Ledger wallet:

1. Tap the **Import Wallet** button
2. Tap the **Hardware Wallet** button
3. Select your Ledger, then tap the **Import** button
4. Follow the instructions and tap the **Continue** button
5. Select your desired Account, then tap the **Import** button
6. Tap the **GO TO YOUR WALLET** button
   {% endtab %}

{% tab title="Browser Extension" %}

| Fresh Start                                                                                                                                                                                                                                                                                                                                               | Add a new one                                                                                                                                                                                                                                                                         |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>The first time you install the app you should:</p><ol><li>Follow and complete or skip the <em>welcome wizard</em></li><li>Type your favorite password twice and then click the <strong>CONFIRM</strong> button</li><li>Protect your wallet by choosing your favorite method (FaceId, Fingerprint or password)</li><li>Follow the steps below</li></ol> | <p>If you already have a wallet on VeWorld, and you want to create a new one:</p><ol><li>From your dashboard tap the top-right 3-dots icon <img src="/files/8M55LVRz6FDwsIIvicXT" alt=""></li><li>Tap the <strong>Add Wallet</strong> button</li><li>Follow the steps below</li></ol> |

Steps for importing a Ledger wallet:

1. In the second section click the **Import wallet** button
2. In the second section *Hardware Wallet* click the **Import Wallet** button
3. Follow the instructions and click the **Ledger** button
4. Follow the instructions and click the **Continue** button
5. Select your desired account then click the **Add** button
   {% endtab %}
   {% endtabs %}

### Import an Observable wallet

{% tabs %}
{% tab title="Mobile" %}
Steps for importing an observable wallet:

1. From your dashboard tap the top-right wallet icon ![](/files/gf9ZPdIBVLtKRzdFUsOe)
2. Tap the **Add Wallet** button
3. Tap the **Observe Wallet** button
4. Tap **Local wallet**
5. Paste the desired address, then tap **IMPORT** button
   {% endtab %}

{% tab title="Browser Extension" %}
Not available yet on the Extension.
{% endtab %}
{% endtabs %}

## Export a wallet

{% tabs %}
{% tab title="Mobile" %}
Steps for exporting a local wallet:

1. Tap the bottom right icon ![](/files/dvNaVWxbQbExJnYuAUf1) to the **Settings** page
2. Tap **Privacy and Security** from the menu
3. Tap **Backup your mnemonic phrase**
4. Select the local wallet you want to export
5. Pass the authentication (fingerprint, faceid or password)
6. Paste or type your saved mnemonic and then tap **VERIFY** button
7. Read or copy to clipboard your mnemonic
   {% endtab %}

{% tab title="Browser Extension" %}
Steps for exporting a local wallet:

1. Click the bottom right icon ![](/files/dvNaVWxbQbExJnYuAUf1) to **Settings** page
2. Click **Privacy and Security** from menu
3. Click **Backup mnemonic**
4. Select the local wallet you want to export, then click the **Continue** button
5. Type your password
6. Read or copy to clipbaord your mnemonic
   {% endtab %}
   {% endtabs %}

## Manage your wallets

With VeWorld you can handle multiple wallets and multiple accounts.

{% hint style="info" %}
Acconts of the same wallet share the same mnemonic. Different wallets have different mnemonic.
{% endhint %}

Feel free to self-organize your wallets as you prefer.

{% tabs %}
{% tab title="Mobile" %}
Change the order of your wallets

1. From your dashboard tap the top-right wallet icon ![](/files/gf9ZPdIBVLtKRzdFUsOe)
2. Tap the icon order-change ![](/files/Azdz3rY2GSyXnYKDOq2o)
3. Move your wallets to your favorite order
4. Tap the **Save** button

Rename a wallet

* From your dashboard tap the top-right wallet icon ![](/files/gf9ZPdIBVLtKRzdFUsOe)
* Select the wallet by pressing the pencil icon
* Change the name of your wallet

Add an account to a wallet

* From your dashboard tap the top-right wallet icon ![](/files/gf9ZPdIBVLtKRzdFUsOe)
* Select the wallet
* Tap the **Add Account** button
* (optional) Rename it by tapping the name of the new account

Remove a wallet

* From your dashboard tap the top-right wallet icon ![](/files/gf9ZPdIBVLtKRzdFUsOe)
* Hold for a second the wallet you want to remove and swipe to the left
* Press the trash icon
* Confirm by tapping the **Remove Wallet** button
  {% endtab %}

{% tab title="Browser Extension" %}
Change the order of your wallets: not available on Extension.

Rename a wallet

* From your dashboard click the top-right wallet icon![](/files/8M55LVRz6FDwsIIvicXT)
* Click on **Manage Wallets**
* Click on the pencil icon of the wallet you want to change
* Type the new name, then click the **Save Changes** button

Add an account to a wallet

* From your dashboard click the top-right wallet icon![](/files/8M55LVRz6FDwsIIvicXT)
* Click on **Manage Wallets**
* Click the **Add Account** link close to the desired wallet
* (optional) Rename the account by clicking the pencil icon

Remove a wallet: not available on Extension
{% endtab %}
{% endtabs %}


# Signing

How to sign a transaction on VeWorld

## Content type <a href="#content-type" id="content-type"></a>

There are two major types of signing contents:

| Type        | Purpose                                       |
| ----------- | --------------------------------------------- |
| Transaction | **Create** / **Transfer** / **Contract Call** |
| Certificate | **Identification** / **Agreement**            |

## Create a Token Transaction

{% tabs %}
{% tab title="Mobile" %}
Steps for creating a transaction:

1. Go to Dashboard
2. Tap **Send** button
3. Choose the asset you would like to send (VET, VTHO or a custom token you own), then tap **Next** button
4. Select the amount (in FIAT or token unit), then tap **Next** button
5. Enter or select the address you want to send tokens, then tap **Next** button
6. Select the delegation model you want
7. Select the priority for this transaction. It will change the fee you are paying
8. Check the details, then tap **Confirm** button
9. Authenticate with your security method, and wait for the confirm screen. You may see a link to the block explorer for the transaction details.
   {% endtab %}

{% tab title="Browser Extension" %}
Steps for creating a transaction:

1. Go to Dashboard
2. Tap **Send** button
3. Choose the asset you would like to send (VET, VTHO or a custom token you own), then click **Next** button
4. Paste the address or vetdomain you want to send tokens to
5. Select the amount of tokens you want to send to, then click **Next** button
6. Select the delegation model you want, then click the **Sign & Send** button
7. Authenticate with your password, and wait for the confirm screen. You may see a link to the block explorer for the transaction details.
   {% endtab %}
   {% endtabs %}

## Create a NFT Transaction

{% tabs %}
{% tab title="Mobile" %}

1. Go to NFTs and choose the NFT you would like to send
2. Tap **Send** button
3. Enter or select the address you want to send tokens, then tap **Next** button
4. Select the delegation model you want
5. Select the priority for this transaction. It will change the fee you are paying
6. Check the details, then tap **Confirm** button
7. Authenticate with your security method, and wait for the confirm screen. You may see a link to the block explorer for the transaction details.
   {% endtab %}

{% tab title="Browser Extension" %}

1. Go to NFTs and choose the NFT you would like to send
2. Click **Send NFT** button
3. Paste or select the destination address, then click **Send NFT** button
4. Select the delegation model you want, then click the **Sign & Send** button
5. Authenticate with your password, and wait for the confirm screen. You may see a link to the block explorer for the transaction details.
   {% endtab %}
   {% endtabs %}

## How to sign a certificate

{% tabs %}
{% tab title="Mobile" %}

1. Go to the **Discovery section** and go to your desired DApp
2. Connect your VeWorld wallet
3. If it's the first time that you interact with that DApp, you'll be asked to sign a certificate
4. Select the account you want to connect with, then tap **Connect**
5. You can check the details, then click "Sign"
6. Authenticate with your security method, and you'll be redirect to the DApp
   {% endtab %}

{% tab title="Browser Extension" %}

1. Open in your browser your desired DApp
2. Connect your VeWorld wallet
3. If it's the first time that you interact with that DApp, you'll be asked to sign a certificate
4. You can check the details, then click "Sign"
   {% endtab %}
   {% endtabs %}

{% hint style="info" %}
Signing a certificate doesn't result in a transaction. Such operations are stored in your wallet history only. There will be no trace onchain so that you don't need to pay any gas fees to approve them.
{% endhint %}


# Activities

How to access your history

{% tabs %}
{% tab title="Mobile" %}
To see your history you should:

1. Go to your Dashboard
2. Tap the History button
3. You'll see a list of activies (some of them are onchain, some aren't)
4. Tap one of them to read more
5. In each details you'll see:
   * From and To Address
   * Datetime of creation
   * Value (which and how many tokens)
   * Transaction ID (you can also copy it in your clipboard)
   * Blocknumber
   * Network
   * Button to read details of that transaction in the Blockexplorer
     {% endtab %}

{% tab title="Browser Extension" %}
To see your history you should:

1. Go to your Dashboard
2. Click the History button
3. You'll see a list of activies (some of them are onchain, some aren't)
4. Click one of them to read more
5. In each details you'll see:
   * Activity type
   * Status
   * Transaction ID (you can also copy it in your clipboard)
   * Network
   * Finality
   * Datetime of creation
   * From and To Address
   * Value (which and how many tokens)
   * Button to read details of that transaction in the Blockexplorer
     {% endtab %}
     {% endtabs %}


# Settings

How to customize your wallet

{% tabs %}
{% tab title="Mobile" %}

#### General

**Conversion Currency**

You can choose among the supported FIAT currencies (EUR, USD)

**Currency Format**

You can choose how the fiat value of your assets appears in the wallet.

* **Comma:** Uses a comma as a separator for the decimal value (e.g., 9.999,99).
* **Dot:** Uses a dot as a separator for the decimal value (e.g., 9,999.99).
* **System:** Uses your device's system settings to automatically set the preference based on your region.

**Symbol Position**

You can choose where the €/$ symbol is displayed in relation to the fiat value of your assets.

* **Before amount:** The symbol appears before the amount (e.g., $9999).
* **After amount:** The symbol appears after the amount (e.g., 9999$).

**Theme**

You can anytime switch between the dark or light theme, or just use your device settings.

**App Language**

VeWorld is now a multi-language wallet and language preferences can be set in the general settings section.

### 🌍 Supported Languages

* 🇬🇧 English
* 🇯🇵 Japanese
* 🇻🇳 Vietnamese
* 🇩🇪 German
* 🇳🇱 Dutch
* 🇰🇷 Korean
* 🇮🇹 Italian
* 🇨🇳 Chinese
* 🇸🇪 Swedish
* 🇫🇷 French
* 🇹🇼 Taiwanese
* 🇪🇸 Spanish
* 🇹🇷 Turkish
* 🇮🇳 Hindi
* 🇵🇱 Polish
* 🇵🇹 Portuguese
* 🇷🇺 Russian

🚨 **Dev Alert**

To create a more immersive and consistent user experience, when opening a dApp from VeWorld mobile, we have implemented a way to provide the current language preference of VeWorld to the dApp. There are two ways to retrieve this information, depending on whether your app is **server-side rendered (SSR)** or **client-side rendered (CSR, non-SSR)**.

**Server side rendered (SSR) Apps**

If your application is SSR, you can obtain the language preference from the `Accept-Language` header. This will provide the current locale set in VeWorld.

**Client-Side Rendered (CSR) / Frontend Apps (Non-SSR)**

If your application its not SSR, to get access to the current language used in VeWorld you can do it simply using the **injected JavaScript property** that you can get it using window\.vechain.acceptLanguage.

**Reset**

You can hard reset your wallet, and clear all your local data. This action cannot be reverted.

{% hint style="warning" %}
If you are going to reset your wallet without your backups properly saved, you'll loose access to all your assets.
{% endhint %}

#### Transaction

**Default delegation**

You can select the default delegation for your transactions.

**Delegations URLs**

You can create a shortlist of delegation urls you could choose easily from.

#### Networks

**Select**

You can choose between Mainnet or Testnet. You could also use a custom node.

#### Contacts

You can manage a list of favourite contacts, to make the trasaction creation process easier.

#### Security and Privacy

**Security Method**

You can choose your favorite security method. Downgrading the level of security is not allowed.

**Backup mnemonic**

You can export a local wallet; your password will be required.

#### Connected Applications\*\*

You can see and manage the list of DApps you interacted with.

#### About VeWorld

Here you can see:

* the release number of your current version.
* the Official Website
* the privacy policy
* the help platform
  {% endtab %}

{% tab title="Browser Extension" %}

#### General

**Conversion Currency**

You can choose among the supported FIAT currencies (EUR, USD)

**Symbol Position**

You can choose where the €/$ symbol is displayed in relation to the fiat value of your assets.

* **Before amount:** The symbol appears before the amount (e.g., $9999).
* **After amount:** The symbol appears after the amount (e.g., 9999$).

**App Language**

VeWorld is now a multi-language wallet and language preferences can be set in the general settings section.

### 🌍 Supported Languages

* 🇬🇧 English
* 🇯🇵 Japanese
* 🇻🇳 Vietnamese
* 🇩🇪 German
* 🇳🇱 Dutch
* 🇰🇷 Korean
* 🇮🇹 Italian
* 🇨🇳 Chinese
* 🇸🇪 Swedish
* 🇫🇷 French
* 🇹🇼 Taiwanese
* 🇪🇸 Spanish
* 🇹🇷 Turkish
* 🇮🇳 Hindi
* 🇵🇱 Polish
* 🇵🇹 Portuguese
* 🇷🇺 Russian

**Hide tokens without balance**

If your balance of a selected token is zero, it won't get it displayed on the dashboard.

**Enable DEV mode**

You can execute transactions even when warnings would block you from doing so. A failing reason will be shown after the transaction fails.

**Theme**

You can anytime switch between the dark or light theme, or just use your device settings.

**State Logs**

State logs contain your public account addresses and sent transactions. You can download log file for diagnosis purposes.

**Reset**

You can hard reset your wallet, and clear all your local data. This action cannot be reverted.

{% hint style="warning" %}
If you are going to reset your wallet without your backups properly saved, you'll loose access to all your assets.
{% endhint %}

#### Transaction

**Default delegation**

You can select the default delegation for your transactions.

**Delegations URLs**

You can create a shortlist of delegation urls you could choose easily from.

#### Networks

**Select**

You can choose between Mainnet or Testnet. You could also use a custom node.

**Indicators**

Display an indicator when transacting on another network

**Conversion**

Show fiat exchange rates when on other networks

#### Contacts

You can manage a list of favourite contacts, to make the trasaction creation process easier.

#### Security and Privacy

**Password authorisation for transactions**

Require the extension password when performing transactions with local wallets

**Change Password**

You can change your local password

**Backup mnemonic**

You can export a local wallet; your password will be required.

**Analytics tracking**

You can allow or block the tracking of your wallet. No personal data are collected.

#### Connected Applications\*\*

You can see and manage the list of DApps you interacted with.

#### About VeWorld

Here you can see the release number of your current version.

#### Bug Report

You can open a ticket for an issue or suggestions.
{% endtab %}
{% endtabs %}


# FAQ

FAQ on VeWorld

The FAQ section was moved to the VeWorld support portal. If you landed here looking for help, and you don't find the answer to your problem, in the same portal you can submit a new ticket.

Visit [our customer support portal](https://support.veworld.com/support/home) .


# VeChain Kit

<figure><img src="https://2928565250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FS8udqSGhGctlwwL1kst7%2Fuploads%2Fyo0a3UnQQ2VmrpRT96iI%2Fvechain-kit-v2-shocase.png?alt=media&#x26;token=70942ad0-ab12-4831-8ebf-62a019df437d" alt=""><figcaption></figcaption></figure>

## Description

VeChain Kit is a comprehensive SDK designed to make building frontend applications on VeChain fast and straightforward.

## Repo

* GitHub: <https://github.com/vechain/vechain-kit>

## Package

* NPM Package: <https://www.npmjs.com/package/@vechain/vechain-kit>

## Key Features

* **Seamless Wallet Integration:** Support for VeWorld, WalletConnect, and social logins.
* **Developer-Friendly Hooks:** Easy-to-use React Hooks that let you read and write data on the VeChainThor blockchain.
* **Token Operations:** Send and swap tokens, check balances, manage VET domains, and more—all in one place.
* **Pre-Built UI Components:** Ready-to-use components (e.g., `TransactionModal`) to simplify wallet operations and enhance your users’ experience.

📚 For detailed documentation, visit our VeChain [Kit Docs](https://docs.vechainkit.vechain.org/)​​

{% hint style="warning" %}
Currently supports React and Next.js only
{% endhint %}

## Resources

* [​Live Demo​](https://vechainkit.vechain.org/)
* [Getting Started](https://docs.vechainkit.vechain.org/quickstart/installation)

## Troubleshooting

* [Troubleshooting](https://docs.vechainkit.vechain.org/vechain-kit/troubleshooting)
* Contact us on [Discord](https://discord.gg/wGkQnPpRVq)

{% hint style="info" %}
Are you still having problems?

* Open an issue on [Github](https://github.com/vechain/vechain-kit/issues)​
  {% endhint %}


# Sync2 (Legacy)

A mobile and browser plugin wallet

## **What is Sync2?**

Sync2 is a mobile and browser plugin wallet that is designed to work with all mainstream web browsers and mobile devices.

## Installation Guide <a href="#install-sync-on-windows" id="install-sync-on-windows"></a>

### Desktop System Requirements <a href="#system-requirement" id="system-requirement"></a>

* **Windows**: Windows 7 and later are supported, older operating systems are not supported (and do not work).
* **MacOS** : Minimum macOS version supported is macOS 10.10 (Yosemite). Native support for Apple Silicon (arm64) devices.
* **Linux** : Ubuntu 14.04 and newer/ Fedora 24 and newer/ Debian 8 and newer

### Download

You can download the latest desktop and mobile versions of Sync2 from the official Sync2 website, <https://sync.vecha.in/>.


# User Guide

Sync2 user guide

The user guide is broken down into several sections:

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Setup</td><td><a href="/pages/cnwTxxZ9WiNfdmJVtDdJ">/pages/cnwTxxZ9WiNfdmJVtDdJ</a></td></tr><tr><td align="center">Wallet</td><td><a href="/pages/JdeFAwWmKCGIaymRlFse">/pages/JdeFAwWmKCGIaymRlFse</a></td></tr><tr><td align="center">Signing</td><td><a href="/pages/1Yw5dpfPpbIX6KU7u0az">/pages/1Yw5dpfPpbIX6KU7u0az</a></td></tr><tr><td align="center">Activities</td><td><a href="/pages/Wa1OKAxTesXPgYbIzKw6">/pages/Wa1OKAxTesXPgYbIzKw6</a></td></tr><tr><td align="center">Settings</td><td><a href="/pages/hVOQX9fEgh7A0MniBjtl">/pages/hVOQX9fEgh7A0MniBjtl</a></td></tr></tbody></table>


# Setup

<figure><img src="/files/sjzADGrbbI8h8MM5NMRD" alt=""><figcaption></figcaption></figure>

## Create password <a href="#create-password" id="create-password"></a>

The password allows you to access Sync2 and unlock your wallet. If you forget the password, you will **not** be able to access Sync2. You will need to delete the app and restore the wallet.

## Back up wallet <a href="#back-up-wallet" id="back-up-wallet"></a>

Once the wallet is created, we recommend you back up the wallet immediately

The mnemonic words store all the information needed at any point in time to recover your wallet. Please back up your wallet once the wallet is created.

{% hint style="info" %}
The mnemonic must be stored in a secure place, preferably offline. The mnemonic allows you to regain wallet access in a scenario where your device is lost, stolen, or unusable due to any reason.
{% endhint %}


# Wallet

<figure><img src="/files/6gP6VNcCf0BnHoTAeqjr" alt=""><figcaption></figcaption></figure>

## Wallet list <a href="#wallet-list" id="wallet-list"></a>

All the wallets will be shown in <img src="/files/7GUklMCvyo1DvxxhE0dJ" alt="" data-size="line"> wallet list.

{% hint style="info" %}
If it is a Ledger wallet, you can identify the wallet by the presence of the <img src="/files/yJ4gRRnQQXgG3x3SznTA" alt="" data-size="line">
{% endhint %}

## New Wallet <a href="#new-wallet" id="new-wallet"></a>

### Generate <a href="#generate" id="generate"></a>

1. Click upper left ![](/files/7GUklMCvyo1DvxxhE0dJ) to open wallet list
2. Click the upper area ![](/files/Sm475ccsKsPUah7PPU5L) to new wallet page
3. Click **Generate**
4. Verification
   1. Password: Enter your password to authorize the generation
   2. Biometric authentication:
      1. Facial recognition: hold your device in portrait orientation, then glance at it.
      2. Fingerprint recognition: place your finger on fingerprint scanner

{% hint style="info" %}
Mobile - Long press the **Generate**

Desktop - Right click the **Generate**
{% endhint %}

### Import <a href="#import" id="import"></a>

1. Click upper left ![](/files/7GUklMCvyo1DvxxhE0dJ) to open wallet list
2. Click the upper area ![](/files/Sm475ccsKsPUah7PPU5L) to new wallet page
3. Click **Import**
4. Enter your mnemonic words
5. Enter your password to authorize the import

### Link Ledger device <a href="#link-ledger-device" id="link-ledger-device"></a>

1. Click upper left ![](/files/7GUklMCvyo1DvxxhE0dJ) to open wallet list
2. Click the upper area ![](/files/Sm475ccsKsPUah7PPU5L) to new wallet page
3. Click **Link Now**
4. Connect and unlocked your Ledger device
5. Click **Link**

### Wallet name <a href="#wallet-name" id="wallet-name"></a>

By default, we use "New Wallet" as the name for each new wallet. You can easily change the name by editing the input text field.

### Custom network wallet <a href="#custom-network-wallet" id="custom-network-wallet"></a>

{% hint style="info" %}
Before adding the custom network wallet, you need to [Settings](/core-concepts/wallets/sync2/user-guide/settings#add-node) beforehand
{% endhint %}

1. Click upper left ![](/files/7GUklMCvyo1DvxxhE0dJ) to open wallet list
2. Click the upper area ![](/files/Sm475ccsKsPUah7PPU5L) to open the new wallet page
3. Click upper right ![](/files/5aNIeIKgH7G0iley6MH8)
4. Select **Private**
5. Click **Import** / **Generate**

## Backup wallet <a href="#backup-wallet" id="backup-wallet"></a>

The mnemonic words store all the information that is needed at any point in time to recover your wallet. The mnemonic words should be **stored in a secure place**. It ensures you have had a backup in a scenario where your device breaks down or becomes unusable due to any reason. In such cases, all you need is your mnemonic words to recover the wallet.

1. Click **Backup Now** on the banner
2. Backup manually
   1. Click on upper right ![](/files/5aNIeIKgH7G0iley6MH8)
   2. Click **Backup**

{% hint style="info" %}

* Once you've backed up the wallet or wallet is imported, the backup banner won't be shown, you can try to back up manually
* Ledger wallet mnemonic words are managed by Ledger itself. therefore, you will not be able to back up your device via Sync2
  {% endhint %}

## Rename wallet <a href="#rename-wallet" id="rename-wallet"></a>

Wallet name is the identifier to help you easily tell the wallet.

1. Click upper right ![](/files/5aNIeIKgH7G0iley6MH8)
2. Click upper right ![](/files/5aNIeIKgH7G0iley6MH8)
3. Click **Rename**
4. Enter the name of your wallet
5. Click **Confirm**

## Delete wallet <a href="#delete-wallet" id="delete-wallet"></a>

1. Click upper right ![](/files/5aNIeIKgH7G0iley6MH8)
2. Click **Delete**
3. Follow the instructions to continue the deletion
4. Click **Delete**
5. Enter your password to authorize the deletion

## Create new address <a href="#create-new-address" id="create-new-address"></a>

1. Click upper right ![](/files/5aNIeIKgH7G0iley6MH8)
2. Click **New Address**

{% hint style="info" %}
A user is limited to a maximum of 10 addresses.
{% endhint %}

## Address <a href="#address" id="address"></a>

<figure><img src="/files/ZPllPnk3Jxjt8Nyzc7t3" alt=""><figcaption></figcaption></figure>

### Add assets <a href="#add-assets" id="add-assets"></a>

1. Click middle right ![](/files/aA8ToSK3vPM679BrPHj8)
2. Choose the token from the token list
3. Toggle on to enable

### Transfer history <a href="#transfer-history" id="transfer-history"></a>

1. Click the asset you would like to check the history
2. Click ![](/files/U3L4fEmQABuS7Fme8IKR) to check the details

### Send asset <a href="#send-asset" id="send-asset"></a>

1. Click the asset you would like to send
2. Click ![](/files/2ruDj4LVS2ViSbwc6WGT) to send asset

### Receive asset <a href="#receive-asset" id="receive-asset"></a>

1. At the upper right
2. Click ![](/files/TOXE6rPm0AFkjwyH1JyO) to view the QR Code or copy address


# Signing

<figure><img src="/files/groF7IaAXdvvvW4OtAdH" alt=""><figcaption></figcaption></figure>

## Content type <a href="#content-type" id="content-type"></a>

There are two major types of signing contents:

| Type        | Purpose                                       |
| ----------- | --------------------------------------------- |
| Transaction | **Create** / **Transfer** / **Contract Call** |
| Certificate | **Identification** / **Agreement**            |

{% hint style="info" %}
Sync2 would not provide the list of your address unless you sign the certificate of identification. Moreover, it only provides the address you've signed to dApp rather than all the addresses.
{% endhint %}

## Signing steps <a href="#signing-steps" id="signing-steps"></a>

### 1. Confirm the request source External Request <a href="#id-1-confirm-the-request-source" id="id-1-confirm-the-request-source"></a>

Sync allows users to choose your browser to interact with dApp. Therefore, It is a behaviour that the browser requesting Sync2 as a signature provider. Once Sync2 receives the signing content, please verify the below contents to continue the signing process.

* **From**： It shows the requested dApp URL
* **Type**: It shows the requested type of singing (Transaction / Certificate )
* **Purpose**: If it's a singing request of the certificate, it indicates the purpose of Identification or Agreement
* **Summary**: Description of transaction
* **Network**: If there's no network appear, it means that the transaction is mainnet based. Otherwise, it will show the network identifier at the upper right

### 2. Review the signing content <a href="#id-2-review-the-signing-content" id="id-2-review-the-signing-content"></a>

#### **A. Transaction content**

1. Check the **To** address is correct
2. Check the **Value** is correct
3. Check the **Data** if it appears
4. Check the Summary of the clause.

#### **B. Certificate content**

1. Check the Certificate type (Identification / Agreement)
2. Read carefully the message the dApp provided.

#### **Check if an error occurred**

Sync will check several things before the user signing.

1. Check the balance is sufficient
2. Check if there is an error occur during the compute in VM (virtual machine).
3. Check the content is valid

If there's an error, you can see there is a warning box above the adjustment area. Pay attention to transaction details before signing. Note that errors may cause the transaction to revert, or may deduct your VTHO due to it costs the VM to compute the transaction. Secondly, it will ask your permission to continue to sign the transaction before the authenticator.

#### **Change signer**

If you own more than one address and did not designate the signer, you can select an address to sign the transaction.

1. If transaction allows you to change the signer
2. Click the address to view all the wallets under the requested network
3. Click the address to become a signer

#### **Adjust priority**

Priority is a human-readable term of the Gas Price coefficient. Sync2 offer three different priority to user. user can adjust the priority (offer higher gas price for the packer to pack your transaction)

* Regular : **1x** of estimate VTHO cost
* Medium : **\~1.5x** of *Regular* VTHO cost
* High : **2x** of *Regular* VTHO cost

### 3. Confirm to sign <a href="#id-3-confirm-to-sign" id="id-3-confirm-to-sign"></a>

Due to the nature of blockchain, transactions cannot be canceled or altered once they are initiated. Therefore, you must **ALWAYS review the signing content before signing.**

1. Click **Sign**
2. If an error occurred, please read the error before continue or terminate the signing process
3. Approve signing:
   1. **Password**: Enter your password to authorize the signing
   2. **Ledger User**: follow the signing steps and confirm the signing on your Ledger device

### 4. Check the result <a href="#id-4-check-the-result" id="id-4-check-the-result"></a>

Once the transaction/ certificate is signed, you can check the result in [activities](/core-concepts/wallets/sync2/user-guide/activities)


# Activities

<figure><img src="/files/HP1TV1y9cAvhgLe0NeVd" alt=""><figcaption></figcaption></figure>

## Activities status <a href="#activities-status" id="activities-status"></a>

### Ongoing <a href="#ongoing" id="ongoing"></a>

* **Sending** : Signed content is awaiting to be processed and not being packed into a block.
* **Confirming** : Transaction is packed into a block and can be "View" on the blockchain but required 12 blocks to confirm.

{% hint style="info" %}

* Unstable connection to the transaction pool may cause the transactions to fail. Sync2 will automatically retry the transaction request until it expires. Once expired, Sync2 will update the status to "expired".
* Transaction required 12 blocks to be confirmed.
  {% endhint %}

### Completed <a href="#completed" id="completed"></a>

* **Confirmed**: Transaction has been confirmed more than 12 blocks or signed a certificate.
* **Expired**: The transaction reached the limit of expiration or the VTHO is not enough to compute the transaction.
* **Reverted**: Several reasons may cause the transaction to revert.

{% hint style="info" %}

* Reverted transaction will deduct the VTHO due to vm(virtual machine) computed
* All the signed transactions/certificates are **stored in local**, therefore, it only shows the transaction/content which you signed on the device.
  {% endhint %}

## View On explorer (Transaction Only) <a href="#view-on-explorer" id="view-on-explorer"></a>

1. Click the transaction to expand the details
2. Click <img src="/files/QJ3bWTZQnIJo9Xb96SaT" alt="" data-size="line"> to check on [explorer](https://explore.vechain.org/)

## Copy TxID (Transaction Only) <a href="#copy-txid" id="copy-txid"></a>

1. Click the transaction to expand the details
2. Click <img src="/files/VyaXicaA3ERqKQuKhd1B" alt="" data-size="line"> to copy the transaction ID

## Link to dApp <a href="#link-to-dapp" id="link-to-dapp"></a>

1. Click the transaction to expand the details
2. Click <img src="/files/OWYqYDZTafR39AN5gPTm" alt="" data-size="line"> to direct to the link which dApps provided

## View signed content (Certificate Only) <a href="#view-signed-content" id="view-signed-content"></a>

1. Click the certificate to check the details
2. Click ![](https://docs.vechain.org/assets/img/message.759cf5c9.svg) to check original signed content


# Settings

<figure><img src="/files/yEQuEsR0U7OLArYnS2MH" alt=""><figcaption></figcaption></figure>

## Switch Language <a href="#switch-language" id="switch-language"></a>

1. Click **Language**
2. Choose your language from the list
3. Click to set your preferred language

## Change Password <a href="#change-password" id="change-password"></a>

1. Click **Password**
2. Enter your password to authorise the password setup
3. Enter your new password
4. Enter your password again for confirmation

## Biometric Authentication (Mobile only) <a href="#biometric-authentication" id="biometric-authentication"></a>

1. Click **Biometric Authentication**
2. Enter your password
3. Biometric verification

Following scenario required your biometric authentication

1. Wallet action(remove, backup, generate, import)
2. General(change password, enable biometric authentication)
3. Signing a Transaction or certificate

## Token List <a href="#token-list" id="token-list"></a>

1. Click **Tokens**
2. Choose the token from the token list
3. Toggle on to enable

## Nodes Management <a href="#nodes-management" id="nodes-management"></a>

Nodes are the primary communication bridge of the blockchain. If the default node's connection speed in your region is not ideal, you can manage it in the following ways.

### Add node <a href="#add-node" id="add-node"></a>

1. Click **Node**
2. Click ![](/files/Sm475ccsKsPUah7PPU5L) at upper right
3. Enter the node's url with `http` or `https`
4. Click **Add** to add node

### Change Node <a href="#change-node" id="change-node"></a>

1. Choose the node from the node list
2. Click to set your preferred node

### Delete Node <a href="#delete-node" id="delete-node"></a>

1. Choose the node from the node list
2. Click <img src="/files/BaCaadL7oPTc6q3z3Yp4" alt="" data-size="line"> to delete the node


# FAQ

## Add custom network <a href="#add-custom-network" id="add-custom-network"></a>

See [Add node](/core-concepts/wallets/sync2/user-guide/settings#add-node) for more details

## Custom wallet <a href="#custom-wallet" id="custom-wallet"></a>

See [custom network wallet](/core-concepts/wallets/sync2/user-guide/wallet#custom-network-wallet) for more details

## Signing warning <a href="#signing-warning" id="signing-warning"></a>

Many reasons may cause the transaction failed/reverted. below are some causes:

### Insufficient VTHO <a href="#insufficient-vtho" id="insufficient-vtho"></a>

it means that the address does not have enough VTHO to send the transaction. Please make sure you have enough VTHO before sending the transaction.

### Failed to request transaction fee delegation <a href="#failed-to-request-transaction-fee-delegation" id="failed-to-request-transaction-fee-delegation"></a>

Network condition may affect connection between Sync2 and fee delegation service. You may try the following:

1. Retry signing process
2. Check your network connection status
3. Disconnect Wi-Fi and try with cellular data

### Requested address not owned <a href="#requested-address-not-owned" id="requested-address-not-owned"></a>

Before the user confirms the transaction/certificate details, Sync2 will automatically ensure the designated signer(address) exists in Sync2.

## Ledger troubleshooting <a href="#ledger-troubleshoots" id="ledger-troubleshoots"></a>

### INS\_NOT\_SUPPORTED (0x6d00) <a href="#ins-not-supported-0x6d00" id="ins-not-supported-0x6d00"></a>

* Ensuring your device runs the latest firmware version.
* Reinstalling the apps on your device, so you run the latest versions. Uninstalling apps does not affect your crypto assets, that are secured on the blockchain.

### INCORRECT\_DATA (0x6a80) <a href="#incorrect-data-0x6a80" id="incorrect-data-0x6a80"></a>

1. Navigate to VeChain App on your Ledger device
2. Navigate to Setting
3. Set **Contract data** to **Yes**
4. Set **Multi-clause** to **Yes**

### Unable to connect your device <a href="#unable-to-connect-your-device" id="unable-to-connect-your-device"></a>

* Close other applications (Ledger apps, crypto wallets, Geth, Parity, Mist, Bitcoin Core, etc.).
* Turn OFF VPN and antivirus temporarily. If that works, make sure to whitelist Sync.
* Change the USB cable if possible. Try removing any dongles or docks you're using.
* Try different USB ports.
* Restart your computer.
* Try another computer.

### Check status failed <a href="#check-status-failed" id="check-status-failed"></a>

The error "**checking status failed**" shown during the Ledger connection, it means that the device you are trying to connect **IS NOT** the device that belongs to the wallet you imported. In other words, it's a brand-new ledger device you never imported. Please check that your Ledger device is the proper device that belongs to the selected account(imported wallet). The easiest way to identify the issue is [import your ledger device](/core-concepts/wallets/sync2/user-guide/wallet#link-ledger-device) again and compare the wallet address.

Reset your Ledger device:

1. Reset your Ledger device by entering three wrong PIN codes.
2. [Restore from recovery phrase](https://support.ledger.com/hc/en-us/articles/4404382560913-Restore-from-recovery-phrase?support=true)

{% hint style="info" %}
In case you have multiple Ledger hardware wallets set up with different recovery phrases, you should connect the device holding the recovery phrase used to import the account.
{% endhint %}

### Mis-transfer the funds to ethereum address <a href="#mis-transfer-the-funds-to-ethereum-address" id="mis-transfer-the-funds-to-ethereum-address"></a>

Please check the [Ledger support-Export your accounts](https://support.ledger.com/hc/en-us/articles/115005297709-Export-your-accounts) instruction. Once the private key / keystore is exported, import to Sync wallet.


# EVM Compatibility

Ethereum virtual machine (EVM) compatibility with the VeChainThor blockchain

## What is Ethereum?

Ethereum was the first programmable blockchain. Ethereum programability is achieved through the Ethereum Virtual Machine (EVM). Before Ethereum the only use case for blockchain was the Bitcoin blockchain and the use of its native asset bitcoin as a form of digital money. The creation of Ethereum and the introduction of programability extended the use case of blockchain technology beyond digital money into use cases such as decentralized financial services (DeFi), games, social networks, the creation of non-fungible tokens (NFTs) and other applications that respect your privacy and cannot censor you.

## What is the EVM?

The Ethereum Virtual Machine (EVM) is a key component of the Ethereum blockchain. The EVM can be considered the computational engine of the Ethereum blockchain. The EVM manages and maintains the state of the blockchain. For this reason it is often referred to as the "world computer". The EVM enables programability to exist and function on the Ethereum blockchain.

## Why is EVM compatibility important?

EVM compatibility is important because it enhances interoperability, developer adoption, network effects and code reusability across the entire blockchain ecosystem. This creates a more vibrant and collaborative environment for building decentralized applications and services.

EVM compatibility is important for several reasons:

* **Interoperability:** EVM compatibility enables different blockchain networks to communicate and interact with each other. This allows developers to build decentralized applications that can be used across multiple blockchain networks, which enhances the interoperability of the entire blockchain ecosystem.
* **Developer Adoption:** EVM compatibility makes it easier for developers to create and deploy smart contracts on the Ethereum blockchain and other EVM compatible blockchains. This is because developers can use familiar programming languages and tools which reduces the learning curve and makes it easier to build decentralized applications.
* **Network Effects:** EVM compatibility creates network effects, which means that as more blockchain networks become EVM compatible the value and utility of the blockchain ecosystem as a whole increases. This creates a virtuous cycle that attracts more developers and users to the network, which further enhances its value.
* **Code Reusability:** EVM compatibility allows developers to reuse code and smart contracts across multiple blockchain networks, which reduces development time and costs. This is particularly important for enterprise applications, where there may be multiple blockchain networks involved.

## VeChain EVM Compatibility

VeChain is EVM compatible. VeChain originated as a fork of Ethereum and the EVM and maintains a high level of EVM compatibility despite some modifications that were introduced into VeChain to make it more enterprise friendly, scalable and sustainable.


# 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](/introduction-to-vechain/dual-token-economic-model) 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 staking `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](/core-concepts/transactions/meta-transaction-features/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](#transaction-model)
* [Transaction clauses](#transaction-model-1)
* [Transaction dependency](#transaction-dependency)
* [Transaction life-cycle control](#transaction-life-cycle-control)
* [Hash function](#hash-function)
* [Nonce](#nonce)

### Transaction Fields <a href="#transaction-model" id="transaction-model"></a>

The structure of a VeChain transaction can be seen below and a more detailed explanation of each field [here](/core-concepts/transactions/transaction-model).

```go
// 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 <a href="#transaction-model" id="transaction-model"></a>

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](/core-concepts/transactions/meta-transaction-features/clauses-multi-task-transaction).

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 <a href="#transaction-dependency" id="transaction-dependency"></a>

[Transaction dependency](/core-concepts/transactions/meta-transaction-features/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](https://docs.vechain.org/developer-resources/sdks-and-providers/sdk/transactions#example-transaction-dependency).

### 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](https://www.veworld.net/).
> * Get some testnet assets, `VET` and `VTHO`, through the [faucet](https://faucet.vecha.in/).
> * Use the [energy station](https://energy.outofgas.io/#/) if you need to convert `VET` to `VTHO` or vice verse.


# Methodology

OpenZeppelin smart contracts play a crucial role in the world of decentralized applications and blockchain development.

## OpenZeppelin v4

To prove the OpenZeppelin smart contract compatibility with the VeChainThor blockchain the OpenZeppelin tests were performed using the Hardhat development environment and a custom plugin specifically designed to connect to the VeChainThor Node.

{% hint style="info" %}
The provider's functionality currently being used can be found in

<https://github.com/vechain/web3-providers-connex>
{% endhint %}

A selection of failing tests were examined and bug fixes were suggested in pull requests. Since test cases include Hardhat specific tests, we opted to compare results against a non Hardhat network, specifically using the [Ganache plugin for Hardhat](https://hardhat.org/hardhat-runner/plugins/nomiclabs-hardhat-ganache).

## OpenZeppelin v5

Upgrading VeChainThor to the Shanghai EVM version, we want to ensure the OpenZeppelin contracts v5 are still compatible. In order to do so we prepared a custom OpenZeppelin contracts [fork](https://github.com/vechain/openzeppelin-contracts/tree/thor-compatibility) where all tests were adapted to run on VeChainThor. Since those tests are meant to be run against Hardhat network, multiple changes were made. Some test cases were removed (the end goal is not to test OpenZeppelin contracts themselves) because they cannot be run against a real blockchain and others were changed to reflect the VeChainThor responses.


# Test Coverage

The tables below provide a summary and detailed information in relation to the number of tests performed, the count of passing tests and the count of failing tests.

To summarise, VeChain is fully compatible with OpenZeppelin contracts (with v5 being the latest version tested), and the main differences encountered are related to Hardhat:

* The `chainId` in VeChain is the genesis block ID of each network
* Custom [Hardhat RPC methods](https://hardhat.org/hardhat-network/docs/reference#special-testing/debugging-methods) like `evm_increaseTime` or `evm_mine` depend on the actual Hardhat VeChain plugin (so differences might be expected in this regard).

You can find detailed analysis of the coverage categories in the pages to follow.

## OpenZeppelin v5

### Summary

<table><thead><tr><th width="271">Category</th><th width="394">Short Description</th><th>Failures</th></tr></thead><tbody><tr><td>Set base URI</td><td>URI was not set in the ERC721 and ERC721Enumerable test cases, causing 6 tests to remain pending. Since these tests focus on compatibility, URI validation is not essential.</td><td>0</td></tr></tbody></table>

### Detail

<table><thead><tr><th width="306">Contract Name</th><th>Pass</th><th>Fail</th><th>Total</th><th data-hidden>Test Coverage</th></tr></thead><tbody><tr><td><strong>Total</strong></td><td><strong>2611</strong></td><td><strong>0</strong></td><td><strong>2617</strong></td><td></td></tr><tr><td>AccessControl</td><td>30</td><td>0</td><td>30</td><td></td></tr><tr><td>Ownable</td><td>8</td><td>0</td><td>8</td><td></td></tr><tr><td>Ownable2Step</td><td>6</td><td>0</td><td>6</td><td></td></tr><tr><td>AccessControlDefaultAdminRules</td><td>56</td><td>0</td><td>56</td><td></td></tr><tr><td>AccessControlEnumerable</td><td>36</td><td>0</td><td>36</td><td></td></tr><tr><td>AccessManaged</td><td>8</td><td>0</td><td>8</td><td></td></tr><tr><td>AccessManager</td><td>113</td><td>0</td><td>113</td><td></td></tr><tr><td>AuthorityUtils</td><td>4</td><td>0</td><td>4</td><td></td></tr><tr><td>VestingWallet</td><td>2</td><td>0</td><td>2</td><td></td></tr><tr><td>Governor</td><td>136</td><td>0</td><td>136</td><td></td></tr><tr><td>GovernorERC721</td><td>2</td><td>0</td><td>2</td><td></td></tr><tr><td>GovernorPreventLateQuorum</td><td>5</td><td>0</td><td>5</td><td></td></tr><tr><td>GovernorStorage</td><td>3</td><td>0</td><td>3</td><td></td></tr><tr><td>GovernorTimelockAccess</td><td>3</td><td>0</td><td>3</td><td></td></tr><tr><td>GovernorTimelockCompound</td><td>8</td><td>0</td><td>8</td><td></td></tr><tr><td>GovernorTimelockControl</td><td>12</td><td>0</td><td>12</td><td></td></tr><tr><td>GovernorVotesQuorumFraction</td><td>4</td><td>0</td><td>4</td><td></td></tr><tr><td>GovernorWithParams</td><td>7</td><td>0</td><td>7</td><td></td></tr><tr><td>Votes</td><td>44</td><td>0</td><td>44</td><td></td></tr><tr><td>ERC2771Context</td><td>11</td><td>0</td><td>11</td><td></td></tr><tr><td>ERC2771Forwarder</td><td>36</td><td>0</td><td>36</td><td></td></tr><tr><td>Clones</td><td>30</td><td>0</td><td>30</td><td></td></tr><tr><td>ERC1967Proxy</td><td>19</td><td>0</td><td>19</td><td></td></tr><tr><td>BeaconProxy</td><td>6</td><td>0</td><td>6</td><td></td></tr><tr><td>UpgradeableBeacon</td><td>6</td><td>0</td><td>6</td><td></td></tr><tr><td>ProxyAdmin</td><td>5</td><td>0</td><td>5</td><td></td></tr><tr><td>TransparentUpgradeableProxy</td><td>19</td><td>0</td><td>19</td><td></td></tr><tr><td>Initializable</td><td>29</td><td>0</td><td>29</td><td></td></tr><tr><td>UUPSupgradeable</td><td>8</td><td>0</td><td>8</td><td></td></tr><tr><td>ERC721</td><td>375</td><td>0</td><td>378</td><td></td></tr><tr><td>ERC721Enumerable</td><td>397</td><td>0</td><td>400</td><td></td></tr><tr><td>ERC721Wrapper</td><td>18</td><td>0</td><td>18</td><td></td></tr><tr><td>ERC721Holder</td><td>1</td><td>0</td><td>1</td><td></td></tr><tr><td>ERC721Burnable</td><td>5</td><td>0</td><td>5</td><td></td></tr><tr><td>ERC721Consecutive</td><td>34</td><td>0</td><td>34</td><td></td></tr><tr><td>ERC721Pausable</td><td>9</td><td>0</td><td>9</td><td></td></tr><tr><td>ERC721Royalty</td><td>16</td><td>0</td><td>16</td><td></td></tr><tr><td>ERC721URIStorage</td><td>17</td><td>0</td><td>17</td><td></td></tr><tr><td>ERC721Votes</td><td>23</td><td>0</td><td>23</td><td></td></tr><tr><td>ERC721Holder</td><td>1</td><td>0</td><td>1</td><td></td></tr><tr><td>ERC1155</td><td>89</td><td>0</td><td>89</td><td></td></tr><tr><td>ERC1155Burnable</td><td>6</td><td>0</td><td>6</td><td></td></tr><tr><td>ERC1155Pausable</td><td>11</td><td>0</td><td>11</td><td></td></tr><tr><td>ERC1155Supply</td><td>4</td><td>0</td><td>4</td><td></td></tr><tr><td>ERC1155URIStorage</td><td>4</td><td>0</td><td>4</td><td></td></tr><tr><td>ERC1155Holder</td><td>7</td><td>0</td><td>7</td><td></td></tr><tr><td>Address</td><td>7</td><td>0</td><td>7</td><td></td></tr><tr><td>Address</td><td>29</td><td>0</td><td>29</td><td></td></tr><tr><td>Arrays</td><td>20</td><td>0</td><td>20</td><td></td></tr><tr><td>Base64</td><td>5</td><td>0</td><td>5</td><td></td></tr><tr><td>Context</td><td>4</td><td>0</td><td>4</td><td></td></tr><tr><td>Create2</td><td>8</td><td>0</td><td>8</td><td></td></tr><tr><td>Multicall</td><td>4</td><td>0</td><td>4</td><td></td></tr><tr><td>Nonces</td><td>6</td><td>0</td><td>6</td><td></td></tr><tr><td>Pausable</td><td>11</td><td>0</td><td>11</td><td></td></tr><tr><td>ReentrancyGuard</td><td>6</td><td>0</td><td>6</td><td></td></tr><tr><td>ShortStrings</td><td>14</td><td>0</td><td>14</td><td></td></tr><tr><td>StorageSlot</td><td>24</td><td>0</td><td>24</td><td></td></tr><tr><td>Strings</td><td>71</td><td>0</td><td>71</td><td></td></tr><tr><td>ECDSA</td><td>14</td><td>0</td><td>14</td><td></td></tr><tr><td>EIP712</td><td>13</td><td>0</td><td>13</td><td></td></tr><tr><td>MerkleProof</td><td>10</td><td>0</td><td>10</td><td></td></tr><tr><td>MessageHashUtils</td><td>4</td><td>0</td><td>4</td><td></td></tr><tr><td>ERC165</td><td>5</td><td>0</td><td>5</td><td></td></tr><tr><td>ERC165Checker</td><td>40</td><td>0</td><td>40</td><td></td></tr><tr><td>Math</td><td>44</td><td>0</td><td>44</td><td></td></tr><tr><td>SafeCast</td><td>444</td><td>0</td><td>444</td><td></td></tr><tr><td>SignedMath</td><td>12</td><td>0</td><td>12</td><td></td></tr><tr><td>BitMap</td><td>10</td><td>0</td><td>10</td><td></td></tr><tr><td>Checkpoints</td><td>33</td><td>0</td><td>33</td><td></td></tr><tr><td>DoubleEndedQueue</td><td>9</td><td>0</td><td>9</td><td></td></tr><tr><td>EnumerableMap</td><td>60</td><td>0</td><td>60</td><td></td></tr><tr><td>EnumerableSet</td><td>24</td><td>0</td><td>24</td><td></td></tr><tr><td>Time</td><td>7</td><td>0</td><td>7</td><td></td></tr></tbody></table>

## OpenZeppelin v4

### Summary

<table><thead><tr><th width="305">Category</th><th width="359">Short Description</th><th>Failures</th></tr></thead><tbody><tr><td>Justifiable</td><td>Failures that result from the inherent design differences between VeChain and Ethereum.</td><td>73</td></tr><tr><td>Contract Address Prediction</td><td>See <a href="https://github.com/vechain/vechain-docs/blob/main/core-concepts/evm-compatibility/test-coverage/broken-reference/README.md">here</a>.</td><td>14</td></tr><tr><td>Failures in Constructor</td><td>Contract fails in constructor, resulting in failure to be deployed.</td><td>7</td></tr><tr><td>Full, with eth_sign implementation</td><td>See <a href="https://github.com/vechain/vechain-docs/blob/main/core-concepts/evm-compatibility/test-coverage/broken-reference/README.md">here</a>.</td><td>4</td></tr><tr><td>Full, with test changes</td><td>Some test modifications had to be added for the tests to pass.</td><td>3</td></tr><tr><td>BadBeaconProxy Address 0x1</td><td>See <a href="https://github.com/vechain/vechain-docs/blob/main/core-concepts/evm-compatibility/test-coverage/broken-reference/README.md">here</a>.</td><td>1</td></tr></tbody></table>

### Detail

<table><thead><tr><th width="305">Contract Name</th><th>Pass</th><th>Fail</th><th>Total</th><th data-hidden>Test Coverage</th><th data-hidden>Hardhat Total Tests</th></tr></thead><tbody><tr><td><strong>Total</strong></td><td><strong>2324</strong></td><td><strong>102</strong></td><td><strong>2426</strong></td><td></td><td><strong>2667</strong></td></tr><tr><td>ERC1967Proxy</td><td>25</td><td>3</td><td>28</td><td></td><td>28</td></tr><tr><td>TransparentUpgradeableProxy</td><td>58</td><td>3</td><td>61</td><td></td><td>61</td></tr><tr><td>BeaconProxy</td><td>7</td><td>2</td><td>9</td><td></td><td>9</td></tr><tr><td>GovernorTimelockCompound</td><td>7</td><td>12</td><td>19</td><td></td><td>19</td></tr><tr><td>GovernorCompatibilityBravo</td><td>7</td><td>2</td><td>9</td><td></td><td>9</td></tr><tr><td>TimelockController</td><td>27</td><td>15</td><td>42</td><td></td><td>48</td></tr><tr><td>CrossChainEnabled</td><td>4</td><td>9</td><td>13</td><td></td><td>15</td></tr><tr><td>GovernorTimelockControl</td><td>12</td><td>9</td><td>21</td><td></td><td>21</td></tr><tr><td>AccessControl</td><td>50</td><td>4</td><td>54</td><td></td><td>80</td></tr><tr><td>MinimalForwarder</td><td>12</td><td>4</td><td>16</td><td></td><td>15</td></tr><tr><td>TokenTimelock</td><td>3</td><td>4</td><td>7</td><td></td><td>7</td></tr><tr><td>VestingWallet</td><td>2</td><td>4</td><td>6</td><td></td><td>6</td></tr><tr><td>ERC721Enumerable</td><td>233</td><td>3</td><td>236</td><td></td><td>236</td></tr><tr><td>DoubleEndedQueue</td><td>7</td><td>2</td><td>9</td><td></td><td>9</td></tr><tr><td>ERC2771Context</td><td>5</td><td>2</td><td>7</td><td></td><td>7</td></tr><tr><td>ERC721</td><td>211</td><td>2</td><td>213</td><td></td><td>213</td></tr><tr><td>Governor</td><td>42</td><td>2</td><td>44</td><td></td><td>44</td></tr><tr><td>Checkpoints</td><td>22</td><td>1</td><td>23</td><td></td><td>23</td></tr><tr><td>ERC1155</td><td>83</td><td>1</td><td>84</td><td></td><td>84</td></tr><tr><td>ERC1155Holder</td><td>4</td><td>1</td><td>5</td><td></td><td>5</td></tr><tr><td>ERC1155PresetMinterPauser</td><td>16</td><td>1</td><td>17</td><td></td><td>17</td></tr><tr><td>ERC165</td><td>2</td><td>1</td><td>3</td><td></td><td>3</td></tr><tr><td>ERC165Storage</td><td>4</td><td>1</td><td>5</td><td></td><td>5</td></tr><tr><td>ERC20Votes</td><td>28</td><td>1</td><td>29</td><td></td><td>29</td></tr><tr><td>ERC20VotesComp</td><td>27</td><td>1</td><td>28</td><td></td><td>28</td></tr><tr><td>ERC721PresetMinterPauserAutoId</td><td>15</td><td>1</td><td>16</td><td></td><td>16</td></tr><tr><td>ERC721Royalty</td><td>13</td><td>1</td><td>14</td><td></td><td>14</td></tr><tr><td>GovernorWithParams</td><td>3</td><td>1</td><td>4</td><td></td><td>4</td></tr><tr><td>MerkleProof</td><td>8</td><td>1</td><td>9</td><td></td><td>9</td></tr><tr><td>TimersTimestamp</td><td>4</td><td>1</td><td>5</td><td></td><td>5</td></tr><tr><td>ECDSA</td><td>14</td><td>3</td><td>17</td><td></td><td>17</td></tr><tr><td>SignatureChecker (ERC1271)</td><td>1</td><td>1</td><td>1</td><td></td><td>7</td></tr><tr><td>ERC1820Implementer</td><td>1</td><td>1</td><td>1</td><td></td><td>6</td></tr><tr><td>ERC777</td><td>1</td><td>1</td><td>1</td><td></td><td>193</td></tr><tr><td>ERC777PresetFixedSupply</td><td>1</td><td>1</td><td>1</td><td></td><td>6</td></tr><tr><td>Address</td><td>29</td><td>0</td><td>29</td><td></td><td>29</td></tr><tr><td>Arrays</td><td>15</td><td>0</td><td>15</td><td></td><td>15</td></tr><tr><td>BitMap</td><td>10</td><td>0</td><td>10</td><td></td><td>10</td></tr><tr><td>Clones</td><td>30</td><td>0</td><td>30</td><td></td><td>30</td></tr><tr><td>ConditionalEscrow</td><td>11</td><td>0</td><td>11</td><td></td><td>11</td></tr><tr><td>Context</td><td>4</td><td>0</td><td>4</td><td></td><td>4</td></tr><tr><td>Counters</td><td>8</td><td>0</td><td>8</td><td></td><td>8</td></tr><tr><td>Create2</td><td>8</td><td>0</td><td>8</td><td></td><td>8</td></tr><tr><td>EIP712</td><td>2</td><td>0</td><td>2</td><td></td><td>2</td></tr><tr><td>EnumerableMap</td><td>70</td><td>0</td><td>70</td><td></td><td>70</td></tr><tr><td>EnumerableSet</td><td>20</td><td>0</td><td>24</td><td></td><td>24</td></tr><tr><td>ERC1155Burnable</td><td>6</td><td>0</td><td>6</td><td></td><td>6</td></tr><tr><td>ERC1155Pausable</td><td>11</td><td>0</td><td>11</td><td></td><td>11</td></tr><tr><td>ERC1155Supply</td><td>10</td><td>0</td><td>10</td><td></td><td>10</td></tr><tr><td>ERC1155URIStorage</td><td>4</td><td>0</td><td>4</td><td></td><td>4</td></tr><tr><td>ERC165Checker</td><td>40</td><td>0</td><td>40</td><td></td><td>40</td></tr><tr><td>ERC20</td><td>118</td><td>0</td><td>118</td><td></td><td>118</td></tr><tr><td>ERC20Burnable</td><td>13</td><td>0</td><td>13</td><td></td><td>13</td></tr><tr><td>ERC20Capped</td><td>5</td><td>0</td><td>5</td><td></td><td>5</td></tr><tr><td>ERC20FlashMint</td><td>12</td><td>0</td><td>12</td><td></td><td>12</td></tr><tr><td>ERC20Pausable</td><td>12</td><td>0</td><td>12</td><td></td><td>12</td></tr><tr><td>ERC20Permit</td><td>6</td><td>0</td><td>6</td><td></td><td>6</td></tr><tr><td>ERC20PresetFixedSupply</td><td>4</td><td>0</td><td>4</td><td></td><td>4</td></tr><tr><td>ERC20PresetMinterPauser</td><td>12</td><td>0</td><td>12</td><td></td><td>12</td></tr><tr><td>ERC20Snapshot</td><td>14</td><td>0</td><td>14</td><td></td><td>14</td></tr><tr><td>ERC4626</td><td>25</td><td>0</td><td>25</td><td></td><td>25</td></tr><tr><td>ERC721Burnable</td><td>4</td><td>0</td><td>4</td><td></td><td>4</td></tr><tr><td>ERC721Consecutive</td><td>13</td><td>0</td><td>13</td><td></td><td>13</td></tr><tr><td>ERC721Holder</td><td>1</td><td>0</td><td>1</td><td></td><td>1</td></tr><tr><td>ERC721Pausable</td><td>10</td><td>0</td><td>10</td><td></td><td>10</td></tr><tr><td>ERC721URIStorage</td><td>10</td><td>0</td><td>10</td><td></td><td>10</td></tr><tr><td>ERC721Votes</td><td>26</td><td>0</td><td>26</td><td></td><td>26</td></tr><tr><td>Escrow</td><td>10</td><td>0</td><td>10</td><td></td><td>10</td></tr><tr><td>GovernorComp</td><td>2</td><td>0</td><td>2</td><td></td><td>2</td></tr><tr><td>GovernorERC721Mock</td><td>2</td><td>0</td><td>2</td><td></td><td>2</td></tr><tr><td>GovernorPreventLateQuorum</td><td>5</td><td>0</td><td>5</td><td></td><td>5</td></tr><tr><td>GovernorVotesQuorumFraction</td><td>6</td><td>0</td><td>6</td><td></td><td>6</td></tr><tr><td>Initializable</td><td>29</td><td>0</td><td>29</td><td></td><td>29</td></tr><tr><td>Math</td><td>25</td><td>0</td><td>25</td><td></td><td>25</td></tr><tr><td>MulticallToken</td><td>4</td><td>0</td><td>4</td><td></td><td>4</td></tr><tr><td>Ownable</td><td>6</td><td>0</td><td>6</td><td></td><td>6</td></tr><tr><td>Ownable2Step</td><td>5</td><td>0</td><td>5</td><td></td><td>5</td></tr><tr><td>Pausable</td><td>11</td><td>0</td><td>11</td><td></td><td>11</td></tr><tr><td>PaymentSplitter</td><td>20</td><td>0</td><td>20</td><td></td><td>20</td></tr><tr><td>ProxyAdmin</td><td>12</td><td>0</td><td>12</td><td></td><td>12</td></tr><tr><td>PullPayment</td><td>4</td><td>0</td><td>4</td><td></td><td>4</td></tr><tr><td>ReentrancyGuard</td><td>6</td><td>0</td><td>6</td><td></td><td>6</td></tr><tr><td>RefundEscrow</td><td>17</td><td>0</td><td>17</td><td></td><td>17</td></tr><tr><td>SafeCast</td><td>444</td><td>0</td><td>444</td><td></td><td>444</td></tr><tr><td>SafeERC20</td><td>35</td><td>0</td><td>35</td><td></td><td>35</td></tr><tr><td>SafeMath</td><td>48</td><td>0</td><td>48</td><td></td><td>48</td></tr><tr><td>SignedMath</td><td>12</td><td>0</td><td>12</td><td></td><td>12</td></tr><tr><td>SignedSafeMath</td><td>17</td><td>0</td><td>17</td><td></td><td>17</td></tr><tr><td>StorageSlot</td><td>12</td><td>0</td><td>12</td><td></td><td>12</td></tr><tr><td>Strings</td><td>31</td><td>0</td><td>31</td><td></td><td>31</td></tr><tr><td>TimersBlockNumber</td><td>5</td><td>0</td><td>5</td><td></td><td>5</td></tr><tr><td>UpgradeableBeacon</td><td>5</td><td>0</td><td>5</td><td></td><td>5</td></tr><tr><td>UUPSUpgradeable</td><td>6</td><td>0</td><td>6</td><td></td><td>6</td></tr><tr><td>Votes</td><td>23</td><td>0</td><td>23</td><td></td><td>23</td></tr></tbody></table>


# Gas model

## Description

These errors are justifiable as they occur due to VeChain and Ethereum having different gas models and the tests being designed with Ethereum's gas model in mind. When these transactions are performed on VeChain the maximum amount of gas set by the test is exceeded, hence the failure. The tests are passable when the tests are modified to account for a higher maximum amount of gas.

## Contracts Affected

| Contract Name                  |
| ------------------------------ |
| ERC165                         |
| ERC165Storage                  |
| AccessControl                  |
| ERC1155Holder                  |
| ERC721Enumerable               |
| TimelockController             |
| ERC721                         |
| ERC1155PresetMinterPauser      |
| ERC1155                        |
| Governor                       |
| ERC721PresetMinterPauserAutoId |
| ERC721Royalty                  |
| ERC721Enumerable               |
| GovernorTimelockCompound       |
| GovernorTimelockControl        |


# Raw transaction

## Description

`ERC1820` is a contract that is considered a special case since it requires a few modifications in order to work on VeChain. It is used by `ERC777` so failure in `ERC1820` inevitably results in failure in `ERC777` also. The changes required for `ERC1820` were the following:

1. Chain-tag
2. Contract address passed in constructor

### Chain-tag

The first change that we have to do is change the chain-tag of the transaction creating the contract from 0(?) to 0xF6. Since the contract exists in a compiled form under `openzeppelin-contracts/node_modules/@openzeppelin/test-helpers/src/data.js` we had to change the binary in that file alongside the address. The two lines that were changed can be seen below:

```javascript
const ERC1820_REGISTRY_ADDRESS = '0xb02a08775234755be24ba32da95cf4509cfcee86';
const ERC1820_REGISTRY_DEPLOY_TX = '0xf90a4381f68084fffffffff909edf909ea8080b909e5608060405234801561001057600080fd5b506109c5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063a41e7d5111610078578063a41e7d51146101d4578063aabbb8ca1461020a578063b705676514610236578063f712f3e814610280576100a5565b806329965a1d146100aa5780633d584063146100e25780635df8122f1461012457806365ba36c114610152575b600080fd5b6100e0600480360360608110156100c057600080fd5b50600160a060020a038135811691602081013591604090910135166102b6565b005b610108600480360360208110156100f857600080fd5b5035600160a060020a0316610570565b60408051600160a060020a039092168252519081900360200190f35b6100e06004803603604081101561013a57600080fd5b50600160a060020a03813581169160200135166105bc565b6101c26004803603602081101561016857600080fd5b81019060208101813564010000000081111561018357600080fd5b82018360208201111561019557600080fd5b803590602001918460018302840111640100000000831117156101b757600080fd5b5090925090506106b3565b60408051918252519081900360200190f35b6100e0600480360360408110156101ea57600080fd5b508035600160a060020a03169060200135600160e060020a0319166106ee565b6101086004803603604081101561022057600080fd5b50600160a060020a038135169060200135610778565b61026c6004803603604081101561024c57600080fd5b508035600160a060020a03169060200135600160e060020a0319166107ef565b604080519115158252519081900360200190f35b61026c6004803603604081101561029657600080fd5b508035600160a060020a03169060200135600160e060020a0319166108aa565b6000600160a060020a038416156102cd57836102cf565b335b9050336102db82610570565b600160a060020a031614610339576040805160e560020a62461bcd02815260206004820152600f60248201527f4e6f7420746865206d616e616765720000000000000000000000000000000000604482015290519081900360640190fd5b6103428361092a565b15610397576040805160e560020a62461bcd02815260206004820152601a60248201527f4d757374206e6f7420626520616e204552433136352068617368000000000000604482015290519081900360640190fd5b600160a060020a038216158015906103b85750600160a060020a0382163314155b156104ff5760405160200180807f455243313832305f4143434550545f4d4147494300000000000000000000000081525060140190506040516020818303038152906040528051906020012082600160a060020a031663249cb3fa85846040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083815260200182600160a060020a0316600160a060020a031681526020019250505060206040518083038186803b15801561047e57600080fd5b505afa158015610492573d6000803e3d6000fd5b505050506040513d60208110156104a857600080fd5b5051146104ff576040805160e560020a62461bcd02815260206004820181905260248201527f446f6573206e6f7420696d706c656d656e742074686520696e74657266616365604482015290519081900360640190fd5b600160a060020a03818116600081815260208181526040808320888452909152808220805473ffffffffffffffffffffffffffffffffffffffff19169487169485179055518692917f93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db15391a450505050565b600160a060020a03818116600090815260016020526040812054909116151561059a5750806105b7565b50600160a060020a03808216600090815260016020526040902054165b919050565b336105c683610570565b600160a060020a031614610624576040805160e560020a62461bcd02815260206004820152600f60248201527f4e6f7420746865206d616e616765720000000000000000000000000000000000604482015290519081900360640190fd5b81600160a060020a031681600160a060020a0316146106435780610646565b60005b600160a060020a03838116600081815260016020526040808220805473ffffffffffffffffffffffffffffffffffffffff19169585169590951790945592519184169290917f605c2dbf762e5f7d60a546d42e7205dcb1b011ebc62a61736a57c9089d3a43509190a35050565b600082826040516020018083838082843780830192505050925050506040516020818303038152906040528051906020012090505b92915050565b6106f882826107ef565b610703576000610705565b815b600160a060020a03928316600081815260208181526040808320600160e060020a031996909616808452958252808320805473ffffffffffffffffffffffffffffffffffffffff19169590971694909417909555908152600284528181209281529190925220805460ff19166001179055565b600080600160a060020a038416156107905783610792565b335b905061079d8361092a565b156107c357826107ad82826108aa565b6107b85760006107ba565b815b925050506106e8565b600160a060020a0390811660009081526020818152604080832086845290915290205416905092915050565b6000808061081d857f01ffc9a70000000000000000000000000000000000000000000000000000000061094c565b909250905081158061082d575080155b1561083d576000925050506106e8565b61084f85600160e060020a031961094c565b909250905081158061086057508015155b15610870576000925050506106e8565b61087a858561094c565b909250905060018214801561088f5750806001145b1561089f576001925050506106e8565b506000949350505050565b600160a060020a0382166000908152600260209081526040808320600160e060020a03198516845290915281205460ff1615156108f2576108eb83836107ef565b90506106e8565b50600160a060020a03808316600081815260208181526040808320600160e060020a0319871684529091529020549091161492915050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b6040517f01ffc9a7000000000000000000000000000000000000000000000000000000008082526004820183905260009182919060208160248189617530fa90519096909550935050505056fea165627a7a72305820377f4a2d4301ede9949f163f319021a6e9c687c292a5e2b2c4734c126b524e6c002980830c35008080c0b841ac9c42653e0fc87c73bb27349a38d6366689f4b6bab847777b1477295d02d9a312de04dfa074a7de02546cfaa398006833ea4d66ab5765e636f3c036c265cc3101';
```

We generated the `ERC1820_REGISTRY_DEPLOY_TX` by using the following [test](https://github.com/freemanzMrojo/thor/blob/test-eip1820/api/transactions/transactions_test.go#L133) in thor to generate the hex string version of the transaction with the new chain-tag. We also had to use the relevant command to query thor to give us the `ERC1820_REGISTRY_ADDRESS`. Once we had that we updated the two lines in the node module.

### Contract address passed in constructor

The last change that we needed to do is in `ERC777SenderRecipientMock.sol` and `ERC777.sol` respectively. In both cases we changed the line that instantiates `IERC1820Registry` by changing to the correct contract address.

```javascript
IERC1820Registry private _erc1820 = IERC1820Registry(0xb02A08775234755Be24Ba32dA95Cf4509CFcEe86);
```

```javascript
IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0xb02A08775234755Be24Ba32dA95Cf4509CFcEe86);
```

With these changes one can deploy `ERC1820` on thor.

## Contracts Affected

| Contract Name           |
| ----------------------- |
| ERC777                  |
| ERC777PresetFixedSupply |
| ERC1820Implementer      |


# Chain id

## Description

In the VeChain EVM, the `block.chainid` opcode returns the 32-byte genesis block ID, which represents a significantly larger value than the typical `chainId` used in other EVM-compatible networks.

This difference will cause the `eip712Domain` hex values of the contract and the local computation in the EIP712 test cases to be different.

Therefore, we modified the test code. When calculating the `eip712Domain` locally, instead of directly using the value returned by the `eth_chainId` RPC interface, we used `eth_getBlockByNumber` to obtain the ID of the genesis block to ensure that the hex value of `eip712Domain` is the same.

## Contracts Affected

| Contract Name |
| ------------- |
| ERC712        |


# hardhat specific

## Description

The first group or errors that we will discuss is called "Hardhat Specific" errors. These errors occur due to the fact that they expect features that are not available on a normal blockchain node. Since when running the tests on VeChain we are using the `thor` node it is expected to not be able to use the hardhat specific features. In the next section we will explore the two types of hardhat specific failures that we have encountered.


# Ganache failures

## Description

These types of errors are comprised of the common errors between the VeChain tests and the same tests being run on Ganache. We consider these errors justified since they also exist in Ganache.

## Contracts Affected

| Contract Name      |
| ------------------ |
| DoubleEndedQueue   |
| CrossChainEnabled  |
| ERC20Votes         |
| ERC20VotesComp     |
| Checkpoints        |
| ECDSA              |
| AccessControl      |
| CrossChainEnabled  |
| VestingWallet      |
| GovernorWithParams |
| MinimalForwarder   |
| Governor           |
| ERC2771Context     |


# evm\_increaseTime

## Description

`evm_increaseTime` is a feature supported by both Ganache and Hardhat. The basic idea is that we can artificially increase time to some future point manually. This is useful when we are testing contracts that use time-locks, and it is not practical to wait for months on end for a test to finish. Unfortunately, since our plugin is connected to `thor`, which is a real blockchain implementation and not a testing framework like Ganache or Hardhat, this feature is not supported. This is inherent to all blockchains not just VeChain.

## Contracts Affected

| Contract Name           |
| ----------------------- |
| GovernorTimelockControl |
| TimelockController      |
| TokenTimelock           |
| TimersTimestamp         |


# Failures in constructor

## Description

This type of error happens due to the fact that something in the contract's constructor prevents it from being deployed as it fails while running the constructor. This is different from other types of errors where the problem occurs on a test after a contract has been deployed. In this case the error is more severe as the contract fails to be deployed.

## Contracts Affected

| Contract Name               |
| --------------------------- |
| BeaconProxy                 |
| ERC1967Proxy                |
| TransparentUpgradeableProxy |


# eth\_sign

## Description

The `eth_sign` issue arises due to the fact that VeChain and Ethereum use different hash functions, more information on this subject [here](https://github.com/vechain/vechain-docs/blob/main/core-concepts/evm-compatibility/test-coverage/broken-reference/README.md). This failure is justifiable as it is a design difference between the two chains. To fix the failing tests, we imported Ethereum's hash function and replaced the `eth_sign` method with one that generates signatures using the required hash function.

The following changes we made:

#### In `compatProvider.ts`

In `web3-providers-connex/src/compatProvider.ts` we changed the error response returned to the following:

```javascript
.catch(err => callback(err, {
				id: payload.id,
				jsonrpc: '2.0',
				error: err
			}));
```

#### In `provider.ts`

In `web3-providers-connex/src/provider.ts` we imported `hashEthMessage` and `bufferToHex` from `utils.js`

```javascript
import { hexToNumber, getErrMsg, toSubscription, toHex, hashEthMessage, bufferToHex } from './utils';
```

We also added the method `eth_sign` in the method map

```javascript
this._methodMap['eth_sign'] = this._sign;
```

and defined the function in the same file

```javascript
private _sign = async (params: any) => {
		if (!this.wallet || this.wallet.list.length === 0) {
			throw new Error("no wallet specified");
		}

		const address = params[0];
		const message = params[1];

		const key = this.wallet.list.find((key) => key.address == address);

		if (key === undefined) {
			throw new Error(`key undefined for address ${address}`)
		}

		const hash = hashEthMessage(message);

		if (hash === undefined) {
			throw new Error("undefined hash");
		}

		const hashStriped = hash?.substring(2);
		const buf = Buffer.from(hashStriped!, 'hex');

		const signature = await key.sign(buf);
		signature[64] += 27;

		return bufferToHex(signature);
	}
```

#### In `utils.ts`

In `web3-providers-connex/src/utils.ts` we imported `keccak256` from 'thor-devkit'.

```javascript
import { abi, keccak256, Transaction } from 'thor-devkit';
```

Then we defined two new functions `hashEthMessage` that hashes a string with Ethereum's hash function and a helper function `bufferToHex`.

```javascript
export function bufferToHex(buf: Buffer) : string {
	return '0x' + buf.toString('hex');
}

export function hashEthMessage(data: string) : string {
	const messageHex = web3Utils.isHexStrict(data) ? data : web3Utils.utf8ToHex(data);
	const messageBytes = web3Utils.hexToBytes(messageHex);
	const messageBuffer = Buffer.from(messageBytes);
	const preamble = '\x19Ethereum Signed Message:\n' + messageBytes.length;
	const preambleBuffer = Buffer.from(preamble);
	const ethMessage = Buffer.concat([preambleBuffer, messageBuffer]);
	return bufferToHex(keccak256(ethMessage));
```

#### In `getChainId.test.ts`

The final change was in `web3-providers-connex/test/web3/getChainId.test.ts` where we replaced the main-net URL with the local instance of thor instead.

```javascript
const net = new SimpleNet("http://127.0.0.1:8669");
```

## Contracts Affected

| Contract Name    |
| ---------------- |
| SignatureChecker |


# Contract address prediction

## Description

Some contracts require another contract's address in their constructor. For various reasons the required contract instance might not be deployed at the time when our contract is being deployed. Thus, we need a way to predict or pre-generate the required contract's address before its deployed. Since Openzeppelin was written for Ethereum, the contract prediction code takes into account how Ethereum addresses are generated. But since VeChain differs in that regard some tests fail since the predicted address is wrong and there is no deployed contract in that address. Specifically, the address of a contract is predicted by incrementing the nonce of an address which can be obtained by the web3 plugin:

```javascript
const nonce = await web3.eth.getTransactionCount(deployer);
const predictGovernor = makeContractAddress(deployer, nonce + 1);
```

Unfortunately, VeChain's `web3-providers-connex` library does not yet support getting the transaction count for an address. Thus, we have to manually set the address after the contract is deployed. See below which contracts are affected.

## Contracts Affected

| Contract Name              |
| -------------------------- |
| GovernorTimelockCompound   |
| GovernorCompatibilityBravo |


# BadBeacon proxy address at 0x1

## Description

The issue described in this section occurs because the `BadBeaconNotContract` returned an invalid address. The necessary change in order to fix this issue was to replace the returned address `0x1` with `0xFFF`.

```solidity
contract BadBeaconNotContract {
    function implementation() external pure returns (address) {
        return address(0xFFF);
    }
```

## Contracts Affected

| Contract Name |
| ------------- |
| BeaconProxy   |


# How to Recreate

A tutorial on how to recreate the OpenZeppelin tests locally using a Thor Solo node.

## Run a Thor Solo Node

Use the tutorial [How to run a Thor Solo Node](/how-to-run-a-node/how-to-run-a-thor-solo-node) to start up a thor solo node.

## Configure a Development Environment

### Clone openzeppelin-contracts

```bash
git clone git@github.com:OpenZeppelin/openzeppelin-contracts.git
cd openzeppelin-contracts
```

### Install the required VeChain libraries

```bash
npm install @vechain/hardhat-vechain@0.0.1 --save-exact
npm install @vechain/hardhat-web3@0.0.1 --save-exact
npm install @vechain/web3-providers-connex@1.0.0 --save-exact
```

### Modify your hardhat.config.js

Add the following to your hardhat config

```javascript
require("@vechain/hardhat-vechain");
require("@vechain/hardhat-web3");
```

Add the VeChain network settings

```javascript
   vechain: {
      url: "http://127.0.0.1:8669",
      accounts: {
        mnemonic: "denial kitchen pet squirrel other broom bar gas better priority spoil cross",
        count: 10,
      },
      restful: true,
      gas: 10000000,
      delegate: {
        url: "hello",
        signer : "world"
      },
    },
```

## Run the OpenZeppelin Tests

Assuming you have cloned OpenZeppelin and are running thor locally in solo mode we can now move on to running the OpenZeppelin tests. First navigate to the appropriate directory.

```bash
cd openzeppelin-contracts
```

### Run a single test

```bash
npx hardhat test --network vechain test/access/AccessControlEnumerable.test.js
```

### Run all tests

```bash
npx hardhat test --network vechain
```

## Running VeChain custom fork

This section explains how to run the custom tests adapted to run on VeChainThor blockchain. This fork is based on [OpenZeppelin version 5](https://github.com/OpenZeppelin/openzeppelin-contracts/releases/tag/v5.0.2).

### Clone openzeppelin-contracts

```bash
git clone -b thor-compatibility git@github.com:vechain/openzeppelin-contracts.git
cd openzeppelin-contracts
```

### Run thor solo

When running the custom fork you need to increase the gas limit.

```bash
bin/thor solo --on-demand --gas-limit 10000000000
```

## Run the OpenZeppelin Tests

Assuming you have cloned OpenZeppelin and are running thor locally in solo mode we can now move on to running the OpenZeppelin tests. First navigate to the appropriate directory.

```bash
cd openzeppelin-contracts
```

### Run a single test

```bash
npx hardhat test --network vechain test/access/AccessControlEnumerable.test.js
```

### Run all tests

> **⚠️ Disclaimer**: Running the complete OpenZeppelin test suite can take several hours due to Thor Solo's processing limitations. Consider running tests in smaller batches.

```bash
npm run test:solo
```

### Run all tests in a specific directory (OZ5)

```bash
npm run test:solo:dir <dir_relative_path>
```

### Results

All the tests in the custom fork are expected to pass.


# How to run a node

To interact with the blockchain, a node is required.

The node is the blockchain client, that runs locally and connects to the distributed network of all the other clients. Every node holds a local copy of the blockchain and can potentially participate in the consensus.

Dapps do require to push and pull information to and from the blockchain, to do so, they will require to be connected to a node. In many cases, a remote connection to a public node is sufficient.

Public nodes are hosted by organizations like VeChain, and are particularly helpful for "light-clients" like wallets to avoid having the weight of a local copy of the blockchain, and of the time required to being operative, since a new node requires to download all the history before being ready. Of course, the machine performance of a public node is shared across the users, even when allocating multiple machines and systems to balance demand, they have an upper limit that might not match what the dapp requires. In such cases, but also for additional trust and to avoid the eventuality of censorship, running a node is recommended.

Mastering VeChainThor nodes opens up a world of possibilities in blockchain development. Whether you're running a local Thor Solo Node for development or connecting to public nodes for production, understanding these concepts is crucial for building robust, blockchain-powered applications.

By leveraging the power of nodes, the flexibility of the Thorest API, and the development-friendly environment of Thor Solo, you're well-equipped to innovate on the VeChainThor blockchain. Happy building!

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Nodes</td><td><a href="/pages/nEbT7UlG5FLtTolT39UD">/pages/nEbT7UlG5FLtTolT39UD</a></td></tr><tr><td align="center">How to run a Thor Solo Node</td><td><a href="/pages/ZHvJ6XdHITFdApJKvR43">/pages/ZHvJ6XdHITFdApJKvR43</a></td></tr><tr><td align="center">Validator Key Management</td><td><a href="https://github.com/vechain/vechain-docs/blob/main/how-to-run-a-node/validator-key-management.md">https://github.com/vechain/vechain-docs/blob/main/how-to-run-a-node/validator-key-management.md</a></td></tr><tr><td align="center">Custom Network</td><td><a href="/pages/Iy3WQZlzkPvvyRPkOIns">/pages/Iy3WQZlzkPvvyRPkOIns</a></td></tr><tr><td align="center">Connect Sync2 to a Thor Solo Node</td><td><a href="/pages/XfLSZ4vTJCJPhxEP77Os">/pages/XfLSZ4vTJCJPhxEP77Os</a></td></tr></tbody></table>


# Nodes

RESTful API to access the VeChainThor blockchain

## Overview

In previous chapters, we discussed some scenarios where it can be convenient for a dApp to use a local or public node. Regardless of the choice, the interface for interacting with VeChainThor blockchain are the RESTful APIs specifically designed known as the Thorest API. This modern interface facilitates seamless interaction with the blockchain, enabling developers and users to harness its full potential.

## Thorest API: Powering Blockchain Communication

The Thorest API stands as the primary communication channel for the VeChainThor blockchain. It offers a comprehensive set of endpoints that allow for diverse interactions, from querying blockchain data to submitting transactions.

For the latest information of each of the available endpoints please use the following link [Thorest API Repo](https://github.com/vechain/thor/blob/16c5d34cfea8262e9fe91bd33b298c8e2f81da21/api/doc/thor.yaml).

## Monitoring Node Health

VeChain prioritizes network performance and reliability. To support this, two key resources are available for node health monitoring:

* Official VeChain Status Page: <https://status.vechain.org/>, with the following filters: <https://mainnet.status.vechain.org>, <https://testnet.status.vechain.org>.
* VeChain Energy Status Page: <https://nodes.status.vechain.energy/>.

These dashboards provide real-time insights into node health, network stability, and overall ecosystem performance. Regular checks can help users and developers ensure optimal connectivity and stay informed about the network's status.

## Mainnet Nodes

<table><thead><tr><th width="277">Provider</th><th width="560">Link</th></tr></thead><tbody><tr><td>VeChain</td><td><a href="https://mainnet.vecha.in/">mainnet.vecha.in</a></td></tr><tr><td>VeChain</td><td><a href="https://sync-mainnet.vechain.org/">sync-mainnet.vechain.org</a></td></tr><tr><td>VeChain</td><td><a href="https://vethor-node.vechain.com/">vethor-node.vechain.com</a></td></tr><tr><td>Veblocks</td><td><a href="https://mainnet.veblocks.net/">mainnet.veblocks.net</a></td></tr><tr><td>Veblocks</td><td><a href="https://mainnet02.vechain.de.blockorder.net/">mainnet02.vechain.de.blockorder.net</a></td></tr><tr><td>Veblocks</td><td><a href="https://mainnet02.vechain.fi.blockorder.net/">mainnet02.vechain.fi.blockorder.net</a></td></tr><tr><td>SafeTech</td><td><a href="https://mainnetc1.vechain.network/">mainnetc1.vechain.network</a></td></tr><tr><td>SafeTech</td><td><a href="https://mainnetc2.vechain.network/">mainnetc2.vechain.network</a></td></tr><tr><td>VeChain Energy</td><td><a href="https://de.node.vechain.energy/">de.node.vechain.energy</a></td></tr><tr><td>VeChain Energy</td><td><a href="https://us.node.vechain.energy/">us.node.vechain.energy</a></td></tr></tbody></table>

## Testnet Node

<table><thead><tr><th width="280">Provider</th><th>Link</th></tr></thead><tbody><tr><td>VeChain</td><td><a href="https://testnet.vecha.in/">testnet.vecha.in</a></td></tr><tr><td>VeChain</td><td><a href="https://sync-testnet.vechain.org/">sync-testnet.vechain.org</a></td></tr><tr><td>VeChain</td><td><a href="https://vethor-node-test.vechaindev.com/">vethor-node-test.vechaindev.com</a></td></tr><tr><td>Veblocks</td><td><a href="https://testnet.veblocks.net/">testnet.veblocks.net</a></td></tr><tr><td>Veblocks</td><td><a href="https://testnet02.vechain.de.blockorder.net/">testnet02.vechain.de.blockorder.net</a></td></tr><tr><td>Veblocks</td><td><a href="https://testnet02.vechain.fi.blockorder.net/">testnet02.vechain.fi.blockorder.net</a></td></tr><tr><td>SafeTech</td><td><a href="https://testnetc1.vechain.network/">testnetc1.vechain.network</a></td></tr></tbody></table>

## Getting started

To begin interacting with the VeChainThor blockchain:

* Choose a suitable node (mainnet or testnet) based on your project requirements.
* Familiarize yourself with the Thorest API documentation.
* Implement API calls in your application to read from or write to the blockchain.
* Utilize the node status page to ensure you're connecting to healthy, responsive nodes.

By leveraging these tools and resources, developers can create robust, blockchain-powered applications on the VeChainThor network, tapping into its unique features and capabilities.


# How to run a Thor Solo Node

A thor solo node is a VeChainThor blockchain node running in a sandbox, particularly useful for developers who might need to wait for a specific condition to be met, that in a living environment would

A [Thor](https://github.com/vechain/thor) Solo Node is a powerful tool for developers, offering a sandbox environment to interact with the VeChainThor blockchain. This guide will walk you through the setup and operation of your own Thor Solo Node, enabling you to test and develop applications in a controlled setting.

## Installation Process

Clone the Thor repository:

```bash
git clone https://github.com/vechain/thor
```

Navigate to the Thor directory and build:

```bash
cd thor
make
```

Upon successful compilation, you'll find the `thor` binary in the `bin` directory.

## Key Command-line Options

Explore Thor's capabilities with `./bin/thor -h`. Essential options include:

* `--api-cors '*'`: Accept cross-origin requests from any domain.
* `--api-addr value`: Set API service listening address (default: "localhost:8669").
* `--api-call-gas-limit value`: Limit contract call gas (default: 50000000).
* `--verbosity value` log verbosity (0-9) (default: 3).

## Advanced Configuration

### Sub-Commands for Enhanced Control

Thor offers versatile sub-commands:

```bash
./bin/thor solo --on-demand            # Create new blocks for pending transactions
./bin/thor solo --persist              # Save blockchain data to disk
./bin/thor solo --persist --on-demand  # The two options can work together
```

### Enabling Remote Access

If Thor node is not running on the same machine of the development environment, then you need to provide an API listening address using the `--api-addr` command-line option. For example, to make Thor accept any remote connection:

```bash
./bin/thor solo --on-demand --api-addr 0.0.0.0:8669
```

### Debugging with Increased Verbosity

The default verbosity option in Thor (3) might not be providing enough debug information. Using the `--verbosity` command-line option, you can increase the amount of information Thor prints out in stdout. For example:

<pre class="language-bash"><code class="lang-bash"><strong>./bin/thor solo --on-demand --verbosity 4
</strong></code></pre>

### Master Key Management

Secure your node with master key commands:

```bash
# View master address
./bin/thor master-key

# Export master key to keystore
./bin/thor master-key --export > keystore.json

# Import master key from keystore
cat keystore.json | ./bin/thor master-key --import
```

## RESTful API: A Developer's Playground

Thor's RESTful API offers a user-friendly interface for blockchain interaction. Access the Stoplight UI at:

```bash
http://127.0.0.1:8669/doc/stoplight-ui/
```

Or the Swagger UI at:

```bash
http://127.0.0.1:8669/doc/swagger-ui/
```

If Thor is running on a different host, make sure to run it using the IP of said host instead of the localhost, as well as the `--api-addr` command-line option.

## Launching Your Solo Node

To run the node in solo mode which is what we need for development purposes use the following:

```bash
./bin/thor solo --on-demand
```

{% hint style="info" %}
Thor can also be run with a test or main network by passing the command

`--network test | main`

A custom network can also be created by passing the command

`--network <custom-net-genesis.json>`

An example genesis config file can be found at [genesis/example.json](https://raw.githubusercontent.com/vechain/thor/master/genesis/example.json).
{% endhint %}

For development purposes the following flags are recommended

{% hint style="warning" %}
The below command runs thor solo allowing all remote connections. Remove the argument `--api-addr 0.0.0.0:8669` to prevent all remote connections.
{% endhint %}

<pre class="language-bash"><code class="lang-bash"><strong>./bin/thor solo --on-demand --api-addr 0.0.0.0:8669 --gas-limit 10000000000000 --api-call-gas-li
</strong></code></pre>

## Docker: Containerized Convenience

The most convenient way can be to use a Docker container. You can run your solo node as follows:

```bash
docker run -p 127.0.0.1:8669:8669 vechain/thor:latest solo --api-cors '*' --api-addr 0.0.0.0:8669
```

This sets up a containerized node with:

* Localhost access on port 8669
* Latest Thor Solo release
* Unrestricted cross-origin requests
* Remote connection capability

## Conclusion

With your Thor Solo Node up and running, you're ready to dive into VeChainThor development. This powerful tool provides a flexible, controlled environment for building and testing blockchain applications. Happy coding!


# Custom Network

To start your own custom network, you need to manually configure the genesis file. Once you finished the setup, it allows you to connect to your own network rather than connect to official network (mainnet / testnet)

## Prerequisites <a href="#requirement" id="requirement"></a>

1. Make sure the network has at least **two** nodes running as a authority master node
2. Thor version ≥ [v1.0.7](https://github.com/vechain/thor/releases/tag/v1.0.7)

{% hint style="info" %}
Running a custom network requires prior knowledge of the [Built-in Contracts](/developer-resources/built-in-contracts)and [Consensus Deep Dive](/introduction-to-vechain/about-the-vechain-blockchain/consensus-deep-dive#proof-of-authorithy-poa)
{% endhint %}

## Configure Your Genesis File <a href="#configure-your-genesis-file" id="configure-your-genesis-file"></a>

You can find an example genesis file [here](https://github.com/vechain/thor/blob/master/genesis/example.json)

### Genesis Description Object <a href="#genesis-description-object" id="genesis-description-object"></a>

* `launchTime`: Launch time (unix timestamp) of your network (i.e. the time of genesis block). If you set the time in the future, master node would not propose block before that.
* `gasLimit`: Initial block gas limit.
* `extraData`: Additional data set to genesis block, limited to 28 characters.
* `accounts`: Preallocated accounts in genesis block, including `balance`, `energy`, `storage` and `code`.
* `authority`: Authority master nodes.
* `params`: Governance parameters.
* `executor`: Executor params for on-chain governance, setting approvers means using VeChain builtin executor, omit means an external address.

### Authority <a href="#authority" id="authority"></a>

For setting the authority node, you need to get your authority node's master address first, simply running the following command

```
thor master-key
```

The master address will be shown. `Endorsor Address` is the endorser's address for authority node, you need to ensure the `Endorsor Address` reach the minimum amount of `proposerEndorsement`. You can adjust the minimum endorsement amount of VET by changing `proposerEndorsement`. `Identity` is an identifier of the authority node.

### Params <a href="#params" id="params"></a>

* `rewardRatio`: Reward ratio for block proposer.
* `baseGasPrice`: Base gas price in `wei`.
* `proposerEndorsement`: Authority node endorsement in `wei`.
* `executorAddress`: Executor address, if there is approver in `executor`, the address will be set code of `Builtin Executor Contract` and set up the approves, otherwise the executor will be an external address.

## Launch Custom Network <a href="#launch-custom-network" id="launch-custom-network"></a>

Start all your nodes by running `thor --network genesis.json` and wait for the nodes to connect to each other and then the master nodes will start packing the blocks.

### Custom Bootnode <a href="#custom-bootnode" id="custom-bootnode"></a>

Starting a custom network will use the foundation's bootnode to discover nodes by default. This means you need at least 1 node with public IP attached. Thor provides the ability to specify bootnode.

1. Start thor by `thor --network genesis.json` then get `Node ID` in the startup info, it looks like `enode://0b9f...6932@[extip]:11235`.
2. Replace `[extip]` with the real ip address of your machine.
3. Launch nodes by running `thor --network genesis.json --bootnode "NodeID-1,NodeID-2..."`.


# Connect Sync2 to a Thor Solo Node

This tutorial will provide a step by step guide for running a Thor solo node and connecting it to the Sync2 wallet. The Thor solo node is a sandbox development mode for the VeChainThor blockchain, that can be started (and is only available) on a single server. It is not publicly accessible and the generated blocks will be lost if the solo node is stopped.

## Step 1 : Launch the solo node <a href="#step-1-launch-the-solo-node" id="step-1-launch-the-solo-node"></a>

Run Thor solo with the following docker command or follow the [https://github.com/vechain/vechain-docs/blob/main/how-to-run-a-node/how-to-run-a-thor-solo-node/README.md](https://github.com/vechain/vechain-docs/blob/main/how-to-run-a-node/how-to-run-a-thor-solo-node/README.md "mention") tutorial.

```bash
docker run -p 127.0.0.1:8669:8669 vechain/thor:latest solo --api-cors '*' --api-addr 0.0.0.0:8669
```

This will launch a solo node with the following configuration:

* On a localhost using port 8669
* Using the latest release of thor solo
* Accepting all cross origin requests
* Allowing all remote connections

## Step 2 : Connect Sync2 node to solo node <a href="#step-2-connect-sync2-node-to-solo-node" id="step-2-connect-sync2-node-to-solo-node"></a>

Sync2 is designed to work with all mainstream web browsers (e.g., Chrome, Safari, MS Edge, Firefox, etc), desktop, and mobile devices.

The main advantage and purpose of Sync2 is the massive simplification of dApps and dApp usage. All editions of Sync2, no matter whether the native app is built for desktop or mobile or the automatically invoked SPA version, are designed to appear and function pretty much in the same way, therefore providing a consistent and comfortable user experience for users across different OS and devices.

### Get Sync2 <a href="#get-sync2" id="get-sync2"></a>

Follow the instructions here [Sync2 (Legacy)](/core-concepts/wallets/sync2) to download and install the Sync2 wallet.

### Connect Sync2 to solo node <a href="#connect-sync2-to-solo-node" id="connect-sync2-to-solo-node"></a>

#### **Step1: Add node**

1. Click the ![](/files/7GUklMCvyo1DvxxhE0dJ)icon, in the top left hand corner.
2. Click **Settings**.
3. Click **Nodes**.
4. Click the ![](/files/Sm475ccsKsPUah7PPU5L) icon, in the upper right hand corner.
5. Enter the node's url `http:localhost:8669.`
6. Click **Add** to add node.

#### **Step2: Import the solo built-in wallet**

1. Click upper left ![](/files/7GUklMCvyo1DvxxhE0dJ) icon, in the top left hand corner, to open the wallet list.
2. Click the ![](/files/Sm475ccsKsPUah7PPU5L)icon to create a new wallet.
3. Click upper right ![](/files/5aNIeIKgH7G0iley6MH8) icon.
4. Select **Private.**
5. Click **Import.**
6. Enter the mnemonic words for the Thor solo node built-in wallet.

{% hint style="info" %}
Mnemonic phrase of the Thor solo node built-in wallet:

denial kitchen pet squirrel other broom bar gas better priority spoil cross
{% endhint %}

{% hint style="danger" %}
Do not use the above mnemonic phrase to secure mainnet assets. The funds will not be secure as the mnemonic is exposed.
{% endhint %}

7. Enter your password to authorize the import

Congrats! You have successfully connected to a Thor solo node with the Sync2 wallet.

### Step 3: Launch Devpal <a href="#step-3-launch-devpal" id="step-3-launch-devpal"></a>

Devpal is a set of tools to help your develop and test on a Thor solo mode and start your blockchain journey smoothly. Devpal contains two tools:

* **Insight**: a serverless VeChain explorer. It allows you to explore and search for blocks, transactions, and accounts. [Mainnet](https://insight.vecha.in/#/main/) and [Testnet](https://insight.vecha.in/#/test/) links.
* **Inspector**: a tool that allows you to deploy and interact with the contract. Available [here](https://inspector.vecha.in/).

You can simply run devpal by running the following command:

```bash
npx @vechain/devpal
```

{% hint style="info" %}
***<http://locahost:8669>*** is set as the default node url.

If you want to change it, please use `npx @vechain/devpal [Thor REST URL]`
{% endhint %}


# Developer Resources

The following section outlines key development resources and tools needed to build and interact with the VeChainThor blockchain.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center">Getting Started</td><td><a href="/pages/HAd4LsZ73MogGs3cDXwL">/pages/HAd4LsZ73MogGs3cDXwL</a></td></tr><tr><td align="center">How to build on VeChain</td><td><a href="/pages/JEBeVZPapzDGB4cGDu01">/pages/JEBeVZPapzDGB4cGDu01</a></td></tr><tr><td align="center">Example dApps</td><td><a href="/pages/5bK4ipLMbTCYG98Devfu">/pages/5bK4ipLMbTCYG98Devfu</a></td></tr><tr><td align="center">How to verify Address-Ownership</td><td><a href="/pages/3izwwgAE8LIC0sBPgdFO">/pages/3izwwgAE8LIC0sBPgdFO</a></td></tr><tr><td align="center">Debug Reverted Transactions</td><td><a href="/pages/zxbKJEQMISKz5yfMEU69">/pages/zxbKJEQMISKz5yfMEU69</a></td></tr><tr><td align="center">Account Abstraction</td><td><a href="/pages/g2QfrWYbVdP6AT9jFTP9">/pages/g2QfrWYbVdP6AT9jFTP9</a></td></tr><tr><td align="center">VIP-191: Designated Gas Payer</td><td><a href="/pages/39Nl6dnc6ZivjrrYbg1y">/pages/39Nl6dnc6ZivjrrYbg1y</a></td></tr><tr><td align="center">Index with Graph Node</td><td><a href="/pages/lo6RbMqhldITCm4WjImo">/pages/lo6RbMqhldITCm4WjImo</a></td></tr><tr><td align="center">SDKs &#x26; Providers</td><td><a href="/pages/0B8hJiENMBrUiUk6o2hl">/pages/0B8hJiENMBrUiUk6o2hl</a></td></tr><tr><td align="center">Frameworks &#x26; IDEs</td><td><a href="/pages/qfyygFhaDqF1M6Vra6JB">/pages/qfyygFhaDqF1M6Vra6JB</a></td></tr><tr><td align="center">Built-in Contracts</td><td><a href="/pages/iCjhEg7w5cwFaeQ2XLbC">/pages/iCjhEg7w5cwFaeQ2XLbC</a></td></tr><tr><td align="center">VORJ</td><td><a href="/pages/hjAgvMPe3sMJJpSsPXFq">/pages/hjAgvMPe3sMJJpSsPXFq</a></td></tr><tr><td align="center">Useful Links</td><td><a href="/pages/opQrpGhGcEWMfclsBrei">/pages/opQrpGhGcEWMfclsBrei</a></td></tr></tbody></table>


# Getting Started

Your gateway to developing VeChain dApps

## What is a dApp?

A dApp (decentralized application) is a software application that operates on a distributed network, typically using blockchain technology. Unlike traditional centralized applications, dApps run on a peer-to-peer network of computers, often utilizing smart contracts on a blockchain for enhanced security and transparency.

## Prerequisites

Before diving into dApp development, ensure you have:

* A solid understanding of blockchain fundamentals.
* Experience with Solidity (for smart contracts) and JavaScript (for front-end development).
* A VeChain-compatible [wallet](/core-concepts/wallets) for testing.

## Quick Start with VeChain Templates

Jump-start your development with our [pre-built templates](https://www.npmjs.com/package/create-vechain-dapp):

```bash
npm create vechain-dapp
```

or

```bash
yarn create vechain-dapp
```

or

<pre class="language-bash"><code class="lang-bash"><strong>npx create-vechain-dapp@latest
</strong></code></pre>

## Development Roadmap

#### 1. Design your dApp

Outline your dApp's functionality, user interface, and key features.

#### 2. **Develop Smart Contracts**

Create Solidity smart contracts to define your dApp's core logic.

* Utilize our [Remix plugin](/developer-resources/frameworks-and-ides/remix) or [Hardhat plugin](/developer-resources/frameworks-and-ides/hardhat) for a seamless development experience.
* Leverage [Built-in Contracts](/developer-resources/built-in-contracts) to enhance functionality.

#### 3. **Build the Front-End**

Craft an intuitive user interface using modern web technologies.

* Implement easy wallet login with [dappKit](/developer-resources/sdks-and-providers/dapp-kit/dapp-kit-1).
* Add social login and get many hooks and features with [VeChain-kit](broken://pages/ENiNTdc6ZOKZZyHb41En).
* Use our comprehensive [SDK](/developer-resources/sdks-and-providers/sdk) for efficient blockchain interactions.
* Connect to VeChainThor via our [node endpoints](https://docs.vechain.org/core-concepts/nodes).

#### 4. **Test Thoroughly**

* Deploy and test on the [VeChainThor Solo Node](/core-concepts/networks/thor-solo-node) before going live.
* Utilize [Devpal](/developer-resources/sdks-and-providers/devpal)for streamlined development and testing.

#### 5. **Launch Your dApp**

Submit your dApp to the [VeChain App Hub](https://apps.vechain.org/#all) for increased visibility.

By following this guide, you'll be well-equipped to create robust, scalable dApps on the VeChainThor blockchain. Happy coding!


# How to build on VeChain


# Connect to the Network

How to connect with to VeChainThor blockchain using @vechain/sdk-network

Interacting with VeChainThor requires only an instance of `ThorClient` that is configured for the relevant network. Once the connection is established, this instance can be utilized to interact in an asynchronous manner. Below is a snippet that demonstrates importing the library and initializing a client:

```js
import { ThorClient } from "@vechain/sdk-network";
const thor = ThorClient.at("https://mainnet.vechain.org");
```

The snippet connects to the MainNet, where all production related activity is found.

Additionally there is a TestNet available for testing and development purposes. This allows developers to experiment without risking real assets.

To connect to the TestNet use `https://testnet.vechain.org` as URL. If you have deployed a [thor solo node](/how-to-run-a-node/how-to-run-a-thor-solo-node), it is normally available on `http://localhost:8669`.

{% hint style="info" %}
The `ThorClient` uses a `HttpClient` underneath to communicate with the VeChain nodes with a [JSON API](https://mainnet.vechain.org/doc/swagger-ui/).

The default [`HttpClient` implementation is using Fetch](https://github.com/vechain/vechain-sdk-js/blob/v1.0.0/packages/network/src/utils/http/http-client.ts) and can be replaced with any custom implementation as long as the interfaces are met.
{% endhint %}

To test the connectivity we'll get request the first and last block from the chain and output their number & id:

```js
// get the current latest & best block from the chain
const bestBlock = await thor.blocks.getBestBlockCompressed();
console.log("Best Block:", bestBlock.number, bestBlock.id);

// get the first and genesis block from the chain
const genesisBlock = await thor.blocks.getBlockCompressed(0);
console.log("Genesis Block:", genesisBlock.number, genesisBlock.id);
```

You can test the above snippet here:

{% embed url="<https://stackblitz.com/github/vechain-energy/example-snippets/tree/v1.0.0/sdk/connect?ctl=1&embed=1&file=index.mjs&hideExplorer=1&hideNavigation=1&view=editor>" %}

{% hint style="info" %}
The `ThorClient` provides a multitude of properties with access to all relevant functionality on VeChain. You can find examples and details about all of them in the [Thor Client docs](/developer-resources/sdks-and-providers/sdk/thor-client).
{% endhint %}


# Read Data

The data within the blockchain is separated into different components, where blocks represent chunks of data continuously added to the chain. Within a block are transactions with instructions and changes, executed by accounts which can be either user or contract controlled.


# Read Blocks

A block is a change to the blockchain storage with a batch of changes that happen simultaneously. With VeChain, every \~10s a new block is generated, even if no transaction has been published.

The most relevant information for interacting with Blocks includes:

* **number**: the number of the block
* **id**: a unique id representing the block
* **parentID**: the previous block the block is based on
* **timestamp**: the unix time at which the block was stored
* **isFinalized**: is the block securely finalized in a snapshot
* **transactions**: contain either all transaction ids or full transaction details including receipts

There are two methods to obtain block details:

1. The *compressed* version, which includes all data and only the transaction IDs.
2. The *expanded* version, which also encompasses full transaction details along with the generated outputs.

A block can be requested as number, id and additionally the reserved words "best" and "finalized" reference the latest or epoch ending blocks.

```js
const blockNumber = 12345678;

// get the block and transaction ids within it
const compressed = await thor.blocks.getBlockCompressed(blockNumber);
console.log(compressed);

// get the block and transaction data including receipts
const expanded = await thor.blocks.getBlockExpanded(blockNumber);
console.log(expanded);
```

Test it yourself:

{% embed url="<https://stackblitz.com/github/vechain-energy/example-snippets/tree/v1.0.0/sdk/read-block?ctl=1&embed=1&file=index.mjs&hideExplorer=1&hideNavigation=1&view=editor>" %}

Type definition and documentation of all attributes:

* [Compressed Block Detail](https://vechain.github.io/vechain-sdk-js/classes/_vechain_sdk_network.BlocksModule.html#getBestBlockCompressed)
* [Expanded Block Detail](https://vechain.github.io/vechain-sdk-js/classes/_vechain_sdk_network.BlocksModule.html#getBestBlockExpanded)

The same information is available using the JSON-API:

* [GET /blocks/{block}](https://mainnet.vechain.org/blocks/12345678)
* [GET /blocks/{block}?expanded=true](https://mainnet.vechain.org/blocks/12345678?expanded=true)

### **Special Blocks**

There are specific keywords associated with special blocks:

* **Genesis** refers to the initial block (number `0`) on a chain, serving also to identify the chain (chain ID) in the ecosystem and among similar networks (EVMs).
* **Best** represents the most recent block, typically having a maximum age of 10 seconds, as a new block is added every 10 seconds.
* **Final** denotes the most recent finalized block, marking the end of an epoch. It is guaranteed that there will be no further re-ordering or changes. A checkpoint happens every 180 blocks and finalization of a checkpointed block occurs again after 180 blocks.


# Read Transactions

A transaction is a request for a change on the blockchain, which can either be a transfer of VET or the execution of a contract's function. Each transaction is signed and submitted by a single entity and may contain multiple instructions, known as multi-clause, to interact with various recipients on the blockchain.

The most relevant information of a transaction includes:

* **id**: The unique identifier of the transaction.
* **chainTag**: Identifies the chain to which the transaction belongs.
* **blockRef**: The block on which the call was based.
* **expiration**: The maximum number of blocks within which the transaction must be included in the blockchain (based on `blockRef`), or it will fail.
* **dependsOn**: Requires this transaction id to be successful first before being included in the blockchain.
* **origin**: The sender of the transaction.
* **meta**: Information about the block where this transaction was included, providing more details about time and block through **blockID**, **blockNumber**, and **blockTimestamp**.
* **reverted**: Indicates whether the transaction failed.
* **clauses**: The instructions to be executed, including a list of the recipients to be called, the data sent, and potential VET transfer values.
* **outputs**: Events that have been emitted as a result of the executed instructions.

A transaction's complete details are comprised of two main components:

1. The basic version, which includes all input data and details on how the transaction is stored.
2. The receipt, which lists all changes emitted by the blockchain, including:
   * the reverted flag,
   * the address of a newly deployed contract,
   * VET transfers,
   * events initiated by contracts.

Example snippet to access transaction details:

```js
// get a single transaction
const txId =
  '0xfc99fe103fccbe61b3c042c1da3499b883d1b17fb40160ed1170ad5e63751e07';
const tx = await thor.transactions.getTransaction(txId);
console.log(tx);

// load effected changes & outputs with the transaction
const txReceipt = await thor.transactions.getTransactionReceipt(txId);
console.log(txReceipt);
```

if your transaction is still pending, the receipt will be `null`, so if you wish to wait for your transaction receipt you will need to use waitForTransactionReceipt instead.

```ts
// load effected changes & outputs with the transaction
const txReceipt = await thor.transactions.waitForTransactionReceipt(txId);
console.log(txReceipt);
```

Test it yourself:

{% embed url="<https://stackblitz.com/edit/vechain-academy-read-transaction?embed=1&file=index.mjs&hideExplorer=1&hideNavigation=1&view=editor>" %}

Type definition and documentation of all attributes:

* [Transaction Body](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.TransactionBodyOptions.html)
* [Transaction Receipt](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.TransactionReceipt.html)

The same information is available using the JSON-API:

* Successful Transaction: [GET /transactions/{transactionId}](https://mainnet.vechain.org/transactions/0xfc99fe103fccbe61b3c042c1da3499b883d1b17fb40160ed1170ad5e63751e07)

```
{
  "id": "0xfc99fe103fccbe61b3c042c1da3499b883d1b17fb40160ed1170ad5e63751e07",
  "type": 0,
  "chainTag": 74,
  "blockRef": "0x00bc614dda10f9e1",
  "expiration": 720,
  "clauses": [
    {
      "to": "0x0000000000000000000000000000456e65726779",
      "value": "0x0",
      "data": "0xa9059cbb00000000000000000000000011e1b586dd371471d0b52046ee3d4309a6c29c6c0000000000000000000000000000000000000000000000009087b2e881f47600"
    }
  ],
  "gasPriceCoef": 0,
  "gas": 90000,
  "origin": "0x2d7c8293b20344223668ed3fd88301381dc35ce0",
  "delegator": null,
  "nonce": "0xe83fd778763a5360",
  "dependsOn": null,
  "size": 193,
  "meta": {
    "blockID": "0x00bc614e285d68f8819b6dfdd729dad6fafbed9d2fdd65b57e4001a47d7f280c",
    "blockNumber": 12345678,
    "blockTimestamp": 1653978240
  }
}
```

* Successful Transaction Receipt: [GET /transactions/{transactionId}/receipt](https://mainnet.vechain.org/transactions/0xfc99fe103fccbe61b3c042c1da3499b883d1b17fb40160ed1170ad5e63751e07/receipt)

```
{
  "gasUsed": 36582,
  "gasPayer": "0x2d7c8293b20344223668ed3fd88301381dc35ce0",
  "paid": "0x513a75a0fbbc000",
  "reward": "0x185e567d1852000",
  "reverted": false,
  "meta": {
    "blockID": "0x00bc614e285d68f8819b6dfdd729dad6fafbed9d2fdd65b57e4001a47d7f280c",
    "blockNumber": 12345678,
    "blockTimestamp": 1653978240,
    "txID": "0xfc99fe103fccbe61b3c042c1da3499b883d1b17fb40160ed1170ad5e63751e07",
    "txOrigin": "0x2d7c8293b20344223668ed3fd88301381dc35ce0"
  },
  "outputs": [
    {
      "contractAddress": null,
      "events": [
        {
          "address": "0x0000000000000000000000000000456e65726779",
          "topics": [
            "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
            "0x0000000000000000000000002d7c8293b20344223668ed3fd88301381dc35ce0",
            "0x00000000000000000000000011e1b586dd371471d0b52046ee3d4309a6c29c6c"
          ],
          "data": "0x0000000000000000000000000000000000000000000000009087b2e881f47600"
        }
      ],
      "transfers": []
    }
  ]
}
```

* Unsuccessful Transaction Receipt: [GET /transactions/{transactionId}/receipt](https://mainnet.vechain.org/transactions/0xae4a0ce2423c49cdb286cdde6691bdc77e9d06e2f5a4d0c3205c79af7d89bf7b/receipt)

```
{
  "gasUsed": 170831,
  "gasPayer": "0x9bb6c24707fc314a3b01324df2841cf61fec58a5",
  "paid": "0x17b522e4dc3f6000",
  "reward": "0x71cbdab0edfd000",
  "reverted": true,
  "meta": {
    "blockID": "0x01155656478ea00e7fd4f55a15cbb8124e504b7a874c0309b24dd90db2e5d500",
    "blockNumber": 18175574,
    "blockTimestamp": 1712283390,
    "txID": "0xae4a0ce2423c49cdb286cdde6691bdc77e9d06e2f5a4d0c3205c79af7d89bf7b",
    "txOrigin": "0x9bb6c24707fc314a3b01324df2841cf61fec58a5"
  },
  "outputs": []
}
```


# Read Accounts

An account can be classified as either an externally owned account or a smart contract. Externally owned accounts typically consist of private keys generated in wallets, whereas smart contracts are deployed with specific program code.

The distinction between the two can be made by examining an account's `hasCode` flag. If it's `true`, it indicates that a smart contract is deployed at that address. For smart contracts, the byte code can also be retrieved.

An account possesses three key attributes:

* **hasCode** to indicate a smart contract at the address
* **balance** to represent the VET balance
* **energy** to denote the VTHO balance

The balance is stored as a hex-encoded BigInt, which can be converted into a human-readable format using `BigInt(balance)`. It's important to note that numbers are stored with all their decimals, and for a more readable version, 18 decimal places should be considered.

Here's an example snippet for accessing account details for the VTHO contract:

```js
const contract = await thor.accounts.getAccount(
  '0x0000000000000000000000000000456e65726779' // <- whatever EOA or Smart contract
);
const bytecode = await thor.accounts.getBytecode(
  '0x0000000000000000000000000000456e65726779' // <- whatever Smart contract
);
```

Test it yourself:

{% embed url="<https://stackblitz.com/edit/ts-vechain-academy-get-account-info?embed=1&file=index.ts&hideExplorer=1&hideNavigation=1&view=editor>" %}

Type definition and documentation of all attributes:

* [Account Detail](https://vechain.github.io/vechain-sdk-js/classes/_vechain_sdk_network.AccountDetail.html)

The same information is available using the JSON-API:

* [GET /accounts/{address}](https://mainnet.vechain.org/accounts/0x0000000000000000000000000000456e65726779)
* [GET /accounts/{address}/code](https://mainnet.vechain.org/accounts/0x0000000000000000000000000000456e65726779/code)


# States & Views

Smart Contracts have the ability to expose variables and functions for sharing their stored data publicly. In order to communicate with a contract, it is essential to have the interface definition, which can be retrieved either from a JSON file or from the function definition in the source code.

## Example Data

This example used below will utilize the VTHO contract, which manages VeChain's VTHO Token.

* Smart Contract Address: `0x0000000000000000000000000000456e65726779`
* The contract's source code can be found on GitHub at: <https://github.com/vechain/thor/blob/f58c17ae50f1ec8698d9daf6e05076d17dcafeaf/builtin/gen/energy.sol>
* Its Application Binary Interface (ABI) is shared on b32, a repository that gathers publicly available interfaces for VeChain projects: <https://github.com/vechain/b32/blob/master/ABIs/energy.json>

## executeCall

Retrieving information is "calling" a function within a contract, which can be variables, view functions, and even functions that alter the state for simulation purposes.

`contracts.executeCall` is used to interact with smart contracts by providing: the contract's address as the first argument, the function ABI as the second argument and function data as the third argument.

A fourth parameter is optional and allows user to provide the options for executing a contract call within a blockchain environment.

### Without Parameters

To get the value stored for the variable `name` from the contract, the VTHO token name in this case, you can use the code below:

```js
const thor = ThorClient.at('https://mainnet.vechain.org');
// it is the ABI of the energy contract mentioned above
const contractABI = new ABIcontract ([
    {
        "constant": true,
        "inputs": [],
        "name": "name",
        "outputs": [
            {
                "name": "",
                "type": "string"
            }
        ],
        "payable": false,
        "stateMutability": "pure",
        "type": "function"
    },
    ...
]);

const name = await thor.contracts.executeCall(
    '0x0000000000000000000000000000456e65726779', 
    contractABI.getFunction('name'), 
    []
);
console.log('Name', name.result.plain);
```

### With Parameters

When calling a function with parameters, the parameters should be passed as a list in the third argument. For instance, to check the balance of a specific address:

```js
const balanceNow = await thor.contracts.executeCall(
    '0x0000000000000000000000000000456e65726779', 
    contractABI.getFunction('balanceOf'), 
    ['0x0000000000000000000000000000000000000000']
);
console.log('Balance Now', balanceNow.result.plain / 1000000000000000000n);
```

### Historical Data

To retrieve data from a previous block, you can specify the block number or id by passing in a `revision` option:

```js
const balancePast = await thor.contracts.executeCall(
    '0x0000000000000000000000000000456e65726779', 
    contractABI.getFunction('balanceOf'), 
    ['0x0000000000000000000000000000000000000000'], 
    { revision: "12345678" }
);
console.log('Balance Past', balancePast.result.plain / 1000000000000000000n);
```

### Simulate Transaction

If a function could change the state, it would require a transaction. To check the success of a transaction, you can invoke the function first and examine the output or handle any potential errors. For example, simulating a transfer that returns `true` if the caller has at least 1 VTHO:

```js
const transfer = await thor.contracts.executeCall(
    '0x0000000000000000000000000000456e65726779', 
    contractABI.getFunction('transfer'), 
    ['0x0000000000000000000000000000456e65726779', '1'], 
    {
        caller: '0x0000000000000000000000000000000000000000',
    }
);
console.log('Transfer Test', transfer.result.plain);
```

If the transaction encounters an error, the method call will also throw an error which needs to be handled appropriately.

### Example Project

{% embed url="<https://stackblitz.com/edit/ts-vechain-academy-execute-call?embed=1&file=index.ts&hideExplorer=1&hideNavigation=1&view=editor>" %}

## contracts.load

To simplify interaction a dynamic object can be created that can interact with passing less of the repeating arguments. This way is suitable when you have the full ABI and want to interact multiple times with the same contract.

For example contracts.read.name() can load the name without the need to pass function signature, address and thor client every time.

### Create Contract Object

To create a contract object it needs to be created from the thor client:

```javascript
const thor = ThorClient.at('https://mainnet.vechain.org');

// contract ABI is same as in example above
const vtho = thor.contracts.load(
    '0x0000000000000000000000000000456e65726779',
    contractABI
);

```

{% hint style="info" %}
The Contract-Loader always requires a JSON ABI Definition.

Fragments are not supported.
{% endhint %}

### Read Functions

Function calls are encapsulated within a sub-object named `read`. This enables calling the contract for variable content, viewing functions, or performing simple transaction simulations.

```javascript
await vtho.read.name() // returns the name
await vtho.read.balanceOf(address) // returns balance of address
await vtho.read.transfer(recipient, amount) // simulates a transfer 
```

### Read Options

Custom parameters, such as `revision` or specifying the caller of a function call, can be set for all requests using `setContractReadOptions`.

```javascript
// read balance of an address
vtho.setContractReadOptions({ revision: "12345678" });
const balancePast = await vtho.read.balanceOf(
  '0x0000000000000000000000000000000000000000'
);
console.log('Balance Past', balancePast/ 1000000000000000000n);
```

### Example Project

{% embed url="<https://stackblitz.com/edit/ts-vechain-academy-contract-read?embed=1&file=index.ts&hideExplorer=1&hideNavigation=1&view=editor>" %}


# Events & Logs

Events are signals that are emitted from smart contracts. Every event is logged, immutable and accessible using a blockchain node only. Smart contracts can not access events themselves.

Client-Applications can either listen to events and act accordingly or use logged events to access historical data.

The example uses a public contract and paginates thru the results.

## Example Data

This example used below will utilize the VTHO contract, which manages VeChain's VTHO Token.

* Smart Contract Address: `0x0000000000000000000000000000456e65726779`
* The contract's source code can be found on GitHub at: <https://github.com/vechain/thor/blob/f58c17ae50f1ec8698d9daf6e05076d17dcafeaf/builtin/gen/energy.sol>
* This and many other Application Binary Interface (ABI) are available on b32, a repository that gathers publicly available interfaces for VeChain projects: <https://github.com/vechain/b32/blob/master/ABIs/energy.json>, but feel free to use your own.

## `contracts.load(address, abi)`

A contract instance using address and ABI definition provides instant access to logs.

### Create Contract Object

To filter events, just like with any other interaction, a contract object needs to be created. It requires to specify a network first, because in general a contract with a specific address only exists on one network

```javascript
import { HttpClient, ThorClient } from '@vechain/sdk-network';
import energyAbi from './energy.json' assert { type: 'json' };

const thor = ThorClient.at('https://testnet.vechain.org/');
const vtho = thor.contracts.load(
  '0x0000000000000000000000000000456e65726779',
  energyAbi
);

```

{% hint style="info" %}
The Contract-Loader always requires a JSON ABI Definition.

Fragments are not supported.
{% endhint %}

### `contract.filters.<EventName>(output)`

The filters provide a simple way to access events in a human-readable way and to populate log requests with the correct criteria. The feature is available for every "event available in the ABI of the contract. In the case of VTHO `Transfers` and `Approvals`, emitted every time a user calls *transfer* and *approve* respectively.

For example, a filter for all `Transfers` can be created using:

```ts
const allTransfers = vtho.filters.Transfer()
const filteredTransfers = vtho.filters.Transfer(<from>, <to>)
```

Another example filters for all transfers to a specific address:

```ts
const filteredTransfers = vtho.filters.Transfer(null, <to>)
```

`_to` is the second output of the ABI. Unwanted filters needs to be skipped by passing null.\
There's a third one for the Transfer event, which is `_value`.

To filter all transfers of a specific value use:

```typescript
const filteredTransfers = vtho.filters.Transfer(null, null, <value>)
```

### Get Logs

To receive the logs from the blockchain, the built filter object provides a `.get()` function. Calling it will return the list of matching events.

```ts
const allTransfers = vtho.filters.Transfer()
const result = await thorClient.logs.filterEventLogs()
```

For pagination, there are three optional parameters that allow filtering for a specific range, paginating, and ordering the result set. All options are optional:

```ts
.get(
    // Specify the range of blocks to search for events
    range: {
        unit: 'block' | 'time', 
        from: 0,
        to: undefined
    },
    // Additional options for the query, such as offset and limit
    options: {
        offset: 0,
        limit: 1000
    },
    // Define criteria for filtering events
     criteriaSet: [
      filteredTransfers
    ],
    // Specify the order in which logs should be retrieved
    order: 'asc' | 'desc'
)
```

### Browse Results

`.filterEventLogs()` returns a list of results because it can support multiple requests as well.

The data is available in both raw and decoded forms:

```ts
const transferCriteria = contract.criteria
  // pass filters in the order of the input definition for the event
  // skip values by passing null or undefined
  .Transfer(null, '0x0000000000000000000000000000456e65726779');

const eventLogs = await thorClient.logs.filterEventLogs()
eventLogs.forEach(log => {
  // Decode each event
  console.log('Decoded event', log.decodedData);
}); 
```

### `filterEventLogs()` to manage multiple events in one request

With `filterEventLogs()`, logs for multiple events can be requested in a single request, improving network performance and simplifying interaction.

For example, requesting VTHO Transfers from and to an address in one request:

```ts
const results = await thor.logs.filterEventLogs({
  criteriaSet: [
    ...vtho.filters.Transfer(ZERO_ADDRESS).criteriaSet, // FROM Zero
    ...vtho.filters.Transfer(null, ZERO_ADDRESS).criteriaSet, // TO Zero
  ],
  range: {
    unit: 'block',
    from: 1_000_000,
    to: 20_000_000,
  },
});

results.forEach((result) => {
  result.forEach((log) => {
    console.log('Decoded event', log.decodedData);
  });
});
```

## `filterRawEventLogs(criteria)`

### Request Logs

Due to the potentially large amount of log entries, it is essential to implement filtering and pagination mechanisms for efficient data access.

To access and retrieve logs, the `logs.filterRawEventLogs` function allows filtering based on a specified range and enables pagination by utilizing offset and limits.

Illustrated in the following example is the process of retrieving transfer events for VTHO tokens. Initially, the event that requires filtering must be encoded into a byte format.

```js
import { ABIEvent } from '@vechain/sdk-core';

const event = new ABIEvent(
  'event Transfer(address indexed from, address indexed to, uint256 amount)'
);
const encodedTopics = event.encodeFilterTopics([])
```

`indexed` variables can be filtered directly in the filter request, providing fast access to a subset of information. The list argument on the encoding can provide them.

The example will filter for the second variable `to`:

```js
const encodedTopics = event.encodeFilterTopics([
  // first indexed value is "from", set to null to not use it
  null,
  // second indexed value is "to"
  '0x...', // <- address to filter for
]);
```

With the encoded version `logs.filterRawEventLogs` can be called to return all matching logs:

```js
const filteredLogs = await thor.logs.filterRawEventLogs({
  criteriaSet: [
    // filter by contract address and topics, empty topics are ignored
    {
      address: '0x0000000000000000000000000000456e65726779',
      topic0: encodedTopics[0],
      topic1: encodedTopics[1],
      topic2: encodedTopics[2],
      topic3: encodedTopics[3],
      topic4: encodedTopics[4],
    },
  ]
});
```

For pagination `options` (`{ offset?: number, limit?: number }`) and `order` (`'asc' | 'desc'`) can be passed as additional parameter. Additionally the logs can be restricted to a certain block range by defining a `range` (`{ unit?: 'block' | 'time', from?: number, to?: number }`).

You can find the full documentation in the description of the [Filter Event Logs Options](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.EventOptions.html).

### **Handle Response**

The response needs to be decoded using the event definition to gain access to all information. `event.decodeEventLog(log)` can be used on a selected event or in our example on all returned logs:

```js
const decodedLogs = filteredLogs.map(log => event.decodeEventLog(log))
```

Each decoded log will have an attribute for each event variable, like `decodedLog.from` and can alternatively be accessed as list in the order of the event parameter definition (`decodedLog[0]` equals `from`).

The types of the results are fully documented in the [Event Logs Interface.](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.EventLogs.html)

### Example Project

{% embed url="<https://stackblitz.com/edit/ts-vechain-academy-read-logs?embed=1&file=index.ts&hideExplorer=1&hideNavigation=1&view=editor>" %}


# VET Transfers

## `filterTransferLogs(criteria)`

The VeChain token `VET` does not have a contract tied to it, so its transfers must be accessed from a different source.

Using `logs.filterTransferLogs` gives you access to the transfers, with the same filter options, but the `criteriaSet` is specifically tailored for transfer events.

Each criteria may include:

* **recipient**: the address that receives VET
* **txOrigin**: the address that initiated the transfer transaction
* **sender**: the address that sent the VET

A sample request with all filters would appear as follows:

```js
// access VET transfers
const logs = await thor.logs.filterTransferLogs({
  options: {
    offset: 0,
    limit: 3,
  },
  range: {
    unit: 'block',
    from: 0,
    to: 20000000,
  },
  criteriaSet: [
    {
      // VET receiver
      recipient: '0x000000000000000000000000000000000000dead',

      // transaction signer/origin
      txOrigin: '0x19135a7c5c51950b3aa4b8de5076dd7e5fb630d4',

      // VET sender
      sender: '0x19135a7c5c51950b3aa4b8de5076dd7e5fb630d4',
    },
  ],
  order: 'asc',
});
```

Multiple optional criteria can be configured to filter for various addresses.

Type definition and documentation of all options and results:

* [Filter Transfer Log Options](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.FilterTransferLogsOptions.html)
* [Transfer Logs](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.TransferLogs.html)

### Example Project

{% embed url="<https://stackblitz.com/edit/ts-vechain-academy-read-logs-vet-transfers?embed=1&file=index.ts&hideExplorer=1&hideNavigation=1&view=editor>" %}


# Write Data


# Transactions

## Build Transaction

Every change on the Blockchain requires a transaction. A transaction wraps function calls in the form of clauses. Each clause sends instructions to an address that are encoded as hex string.

To send a transaction you will need to do multiple steps:

1. Have Private Key at hand that will sign the transaction
2. Encode the function calls into data calls
3. Calculate how much gas the transaction will cost
4. Build a transaction object with all the previous information
5. Sign the transaction
6. Send the transaction to the network

### Collecting Function Calls in Clauses

The instructions for executing a function on the blockchain needs to be encoded in a certain way. There are different functions to help create the right format, one is the `callFunction` that will call `increment`, a function of the smart contract available a the given address:

```typescript
const clauses = [
    Clause.callFunction(
        '0x8384738c995d49c5b692560ae688fc8b51af1059',
        new ABIFunction({
            name: 'increment',
            inputs: [],
            outputs: [],
            constant: false,
            payable: false,
            type: 'function',
        })
    ),
];
```

A clause can also send VET in the same action. Check the [type definition](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_core.TransactionClause.html) to also learn more about the internals.

### Calculate Gas

While reading on the blockchain is free, writing requires to pay the so-called gas fees to cover the cost of the transaction. Gas is paid in VTHO, the secondary token on VeChain.

To calculate the right amount of gas for your transaction, you can use `estimateGas`.

```typescript
const gasResult = await thor.transactions.estimateGas(clauses, senderAddress);
```

{% hint style="info" %}
If you expect your contracts to have different results based on the sender, you can also pass in the sender address as optional second parameter.
{% endhint %}

### Build Transaction

Once you have instructions + costs, you'll wrap them together into a transaction object with `buildTransactionBody`.

```typescript
const txBody = await thor.transactions.buildTransactionBody(
    clauses,
    gasResult.totalGas
);

```

{% hint style="info" %}
There are [several options](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.TransactionBodyOptions.html) that can optionally be passed as third argument to enable fee delegation, dependency on other transactions, priority and an expiration. You will learn more about them in other sections.
{% endhint %}

### Sign Transaction

Once a transaction is built, it needs to be signed by an entity that will execute all the code. This also makes the origin verifiable.

It is a four steps process, of getting a signer first:

#### Get Signer

```typescript
const wallet = new ProviderInternalBaseWallet(
  [{ privateKey, address: senderAddress }]
);

const provider = new VeChainProvider(
  // Thor client used by the provider
  thorClient,

  // Internal wallet used by the provider (needed to call the getSigner() method)
  wallet,

  // Enable fee delegation
  false
);

const signer = await provider.getSigner(senderAddress);
```

#### Sign Transaction

And using the signer to sign the transaction:

```javascript
const rawSignedTx = await signer.signTransaction(tx, privateKey);
```

#### Build Signed Transaction Object

`signTransaction` returns the fully signed transaction that can already be published using a POST request to the `/transactions` endpoint of a VeChain node:

```typescript
await fetch(`${nodeUrl}/transactions`, {
  method: 'POST',
  headers: {
    'content-type': 'application/json',
  },
  body: JSON.stringify({
    raw: rawSignedTx,
  }),
})
```

For submission by SDK, the raw hex string needs to be restored into a transaction object:

```typescript
const signedTx = Transaction.decode(
  HexUInt.of(rawSignedTx).bytes,
  true
);
```

### Send Transaction

The signed transaction can be published to the network using `sendTransaction`, which will post the data to the connected node:

```javascript
const sendTransactionResult = await thor.transactions.sendTransaction(signedTx);
```

### Wait for Results

`sendTransaction` returns a transaction id that can be used to track the status of the newly published transaction. `waitForTransaction` will resolve with the full receipt as soon as the result is available:

```javascript
const txReceipt = await thor.transactions.waitForTransaction(
  sendTransactionResult.id
);
```

### Example Project

{% embed url="<https://stackblitz.com/edit/vechain-academy-build-transaction-example?embed=1&file=index.mjs&hideExplorer=1&hideNavigation=1&view=editor>" %}

## Execute Transactions

### Transfer Token

Using `executeTransaction` the signed transaction will directly be published to the network

```javascript
const tokenContract = '0x5ef79995fe8a89e0812330e4378eb2660cede699'; // B3TR
const amount = 1.234 * 10**18; // 1.234 B3TR 

const transferAbi = new ABIFunction("function transfer(address to, uint256 value) public returns (bool)")

const transactionResult = await thorClient.transactions.executeTransaction(
  signer,
  tokenContract,
  transferAbi,
  [receiverAddress,amount]
)
```

### Delegated transaction - Transfer Token

If your transaction is delegated, you need to enable the fee delegation on your provider,

```typescript
const provider = new VeChainProvider(
  // Thor client used by the provider
  thorClient,
  // Internal wallet used by the provider (needed to call the getSigner() method)
  wallet,
  // Enable fee delegation
  true
);
```

and the `delegationUrl` must be provided.

```typescript
const transactionResult = await thorClient.transactions.executeTransaction(
  signer,
  tokenContract,
  transferAbi,
  [receiverAddress,amount],
  {delegationUrl:'https://sponsor-testnet.vechain.energy/by/441'}
)
```

### Example Project

{% embed url="<https://stackblitz.com/edit/vechain-academy-transfer-token?embed=1&file=index.mjs&hideExplorer=1&hideNavigation=1&view=editor>" %}


# Fee Delegation

Gas fees are usually paid by the address that signs the transaction. VeChain's fee delegation allows you to pass on this payment to another wallet, which can either reside as private key in your realm or shielded by a web service.

To use fee delegation, you can need to:

1. Enable it while building the transaction object
2. Provide information about the gas-payer during transaction signing

## Enable Fee Delegation

To enable fee delegation as feature, you need to set `isDelegated` to `true` while building the transaction body:

```typescript
const tx = await thor.transactions.buildTransactionBody(clauses, gas.totalGas,
  { isDelegated: true }
);
```

## Sign with Fee Delegation

To get the gas-payer involved, you'll pass either `gasPayerPrivateKey` or `gasPayerServiceUrl` to the signing wallet:

```typescript
const walletWithUrlSponsor = new ProviderInternalBaseWallet(
    [{privateKey, address: senderAddress}],
    {
        gasPayer: {
            gasPayerServiceUrl: 'https://sponsor-testnet.vechain.energy/by/90',
        },
    }
);

const walletWithAccountSponsor = new ProviderInternalBaseWallet(
    [{privateKey, address: senderAddress}],
    {
        gasPayer: {
            gasPayerPrivateKey: gasPayerAccount.privateKey,
        },
    }
);
```

### Example Project

{% embed url="<https://stackblitz.com/github/vechain-energy/example-snippets/tree/v1.0.0/sdk/transaction-execute?ctl=1&embed=1&file=index.mjs&hideExplorer=1&hideNavigation=1&view=editor>" %}

## Sign as Gas-Payer Service

To shield your private key for paying gas fees into a backend service, you can set up a web-service that receives a raw transaction and co-signs it to confirm gas payment (based on [VIP-201](https://github.com/vechain/VIPs/blob/master/vips/VIP-201.md)).

The process requires you to rebuild a transaction object from a hex encoded version:

```typescript
const transactionToSign = Transaction.decode(
  HexUInt.of(req.body.raw).bytes
);
```

Afterward, a unique hash is calculated for the given transaction, only valid if a specific origin will sign it:

```typescript
const delegatedHash = transactionToSign.getTransactionHash(req.body.origin);
```

The resulting hash is signed and then returned as hex string for further processing on the client side:

```typescript
const signature = HexUInt.of(Secp256k1.sign(delegatedHash, gasPayerPrivateKey)).toString();
```

### Example Project

{% embed url="<https://stackblitz.com/edit/github-gsktbqp6?file=index.mjs&view=editor>" %}


# Listen to Changes

WebSockets provide the ability to receive a stream of all changes on VeChain, reducing the number of network requests that are normally associated with polling data at regular intervals.

The available streams for changes are:

1. Events that are emitted from contracts
2. Blocks appended to the Blockchain
3. VET Transfers occurring between addresses
4. Transactions added to the transaction pools
5. Beats of new blocks which can be used to check if the block contains a specific account


# Events

## Example Data

This example used below will utilize the VTHO contract, which manages VeChain's VTHO Token.

* Smart Contract Address: `0x0000000000000000000000000000456e65726779`
* The contract's source code can be found on GitHub at: <https://github.com/vechain/thor/blob/f58c17ae50f1ec8698d9daf6e05076d17dcafeaf/builtin/gen/energy.sol>
* Its Application Binary Interface (ABI) is shared on b32, a repository that gathers publicly available interfaces for VeChain projects: <https://github.com/vechain/b32/blob/master/ABIs/energy.json>

## Connection

The connection is managed using WebSockets, which connect directly to a VeChain node.

A simple connection can be established with this snippet:

```js
import WebSocket from 'ws';
const ws = new WebSocket('wss://mainnet.vechain.org/subscriptions/event');
ws.onmessage = (message) => {
    console.log('New event', message.data);
}
```

This will receive all events on the blockchain as JSON-encoded strings.

## Filter Specific Events

Using the `subscriptions` helper, a custom subscription URL can be built that listens only to the specified event:

```js
const wsUrl = subscriptions.getEventSubscriptionUrl(
  'https://mainnet.vechain.org',
  "event Transfer(address indexed from, address indexed to, uint256 value)"
);
```

### Event Parameters

Filters can be adjusted to only show events that meet specific criteria. These parameters must be `indexed` and are given as a list.

The transfer event uses two indexed parameters: `from` and `to`.

For instance, to filter all transfers originating from a specific address, you would supply that address as the first parameter:

```js
const wsUrl = subscriptions.getEventSubscriptionUrl(
  'https://mainnet.vechain.org',
  "event Transfer(address indexed from, address indexed to, uint256 value)",
  ['0x0000000000000000000000000000456e65726779']
);
```

To filter for all transfers to a specific address, provide only the second value in the list:

```js
const wsUrl = subscriptions.getEventSubscriptionUrl(
  'https://mainnet.vechain.org',
  "event Transfer(address indexed from, address indexed to, uint256 value)",
  [null, '0x0000000000000000000000000000456e65726779']
);
```

When using filters, all provided values must match for the filters to apply.

### Blockchain Parameters

#### Emitter

Many contracts emit similar events, which sometimes necessitates restricting listening to a specific contract. An optional `options` argument can be used to filter for a particular contract address.

For example, to listen exclusively for VTHO transfers from the VTHO contract at `0x0000000000000000000000000000456e65726779`, it would be defined as follows:

```js
const wsUrl = subscriptions.getEventSubscriptionUrl(
  'https://mainnet.vechain.org',
  "event Transfer(address indexed from, address indexed to, uint256 value)",
  [],
  { address: '0x0000000000000000000000000000456e65726779' }
);
```

#### Blocks

To resume listening from a specific block position, the options can define a `blockID` to continue from where a previous listener may have disconnected.

{% hint style="info" %}
For additional details on the options, check out the documentation of [`EventSubscriptionOptions`](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.EventSubscriptionOptions.html).
{% endhint %}

## Decoding Events

The events are received as JSON-encoded strings. These strings must be parsed and decoded into usable objects.

Using the contract interface defined earlier, you can decode these events with the `parseLog()` function:

```js
import WebSocket from "ws";
import { ABIContract } from "@vechain/sdk-core";
import { subscriptions } from "@vechain/sdk-network";

const ws = new WebSocket(
  subscriptions.getEventSubscriptionUrl(
    "https://mainnet.vechain.org",
    "event Transfer(address indexed from, address indexed to, uint256 value)",
    [],
    {
        address: "0x0000000000000000000000000000456e65726779"
    }
  )
);

ws.onmessage = (message) => {
    console.log(message.data);
  const eventData = JSON.parse(message.data as any);

  // Ensure topics is an array of strings
  const topics = Array.isArray(eventData.topics)
    ? eventData.topics.map(String)
    : [String(eventData.topics)];

  // Ensure data is a single hex string
  const data = Array.isArray(eventData.data)
    ? eventData.data.map(String).join("")
    : String(eventData.data) || "0x";

  const abiContract = new ABIContract([
    {
      type: "event",
      name: "Transfer",
      inputs: [
        { type: "address", name: "from", indexed: true },
        { type: "address", name: "to", indexed: true },
        { type: "uint256", name: "value", indexed: false },
      ],
    },
  ]);

  const decoded = abiContract.parseLog<"Transfer">(data, topics);

  if (!decoded || decoded.eventName !== "Transfer") {
    throw new Error("Transfer event not detected");
  }
};

```

{% hint style="info" %}
Generic transaction details such as ID, block information, or the origin of the transaction are available in the object as well. Check `eventLog.meta` from the example. Learn more about the message type definition in the documentation of [`EventLogs`](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.EventLogs.html).
{% endhint %}

## Example Project

{% embed url="<https://stackblitz.com/github/vechain-energy/example-snippets/tree/v1.0.0/sdk/listen-events?ctl=1&embed=1&file=index.mjs&hideExplorer=1&hideNavigation=1&view=editor>" %}


# VET Transfers

## Connection

The connection is managed using WebSockets, which connect directly to a VeChain node.

A simple connection can be established with this snippet:

```js
import WebSocket from 'ws';
const ws = new WebSocket('wss://mainnet.vechain.org/subscriptions/transfer');
ws.onmessage = (message) => {
    console.log('New transfer', message.data);
}
```

This will receive all transfers on the blockchain as JSON-encoded strings.

## Filter Specific Transfers

The VeChain SDK facilitates the construction of filters to retrieve only the desired data by generating a subscription URL with specified parameters. Using the `subscriptions` helper, you can create a custom subscription URL that listens exclusively to the specified event.

All options are optional, and a transfer must match all specified criteria:

```js
const wsUrl = subscriptions.getVETtransfersSubscriptionUrl(
  'https://mainnet.vechain.org',
  {
    blockID: undefined, // block id to start from, defaults to the best block.
    signerAddress: undefined, // The address of the signer/origin of the transaction to filter transfers by.
    sender: undefined, // The sender address to filter transfers by.
    recipient: undefined, // The recipient address to filter transfers by.
  }
);
```

## Transfer Details

The transfers are received as JSON-encoded strings. These strings must be parsed into usable objects, resulting in an object of type [`TransferLogs`](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.TransferLogs.html).

An example result is:

```json
{
  "sender": "0xff5ba88a17b2e16d23ff6647e9052e937acb1406",
  "recipient": "0xf1663a96eb4760d74a3084636b25eac161c238ed",
  "amount": "0xa7b7a750ac2f0400",
  "meta": {
    "blockID": "0x0117dfcc79e6cfd0002a99aca8af0123cf1b1f3c67df7d3eb1e22aaf286088b2",
    "blockNumber": 18341836,
    "blockTimestamp": 1713946150,
    "txID": "0xb5dc022265321a2bc3aef9faf9224544b0ff54fcaf1d4f5846fc6caee0187009",
    "txOrigin": "0xff5ba88a17b2e16d23ff6647e9052e937acb1406",
    "clauseIndex": 0
  },
  "obsolete": false
}
```

The amount is a hexlified BigInt that can be converted into a BigInt using `BigInt(transferLog.amount)`.

## Example Project

{% embed url="<https://stackblitz.com/github/vechain-energy/example-snippets/tree/v1.0.0/sdk/listen-transfers?ctl=1&embed=1&file=index.mjs&hideExplorer=1&hideNavigation=1&view=editor>" %}


# Transactions

## Connection

The connection is managed using WebSockets, which connect directly to a VeChain node.

A simple connection can be established with this snippet:

```js
import WebSocket from 'ws';
const ws = new WebSocket('wss://mainnet.vechain.org/subscriptions/txpool');
ws.onmessage = (message) => {
    console.log('New pending transaction', message.data);
}
```

This will receive all new entries added to the transaction pool in the form of JSON-encoded strings.

Subscriptions only receive the transaction ID as soon as it is added to the transaction pool. A transaction may either be successfully included in a block, reverted, or expire in the future.

To obtain detailed information about a transaction, you will need to make a second request, either directly from the node or by using a Thor client.

```js
await fetch(`https://mainnet.vechain.org/transactions/${txId}?pending=true`).then(res => res.json())
```

```js
const tx = await thor.transactions.getTransaction(addedTx.id, {
  pending: true,
});
```

## Example Project

{% embed url="<https://stackblitz.com/github/vechain-energy/example-snippets/tree/v1.0.0/sdk/listen-transactions?ctl=1&embed=1&file=index.mjs&hideExplorer=1&hideNavigation=1&view=editor>" %}


# Blocks

## Connection

The connection is managed using WebSockets, which connect directly to a VeChain node.

A simple connection can be established with this snippet:

```js
import WebSocket from 'ws';
const ws = new WebSocket('wss://mainnet.vechain.org/subscriptions/block');
ws.onmessage = (message) => {
    console.log('New block', message.data);
}
```

This will receive a new block as soon as it is added to the blockchain, in the form of JSON-encoded strings.

## Options

To resume listening from a specific block position, the options can include a `blockID` to continue from where a previous listener may have disconnected.

For additional details on the options, refer to the documentation of [`BlockSubscriptionOptions`](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.BlockSubscriptionOptions.html).

## Block Details

The blocks are received as JSON-encoded strings. These strings must be parsed into usable objects, resulting in an object of type [`BlockDetail`](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.BlockDetail.html).

An example result is:

```json
{
  number: 18342166,
  id: '0x0117e116630b0db7c0208cf0e01d9dfefcc400310e75e738ebafaeca221ae31d',
  size: 684,
  parentID: '0x0117e115cc9e7eab70f4513ab8d82517c2d6e5dee3c121f5caba9dbfe517587f',
  timestamp: 1713949450,
  gasLimit: 29999972,
  beneficiary: '0x0ffb1cbc86b3ad0a17292b7fda577d59c0d7aed9',
  gasUsed: 57454,
  totalScore: 1787902837,
  txsRoot: '0x00a3024aac1092060e5f9368dd364f9eb9918eddc2d5ecfd92c64faf506c5176',
  txsFeatures: 1,
  stateRoot: '0x3ffc3fecb7d43d982b712f38ea5c9324375bc0c8db9f54dae91bd07777905b9e',
  receiptsRoot: '0x186a987d166ec60daf5a54ef97344a47d5c6e5f816b51e8ae49b14a332aebbb1',
  com: true,
  signer: '0x9e1c86df9e17451c0177544aa9a55edb3e0581b0',
  transactions: [
    '0xecc1a99b0afcf25c3283babc91641ed57d7dd3e6ae9e78058c439ae8c476f543',
    '0x27af83997e4b045024eafdb6041a97097de8cd528a22176056d0652f81a98fc4'
  ],
  obsolete: false
}
```

## Example Project

{% embed url="<https://stackblitz.com/github/vechain-energy/example-snippets/tree/v1.0.0/sdk/listen-blocks?ctl=1&embed=1&file=index.mjs&hideExplorer=1&hideNavigation=1&view=editor>" %}


# Beats

Beats are messages that are sent on each new block, containing tiny bits of data that can be used to detect changes happening on the blockchain. Beats provide as little data as possible to remove the need to load full block and receipt data every time.

## Connection

The connection is managed using WebSockets, which connect directly to a VeChain node.

A simple connection can be established with this snippet:

```js
import WebSocket from 'ws';
const ws = new WebSocket('wss://mainnet.vechain.org/subscriptions/beat2');
ws.onmessage = (message) => {
    console.log('New block', message.data);
}
```

This will receive a new block as soon as it is added to the blockchain, in the form of JSON-encoded strings with a bloom filter which can be used to check if the block contains an account.

## Options

To resume listening from a specific block position, the options can include a `blockID` to continue from where a previous listener may have disconnected.

For additional details on the options, refer to the documentation of [`BlockSubscriptionOptions`](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.BlockSubscriptionOptions.html).

## Block Details

The blocks are received as JSON-encoded strings. These strings must be parsed into usable objects.

An example result is:

```json
{
  number: 18342209,
  id: '0x0117e1411afb526f813370417d23d1757e03c47887d73de999bb178919d41f96',
  parentID: '0x0117e1408ea3161e8561868dbae1828841588954bd71ae845866d9b67ec07e83',
  timestamp: 1713949880,
  txsFeatures: 1,
  gasLimit: 30146568,
  bloom: '0x990c2f3331b75f955af09180665aadf3f017',
  k: 13,
  obsolete: false
}
```

## Bloom Filter

{% hint style="info" %}
[You can find more information about the Bloom Filter in another section of the documentation.](/developer-resources/sdks-and-providers/sdk/bloom-filter)
{% endhint %}

It enables the verification of interactions involving a specific address, potentially eliminating the need for further transaction or block lookups if the block lacks information related to that address.

The `bloomUtils` offer a straightforward test function to determine whether an address has had interactions within a block:

```js
import WebSocket from 'ws';
import { Address, BloomFilter } from '@vechain/sdk-core'
const ws = new WebSocket('wss://mainnet.vechain.org/subscriptions/beat2');

ws.onmessage = (message) => {
    console.log('New block', message.data);
    const block = JSON.parse(message.data as any);
    const bloom = BloomFilter.of(block.bloom).build();

    const addressToTest = '0x0000000000000000000000000000000000000000';
    console.log('Have there been any interactions ?', bloom.contains(Address.of(addressToTest)));
}
```

The bloom filter is used for testing and includes:

* The Gas Payer of a transaction
* The emitters of all events within transactions
* The topics of all events in transactions that include an address or shorter than an address
* The sender and receiver of transfers
* The origin of the transaction
* The signer of the block
* The beneficiary of the block

{% hint style="info" %}
For more details on the implementation, you can view the [node's code on GitHub](https://github.com/vechain/thor/blob/d847c4683469a8ccffb4e472ca7449059b3ceefc/api/subscriptions/beat2_reader.go#L29-L90).
{% endhint %}

## Example Project

{% embed url="<https://stackblitz.com/github/vechain-energy/example-snippets/tree/v1.0.0/sdk/listen-beats?ctl=1&embed=1&file=index.mjs&hideExplorer=1&hideNavigation=1&view=editor>" %}

Another example can be found on GitHub using a React Hook that listens and provides state updates when information is found in a new block. For example, transaction IDs or addresses:

<https://github.com/ifavo/example-buy-me-a-coffee/blob/main/src/hooks/useBeats.ts>


# Build with Hardhat

Hardhat is a development environment to compile, deploy, test, and debug your EVM-compatible applications. It helps developers manage and automate the recurring tasks inherent to the process of building smart contracts, as well as easily integrating with various plugins to extend its functionality. With Hardhat, you can write and run tests, script deployments, and interact with your contracts.

VeChain's SDK provides a plugin to instantly enable connectivity.

*The example project is relying on hardhat version 2.22.15 and the project initiated with `npx hardhat init`.*

## Setup Hardhat

### Setup

To bootstrap a hardhat project:

```shell
npm install --save-dev hardhat
npx hardhat init
```

### Install Hardhat Plugin

To add VeChain support, install the hardhat plugin:

```bash
npm install --save-dev @vechain/sdk-hardhat-plugin
```

### Configure

Import or require the plugin in your `hardhat.config.ts` file:

```ts
import '@vechain/sdk-hardhat-plugin'
```

Add a network for TestNet or MainNet:

1. The Hardhat plugin requires `vechain` in the network's name.
2. Remote accounts are unsupported; therefore, provide account information.

Configure the solidity compile to `Paris` (or version that VeChain is compatible with)

A fully functional example configuration with:

* defined accounts to use
* fee delegation using vechain energy
* networks for mainnet, testnet, solo and hardhard

```ts
import { type HardhatUserConfig } from 'hardhat/config';
import '@nomicfoundation/hardhat-toolbox';
import '@vechain/sdk-hardhat-plugin';
import { HDKey } from '@vechain/sdk-core';
import { type HttpNetworkConfig } from 'hardhat/types';

// account to use
const accounts = ['0x2422eb37a0046d42e3c8d05c7d972de7fe1bb805e90b3a0dbc7d12b4d444c634']


const config: HardhatUserConfig = {
	solidity: {
		compilers: [
			{
				version: '0.8.20', // Specify the first Solidity version
				settings: {
				// Additional compiler settings for this version
					optimizer: {
					enabled: true,
					runs: 200
					},
				evmVersion: 'paris'
				}
			}
		]
	},
	networks: {

		/**
		* Example Mainnet configuration
		* No fee delegation
		*/
		vechain_mainnet: {
			// Mainnet
			url: 'https://mainnet.vechain.org',
			accounts,
			debug: false,
			gasPayer: undefined,
			gas: 'auto',
			gasPrice: 'auto',
			gasMultiplier: 1,
			timeout: 20000,
			httpHeaders: {}
		} satisfies HttpNetworkConfig,

		/**
		* Example Testnet configuration
		* With gasPayer url for fee delegation
		* Here a mnemonic is used to specify accounts
		*/
		vechain_testnet_gas_payer_url: {
			// Testnet
			url: 'https://testnet.vechain.org',
			accounts: {
				mnemonic:
					'vivid any call mammal mosquito budget midnight expose spirit approve reject system',
				path: HDKey.VET_DERIVATION_PATH,
				count: 3,
				initialIndex: 0,
				passphrase: 'vechainthor'
			},
			debug: true,
			gasPayer: {
				gasPayerServiceUrl:
					'https://sponsor-testnet.vechain.energy/by/269'
			},
			enableDelegation: true,
			gas: 'auto',
			gasPrice: 'auto',
			gasMultiplier: 1,
			timeout: 20000,
			httpHeaders: {}
		} satisfies HttpNetworkConfig,

		/**
		* Thor solo network configuration
		* Thor solo can be used for local deployment and testing
		*/
		vechain_solo: {
			// Thor solo network
			url: 'http://localhost:8669',
			accounts: [
			'7f9290cc44c5fd2b95fe21d6ad6fe5fa9c177e1cd6f3b4c96a97b13e09eaa158'
			],
			debug: false,
			enableDelegation: false,
			gasPayer: undefined,
			gas: 'auto',
			gasPrice: 'auto',
			gasMultiplier: 1,
			timeout: 20000,
			httpHeaders: {}
		} satisfies HttpNetworkConfig,

		/**
		* Default hardhat network configuration
		*/
		hardhat: {
			accounts: {
				mnemonic:
					'vivid any call mammal mosquito budget midnight expose spirit approve reject system',
				path: HDKey.VET_DERIVATION_PATH,
				count: 3,
				initialIndex: 0

			},
			debug: true,
			gasPayer: undefined,
			gas: 'auto',
			gasPrice: 'auto',
			gasMultiplier: 1,
			timeout: 20000,
			httpHeaders: {}

		}

	}

};

export default config;
```

## OpenZeppelin Contracts

Bootstrap your smart contract creation with [OpenZeppelin](https://www.openzeppelin.com/contracts) contracts. A compilation of widely used standards and patterns can significantly speed up the development process.

### Install

Install contract libraries and Hardhat helpers:

```shell
npm install --save @openzeppelin/contracts @openzeppelin/contracts-upgradeable @openzeppelin/hardhat-upgrades
```

### Create a ERC20 Token

Create `contracts/GLDToken.sol` and save this example:

```sol
// contracts/GLDToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;


// Importing the ERC20 contract from OpenZeppelin
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

// Defining the GLDToken contract which inherits from ERC20
contract GLDToken is ERC20 {

	// Constructor to initialize the token with an initial supply
	// `initialSupply` is the amount of tokens that will be created at deployment

	constructor(uint256 initialSupply) ERC20("Gold", "GLD") {

		// Mint the initial supply of tokens and assign them to the contract deployer
		_mint(msg.sender, initialSupply);

	}
}
```

Run the following command to compile your contract:

```shell
npx hardhat compile
```

<https://wizard.openzeppelin.com> provides an easy-to-use web interface for generating basic smart contracts.

## Deployment Contract

With [`hardhat-deploy`](https://github.com/wighawag/hardhat-deploy), deployments can be managed automatically without tracking the addresses of deployed contracts or manually upgrading contracts.

Create a deployment script in `deploy/MyToken.ts`:

```ts
import { ethers } from 'hardhat';

  
async function main(): Promise<void> {
	const erc20Contract = await ethers.deployContract('GLDToken', [100000]);
	await erc20Contract.waitForDeployment();
	const address = await erc20Contract.getAddress();
	console.log(`Gold contract deployed with address: ${address}`);
}

  
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
	console.error(error);
	process.exitCode = 1;
});
```

To execute the deploy script, specifying the network to deploy to:

```bash
npx hardhat deploy --network vechain_testnet_gas_payer_url
```

If a contract changes, deployment will automatically take place.

The status of deployments is stored in `deployments/<network name>`. Check out [`hardhat-deploy`](https://github.com/wighawag/hardhat-deploy) to learn more about its features and best practices.

### Example

The above steps are available in an example project with the SDK repository: [Example App](https://github.com/vechain/vechain-sdk-js/tree/main/apps/sdk-hardhat-integration)


# Utilities


# BigInt and Unit-Handling

Numbers in smart contracts are usually stored without decimals as big numbers, and a second variable contains information about the amount of decimals.

Some utility functions can help ease the handling of these numbers, especially with the `bigint` support now being natively available:

## Convert Token Balance to Human-Readable Version

For example, reading the balance of VTHO and turning it into a readable version:

```ts
// Example 1: simulate multicall 
import { ThorClient, TESTNET_URL } from '@vechain/sdk-network';
import { ERC20_ABI} from '@vechain/sdk-core'

const thor = ThorClient.at(TESTNET_URL+'/');
const contract = thor.contracts.load('0x0000000000000000000000000000456e65726779', ERC20_ABI );

let clauses = [];

clauses.push(contract.clause.balanceOf('0x0000000000000000000000000000456e65726779'));
clauses.push(contract.clause.decimals());

const response = await thor.contracts.executeMultipleClausesCall(clauses);

console.log(response);

// Example 2: execute multicall (with signer)
import { ThorClient, TESTNET_URL, Contract, VeChainAbstractSigner , VeChainProvider, ProviderInternalBaseWallet } from '@vechain/sdk-network';
import { HexUInt , ERC20_ABI} from '@vechain/sdk-core'

const thor = ThorClient.at(TESTNET_URL+'/');
const contract = thor.contracts.load('0x0000000000000000000000000000456e65726779', ERC20_ABI );

const senderAccount = {
  privateKey:
      'f9fc826b63a35413541d92d2bfb6661128cd5075fcdca583446d20c59994ba26',
  address: '0x7a28e7361fd10f4f058f9fefc77544349ecff5d6'
};

let clauses = [];

clauses.push(contract.clause.balanceOf('0x0000000000000000000000000000456e65726779'));
clauses.push(contract.clause.decimals());

// Create the provider
const provider = new VeChainProvider(
  // Thor client used by the provider
  thor,
  // Wallets used by the provider
  new ProviderInternalBaseWallet([
      {
          privateKey: HexUInt.of(senderAccount.privateKey).bytes,
          address: senderAccount.address
      }
  ]),
  false
);

const signer = await provider.getSigner(senderAccount.address);

const response = await thor.contracts.executeMultipleClausesTransaction(clauses, signer);
console.log(response);

```

## Convert Human Inputs to BigInts

When building user interfaces, numbers are entered as strings and need to be turned into BigInts for interaction with the blockchain.

`unitsUtils.parseUnits(string, decimals)` helps in that way. For example:

```ts
unitsUtils.parseUnits('5', 18)   // => turns into 5000000000000000000n
unitsUtils.parseUnits('0.1', 18) // => turns into 100000000000000000n
```


# Name Service Lookups

The SDK provides programmatic access to the VeChain Name Service (VNS) at [vet.domains](https://vet.domains).

Name Services provide the ability to use human-readable names that point to addresses.

## Resolve Names

`vnsUtils` is available within the network module and can be used with a ThorClient.

After importing and connecting the ThorClient, `resolveName` and `resolveNames` provide access to resolve single or multiple names. If a name is not known or configured, `null` is returned instead of an address.

```ts
import { ThorClient, vnsUtils } from '@vechain/sdk-network';
const thor = ThorClient.at('https://mainnet.vechain.org');

console.log('resolveName', await vnsUtils.resolveName(thor, 'test.vet'));
console.log('resolveNames', await vnsUtils.resolveNames(thor, ['test.vet']));
console.log(
  'resolveName',
  await vnsUtils.resolveName(thor, '_invalid_test.vet')
);
```

## Lookup Addresses

After importing and connecting the ThorClient, `lookupAddress` and `lookupAddresses` provide access to resolve single or multiple addresses. If an address has no (valid) primary name, a `null` is returned instead of a string.

```ts
import { ThorClient, vnsUtils } from '@vechain/sdk-network';
const thor = ThorClient.at('https://mainnet.vechain.org');

console.log(
  'lookupAddress',
  await vnsUtils.lookupAddress(
    thor,
    '0x105199a26b10e55300CB71B46c5B5e867b7dF427'
  )
);
console.log(
  'lookupAddresses',
  await vnsUtils.lookupAddresses(thor, [
    '0x105199a26b10e55300CB71B46c5B5e867b7dF427',
  ])
);
console.log(
  'lookupAddress',
  await vnsUtils.lookupAddress(
    thor,
    '0x0000000000000000000000000000000000000000'
  )
);

```


# Example dApps


# Buy me a Coffee

## Buy me a Coffee with dApp-Kit

The outcome of this tutorial is a React application capable of identifying a user's wallet, sending tokens, and verifying the transaction on the VeChain network.

You can open the resulting project on [GitHub](https://github.com/ifavo/example-buy-me-a-coffee) to check on all steps in parallel while reading each section:

Here is the sequence we are building during this Tutorial:

{% @mermaid/diagram content="sequenceDiagram
participant User
participant Wallet
participant App
participant Blockchain
participant GitHub

note over User, GitHub: Starting the App
User->>App: open app
App->>GitHub: get list of tokens
GitHub-->>App: list of tokens
App-->>User: show tokens and form to enter amount

note over User, App: User Login
User->>App: log in
App->>Wallet: ask for user verification
Wallet->>User: verify identity
User-->>Wallet: approve verification
Wallet-->>App: verification approved
App-->>User: show user's wallet address

note over User, Blockchain: Token Transfer
User->>App: initiate token transfer
App->>Wallet: request transaction signature
Wallet->>User: request signature
User-->>Wallet: provide signature
Wallet-->>Blockchain: send transaction
Blockchain-->>Wallet: transaction ID or error message
Wallet-->>User: show confirmation
Wallet-->>App: send transaction ID or error message

loop until transaction is confirmed
App->>Blockchain: check transaction status
Blockchain-->>App: pending, successful, or failed
end

App-->>User: show transaction result" %}

## Preparation

This tutorial is based on a pre-existing React project that has already been configured with widely-used libraries. It will focus on incorporating VeChain-specific modules into this project. Therefore, only information related to VeChain will be covered in this article. It assumes a basic understanding of React, such as managing states and passing props, which will not be explained.

* **@vechain/dapp-kit-react** - A collection of React hooks and components designed to facilitate the integration of the dApp kit into React applications.
* **@vechain/dapp-kit-ui** - A set of UI components aimed at simplifying the process of wallet selection and connection.
* **@vechain/sdk-core** - A library focused on providing features specific to VeChain.
* **@vechain/sdk-network** - A library created to streamline communication with VeChain nodes.

Install all these modules with npm:

```shell
npm install --save @vechain/dapp-kit-react @vechain/dapp-kit-ui @vechain/sdk-core @vechain/sdk-network
```

### Integrating the dApp-Kit

{% hint style="info" %}
You can read more about the dApp-Kit in their [docs section](https://docs.vechain.org/developer-resources/sdks-and-providers/dapp-kit/dapp-kit-1).
{% endhint %}

To connect your application to VeChain you will wrap it into a provider that will share a single connection and user authentification globally.

In our example app, this is done within the [`App.tsx`](https://github.com/ifavo/example-buy-me-a-coffee/blob/main/src/App.tsx).

Import the Provider:

```tsx
import { DAppKitProvider } from "@vechain/dapp-kit-react";
```

And wrap your content with it:

```tsx
    <DAppKitProvider
        // the network & node to connect to
        nodeUrl="https://testnet.vechain.org
        genesis="test"

        // remember last connected address on page reload
        usePersistence={true}
    >
        {children}
    </DAppKitProvider>
```

Consequently, you will have the capability to utilize functions such as `useWallet()` for user identification or `useConnex()` for interacting with VeChain.

### Integrating `useQuery`

By using [`@tanstack/react-query`](https://tanstack.com/query/latest), we will access VeChain nodes directly to retrieve some data from the public infrastructure. Just like with dApp-Kit, you need a provider that enables shared fetch and cache management.

Import the Provider and establish a default client configuration:

```tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
```

And wrap your dApp-Kit Provider with it:

```tsx
<QueryClientProvider client={queryClient}>
  <DAppKitProvider>..</DAppKitProvider>
</QueryClientProvider>
```

### Authentification

The entire authentication procedure is contained within a React component offered by the dApp-Kit.

The [`WalletButton`](https://docs.vechain.org/developer-resources/sdks-and-providers/dapp-kit/dapp-kit-1/react/usage#walletbutton) generates a button that prompts for connection or displays the address of the signed-in user.

By using this feature, our streamlined Menu will present either a connect button or the user's address within this one component.

```tsx
import { WalletButton } from "@vechain/dapp-kit-react";

export default function LayoutMenu() {
  return <WalletButton />;
}
```

By utilizing the [`useWallet()`](https://docs.vechain.org/developer-resources/sdks-and-providers/dapp-kit/dapp-kit-1/react/usage#usewallet) hook, we can already make use of the dApp-Kit's functionality to display a hint for signing in within our primary component.

```tsx
import { useWallet } from "@vechain/dapp-kit-react";
export default function BuyCoffee() {
  // get the connected wallet
  const { account } = useWallet();

  // if there is no wallet connected, ask the user to connect first
  if (!account) {
    return "Please connect your wallet to continue.";
  }

  return "Placeholder";
}
```

### Select Token from Registry

VeChain curates a public repository of tokens on [GitHub](https://github.com/vechain/token-registry) to streamline token interaction within decentralized applications (dApps).

{% hint style="info" %}
Have you published a new Token on VeChain? You are welcome to create a pull request to add it to the public registry!
{% endhint %}

We will utilize it to dynamically retrieve all recognized tokens within the application and enable the user to purchase a coffee using a token of their choosing.

To obtain the list, we will employ the `useQuery()` function:

```tsx
// fetch the token registry, to display a list of tokens
const tokenRegistry = useQuery({
  queryKey: ["tokenRegistry"],
  queryFn: async () =>
    fetch(`https://vechain.github.io/token-registry/main.json`).then((res) =>
      res.json()
    ),
});
```

The code snippet retrieves the list and returns its content. `useQuery()` offers useful functionalities such as a loading indicator, error handling, and automated retry attempts.

A loading indicator will be displayed during the loading process:

```tsx
if (tokenRegistry.isLoading) {
  return <IconLoading />;
}
```

In order to show the data, it can be presented in a dropdown menu:

```tsx
<>
  <label htmlFor="token" className="sr-only">
    Token
  </label>
  <select name="token" id="token">
    <option value="">VET</option>
    {tokenRegistry.data?.map((token) => (
      <option key={token.address} value={token.address}>
        {token.symbol}
      </option>
    ))}
  </select>
</>
```

We will display `VET` as a blank choice for utilizing VeChain's native token as a payment option if no token has been chosen. The complete component, along with its state management, can be found in the [`src/BuyCoffee/SelectToken.tsx` file on GitHub](https://github.com/ifavo/example-buy-me-a-coffee/blob/main/src/BuyCoffee/SelectToken.tsx).

### Read Token Balance

To assist users in determining the amount to send, we will retrieve the VET or Token balance of the currently signed-in user.

Utilizing `useConnex()` and `useWallet()`, we will request the account details and present the outcome in a user-friendly manner using `unitsUtil`, a utility function from the VeChain SDK:

```js
// import hooks
import { useConnex, useWallet } from '@vechain/dapp-kit-react';
// ..

// get currently signed in account and the currenct vechain connection
const { account } = useWallet()
const connex = useConnex()
```

Read VET Balance by requesting account details:

```js
connex.thor.account(account).get()
    .then(({ balance }) => {
        console.log('VET Balance:', balance)
    })
```

For tokens, we will execute a function on the contract by defining an interface that remains consistent across all tokens.

```js
connex.thor.account(token.address)
    .method(
        {
            "inputs": [{ "name": "owner", "type": "address" }],
            "name": "balanceOf",
            "outputs": [{ "name": "balance", "type": "uint256" }]
        })
    .call(account)
    .then(({ decoded: { balance } }) => {
        console.log('Token Balance', balance)
    })
```

Further details on the [Account Visitor can be found in various sections of the documentation](https://docs.vechain.org/developer-resources/sdks-and-providers/connex/api-specification#account-visitor).

The output of both functions is a BigNumber representation of the value, either in hexadecimal or as a 256-byte integer value that may be challenging for a user to interpret. The `@vechain/sdk-core` library provides `unitsUtils` to convert the balance into a readable format:

* `unitsUtils.formatVET(balance)` transforms the balance into a complete VET number by dividing it by 18 decimal places.
* `unitsUtils.formatUnits(balance, token.decimals)` converts the balance into a complete number with a specified custom decimal value from the token registry.

For the full implementation of this functionality, refer to [`src/BuyCoffee/Balance.tsx`](https://github.com/ifavo/example-buy-me-a-coffee/blob/main/src/BuyCoffee/Balance.tsx) in the GitHub demonstration project.

### Prepare Token Sending

The [`@vechain/sdk-core`](https://www.npmjs.com/package/@vechain/sdk-core) library offers tools to easily create blockchain commands.

A "clause" is a single command, similar to a function call, that's included in a transaction. The `Clause` helps create these commands in a more straightforward way. Additionally, `unitsUtils` helps adjust user inputs to the correct format for the blockchain:

* `unitsUtils.parseVET(amount)` – Since VET tokens are divided into 18 decimal places, this function adjusts the input number to include these decimals, converting it into a format the blockchain can understand.
* `clauseBuilder.transferVET(recipient, parsedVET)` – This command creates instructions to send VET tokens to another wallet.
* `unitsUtils.parseUnits(amount, decimals)` – For tokens with a different number of decimal places, this function allows specifying the exact number of decimals to correctly format the amount.
* `clauseBuilder.transferToken(token, recipient, parsedAmount)` – This command generates instructions to send a specified amount of a particular token to another wallet.

{% hint style="info" %}
To explore more about the clauseBuilder and its additional functionalities, check out the [Clause](https://vechain.github.io/vechain-sdk-js/classes/_vechain_sdk_core.Clause.html).
{% endhint %}

For our Buy me a Coffee with any token app this will translate into this snippet:

```tsx
const clauses = [
  // if a token was selected, transfer the token
  selectedToken
    ? // the clauseBuilder helps build the data for the transaction
      clauseBuilder.transferToken(
        selectedToken.address,
        RECIPIENT_ADDRESS,
        unitsUtils.parseUnits(amount, selectedToken.decimals)
      )
    : // or use the clauseBuilder to transfer VET by default
      clauseBuilder.transferVET(RECIPIENT_ADDRESS, unitsUtils.parseVET(amount)),
];
```

A valuable feature of VeChain Wallets is their ability to include comments, which explain individual clauses or entire transactions to the user.

By adding a `comment` attribute to the clause object, Wallets will display it alongside each clause for the user.

### Sending Tokens

Function calls on the Blockchain are executed by sending a transaction, which incurs a VTHO charge for each action based on the associated workload. To verify its identity, a transaction must be signed with the sender's private key.

After setting up the `DAppKitProvider`, we can use the `useConnex()` hook to connect to VeChain.

To have the user sign and send a transaction, we use `await connex.vendor.sign('tx', clauses).request()`.

Here's what happens during this process:

1. `sign('tx', clauses)` creates a transaction object with the specified clauses, using the blockchain settings from `DAppKitProvider`.
2. `request()` asks the user's wallet to get the user's signature for the transaction. This function is async, because it will wait until the wallet interaction is completed.
3. The wallet shows the transaction details to the user. If the user agrees and signs it, the transaction is forwarded to a VeChain node.
4. The VeChain node confirms the transaction by returning a transaction ID. This ID can be used to track the transaction's status.

### Track Transaction Status

By utilizing the transaction ID, progress can be monitored through a request for a receipt.

By using the `useQuery()` function, an updated receipt will be retrieved at regular intervals. Given that new blocks are included into VeChain approximately every 10 seconds, a transaction is typically included after that time.

Utilizing a public node as a direct method offers an alternative way of connecting to VeChain. Each node offers a public JSON API, which allows for retrieving raw data.

```tsx
import type { TransactionReceipt } from '@vechain/sdk-network';

// ..

const receipt = useQuery<TransactionReceipt | null>({
    queryKey: ['transaction', txId],
    queryFn: async () => fetch(`${NODE_URL}/transactions/${txId}/receipt`).then((res) => res.json()) as Promise<TransactionReceipt | null>,
    refetchInterval: 7000,
    placeholderData: (previousData) => previousData,
    enabled: Boolean(txId) && !hasReceipt
})
```

The [`Transaction Receipt`](https://vechain.github.io/vechain-sdk-js/interfaces/_vechain_sdk_network.TransactionReceipt.html) provides details regarding the fundamental transaction information along with its outcomes. When checking the success of the transaction, we will specifically examine the `reverted` indicator in the receipt.

Initially, before the transaction is confirmed, the receipt will be absent, resulting in three possible states:

1. When no receipt is available, the status is `pending`.
2. If the receipt is present and the `reverted` flag is marked as `true`, the status is `reverted`.
3. In case the receipt exists and the `reverted` flag is set to `false`, the status is `success`.

```tsx
const status = !receipt.data ? 'pending' : receipt.data?.reverted ? 'reverted' : 'success'
```

A React component displaying status for the user can be found in the sample project at [`src/BuyCoffee/Transaction.tsx`](https://github.com/ifavo/example-buy-me-a-coffee/blob/main/src/BuyCoffee/Transaction.tsx).

## Proof of Concept Completed

The preceding sections have shown a rudimentary application that communicates with VeChain:

* It outlined the process of establishing VeChain Connectivity within a React Application.
* Demonstrated how to identify a user's wallet address.
* Utilized the public token registry to show a list VeChain Tokens.
* Interact with the Blockchain to read an accounts balance or call a contract function and read its reply.
* Creating transactions to send VET or other ecosystem tokens.
* Monitored the status of a transaction to confirm its completion.




---

[Next Page](/llms-full.txt/1)

