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
  • Account
  • Account Registry
  • Creating an Account
  • Getting an Account's Address
  • Account Interaction
  • NFT
  • Account Ownership
  • Example

Was this helpful?

  1. Developer Resources
  2. Example dApps

Token Bound Accounts

PreviousBuy me a CoffeeNextPWA with Privy and Account Abstraction

Last updated 11 months ago

Was this helpful?

Account

Account abstraction sets up an on-chain wallet that can store assets and act like a regular wallet. With this approach, a crypto wallet becomes a unique smart contract that can be programmed for various purposes.

A single contract with wallet functionality is deployed, controlled by a single owner. The owner is identified by checking the owner of the tokenId at the NFT contract address, both stored in the account during creation.

An example account contract is available on GitHub: .

Account Registry

The registry is a helper contract that deploys account contracts and calculates their unique contract address using a tokenId & NFT contract address. It acts like a singleton factory that creates an account only once and returns the same address every time.

The NFT contract address and tokenId linked to the account are provided during account creation and stored in the account for future access verification.

An example registry contract is available on GitHub: .

Creating an Account

During NFT minting, the Registry can be instructed to create a new Account. The account will only be created once:

IERC6551Registry("0x_<Registry-Deployment>")
    .createAccount(
        "0x_<Account-Deployment>",
        block.chainid,
        "0x_<NFT-Deployment>",
        tokenId,
        salt,
        ""
    );

The account creation can also be delayed, to only create it when required.

Getting an Account's Address

Using the account() function, the same address will always be calculated, allowing you to know an address even before the wallet is deployed.

IERC6551Registry("0x_<Registry-Deployment>")
    .account(
        "0x_<Account-Deployment>",
        block.chainid,
        "0x_<NFT-Deployment>",
        tokenId,
        salt
    );

Account Interaction

Using the address and the account interface, the account can be instructed using the execute() function:

ExampleERC6551Account("0x_<Account Address>")
    .execute(
        "0x_<recipient/to address>",
        vetBalanceToTransferOr0,
        encodedData,
        0
    )

For example, transferring VTHO and 0 VET:

TBA.execute(
    // VTHO Address
    "0x0000000000000000000000000000456e65726779",
    
    // VET Value to transfer
    0,
    
    // Instructions on the recipient
    vtho.interface.encodeFunctionData("transfer", [owner, vthoAmount]),
    
    // must be 0 in the example contract
    0
)

NFT

The NFT contract is a basic OpenZeppelin template. Its address and tokenId provide proof of ownership.

Account Ownership

Ownership in the example account is possible because, during account creation, the address of the NFT contract and the corresponding tokenId are stored within the account.

Using this information, the account will verify ownership using the ownerOf() functionality on the NFT contract:

IERC721(tokenContract).ownerOf(tokenId);

Example

An example contract can be generated with OpenZeppelin as ERC721 on .

An example project showing all elements connected into a single Hardhat project is available on GitHub at .

ExampleERC6551Account.sol
ERC6551Registry.sol
https://wizard.openzeppelin.com/#erc721
example-token-bound-accounts