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
      • 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
  • Introduction
  • Description and Flow
  • Credit Plan
  • Master Account
  • MPP Implementation
  • Functions related to user
  • Functions related to the credit plan
  • Functions related to master
  • Functions related to sponsor

Was this helpful?

  1. Core Concepts
  2. Transactions
  3. Meta Transaction Features
  4. Fee Delegation

Multi-Party Payment (MPP)

The native VeChainThor fee delegation protocol.

PreviousFee DelegationNextDesignated Gas Payer (VIP-191)

Last updated 11 months ago

Was this helpful?

Introduction

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.

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

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:

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−cused+r⋅max(0,h−h0))c = min(C, C - c_{used} + r \cdot max(0,h-h_0))c=min(C,C−cused​+r⋅max(0,h−h0​))

where CCC denotes Credit, rrrRecoverRate, hhh the current block height, h0h_0h0​ the block height when the user used credit last time and cusedc_{used}cused​ the amount of credit consumed after the user's last transaction is paid by the account. Note that C−cusedC - c_{used}C−cused​ is the remaining credit after the last transaction is paid.

Master Account

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

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.

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.

The MPP implementation is available here

prototype.sol
MPP fee delegation flow