VeChain Docs
  • Welcome to VeChain
  • Blockchain Basics
    • Introduction to blockchain
    • Introduction to digital property
    • The evolution of the internet
  • Introduction to VeChain
    • About the VeChain blockchain
      • Consensus Deep Dive
      • Governance
    • Dual-Token Economic Model
      • VeChain (VET)
      • VeThor (VTHO)
    • Acquire VeChain Assets
    • Sustainability
  • Core Concepts
    • Networks
      • Thor Solo Node
      • Testnet
      • Mainnet
    • Nodes
      • Node Rewards Programme
    • Blocks
      • Block Model
    • Transactions
      • Transaction Model
      • Transaction Fees
      • Transaction Calculation
      • Meta Transaction Features
        • Transaction Uniqueness
        • Controllable Transaction Lifecycle
        • Clauses (Multi-Task Transaction)
        • Fee Delegation
          • Multi-Party Payment (MPP)
          • Designated Gas Payer (VIP-191)
        • Transaction Dependency
    • Block Explorers
    • Wallets
      • VeWorld
        • User Guide
          • Setup
          • Wallet
          • Signing
          • Activities
          • Settings
        • FAQ
      • Sync2
        • User Guide
          • Setup
          • Wallet
          • Signing
          • Activities
          • Settings
        • FAQ
      • Sync
        • User Guide
          • Wallet
          • Ledger Device
          • Browser dApps and web
          • Interact with dApps
          • Activities
          • Settings
          • Report an Issue
          • Contributing
        • FAQ
    • EVM Compatibility
      • VeChain Modifications
      • Methodology
      • Test Coverage
        • Gas model
        • Raw transaction
        • hardhat specific
          • Ganache failures
          • evm_increaseTime
        • Failures in constructor
        • eth_sign
        • Contract address prediction
        • BadBeacon proxy address at 0x1
      • How to Recreate
      • Additional Information
        • Using Governance Contracts
        • ERC1820/ERC777 Testnet
        • Delegate Options
    • Account Abstraction
      • UserOperation
      • Bundler
      • EntryPoint Contract
      • Account Factory Contract
      • Paymaster Contract
    • Token Bound Accounts
  • How to run a node
    • Nodes
    • How to run a Thor Solo Node
    • Custom Network
    • Connect Sync2 to a Thor Solo Node
  • Developer Resources
    • Getting Started
    • How to build on VeChain
      • Connect to the Network
      • Read Data
        • Read Blocks
        • Read Transactions
        • Read Accounts
        • States & Views
        • Events & Logs
        • VET Transfers
      • Write Data
        • Transactions
        • Fee Delegation
      • Listen to Changes
        • Events
        • VET Transfers
        • Transactions
        • Blocks
        • Beats
      • Build with Hardhat
      • Utilities
        • BigInt and Unit-Handling
        • Name Service Lookups
    • Example dApps
      • Buy me a Coffee
      • Token Bound Accounts
      • PWA with Privy and Account Abstraction
    • EVM Compatibility for Developers
      • Key Architectural Differences and Optimizations
      • Practical Implications for Developers: Key Considerations
      • RPC Methods (Detailed Breakdown)
      • Frequently Asked Questions (FAQs)
      • VeChain Blockchain Specifications
      • Key Differences Between VeChain and Ethereum (Summary)
      • Best Practices for Developing on VeChainThor
    • How to verify Address-Ownership
      • Next.js Session Verification
    • Debug Reverted Transactions
    • Account Abstraction
    • VIP-191: Designated Gas Payer
      • How to Integrate VIP-191 (I)
      • How to Integrate VIP-191 (II)
      • How to Integrate VIP-191 (III)
    • Index with Graph Node
      • Setup with Docker
      • Index with OpenZeppelin
        • Create Subgraph Project
        • Configure Contracts
        • Deploy Subgraph and start Indexing
        • Track Subgraph Indexing
        • Access Subgraph
        • Update Subgraph
    • SDKs & Providers
      • SDK
        • Architecture
        • Accounts
        • Bloom Filter
        • Certificates
        • Contracts
        • Cryptography
        • Debug
        • Encoding
        • Polls
        • Subscriptions
        • Thor Client
        • Transactions
      • Thor DevKit
        • Installation
        • Usage
          • Cryptography
          • Accounts
          • Encoding
          • Transactions
          • Certificates
          • Bloom Filter
      • DApp Kit
        • v2
          • Installation
          • React
            • Installation
            • Usage
          • Vanilla JS
            • Installation
            • Usage
          • Core
            • Installation
            • Usage
          • Theme Variables
          • i18n
        • v1
          • Installation
          • React
            • Installation
            • Usage
          • Vanilla JS
            • Installation
            • Usage
          • Core
            • Installation
            • Usage
          • Theme Variables
          • i18n
          • Node Polyfills
          • V0 to V1
        • v0
          • Installation
          • Usage
          • React
            • Installation
            • Usage
          • Vanilla (UI)
            • Installation
            • Usage
          • Styles (UI)
          • i18n
      • VeChain Kit
      • DevPal
      • Web3-Providers-Connex
        • Installation
        • Usage
      • Connex
        • Installation
        • API Specification
    • Frameworks & IDEs
      • Hardhat
      • Remix
    • Built-in Contracts
    • VORJ
    • Useful Links
  • How to contribute
Powered by GitBook
On this page
  • Build Transaction
  • Collecting Function Calls in Clauses
  • Calculate Gas
  • Build Transaction
  • Sign Transaction
  • Send Transaction
  • Wait for Results
  • Example Project

Was this helpful?

  1. Developer Resources
  2. How to build on VeChain
  3. 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:

const clauses = [
    Clause.callFunction(
        '0x8384738c995d49c5b692560ae688fc8b51af1059',
        new ABIFunction({
            name: 'increment',
            inputs: [],
            outputs: [],
            constant: false,
            payable: false,
            type: 'function',
        })
    ),
];

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, which is generated by holding VET.

To calculate the right amount of gas for your transaction, you can use estimateGas.

const gasResult = await thor.transactions.estimateGas(clauses, senderAddress);

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.

Build Transaction

Once you have instructions + costs, you'll wrap them together into a transaction object with buildTransactionBody.

const txBody = await thor.transactions.buildTransactionBody(
    clauses,
    gasResult.totalGas
);

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

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:

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:

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:

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:

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:

const txReceipt = await thor.transactions.waitForTransaction(
  sendTransactionResult.id
);

Example Project

PreviousWrite DataNextFee Delegation

Last updated 2 months ago

Was this helpful?

A clause can also send VET in the same action. Check the to also learn more about the internals.

There are 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.

type definition
several options