# Table of Contents - [Home | OP_NET Docs](#home-op-net-docs) - [Search the documentation | OP_NET Docs](#search-the-documentation-op-net-docs) - [Prerequisites | OP_NET Docs](#prerequisites-op-net-docs) - [Introduction | OP_NET Docs](#introduction-op-net-docs) - [For Next.js | OP_NET Docs](#for-next-js-op-net-docs) - [For Node.js | OP_NET Docs](#for-node-js-op-net-docs) - [OP_NET OpenZeppelin Alternatives | OP_NET Docs](#op-net-openzeppelin-alternatives-op-net-docs) - [For React (Vite) | OP_NET Docs](#for-react-vite-op-net-docs) - [Creating Custom Calldata with BinaryWriter | OP_NET Docs](#creating-custom-calldata-with-binarywriter-op-net-docs) - [WebSocket Provider | OP_NET Docs](#websocket-provider-op-net-docs) - [Staking Simulation | OP_NET Docs](#staking-simulation-op-net-docs) - [Using the ABICoder Class | OP_NET Docs](#using-the-abicoder-class-op-net-docs) - [HTTP Provider | OP_NET Docs](#http-provider-op-net-docs) - [Instantiating a Contract | OP_NET Docs](#instantiating-a-contract-op-net-docs) - [Getting a Contract ABI | OP_NET Docs](#getting-a-contract-abi-op-net-docs) - [Cross-Chain Mining | OP_NET Docs](#cross-chain-mining-op-net-docs) - [SHA-1 Collision Challenge | OP_NET Docs](#sha-1-collision-challenge-op-net-docs) - [Deploying a Contract | OP_NET Docs](#deploying-a-contract-op-net-docs) - [Introduction to Mineable UTXOs | OP_NET Docs](#introduction-to-mineable-utxos-op-net-docs) - [Sending a Simulated Transaction | OP_NET Docs](#sending-a-simulated-transaction-op-net-docs) - [Simulating a Transaction | OP_NET Docs](#simulating-a-transaction-op-net-docs) - [Nodes | OP_NET Docs](#nodes-op-net-docs) - [NFTs | OP_NET Docs](#nfts-op-net-docs) - [Networks | OP_NET Docs](#networks-op-net-docs) - [Native Bitcoin | OP_NET Docs](#native-bitcoin-op-net-docs) - [Introduction | OP_NET Docs](#introduction-op-net-docs) - [OP_20 Standard | OP_NET Docs](#op-20-standard-op-net-docs) - [What is OP_NET? | OP_NET Docs](#what-is-op-net-op-net-docs) - [Getting UTXOs for an Address with Required Amount | OP_NET Docs](#getting-utxos-for-an-address-with-required-amount-op-net-docs) - [Keeping UTXOs Changes in Memory | OP_NET Docs](#keeping-utxos-changes-in-memory-op-net-docs) - [Markdown Examples | OP_NET Docs](#markdown-examples-op-net-docs) - [Transaction Gas & Priority | OP_NET Docs](#transaction-gas-priority-op-net-docs) - [Unified Accounts | OP_NET Docs](#unified-accounts-op-net-docs) - [Introduction | OP_NET Docs](#introduction-op-net-docs) - [Getting UTXOs for an Address | OP_NET Docs](#getting-utxos-for-an-address-op-net-docs) - [Introduction | OP_NET Docs](#introduction-op-net-docs) - [Sending a Transaction | OP_NET Docs](#sending-a-transaction-op-net-docs) - [Handling Events and Logs | OP_NET Docs](#handling-events-and-logs-op-net-docs) - [Advanced Testing Techniques | OP_NET Docs](#advanced-testing-techniques-op-net-docs) - [Deploying a Contract | OP_NET Docs](#deploying-a-contract-op-net-docs) - [Common Testing Scenarios | OP_NET Docs](#common-testing-scenarios-op-net-docs) - [Interacting with the Blockchain in Tests | OP_NET Docs](#interacting-with-the-blockchain-in-tests-op-net-docs) - [Writing Unit Tests | OP_NET Docs](#writing-unit-tests-op-net-docs) - [Setting Up WalletConnect | OP_NET Docs](#setting-up-walletconnect-op-net-docs) - [Introduction | OP_NET Docs](#introduction-op-net-docs) - [Setting Up the Unit Test Environment | OP_NET Docs](#setting-up-the-unit-test-environment-op-net-docs) - [Testing Smart Contracts | OP_NET Docs](#testing-smart-contracts-op-net-docs) - [Calling Another Contract | OP_NET Docs](#calling-another-contract-op-net-docs) - [Setting Up the Template for Your OP_NET Contract | OP_NET Docs](#setting-up-the-template-for-your-op-net-contract-op-net-docs) - [Addresses on OP_NET | OP_NET Docs](#addresses-on-op-net-op-net-docs) - [Debugging Contracts on OP_NET | OP_NET Docs](#debugging-contracts-on-op-net-op-net-docs) - [BinaryWriter and BinaryReader Usage | OP_NET Docs](#binarywriter-and-binaryreader-usage-op-net-docs) - [Fetching Block Gas | OP_NET Docs](#fetching-block-gas-op-net-docs) - [Fetching Block Data | OP_NET Docs](#fetching-block-data-op-net-docs) - [SafeMath and u256 Usage | OP_NET Docs](#safemath-and-u256-usage-op-net-docs) - [Contract Runtime | OP_NET Docs](#contract-runtime-op-net-docs) - [Fetching Transaction Data | OP_NET Docs](#fetching-transaction-data-op-net-docs) - [Fetching Transaction Receipt | OP_NET Docs](#fetching-transaction-receipt-op-net-docs) - [Get Gas Parameters | OP_NET Docs](#get-gas-parameters-op-net-docs) - [Fetching Public Key from Address | OP_NET Docs](#fetching-public-key-from-address-op-net-docs) - [Getting the Balance of an Address | OP_NET Docs](#getting-the-balance-of-an-address-op-net-docs) - [Get Current Block Number | OP_NET Docs](#get-current-block-number-op-net-docs) - [Interacting with Smart Contracts Using Call | OP_NET Docs](#interacting-with-smart-contracts-using-call-op-net-docs) - [Fetching a Storage Slot | OP_NET Docs](#fetching-a-storage-slot-op-net-docs) - [Sending Raw Transaction (Hex) | OP_NET Docs](#sending-raw-transaction-hex-op-net-docs) - [Validating a Bitcoin Address for a Network | OP_NET Docs](#validating-a-bitcoin-address-for-a-network-op-net-docs) - [Fetching the Code of a Contract | OP_NET Docs](#fetching-the-code-of-a-contract-op-net-docs) - [Introduction | OP_NET Docs](#introduction-op-net-docs) - [Storing Data on OP_NET | OP_NET Docs](#storing-data-on-op-net-op-net-docs) - [Getting Block Witnesses | OP_NET Docs](#getting-block-witnesses-op-net-docs) - [Getting Reorganizations (Reorgs) | OP_NET Docs](#getting-reorganizations-reorgs-op-net-docs) - [Batch Requests | OP_NET Docs](#batch-requests-op-net-docs) --- # Home | OP_NET Docs [Skip to main content](https://docs.opnet.org/#__docusaurus_skipToContent_fallback) OP\_NET Documentation ===================== Unleash the Power of Bitcoin with OP\_NET. * [Learn about OP\_NET\ \ Understand the core concepts and features of OP\_NET.](https://docs.opnet.org/learn/what-is-opnet) * [Get started with OP\_NET\ \ Learn how to get started by setting up your development environment.](https://docs.opnet.org/developers/getting-started/introduction) Explore Key Topics in the OP\_NET Documentation ----------------------------------------------- * [Unified Accounts\ \ Discover how unified accounts simplify interactions by eliminating address type complexities.](https://docs.opnet.org/learn/unified-accounts) * [Setting Up a Provider\ \ Step-by-step guide to connecting your application to an OP\_NET node.](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider) * [OP\_20 Standard\ \ Learn about the OP\_20 standard, OP\_NET’s equivalent to ERC-20.](https://docs.opnet.org/learn/op-20-standard) * [Using the UTXO Manager\ \ Optimize your application’s UTXO handling with the powerful UTXO Manager.](https://docs.opnet.org/developers/using-the-utxo-manager/introduction) * [Contract Interactions\ \ Understand how to deploy and interact with contracts on OP\_NET.](https://docs.opnet.org/developers/interacting-with-a-contract/introduction) * [Transaction Gas and Priority\ \ Learn everything you need to know about transaction gas and priority.](https://docs.opnet.org/learn/transaction-gas-and-priority) * [Smart Contract Development\ \ Guides and tools for creating powerful smart contracts on OP\_NET.](https://docs.opnet.org/developers/smart-contract-development/introduction) * [Advanced Topics\ \ Explore advanced interactions like custom calldata and batch requests.](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/fetching-a-storage-slot) Engage the developer community ------------------------------ Join the OP\_NET community to learn, share, and collaborate with other developers building on OP\_NET. * [Developer Telegram\ \ Connect with other OP\_NET Builders and developers.](https://t.me/+Oi6rBWe66zJkNDkx) More resources: * [Founders Talks About OP\_NET](https://www.youtube.com/watch?v=80g4g2WvZi4&t=933s) * [@opnetbtc on X](https://x.com/opnetbtc) --- # Search the documentation | OP_NET Docs [Skip to main content](https://docs.opnet.org/search#__docusaurus_skipToContent_fallback) Search the documentation ======================== [](https://www.algolia.com/) --- # Prerequisites | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/getting-started/prerequisites#__docusaurus_skipToContent_fallback) On this page Before starting development on the OP\_NET metaprotocol, ensure your environment meets the following requirements. These tools and dependencies are essential to interact with the OP\_NET ecosystem efficiently. * * * **System Requirements**[​](https://docs.opnet.org/developers/getting-started/prerequisites#system-requirements "Direct link to system-requirements") ----------------------------------------------------------------------------------------------------------------------------------------------------- ### **Software**[​](https://docs.opnet.org/developers/getting-started/prerequisites#software "Direct link to software") 1. **Node.js (v22.x) - Not lower or higher** * Required for running JavaScript/TypeScript projects. ([TYPESCRIPT IS HIGHLY RECOMMENDED](https://docs.opnet.org/developers/getting-started/prerequisites#important-warnings) ) * Download the version from [Node.js Official Website](https://nodejs.org/) . 2. **Rust (latest version)** Rust is required for compiling and running packages like `@btc-vision/op-vm` and `@btc-vision/unit-test-framework`. You can install it on Linux, macOS, or Windows: * **Linux & macOS** 1. Open your terminal. 2. Run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 3. Follow the on‑screen prompts (choose the default installation unless you have custom needs). 4. Verify with: rustc --version * **Windows (MSVC)** 1. Make sure you have the **Visual Studio Build Tools** installed (see [Windows prerequisites](https://rust-lang.github.io/rustup/installation/windows-msvc.html) ). 2. Visit [rustup.rs](https://rustup.rs/) in your browser. 3. Click **“Install”** (the site will detect Windows and offer the correct installer). 4. Run the downloaded `rustup-init.exe` and follow the default steps. 5. Open **PowerShell** or **Command Prompt** and verify: rustc --version **Essential NPM Packages**[​](https://docs.opnet.org/developers/getting-started/prerequisites#essential-npm-packages "Direct link to essential-npm-packages") -------------------------------------------------------------------------------------------------------------------------------------------------------------- The OP\_NET ecosystem includes the following NPM packages that streamline development: ### **Important Packages**[​](https://docs.opnet.org/developers/getting-started/prerequisites#important-packages "Direct link to important-packages") 1. [`opnet`](https://github.com/btc-vision/opnet) * The official OP\_NET TypeScript SDK for interacting with the metaprotocol. 2. [`@btc-vision/transaction`](https://github.com/btc-vision/transaction) * A library for creating and signing transactions within the OP\_NET environment. 3. [`@btc-vision/walletconnect`](https://github.com/btc-vision/walletconnect) * A library for connecting wallets to web applications. 4. [`@btc-vision/bitcoin`](https://github.com/btc-vision/bitcoin) * A Bitcoin library like `bitcoinjs-lib` but specifically designed for OP\_NET. Important Note DO NOT USE `bitcoinjs-lib` or any other Bitcoin library. Use `@btc-vision/bitcoin`, which is specifically designed for OP\_NET. 5. [`@btc-vision/op-vm`](https://github.com/btc-vision/op-vm) * A virtual machine runtime for OP\_NET smart contracts. * **Requires Rust (latest version)** for installation and usage. 6. [`@btc-vision/unit-test-framework`](https://github.com/btc-vision/unit-test-framework) * A testing framework designed for projects utilizing `@btc-vision/op-vm`. * **Requires Rust (latest version)** for installation and usage. * * * **Hardware Recommendations**[​](https://docs.opnet.org/developers/getting-started/prerequisites#hardware-recommendations "Direct link to hardware-recommendations") -------------------------------------------------------------------------------------------------------------------------------------------------------------------- * **Processor**: Multi-core CPU recommended for faster compilation. * **Memory**: Minimum 8 GB RAM for smooth development. * **Storage**: At least 10 GB of free disk space for dependencies and project files. * * * **Important Warnings**[​](https://docs.opnet.org/developers/getting-started/prerequisites#important-warnings "Direct link to important-warnings") -------------------------------------------------------------------------------------------------------------------------------------------------- TypeScript Usage While it is possible to use JavaScript for developing on OP\_NET, it is **highly recommended** to use TypeScript. TypeScript provides type safety, which helps prevent runtime errors and improves code maintainability. Without TypeScript, developers may encounter unexpected issues and errors in their projects. To get started with TypeScript: 1. Install TypeScript globally: npm install -g typescript 2. Verify the installation: tsc --version * * * **What’s Next?**[​](https://docs.opnet.org/developers/getting-started/prerequisites#whats-next "Direct link to whats-next") ---------------------------------------------------------------------------------------------------------------------------- Once you’ve met these prerequisites, proceed to [Setting Up Your Development Environment](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs) to start building with OP\_NET. Note Failure to meet these requirements, especially Node.js v22.x or the latest Rust version, may result in errors during package installation or runtime. * [**System Requirements**](https://docs.opnet.org/developers/getting-started/prerequisites#system-requirements) * [**Software**](https://docs.opnet.org/developers/getting-started/prerequisites#software) * [**Essential NPM Packages**](https://docs.opnet.org/developers/getting-started/prerequisites#essential-npm-packages) * [**Important Packages**](https://docs.opnet.org/developers/getting-started/prerequisites#important-packages) * [**Hardware Recommendations**](https://docs.opnet.org/developers/getting-started/prerequisites#hardware-recommendations) * [**Important Warnings**](https://docs.opnet.org/developers/getting-started/prerequisites#important-warnings) * [**What’s Next?**](https://docs.opnet.org/developers/getting-started/prerequisites#whats-next) --- # Introduction | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/getting-started/introduction#__docusaurus_skipToContent_fallback) On this page Welcome to the developer's guide for OP\_NET, the metaprotocol that brings smart contract functionality to Bitcoin. This guide will walk you through the basics of setting up your environment, understanding the core concepts, and starting your journey to build decentralized applications (dApps) on the Bitcoin blockchain. New to OP\_NET? If you're new to OP\_NET, we recommend reviewing the [Learn Section](https://docs.opnet.org/learn/unified-accounts) for an introduction to the protocol and its features. * * * **What You'll Learn**[​](https://docs.opnet.org/developers/getting-started/introduction#what-youll-learn "Direct link to what-youll-learn") -------------------------------------------------------------------------------------------------------------------------------------------- This guide will help you: 1. **Set Up Your Environment**: Learn the tools and dependencies required to build on OP\_NET. 2. **Understand the Basics**: Dive into fundamental concepts like accounts, contracts, and transactions. 3. **Build Your First dApp**: Step-by-step instructions to deploy and interact with smart contracts. * * * **Development Workflow**[​](https://docs.opnet.org/developers/getting-started/introduction#development-workflow "Direct link to development-workflow") ------------------------------------------------------------------------------------------------------------------------------------------------------- Here’s an overview of the typical development process on OP\_NET: ### **1\. Install the prerequisites**[​](https://docs.opnet.org/developers/getting-started/introduction#1-install-the-prerequisites "Direct link to 1-install-the-prerequisites") Ensure you have the necessary tools and dependencies installed on your system. Follow the instructions in the [Prerequisites](https://docs.opnet.org/developers/getting-started/prerequisites) section. ### **2\. Setting Up the Environment**[​](https://docs.opnet.org/developers/getting-started/introduction#2-setting-up-the-environment "Direct link to 2-setting-up-the-environment") Prepare your development environment by installing the required tools, libraries, and SDKs. Follow the instructions in [Setting Up Your Environment](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs) . ### **3\. Writing and Deploying Smart Contracts**[​](https://docs.opnet.org/developers/getting-started/introduction#3-writing-and-deploying-smart-contracts "Direct link to 3-writing-and-deploying-smart-contracts") Develop smart contracts using AssemblyScript or Rust, compile them to WebAssembly (Wasm), and deploy them to the OP\_NET network. Learn more in the [Smart Contract Development](https://docs.opnet.org/developers/smart-contract-development/introduction) section. ### **4\. Interacting with Contracts**[​](https://docs.opnet.org/developers/getting-started/introduction#4-interacting-with-contracts "Direct link to 4-interacting-with-contracts") Leverage the OP\_NET SDK to interact with deployed contracts, perform token transfers, and execute complex dApp logic. Learn more in the [Interacting with a Contract](https://docs.opnet.org/developers/interacting-with-a-contract/introduction) . ### **5\. Testing and Debugging**[​](https://docs.opnet.org/developers/getting-started/introduction#5-testing-and-debugging "Direct link to 5-testing-and-debugging") Use the OP\_NET unit testing framework to ensure your contracts behave as expected. Debug using built-in logging features. Learn more in the [OP\_NET Unit Test Framework](https://docs.opnet.org/developers/opnet-unit-test-framework/introduction) . * * * **Get Involved**[​](https://docs.opnet.org/developers/getting-started/introduction#get-involved "Direct link to get-involved") ------------------------------------------------------------------------------------------------------------------------------- Join the OP\_NET developer community to share ideas, get support, and collaborate: * **Telegram**: [Join the discussion](https://t.me/+Oi6rBWe66zJkNDkx) * **GitHub**: [Access resources and repositories](https://github.com/btc-vision) * **Twitter**: [Join the community](https://x.com/opnetbtc) Let’s start building the future of decentralized applications on Bitcoin with OP\_NET! * [**What You'll Learn**](https://docs.opnet.org/developers/getting-started/introduction#what-youll-learn) * [**Development Workflow**](https://docs.opnet.org/developers/getting-started/introduction#development-workflow) * [**1\. Install the prerequisites**](https://docs.opnet.org/developers/getting-started/introduction#1-install-the-prerequisites) * [**2\. Setting Up the Environment**](https://docs.opnet.org/developers/getting-started/introduction#2-setting-up-the-environment) * [**3\. Writing and Deploying Smart Contracts**](https://docs.opnet.org/developers/getting-started/introduction#3-writing-and-deploying-smart-contracts) * [**4\. Interacting with Contracts**](https://docs.opnet.org/developers/getting-started/introduction#4-interacting-with-contracts) * [**5\. Testing and Debugging**](https://docs.opnet.org/developers/getting-started/introduction#5-testing-and-debugging) * [**Get Involved**](https://docs.opnet.org/developers/getting-started/introduction#get-involved) --- # For Next.js | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nextjs#__docusaurus_skipToContent_fallback) On this page This guide explains how to install the necessary packages to start developing with OP\_NET in a Next.js environment. Important Note ### **Use TypeScript Instead of JavaScript**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nextjs#use-typescript-instead-of-javascript "Direct link to use-typescript-instead-of-javascript") OP\_NET development requires strict type handling to avoid runtime errors. Using **JavaScript** may lead to unexpected issues due to its lack of type enforcement. **TypeScript** is strongly recommended as it provides: * Type safety for all OP\_NET packages. * Better debugging and error handling during development. If you must use JavaScript, ensure you carefully validate all inputs and outputs, but TypeScript remains the preferred option for stability and accuracy. ### **Node.js Version Compatibility**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nextjs#nodejs-version-compatibility "Direct link to nodejs-version-compatibility") Ensure you are using **Node.js v22.x**. Older versions or newer releases may cause compatibility issues with OP\_NET packages. Check your Node.js version using: node -v * * * **Installing Required Packages**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nextjs#installing-required-packages "Direct link to installing-required-packages") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Install it via npm: npm install opnet @btc-vision/transaction @btc-vision/bitcoin For more information on each package, refer to the following links: [Prerequisites](https://docs.opnet.org/developers/getting-started/prerequisites) . * * * **Next Steps**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nextjs#next-steps "Direct link to next-steps") ---------------------------------------------------------------------------------------------------------------------------------------------- Once your environment is configured, proceed to [Interacting with an OP\_NET Node](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider) for further guidance. You can also refer to the [WalletConnect Documentation](https://docs.opnet.org/developers/walletconnect/introduction) for information on connecting wallets to your Next.js application. * [**Use TypeScript Instead of JavaScript**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nextjs#use-typescript-instead-of-javascript) * [**Node.js Version Compatibility**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nextjs#nodejs-version-compatibility) * [**Installing Required Packages**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nextjs#installing-required-packages) * [**Next Steps**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nextjs#next-steps) --- # For Node.js | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs#__docusaurus_skipToContent_fallback) On this page This guide explains how to install the necessary packages to start developing with OP\_NET in a Node.js environment. Important Note ### **Use TypeScript Instead of JavaScript**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs#use-typescript-instead-of-javascript "Direct link to use-typescript-instead-of-javascript") OP\_NET development requires strict type handling to avoid runtime errors. Using **JavaScript** may lead to unexpected issues due to its lack of type enforcement. **TypeScript** is strongly recommended as it provides: * Type safety for all OP\_NET packages. * Better debugging and error handling during development. If you must use JavaScript, ensure you carefully validate all inputs and outputs, but TypeScript remains the preferred option for stability and accuracy. ### **Node.js Version Compatibility**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs#nodejs-version-compatibility "Direct link to nodejs-version-compatibility") Ensure you are using **Node.js v22.x**. Older versions or newer releases may cause compatibility issues with OP\_NET packages. Check your Node.js version using: node -v * * * **Installing Required Packages**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs#installing-required-packages "Direct link to installing-required-packages") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Install it via npm: npm install opnet @btc-vision/transaction @btc-vision/bitcoin For more information on each package, refer to the following links: [Prerequisites](https://docs.opnet.org/developers/getting-started/prerequisites) . * * * **Next Steps**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs#next-steps "Direct link to next-steps") ---------------------------------------------------------------------------------------------------------------------------------------------- Once your environment is configured, proceed to [Interacting with an OP\_NET Node](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider) for further guidance. * [**Use TypeScript Instead of JavaScript**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs#use-typescript-instead-of-javascript) * [**Node.js Version Compatibility**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs#nodejs-version-compatibility) * [**Installing Required Packages**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs#installing-required-packages) * [**Next Steps**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs#next-steps) --- # OP_NET OpenZeppelin Alternatives | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/opnet-openzeppelin-alternatives#__docusaurus_skipToContent_fallback) On this page When developing on OP\_NET, you can leverage pre-built contract libraries similar to OpenZeppelin for Ethereum. These libraries provide essential building blocks for creating robust smart contracts, enabling developers to focus on innovation without reinventing the wheel. Advantages of Using OP\_NET Libraries * **Time Savings**: Skip the hassle of creating foundational code from scratch. * **Security Assurance**: Use thoroughly tested and community-validated modules. * **Ease of Integration**: Libraries are designed to work seamlessly with the OP\_NET runtime and development tools. * **Customization**: Extend or modify existing modules to suit your specific requirements. * * * **Available Contracts for Developers**[​](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/opnet-openzeppelin-alternatives#available-contracts-for-developers "Direct link to available-contracts-for-developers") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The OP\_NET ecosystem offers a growing set of reusable contract modules, including templates for: * **Access Control**: Role-based access control for secure contract management. * **Utility Contracts**: Libraries for math operations, address validation, and more. ### **Explore the Repository**[​](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/opnet-openzeppelin-alternatives#explore-the-repository "Direct link to explore-the-repository") Access the official **Contract Libraries Repository** on GitHub to browse and integrate these ready-to-use modules: [Contract Libraries Repository](https://github.com/btc-vision/contract-libraries) * * * **How to Use These Libraries**[​](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/opnet-openzeppelin-alternatives#how-to-use-these-libraries "Direct link to how-to-use-these-libraries") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1. **Clone the Repository** Download the library source code: git clone https://github.com/btc-vision/contract-libraries.gitcd contract-libraries 2. **Install Dependencies** Ensure your environment is set up correctly by installing the required dependencies: npm install * * * **Next Steps**[​](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/opnet-openzeppelin-alternatives#next-steps "Direct link to next-steps") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * **Browse Contract Templates**: Start exploring the [Contract Libraries Repository](https://github.com/btc-vision/contract-libraries) to find modules relevant to your project. * **Learn More**: Dive into OP\_NET's [Smart Contract Development Documentation](https://docs.opnet.org/developers/smart-contract-development/introduction) for additional resources. * [**Available Contracts for Developers**](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/opnet-openzeppelin-alternatives#available-contracts-for-developers) * [**Explore the Repository**](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/opnet-openzeppelin-alternatives#explore-the-repository) * [**How to Use These Libraries**](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/opnet-openzeppelin-alternatives#how-to-use-these-libraries) * [**Next Steps**](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/opnet-openzeppelin-alternatives#next-steps) --- # For React (Vite) | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#__docusaurus_skipToContent_fallback) On this page To build React applications for OP\_NET, you must use **Vite** instead of Create React App (CRA), as CRA is outdated and doesn't provide the optimizations and compatibility required for modern development. This guide outlines the required configurations for your development environment. Why use Vite? Vite offers a modern, fast, and optimized bundler that integrates seamlessly with React. It ensures compatibility with OP\_NET and significantly improves the development experience. * * * **Creating a New React Project**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#creating-a-new-react-project "Direct link to creating-a-new-react-project") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To create a new React project with Vite, use the following command: npm create vite@latest my-app -- --template react-ts * * * **Configuration**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#configuration "Direct link to configuration") ------------------------------------------------------------------------------------------------------------------------------------------------------ To ensure your React project works properly with OP\_NET, the following configurations are **required**. Without these, your React project may not build or run correctly. ### **1\. Vite Configuration**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#1-vite-configuration "Direct link to 1-vite-configuration") Install the required plugins: npm install vite@5 vite-plugin-node-polyfills vite-plugin-eslint2 IMPORTANT Ensure you use **vite@5** for compatibility with `vite-plugin-eslint2`. Below is the required `vite.config.ts` file: import react from "@vitejs/plugin-react";import { defineConfig } from "vite";import eslint from "vite-plugin-eslint2";import { nodePolyfills } from "vite-plugin-node-polyfills";export default defineConfig({ plugins: [react(), nodePolyfills(), eslint()], resolve: { alias: { global: "global", }, }, build: { rollupOptions: { output: { manualChunks(id) { if (id.includes("node_modules")) { return "vendor"; } }, }, }, },}); Best Practices * Using ESLint **version 9** is mandatory. Any other version may cause linting errors. * TypeScript is required for OP\_NET React development. Using JavaScript may lead to runtime issues and is strongly discouraged. * Ensure you configure your project with Vite, as Create React App is **not supported**. * Always use version 5 of Vite for compatibility with `vite-plugin-eslint2`. * * * ### **2\. TypeScript Configuration**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#2-typescript-configuration "Direct link to 2-typescript-configuration") Using TypeScript is mandatory for OP\_NET development. JavaScript may cause runtime issues and is not supported for production-level development. #### Root `tsconfig.json`:[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#root-tsconfigjson "Direct link to root-tsconfigjson") { "files": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ]} #### App-specific `tsconfig.app.json`:[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#app-specific-tsconfigappjson "Direct link to app-specific-tsconfigappjson") { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", "noEmit": true, "jsx": "react-jsx", "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"]} #### Node-specific `tsconfig.node.json`:[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#node-specific-tsconfignodejson "Direct link to node-specific-tsconfignodejson") { "compilerOptions": { "target": "ES2022", "lib": ["ES2023"], "module": "ESNext", "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", "noEmit": true, "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["vite.config.ts"]} ### **3\. ESLint Configuration**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#3-eslint-configuration "Direct link to 3-eslint-configuration") You must use ESLint **version 9**, no higher or lower versions are supported. Below is the required configuration file: **`eslint.config.js`** // @ts-checkimport eslint from "@eslint/js";import reactHooks from "eslint-plugin-react-hooks";import reactRefresh from "eslint-plugin-react-refresh";import globals from "globals";import tseslint from "typescript-eslint";export default tseslint.config( { ignores: ["dist"] }, { extends: [ eslint.configs.recommended, ...tseslint.configs.recommended, ...tseslint.configs.strictTypeChecked, ], files: ["**/*.{ts,tsx}"], languageOptions: { ecmaVersion: 2023, globals: globals.browser, parserOptions: { projectService: true, tsconfigDirName: import.meta.dirname, }, }, plugins: { // @ts-ignore "react-hooks": reactHooks, "react-refresh": reactRefresh, }, // @ts-ignore rules: { ...reactHooks.configs.recommended.rules, "react-refresh/only-export-components": [ "warn", { allowConstantExport: true }, ], "no-undef": "off", "@typescript-eslint/no-unused-vars": "off", "no-empty": "off", "@typescript-eslint/restrict-template-expressions": "off", "@typescript-eslint/only-throw-error": "off", "@typescript-eslint/no-unnecessary-condition": "off", "@typescript-eslint/unbound-method": "warn", "@typescript-eslint/no-confusing-void-expression": "off", "@typescript-eslint/no-extraneous-class": "off", "no-async-promise-executor": "off", "@typescript-eslint/no-misused-promises": "off", "@typescript-eslint/no-unnecessary-type-parameters": "off", "@typescript-eslint/no-duplicate-enum-values": "off", "prefer-spread": "off", "@typescript-eslint/no-empty-object-type": "off", "@typescript-eslint/no-non-null-assertion": "off", }, }, { files: ["**/*.js"], ...tseslint.configs.disableTypeChecked, }); **Next Steps**[​](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#next-steps "Direct link to next-steps") --------------------------------------------------------------------------------------------------------------------------------------------- Once your environment is configured, proceed to [Interacting with an OP\_NET Node](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider) for further guidance. You can also refer to the [WalletConnect Documentation](https://docs.opnet.org/developers/walletconnect/introduction) for information on connecting wallets to your React application. * [**Creating a New React Project**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#creating-a-new-react-project) * [**Configuration**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#configuration) * [**1\. Vite Configuration**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#1-vite-configuration) * [**2\. TypeScript Configuration**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#2-typescript-configuration) * [**3\. ESLint Configuration**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#3-eslint-configuration) * [**Next Steps**](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react#next-steps) --- # Creating Custom Calldata with BinaryWriter | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#__docusaurus_skipToContent_fallback) On this page The `BinaryWriter` class from `@btc-vision/transaction` is an essential tool for constructing calldata on OP\_NET. It offers precise control over encoding and ensures compatibility with smart contract interactions. Key Features of `BinaryWriter` * Encodes primitive types (`U8`, `U256`, `Boolean`, etc.) and complex structures (arrays, maps, tuples). * Designed to integrate seamlessly with OP\_NET's ABI coding. * Optimized for gas efficiency when used correctly. * * * **Using `BinaryWriter`**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#using-binarywriter "Direct link to using-binarywriter") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### Instantiation[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#instantiation "Direct link to Instantiation") const writer = new BinaryWriter(length?); * **`length` (optional)**: Pre-allocates the buffer to a specific size. Note Pre-allocating a buffer can improve performance when constructing large calldata. e.g., `new BinaryWriter(1024)` allocates a buffer of 1024 bytes. * * * ### **Creating Function Selectors**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#creating-function-selectors "Direct link to creating-function-selectors") To create a selector, use the `ABICoder`: import { ABICoder } from "@btc-vision/transaction";// Initialize ABI coderconst abiCoder = new ABICoder();// Generate the selector for a function (e.g., "mint")const mintSelector = Number(`0x${abiCoder.encodeSelector("mint()")}`);console.log("Mint Selector:", mintSelector); This selector represents the unique identifier for the contract's `mint` function. tip Learn more about [ABICoder](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder) for generating function selectors, encoding input parameters, and decoding returned data * * * ### **Common Methods in `BinaryWriter`**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#common-methods-in-binarywriter "Direct link to common-methods-in-binarywriter") ### Primitive Data Types[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#primitive-data-types "Direct link to Primitive Data Types") writer.writeU8(value: number); // Writes an unsigned 8-bit integer.writer.writeU256(value: bigint); // Writes an unsigned 256-bit integer.writer.writeBoolean(value: boolean); // Writes a boolean (1 byte). ### Complex Structures[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#complex-structures "Direct link to Complex Structures") writer.writeAddress(value: Address); // Writes an Address object.writer.writeTuple(values: bigint[]); // Writes a tuple of integers.writer.writeString(value: string); // Writes a string.writer.writeAddressValueTuple(map: AddressMap); // Writes an AddressMap. ### Buffer Operations[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#buffer-operations "Direct link to Buffer Operations") writer.getBuffer(clear: boolean = true): Uint8Array; // Returns the constructed buffer.writer.reset(); // Resets the writer to its initial state.writer.setOffset(offset: number); // Adjusts the current write offset. * * * **Example: Constructing Calldata**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#example-constructing-calldata "Direct link to example-constructing-calldata") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Here’s an example of creating calldata for a `mint` function: import { ABICoder, Address, AddressMap, BinaryWriter,} from "@btc-vision/transaction";const abiCoder = new ABICoder();const mintSelector = Number(`0x${abiCoder.encodeSelector("mint()")}`); // Generate selectorconst recipient = new Address(Buffer.from("...")); // Replace with valid Addressconst amount = 1000n; // Amount to mintconst decimals = 18n; // Token decimalsconst calldata = new BinaryWriter(); // Create a new BinaryWritercalldata.writeSelector(mintSelector); // Function selectorcalldata.writeAddress(recipient); // Recipient's addresscalldata.writeU256(BigInt(amount * 10n ** decimals)); // Amount scaled to token decimalscalldata.writeAddressValueTuple(new AddressMap()); // Example: Empty mapcalldata.writeU256(0n); // Placeholder for additional parametersconsole.log(calldata.getBuffer()); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#best-practices "Direct link to best-practices") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Specify an appropriate buffer size during instantiation for better performance. * Write compact types wherever possible, such as `writeU8` for small integers. * Always test calldata with simulations before broadcasting to ensure correctness. * Use the `ABICoder` to generate selectors dynamically. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#whats-next "Direct link to whats-next") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Continue exploring contract interaction techniques: * [Simulating a Transaction with a Contract Instance](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance) * [Sending a Simulated Transaction](https://docs.opnet.org/developers/interacting-with-a-contract/sending-a-simulated-transaction) * [**Using `BinaryWriter`**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#using-binarywriter) * [Instantiation](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#instantiation) * [**Creating Function Selectors**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#creating-function-selectors) * [**Common Methods in `BinaryWriter`**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#common-methods-in-binarywriter) * [Primitive Data Types](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#primitive-data-types) * [Complex Structures](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#complex-structures) * [Buffer Operations](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#buffer-operations) * [**Example: Constructing Calldata**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#example-constructing-calldata) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter#whats-next) --- # WebSocket Provider | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/websocket-provider#__docusaurus_skipToContent_fallback) On this page The WebSocket provider enables real-time communication with OP\_NET nodes, making it ideal for applications requiring instant updates, such as event listening. * * * **Coming Soon**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/websocket-provider#coming-soon "Direct link to coming-soon") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- Support for WebSocket providers is currently under development and will be available in a future update. Stay tuned for more information. Alternative For now, you can use the [HTTP Provider](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider) to interact with OP\_NET nodes. * [**Coming Soon**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/websocket-provider#coming-soon) --- # Staking Simulation | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-a-contract/btc-staking/staking-simulation#__docusaurus_skipToContent_fallback) On this page Simulating a BTC staking transaction is a crucial step before broadcasting it to the network. Simulation helps: * Prepare expected outputs * Verify the success of the transaction * Avoid errors like `No valid UTXO found for treasury fee` ### Example:[​](https://docs.opnet.org/developers/interacting-with-a-contract/btc-staking/staking-simulation#example "Direct link to Example:") const resDeposit = await simulateStakeBTC({ motoChefContract, stakeAmount, feeAmount, netStakeAmount, treasuryAddressP2TR, accountAddressTyped,}); The returned object contains: * **Outputs**: The fee and staking outputs to include * **Result**: The simulated transaction to send later Always run this simulation step before `sendTransaction()`. * * * ### Full example:[​](https://docs.opnet.org/developers/interacting-with-a-contract/btc-staking/staking-simulation#full-example "Direct link to Full example:") This full implementation is an example taken from a MotoChef staking use case. It demonstrates how to manually construct simulation outputs for a specific pool and pass them to the contract before calling `stakeBTC()`. export async function simulateStakeBTC({ motoChefContract, stakeAmount, feeAmount, netStakeAmount, treasuryAddressP2TR, accountAddressTyped,}: { motoChefContract: IMotoChef; stakeAmount: bigint; feeAmount: bigint; netStakeAmount: bigint; treasuryAddressP2TR: string; accountAddressTyped: string;}): Promise<{ result: StakeBTC; outputs: PsbtOutputExtended[] }> { const outSimulation: StrippedTransactionOutput[] = []; const outputs: PsbtOutputExtended[] = []; let index = 2; // Treasury output outputs.push({ address: treasuryAddressP2TR, value: Number(feeAmount), }); outSimulation.push({ index, to: treasuryAddressP2TR, value: feeAmount, flags: TransactionOutputFlags.hasTo, scriptPubKey: undefined, }); index++; // Stake output outputs.push({ address: accountAddressTyped, value: Number(netStakeAmount), }); outSimulation.push({ index, to: accountAddressTyped, value: netStakeAmount, flags: TransactionOutputFlags.hasTo, scriptPubKey: undefined, }); // Set simulation details const details: ParsedSimulatedTransaction = { inputs: [], outputs: outSimulation, }; motoChefContract.setTransactionDetails(details); // Simulate stakeBTC const result = await motoChefContract.stakeBTC(stakeAmount); if (!result.properties.success) throw new Error("Failed to simulate stake"); return { result, outputs };} * [Example:](https://docs.opnet.org/developers/interacting-with-a-contract/btc-staking/staking-simulation#example) * [Full example:](https://docs.opnet.org/developers/interacting-with-a-contract/btc-staking/staking-simulation#full-example) --- # Using the ABICoder Class | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#__docusaurus_skipToContent_fallback) On this page The `ABICoder` class is a powerful utility for encoding and decoding data to interact with OP\_NET smart contracts. It simplifies generating function selectors, encoding input parameters, and decoding returned data, ensuring seamless communication with OP\_NET contracts. * * * **Overview of the `ABICoder` Class**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#overview-of-the-abicoder-class "Direct link to overview-of-the-abicoder-class") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ The `ABICoder` class is part of the `@btc-vision/transaction` library and supports the following functionalities: * Encoding function selectors * Decoding contract return data * Encoding complex data types for calldata ### **Supported Data Types**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#supported-data-types "Direct link to supported-data-types") The `ABICoder` supports a wide range of data types defined in the `ABIDataTypes` enumeration: export declare enum ABIDataTypes { UINT8 = "UINT8", UINT16 = "UINT16", UINT32 = "UINT32", UINT64 = "UINT64", UINT128 = "UINT128", UINT256 = "UINT256", BOOL = "BOOL", ADDRESS = "ADDRESS", STRING = "STRING", BYTES32 = "BYTES32", TUPLE = "TUPLE", BYTES = "BYTES", ADDRESS_UINT256_TUPLE = "ADDRESS_UINT256_TUPLE", ARRAY_OF_ADDRESSES = "ARRAY_OF_ADDRESSES", ARRAY_OF_UINT256 = "ARRAY_OF_UINT256", ARRAY_OF_UINT128 = "ARRAY_OF_UINT128", ARRAY_OF_UINT64 = "ARRAY_OF_UINT64", ARRAY_OF_UINT32 = "ARRAY_OF_UINT32", ARRAY_OF_UINT16 = "ARRAY_OF_UINT16", ARRAY_OF_UINT8 = "ARRAY_OF_UINT8", ARRAY_OF_STRING = "ARRAY_OF_STRING", ARRAY_OF_BYTES = "ARRAY_OF_BYTES",} * * * **Key Methods in `ABICoder`**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#key-methods-in-abicoder "Direct link to key-methods-in-abicoder") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. `encodeSelector`**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#1-encodeselector "Direct link to 1-encodeselector") Generates a hexadecimal function selector based on the function name. The selector uniquely identifies a contract function. encodeSelector(selectorIdentifier: string): string; #### **Example:**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#example "Direct link to example") import { ABICoder } from "@btc-vision/transaction";const abiCoder = new ABICoder();const selector = abiCoder.encodeSelector("mint()");console.log("Hex Selector:", selector); // Outputs the hex representation of the mint function selector * * * ### **2\. `numericSelectorToHex`**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#2-numericselectortohex "Direct link to 2-numericselectortohex") Converts a numeric selector into a hexadecimal representation. numericSelectorToHex(selector: number): string; #### **Example:**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#example-1 "Direct link to example-1") const numericSelector = 12345;const hexSelector = abiCoder.numericSelectorToHex(numericSelector);console.log("Hexadecimal Selector:", hexSelector); * * * ### **3\. `decodeData`**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#3-decodedata "Direct link to 3-decodedata") Decodes data returned from a contract based on specified ABI types. decodeData(data: Uint8Array, types: ABIDataTypes[]): unknown[]; #### **Example:**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#example-2 "Direct link to example-2") const returnedData = new Uint8Array([...]); // Replace with actual dataconst decoded = abiCoder.decodeData(returnedData, [ABIDataTypes.UINT256, ABIDataTypes.ADDRESS]);console.log("Decoded Data:", decoded); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#best-practices "Direct link to best-practices") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure the data types used in encoding and decoding match the contract's ABI definitions. * Store frequently used selectors (e.g., `mint`, `transfer`) in constants for consistency and reduced overhead. * Always simulate transactions to verify the correctness of your decoding logic before deploying to mainnet. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#whats-next "Direct link to whats-next") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Learn how to create custom calldata for OP\_NET contracts and optimize interactions: * [Creating Custom Calldata with BinaryWriter](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/creating-custom-calldata-with-binarywriter) * [Simulating a Transaction with a Contract Instance](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance) * [**Overview of the `ABICoder` Class**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#overview-of-the-abicoder-class) * [**Supported Data Types**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#supported-data-types) * [**Key Methods in `ABICoder`**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#key-methods-in-abicoder) * [**1\. `encodeSelector`**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#1-encodeselector) * [**2\. `numericSelectorToHex`**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#2-numericselectortohex) * [**3\. `decodeData`**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#3-decodedata) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-a-contract/advanced-contract-interactions/using-abicoder#whats-next) --- # HTTP Provider | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider#__docusaurus_skipToContent_fallback) On this page The HTTP provider is a core component of the OP\_NET metaprotocol. It allows applications to interact with OP\_NET nodes over standard HTTP connections, enabling features such as fetching blockchain data, sending transactions, and querying smart contracts. This guide focuses on setting up the `JSONRpcProvider` as an HTTP provider for OP\_NET. What is a provider? A provider facilitates communication between your application and an OP\_NET node. It handles: * Reading blockchain data (e.g., blocks, transactions, and contracts). * Writing data to the blockchain, such as broadcasting transactions. * Querying smart contracts deployed on the OP\_NET metaprotocol. * * * **The JSONRpcProvider**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider#the-jsonrpcprovider "Direct link to the-jsonrpcprovider") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ The `JSONRpcProvider`, part of the [opnet](https://github.com/btc-vision/opnet) package, is the class responsible for establishing connections with OP\_NET nodes. It inherits from the `AbstractRpcProvider` class and provides methods to send JSON-RPC requests to the node. ### **Constructor**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider#constructor "Direct link to constructor") export declare class JSONRpcProvider extends AbstractRpcProvider { constructor(url: string, network: Network, timeout?: number);} * **`url: string`**: The URL of the OP\_NET node. List of active nodes can be found in the [Networks](https://docs.opnet.org/learn/networks#overview-of-networks) guide. * **`network: Network`**: Network configuration provided by the `@btc-vision/bitcoin` package. * **`timeout?: number`**: Optional timeout for RPC calls in milliseconds. * * * **Setting Up an HTTP Provider**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider#setting-up-an-http-provider "Direct link to setting-up-an-http-provider") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ import { JSONRpcProvider } from "opnet";import { networks } from "@btc-vision/bitcoin";// Define the RPC endpoint and networkconst url = "https://regtest.opnet.org";const network = networks.regtest;// Initialize the providerconst provider = new JSONRpcProvider(url, network);// Optional: Set a custom timeout (in milliseconds)const timeout = 10000; // 10 secondsconst customProvider = new JSONRpcProvider(url, network, timeout); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * **Network Configuration**: Always ensure that the `network` parameter matches the node's configuration to avoid mismatches. * **Error Handling**: Implement robust error handling for failed requests and timeouts. * **Active Node Selection**: Use active nodes from the [supported networks table](https://docs.opnet.org/learn/networks#overview-of-networks) . * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider#whats-next "Direct link to whats-next") ----------------------------------------------------------------------------------------------------------------------------------------------------------------- After setting up an HTTP provider, you can proceed to: * [WebSocket Provider](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/websocket-provider) * [Using a Provider](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/get-current-block-number) * [**The JSONRpcProvider**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider#the-jsonrpcprovider) * [**Constructor**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider#constructor) * [**Setting Up an HTTP Provider**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider#setting-up-an-http-provider) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/setting-up-a-provider/http-provider#whats-next) --- # Instantiating a Contract | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#__docusaurus_skipToContent_fallback) On this page The `getContract` function is your gateway to creating and interacting with contract instances on OP\_NET. By utilizing this function, you ensure that your contract instance is correctly typed and capable of interacting seamlessly with its ABI-defined methods. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#method "Direct link to method") ------------------------------------------------------------------------------------------------------------------------------------- getContract( address: string | Address, abi: BitcoinInterface | BitcoinInterfaceAbi, provider: AbstractRpcProvider, network: Network, sender?: Address): BaseContract & Omit>; * **Parameters**: * **`address: string | Address`**: The address of the contract to instantiate. * **`abi: BitcoinInterface | BitcoinInterfaceAbi`**: The ABI of the contract. * **`provider: AbstractRpcProvider`**: The provider instance connected to OP\_NET. * **`network: Network`**: The target network for the contract. * **`sender?: Address`**: _(Optional)_ The sender address for contract interactions. * **Returns**: * **`BaseContract`**: The contract instance with all methods, events, and properties defined in the ABI. * **`Omit>`**: The contract interface without the methods and events inherited from the base contract. * * * **Example of Instantiating a Contract**[​](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#example-of-instantiating-a-contract "Direct link to example-of-instantiating-a-contract") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### Instantiating with a String Address[​](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#instantiating-with-a-string-address "Direct link to Instantiating with a String Address") import { getContract, IOP_20Contract, OP_20_ABI } from "opnet";import { networks } from "@btc-vision/bitcoin";const op20Contract = getContract( "opr1exampleaddress", // Contract address as a string OP_20_ABI, // OP_20 token contract ABI provider, // JSONRpcProvider connected to OP_NET networks.regtest // Target network // Optional: Add the sender's address // Address.fromString("your-public-key")); ### Instantiating with an `Address` Object[​](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#instantiating-with-an-address-object "Direct link to instantiating-with-an-address-object") const op20Contract = getContract( contractAddressObject, // Address object resolved via getPublicKeyInfo or other methods OP_20_ABI, provider, networks.regtest // Optional: Add the sender's address // Address.fromString("your-public-key")); In both cases, the returned instance allows you to interact with the OP\_20 token contract, using methods defined in its ABI (e.g., `balanceOf`, `transfer`). * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#best-practices "Direct link to best-practices") ------------------------------------------------------------------------------------------------------------------------------------------------------------- * Specify the expected contract interface (e.g., `IOP_20Contract`) to enable full IntelliSense support and reduce runtime errors. * Create and reuse a single instance of your `JSONRpcProvider` for consistent connectivity and improved performance. * Set the `sender` parameter explicitly if your contract interactions require it, otherwise, leave it unset for general use. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#whats-next "Direct link to whats-next") --------------------------------------------------------------------------------------------------------------------------------------------------- Now that you understand the basics, explore the following topics to dive deeper into contract interactions: * [Simulating a Transaction with a Contract Instance](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance) * [**Method**](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#method) * [**Example of Instantiating a Contract**](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#example-of-instantiating-a-contract) * [Instantiating with a String Address](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#instantiating-with-a-string-address) * [Instantiating with an `Address` Object](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#instantiating-with-an-address-object) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract#whats-next) --- # Getting a Contract ABI | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#__docusaurus_skipToContent_fallback) On this page The ABI (Application Binary Interface) defines the methods and events of a smart contract, serving as a blueprint for interacting with it. On OP\_NET, creating a JSON ABI is straightforward and allows you to define the structure of your contract's functions, properties, and events. * * * ### **Creating a Contract JSON ABI**[​](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#creating-a-contract-json-abi "Direct link to creating-a-contract-json-abi") To create a contract ABI, you need to define the functions and events using the appropriate types from the OP\_NET library. Below is a breakdown of how to create a JSON ABI for an OP\_20 token contract. * * * ### **Example: OP\_20 ABI Definition**[​](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#example-op_20-abi-definition "Direct link to example-op_20-abi-definition") #### **Dependencies**[​](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#dependencies "Direct link to dependencies") Ensure you import the necessary types and helpers for defining your ABI: import { ABIDataTypes } from "@btc-vision/transaction";import { BitcoinAbiTypes, BitcoinInterfaceAbi, OP_NET_ABI } from "opnet"; #### **Event Definitions**[​](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#event-definitions "Direct link to event-definitions") Define the contract's events. For OP\_20, these include events such as `Mint`, `Transfer`, and `Approve`: export const OP20Events: BitcoinInterfaceAbi = [ { name: "Mint", values: [ { name: "to", type: ABIDataTypes.ADDRESS }, { name: "amount", type: ABIDataTypes.UINT256 }, ], type: BitcoinAbiTypes.Event, }, { name: "Transfer", values: [ { name: "from", type: ABIDataTypes.ADDRESS }, { name: "to", type: ABIDataTypes.ADDRESS }, { name: "amount", type: ABIDataTypes.UINT256 }, ], type: BitcoinAbiTypes.Event, }, { name: "Approve", values: [ { name: "owner", type: ABIDataTypes.ADDRESS }, { name: "spender", type: ABIDataTypes.ADDRESS }, { name: "value", type: ABIDataTypes.UINT256 }, ], type: BitcoinAbiTypes.Event, },]; #### **Function Definitions**[​](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#function-definitions "Direct link to function-definitions") Functions are the primary way to interact with a contract. Each function includes: * **Inputs:** Parameters passed to the function. * **Outputs:** Return values from the function. For example, defining the `balanceOf` function: export const OP_20_ABI: BitcoinInterfaceAbi = [ { name: "balanceOf", inputs: [{ name: "account", type: ABIDataTypes.ADDRESS }], outputs: [{ name: "balance", type: ABIDataTypes.UINT256 }], type: BitcoinAbiTypes.Function, },]; #### **Combining Events and Functions**[​](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#combining-events-and-functions "Direct link to combining-events-and-functions") Combine events, functions, and any additional properties to create the complete ABI: export const OP_20_ABI: BitcoinInterfaceAbi = [ // Functions { name: "transfer", inputs: [ { name: "recipient", type: ABIDataTypes.ADDRESS }, { name: "amount", type: ABIDataTypes.UINT256 }, ], outputs: [{ name: "success", type: ABIDataTypes.BOOL }], type: BitcoinAbiTypes.Function, }, { name: "approve", inputs: [ { name: "spender", type: ABIDataTypes.ADDRESS }, { name: "amount", type: ABIDataTypes.UINT256 }, ], outputs: [{ name: "success", type: ABIDataTypes.BOOL }], type: BitcoinAbiTypes.Function, }, // Properties { name: "totalSupply", outputs: [{ name: "totalSupply", type: ABIDataTypes.UINT256 }], type: BitcoinAbiTypes.Function, }, // Events ...OP20Events, // OP_NET Specific ...OP_NET_ABI,]; * * * ABI Components Overview * **Functions** Define contract methods with inputs and outputs, specifying their data types (`ABIDataTypes`). * **Events** Include event definitions for tracking on-chain interactions. * **Properties** Add constant values or properties that can be queried from the contract. * **OP\_NET-Specific Extensions** Extend with OP\_NET-specific functionality by importing `OP_NET_ABI`. * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#best-practices "Direct link to best-practices") ----------------------------------------------------------------------------------------------------------------------------------------------------------- * Use `ABIDataTypes` for parameter and return types. * Modularize event and function definitions for easy maintenance. * Test the ABI against a deployed contract to ensure correctness. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#whats-next "Direct link to whats-next") ------------------------------------------------------------------------------------------------------------------------------------------------- Now that you understand the basics, explore the following topics to dive deeper into contract interactions: * [Instantiating a Contract](https://docs.opnet.org/developers/interacting-with-a-contract/instantiating-a-contract) * [**Creating a Contract JSON ABI**](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#creating-a-contract-json-abi) * [**Example: OP\_20 ABI Definition**](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#example-op_20-abi-definition) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi#whats-next) --- # Cross-Chain Mining | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/mineable-utxos/cross-chain-mining#__docusaurus_skipToContent_fallback) On this page Cross-chain mining expands the potential of [Mineable UTXOs](https://docs.opnet.org/developers/mineable-utxos/introduction) by enabling cryptographic collision challenges across multiple blockchains. This concept not only increases security but also creates opportunities for miners to claim rewards from several chains simultaneously. Key Benefits of Cross-Chain Mining * **Unified Incentives:** Align miner rewards and participation across different networks. * **Increased Mining Rewards:** Maximize profits by solving challenges on multiple chains. * **Enhanced Security:** Each solved challenge acts as a checkpoint, reinforcing the network's robustness. * * * **Overview**[​](https://docs.opnet.org/developers/mineable-utxos/cross-chain-mining#overview "Direct link to overview") ------------------------------------------------------------------------------------------------------------------------ Cross-chain mining involves setting up identical SHA-1 collision challenges on different blockchains. Miners or users who solve the collision on one chain can often use the same challenges to claim rewards on other chains, provided the challenge scripts and reward structures align. Key Objectives * Unifying miner incentives across chains. * Efficiently utilizing mining resources. * Building an interconnected blockchain ecosystem where rewards span multiple networks. * * * **Example Workflow**[​](https://docs.opnet.org/developers/mineable-utxos/cross-chain-mining#example-workflow "Direct link to example-workflow") ------------------------------------------------------------------------------------------------------------------------------------------------ 1. **Setup:** Deploy a SHA-1 collision challenge on Bitcoin, Litecoin, and Dogecoin networks. 2. **Mining:** Miners solve the challenge by finding a solution that collides with challenge1 to produce the same SHA-1 hash. 3. **Reward Claim:** The miner submits the challenges to each chain, claiming rewards from all. 4. **Propagation:** The solution can be verified across chains, ensuring no double-spending or inconsistencies. Implementation Considerations * **Standardized Challenge Scripts:** Ensure the locking and unlocking scripts are identical across chains to avoid compatibility issues. * **Cross-Chain Aggregators:** Use aggregators to monitor challenges and solutions across chains, simplifying miner participation. * **Fee Structures:** Adjust fee distributions to incentivize cross-chain miners while maintaining fairness. * * * **What’s Next?**[​](https://docs.opnet.org/developers/mineable-utxos/cross-chain-mining#whats-next "Direct link to whats-next") -------------------------------------------------------------------------------------------------------------------------------- Learn more about how to implement and optimize cross-chain mining for your network: * [Mineable UTXOs Overview](https://docs.opnet.org/developers/mineable-utxos/introduction) * [SHA-1 Collision Challenge](https://docs.opnet.org/developers/mineable-utxos/sha1-collision-challenge) * [Full Documentation](https://github.com/btc-vision/opnet-node/blob/features/contract-utxos/docs/in-progress/MineableUTXOs.md) * [**Overview**](https://docs.opnet.org/developers/mineable-utxos/cross-chain-mining#overview) * [**Example Workflow**](https://docs.opnet.org/developers/mineable-utxos/cross-chain-mining#example-workflow) * [**What’s Next?**](https://docs.opnet.org/developers/mineable-utxos/cross-chain-mining#whats-next) --- # SHA-1 Collision Challenge | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/mineable-utxos/sha1-collision-challenge#__docusaurus_skipToContent_fallback) On this page The SHA-1 Collision Challenge is a core component of [Mineable UTXOs](https://docs.opnet.org/developers/mineable-utxos/introduction) on OP\_NET. It provides a unique mechanism for miners to claim rewards by solving cryptographic puzzles, contributing to both the security and utility of the network. * * * **Understanding the Collision Challenge**[​](https://docs.opnet.org/developers/mineable-utxos/sha1-collision-challenge#understanding-the-collision-challenge "Direct link to understanding-the-collision-challenge") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The challenge requires miners to find a solution that collides with a given challenge (challenge1) to produce the same SHA-1 hash. This solution, once found, allows the spender to unlock the associated UTXO funds. Conditions for success `SHA1(solution) == SHA1(challenge1)` This mechanism transforms OP\_NET into a dual-purpose platform, merging traditional transaction validation with cryptographic mining. * * * **Bitcoin Script Example**[​](https://docs.opnet.org/developers/mineable-utxos/sha1-collision-challenge#bitcoin-script-example "Direct link to bitcoin-script-example") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Below is a simplified Bitcoin script enforcing a SHA-1 collision challenge. OP_2DUP # Duplicate top two items (challenge1, challenge2)OP_EQUAL # Compare them. Push 1 if equal, else 0OP_NOT # Ensure they are distinctOP_VERIFY # Fail if not distinctOP_SHA1 # Replace top stack item with SHA-1(challenge1)OP_SWAP # Swap top two stack itemsOP_SHA1 # Replace new top stack item with SHA-1(challenge2)OP_EQUAL # Ensure both hashes are identical **P2SH Redeem Script Example:** OP_HASH160 OP_EQUAL Redeem Script Details The spender must reveal: 1. The solution that collides with challenge1 2. The redeem script itself * * * **Solving the Collision Challenge**[​](https://docs.opnet.org/developers/mineable-utxos/sha1-collision-challenge#solving-the-collision-challenge "Direct link to solving-the-collision-challenge") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Here’s a step-by-step guide to solving the challenge and claiming rewards: // Step 1: Prepare the solution (hash collision)const solution = Buffer.from( "abe4bbf04b207bffce16000fd1c3a21c019cdfbea51f86cef4789b848c0a7d5cedd3151f262c964e323c73ef2d31bee518252acec5b895543eeabc8c4059b393a582d7be38dac8b70bb437e6c01d1b4e8c61d2ba2a5b8ed3e3c0a9cf2683b78b3a479de9866e44adf5425976579483b3b4f325847ceabe4f5e18d2ad8e568c58", "hex");// Step 2: Initialize the transaction factoryconst txFactory = new TransactionFactory();// Step 3: Generate the redeem script for the mineable rewardconst redeemScript = ChallengeGenerator.generateMineableReward( challenge1, network);// Step 4: Fetch UTXOs (unspent transaction outputs) for the specified amountconst utxos = await provider.utxoManager.getUTXOsForAmount({ address: redeemScript.address, // Address derived from the redeem script amount: 100000000n, // Required amount in satoshis optimize: false, // Disable optimization to fetch raw UTXOs});// Step 5: Prepare the last UTXO for the transactionconst lastUTXO = utxos[utxos.length - 1] as UTXO; // Select the last UTXOlastUTXO.redeemScript = redeemScript.p2shOutputScript; // Attach the redeem script// Step 6: Define transaction parameters for solving the challengeconst challengeSolutionParams: IChallengeSolutionTransactionParameters = { challengeSolution: solution, // Provide the collision solution from: redeemScript.address, // Address funding the transaction utxos: [lastUTXO], // UTXOs to be used amount: BigInt(minDust), // Minimum dust amount to send to: address.p2tr(network), // Destination address (Pay-to-Taproot in this case) feeRate: gasParameters.bitcoin.recommended.medium, // Fee rate for the transaction priorityFee: 0n, // Additional priority fee (none in this example) network: network, // Current network configuration signer: wallet.keypair, // Signer for the transaction};// Step 7: Create the transaction to solve the challengeconst fundingTransaction = await txFactory.createChallengeSolution( challengeSolutionParams);// Step 8: Broadcast the transaction to the networkconst result = await Configs.RPC.sendRawTransaction({ hexstring: fundingTransaction.tx, // Serialized transaction in hex format}); * * * **What’s Next?**[​](https://docs.opnet.org/developers/mineable-utxos/sha1-collision-challenge#whats-next "Direct link to whats-next") -------------------------------------------------------------------------------------------------------------------------------------- Learn more about how to implement and optimize cross-chain mining for your network: * [Mineable UTXOs Overview](https://docs.opnet.org/developers/mineable-utxos/introduction) * [Cross-Chain Mining](https://docs.opnet.org/developers/mineable-utxos/cross-chain-mining) * [Full Documentation](https://github.com/btc-vision/opnet-node/blob/features/contract-utxos/docs/in-progress/MineableUTXOs.md) * [**Understanding the Collision Challenge**](https://docs.opnet.org/developers/mineable-utxos/sha1-collision-challenge#understanding-the-collision-challenge) * [**Bitcoin Script Example**](https://docs.opnet.org/developers/mineable-utxos/sha1-collision-challenge#bitcoin-script-example) * [**Solving the Collision Challenge**](https://docs.opnet.org/developers/mineable-utxos/sha1-collision-challenge#solving-the-collision-challenge) * [**What’s Next?**](https://docs.opnet.org/developers/mineable-utxos/sha1-collision-challenge#whats-next) --- # Deploying a Contract | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#__docusaurus_skipToContent_fallback) On this page Deploying a smart contract on OP\_NET requires careful handling of UTXOs and constructing deployment parameters. This guide explains the process of using `TransactionFactory` to sign and deploy contracts. Full Example Is In Node.js Environment If you're in a browser environment, please refer to [WalletConnect Documentation](https://docs.opnet.org/developers/walletconnect/introduction) for information on deploying contracts. * * * **Steps to Deploy a Contract**[​](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#steps-to-deploy-a-contract "Direct link to steps-to-deploy-a-contract") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. Obtaining Proper UTXOs**[​](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#1-obtaining-proper-utxos "Direct link to 1-obtaining-proper-utxos") Before building a transaction, you need to gather the required UTXOs for funding. Use the `utxoManager` from the `JSONRpcProvider` to fetch UTXOs associated with your address. const utxos = await provider.utxoManager.getUTXOs({ address: wallet.p2tr,}); UTXO Management Ensure you have enough UTXOs to cover the transaction inputs, gas fees, and any additional outputs. Learn more about [**UTXO Manager**](https://docs.opnet.org/developers/using-the-utxo-manager/introduction) . ### **2\. Fetching Contract Bytecode**[​](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#2-fetching-contract-bytecode "Direct link to 2-fetching-contract-bytecode") Retrieve the contract bytecode (compiled contract code) to be deployed. You can read the bytecode from a compiled `.wasm` file or use the hex string directly. const bytecode = fs.readFileSync("your-contract.wasm");// Or you can use the hex string directly:// const bytecode = Buffer.from("your-contract-bytecode", "hex"); ### **3\. Constructing Deployment Parameters**[​](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#3-constructing-deployment-parameters "Direct link to 3-constructing-deployment-parameters") The `IDeploymentParameters` interface defines the required parameters for contract deployment. Ensure you provide the signer, network, contract bytecode, and other necessary details. const gasParameters = await provider.gasParameters();const challenge = await provider.getChallenge();const deploymentParameters: IDeploymentParameters = { signer: wallet.keypair, network: networks.regtest, from: wallet.p2tr, utxos, bytecode, challenge, feeRate: gasParameters.bitcoin.recommended.medium, priorityFee: 0n,}; ### **4\. Signing the Deployment Transaction**[​](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#4-signing-the-deployment-transaction "Direct link to 4-signing-the-deployment-transaction") Use the `signDeployment` method from `TransactionFactory` to sign the deployment transaction. This method returns a `DeploymentResult` object containing the signed transaction and contract details. const transactionFactory = new TransactionFactory();const deploymentResult = await transactionFactory.signDeployment( deploymentParameters); ### **5\. Broadcasting the Transaction**[​](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#5-broadcasting-the-transaction "Direct link to 5-broadcasting-the-transaction") After signing the transaction, broadcast it to the network using the `sendRawTransactions` method from the provider. const tx = await provider.sendRawTransactions(deploymentResult.transaction);if (!tx[1].success) { throw new Error(`Transaction failed: ${tx[1].error}`);}// Deployment resultconsole.log("Transaction ID:", tx[1].result);console.log("Contract Pubkey:", deploymentResult.contractPubKey);console.log("P2OP Address:", deploymentResult.contractAddress); * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#object-definitions "Direct link to object-definitions") --------------------------------------------------------------------------------------------------------------------------------------------------------------------- `DeploymentResult` Object | **Property** | **Type** | **Description** | | --- | --- | --- | | **`transaction`** | `string` | Array of raw transaction strings. | | **`contractAddress`** | `string` | Contract's P2OP address. | | **`contractPubKey`** | `string` | Contract's tweaked public key. | | **`p2opAddress`** | `string` | Contract's P2OP address. | | **`utxos`** | `UTXO[]` | Array of new UTXOs after deployment. | * * * **Full Example**[​](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#full-example "Direct link to full-example") --------------------------------------------------------------------------------------------------------------------------------------------------- import { networks } from "@btc-vision/bitcoin";import { IDeploymentParameters, TransactionFactory, Wallet,} from "@btc-vision/transaction";import fs from "fs";import { JSONRpcProvider } from "opnet";// Initialize provider and walletconst provider = new JSONRpcProvider( "https://regtest.opnet.org", networks.regtest);const wallet = Wallet.fromWif("your-private-key", networks.regtest);// Fetch UTXOs for funding the deploymentconst utxos = await provider.utxoManager.getUTXOs({ address: wallet.p2tr,});// Contract bytecode (compiled contract code)// You can get it from your wasm file, for example:const bytecode = fs.readFileSync("your-contract.wasm");// Or you can use the hex string directly:// const bytecode = Buffer.from("your-contract-bytecode", "hex");// Define deployment parametersconst gasParameters = await provider.gasParameters();const challenge = await provider.getChallenge();const deploymentParameters: IDeploymentParameters = { signer: wallet.keypair, network: networks.regtest, from: wallet.p2tr, utxos, bytecode, challenge, feeRate: gasParameters.bitcoin.recommended.medium, priorityFee: 0n,};// Create and sign the deployment transactionconst transactionFactory = new TransactionFactory();const deploymentResult = await transactionFactory.signDeployment( deploymentParameters);// Broadcast the transactionconst tx = await provider.sendRawTransactions(deploymentResult.transaction);if (!tx[1].success) { throw new Error(`Transaction failed: ${tx[1].error}`);}// Deployment resultconsole.log("Transaction ID:", tx[1].result);console.log("Contract Pubkey:", deploymentResult.contractPubKey);console.log("P2OP Address:", deploymentResult.contractAddress); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure your wallet has sufficient UTXOs to fund the deployment and associated fees. * Adjust the `feeRate` and `priorityFee` parameters based on current network conditions to minimize costs. * Before deploying on mainnet, test your contract deployment process on regtest or testnet to avoid unnecessary costs. * [**Steps to Deploy a Contract**](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#steps-to-deploy-a-contract) * [**1\. Obtaining Proper UTXOs**](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#1-obtaining-proper-utxos) * [**2\. Fetching Contract Bytecode**](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#2-fetching-contract-bytecode) * [**3\. Constructing Deployment Parameters**](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#3-constructing-deployment-parameters) * [**4\. Signing the Deployment Transaction**](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#4-signing-the-deployment-transaction) * [**5\. Broadcasting the Transaction**](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#5-broadcasting-the-transaction) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#object-definitions) * [**Full Example**](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#full-example) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-a-contract/deploying-a-contract#best-practices) --- # Introduction to Mineable UTXOs | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/mineable-utxos/introduction#__docusaurus_skipToContent_fallback) On this page The concept of **Mineable UTXOs** introduces a novel approach to incentivizing miners and enhancing the security of the OP\_NET ecosystem. By embedding cryptographic collision challenges within Bitcoin UTXOs, we create a unique mechanism for miners to claim rewards while improving the network's robustness. Key Benefits of Mineable UTXOs * **Enhanced Miner Rewards:** Miners can claim transaction fees by solving cryptographic challenges, increasing their earnings. * **Improved Security for OP\_NET:** Each solved challenge acts as a checkpoint, reinforcing the integrity of the OP\_NET ecosystem. * **Cross-Chain Possibilities:** The mechanism can extend across multiple blockchains, enabling shared incentives and rewards. * * * **What are Mineable UTXOs?**[​](https://docs.opnet.org/developers/mineable-utxos/introduction#what-are-mineable-utxos "Direct link to what-are-mineable-utxos") ---------------------------------------------------------------------------------------------------------------------------------------------------------------- Mineable UTXOs are specialized unspent transaction outputs (UTXOs) that contain cryptographic challenges, such as finding a SHA-1 collision. Solving these challenges enables miners to claim funds locked within the UTXO. This innovative approach ensures that: * **Fees are recycled back into the ecosystem** rather than being burned. * **Miners are incentivized** to solve cryptographic puzzles, acting as additional checkpoints for OP\_NET security. * **Cross-chain mining opportunities** become possible, allowing for shared incentives across multiple blockchain networks. * * * **How It Works**[​](https://docs.opnet.org/developers/mineable-utxos/introduction#how-it-works "Direct link to how-it-works") ------------------------------------------------------------------------------------------------------------------------------ 1. **Challenge Creation** A UTXO is created with a locking script that defines a collision challenge. Miners must provide a solution that collides with `challenge1` to produce the same SHA-1 hash. 2. **Reward Claim** Once a miner finds a valid collision, they can spend the UTXO by providing the challenges, claiming the locked funds. 3. **Cross-Chain Integration** The same challenge can exist on multiple chains, allowing miners to claim rewards across networks simultaneously. * * * **What’s Next?**[​](https://docs.opnet.org/developers/mineable-utxos/introduction#whats-next "Direct link to whats-next") -------------------------------------------------------------------------------------------------------------------------- Learn more about how to implement and optimize cross-chain mining for your network: * [SHA-1 Collision Challenge](https://docs.opnet.org/developers/mineable-utxos/sha1-collision-challenge) * [Cross-Chain Mining](https://docs.opnet.org/developers/mineable-utxos/cross-chain-mining) * [Full Documentation](https://github.com/btc-vision/opnet-node/blob/features/contract-utxos/docs/in-progress/MineableUTXOs.md) * [**What are Mineable UTXOs?**](https://docs.opnet.org/developers/mineable-utxos/introduction#what-are-mineable-utxos) * [**How It Works**](https://docs.opnet.org/developers/mineable-utxos/introduction#how-it-works) * [**What’s Next?**](https://docs.opnet.org/developers/mineable-utxos/introduction#whats-next) --- # Sending a Simulated Transaction | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-a-contract/sending-a-simulated-transaction#__docusaurus_skipToContent_fallback) On this page After simulating a transaction and ensuring it behaves as expected, the next step is to send the transaction on the OP\_NET network. This guide explains how to build and send a transaction based on simulation results using the `sendTransaction` method. Only In Node.js Environment The `sendTransaction` method is only available in the Node.js environment. Ensure you have set up your Node.js environment before proceeding. If you're in a browser environment, please refer to [WalletConnect Documentation](https://docs.opnet.org/developers/walletconnect/introduction) for information on sending transactions. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-a-contract/sending-a-simulated-transaction#method "Direct link to method") -------------------------------------------------------------------------------------------------------------------------------------------- sendTransaction(interactionParams: TransactionParameters): Promise; * **Parameters**: * **`interactionParams: TransactionParameters`**: The parameters required to send the transaction. * **Returns**: * **`Promise`**: An object containing details about the submitted transaction. * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-a-contract/sending-a-simulated-transaction#object-definitions "Direct link to object-definitions") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `TransactionParameters` Object | **Field** | **Type** | **Description** | | --- | --- | --- | | **`signer`** | `Signer \| ECPairInterface` | Signer to authorize the transaction. | | **`refundTo`** | `string` | Address to refund unused satoshis. | | **`priorityFee`** | `bigint` | _(Optional)_ Fee for prioritizing the transaction. | | **`feeRate`** | `number` | _(Optional)_ Fee rate in satoshis per byte. | | **`utxos`** | `UTXO[]` | _(Optional)_ UTXOs to fund the transaction. | | **`maximumAllowedSatToSpend`** | `bigint` | Max satoshis allowed to spend. | | **`network`** | `Network` | The Bitcoin network (e.g., regtest, mainnet). | `InteractionTransactionReceipt` Object | **Field** | **Type** | **Description** | | --- | --- | --- | | **`transactionId`** | `string` | The ID of the transaction on the network. | | **`newUTXOs`** | `UTXO[]` | Newly created UTXOs from the transaction. | | **`peerAcknowledgements`** | `number` | Number of peers that acknowledged the transaction. | * * * **Sending the Transaction**[​](https://docs.opnet.org/developers/interacting-with-a-contract/sending-a-simulated-transaction#sending-the-transaction "Direct link to sending-the-transaction") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Once you have the simulation result, you can call the `sendTransaction` method directly on the simulation object. Here’s a conceptual explanation: 1. **Simulate the Transaction**: Obtain the simulation result from a contract interaction. For example: const result = await op20Contract.approve(addressPublicKey, 1000n); // Simulate an `approve` transaction 2. **Signer Setup**: Use the `Wallet.fromWif` for example, to create a signer object: const wallet = Wallet.fromWif("your-wif-key", networks.regtest); // Replace with your actual WIFconst signer = wallet.keypair; 3. **Call `sendTransaction`**: Using the simulation object, pass the necessary parameters to `sendTransaction`: const receipt = await result.sendTransaction({ signer: signer, refundTo: "bcrt1...address", // Replace with your refund address maximumAllowedSatToSpend: 100_000n, // Maximum satoshis to spend network: networks.regtest, // Network configuration}); * [**Method**](https://docs.opnet.org/developers/interacting-with-a-contract/sending-a-simulated-transaction#method) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-a-contract/sending-a-simulated-transaction#object-definitions) * [**Sending the Transaction**](https://docs.opnet.org/developers/interacting-with-a-contract/sending-a-simulated-transaction#sending-the-transaction) --- # Simulating a Transaction | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#__docusaurus_skipToContent_fallback) On this page Simulating transactions on OP\_NET helps predict the outcome of smart contract interactions without broadcasting them to the network. This crucial step ensures accuracy in returned values, gas estimation, and transaction behavior, enabling developers to debug effectively and avoid unnecessary failures. * * * **Using Simulation and Accessing Returned Values**[​](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#using-simulation-and-accessing-returned-values "Direct link to using-simulation-and-accessing-returned-values") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- When you simulate a transaction, the result contains detailed information, including returned values, gas requirements, and metadata. This data is essential for validating the interaction before executing it. ### **Accessing Returned Values**[​](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#accessing-returned-values "Direct link to accessing-returned-values") The simulation result includes a `properties` object that maps the contract's returned values based on its ABI. You can access these values directly using their defined names. #### Example:[​](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#example "Direct link to Example:") const result = await op20Contract.balanceOf(addressPublicKey);console.log("Balance:", result.properties.balance); * **`properties.balance`**: The balance returned by the `balanceOf` function. * **Mapped to ABI**: The `properties` field ensures that outputs match the contract’s ABI structure, reducing ambiguity. * * * **Gas Calculation**[​](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#gas-calculation "Direct link to gas-calculation") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Estimating gas usage is a core feature of OP\_NET simulations. Simulations provide a field called `estimatedGas` that represents the amount of gas required for a transaction. ### **Adding a Buffer**[​](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#adding-a-buffer "Direct link to adding-a-buffer") Gas requirements may fluctuate due to network conditions. It’s recommended to add a **15% buffer** to the `estimatedGas` value to ensure transaction success. #### Example:[​](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#example-1 "Direct link to Example:") const estimatedGasWithBuffer = result.estimatedGas * 1.15n;console.log("Estimated Gas with Buffer:", estimatedGasWithBuffer); * * * **Simulation Example**[​](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#simulation-example "Direct link to simulation-example") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Below is an example of a simulation result for the `balanceOf` method: { "result": { "currentOffset": 32, "buffer": { "byteLength": 32, "byteOffset": 0, "buffer": [ArrayBuffer] } }, "accessList": {}, "revert": undefined, "calldata": "", "estimatedGas": 120566118n, "properties": { "balance": 866000n }, "estimatedSatGas": 330n, "events": [], "to": "opr1exampleaddress"} ### Key Fields[​](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#key-fields "Direct link to Key Fields") * **`properties`**: The returned values, such as `balance` in this example. * **`estimatedGas`**: The estimated gas needed for the transaction. * **`calldata`**: Encoded transaction data sent to the contract. * **`estimatedSatGas`**: The cost of gas in satoshis. * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#best-practices "Direct link to best-practices") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Simulating allows you to verify the transaction's behavior and ensures accurate gas estimation, minimizing risks. * Use the `properties` object to directly read data returned by the contract, as defined in its ABI. * Include a 15% buffer to the `estimatedGas` value to account for unexpected fluctuations. * The `sendTransaction` method simplifies gas estimation and broadcasting. It’s a reliable option for production transactions. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#whats-next "Direct link to whats-next") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Once you've simulated and verified your transaction, the next step is sending it to the network. Learn how to build and send transactions in the next section: * [Sending a Simulated Transaction](https://docs.opnet.org/developers/interacting-with-a-contract/sending-a-simulated-transaction) * [**Using Simulation and Accessing Returned Values**](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#using-simulation-and-accessing-returned-values) * [**Accessing Returned Values**](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#accessing-returned-values) * [**Gas Calculation**](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#gas-calculation) * [**Adding a Buffer**](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#adding-a-buffer) * [**Simulation Example**](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#simulation-example) * [Key Fields](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#key-fields) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance#whats-next) --- # Nodes | OP_NET Docs [Skip to main content](https://docs.opnet.org/learn/opnet-nodes#__docusaurus_skipToContent_fallback) On this page Introduction[​](https://docs.opnet.org/learn/opnet-nodes#introduction "Direct link to Introduction") ----------------------------------------------------------------------------------------------------- OP\_NET Nodes are full‐featured Bitcoin clients extended to run OP\_NET smart contracts, manage token state, and power decentralized applications—without changing Bitcoin’s core rules. By combining Bitcoin Core’s UTXO handling with a lightweight WebAssembly runtime, OP\_NET Nodes: * **Validate Bitcoin transactions** exactly as before, ensuring full compatibility with Bitcoin Core and other nodes. * **Execute Wasm contracts off‐chain**, deterministically applying state changes before anchoring results in standard Bitcoin transactions. * **Index token balances and contract data**, letting wallets and dApps query your account or contract state in real time. Storage Requirements **Archive mode only:** A production‐ready OP\_NET Node must keep every historical UTXO and contract state. Plan for **at least 5 TB of fast SSD space** to store Bitcoin’s full archive plus OP\_NET data. * * * **Why Run an OP\_NET Node?**[​](https://docs.opnet.org/learn/opnet-nodes#why-run-an-op_net-node "Direct link to why-run-an-op_net-node") ----------------------------------------------------------------------------------------------------------------------------------------- Running an OP\_NET Node provides several advantages: * **Full Control**: Direct interaction with the OP\_NET environment for deploying contracts and managing UTXOs. * **Enhanced Security**: Use your node to validate transactions and ensure trustless interactions. * **Decentralization**: Contribute to OP\_NET's distributed ecosystem. * **Development Environment**: Test and debug smart contracts locally before deploying to mainnet. * * * **Types of OP\_NET Nodes**[​](https://docs.opnet.org/learn/opnet-nodes#types-of-op_net-nodes "Direct link to types-of-op_net-nodes") ------------------------------------------------------------------------------------------------------------------------------------- 1. **Archive Node**: Stores the entire Bitcoin blockchain and OP\_NET data for full interaction. 2. **Full Node**: Hosts the entire Bitcoin blockchain and processes all OP\_NET interactions. **(Coming Soon)** 3. **Lightweight Node**: Relies on trusted full nodes for blockchain data while focusing on OP\_NET-specific interactions. **(Coming Soon)** Node Selection For development purposes, a lightweight node is usually sufficient. Use a full node for enhanced security and decentralized participation. * * * **Networks Supported**[​](https://docs.opnet.org/learn/opnet-nodes#networks-supported "Direct link to networks-supported") --------------------------------------------------------------------------------------------------------------------------- OP\_NET Nodes support multiple environments: [Full List](https://docs.opnet.org/learn/networks#overview-of-networks) * [Introduction](https://docs.opnet.org/learn/opnet-nodes#introduction) * [**Why Run an OP\_NET Node?**](https://docs.opnet.org/learn/opnet-nodes#why-run-an-op_net-node) * [**Types of OP\_NET Nodes**](https://docs.opnet.org/learn/opnet-nodes#types-of-op_net-nodes) * [**Networks Supported**](https://docs.opnet.org/learn/opnet-nodes#networks-supported) --- # NFTs | OP_NET Docs [Skip to main content](https://docs.opnet.org/learn/nfts-on-opnet#__docusaurus_skipToContent_fallback) On this page **Introduction**[​](https://docs.opnet.org/learn/nfts-on-opnet#introduction "Direct link to introduction") ----------------------------------------------------------------------------------------------------------- Non-Fungible Tokens (NFTs) are unique digital assets that represent ownership or proof of authenticity for items such as art, music, collectibles, and more. On OP\_NET, NFTs are implemented using the **OP\_721 standard**, an equivalent to Ethereum's ERC-721. By leveraging Bitcoin’s robust security and OP\_NET's advanced features, OP\_721 enables the creation and management of NFTs directly on Bitcoin. Use Cases for NFTs on OP\_NET Developers can use OP\_721 tokens for various applications, including digital art platforms, gaming assets, and collectibles. * * * **Why NFTs on OP\_NET?**[​](https://docs.opnet.org/learn/nfts-on-opnet#why-nfts-on-op_net "Direct link to why-nfts-on-op_net") ------------------------------------------------------------------------------------------------------------------------------- Key Advantages of NFTs on OP\_NET * **Bitcoin Security**: NFTs inherit Bitcoin's decentralization and immutability. * **Customizability**: Create unique NFTs with rich metadata. * **Low Transaction Costs**: Pay gas fees in Bitcoin, ensuring cost efficiency. * **Direct Ownership**: NFTs are directly tied to Bitcoin UTXOs, enabling unique provenance. * * * **How NFTs Work on OP\_NET**[​](https://docs.opnet.org/learn/nfts-on-opnet#how-nfts-work-on-op_net "Direct link to how-nfts-work-on-op_net") --------------------------------------------------------------------------------------------------------------------------------------------- NFTs on OP\_NET use the **OP\_721 standard**, which defines how unique tokens are minted, transferred, and interacted with. Key Features of OP\_721 * **Uniqueness**: Each NFT has a unique identifier (token ID). * **Ownership**: Each NFT is tied to a specific owner address. * **Metadata**: NFTs can store metadata (e.g., image links, descriptions) on-chain or off-chain. * **Transferability**: NFTs can be easily transferred between users. * [**Introduction**](https://docs.opnet.org/learn/nfts-on-opnet#introduction) * [**Why NFTs on OP\_NET?**](https://docs.opnet.org/learn/nfts-on-opnet#why-nfts-on-op_net) * [**How NFTs Work on OP\_NET**](https://docs.opnet.org/learn/nfts-on-opnet#how-nfts-work-on-op_net) --- # Networks | OP_NET Docs [Skip to main content](https://docs.opnet.org/learn/networks#__docusaurus_skipToContent_fallback) On this page **Introduction**[​](https://docs.opnet.org/learn/networks#introduction "Direct link to introduction") ------------------------------------------------------------------------------------------------------ OP\_NET operates across multiple network environments, allowing developers to test, deploy, and interact with decentralized applications and smart contracts. Each network serves a specific purpose, ranging from development and testing to production-ready applications. Updates on Regtest All breaking changes and experimental updates are implemented on Regtest without prior announcements. Developers should anticipate frequent changes and adapt their workflows accordingly. * * * **Overview of Networks**[​](https://docs.opnet.org/learn/networks#overview-of-networks "Direct link to overview-of-networks") ------------------------------------------------------------------------------------------------------------------------------ OP\_NET supports the following network environments: | **Network** | **RPC URL** | **Status** | **Purpose** | | --- | --- | --- | --- | | **Mainnet** | `https://api.opnet.org` | Disabled | The primary production environment for live applications and smart contracts. | | **Testnet** | `https://testnet.opnet.org` | Active | A sandbox environment for wider application testing. | | **Regtest** | `https://regtest.opnet.org` | Active | A network designed for local development and testing. | | **Fractal** | `https://fractal.opnet.org` | Active | [Fractal Network](https://www.fractalbitcoin.io/)
. | * * * **Details on Each Network**[​](https://docs.opnet.org/learn/networks#details-on-each-network "Direct link to details-on-each-network") --------------------------------------------------------------------------------------------------------------------------------------- ### **Mainnet**[​](https://docs.opnet.org/learn/networks#mainnet "Direct link to mainnet") The mainnet is OP\_NET's production environment, where real Bitcoin transactions occur. Use this network for: * Deploying finalized smart contracts. * Running production dApps. * Handling real Bitcoin assets. Note Currently, the Mainnet is **disabled** while OP\_NET undergoes further development and optimization. * * * ### **Testnet**[​](https://docs.opnet.org/learn/networks#testnet "Direct link to testnet") The testnet will be a testing environment designed to mirror the mainnet while using test BTC instead of real Bitcoin. It will be ideal for: * Broader testing of applications in a semi-production environment. * Ensuring stability before deployment to the mainnet. tip To obtain test BTC for use on the Testnet network, visit the [Testnet Faucet](https://faucet.opnet.org/) . * * * ### **Regtest**[​](https://docs.opnet.org/learn/networks#regtest "Direct link to regtest") Regtest is your private, local Bitcoin network for development and testing: * **Full Control** You decide when blocks are mined, no waiting for real miners. * **Instant Feedback** Generate or rewind the chain instantly to test contract logic and transactions. * **Safe Sandbox** Use valueless coins and experiment freely without impacting Testnet or Mainnet. * * * ### **Fractal**[​](https://docs.opnet.org/learn/networks#fractal "Direct link to fractal") Read more about the Fractal network and its unique features: [Fractal Network](https://www.fractalbitcoin.io/) . * [**Introduction**](https://docs.opnet.org/learn/networks#introduction) * [**Overview of Networks**](https://docs.opnet.org/learn/networks#overview-of-networks) * [**Details on Each Network**](https://docs.opnet.org/learn/networks#details-on-each-network) * [**Mainnet**](https://docs.opnet.org/learn/networks#mainnet) * [**Testnet**](https://docs.opnet.org/learn/networks#testnet) * [**Regtest**](https://docs.opnet.org/learn/networks#regtest) * [**Fractal**](https://docs.opnet.org/learn/networks#fractal) --- # Native Bitcoin | OP_NET Docs [Skip to main content](https://docs.opnet.org/learn/native-bitcoin#__docusaurus_skipToContent_fallback) On this page **Introduction**[​](https://docs.opnet.org/learn/native-bitcoin#introduction "Direct link to introduction") ------------------------------------------------------------------------------------------------------------ Bitcoin is the world’s most secure digital cash network—but until now, it’s been hard to build apps or tokens on top of it. OP\_NET changes that by plugging directly into Bitcoin’s existing rules and data model. There’s no new blockchain to learn or wrap; you get: * **Smart contracts** that run alongside your BTC. * **Tokens and NFTs** issued in satoshis, not wrapped coins. * **dApps** that read and write Bitcoin’s UTXO ledger without any protocol changes. Under the hood, OP\_NET treats each UTXO as a tiny on-chain “object” and uses WebAssembly to execute code off-chain, then commits the results back into normal Bitcoin transactions. That means you keep all of Bitcoin’s security and decentralization, plus a full suite of modern blockchain features—without leaving Bitcoin. Key Points OP\_NET runs entirely within Bitcoin’s existing protocol and fee system, so your apps stay compatible with Bitcoin Core and benefit from Bitcoin’s battle-tested security. * * * **What Does "Native Bitcoin" Mean?**[​](https://docs.opnet.org/learn/native-bitcoin#what-does-native-bitcoin-mean "Direct link to what-does-native-bitcoin-mean") ------------------------------------------------------------------------------------------------------------------------------------------------------------------ Key Characteristics of Native Bitcoin * **Direct Integration**: OP\_NET operates on Bitcoin’s base layer, using its UTXO model for state management and contract execution. * **No Forks or Modifications**: OP\_NET does not require any changes to Bitcoin’s protocol. * **Gas Fees in Satoshis**: All transaction fees are paid in Bitcoin, ensuring simplicity and consistency for users and developers. * * * **Why Use Bitcoin Natively?**[​](https://docs.opnet.org/learn/native-bitcoin#why-use-bitcoin-natively "Direct link to why-use-bitcoin-natively") ------------------------------------------------------------------------------------------------------------------------------------------------- ### **Rock-Solid Security**[​](https://docs.opnet.org/learn/native-bitcoin#rock-solid-security "Direct link to rock-solid-security") Bitcoin’s proof-of-work consensus is the most battle-tested in crypto. By running OP\_NET atop Bitcoin: * **Immutable Finality**: Every contract and token state is anchored by Bitcoin miners-no separate security assumptions. * **Permissionless Validation**: Anyone can run a full node to independently verify OP\_NET transactions. ### **Unmatched Decentralization**[​](https://docs.opnet.org/learn/native-bitcoin#unmatched-decentralization "Direct link to unmatched-decentralization") Bitcoin’s global network of nodes and miners means: * **Censorship Resistance**: No single party can block or reverse transactions. * **Open Participation**: Developers and users worldwide join without special hardware or approvals. ### **Proven Uptime & Stability**[​](https://docs.opnet.org/learn/native-bitcoin#proven-uptime--stability "Direct link to proven-uptime--stability") With over a decade of continuous operation: * **Network Durability**: Bitcoin has never halted-your dApps inherit this 24/7 availability. * **Mature Tooling**: Leverage existing Bitcoin wallets, explorers, and infrastructure without learning new protocols. * * * **How OP\_NET Leverages Bitcoin**[​](https://docs.opnet.org/learn/native-bitcoin#how-op_net-leverages-bitcoin "Direct link to how-op_net-leverages-bitcoin") ------------------------------------------------------------------------------------------------------------------------------------------------------------- OP\_NET builds directly on Bitcoin’s existing features, no forks or sidechains by using two key mechanisms: ### **1\. Tapscript for Smart Contracts**[​](https://docs.opnet.org/learn/native-bitcoin#1-tapscript-for-smart-contracts "Direct link to 1-tapscript-for-smart-contracts") * **What it is:** Tapscript is Bitcoin’s upgraded scripting language under Taproot. * **Why it matters:** OP\_NET uses Tapscript to run more complex logic (loops, conditionals, function calls) while still fitting within Bitcoin’s lightweight design. * **Bottom line:** You get the flexibility of smart contracts without changing Bitcoin’s core rules. ### **2\. Gas Fees in Satoshis**[​](https://docs.opnet.org/learn/native-bitcoin#2-gas-fees-in-satoshis "Direct link to 2-gas-fees-in-satoshis") * **Fee model:** Every OP\_NET operation costs a small amount of Bitcoin (satoshis) per byte of data processed. * **Base fee:** Covers the work of publishing transactions and any contract execution. * **Priority fee:** You can add extra satoshis to encourage miners to include your transaction sooner. caution Actual fees depend on network congestion. High activity means higher satoshi-per-byte rates for both base and priority fees. * * * **Use Cases Enabled by Native Bitcoin**[​](https://docs.opnet.org/learn/native-bitcoin#use-cases-enabled-by-native-bitcoin "Direct link to use-cases-enabled-by-native-bitcoin") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. Decentralized Applications (dApps)**[​](https://docs.opnet.org/learn/native-bitcoin#1-decentralized-applications-dapps "Direct link to 1-decentralized-applications-dapps") Developers can build dApps that interact directly with Bitcoin’s UTXOs, ensuring security and scalability. ### **2\. Tokenization**[​](https://docs.opnet.org/learn/native-bitcoin#2-tokenization "Direct link to 2-tokenization") OP\_NET supports token standards like [OP\_20](https://docs.opnet.org/learn/op-20-standard) and OP\_721, enabling the creation of fungible and non-fungible assets directly on Bitcoin. * [**Introduction**](https://docs.opnet.org/learn/native-bitcoin#introduction) * [**What Does "Native Bitcoin" Mean?**](https://docs.opnet.org/learn/native-bitcoin#what-does-native-bitcoin-mean) * [**Why Use Bitcoin Natively?**](https://docs.opnet.org/learn/native-bitcoin#why-use-bitcoin-natively) * [**Rock-Solid Security**](https://docs.opnet.org/learn/native-bitcoin#rock-solid-security) * [**Unmatched Decentralization**](https://docs.opnet.org/learn/native-bitcoin#unmatched-decentralization) * [**Proven Uptime & Stability**](https://docs.opnet.org/learn/native-bitcoin#proven-uptime--stability) * [**How OP\_NET Leverages Bitcoin**](https://docs.opnet.org/learn/native-bitcoin#how-op_net-leverages-bitcoin) * [**1\. Tapscript for Smart Contracts**](https://docs.opnet.org/learn/native-bitcoin#1-tapscript-for-smart-contracts) * [**2\. Gas Fees in Satoshis**](https://docs.opnet.org/learn/native-bitcoin#2-gas-fees-in-satoshis) * [**Use Cases Enabled by Native Bitcoin**](https://docs.opnet.org/learn/native-bitcoin#use-cases-enabled-by-native-bitcoin) * [**1\. Decentralized Applications (dApps)**](https://docs.opnet.org/learn/native-bitcoin#1-decentralized-applications-dapps) * [**2\. Tokenization**](https://docs.opnet.org/learn/native-bitcoin#2-tokenization) --- # Introduction | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#__docusaurus_skipToContent_fallback) On this page Interacting with contracts on OP\_NET offers a seamless experience while leveraging innovative features like **Unified Contract Addresses** and **Gas Optimization**, all built on top of Bitcoin. This guide provides an overview of OP\_NET's contract functionality, including how it compares to Ethereum and its gas system. * * * **Unified Contract Addresses**[​](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#unified-contract-addresses "Direct link to unified-contract-addresses") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OP\_NET introduces **Unified Contract Addresses**, an approach that simplifies contract interactions by associating contracts with tweaked public keys. This system eliminates the complexity of managing multiple address formats, creating a streamlined developer experience. For more details, see [How OP\_NET Works: Unified Accounts](https://docs.opnet.org/learn/unified-accounts) . Key Features * **Tweaked Public Key**: Contracts are tied to a tweaked public key, ensuring compatibility with Bitcoin's Taproot. * **Unified Account System**: Unified contract addresses are part of the OP\_NET Unified Account system, which simplifies interactions across all address types. * * * **Contract Functionality: Similar to Ethereum**[​](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#contract-functionality-similar-to-ethereum "Direct link to contract-functionality-similar-to-ethereum") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OP\_NET's contract functionality is inspired by Ethereum but tailored for the Bitcoin ecosystem. Key similarities and differences include: ### **Similarities**[​](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#similarities "Direct link to similarities") * **Function Calls**: Contracts can define and expose functions, similar to Ethereum's smart contracts. * **Event Logs**: Contracts emit logs during execution, providing traceable interactions. * **State Storage**: Contracts can maintain persistent storage for data. ### **Differences**[​](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#differences "Direct link to differences") * **UTXO Model**: OP\_NET contracts operate on Bitcoin's UTXO model rather than Ethereum's account model. * **Contract Deployment**: Contracts are associated with Bitcoin transactions and a tweaked public key. * * * **Gas System on OP\_NET**[​](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#gas-system-on-op_net "Direct link to gas-system-on-op_net") -------------------------------------------------------------------------------------------------------------------------------------------------------------------- The gas system on OP\_NET ensures efficient transaction processing while balancing resource usage and network demand. It introduces the following key features: ### **1\. Block Base Fee**[​](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#1-block-base-fee "Direct link to 1-block-base-fee") * Each block includes a **base gas fee**, dynamically adjusted based on network conditions. * Transactions pay for the gas they consume, which includes the base fee. ### **2\. Gas Simulations**[​](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#2-gas-simulations "Direct link to 2-gas-simulations") * Providers automatically simulate transactions to estimate gas usage. * Simulations account for the current block's base fee, ensuring accurate gas calculations. Important Note The gas system on OP\_NET is adaptive, and gas fees may change with each block. Always check the estimated gas before broadcasting a transaction. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#whats-next "Direct link to whats-next") --------------------------------------------------------------------------------------------------------------------------------------- Now that you understand the basics, explore the following topics to dive deeper into contract interactions: * [Getting a Contract ABI](https://docs.opnet.org/developers/interacting-with-a-contract/getting-a-contract-abi) * [**Unified Contract Addresses**](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#unified-contract-addresses) * [**Contract Functionality: Similar to Ethereum**](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#contract-functionality-similar-to-ethereum) * [**Similarities**](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#similarities) * [**Differences**](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#differences) * [**Gas System on OP\_NET**](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#gas-system-on-op_net) * [**1\. Block Base Fee**](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#1-block-base-fee) * [**2\. Gas Simulations**](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#2-gas-simulations) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-a-contract/introduction#whats-next) --- # OP_20 Standard | OP_NET Docs [Skip to main content](https://docs.opnet.org/learn/op-20-standard#__docusaurus_skipToContent_fallback) On this page **Introduction**[​](https://docs.opnet.org/learn/op-20-standard#introduction "Direct link to introduction") ------------------------------------------------------------------------------------------------------------ The **OP\_20** ( OP\_NET's equivalent to Ethereum’s ERC-20 ) standard brings the familiar power of fungible tokens to Bitcoin. With OP\_20, you can: * **Mint and manage tokens** natively in satoshis, without wrapping BTC or relying on sidechains. * **Transfer and approve** token operations (e.g., `transfer`, `approve`, `transferFrom`) just like in Ethereum. * **Build DeFi, stablecoins, and loyalty systems** on top of Bitcoin’s security. Use Cases for OP\_20 Tokens Use OP\_20 for applications such as: * Stablecoins pegged to real‑world assets * Reward and loyalty programs * Decentralized exchanges, lending platforms, and other DeFi protocols * * * **Why OP\_20?**[​](https://docs.opnet.org/learn/op-20-standard#why-op_20 "Direct link to why-op_20") ----------------------------------------------------------------------------------------------------- Key Features of OP\_20 * **Fungible & Interchangeable** Every OP\_20 token unit is identical. Perfect for currencies, stablecoins, or any use case where you need equal value tokens. * **Bitcoin-Native Security** OP\_20 lives on Bitcoin’s base layer, so you get all of Bitcoin’s proven security and full compatibility with existing wallets and infrastructure. * **Low Fees** All gas fees are paid in satoshis, making transaction costs easy to estimate and generally very low. * **Flexible Controls** Built‑in support for minting new tokens, burning supply when needed, and setting allowances for trusted third parties. * * * **How OP\_20 Works**[​](https://docs.opnet.org/learn/op-20-standard#how-op_20-works "Direct link to how-op_20-works") ---------------------------------------------------------------------------------------------------------------------- ### **1\. Contract Deployment**[​](https://docs.opnet.org/learn/op-20-standard#1-contract-deployment "Direct link to 1-contract-deployment") You deploy an OP\_20 token contract as a Tapscript (P2OP) output on Bitcoin. That script encodes your token’s core parameters: * **Token Name** – A human‑readable string (e.g. “MyToken”). * **Symbol** – A short ticker (e.g. “BTC”). * **Total Supply** – The maximum number of tokens ever mintable. Behind the scenes, the contract’s Wasm logic initializes a key/value store in the UTXO, writing these values into contract state. ### **2\. Token Interactions**[​](https://docs.opnet.org/learn/op-20-standard#2-token-interactions "Direct link to 2-token-interactions") Once deployed, your contract exposes standard methods exactly like ERC‑20: * **`transfer(to, amount)`** Creates a new UTXO under your token’s P2OP address, deducting `amount` from your balance and crediting `to`. * **`approve(spender, amount)`** Records in state that `spender` may transfer up to `amount` tokens on your behalf. * **`transferFrom(from, to, amount)`** Allows `spender` (once approved) to move `amount` from `from`’s balance into `to`’s balance. * **`mint(to, amount)`** _(if enabled)_ Increases `totalSupply` and assigns new tokens to `to`. * **`burn(amount)`** _(if enabled)_ Destroys `amount` tokens from your balance and reduces `totalSupply`. Each method call runs off‑chain in the OP\_NET VM, then commits state updates as a set of UTXOs in a normal Bitcoin transaction. ### **3\. Gas Fees & UTXO Model**[​](https://docs.opnet.org/learn/op-20-standard#3-gas-fees--utxo-model "Direct link to 3-gas-fees--utxo-model") * **Fees in Satoshis** Every OP\_20 call is just a Bitcoin transaction under the hood, so you pay transaction fees in satoshis per byte. * **UTXO Efficiency** Instead of a global ledger, OP\_20 stores token balances and allowances inside UTXOs. When you call `transfer`, the VM reads your UTXO state, updates balances, and outputs new UTXOs reflecting the changes—minimizing on‑chain data and benefiting from parallel validation. * **Priority & Congestion** You can add a higher fee-per-byte to your transaction to get faster inclusion during busy periods, just like a regular Bitcoin tx. * * * **Advantages of OP\_20**[​](https://docs.opnet.org/learn/op-20-standard#advantages-of-op_20 "Direct link to advantages-of-op_20") ---------------------------------------------------------------------------------------------------------------------------------- ### **1\. Bitcoin’s Security**[​](https://docs.opnet.org/learn/op-20-standard#1-bitcoins-security "Direct link to 1-bitcoins-security") By building on Bitcoin’s base layer, OP\_20 tokens inherit the security and decentralization of Bitcoin. ### **2\. Flexibility**[​](https://docs.opnet.org/learn/op-20-standard#2-flexibility "Direct link to 2-flexibility") OP\_20 tokens can be customized to fit various use cases, from stablecoins to loyalty points. ### **3\. Compatibility**[​](https://docs.opnet.org/learn/op-20-standard#3-compatibility "Direct link to 3-compatibility") OP\_20 is designed to work seamlessly with Bitcoin wallets, dApps, and infrastructure. * * * **Permission System**[​](https://docs.opnet.org/learn/op-20-standard#permission-system "Direct link to permission-system") --------------------------------------------------------------------------------------------------------------------------- OP\_20’s permission model follows familiar ERC‑20 patterns to balance usability and security: 1. **Granting Allowances** * **One‑Time Approval:** You call `approve(spender, amount)` once to authorize a contract (e.g., a DEX) to spend up to `amount` of your tokens. * **Seamless Interaction:** After approval, you can execute multiple token transfers (swaps, staking, etc.) without repeating the approval step. 2. **Revoking Allowances** * **Full Control:** At any point, call `approve(spender, 0)` to revoke a spender’s permission. * **Security Best Practice:** Periodically review and revoke unused approvals to minimize risk. * * * **Future Enhancements**[​](https://docs.opnet.org/learn/op-20-standard#future-enhancements "Direct link to future-enhancements") --------------------------------------------------------------------------------------------------------------------------------- We’re making OP\_20 even easier and more powerful: * **Approve & Transfer in One Step** Soon you’ll be able to give permission and send tokens in a single click—no extra confirmations. * **Simplified Wallet Experience** Wallets will offer one‑button approval and revocation, so you spend less time managing settings. * **Smoother DeFi Interactions** For things like swaps or liquidity pools, you’ll enjoy faster, seamless token moves without juggling multiple transactions. * * * **Unified Account Integration**[​](https://docs.opnet.org/learn/op-20-standard#unified-account-integration "Direct link to unified-account-integration") --------------------------------------------------------------------------------------------------------------------------------------------------------- OP\_NET’s unified account system ensures that tokens can be managed using a single public key, simplifying asset management. For more information, refer to [Unified Accounts](https://docs.opnet.org/learn/unified-accounts) . * [**Introduction**](https://docs.opnet.org/learn/op-20-standard#introduction) * [**Why OP\_20?**](https://docs.opnet.org/learn/op-20-standard#why-op_20) * [**How OP\_20 Works**](https://docs.opnet.org/learn/op-20-standard#how-op_20-works) * [**1\. Contract Deployment**](https://docs.opnet.org/learn/op-20-standard#1-contract-deployment) * [**2\. Token Interactions**](https://docs.opnet.org/learn/op-20-standard#2-token-interactions) * [**3\. Gas Fees & UTXO Model**](https://docs.opnet.org/learn/op-20-standard#3-gas-fees--utxo-model) * [**Advantages of OP\_20**](https://docs.opnet.org/learn/op-20-standard#advantages-of-op_20) * [**1\. Bitcoin’s Security**](https://docs.opnet.org/learn/op-20-standard#1-bitcoins-security) * [**2\. Flexibility**](https://docs.opnet.org/learn/op-20-standard#2-flexibility) * [**3\. Compatibility**](https://docs.opnet.org/learn/op-20-standard#3-compatibility) * [**Permission System**](https://docs.opnet.org/learn/op-20-standard#permission-system) * [**Future Enhancements**](https://docs.opnet.org/learn/op-20-standard#future-enhancements) * [**Unified Account Integration**](https://docs.opnet.org/learn/op-20-standard#unified-account-integration) --- # What is OP_NET? | OP_NET Docs [Skip to main content](https://docs.opnet.org/learn/what-is-opnet#__docusaurus_skipToContent_fallback) On this page OP\_NET brings **smart contracts**, [**tokens**](https://docs.opnet.org/learn/op-20-standard) , and [**NFTs**](https://docs.opnet.org/learn/nfts-on-opnet) directly to Bitcoin-using **only** Bitcoin’s existing rules. No extra blockchains, no wrapped coins, no risky bridges. Think of Bitcoin as a global, permissionless money network. OP\_NET adds a way to run small programs on that network so you can: * **Create tokens** (e.g., stablecoins, loyalty points) * **Mint NFTs** (digital art, collectibles) * **Build dApps** (games, marketplaces, DeFi) * * * Why OP\_NET?[​](https://docs.opnet.org/learn/what-is-opnet#why-op_net "Direct link to Why OP_NET?") ---------------------------------------------------------------------------------------------------- * **Pure Bitcoin**: Everything happens on Bitcoin. Your BTC stays BTC. * **Rock-solid security**: Leverages Bitcoin’s battle-tested consensus. * **Clean UTXOs**: Miners automatically remove unused data—no clutter. * **Familiar tooling**: Write contracts in TypeScript via WebAssembly (Wasm). * * * How It Works[​](https://docs.opnet.org/learn/what-is-opnet#how-it-works "Direct link to How It Works") ------------------------------------------------------------------------------------------------------- At its core, OP\_NET uses Bitcoin’s existing transaction format and a special SegWit v16 address type (P2OP) to host WebAssembly (Wasm) smart contracts. Here’s what happens under the hood: 1. **Contract Deployment**: Your compiled Wasm code is embedded in a P2OP output—this lives on-chain just like any Bitcoin transaction. 2. **Off-Chain Execution**: The `opnet-node` daemon fetches P2OP outputs, runs the Wasm logic in a sandboxed environment, and tracks contract state securely. 3. **State Commitment**: After execution, any state changes or asset movements are submitted back to Bitcoin as standard transactions, ensuring every update is anchored by Bitcoin miners without altering consensus. This approach means all contract logic remains trustless (via deterministic Wasm) while piggybacking on Bitcoin’s security model and UTXO architecture. * * * P2OP Addresses[​](https://docs.opnet.org/learn/what-is-opnet#p2op-addresses "Direct link to P2OP Addresses") ------------------------------------------------------------------------------------------------------------- P2OP (Pay‑to‑OPNet) is a new Bitcoin address type used to store and reference smart contracts (addresses start with op1...): * **Address format**: Starts with `op1...` * **Anyone‑can‑spend**: Bitcoin treats P2OP outputs as anyone-can-spend, while off-chain logic enforces access control * **Automatic cleanup**: Miners drop spent P2OP UTXOs to prevent chain bloat * **Future-proof**: Fully compatible with upcoming Bitcoin soft forks * * * Smart Contracts on OP\_NET[​](https://docs.opnet.org/learn/what-is-opnet#smart-contracts-on-op_net "Direct link to Smart Contracts on OP_NET") ----------------------------------------------------------------------------------------------------------------------------------------------- Smart contracts on OP\_NET are: * **Written in AssemblyScript** (TypeScript subset) * **Compiled to WebAssembly (Wasm)** modules * **Deployed on-chain** by embedding the Wasm bytecode in a P2OP output * **Executed off-chain** by the `opnet-node` runtime, which: 1. Loads the Wasm module for each contract UTXO 2. Runs contract methods deterministically 3. Tracks and persists contract state (key/value store) Contracts can store data, transfer assets, and invoke other contracts, all while ensuring every node arrives at the same result. * * * Tokens on OP\_NET[​](https://docs.opnet.org/learn/what-is-opnet#tokens-on-op_net "Direct link to Tokens on OP_NET") -------------------------------------------------------------------------------------------------------------------- OP\_NET standardizes fungible tokens with the [**OP\_20 standard**](https://docs.opnet.org/learn/op-20-standard) , similar to Ethereum’s ERC-20: * **Mint, transfer, burn** functions * **Allowance & approval** mechanisms * **Sats-backed**: Tokens can represent, lock, or wrap sats directly * **Composable**: Tokens can integrate seamlessly into DeFi dApps on OP\_NET * * * Is OP\_NET a Layer 2?[​](https://docs.opnet.org/learn/what-is-opnet#is-op_net-a-layer2 "Direct link to Is OP_NET a Layer 2?") ------------------------------------------------------------------------------------------------------------------------------ No. OP\_NET is **not** a Layer 2, sidechain, or rollup: * **No new consensus**: All execution and validation stay within Bitcoin’s consensus rules * **No bridges or wrapped assets**: BTC remains BTC at all times * **UTXO-native**: Uses standard Bitcoin transaction formats and outputs Your apps run directly on Bitcoin, inheriting its security without adding novel trust assumptions. * * * Security Model[​](https://docs.opnet.org/learn/what-is-opnet#security-model "Direct link to Security Model") ------------------------------------------------------------------------------------------------------------- 1. **Bitcoin Consensus**: Miners verify only Bitcoin scripts and P2OP outputs-no protocol changes 2. **Deterministic Execution**: Wasm ensures identical behavior across all nodes 3. **State Verification**: `opnet-node` nodes re-run contract logic locally to confirm state transitions 4. **Open & Auditable**: All Wasm bytecode lives on-chain in transparent P2OP outputs * * * Who Is OP\_NET For?[​](https://docs.opnet.org/learn/what-is-opnet#who-is-op_net-for "Direct link to Who Is OP_NET For?") ------------------------------------------------------------------------------------------------------------------------- * **Bitcoin users** who want tokens and apps without trust risks. * **Developers** familiar with JavaScript/TypeScript, looking to tap into Bitcoin’s security. * **Businesses** seeking to launch tokenized products on a proven blockchain. * * * _Unlock The Full Potential Of Bitcoin with OP\_NET_ * [Why OP\_NET?](https://docs.opnet.org/learn/what-is-opnet#why-op_net) * [How It Works](https://docs.opnet.org/learn/what-is-opnet#how-it-works) * [P2OP Addresses](https://docs.opnet.org/learn/what-is-opnet#p2op-addresses) * [Smart Contracts on OP\_NET](https://docs.opnet.org/learn/what-is-opnet#smart-contracts-on-op_net) * [Tokens on OP\_NET](https://docs.opnet.org/learn/what-is-opnet#tokens-on-op_net) * [Is OP\_NET a Layer 2?](https://docs.opnet.org/learn/what-is-opnet#is-op_net-a-layer2) * [Security Model](https://docs.opnet.org/learn/what-is-opnet#security-model) * [Who Is OP\_NET For?](https://docs.opnet.org/learn/what-is-opnet#who-is-op_net-for) --- # Getting UTXOs for an Address with Required Amount | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#__docusaurus_skipToContent_fallback) On this page The `getUTXOsForAmount` method allows you to fetch Unspent Transaction Outputs (UTXOs) for a specific Bitcoin address that cover a required amount. This method simplifies the process of selecting UTXOs for transaction creation, ensuring that the total value of the UTXOs meets the specified amount. * * * **Method**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#method "Direct link to method") --------------------------------------------------------------------------------------------------------------------------------------------------------- getUTXOsForAmount({ address, amount, optimize?, mergePendingUTXOs?, filterSpentUTXOs?, throwErrors?,}: RequestUTXOsParamsWithAmount): Promise; * **Parameters**: * **`address: string`**: The Bitcoin address to fetch UTXOs for. * **`amount: bigint`**: The required amount (in satoshis) to cover with UTXOs. * **`optimize?: boolean`** _(Optional)_: * If `true`, optimizes UTXO selection for efficiency and minimal transaction fees. * **`mergePendingUTXOs?: boolean`** _(Optional)_: * If `true`, includes pending UTXOs awaiting confirmation. * **`filterSpentUTXOs?: boolean`** _(Optional)_: * If `true`, filters out any already spent UTXOs. * **`throwErrors?: boolean`** _(Optional)_: * If `true`, throws an error if sufficient UTXOs are not found. * **Returns**: * **`Promise`**: An array of `UTXO` objects that cover the specified amount. * * * **Object Definitions**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#object-definitions "Direct link to object-definitions") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `UTXO` Object | **Property** | **Type** | **Description** | | --- | --- | --- | | **`transactionId`** | `string` | The ID of the transaction containing the UTXO. | | **`outputIndex`** | `number` | The index of the UTXO in the transaction outputs. | | **`value`** | `bigint` | The amount of Bitcoin (in satoshis) held by the UTXO. | | **`scriptPubKey`** | `ScriptPubKey` | The locking script for the UTXO. | * * * **Example Usage**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ### **Fetching UTXOs for a Required Amount**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#fetching-utxos-for-a-required-amount "Direct link to fetching-utxos-for-a-required-amount") const address = "bcrt1qexampleaddress...";const amount = BigInt(100000); // 100,000 satoshis (0.001 BTC)const utxos = await provider.utxoManager.getUTXOsForAmount({ address, amount });console.log("Fetched UTXOs for amount:", utxos); ### **Handling Insufficient UTXOs**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#handling-insufficient-utxos "Direct link to handling-insufficient-utxos") try { const utxos = await provider.utxoManager.getUTXOsForAmount({ address, amount, throwErrors: true, }); console.log("UTXOs:", utxos);} catch (error) { console.error("Insufficient UTXOs:", error.message);} * * * **Best Practices**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure the `amount` parameter is specified as a `bigint` and accurately represents the required value in satoshis. * Use the `throwErrors` parameter to explicitly handle cases where sufficient UTXOs cannot be found. * If the `mergePendingUTXOs` option is enabled, unconfirmed UTXOs will also be included in the result. * * * **What’s Next?**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#whats-next "Direct link to whats-next") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- After fetching UTXOs for a specific amount, you can: * [Getting UTXOs for an Address](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address) * [Keeping UTXOs Changes in Memory](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory) * [Build and Send Transactions](https://docs.opnet.org/developers/interacting-with-a-contract/introduction) * [**Method**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#method) * [**Object Definitions**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#example-usage) * [**Fetching UTXOs for a Required Amount**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#fetching-utxos-for-a-required-amount) * [**Handling Insufficient UTXOs**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#handling-insufficient-utxos) * [**Best Practices**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount#whats-next) --- # Keeping UTXOs Changes in Memory | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#__docusaurus_skipToContent_fallback) On this page The `spendUTXO` method in the UTXOs Manager allows you to mark UTXOs as spent and manage changes in memory. This guide explains how to use this method and reset the UTXO memory when needed. * * * **Methods**[​](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#methods "Direct link to methods") ------------------------------------------------------------------------------------------------------------------------------------------ ### **1\. Marking UTXOs as Spent**[​](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#1-marking-utxos-as-spent "Direct link to 1-marking-utxos-as-spent") spentUTXO(spent: UTXOs, newUTXOs: UTXOs): void; * **Parameters**: * **`spent: UTXOs`**: The UTXOs that have been used in a transaction. * **`newUTXOs: UTXOs`**: New UTXOs created by the transaction, if any, else an empty array. * * * ### **2\. Resetting Memory**[​](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#2-resetting-memory "Direct link to 2-resetting-memory") clean(): void; * * * **Example Usage**[​](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------------------------ ### **Marking UTXOs as Spent**[​](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#marking-utxos-as-spent "Direct link to marking-utxos-as-spent") const utxosManager = provider.utxoManager;// Fetch UTXOs for an addressconst address = "bcrt1qfqsr3m7vjxheghcvw4ks0fryqxfq8qzjf8fxes";const requiredAmount = BigInt(100000); // 100,000 satoshisconst utxos = await utxosManager.getUTXOsForAmount({ address, amount: requiredAmount,});// Use the UTXOs in a transaction and mark them as spentutxosManager.spentUTXO(utxos, []); // Add new UTXOs if they are createdconsole.log("UTXOs marked as spent");// Fetch the UTXOs againconst newUTXOs = await utxosManager.getUTXOsForAmount({ address, amount: requiredAmount,});// Check if the UTXOs are differentconsole.log("UTXOs are different:", newUTXOs !== utxos); // true * * * ### **Resetting the UTXO Memory**[​](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#resetting-the-utxo-memory "Direct link to resetting-the-utxo-memory") If you want to reset the in-memory state (e.g., to fetch fresh UTXOs), you can call the `clean` method: utxosManager.clean();console.log("UTXO memory reset"); * * * **Best Practices**[​](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------------------------- * Always call `spentUTXO` after using UTXOs in a transaction to avoid reusing them. * Resetting the UTXO memory using `clean` will clear all tracked spent and pending UTXOs. Use it cautiously if you need to preserve the current state. * * * **What’s Next?**[​](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#whats-next "Direct link to whats-next") ----------------------------------------------------------------------------------------------------------------------------------------------------- Explore additional UTXO Manager capabilities: * [Getting UTXOs for an Address](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address) * [Getting UTXOs for an Address with Required Amount](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount) * [**Methods**](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#methods) * [**1\. Marking UTXOs as Spent**](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#1-marking-utxos-as-spent) * [**2\. Resetting Memory**](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#2-resetting-memory) * [**Example Usage**](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#example-usage) * [**Marking UTXOs as Spent**](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#marking-utxos-as-spent) * [**Resetting the UTXO Memory**](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#resetting-the-utxo-memory) * [**Best Practices**](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory#whats-next) --- # Markdown Examples | OP_NET Docs [Skip to main content](https://docs.opnet.org/utils#__docusaurus_skipToContent_fallback) On this page Base Syntax[​](https://docs.opnet.org/utils#base-syntax "Direct link to Base Syntax") -------------------------------------------------------------------------------------- Example text with nothing specific ### Bold[​](https://docs.opnet.org/utils#bold "Direct link to Bold") **bold text** ### Italic[​](https://docs.opnet.org/utils#italic "Direct link to Italic") _italicized text_ ### Blockquote[​](https://docs.opnet.org/utils#blockquote "Direct link to Blockquote") > blockquote ### Ordered List[​](https://docs.opnet.org/utils#ordered-list "Direct link to Ordered List") 1. First item 2. Second item 3. Third item ### Unordered List[​](https://docs.opnet.org/utils#unordered-list "Direct link to Unordered List") * First item * Second item * Third item ### Code[​](https://docs.opnet.org/utils#code "Direct link to Code") `code` ### Horizontal Rule[​](https://docs.opnet.org/utils#horizontal-rule "Direct link to Horizontal Rule") * * * ### Link[​](https://docs.opnet.org/utils#link "Direct link to Link") [absolute URL](https://www.example.com/) [relative URL](https://docs.opnet.org/tokens/fungible-tokens) Extended Syntax[​](https://docs.opnet.org/utils#extended-syntax "Direct link to Extended Syntax") -------------------------------------------------------------------------------------------------- ### Table[​](https://docs.opnet.org/utils#table "Direct link to Table") | Syntax | Description | | --- | --- | | Header | Title | | Paragraph | Text | ### Fenced Code Block[​](https://docs.opnet.org/utils#fenced-code-block "Direct link to Fenced Code Block") { "firstName": "John", "lastName": "Smith", "age": 25} ### Footnote[​](https://docs.opnet.org/utils#footnote "Direct link to Footnote") Here's a sentence with a footnote. [1](https://docs.opnet.org/utils#user-content-fn-1) ### Heading ID[​](https://docs.opnet.org/utils#heading-id "Direct link to Heading ID") ### My Great Heading[​](https://docs.opnet.org/utils#custom-id "Direct link to My Great Heading") ### Definition List[​](https://docs.opnet.org/utils#definition-list "Direct link to Definition List") term : definition ### Strikethrough[​](https://docs.opnet.org/utils#strikethrough "Direct link to Strikethrough") ~The world is flat.~ ### Task List[​](https://docs.opnet.org/utils#task-list "Direct link to Task List") * [x] Write the press release * [ ] Update the website * [ ] Contact the media ### Tabs[​](https://docs.opnet.org/utils#tabs "Direct link to Tabs") * First * Second * Third Example text with an emoji 🟢 Good info 🔴 Bad info console.log("Hello, world!"); { "status": { "key0": 0, "key1": 1, "key2": 123, "key3": 1234, "key4": 123456 }} ### Info Admonitions[​](https://docs.opnet.org/utils#info-admonitions "Direct link to Info Admonitions") Available cases: caution, note, important, tip, warning caution Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in turpis dignissim sapien sodales dignissim. Phasellus malesuada viverra consectetur. Aliquam et diam quis lectus luctus molestie. Pellentesque a dictum orci. Custom Title The content and title _can_ include markdown. For example: console.log("Hello, world!"); important `example/endpoint` text about it tip Lorem ipsum dolor sit amet ! caution Oh, no ! Lorem ipsum dolor sit amet * * * ### `GET` API Call[​](https://docs.opnet.org/utils#get-api-call "Direct link to get-api-call") GET API Call[​](https://docs.opnet.org/utils#get-api-call "Direct link to get-api-call") ----------------------------------------------------------------------------------------- POST API Call[​](https://docs.opnet.org/utils#post-api-call "Direct link to post-api-call") -------------------------------------------------------------------------------------------- Custom Title The content and title _can_ include markdown. For example: * First * Second * Third Path Parameters `https://example.com/*param*` | Param | Required | Type | Description | | --- | --- | --- | --- | | bech32Address | REQUIRED | `string` | The Address to query. | | gasPrice | OPTIONAL | `number` | The desired Gas Price (per Gas Unit). | | storageKey | REQUIRED | `string` | The storage entry to fetch. | | bech32Address | REQUIRED | `string` | The Address to query. | console.log("Hello, world!"); 🟢 200 OK Value (hex-encoded) successfully retrieved. { "status": { "key0": 0, "key1": 1, "key2": 123, "key3": 1234, "key4": 123456 }} LaTeX ===== LaTeX Example[​](https://docs.opnet.org/utils#latex-example "Direct link to LaTeX Example") -------------------------------------------------------------------------------------------- ### Inline[​](https://docs.opnet.org/utils#inline "Direct link to Inline") Text that contains a function f(a,b,c)\=(a2+b2+c2)3f(a,b,c) = (a^2+b^2+c^2)^3f(a,b,c)\=(a2+b2+c2)3 and continues after that function. Text that contains an integral ∫abx2 dx\\int\_{a}^{b} x^2 \\,dx∫ab​x2dx and continues after that (nk)\\binom{n}{k}(kn​) ### Block[​](https://docs.opnet.org/utils#block "Direct link to Block") f(a,b,c)\=(a2+b2+c2)3f(a,b,c) = (a^2+b^2+c^2)^3f(a,b,c)\=(a2+b2+c2)3 Example text (nk)\=n!k!(n−k)!\\binom{n}{k} = \\frac{n!}{k!(n-k)!}(kn​)\=k!(n−k)!n!​ y\=∫−∞∞ξ^ e2πiξx dξ\\relax{y} = \\int\_{-\\infty}^\\infty \\hat\\xi\\,e^{2 \\pi i \\xi x} \\,d\\xiy\=∫−∞∞​ξ^​e2πiξxdξ ∣x∣\={xifx≥0−xifx<0}|x| = \\begin{Bmatrix} x & {if } x \\geq 0 \\\\ -x & {if } x < 0 \\end{Bmatrix}∣x∣\={x−x​ifx≥0ifx<0​} ### YouTube Embed[​](https://docs.opnet.org/utils#youtube-embed "Direct link to YouTube Embed") First Version[​](https://docs.opnet.org/utils#first-version "Direct link to First Version") -------------------------------------------------------------------------------------------- [![Blockchain basics](https://img.youtube.com/vi/tv6OBimIX98/maxresdefault.jpg)](https://www.youtube.com/watch?v=tv6OBimIX98 "Blockchain basics") Second version[​](https://docs.opnet.org/utils#second-version "Direct link to Second version") ----------------------------------------------------------------------------------------------- Mermaid diagrams[​](https://docs.opnet.org/utils#mermaid-diagrams "Direct link to Mermaid diagrams") ----------------------------------------------------------------------------------------------------- Footnotes[​](https://docs.opnet.org/utils#footnote-label "Direct link to Footnotes") ------------------------------------------------------------------------------------- 1. This is the footnote. [↩](https://docs.opnet.org/utils#user-content-fnref-1) * [Base Syntax](https://docs.opnet.org/utils#base-syntax) * [Bold](https://docs.opnet.org/utils#bold) * [Italic](https://docs.opnet.org/utils#italic) * [Blockquote](https://docs.opnet.org/utils#blockquote) * [Ordered List](https://docs.opnet.org/utils#ordered-list) * [Unordered List](https://docs.opnet.org/utils#unordered-list) * [Code](https://docs.opnet.org/utils#code) * [Horizontal Rule](https://docs.opnet.org/utils#horizontal-rule) * [Link](https://docs.opnet.org/utils#link) * [Extended Syntax](https://docs.opnet.org/utils#extended-syntax) * [Table](https://docs.opnet.org/utils#table) * [Fenced Code Block](https://docs.opnet.org/utils#fenced-code-block) * [Footnote](https://docs.opnet.org/utils#footnote) * [Heading ID](https://docs.opnet.org/utils#heading-id) * [My Great Heading](https://docs.opnet.org/utils#custom-id) * [Definition List](https://docs.opnet.org/utils#definition-list) * [Strikethrough](https://docs.opnet.org/utils#strikethrough) * [Task List](https://docs.opnet.org/utils#task-list) * [Tabs](https://docs.opnet.org/utils#tabs) * [Info Admonitions](https://docs.opnet.org/utils#info-admonitions) * [`GET` API Call](https://docs.opnet.org/utils#get-api-call) * [GET API Call](https://docs.opnet.org/utils#get-api-call) * [POST API Call](https://docs.opnet.org/utils#post-api-call) * [LaTeX Example](https://docs.opnet.org/utils#latex-example) * [Inline](https://docs.opnet.org/utils#inline) * [Block](https://docs.opnet.org/utils#block) * [YouTube Embed](https://docs.opnet.org/utils#youtube-embed) * [First Version](https://docs.opnet.org/utils#first-version) * [Second version](https://docs.opnet.org/utils#second-version) * [Mermaid diagrams](https://docs.opnet.org/utils#mermaid-diagrams) --- # Transaction Gas & Priority | OP_NET Docs [Skip to main content](https://docs.opnet.org/learn/transaction-gas-and-priority#__docusaurus_skipToContent_fallback) On this page On OP\_NET, every transaction pays two fees in satoshis: 1. **Gas Fee** – covers execution and on‑chain data storage. 2. **Priority Fee** – an optional tip to miners for faster inclusion. Use this guide to see how these fees work together and where they go. * * * **1\. Gas Usage**[​](https://docs.opnet.org/learn/transaction-gas-and-priority#1-gas-usage "Direct link to 1-gas-usage") ------------------------------------------------------------------------------------------------------------------------- * Every transaction on OP\_NET requires a certain amount of gas to execute * The gas amount is proportional to the computational resources consumed by the transaction. * Transactions with higher gas usage are more resource-intensive, which impacts their priority in the mempool. * * * **2\. Priority Fee**[​](https://docs.opnet.org/learn/transaction-gas-and-priority#2-priority-fee "Direct link to 2-priority-fee") ---------------------------------------------------------------------------------------------------------------------------------- * Users can include a **priority fee** in their transaction to boost its priority in the network * Transactions with higher priority fees are more likely to be included in the next block. tip To ensure your transaction is processed promptly, consider including a priority fee, especially during periods of high network activity * * * **3\. Fee Burning**[​](https://docs.opnet.org/learn/transaction-gas-and-priority#3-fee-burning "Direct link to 3-fee-burning") ------------------------------------------------------------------------------------------------------------------------------- * **No redistribution**: All gas and priority fees are sent to “dead” contract addresses and removed from circulation. * **Why burn fees**: Prevents re‑use or gaming of the fee pool, ensuring a fair, one‑way payment for network resources. * * * **4\. Best Practices**[​](https://docs.opnet.org/learn/transaction-gas-and-priority#4-best-practices "Direct link to 4-best-practices") ---------------------------------------------------------------------------------------------------------------------------------------- * **Simulate gas**: Use OP\_NET’s [gas estimator tools](https://docs.opnet.org/developers/interacting-with-a-contract/simulating-a-transaction-with-a-contract-instance) before sending real transactions. * **Adjust tips**: Watch Bitcoin mempool metrics and raise your priority fee when blocks fill up. * **Bundle operations**: Combine multiple contract calls into one transaction to save on base fees. * **Optimize contracts**: Write efficient Wasm code and minimize on‑chain data to reduce gas usage. * * * * [**1\. Gas Usage**](https://docs.opnet.org/learn/transaction-gas-and-priority#1-gas-usage) * [**2\. Priority Fee**](https://docs.opnet.org/learn/transaction-gas-and-priority#2-priority-fee) * [**3\. Fee Burning**](https://docs.opnet.org/learn/transaction-gas-and-priority#3-fee-burning) * [**4\. Best Practices**](https://docs.opnet.org/learn/transaction-gas-and-priority#4-best-practices) --- # Unified Accounts | OP_NET Docs [Skip to main content](https://docs.opnet.org/learn/unified-accounts#__docusaurus_skipToContent_fallback) On this page **Introduction**[​](https://docs.opnet.org/learn/unified-accounts#introduction "Direct link to introduction") -------------------------------------------------------------------------------------------------------------- Managing Bitcoin often means juggling many address types-legacy (1…), SegWit (bc1q…), Taproot (bc1p…). OP\_NET’s **Unified Accounts** change all that: you only ever use one public key. Behind the scenes, OP\_NET applies a small adjustment (a “tweak”) to fit the right address format automatically. With Unified Accounts: * You share or store one key instead of multiple addresses. * You sign transactions once, and the network handles the rest. * Your apps and wallets work seamlessly with any Bitcoin upgrade. Key Points Unified Accounts let you treat a public key as your single Bitcoin account, no more copying, pasting, or converting between address styles. * * * **How Does the Unified Account System Work?**[​](https://docs.opnet.org/learn/unified-accounts#how-does-the-unified-account-system-work "Direct link to how-does-the-unified-account-system-work") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Bitcoin uses multiple address formats (e.g., P2PKH, P2SH, P2WPKH, P2TR) all derived from public keys. OP\_NET simplifies this by letting you work with **one public key**. Behind the scenes, OP\_NET “tweaks” your key as needed and maps it to the right address format automatically. Key Benefits of Unified Accounts * **Single Identity**: All transactions, tokens, and contracts tie back to your one public key, no more juggling addresses. * **Simplified Asset Management**: Balances and assets (BTC, tokens, NFTs) live under your key, making tracking effortless. * **Seamless Compatibility**: Wallets and dApps can switch between legacy, SegWit, or Taproot formats without any extra steps. * **Built-in Signature Verification**: Contracts on OP\_NET can directly verify Schnorr signatures from your public key, enabling features like: * **`approveFrom`**: Delegated approvals for spending. * **`swapWithPermit`**: Trustless swaps with built-in signature verification. * **Claim Systems**: Allowing users to claim assets or rewards via verifiable signatures. * * * Why Unified Accounts Matter[​](https://docs.opnet.org/learn/unified-accounts#why-unified-accounts-matter "Direct link to Why Unified Accounts Matter") ------------------------------------------------------------------------------------------------------------------------------------------------------- ### For Developers[​](https://docs.opnet.org/learn/unified-accounts#for-developers "Direct link to For Developers") Unified Accounts simplify how you build on Bitcoin by giving you one consistent way to work with accounts, contracts, and tokens: * **No address-type logic**: Write your code once—no branching for `1…`, `3…`, `bc1q…`, or `bc1p…`. * **Signature-based flows**: Use Schnorr signatures from your public key to authorize actions like delegated approvals or swaps. * **More efficient transactions**: Skipping address conversion can save up to **40%** in transaction fees. ### For Users[​](https://docs.opnet.org/learn/unified-accounts#for-users "Direct link to For Users") Unified Accounts make using Bitcoin apps and wallets much easier: * **One key to rule them all**: Manage a single public key instead of multiple addresses. * **Seamless airdrops**: Receive tokens or NFTs directly to your public key, no prior address setup needed. * **Hassle-free interactions**: Send, receive, or sign without ever choosing an address format. * * * **How Does It Work in Practice?**[​](https://docs.opnet.org/learn/unified-accounts#how-does-it-work-in-practice "Direct link to how-does-it-work-in-practice") --------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. Public Key Integration**[​](https://docs.opnet.org/learn/unified-accounts#1-public-key-integration "Direct link to 1-public-key-integration") Every action on OP\_NET uses your public key directly: * **Sending Funds:** Sign and send transactions with your public key. OP\_NET automatically derives the correct address format. * **Interacting with Contracts:** Smart contracts use your public key as your account ID, no manual address conversion needed. ### **2\. Tweaked Public Keys**[​](https://docs.opnet.org/learn/unified-accounts#2-tweaked-public-keys "Direct link to 2-tweaked-public-keys") With Taproot, public keys are tweaked to enhance privacy and enable advanced scripting. OP\_NET fully integrates this feature: Q\=P+H(P∥c)⋅GQ = P + H(P ∥ c) ⋅ G Q\=P+H(P∥c)⋅G Where: * `P` is the original public key. * `H` is a hash function. * `c` is optional commitment data. * `G` is the elliptic curve generator point. Using tweaked public keys allows OP\_NET contracts to perform Schnorr signature verification directly. For instance: ### **Example: Schnorr Signature Verification**[​](https://docs.opnet.org/learn/unified-accounts#example-schnorr-signature-verification "Direct link to example-schnorr-signature-verification") Inside a contract, OP\_NET uses a function like this: private verifySignature(calldata: Calldata): BytesWriter { const signature = calldata.readBytesWithLength(); const message = calldata.readBytesWithLength(); const isValidSignature = Blockchain.verifySchnorrSignature( Blockchain.tx.origin, // Signer's public key signature, // Schnorr signature message // Original message to verify ); const result = new BytesWriter(1); result.writeBoolean(isValidSignature); return result;} This functionality enables features like `approveFrom`, `swapWithPermit`, and other advanced interactions, allowing users to sign off-chain data securely and submit it for verification on-chain. * * * **Features of the Unified Account System**[​](https://docs.opnet.org/learn/unified-accounts#features-of-the-unified-account-system "Direct link to features-of-the-unified-account-system") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Compatibility with Bitcoin**[​](https://docs.opnet.org/learn/unified-accounts#compatibility-with-bitcoin "Direct link to compatibility-with-bitcoin") Unified accounts are fully compatible with Bitcoin's existing protocols: * **Backward Compatibility:** Works seamlessly with all address types (e.g., legacy, SegWit, Taproot). * **Forward Compatibility:** Ready for future Bitcoin upgrades and enhancements. ### **Public Key Retrieval API**[​](https://docs.opnet.org/learn/unified-accounts#public-key-retrieval-api "Direct link to public-key-retrieval-api") Retrieving public key information on OP\_NET is straightforward using the provider's API. Fetching Public Key from Address For detailed instructions, refer to the [Fetching Public Key from Address](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address) documentation. * * * **Considerations**[​](https://docs.opnet.org/learn/unified-accounts#considerations "Direct link to considerations") -------------------------------------------------------------------------------------------------------------------- While unified accounts bring many benefits, there are edge cases to consider: * **Fresh Wallets:** Public keys must be revealed through a transaction before they can be used. * **Non-Standard Scripts:** Addresses created with custom scripts may require manual public key input. * [**Introduction**](https://docs.opnet.org/learn/unified-accounts#introduction) * [**How Does the Unified Account System Work?**](https://docs.opnet.org/learn/unified-accounts#how-does-the-unified-account-system-work) * [Why Unified Accounts Matter](https://docs.opnet.org/learn/unified-accounts#why-unified-accounts-matter) * [For Developers](https://docs.opnet.org/learn/unified-accounts#for-developers) * [For Users](https://docs.opnet.org/learn/unified-accounts#for-users) * [**How Does It Work in Practice?**](https://docs.opnet.org/learn/unified-accounts#how-does-it-work-in-practice) * [**1\. Public Key Integration**](https://docs.opnet.org/learn/unified-accounts#1-public-key-integration) * [**2\. Tweaked Public Keys**](https://docs.opnet.org/learn/unified-accounts#2-tweaked-public-keys) * [**Example: Schnorr Signature Verification**](https://docs.opnet.org/learn/unified-accounts#example-schnorr-signature-verification) * [**Features of the Unified Account System**](https://docs.opnet.org/learn/unified-accounts#features-of-the-unified-account-system) * [**Compatibility with Bitcoin**](https://docs.opnet.org/learn/unified-accounts#compatibility-with-bitcoin) * [**Public Key Retrieval API**](https://docs.opnet.org/learn/unified-accounts#public-key-retrieval-api) * [**Considerations**](https://docs.opnet.org/learn/unified-accounts#considerations) --- # Introduction | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#__docusaurus_skipToContent_fallback) On this page The UTXO Manager in the OP\_NET ecosystem simplifies managing Bitcoin's Unspent Transaction Outputs (UTXOs). It abstracts the complexities of fetching, optimizing, and managing UTXOs for wallets and smart contracts, allowing developers to interact efficiently with the UTXO model. * * * **What is a UTXO?**[​](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#what-is-a-utxo "Direct link to what-is-a-utxo") --------------------------------------------------------------------------------------------------------------------------------------------- In Bitcoin, a UTXO (Unspent Transaction Output) is an output of a blockchain transaction that has not yet been spent. UTXOs form the foundation of Bitcoin’s transaction model. Each UTXO represents a certain amount of Bitcoin locked in an output, which can later be used as an input for another transaction. Key Attributes of a UTXO * **Transaction ID**: Identifies the transaction that created the UTXO. * **Output Index**: The index of the UTXO within the transaction. * **Value**: The amount of Bitcoin the UTXO represents. * **ScriptPubKey**: The locking script that specifies the conditions under which the UTXO can be spent. * * * **Features of the UTXO Manager**[​](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#features-of-the-utxo-manager "Direct link to features-of-the-utxo-manager") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Core Capabilities**[​](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#core-capabilities "Direct link to core-capabilities") | **Feature** | **Description** | | --- | --- | | **Fetch UTXOs** | Retrieve all UTXOs for a given address. | | **Fetch UTXOs for Amount** | Retrieve UTXOs that satisfy a specific amount, useful for transaction creation. | | **Optimize UTXOs** | Optimize UTXO selection to minimize transaction fees. | | **Merge Pending UTXOs** | Combine UTXOs that are pending confirmation. | | **Filter Spent UTXOs** | Filter out already spent UTXOs from the results. | ### **Integration**[​](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#integration "Direct link to integration") The UTXO Manager is seamlessly integrated into the `JSONRpcProvider` as part of the OP\_NET ecosystem. This allows for direct interaction with Bitcoin UTXOs in both single and batch operations. * * * **Best Practices**[​](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#best-practices "Direct link to best-practices") -------------------------------------------------------------------------------------------------------------------------------------------- * Always filter out spent UTXOs to ensure accurate results. * Use UTXO optimization to reduce transaction fees, especially when dealing with multiple inputs. * Fetch UTXOs for a specific amount to streamline transaction creation. * * * **What’s Next?**[​](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#whats-next "Direct link to whats-next") ---------------------------------------------------------------------------------------------------------------------------------- Explore the following guides to dive deeper into the UTXO Manager: * [Getting UTXOs for an Address](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address) * [Getting UTXOs for an Address with Required Amount](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount) * [Keeping UTXOs Changes in Memory](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory) * [**What is a UTXO?**](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#what-is-a-utxo) * [**Features of the UTXO Manager**](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#features-of-the-utxo-manager) * [**Core Capabilities**](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#core-capabilities) * [**Integration**](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#integration) * [**Best Practices**](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/using-the-utxo-manager/introduction#whats-next) --- # Getting UTXOs for an Address | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#__docusaurus_skipToContent_fallback) On this page The `getUTXOs` method allows you to fetch all Unspent Transaction Outputs (UTXOs) associated with a specific Bitcoin address. * * * **Method**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#method "Direct link to method") ------------------------------------------------------------------------------------------------------------------------------------ getUTXOs({ address, optimize?, mergePendingUTXOs?, filterSpentUTXOs?,}: RequestUTXOsParams): Promise; * **Parameters**: * **`address: string`**: The Bitcoin address to fetch UTXOs for. * **`optimize?: boolean`** _(Optional)_: * If `true`, optimizes UTXO selection for efficiency and minimal transaction fees. * **`mergePendingUTXOs?: boolean`** _(Optional)_: * If `true`, includes pending UTXOs that are awaiting confirmation. * **`filterSpentUTXOs?: boolean`** _(Optional)_: * If `true`, filters out any already spent UTXOs. * **Returns**: * **`Promise`**: An array of `UTXO` objects representing the unspent outputs for the specified address. * * * **Object Definitions**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#object-definitions "Direct link to object-definitions") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ `UTXO` Object | **Property** | **Type** | **Description** | | --- | --- | --- | | **`transactionId`** | `string` | The ID of the transaction containing the UTXO. | | **`outputIndex`** | `number` | The index of the UTXO in the transaction outputs. | | **`value`** | `bigint` | The amount of Bitcoin (in satoshis) held by the UTXO. | | **`scriptPubKey`** | `ScriptPubKey` | The locking script for the UTXO. | * * * **Example Usage**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#example-usage "Direct link to example-usage") --------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Fetching UTXOs for an Address**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#fetching-utxos-for-an-address "Direct link to fetching-utxos-for-an-address") const address = "bcrt1qexampleaddress...";const utxos = await provider.utxoManager.getUTXOs({ address });console.log("Fetched UTXOs:", utxos); ### **Optimized UTXO Fetching**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#optimized-utxo-fetching "Direct link to optimized-utxo-fetching") const optimizedUtxos = await provider.utxoManager.getUTXOs({ address, optimize: true,});console.log("Optimized UTXOs:", optimizedUtxos); * * * **Best Practices**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#best-practices "Direct link to best-practices") ------------------------------------------------------------------------------------------------------------------------------------------------------------ * The `optimize` parameter is useful for minimizing transaction fees by selecting the smallest number of UTXOs. * Use the `mergePendingUTXOs` parameter if you need to include pending UTXOs that are not yet confirmed. * The `filterSpentUTXOs` parameter helps ensure that only unspent outputs are returned. * * * **What’s Next?**[​](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#whats-next "Direct link to whats-next") -------------------------------------------------------------------------------------------------------------------------------------------------- After retrieving UTXOs, you can: * [Getting UTXOs for an Address with Required Amount](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address-with-required-amount) * [Keeping UTXOs Changes in Memory](https://docs.opnet.org/developers/using-the-utxo-manager/keeping-utxos-changes-in-memory) * [Build and Send Transactions](https://docs.opnet.org/developers/interacting-with-a-contract/introduction) * [**Method**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#method) * [**Object Definitions**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#example-usage) * [**Fetching UTXOs for an Address**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#fetching-utxos-for-an-address) * [**Optimized UTXO Fetching**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#optimized-utxo-fetching) * [**Best Practices**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/using-the-utxo-manager/getting-utxos-for-an-address#whats-next) --- # Introduction | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/walletconnect/introduction#__docusaurus_skipToContent_fallback) On this page WalletConnect enables secure communication between decentralized applications (dApps) and browsers, desktops, and mobile wallets. Why Use WalletConnect with OP\_NET? WalletConnect simplifies wallet integration for developers, providing: * **Cross-platform compatibility**: Connect with wallets across browsers, desktop, and mobile devices. * **Secure communication**: End-to-end encryption ensures secure interaction between dApps and wallets. * **Seamless OP\_NET support**: Easily integrate WalletConnect to handle OP\_NET transactions and interactions. * * * **Installing WalletConnect**[​](https://docs.opnet.org/developers/walletconnect/introduction#installing-walletconnect "Direct link to installing-walletconnect") ----------------------------------------------------------------------------------------------------------------------------------------------------------------- Install the `@btc-vision/walletconnect` package via npm: npm install @btc-vision/walletconnect The `@btc-vision/walletconnect` package provides all the tools needed to integrate WalletConnect with OP\_NET seamlessly. * * * **Next Steps**[​](https://docs.opnet.org/developers/walletconnect/introduction#next-steps "Direct link to next-steps") ----------------------------------------------------------------------------------------------------------------------- To get started with WalletConnect, proceed to the [Setting Up WalletConnect](https://docs.opnet.org/developers/walletconnect/setup) guide. * [**Installing WalletConnect**](https://docs.opnet.org/developers/walletconnect/introduction#installing-walletconnect) * [**Next Steps**](https://docs.opnet.org/developers/walletconnect/introduction#next-steps) --- # Sending a Transaction | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#__docusaurus_skipToContent_fallback) On this page This guide walks you through the process of sending a transaction using WalletConnect, specifically for interactions with OP\_NET smart contracts. * * * **Steps to Send a Transaction**[​](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#steps-to-send-a-transaction "Direct link to steps-to-send-a-transaction") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. Get Required Parameters**[​](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#1-get-required-parameters "Direct link to 1-get-required-parameters") Before sending a transaction, ensure you have the following parameters: * **`account`**: Wallet account for transaction signing. import { useWallet } from "@btc-vision/walletconnect";const { account } = useWallet(); ### **2\. Define the Contract Instance**[​](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#2-define-the-contract-instance "Direct link to 2-define-the-contract-instance") Use the `getContract` method to define the contract you want to interact with. This step ensures you have a properly typed contract instance that can encode calldata for the desired function. const contractAddress = "opr1exampleaddress"; // Replace with a valid contract addressconst contractInstance = getContract( contractAddress, // Contract address OP_20_ABI, // Contract ABI provider: account.provider, // Provider instance network: account.network, // Target network address: account.address // Sender's address); Contract Interaction Ensure the contract instance matches the contract you want to interact with, including the correct address and ABI. Learn more about [**Interacting with Smart Contracts**](https://docs.opnet.org/developers/interacting-with-a-contract/introduction) . * * * ### **3\. Simulate the Transaction**[​](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#3-simulate-the-transaction "Direct link to 3-simulate-the-transaction") Before sending the transaction, simulate it to ensure it will succeed. This step is crucial for avoiding failed transactions due to incorrect parameters. const resApprove = await contractInstance.approve(account.address, 100n);if (!resApprove) throw new Error("Approve call failed."); ### **4\. Signing and Sending the Transaction**[​](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#4-signing-and-sending-the-transaction "Direct link to 4-signing-and-sending-the-transaction") Use the `sendTransaction` method to sign and send the transaction. const tx = await resApprove.sendTransaction({ signer: account.signer!, // OP_WALLET doesn't need a signer maximumAllowedSatToSpend: 100_000n, network: account.network, refundTo: account.addressTyped,});if (!tx.transactionId) throw new Error("Failed to send transaction");console.log("Transaction:", tx); **Full Example**[​](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#full-example "Direct link to full-example") -------------------------------------------------------------------------------------------------------------------------------------- import { IInteractionParameters, TransactionFactory,} from "@btc-vision/transaction";import { SupportedWallets, useWallet } from "@btc-vision/walletconnect";import { getContract, IOP_20Contract, OP_20_ABI } from "opnet";function BuildAnApproveTransaction() { const { account, connect, disconnect } = useWallet(); async function approveRandomToken() { if (!account) throw new Error("Connect wallet first"); const contractAddress = "opr1exampleaddress"; // Replace with a valid contract address const contractInstance = getContract( contractAddress, // Contract address OP_20_ABI, // Contract ABI provider: account.provider, // Provider instance network: account.network, // Target network address: account.address // Sender's address ); const resApprove = await contractInstance.approve(account.address, 100n); if (!resApprove) throw new Error("Approve call failed."); const tx = await resApprove.sendTransaction({ signer: account.signer!, // OP_WALLET doesn't need a signer maximumAllowedSatToSpend: 100_000n, network: account.network, refundTo: account.addressTyped, }); if (!tx.transactionId) throw new Error("Failed to send transaction"); console.log("Transaction:", tx); } return (
{account ? (

Connected Address: {account.addressTyped}

) : ( )}
);}export default BuildAnApproveTransaction; * * * **Best Practices**[​](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#best-practices "Direct link to best-practices") -------------------------------------------------------------------------------------------------------------------------------------------- * Always simulate the transaction before sending it to ensure it will succeed. * Use the `maximumAllowedSatToSpend` parameter to limit the amount of satoshis that can be spent in the transaction. * Monitor the transaction status after sending it to confirm its success or failure. * Handle errors gracefully to provide a better user experience. * Ensure you have the correct contract address and ABI to avoid transaction failures. * [**Steps to Send a Transaction**](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#steps-to-send-a-transaction) * [**1\. Get Required Parameters**](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#1-get-required-parameters) * [**2\. Define the Contract Instance**](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#2-define-the-contract-instance) * [**3\. Simulate the Transaction**](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#3-simulate-the-transaction) * [**4\. Signing and Sending the Transaction**](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#4-signing-and-sending-the-transaction) * [**Full Example**](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#full-example) * [**Best Practices**](https://docs.opnet.org/developers/walletconnect/sending-a-transaction#best-practices) --- # Handling Events and Logs | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/opnet-unit-test-framework/handling-events-and-logs#__docusaurus_skipToContent_fallback) On this page OP\_NET smart contracts emit events to notify external systems of important state changes. These events are recorded in the blockchain as logs, which can be accessed and processed by external applications. * * * **Coming Soon**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/handling-events-and-logs#coming-soon "Direct link to coming-soon") -------------------------------------------------------------------------------------------------------------------------------------------------- The WebSocket feature for listening to events directly from the OP\_NET network is not yet available. Alternative If you need to capture and handle events immediately, you will need to build your own indexer. This involves: * Scanning the blockchain for relevant transactions. * Decoding event data using the event decoders provided by your contracts. Stay tuned for updates as WebSocket support is introduced, simplifying event listening and real-time interactions. * [**Coming Soon**](https://docs.opnet.org/developers/opnet-unit-test-framework/handling-events-and-logs#coming-soon) --- # Advanced Testing Techniques | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#__docusaurus_skipToContent_fallback) On this page This guide covers advanced techniques for testing smart contracts on OP\_NET, including time progression simulation, error handling, and edge case testing. * * * **Simulating Time and Block Progression**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#simulating-time-and-block-progression "Direct link to simulating-time-and-block-progression") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Testing time-dependent logic is critical for contracts with features like expirations or time locks. * **Progressing Blocks**: Use `Blockchain.blockNumber` to simulate advancing the block number. * **Adjusting Timestamps**: Modify `Blockchain.medianTimestamp` to test time-sensitive contract logic. import { Blockchain } from "@btc-vision/unit-test-framework";Blockchain.blockNumber += 10n; // Simulate advancing 10 blocksBlockchain.medianTimestamp += 600n; // Simulate 10 minutes forward (600 seconds) ### **Use Case**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#use-case "Direct link to use-case") Testing time-based expirations: await vm.it("should expire after 10 minutes", async () => { Blockchain.medianTimestamp += 600n; // Simulate 10 minutes const isExpired = await contract.checkExpiration(); // Example function to check expiration Assert.expect(isExpired).toEqual(true);}); * * * **Testing Error Handling and Reverts**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#testing-error-handling-and-reverts "Direct link to testing-error-handling-and-reverts") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ensure that your contract behaves as expected when errors or invalid conditions occur. ### **Expecting Errors**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#expecting-errors "Direct link to expecting-errors") Use `Assert.expect().toThrow()` to test functions expected to throw an error or revert. await vm.it("should not mint invalid amount", async () => { const receiver = Blockchain.generateRandomAddress(); await Assert.expect(async () => { await contract.mint(receiver, 0.01); // Invalid mint amount }).toThrow();}); ### **Verifying Error Messages**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#verifying-error-messages "Direct link to verifying-error-messages") Validate specific revert reasons or error messages: await vm.it( "should not transfer tokens if the sender has insufficient balance", async () => { const sender = Blockchain.generateRandomAddress(); const receiver = Blockchain.generateRandomAddress(); await Assert.expect(async () => { await contract.transfer(sender, receiver, 100n); }).toThrow("Insufficient balance"); }); * * * **Testing Edge Cases and Boundary Conditions**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#testing-edge-cases-and-boundary-conditions "Direct link to testing-edge-cases-and-boundary-conditions") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Stress your contract logic by testing with extreme values and edge cases. ### **Stress Testing with Extreme Values**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#stress-testing-with-extreme-values "Direct link to stress-testing-with-extreme-values") Test the behavior of contracts under unusually high or low values. await vm.it("should handle maximum token supply", async () => { const receiver = Blockchain.generateRandomAddress(); const maxSupply = 1e8; await Assert.expect(async () => { await contract.mint(receiver, maxSupply); }).toNotThrow();}); ### **Underflow and Overflow Conditions**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#underflow-and-overflow-conditions "Direct link to underflow-and-overflow-conditions") Verify that the contract correctly handles arithmetic boundaries: await vm.it("should prevent underflow", async () => { await Assert.expect(async () => { await contract.burn(receiver, 1); // Burn more than balance }).toThrow("Insufficient balance");});await vm.it("should prevent overflow", async () => { const maxSupply = 1e8; await Assert.expect(async () => { await contract.mint(receiver, maxSupply + 1); // Mint more than the max supply }).toThrow("Max supply reached");}); * * * **Best Practices**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#best-practices "Direct link to best-practices") -------------------------------------------------------------------------------------------------------------------------------------------------------------- * Clearly describe the test scenario and expected outcomes. * Cover all possible execution paths, including edge cases and error conditions. * Use `Assert.expect().toThrow()` to verify error handling and reverts. * Simulate time progression and block advancement for time-sensitive logic. * [**Simulating Time and Block Progression**](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#simulating-time-and-block-progression) * [**Use Case**](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#use-case) * [**Testing Error Handling and Reverts**](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#testing-error-handling-and-reverts) * [**Expecting Errors**](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#expecting-errors) * [**Verifying Error Messages**](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#verifying-error-messages) * [**Testing Edge Cases and Boundary Conditions**](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#testing-edge-cases-and-boundary-conditions) * [**Stress Testing with Extreme Values**](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#stress-testing-with-extreme-values) * [**Underflow and Overflow Conditions**](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#underflow-and-overflow-conditions) * [**Best Practices**](https://docs.opnet.org/developers/opnet-unit-test-framework/advanced-testing-techniques#best-practices) --- # Deploying a Contract | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#__docusaurus_skipToContent_fallback) On this page Deploying a smart contract on OP\_NET using WalletConnect requires careful handling of UTXOs and constructing deployment parameters. This guide explains the process of using `walletWindowInstance` to sign and deploy contracts. Use OP\_WALLET Ensure you are using the OP\_WALLET for deploying a smart contract. The `walletWindowInstance` should be initialized with the OP\_WALLET provider to access the `web3` methods. const { walletWindowInstance } = useWallet();if (!walletWindowInstance.web3) { throw new Error("Web3 not found (use OP_WALLET)");} * * * **Steps to Deploy a Contract**[​](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#steps-to-deploy-a-contract "Direct link to steps-to-deploy-a-contract") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. Get Required Parameters**[​](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#1-get-required-parameters "Direct link to 1-get-required-parameters") Before deploying a contract, ensure you have the following parameters: * **`account`**: Wallet account for transaction signing. * **`walletWindowInstance`**: The instance of the wallet window for signing transactions. * **`connect`**: Function to connect to the wallet. * **`disconnect`**: Function to disconnect from the wallet. import { useWallet } from "@btc-vision/walletconnect";const { account, walletWindowInstance, connect, disconnect } = useWallet(); ### **2\. Obtaining Proper UTXOs**[​](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#2-obtaining-proper-utxos "Direct link to 2-obtaining-proper-utxos") Before building a transaction, you need to gather the required UTXOs for funding. Use the `utxoManager` from the `JSONRpcProvider` to fetch UTXOs associated with your address. const utxos = await account.provider.utxoManager.getUTXOs({ address: account.addressTyped,}); UTXO Management Ensure you have enough UTXOs to cover the transaction inputs, gas fees, and any additional outputs. Learn more about [**UTXO Manager**](https://docs.opnet.org/developers/using-the-utxo-manager/introduction) . ### **3\. Fetching Contract Bytecode**[​](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#3-fetching-contract-bytecode "Direct link to 3-fetching-contract-bytecode") Retrieve the contract bytecode (compiled contract code) to be deployed. You can read the bytecode from a compiled `.wasm` file or use the hex string directly. const bytecodeArrayBuffer = await fetch("contract.wasm").then((res) => res.arrayBuffer());// OR directly define the bytecode as a hex string// const bytecode = Buffer.from(`your-contract-bytecode`, "hex"); ### **4\. Constructing Deployment Parameters**[​](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#4-constructing-deployment-parameters "Direct link to 4-constructing-deployment-parameters") The `IDeploymentParametersWithoutSigner` interface defines the required parameters for contract deployment. Ensure you provide the contract bytecode, and other necessary details. const gasParameters = await provider.gasParameters();const deploymentParameters: IDeploymentParametersWithoutSigner = { from: account.addressTyped, bytecode: Buffer.from(bytecodeArrayBuffer), utxos: utxos, feeRate: gasParameters.bitcoin.recommended.medium, // <- use the result from provider.gasParameters() priorityFee: 0n, gasSatFee: gasParameters.gasPerSat,}; ### **5\. Signing the Deployment Transaction**[​](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#5-signing-the-deployment-transaction "Direct link to 5-signing-the-deployment-transaction") Use the `walletWindowInstance` to sign the deployment transaction. The `deployContract` method will handle the signing process and return a `DeploymentResult` object. const deploymentResult = await walletWindowInstance.web3.deployContract( deploymentParameters);if (!deploymentResult) throw new Error("Failed to deploy contract");console.log("Deployment Result:", deploymentResult); ### **6\. Broadcasting the Transaction**[​](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#6-broadcasting-the-transaction "Direct link to 6-broadcasting-the-transaction") After signing the deployment transaction, you can broadcast it to the network using the `sendRawTransactions` method. This step finalizes the contract deployment process. const transactionReceipt = await account.provider.sendRawTransactions( deploymentResult.transaction);const txId = transactionReceipt[1].result;console.log("Deploy Transaction:", txId);console.log("Contract Address:", deploymentResult.contractPubKey); * * * **Object Definitions**[​](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#object-definitions "Direct link to object-definitions") ------------------------------------------------------------------------------------------------------------------------------------------------------- `DeploymentResult` Object | **Property** | **Type** | **Description** | | --- | --- | --- | | **`transaction`** | `string` | Array of raw transaction strings. | | **`contractAddress`** | `string` | Contract's P2OP address. | | **`contractPubKey`** | `string` | Contract's tweaked public key. | | **`p2opAddress`** | `string` | Contract's P2OP address. | | **`utxos`** | `UTXO[]` | Array of new UTXOs after deployment. | * * * **Full Example**[​](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#full-example "Direct link to full-example") ------------------------------------------------------------------------------------------------------------------------------------- import { IDeploymentParametersWithoutSigner } from "@btc-vision/transaction";import { SupportedWallets, useWallet } from "@btc-vision/walletconnect";function DeployContract() { const { account, walletWindowInstance, connect, disconnect } = useWallet(); async function deployContract() { if (!account || !walletWindowInstance) throw new Error("Connect wallet first"); if (!walletWindowInstance.web3) throw new Error("Web3 not found (use OP_WALLET)"); const utxos = await account.provider.utxoManager.getUTXOs({ address: account.addressTyped, }); const bytecodeArrayBuffer = await fetch("contract.wasm").then((res) => res.arrayBuffer() ); const gasParameters = await provider.gasParameters(); const deploymentParameters: IDeploymentParametersWithoutSigner = { from: account.addressTyped, bytecode: Buffer.from(bytecodeArrayBuffer), utxos: utxos, feeRate: gasParameters.bitcoin.recommended.medium, priorityFee: 0n, gasSatFee: gasParameters.gasPerSat, }; const deploymentResult = await walletWindowInstance.web3.deployContract( deploymentParameters ); if (!deploymentResult) throw new Error("Failed to deploy contract"); console.log("Deployment Result:", deploymentResult); const transactionReceipt = await account.provider.sendRawTransactions( deploymentResult.transaction ); const txId = transactionReceipt[1].result; console.log("Deploy Transaction:", txId); console.log("Contract Address:", deploymentResult.contractPubKey); } return (
{account ? (

Connected Address: {account.addressTyped}

) : ( )}
);}export default DeployContract; * * * **Best Practices**[​](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#best-practices "Direct link to best-practices") ------------------------------------------------------------------------------------------------------------------------------------------- * Ensure your wallet has sufficient UTXOs to fund the deployment and associated fees. * Adjust the `feeRate` and `priorityFee` parameters based on current network conditions to minimize costs. * Before deploying on mainnet, test your contract deployment process on regtest or testnet to avoid unnecessary costs. * [**Steps to Deploy a Contract**](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#steps-to-deploy-a-contract) * [**1\. Get Required Parameters**](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#1-get-required-parameters) * [**2\. Obtaining Proper UTXOs**](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#2-obtaining-proper-utxos) * [**3\. Fetching Contract Bytecode**](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#3-fetching-contract-bytecode) * [**4\. Constructing Deployment Parameters**](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#4-constructing-deployment-parameters) * [**5\. Signing the Deployment Transaction**](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#5-signing-the-deployment-transaction) * [**6\. Broadcasting the Transaction**](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#6-broadcasting-the-transaction) * [**Object Definitions**](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#object-definitions) * [**Full Example**](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#full-example) * [**Best Practices**](https://docs.opnet.org/developers/walletconnect/deploying-a-contract#best-practices) --- # Common Testing Scenarios | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#__docusaurus_skipToContent_fallback) On this page This guide highlights key testing scenarios for OP\_NET smart contracts, including token transfers, access control, and inter-contract communication. These tests ensure your contracts function correctly in common use cases. * * * **Testing Token Transfers and Balances**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#testing-token-transfers-and-balances "Direct link to testing-token-transfers-and-balances") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Validating Transfers**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#validating-transfers "Direct link to validating-transfers") Ensure tokens are transferred correctly between accounts: await vm.it("should transfer tokens correctly", async () => { const sender = Blockchain.generateRandomAddress(); const receiver = Blockchain.generateRandomAddress(); const amount = 100; await token.mint(sender, amount); // Mint tokens to sender await token.transfer(sender, receiver, BigInt(amount * 10 ** 18)); // Transfer tokens from sender to receiver const senderBalance = await token.balanceOf(sender); const receiverBalance = await token.balanceOf(receiver); Assert.expect(senderBalance).toEqual(0n); Assert.expect(receiverBalance).toEqual(BigInt(amount * 10 ** 18));}); ### **Testing Transfer Restrictions**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#testing-transfer-restrictions "Direct link to testing-transfer-restrictions") Validate that invalid transfers are restricted: await vm.it("should not allow transfer exceeding balance", async () => { const sender = Blockchain.generateRandomAddress(); const receiver = Blockchain.generateRandomAddress(); await Assert.expect(async () => { await token.transfer(sender, receiver, 100n); // Exceeds sender's balance }).toThrow("Insufficient balance");}); * * * **Testing Access Control and Permissions**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#testing-access-control-and-permissions "Direct link to testing-access-control-and-permissions") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ensure that only authorized users can perform certain actions: await vm.it("should allow only the owner to mint tokens", async () => { const receiver = Blockchain.generateRandomAddress(); await Assert.expect(async () => { await token.mint(receiver, 100); // Authorized sender }).toNotThrow(); const unauthorizedAddress = Blockchain.generateRandomAddress(); Blockchain.msgSender = unauthorizedAddress; // Change the sender to an unauthorized address Blockchain.txOrigin = unauthorizedAddress; // Change the txOrigin to an unauthorized address await Assert.expect(async () => { await token.mint(receiver, 100); // Unauthorized sender }).toThrow("Caller is not the owner");}); ### **Testing Permissioned Transfers**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#testing-permissioned-transfers "Direct link to testing-permissioned-transfers") Validate access control on specific operations: await vm.it("should prevent unauthorized transfers", async () => { const sender = Blockchain.generateRandomAddress(); const receiver = Blockchain.generateRandomAddress(); await Assert.expect(async () => { await token.mint(sender, 100); }).toNotThrow(); Blockchain.msgSender = Blockchain.generateRandomAddress(); // Change the sender to an unauthorized address Blockchain.txOrigin = Blockchain.generateRandomAddress(); // Change the txOrigin to an unauthorized address await Assert.expect(async () => { await token.transfer(sender, receiver, 100n); }).toThrow("Unauthorized transfer");}); * * * **Testing Inter-Contract Communication (In-Progress)**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#testing-inter-contract-communication-in-progress "Direct link to testing-inter-contract-communication-in-progress") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Inter-contract interactions require robust testing. While some features are in progress, here’s how you can prepare for future scenarios: ### **Mocking External Contract Calls (In-Progress)**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#mocking-external-contract-calls-in-progress "Direct link to mocking-external-contract-calls-in-progress") Simulate external contract interactions by mocking their responses. COMING SOON Detailed examples once OP\_NET's mocking features are finalized. ### **Verifying Cross-Contract Interactions (In-Progress)**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#verifying-cross-contract-interactions-in-progress "Direct link to verifying-cross-contract-interactions-in-progress") Ensure that contracts interact correctly with others by verifying calldata and responses. COMING SOON Additional tools for cross-contract testing. * [**Testing Token Transfers and Balances**](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#testing-token-transfers-and-balances) * [**Validating Transfers**](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#validating-transfers) * [**Testing Transfer Restrictions**](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#testing-transfer-restrictions) * [**Testing Access Control and Permissions**](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#testing-access-control-and-permissions) * [**Testing Permissioned Transfers**](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#testing-permissioned-transfers) * [**Testing Inter-Contract Communication (In-Progress)**](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#testing-inter-contract-communication-in-progress) * [**Mocking External Contract Calls (In-Progress)**](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#mocking-external-contract-calls-in-progress) * [**Verifying Cross-Contract Interactions (In-Progress)**](https://docs.opnet.org/developers/opnet-unit-test-framework/common-testing-scenarios#verifying-cross-contract-interactions-in-progress) --- # Interacting with the Blockchain in Tests | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#__docusaurus_skipToContent_fallback) On this page The OP\_NET Unit Test Framework provides a `Blockchain` class that allows developers to simulate and manipulate the blockchain environment for testing purposes. This guide covers key functionalities, including setting block numbers, simulating transactions, and working with accounts. * * * **Using the `Blockchain` Class in Tests**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#using-the-blockchain-class-in-tests "Direct link to using-the-blockchain-class-in-tests") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The `Blockchain` class is central to managing blockchain interactions during tests. It enables you to set up blocks, transactions, and accounts dynamically. ### **Setting and Manipulating `Blockchain.blockNumber`**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#setting-and-manipulating-blockchainblocknumber "Direct link to setting-and-manipulating-blockchainblocknumber") You can directly manipulate the block number to simulate changes in blockchain state. import { Blockchain } from "@btc-vision/unit-test-framework";Blockchain.blockNumber = 1234n; // Set the block numberBlockchain.log(`Current Block Number: ${Blockchain.blockNumber}`); * * * **Manipulating Transactions and Blocks**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#manipulating-transactions-and-blocks "Direct link to manipulating-transactions-and-blocks") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Simulating Transactions**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#simulating-transactions "Direct link to simulating-transactions") You can assign a custom transaction object to `Blockchain.transaction` to simulate a transaction. import { Transaction } from "@btc-vision/transaction";import { Blockchain } from "@btc-vision/unit-test-framework";const customTransaction = new Transaction( ..., // uint8Array format (txId) [ // inputs { outputIndex: ..., // number format (index) scriptSig: ..., // Uint8Array format (script) txId: ..., // Uint8Array format (txId) }, ], [ // outputs { index: ..., // number format (index) to: ..., // string format (address) value: ..., // bigint format (value) }, ]);Blockchain.transaction = customTransaction;Blockchain.log(`Transaction ID: ${Blockchain.transaction.id}`); ### **Simulating Accounts**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#simulating-accounts "Direct link to simulating-accounts") #### **Generating Random Addresses**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#generating-random-addresses "Direct link to generating-random-addresses") Use the `Blockchain.generateRandomAddress` method to create random addresses for testing purposes. const randomAddress = Blockchain.generateRandomAddress();Blockchain.log(`Generated Random Address: ${randomAddress}`); #### **Setting `Blockchain.msgSender` and `Blockchain.txOrigin`**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#setting-blockchainmsgsender-and-blockchaintxorigin "Direct link to setting-blockchainmsgsender-and-blockchaintxorigin") You can define the sender (`msgSender`) and origin (`txOrigin`) of a transaction to simulate contract calls. Blockchain.msgSender = Blockchain.generateRandomAddress();Blockchain.txOrigin = Blockchain.generateRandomAddress();Blockchain.log(`Message Sender: ${Blockchain.msgSender}`);Blockchain.log(`Transaction Origin: ${Blockchain.txOrigin}`); * * * **Example Test: Simulating Blockchain Interactions**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#example-test-simulating-blockchain-interactions "Direct link to example-test-simulating-blockchain-interactions") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- import { Assert, Blockchain, opnet, OPNetUnit,} from "@btc-vision/unit-test-framework";await opnet("Blockchain Simulation Test Suite", async (vm: OPNetUnit) => { await vm.beforeAll(() => { Blockchain.blockNumber = 1n; // Initialize block number }); await vm.it("should simulate transaction and account states", () => { // Simulate sender and origin Blockchain.msgSender = Blockchain.generateRandomAddress(); Blockchain.txOrigin = Blockchain.generateRandomAddress(); // Set and verify block number Blockchain.blockNumber = 1234n; Assert.expect(Blockchain.blockNumber).toEqual(1234n); // Generate and verify random address const randomAddress = Blockchain.generateRandomAddress(); Assert.expect(randomAddress).toNotEqual(Blockchain.msgSender); Blockchain.log("Blockchain interactions simulated successfully."); });}); * * * **Best Practices**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Use `vm.beforeEach` and `vm.afterEach` to ensure blockchain states are reset between tests. * Leverage `Blockchain.log` to debug interactions during test execution. * Use assertions to confirm the expected behavior of simulated blockchain interactions. * [**Using the `Blockchain` Class in Tests**](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#using-the-blockchain-class-in-tests) * [**Setting and Manipulating `Blockchain.blockNumber`**](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#setting-and-manipulating-blockchainblocknumber) * [**Manipulating Transactions and Blocks**](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#manipulating-transactions-and-blocks) * [**Simulating Transactions**](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#simulating-transactions) * [**Simulating Accounts**](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#simulating-accounts) * [**Example Test: Simulating Blockchain Interactions**](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#example-test-simulating-blockchain-interactions) * [**Best Practices**](https://docs.opnet.org/developers/opnet-unit-test-framework/interacting-with-the-blockchain-in-tests#best-practices) --- # Writing Unit Tests | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#__docusaurus_skipToContent_fallback) On this page Unit testing is an essential part of developing smart contracts on OP\_NET. This guide covers the structure of a test file, key components of the OP\_NET Unit Test Framework, and best practices for writing effective tests. * * * **Basic Structure of a Test File**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#basic-structure-of-a-test-file "Direct link to basic-structure-of-a-test-file") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Importing Required Modules and Contracts**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#importing-required-modules-and-contracts "Direct link to importing-required-modules-and-contracts") Every test file starts by importing the necessary modules and contracts. import { Address } from "@btc-vision/transaction";import { Assert, Blockchain, OP_20, opnet, OPNetUnit,} from "@btc-vision/unit-test-framework"; ### **Using the `opnet` Function for Test Suites**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#using-the-opnet-function-for-test-suites "Direct link to using-the-opnet-function-for-test-suites") The `opnet` function defines the test suite, and each test case is specified within it. await opnet("Test Suite Name", async (vm: OPNetUnit) => { // Define your tests here}); ### **Defining Test Cases with `vm.it`**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#defining-test-cases-with-vmit "Direct link to defining-test-cases-with-vmit") Each test case is written using `vm.it`. await vm.it("should perform a specific action", async () => { // Test logic here const value = true; Assert.expect(value).toEqual(true);}); * * * **Test Lifecycle Hooks**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#test-lifecycle-hooks "Direct link to test-lifecycle-hooks") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Setup with `vm.beforeEach` and `vm.afterEach`**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#setup-with-vmbeforeeach-and-vmaftereach "Direct link to setup-with-vmbeforeeach-and-vmaftereach") Use `vm.beforeEach` and `vm.afterEach` to set up and clean up resources for each test. vm.beforeEach(async () => { await Blockchain.init();});vm.afterEach(() => { Blockchain.dispose();}); ### **Initializing and Disposing Resources**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#initializing-and-disposing-resources "Direct link to initializing-and-disposing-resources") For reusable components, initialize them in `vm.beforeAll` and dispose of them in `vm.afterAll`. await vm.beforeAll(async () => { await Blockchain.init();});vm.afterAll(() => { Blockchain.dispose();}); * * * **Asynchronous Testing**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#asynchronous-testing "Direct link to asynchronous-testing") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Using `async/await` in Tests**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#using-asyncawait-in-tests "Direct link to using-asyncawait-in-tests") All tests support asynchronous operations. Use `async/await` for clarity and to handle promises. await vm.it("should execute asynchronously", async () => { const result = await Promise.resolve(true); Assert.expect(result).toEqual(true);}); ### **Handling Promises and Callbacks**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#handling-promises-and-callbacks "Direct link to handling-promises-and-callbacks") For more complex cases, ensure all promises are handled properly. await Assert.expect(async () => { await someAsyncFunction();}).toNotThrow(); * * * **Assertions**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#assertions "Direct link to assertions") ----------------------------------------------------------------------------------------------------------------------------------------- ### **Using the `Assert` Module**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#using-the-assert-module "Direct link to using-the-assert-module") The `Assert` module provides methods to validate conditions in your tests. ### **Common Assertion Methods**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#common-assertion-methods "Direct link to common-assertion-methods") * **`toEqual`**: Compare values for equality. * **`toBe`**: Validate truthy or falsy values. * **`toThrow`**: Check for exceptions. * **`toNotThrow`**: Ensure no exceptions are thrown. const value = 10;Assert.expect(value).toEqual(10);await Assert.expect(async () => { const result = await Promise.resolve("success"); if (!result) throw new Error("Failure");}).toNotThrow(); * [**Basic Structure of a Test File**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#basic-structure-of-a-test-file) * [**Importing Required Modules and Contracts**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#importing-required-modules-and-contracts) * [**Using the `opnet` Function for Test Suites**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#using-the-opnet-function-for-test-suites) * [**Defining Test Cases with `vm.it`**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#defining-test-cases-with-vmit) * [**Test Lifecycle Hooks**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#test-lifecycle-hooks) * [**Setup with `vm.beforeEach` and `vm.afterEach`**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#setup-with-vmbeforeeach-and-vmaftereach) * [**Initializing and Disposing Resources**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#initializing-and-disposing-resources) * [**Asynchronous Testing**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#asynchronous-testing) * [**Using `async/await` in Tests**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#using-asyncawait-in-tests) * [**Handling Promises and Callbacks**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#handling-promises-and-callbacks) * [**Assertions**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#assertions) * [**Using the `Assert` Module**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#using-the-assert-module) * [**Common Assertion Methods**](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests#common-assertion-methods) --- # Setting Up WalletConnect | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/walletconnect/setup#__docusaurus_skipToContent_fallback) On this page This guide explains how to set up WalletConnect in your project and integrate it seamlessly with OP\_NET. Follow these steps to get started. * * * **Step 1: Set Up Your Environment**[​](https://docs.opnet.org/developers/walletconnect/setup#step-1-set-up-your-environment "Direct link to step-1-set-up-your-environment") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Before proceeding, ensure your environment is configured for your framework of choice. Refer to the following guides for detailed instructions: * [Setting Up for React](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-react) * [Setting Up for Next.js](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nextjs) These guides cover how to set up your environment, including installing the required dependencies and configuring your project. * * * **Step 2: Install WalletConnect**[​](https://docs.opnet.org/developers/walletconnect/setup#step-2-install-walletconnect "Direct link to step-2-install-walletconnect") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- If you haven’t installed the `@btc-vision/walletconnect` package yet, do so now: npm install @btc-vision/walletconnect This package provides all the tools necessary for integrating WalletConnect into your project. * * * **Step 3: Add the ``**[​](https://docs.opnet.org/developers/walletconnect/setup#step-3-add-the-walletprovider "Direct link to step-3-add-the-walletprovider") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ The `WalletProvider` is a context provider that wraps your application and makes wallet-related functionalities available throughout your app. ### **React Example**[​](https://docs.opnet.org/developers/walletconnect/setup#react-example "Direct link to react-example") In your `main.tsx`: import { WalletProvider } from "@btc-vision/walletconnect";createRoot(document.getElementById("root")!).render( {/* Add the WalletProvider here */} ); ### **Next.js Example**[​](https://docs.opnet.org/developers/walletconnect/setup#nextjs-example "Direct link to nextjs-example") In your `layout.tsx`: import { WalletProvider } from "@btc-vision/walletconnect";export default function Layout({ children }) { return ( {/* Add the WalletProvider here */}
{children}
);} * * * **Step 4: Use WalletConnect in Your Application**[​](https://docs.opnet.org/developers/walletconnect/setup#step-4-use-walletconnect-in-your-application "Direct link to step-4-use-walletconnect-in-your-application") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Once the `WalletProvider` is set up, you can access wallet-related functionalities using the `useWallet` hook. ### **Example**[​](https://docs.opnet.org/developers/walletconnect/setup#example "Direct link to example") import { SupportedWallets, useWallet } from "@btc-vision/walletconnect";function WalletStatus() { const { account, connect, disconnect } = useWallet(); return (
{account ? (

Connected Address: {account.addressTyped}

) : ( )}
);}export default WalletStatus; This example demonstrates how to use the `useWallet` hook to access the wallet's state, initiate connections, and disconnect from the wallet. * * * With these steps, your application is now ready to use WalletConnect to interact with OP\_NET. For further details, refer to the [WalletConnect Documentation](https://docs.opnet.org/developers/walletconnect/introduction) . * [**Step 1: Set Up Your Environment**](https://docs.opnet.org/developers/walletconnect/setup#step-1-set-up-your-environment) * [**Step 2: Install WalletConnect**](https://docs.opnet.org/developers/walletconnect/setup#step-2-install-walletconnect) * [**Step 3: Add the ``**](https://docs.opnet.org/developers/walletconnect/setup#step-3-add-the-walletprovider) * [**React Example**](https://docs.opnet.org/developers/walletconnect/setup#react-example) * [**Next.js Example**](https://docs.opnet.org/developers/walletconnect/setup#nextjs-example) * [**Step 4: Use WalletConnect in Your Application**](https://docs.opnet.org/developers/walletconnect/setup#step-4-use-walletconnect-in-your-application) * [**Example**](https://docs.opnet.org/developers/walletconnect/setup#example) --- # Introduction | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/opnet-unit-test-framework/introduction#__docusaurus_skipToContent_fallback) On this page Unit testing is an essential part of the smart contract development lifecycle. It ensures that your contracts behave as expected, are secure, and maintain reliability over time. The OP\_NET Unit Test Framework provides a structured environment to create and run tests for OP\_NET smart contracts, enabling developers to validate their code effectively. Key Benefits of Unit Testing * **Validate Functionality:** Verify that each function performs as intended. * **Enhance Security:** Detect potential vulnerabilities early in the development process. * **Ensure Reliability:** Build confidence in your code by testing edge cases and unexpected inputs. * **Simplify Maintenance:** Facilitate future updates by catching regressions introduced by new changes. * * * **Overview of the OP\_NET Unit Test Framework**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/introduction#overview-of-the-op_net-unit-test-framework "Direct link to overview-of-the-op_net-unit-test-framework") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ The OP\_NET Unit Test Framework is specifically designed to streamline the development and testing of smart contracts within the OP\_NET ecosystem. It provides: * **Comprehensive Tools**: Utilities and modules tailored for OP\_NET smart contracts. * **Structured Environment**: A well-organized framework to manage and execute test cases efficiently. * **Developer-Friendly Setup**: Easy-to-use features that make testing straightforward and productive. ### **Repository**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/introduction#repository "Direct link to repository") Explore the full framework and get started with unit testing: [**OP\_NET Unit Test Framework Repository**](https://github.com/btc-vision/unit-test-framework/) * * * **Features**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/introduction#features "Direct link to features") ----------------------------------------------------------------------------------------------------------------------------- * **Custom Testing Environment**: A tailored environment to simulate and test OP\_NET-specific scenarios. * **Test Case Management**: Define and organize test cases with clear setups (`beforeEach`) and cleanups (`afterEach`). * **Assertion Library**: Built-in assertion tools to validate contract behavior against expected outcomes. * **Seamless Integration**: Fully compatible with the OP\_NET runtime and development tools. * * * **Next Steps**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/introduction#next-steps "Direct link to next-steps") ----------------------------------------------------------------------------------------------------------------------------------- * Get started with the OP\_NET Unit Test Framework by [setting up the unit test environment](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment) . * Learn how to [write your first test case](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests) . * Explore example contracts and test cases in the [unit test framework repository](https://github.com/btc-vision/unit-test-framework/) . * [**Overview of the OP\_NET Unit Test Framework**](https://docs.opnet.org/developers/opnet-unit-test-framework/introduction#overview-of-the-op_net-unit-test-framework) * [**Repository**](https://docs.opnet.org/developers/opnet-unit-test-framework/introduction#repository) * [**Features**](https://docs.opnet.org/developers/opnet-unit-test-framework/introduction#features) * [**Next Steps**](https://docs.opnet.org/developers/opnet-unit-test-framework/introduction#next-steps) --- # Setting Up the Unit Test Environment | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#__docusaurus_skipToContent_fallback) On this page To streamline your OP\_NET smart contract development and testing workflow, you can use a pre-configured template. This template simplifies the setup process, offering pre-configured scripts, commands, and examples tailored to OP\_NET contracts. * * * **Step 1: Clone the Template**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#step-1-clone-the-template "Direct link to step-1-clone-the-template") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Start with the official [OP\_NET Starter Template](https://github.com/memoriesadrift/opnet-starter-template) , which includes all necessary configurations, dependencies, and example contracts. Clone the repository using the following commands: git clone https://github.com/memoriesadrift/opnet-starter-templatecd opnet-starter-template * * * **Step 2: Install Dependencies**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#step-2-install-dependencies "Direct link to step-2-install-dependencies") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- After cloning the repository, install the required dependencies: npm install warning Ensure that you have all the prerequisites installed on your system. For more information, refer to the [Prerequisites](https://docs.opnet.org/developers/getting-started/prerequisites) guide. * * * **Step 3: Using the Template**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#step-3-using-the-template "Direct link to step-3-using-the-template") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Compile Contracts**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#compile-contracts "Direct link to compile-contracts") To compile the contracts provided in the template: make compile ### **Run Unit Tests**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#run-unit-tests "Direct link to run-unit-tests") To execute all unit tests: make test To run a specific test file: make test-only name= Example: make test-only name=vesting ### **Clean the Project**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#clean-the-project "Direct link to clean-the-project") To remove build artifacts and reset the environment: make clean * * * **Project Structure**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#project-structure "Direct link to project-structure") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- This template follows a well-organized structure for managing contracts, tests, and compiled bytecode: opnet-starter-template/├── src/│ ├── vesting/ # Example contract folder├── __test__/ # Test files│ ├── unit/│ │ ├── contracts/ # Contract interfaces│ │ ├── tests/ # Unit test files├── build/ # Compiled contract bytecode├── lib/│ ├── bytecode/ # Bytecode of external dependencies├── Makefile # Build and testing automation├── package.json # Project metadata and dependencies * * * **Heuristics for Automation**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#heuristics-for-automation "Direct link to heuristics-for-automation") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Contract Heuristics**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#contract-heuristics "Direct link to contract-heuristics") * Contracts are defined in the `src/` directory, with a `Blockchain.contract` reference in the `index.ts` file. * Each contract is compiled into a `.wasm` file using the directory's name. For example, `src/vesting/index.ts` compiles to `build/vesting.wasm`. ### **Test Heuristics**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#test-heuristics "Direct link to test-heuristics") * Unit test files are located in the `__test__/unit/tests/` directory. * For running specific tests, provide the file name without the extension. For example: make test-only name=vesting * * * **Integration Testing**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#integration-testing "Direct link to integration-testing") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Integration testing is included with basic examples to interact with deployed contracts. Set up environment variables according to the `.env.template` file provided in the repository. Run integration tests using: make interact * * * **Next Steps**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#next-steps "Direct link to next-steps") ----------------------------------------------------------------------------------------------------------------------------------------------------------- Once your environment is set up, you can begin writing and running your unit tests. For details on how to write test files, refer to the [Writing Unit Tests](https://docs.opnet.org/developers/opnet-unit-test-framework/writing-unit-tests) guide. * [**Step 1: Clone the Template**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#step-1-clone-the-template) * [**Step 2: Install Dependencies**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#step-2-install-dependencies) * [**Step 3: Using the Template**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#step-3-using-the-template) * [**Compile Contracts**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#compile-contracts) * [**Run Unit Tests**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#run-unit-tests) * [**Clean the Project**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#clean-the-project) * [**Project Structure**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#project-structure) * [**Heuristics for Automation**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#heuristics-for-automation) * [**Contract Heuristics**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#contract-heuristics) * [**Test Heuristics**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#test-heuristics) * [**Integration Testing**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#integration-testing) * [**Next Steps**](https://docs.opnet.org/developers/opnet-unit-test-framework/setting-up-the-unit-test-environment#next-steps) --- # Testing Smart Contracts | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#__docusaurus_skipToContent_fallback) On this page This guide explains how to effectively test smart contracts on OP\_NET using the Unit Test Framework. It covers deploying contracts, interacting with them, and verifying their state changes. * * * **Deploying Contracts in Tests**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#deploying-contracts-in-tests "Direct link to deploying-contracts-in-tests") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. Instantiating Contract Instances**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#1-instantiating-contract-instances "Direct link to 1-instantiating-contract-instances") Create a contract instance and configure it with its deployment parameters. import { OP_20 } from "@btc-vision/unit-test-framework";const contract = new OP_20({ file: "MyToken", // Contract file name (it should be in the bytecode folder as MyToken.wasm for example) deployer: Blockchain.generateRandomAddress(), // Deployer address address: Blockchain.generateRandomAddress(), // Contract address decimals: 18, // Number of decimals gasLimit: 100_000_000_000n, // (Optional) Gas limit, default is 100_000_000_000n}); * * * ### **2\. Registering Contracts with the Blockchain**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#2-registering-contracts-with-the-blockchain "Direct link to 2-registering-contracts-with-the-blockchain") Register the contract instance with the blockchain using `Blockchain.register`. import { Blockchain } from "@btc-vision/unit-test-framework";Blockchain.register(contract); // Register the contract with the blockchain * * * ### **3\. Initializing Contracts with Parameters (Calldata)**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#3-initializing-contracts-with-parameters-calldata "Direct link to 3-initializing-contracts-with-parameters-calldata") You can initialize contracts with specific parameters, typically passed as calldata. await contract.init(); // Initialize contractawait contract.deployContract(); // Deploy the contract on the blockchain * * * **Interacting with Contracts**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#interacting-with-contracts "Direct link to interacting-with-contracts") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. Calling Contract Methods**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#1-calling-contract-methods "Direct link to 1-calling-contract-methods") Call contract methods by invoking the respective functions on the contract instance. const receiverAddress = Blockchain.generateRandomAddress();await contract.mint(receiverAddress, 1000); // Mint tokens to a specific address * * * ### **2\. Passing Parameters and Handling Return Values**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#2-passing-parameters-and-handling-return-values "Direct link to 2-passing-parameters-and-handling-return-values") Pass arguments to contract methods and handle the return values. const balance = await contract.balanceOf(receiverAddress);Blockchain.log(`Balance: ${balance}`); * * * **Testing Contract State Changes**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#testing-contract-state-changes "Direct link to testing-contract-state-changes") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. Verifying Storage Changes and State Variables**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#1-verifying-storage-changes-and-state-variables "Direct link to 1-verifying-storage-changes-and-state-variables") Ensure that the contract's state changes as expected after a method call. const testAddress = Blockchain.generateRandomAddress();await contract.mint(testAddress, 1000);const newBalance = await contract.balanceOfNoDecimals(testAddress);Assert.expect(newBalance).toEqual(1000); // Verify the balance was updated * * * **Example Test: Deploying and Interacting with a Contract**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#example-test-deploying-and-interacting-with-a-contract "Direct link to example-test-deploying-and-interacting-with-a-contract") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- import { Address } from "@btc-vision/transaction";import { Assert, Blockchain, OP_20, opnet, OPNetUnit,} from "@btc-vision/unit-test-framework";const rndAddress = Blockchain.generateRandomAddress();const receiver: Address = Blockchain.generateRandomAddress();await opnet("Contract Interaction Tests", async (vm: OPNetUnit) => { Blockchain.msgSender = receiver; Blockchain.txOrigin = receiver; vm.beforeEach(async () => { await Blockchain.init(); }); vm.afterAll(() => { Blockchain.dispose(); }); const contract = new OP_20({ file: "MyToken", deployer: Blockchain.txOrigin, address: rndAddress, decimals: 18, gasLimit: 100_000_000_000n, }); Blockchain.register(contract); await vm.it("should mint tokens and update balance", async () => { const testAddress = Blockchain.generateRandomAddress(); await contract.mint(testAddress, 1000); const balance = await contract.balanceOfNoDecimals(testAddress); Assert.expect(balance).toEqual(1000); });}); * * * **Best Practices**[​](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#best-practices "Direct link to best-practices") ---------------------------------------------------------------------------------------------------------------------------------------------------------- * Utilize `vm.beforeEach` and `vm.afterEach` to reset states between tests. * Use `Blockchain.log` to track contract interactions during tests. * Use assertions to verify storage and state changes after each operation. * [**Deploying Contracts in Tests**](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#deploying-contracts-in-tests) * [**1\. Instantiating Contract Instances**](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#1-instantiating-contract-instances) * [**2\. Registering Contracts with the Blockchain**](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#2-registering-contracts-with-the-blockchain) * [**3\. Initializing Contracts with Parameters (Calldata)**](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#3-initializing-contracts-with-parameters-calldata) * [**Interacting with Contracts**](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#interacting-with-contracts) * [**1\. Calling Contract Methods**](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#1-calling-contract-methods) * [**2\. Passing Parameters and Handling Return Values**](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#2-passing-parameters-and-handling-return-values) * [**Testing Contract State Changes**](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#testing-contract-state-changes) * [**1\. Verifying Storage Changes and State Variables**](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#1-verifying-storage-changes-and-state-variables) * [**Example Test: Deploying and Interacting with a Contract**](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#example-test-deploying-and-interacting-with-a-contract) * [**Best Practices**](https://docs.opnet.org/developers/opnet-unit-test-framework/testing-smart-contracts#best-practices) --- # Calling Another Contract | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/smart-contract-development/calling-another-contract#__docusaurus_skipToContent_fallback) On this page The `call` method allows one contract to interact with another contract by sending calldata to it. * * * **Method**[​](https://docs.opnet.org/developers/smart-contract-development/calling-another-contract#method "Direct link to method") ------------------------------------------------------------------------------------------------------------------------------------ call(destinationContract: Address, calldata: BytesWriter): BytesReader * **Parameters**: * `destinationContract`: The address of the contract you want to call. * `calldata`: The data to send to the destination contract, formatted using `BytesWriter`. * **Returns**: * `BytesReader`: The response from the destination contract, which can be parsed as needed. * * * **Example Usage**[​](https://docs.opnet.org/developers/smart-contract-development/calling-another-contract#example-usage "Direct link to example-usage") --------------------------------------------------------------------------------------------------------------------------------------------------------- import { Address, BytesWriter, Blockchain,} from "@btc-vision/btc-runtime/runtime";import { u256 } from 'as-bignum/assembly';// Define the destination contract addresslet destination: Address = Address.fromString(...);// Create calldatalet calldata = new BytesWriter(64); // 64 is the length in bytes of the calldatacalldata.writeString("methodName");calldata.writeU256(u256.from(1234)); // Example of adding additional method parameters// Execute the calllet response = Blockchain.call(destination, calldata);// Log the responseBlockchain.log(`Response: ${response}`); * * * **Best Practices**[​](https://docs.opnet.org/developers/smart-contract-development/calling-another-contract#best-practices "Direct link to best-practices") ------------------------------------------------------------------------------------------------------------------------------------------------------------ * The `calldata` must be formatted correctly to match the expected input of the destination contract. * Ensure that the destination contract is deployed and the address is valid. * Always parse the `BytesReader` response correctly to extract meaningful data. * Errors during the call may not directly throw exceptions but could result in an empty or unexpected response. * [**Method**](https://docs.opnet.org/developers/smart-contract-development/calling-another-contract#method) * [**Example Usage**](https://docs.opnet.org/developers/smart-contract-development/calling-another-contract#example-usage) * [**Best Practices**](https://docs.opnet.org/developers/smart-contract-development/calling-another-contract#best-practices) --- # Setting Up the Template for Your OP_NET Contract | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/setting-up-the-template#__docusaurus_skipToContent_fallback) On this page This guide explains how to set up a custom OP\_NET contract by forking the **OP\_20 template** as a base for your smart contract development. The **OP\_20** template already includes a sample implementation of a token contract, making it an ideal starting point for customization. * * * **Step 1: Forking the OP\_20 Template**[​](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/setting-up-the-template#step-1-forking-the-op_20-template "Direct link to step-1-forking-the-op_20-template") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1. **Visit the Repository**: Navigate to the official OP\_20 GitHub repository: [https://github.com/btc-vision/OP\_20](https://github.com/btc-vision/OP_20) 2. **Fork the Repository**: Click the "Fork" button on GitHub to create a copy of the OP\_20 repository in your account. 3. **Clone Your Fork**: Clone your forked repository to your local machine: git clone https://github.com/your-username/OP_20.gitcd OP_20 4. **Install Dependencies**: Run the following command to install all necessary dependencies: npm install * * * **Step 2: Locate the Sample Contract**[​](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/setting-up-the-template#step-2-locate-the-sample-contract "Direct link to step-2-locate-the-sample-contract") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ After setting up the repository, you can find the sample token contract in the following file: src/contracts/MyToken.ts This contract provides a solid base with the following functionalities: * Token deployment with customizable name, symbol, decimals, and maximum supply. * Built-in minting and airdrop methods. * Ready-to-use OP\_20 compatibility. * * * **Step 3: Customize Your Contract**[​](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/setting-up-the-template#step-3-customize-your-contract "Direct link to step-3-customize-your-contract") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Modify the `onDeployment` method to set your token's name, symbol, decimals, and max supply. Add or remove methods in the `execute` function to customize your token's functionality. For example, you could implement a **burn** method or advanced token economics. ### **Example: Adding a Burn Method**[​](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/setting-up-the-template#example-adding-a-burn-method "Direct link to example-adding-a-burn-method") @method({ name: 'amount', type: ABIDataTypes.UINT256,})@returns({ name: 'success', type: ABIDataTypes.BOOL,})@emit('Burn')private burn(calldata: Calldata): BytesWriter { const amount: u256 = calldata.readU256(); // Read the amount to burn from the calldata const resp = this._burn(amount, false); // true means that only the deployer can call this method const writer: BytesWriter = new BytesWriter(BOOLEAN_BYTE_LENGTH); writer.writeBoolean(resp); // Write the response to the writer return writer;} * * * **Step 4: Build and Test Your Contract**[​](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/setting-up-the-template#step-4-build-and-test-your-contract "Direct link to step-4-build-and-test-your-contract") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1. **Compile Your Contract**: Run the following command to compile your contract into WebAssembly (WASM): npm run build 2. **Test Your Contract**: Learn more about [testing your contract](https://docs.opnet.org/developers/opnet-unit-test-framework/introduction) using the unit test framework. * [**Step 1: Forking the OP\_20 Template**](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/setting-up-the-template#step-1-forking-the-op_20-template) * [**Step 2: Locate the Sample Contract**](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/setting-up-the-template#step-2-locate-the-sample-contract) * [**Step 3: Customize Your Contract**](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/setting-up-the-template#step-3-customize-your-contract) * [**Example: Adding a Burn Method**](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/setting-up-the-template#example-adding-a-burn-method) * [**Step 4: Build and Test Your Contract**](https://docs.opnet.org/developers/smart-contract-development/creating-an-opnet-contract/setting-up-the-template#step-4-build-and-test-your-contract) --- # Addresses on OP_NET | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#__docusaurus_skipToContent_fallback) On this page **Introduction**[​](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#introduction "Direct link to introduction") ------------------------------------------------------------------------------------------------------------------------------------------------ Addresses on OP\_NET play a fundamental role in enabling interactions with Bitcoin’s UTXO model, smart contracts, and dApps. Understanding how addresses function inside contracts is essential for efficient development and seamless integration with the OP\_NET ecosystem. Key Concepts * **Unified Account System:** OP\_NET uses Unified Accounts to manage multiple address types associated with a single public key. * **Tweaked Public Keys:** Addresses are derived from tweaked public keys, enhancing privacy and security. * **Address Mechanics:** Addresses are used for validation, conversion, and direct interaction within smart contracts. * * * **Address Mechanics Inside Contracts**[​](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#address-mechanics-inside-contracts "Direct link to address-mechanics-inside-contracts") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ### **Unified Account System**[​](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#unified-account-system "Direct link to unified-account-system") OP\_NET uses **Unified Accounts**, which simplify address management by associating multiple address types (e.g., Taproot, SegWit) with a single public key. This design removes the complexity of working with different address formats and ensures compatibility with Bitcoin's core architecture. Learn More Learn more about [Unified Accounts](https://docs.opnet.org/learn/unified-accounts) and their role in OP\_NET development. ### **Tweaked Public Keys**[​](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#tweaked-public-keys "Direct link to tweaked-public-keys") Inside OP\_NET smart contracts, addresses are typically derived from **tweaked public keys**, which enhance privacy and enable advanced scripting capabilities. These keys provide a direct cryptographic link between the address and its owner. ### **Interaction in Contracts**[​](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#interaction-in-contracts "Direct link to interaction-in-contracts") Addresses are used in various ways within OP\_NET smart contracts, such as verifying ownership, and managing contract states. By leveraging addresses, developers can create secure and efficient contract interactions. Key Use Cases * **Address Validation:** Contracts can verify that an address corresponds to a valid public key. * **Address Conversion:** Tools and libraries allow developers to convert between different address formats (e.g., P2TR to P2PKH) when necessary. * **Direct Interaction:** Addresses are used to reference participants in transactions, such as sender and recipient accounts. * * * **Further Documentation**[​](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#further-documentation "Direct link to further-documentation") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- For detailed specifications and mechanics of addresses on OP\_NET, refer to the official [Addresses Documentation](https://github.com/btc-vision/opnet-node/blob/main/docs/completed/ADDRESSES.md) . * [**Introduction**](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#introduction) * [**Address Mechanics Inside Contracts**](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#address-mechanics-inside-contracts) * [**Unified Account System**](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#unified-account-system) * [**Tweaked Public Keys**](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#tweaked-public-keys) * [**Interaction in Contracts**](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#interaction-in-contracts) * [**Further Documentation**](https://docs.opnet.org/developers/smart-contract-development/addresses-on-opnet#further-documentation) --- # Debugging Contracts on OP_NET | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/smart-contract-development/debugging#__docusaurus_skipToContent_fallback) On this page Debugging smart contracts on OP\_NET is essential for ensuring functionality and identifying issues during development. OP\_NET provides tools like `Blockchain.log` for contract-level logging, specifically designed for development environments. Key Features * **Simple and Intuitive:** Easily log strings or computed values within the contract. * **Real-Time Output:** Logs are accessible during contract execution, providing immediate feedback. * **Development-Only:** Logging is only available in development environments, ensuring that production contracts are not affected. * * * **Method**[​](https://docs.opnet.org/developers/smart-contract-development/debugging#method "Direct link to method") --------------------------------------------------------------------------------------------------------------------- Blockchain.log(data: string): void; * **Parameters**: * **`data: string`**: The message or value to log within the contract. * * * How to Use `Blockchain.log`[​](https://docs.opnet.org/developers/smart-contract-development/debugging#how-to-use-blockchainlog "Direct link to how-to-use-blockchainlog") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- import { Blockchain, OP_NET } from "@btc-vision/btc-runtime/runtime";class MyContract extends OP_NET { public someFunction(): void { Blockchain.log("Function execution started."); const someValue = 42; Blockchain.log(`Computed value: ${someValue}`); // Add more logs as needed Blockchain.log("Function execution completed."); }} * * * **Example Usage**[​](https://docs.opnet.org/developers/smart-contract-development/debugging#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------ 1. **Tracking Execution Flow:** Blockchain.log("Step 1: Initializing variables...");Blockchain.log("Step 2: Performing calculations...");Blockchain.log("Step 3: Finalizing results..."); 2. **Debugging Contract State:** const currentBalance = 100n;Blockchain.log(`Current balance: ${currentBalance}`); * * * **Best Practices**[​](https://docs.opnet.org/developers/smart-contract-development/debugging#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------- * Only use `Blockchain.log` for debugging and tracking purposes in development environments. * Use logging strategically to capture critical points in your contract's execution. * Ensure logs are meaningful and provide enough context for debugging. * [**Method**](https://docs.opnet.org/developers/smart-contract-development/debugging#method) * [How to Use `Blockchain.log`](https://docs.opnet.org/developers/smart-contract-development/debugging#how-to-use-blockchainlog) * [**Example Usage**](https://docs.opnet.org/developers/smart-contract-development/debugging#example-usage) * [**Best Practices**](https://docs.opnet.org/developers/smart-contract-development/debugging#best-practices) --- # BinaryWriter and BinaryReader Usage | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#__docusaurus_skipToContent_fallback) On this page This document details the usage of the `BytesWriter` and `BytesReader` classes for encoding and decoding binary data efficiently in blockchain smart contracts. Why Use BinaryWriter and BinaryReader? Efficient data serialization and deserialization are critical for blockchain applications to minimize gas costs and ensure compatibility with decentralized protocols. `BytesWriter` and `BytesReader` provide robust tools for: * **Encoding data:** Serialize primitive and complex data types into a binary format. * **Decoding data:** Read and parse binary data back into usable types. * * * **Importing BinaryWriter and BinaryReader**[​](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#importing-binarywriter-and-binaryreader "Direct link to importing-binarywriter-and-binaryreader") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To use these utilities, include the necessary imports: import { BytesWriter, BytesReader } from "@btc-vision/btc-runtime/runtime";import { u128, u256 } from "as-bignum/assembly"; * * * **BytesWriter: Writing Data**[​](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#byteswriter-writing-data "Direct link to byteswriter-writing-data") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ The `BytesWriter` class allows you to serialize various data types into a binary format. ### **Key Methods**[​](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#key-methods "Direct link to key-methods") * `writeU8(value: u8): void` Writes an unsigned 8-bit integer. * `writeU256(value: u256): void` Writes a 256-bit unsigned integer. * `writeString(value: string): void` Writes a string, character by character. * `writeBytes(value: Uint8Array): void` Writes a raw byte array. ### **Usage Example**[​](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#usage-example "Direct link to usage-example") import { BytesWriter } from "@btc-vision/btc-runtime/runtime";import { u256 } from "as-bignum/assembly";const writer = new BytesWriter(64);writer.writeU8(255); // Write a single bytewriter.writeString("Hello, blockchain!"); // Write a stringwriter.writeU256(new u256(123456)); // Write a 256-bit integerconst encodedData = writer.getBuffer();console.log(encodedData.toString()); // Encoded byte array * * * **BytesReader: Reading Data**[​](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#bytesreader-reading-data "Direct link to bytesreader-reading-data") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ The `BytesReader` class is used to deserialize binary data into usable types. ### **Key Methods**[​](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#key-methods-1 "Direct link to key-methods-1") * `readU8(): u8` Reads an unsigned 8-bit integer. * `readU256(): u256` Reads a 256-bit unsigned integer. * `readString(length: u16): string` Reads a string of a specified length. * `readBytes(length: u32): Uint8Array` Reads a raw byte array. ### **Usage Example**[​](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#usage-example-1 "Direct link to usage-example-1") import { BytesReader } from "@btc-vision/btc-runtime/runtime";import { u256 } from "as-bignum/assembly";const encodedData: Uint8Array = new Uint8Array(6); // 6 is the length in bytes of the encoded dataencodedData.set([255, 72, 101, 108, 108, 111]); // 255, 72, 101, 108, 108, 111const reader = new BytesReader(encodedData);const byte = reader.readU8(); // Read first byte (255)const str = reader.readString(5); // Read next 5 bytes as a string ("Hello")console.log(`Byte: ${byte}, String: ${str}`); * * * **Combining BytesWriter and BytesReader**[​](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#combining-byteswriter-and-bytesreader "Direct link to combining-byteswriter-and-bytesreader") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- These classes work seamlessly together for encoding and decoding structured data. ### **Example**[​](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#example "Direct link to example") import { BytesWriter, BytesReader } from "@btc-vision/btc-runtime/runtime";import { u256 } from "as-bignum/assembly";// Writing dataconst writer = new BytesWriter(64);writer.writeU8(100);writer.writeU256(new u256(500));const encoded = writer.getBuffer();// Reading dataconst reader = new BytesReader(encoded);const byte = reader.readU8(); // Read 100const bigNumber = reader.readU256(); // Read 500console.log(`Byte: ${byte}, Big Number: ${bigNumber.toString()}`); * * * **Best Practices**[​](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#best-practices "Direct link to best-practices") ----------------------------------------------------------------------------------------------------------------------------------------------------------------- * Always ensure your buffer is large enough to hold all data. * Validate inputs and catch errors (e.g., out-of-bounds reads) to prevent runtime issues. * Use compact representations (e.g., `u8` instead of `u32`) where possible to reduce gas costs. * [**Importing BinaryWriter and BinaryReader**](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#importing-binarywriter-and-binaryreader) * [**BytesWriter: Writing Data**](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#byteswriter-writing-data) * [**Key Methods**](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#key-methods) * [**Usage Example**](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#usage-example) * [**BytesReader: Reading Data**](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#bytesreader-reading-data) * [**Key Methods**](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#key-methods-1) * [**Usage Example**](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#usage-example-1) * [**Combining BytesWriter and BytesReader**](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#combining-byteswriter-and-bytesreader) * [**Example**](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#example) * [**Best Practices**](https://docs.opnet.org/developers/smart-contract-development/binarywriter-and-binaryreader#best-practices) --- # Fetching Block Gas | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas#__docusaurus_skipToContent_fallback) On this page The `gasParameters` method allows you to retrieve gas metrics for the current block on the OP\_NET network. These parameters include the total gas used, target gas limit, base gas price, and Exponential Moving Average (EMA) of gas prices. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas#method "Direct link to method") --------------------------------------------------------------------------------------------------------------------------------------------------- gasParameters(): Promise; * **Returns**: * **`Promise`**: An object containing gas metrics for the current block. * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas#object-definitions "Direct link to object-definitions") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `BlockGasParameters` Object | **Property** | **Type** | **Description** | | --- | --- | --- | | **`blockNumber`** | `bigint` | The number of the block being analyzed. | | **`gasUsed`** | `bigint` | The total amount of gas used in the block. | | **`targetGasLimit`** | `bigint` | The target gas limit for the block. | | **`ema`** | `bigint` | The Exponential Moving Average of gas prices. | | **`baseGas`** | `bigint` | The base gas price for the block. | | **`gasPerSat`** | `bigint` | The amount of gas equivalent to one satoshi. | * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ const gasParameters = await provider.gasParameters();console.log("Block Gas Parameters:", gasParameters);console.log("Block Number:", gasParameters.blockNumber);console.log("Gas Used:", gasParameters.gasUsed);console.log("Base Gas Price:", gasParameters.baseGas); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure your application dynamically adapts to changes in `baseGas` and `gasPerSat` for accurate transaction fee estimations. * The gas parameters provide insights into the network's gas usage and pricing model, which is crucial for optimizing transaction costs. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas#whats-next "Direct link to whats-next") ----------------------------------------------------------------------------------------------------------------------------------------------------------------- After fetching block gas parameters, you can: * [Get Gas Parameters](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-gas-parameters) * [Fetch Block Data](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data) * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas#method) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas#example-usage) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas#whats-next) --- # Fetching Block Data | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#__docusaurus_skipToContent_fallback) On this page The `getBlock` and `getBlocks` methods allow you to retrieve detailed information about a single block or multiple blocks on the OP\_NET network. You can fetch blocks by their height or hash. * * * **Available Methods**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#available-methods "Direct link to available-methods") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. Fetching a Single Block**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#1-fetching-a-single-block "Direct link to 1-fetching-a-single-block") getBlock(blockNumberOrHash: BlockTag, prefetchTxs?: boolean): Promise; * **Parameters**: * **`blockNumberOrHash: BlockTag`**: The block number or hash to fetch. * **`prefetchTxs?: boolean`**: Optional. If `true`, fetches the transactions within the block. * **Returns**: * **`Promise`**: A `Block` object containing detailed information. * * * ### **2\. Fetching Multiple Blocks**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#2-fetching-multiple-blocks "Direct link to 2-fetching-multiple-blocks") getBlocks(blockNumbers: BlockTag[], prefetchTxs?: boolean): Promise; * **Parameters**: * **`blockNumbers: BlockTag[]`**: An array of block numbers or hashes. * **`prefetchTxs?: boolean`**: Optional. If `true`, fetches the transactions for each block. * **Returns**: * **`Promise`**: An array of `Block` objects. * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#object-definitions "Direct link to object-definitions") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `Block` Object | **Property** | **Type** | **Description** | | --- | --- | --- | | **`height`** | `BigNumberish` | The block height. | | **`hash`** | `string` | The block's hash. | | **`previousBlockHash`** | `string` | Hash of the previous block. | | **`time`** | `number` | The block's timestamp. | | **`transactions`** | `TransactionBase[]` | An array of transactions within the block. | | **`gasUsed`** | `bigint` | Total gas used in the block. | | **`ema`** | `bigint` | Exponentially weighted moving average of gas usage. | | **`baseGas`** | `bigint` | Base gas cost for transactions in the block. | * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Fetching a Single Block**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#fetching-a-single-block "Direct link to fetching-a-single-block") const block = await provider.getBlock(100);console.log("Block details:", block); ### **Fetching Multiple Blocks**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#fetching-multiple-blocks "Direct link to fetching-multiple-blocks") const blocks = await provider.getBlocks([100, 101, 102]);console.log("Fetched blocks:", blocks); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#best-practices "Direct link to best-practices") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Use `prefetchTxs` to fetch transactions within the blocks. Set to `false` to save bandwidth if transaction data is unnecessary. * Use `getBlocks` for better performance when retrieving multiple blocks. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#whats-next "Direct link to whats-next") ------------------------------------------------------------------------------------------------------------------------------------------------------------------ * [Fetch Gas Parameters for Blocks](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas) * [Fetch Transaction Data](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data) * [**Available Methods**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#available-methods) * [**1\. Fetching a Single Block**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#1-fetching-a-single-block) * [**2\. Fetching Multiple Blocks**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#2-fetching-multiple-blocks) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#example-usage) * [**Fetching a Single Block**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#fetching-a-single-block) * [**Fetching Multiple Blocks**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#fetching-multiple-blocks) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data#whats-next) --- # SafeMath and u256 Usage | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#__docusaurus_skipToContent_fallback) On this page This document explains the implementation and usage of `SafeMath` for the `u256` data type, focusing on its importance in avoiding overflows and underflows in blockchain smart contracts. Why Use SafeMath? When working with unsigned integers like `u256`, overflows and underflows can lead to critical bugs or vulnerabilities in your smart contracts. `SafeMath` mitigates these risks by adding checks for these conditions during arithmetic operations. * * * **Importing SafeMath**[​](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#importing-safemath "Direct link to importing-safemath") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- To start using `SafeMath`, include the necessary imports in your AssemblyScript code: import { SafeMath } from "@btc-vision/btc-runtime/runtime";import { u128, u256 } from "as-bignum/assembly"; * * * **Available Methods**[​](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#available-methods "Direct link to available-methods") -------------------------------------------------------------------------------------------------------------------------------------------------------------------- `SafeMath` provides a comprehensive suite of arithmetic operations for `u256`, `u128`, and smaller unsigned integers (`u64`). Below is a list of the most commonly used methods: ### **Addition**[​](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#addition "Direct link to addition") * **Method:** `SafeMath.add(a: u256, b: u256): u256` * **Description:** Adds two `u256` values safely, throwing an error if an overflow occurs. * **Example:** let a: u256 = u256.fromU32(1000);let b: u256 = u256.fromU32(2000);let sum: u256 = SafeMath.add(a, b); // Result: 3000 ### **Subtraction**[​](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#subtraction "Direct link to subtraction") * **Method:** `SafeMath.sub(a: u256, b: u256): u256` * **Description:** Subtracts one `u256` value from another, throwing an error if an underflow occurs. * **Example:** let a: u256 = u256.fromU32(5000);let b: u256 = u256.fromU32(3000);let difference: u256 = SafeMath.sub(a, b); // Result: 2000 ### **Multiplication**[​](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#multiplication "Direct link to multiplication") * **Method:** `SafeMath.mul(a: u256, b: u256): u256` * **Description:** Multiplies two `u256` values safely, throwing an error if an overflow occurs. * **Example:** let a: u256 = u256.fromU32(10);let b: u256 = u256.fromU32(20);let product: u256 = SafeMath.mul(a, b); // Result: 200 ### **Division**[​](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#division "Direct link to division") * **Method:** `SafeMath.div(a: u256, b: u256): u256` * **Description:** Divides one `u256` value by another, throwing an error if a division by zero occurs. * **Example:** let a: u256 = u256.fromU32(100);let b: u256 = u256.fromU32(5);let quotient: u256 = SafeMath.div(a, b); // Result: 20 ### **Modulo**[​](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#modulo "Direct link to modulo") * **Method:** `SafeMath.mod(a: u256, b: u256): u256` * **Description:** Computes the remainder of `a` divided by `b`, throwing an error if `b` is zero. * **Example:** let a: u256 = u256.fromU32(10);let b: u256 = u256.fromU32(3);let remainder: u256 = SafeMath.mod(a, b); // Result: 1 * * * **Advanced Methods**[​](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#advanced-methods "Direct link to advanced-methods") ----------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Exponentiation**[​](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#exponentiation "Direct link to exponentiation") * **Method:** `SafeMath.pow(base: u256, exponent: u256): u256` * **Description:** Computes `base` raised to the power of `exponent` safely. * **Example:** let base: u256 = u256.fromU32(2);let exponent: u256 = u256.fromU32(10);let result: u256 = SafeMath.pow(base, exponent); // Result: 1024 ### **Logarithm (Approximate)**[​](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#logarithm-approximate "Direct link to logarithm-approximate") * **Method:** `SafeMath.approximateLog2(x: u256): u256` * **Description:** Approximates the binary logarithm (`log2`) of a `u256` value. * **Example:** let x: u256 = u256.fromU32(1024);let log2: u256 = SafeMath.approximateLog2(x); // Result: 10 * * * **Best Practices**[​](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#best-practices "Direct link to best-practices") ----------------------------------------------------------------------------------------------------------------------------------------------------------- * Avoid native operations (`+`, `-`, `*`, `/`) to ensure safety. * Even with SafeMath, ensure the inputs are within the expected range to prevent logical errors. * For performance-critical code, use unchecked arithmetic only when absolutely safe and well-documented. * [**Importing SafeMath**](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#importing-safemath) * [**Available Methods**](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#available-methods) * [**Addition**](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#addition) * [**Subtraction**](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#subtraction) * [**Multiplication**](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#multiplication) * [**Division**](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#division) * [**Modulo**](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#modulo) * [**Advanced Methods**](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#advanced-methods) * [**Exponentiation**](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#exponentiation) * [**Logarithm (Approximate)**](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#logarithm-approximate) * [**Best Practices**](https://docs.opnet.org/developers/smart-contract-development/safemath-and-u256-usage#best-practices) --- # Contract Runtime | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#__docusaurus_skipToContent_fallback) On this page The **Contract Runtime** on OP\_NET, powered by `@btc-vision/btc-runtime/runtime`, provides developers with tools to interact with the blockchain environment. This guide explains the key features of the `Blockchain` class and its associated components, enabling advanced contract functionality. * * * **Blockchain Documentation**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#blockchain-documentation "Direct link to blockchain-documentation") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The `Blockchain` object is essential for executing smart contracts within the OP\_NET runtime. It provides the necessary context, such as the transaction origin, sender, block details, and contract-specific information. * * * ### **Public Properties**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#public-properties "Direct link to public-properties") #### **1\. `tx.origin`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#1-txorigin "Direct link to 1-txorigin") Property Details * **Type**: `Address` * **Description**: Represents the initial sender of the transaction. (equivalent to `tx.origin` in Solidity) * **Usage Example**: let txOrigin: Address = Blockchain.tx.origin;Blockchain.log(`Transaction Origin: ${txOrigin}`); #### **2\. `tx.sender`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#2-txsender "Direct link to 2-txsender") Property Details * **Type**: `Address` * **Description**: Refers to the immediate caller of the transaction. (equivalent to `msg.sender` in Solidity) * **Usage Example**: let txSender: Address = Blockchain.tx.sender;Blockchain.log(`Transaction Sender: ${txSender}`); #### **3\. `block.medianTimestamp`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#3-blockmediantimestamp "Direct link to 3-blockmediantimestamp") Property Details * **Type**: `u64` * **Description**: Timestamp of the block in which the transaction is executed. * **Usage Example**: let blockTimestamp: u64 = Blockchain.block.medianTimestamp;Blockchain.log(`Block Timestamp: ${blockTimestamp}`); #### **4\. `contract`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#4-contract "Direct link to 4-contract") Property Details * **Type**: `OP_NET` * **Description**: Accesses the current contract instance. * **Usage Example**: let currentContract: OP_NET = Blockchain.contract; #### **5\. `nextPointer`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#5-nextpointer "Direct link to 5-nextpointer") Property Details * **Type**: `u16` * **Description**: Manages dynamic storage pointers. * **Usage Example**: let pointer: u16 = Blockchain.nextPointer;Blockchain.log(`Next Pointer: ${pointer}`); #### **6\. `contractDeployer`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#6-contractdeployer "Direct link to 6-contractdeployer") Property Details * **Type**: `Address` * **Description**: The contract deployer's address. * **Usage Example**: let contractDeployer: Address = Blockchain.contractDeployer;Blockchain.log(`Contract Deployer: ${contractDeployer}`); #### **7\. `contractAddress`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#7-contractaddress "Direct link to 7-contractaddress") Property Details * **Type**: `Address` * **Description**: The deployed address of the contract. * **Usage Example**: let deployedAddress: Address = Blockchain.contractAddress;Blockchain.log(`Deployed Contract Address: ${deployedAddress}`); #### **8\. `block.number`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#8-blocknumber "Direct link to 8-blocknumber") Property Details * **Type**: `u256` * **Description**: The current block number as a 256-bit unsigned integer. * **Usage Example**: let currentBlockNum: u256 = Blockchain.block.number;Blockchain.log(`Current Block Number: ${currentBlockNum}`); #### **9\. `block.numberU64`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#9-blocknumberu64 "Direct link to 9-blocknumberu64") Property Details * **Type**: `u64` * **Description**: The current block number as a 64-bit unsigned integer. * **Usage Example**: let currentBlockNum: u64 = Blockchain.block.numberU64;Blockchain.log(`Current Block Number: ${currentBlockNum}`); * * * ### **Public Methods**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#public-methods "Direct link to public-methods") #### **1\. `call(destinationContract: Address, calldata: BytesWriter)`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#1-calldestinationcontract-address-calldata-byteswriter "Direct link to 1-calldestinationcontract-address-calldata-byteswriter") Method Details * **Returns**: `BytesReader` * **Description**: Executes a call to another contract. * **Usage Example**: let destination: Address = ...;let calldata = new BytesWriter(length);calldata.writeString('methodName');let response = Blockchain.call(destination, calldata);Blockchain.log(`Response: ${response}`); #### **2\. `log(data: string)`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#2-logdata-string "Direct link to 2-logdata-string") Method Details * **Description**: Logs string data for debugging or tracking. _(only available in the development environment)_ * **Usage Example**: Blockchain.log("Execution started."); #### **3\. `deployContract(hash: u256, bytecode: Uint8Array)`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#3-deploycontracthash-u256-bytecode-uint8array "Direct link to 3-deploycontracthash-u256-bytecode-uint8array") Method Details * **Returns**: `DeployContractResponse` * **Description**: Deploys a contract using a hash and bytecode. * **Usage Example**: let contractHash = u256.fromU64(0x1234567890); // Your contract hash.let bytecode: Uint8Array = ...; // Your contract bytecode.let deployResponse = Blockchain.deployContract(contractHash, bytecode);Blockchain.log(`Deployed Address: ${deployResponse.contractAddress}`); #### **4\. `encodeVirtualAddress(virtualAddress: u8[])`**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#4-encodevirtualaddressvirtualaddress-u8 "Direct link to 4-encodevirtualaddressvirtualaddress-u8") Method Details * **Returns**: `Address` * **Description**: Encodes a virtual address into a standard format. * **Usage Example**: let virtualAddr: u8[] = ...;let encodedAddr: Address = Blockchain.encodeVirtualAddress(virtualAddr);Blockchain.log(`Encoded Address: ${encodedAddr}`); * * * **Loading and Storing Pointers**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#loading-and-storing-pointers "Direct link to loading-and-storing-pointers") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. Encoding and Hashing Process**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#1-encoding-and-hashing-process "Direct link to 1-encoding-and-hashing-process") Storage on OP\_NET uses a combination of pointers (`u16`) and sub-pointers (`u256`) for efficient data management. These are encoded and hashed into a `MemorySlotPointer`. #### **Encoding Example**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#encoding-example "Direct link to encoding-example") export function encodePointerHash(pointer: u16, sub: u256): MemorySlotPointer { const buffer = new Uint8Array(34); const mergedKey = [u8(pointer & 0xff), u8((pointer >> 8) & 0xff)]; buffer.set(mergedKey, 0); buffer.set(sub.toUint8Array(), 2); return bytes32(Sha256.hash(buffer));} * * * ### **2\. Usage Example in a Contract**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#2-usage-example-in-a-contract "Direct link to 2-usage-example-in-a-contract") Let's consider a simple contract that stores and retrieves data using pointers. #### **Contract Implementation**[​](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#contract-implementation "Direct link to contract-implementation") class MyContract { private pointer: u16; private subPointer: MemorySlotPointer; constructor(pointer: u16, subKey: string) { this.pointer = pointer; this.subPointer = encodePointer( this.pointer, Uint8Array.wrap(String.UTF8.encode(subKey)) ); } public storeData(value: u256): void { const storageKey = encodePointerHash(this.pointer, this.subPointer); Blockchain.setStorageAt(storageKey, value); } public retrieveData(): u256 { const storageKey = encodePointerHash(this.pointer, this.subPointer); return Blockchain.getStorageAt(storageKey, u256.Zero); }} * [**Blockchain Documentation**](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#blockchain-documentation) * [**Public Properties**](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#public-properties) * [**Public Methods**](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#public-methods) * [**Loading and Storing Pointers**](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#loading-and-storing-pointers) * [**1\. Encoding and Hashing Process**](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#1-encoding-and-hashing-process) * [**2\. Usage Example in a Contract**](https://docs.opnet.org/developers/smart-contract-development/contract-runtime#2-usage-example-in-a-contract) --- # Fetching Transaction Data | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data#__docusaurus_skipToContent_fallback) On this page The `getTransaction` method allows you to retrieve detailed information about a specific transaction on the OP\_NET network. You can fetch transactions by their hash and analyze their details, including gas usage, inputs, outputs, and transaction type. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data#method "Direct link to method") ---------------------------------------------------------------------------------------------------------------------------------------------------------- getTransaction(txHash: string): Promise>; * **Parameters**: * **`txHash: string`**: The hash of the transaction to fetch. * **Returns**: * **`Promise>`**: A transaction object containing its details. * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data#object-definitions "Direct link to object-definitions") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `TransactionBase` Object | **Property** | **Type** | **Description** | | --- | --- | --- | | **`id`** | `string` | A unique identifier for the transaction. | | **`hash`** | `string` | The transaction's hash. | | **`index`** | `number` | The index of the transaction in the block. | | **`burnedBitcoin`** | `BigNumberish` | Amount of Bitcoin burned in the transaction. | | **`inputs`** | `TransactionInput[]` | List of transaction inputs. | | **`outputs`** | `TransactionOutput[]` | List of transaction outputs. | | **`OPNetType`** | `OPNetTransactionTypes` | The type of the OP\_NET transaction (see below). | | **`gasUsed`** | `bigint` | The amount of gas used by the transaction. | * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- const txHash = "8bdb1b21a...";const transaction = await provider.getTransaction(txHash);console.log("Transaction ID:", transaction.id);console.log("Transaction Hash:", transaction.hash);console.log("Gas Used:", transaction.gasUsed);console.log("Transaction Type:", transaction.OPNetType); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data#best-practices "Direct link to best-practices") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure the `txHash` provided is valid and exists on the network you are connected to. * The transaction type (`OPNetType`) helps you identify if the transaction is a deployment, interaction, or generic. * Use this method to retrieve metadata such as sender, receiver, value, and gas usage. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data#whats-next "Direct link to whats-next") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ * [Fetch Block Data](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data) * [Fetch Transaction Receipts](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt) * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data#method) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data#example-usage) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data#whats-next) --- # Fetching Transaction Receipt | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt#__docusaurus_skipToContent_fallback) On this page The `getTransactionReceipt` method allows you to retrieve the receipt of a specific transaction on the OP\_NET network. This receipt includes detailed information about the transaction's execution, such as logs, events, and proofs validating the receipt. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt#method "Direct link to method") ------------------------------------------------------------------------------------------------------------------------------------------------------------- getTransactionReceipt(txHash: string): Promise; * **Parameters**: * **`txHash: string`**: The hash of the transaction to fetch the receipt for. * **Returns**: * **`Promise`**: A transaction receipt object containing detailed information. * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt#object-definitions "Direct link to object-definitions") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `TransactionReceipt` Object | **Property** | **Type** | **Description** | | --- | --- | --- | | **`receipt`** | `Buffer` | The raw receipt data (optional). | | **`receiptProofs`** | `string[]` | Proofs validating the transaction's receipt. | | **`events`** | `ContractEvents` | Logs emitted by the transaction, typically contract events. | | **`revert`** | `Buffer` | Revert reason for failed transactions (optional). | * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt#example-usage "Direct link to example-usage") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- const txHash = "8bdb1b21a...";const receipt = await provider.getTransactionReceipt(txHash);console.log("Transaction Receipt:", receipt);console.log("Receipt Proofs:", receipt.receiptProofs);console.log("Events:", receipt.events);if (receipt.revert) { console.log("Revert Reason:", receipt.revert.toString("utf-8"));} * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt#best-practices "Direct link to best-practices") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Check the `revert` field to identify if the transaction failed. * Use the `events` property to analyze emitted logs, which are essential when interacting with smart contracts. * The `receiptProofs` provide cryptographic validation for the receipt, ensuring its integrity. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt#whats-next "Direct link to whats-next") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- After fetching the transaction receipt, you can: * [Fetch Transaction Data](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data) . * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt#method) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt#example-usage) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt#whats-next) --- # Get Gas Parameters | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-gas-parameters#__docusaurus_skipToContent_fallback) On this page The `gasParameters` allows you to fetch recommended fees and gas information directly from the node. This is more reliable than using fixed values. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-gas-parameters#method "Direct link to method") ------------------------------------------------------------------------------------------------------------------------------------------------------- const gasParameters = await provider.gasParameters(); The returned object includes: * **`blockNumber`** – The current block number of the network. * **`gasUsed`** – Amount of gas used in the last block. * **`targetGasLimit`** – Target gas limit for blocks. * **`ema`** – Exponential moving average for gas metrics. * **`baseGas`** – Base gas value used for fee calculations. * **`gasPerSat`** – Gas price per satoshi. * **`bitcoin.conservative`** – Conservative Bitcoin fee rate suggestion. * **`bitcoin.recommended.low`** – Suggested fee rate for low-priority transactions. * **`bitcoin.recommended.medium`** – Suggested fee rate for standard transactions. * **`bitcoin.recommended.high`** – Suggested fee rate for high-priority transactions. **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-gas-parameters#whats-next "Direct link to whats-next") --------------------------------------------------------------------------------------------------------------------------------------------------------------------- After fetching block gas parameters, you can: * [Fetch Block Data](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data) * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-gas-parameters#method) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-gas-parameters#whats-next) --- # Fetching Public Key from Address | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address#__docusaurus_skipToContent_fallback) On this page The `getPublicKeyInfo` method allows you to fetch the public key associated with a Bitcoin address on the OP\_NET network. This method is useful for retrieving the public key to interact with smart contracts, etc. important * [Learn More About Unified Accounts](https://docs.opnet.org/learn/unified-accounts) and how public keys are unified across different address types on OP\_NET. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address#method "Direct link to method") ---------------------------------------------------------------------------------------------------------------------------------------------------------------- getPublicKeyInfo(address: string): Promise
; * **Parameters**: * **`address: string`**: The Bitcoin address for which you want to fetch the public key. * **Returns**: * **`Promise
`**: An `Address` object containing the public key information. * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address#object-definitions "Direct link to object-definitions") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `Address` Object | **Method** | **Description** | | --- | --- | | **`originalPublicKey`** | Retrieves the original public key (if available). | | **`toHex()`** | Converts the address to a hexadecimal string. | | **`toBuffer()`** | Converts the address to a `Buffer` object. | | **`p2wpkh(network)`** | Generates a P2WPKH address for the specified network. | | **`p2pkh(network)`** | Generates a P2PKH address for the specified network. | | **`p2tr(network)`** | Generates a P2TR address for the specified network. | | **`p2op(network)`** | Generates a P2OP address for the specified network. | | **`toCSV(75, network)`** | Generates a CSV address for SHA1 Mining reward payouts. | | **`toCSV(1, network)`** | Generates a CSV address for anti-pinning protection, used by contracts like NativeSwap. | | **`toString()`** | Converts the address to its string representation. | | **`isValid(network)`** | Checks if the address is valid for a specific Bitcoin network. | * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- import { networks } from "@btc-vision/bitcoin";const address = "bcrt1qexampleaddress...";const publicKeyInfo = await provider.getPublicKeyInfo(address);console.log( "Original Public Key (Hex):", publicKeyInfo.originalPublicKey?.toString());console.log("P2WPKH Address:", publicKeyInfo.p2wpkh(networks.regtest));console.log("P2PKH Address:", publicKeyInfo.p2pkh(networks.regtest));console.log("P2TR Address:", publicKeyInfo.p2tr(networks.regtest));console.log("CSV75 Address:", publicKeyInfo.toCSV(75, networks.regtest).address);console.log("CSV1 Address:", publicKeyInfo.toCSV(1, networks.regtest).address); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address#best-practices "Direct link to best-practices") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure the address provided is valid for the Bitcoin network you are working on. * The returned `Address` object provides utility methods for generating various address formats (e.g., P2WPKH, P2PKH, P2TR). * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address#whats-next "Direct link to whats-next") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ After retrieving the public key, you can: * [Validate Bitcoin Addresses for a Network](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network) * [Fetch Transaction Data](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data) * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address#method) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address#example-usage) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address#whats-next) --- # Getting the Balance of an Address | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#__docusaurus_skipToContent_fallback) On this page The `getBalance` method allows you to retrieve the total balance of a Bitcoin address on the OP\_NET network. This balance includes the sum of all unspent transaction outputs (UTXOs) associated with the address. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#method "Direct link to method") ------------------------------------------------------------------------------------------------------------------------------------------------------------------ getBalance(addressLike: string, filterOrdinals?: boolean): Promise; * **Parameters**: * **`addressLike: string`**: The Bitcoin address whose balance you want to retrieve. * **`filterOrdinals?: boolean`**: (Optional) If `true`, excludes balances associated with Bitcoin Ordinals. Defaults to `false`. * **Returns**: * **`Promise`**: The total balance of the specified address in satoshis. * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#example-usage "Direct link to example-usage") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Fetching Balance Without Filtering Ordinals**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#fetching-balance-without-filtering-ordinals "Direct link to fetching-balance-without-filtering-ordinals") const address = "bcrt1qexampleaddress...";const balance = await provider.getBalance(address);console.log("Address Balance:", balance, "satoshis"); ### **Fetching Balance with Ordinals Filter**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#fetching-balance-with-ordinals-filter "Direct link to fetching-balance-with-ordinals-filter") const filteredBalance = await provider.getBalance(address, true);console.log("Filtered Balance:", filteredBalance, "satoshis"); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#best-practices "Direct link to best-practices") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ * Use the `filterOrdinals` parameter to exclude any balances tied to Bitcoin Ordinals for a clearer view of spendable funds. * The returned balance is in **satoshis**, not BTC. Convert it to BTC by dividing by `1e8` if needed. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#whats-next "Direct link to whats-next") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Once you have the balance, you can: * [Send Raw Transactions](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex) * [Fetch UTXOs for an Address](https://docs.opnet.org/developers/using-the-utxo-manager/introduction) * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#method) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#example-usage) * [**Fetching Balance Without Filtering Ordinals**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#fetching-balance-without-filtering-ordinals) * [**Fetching Balance with Ordinals Filter**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#fetching-balance-with-ordinals-filter) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address#whats-next) --- # Get Current Block Number | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/get-current-block-number#__docusaurus_skipToContent_fallback) On this page The `getBlockNumber` method allows you to fetch the current block number on the OP\_NET network (mainnet, testnet, or regtest). * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/get-current-block-number#method "Direct link to method") --------------------------------------------------------------------------------------------------------------------------------------------------------- getBlockNumber(): Promise; * **Returns**: * **`Promise`**: The current block number on the OP\_NET network. * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/get-current-block-number#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ const blockNumber = await provider.getBlockNumber();console.log(`Current Block Number: ${blockNumber}`); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/get-current-block-number#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure the `network` parameter in your provider matches the network you want to fetch the block number from (e.g., `regtest`, `testnet`, `mainnet`). * Network delays may affect response time, consider increasing the timeout if needed. * Always handle errors in case the network is unavailable or the request fails. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/get-current-block-number#whats-next "Direct link to whats-next") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- After retrieving the block number, you can: * [Fetch Block Gas Parameters](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-gas) * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/get-current-block-number#method) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/get-current-block-number#example-usage) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/get-current-block-number#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/get-current-block-number#whats-next) --- # Interacting with Smart Contracts Using Call | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call#__docusaurus_skipToContent_fallback) On this page The `call` method allows you to interact with deployed smart contracts without broadcasting a transaction. This method is useful for reading contract state or simulating transactions. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call#method "Direct link to method") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- call( to: string | Address, data: Buffer | string, from?: Address, height?: BigNumberish): Promise; * **Parameters**: * **`to: string | Address`**: The address of the contract to call. * **`data: Buffer | string`**: The calldata to send to the contract. * **`from?: Address`**: _(Optional)_ The address making the call. * **`height?: BigNumberish`**: _(Optional)_ The blockchain height at which to perform the call. * **Returns**: * **`Promise`**: Contains the execution result, including any returned data or events. * **`Promise`**: Contains error details if the call fails. * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call#object-definitions "Direct link to object-definitions") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `CallResult` Object | **Property/Method** | **Type** | **Description** | | --- | --- | --- | | **`result`** | `BinaryReader` | The raw result of the call. | | **`accessList`** | `IAccessList` | Accessed storage and contract addresses. | | **`revert`** | `string \| undefined` | The reason for revert, if the call fails. | | **`calldata`** | `Buffer \| undefined` | The calldata used for the call. | | **`estimatedGas`** | `bigint \| undefined` | Estimated gas for the call. | | **`events`** | `OPNetEvent[]` | Events emitted during the call. | | **`sendTransaction()`** | `Function` | Sends a transaction with the current parameters. | * * * **Example Usage (Get Balance of a Public Key)**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call#example-usage-get-balance-of-a-public-key "Direct link to example-usage-get-balance-of-a-public-key") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- import { networks } from "@btc-vision/bitcoin";import { getContract, IOP_20Contract, OP_20_ABI } from "opnet";// Get the contractconst contractAddress = "opr1exampleaddress..."; // Replace with actual contract addressconst contract = getContract( contractAddress, OP_20_ABI, provider, networks.regtest // Optional: Add the sender's address // Address.fromString("your-public-key"));const pubKey = await provider.getPublicKeyInfo("bcrt1p..."); // Replace with the address// Call the contractconst calldata = contract.encodeCalldata("balanceOf", [pubKey]);try { const callResult = await provider.call(contractAddress, calldata); if ("error" in callResult) { throw new Error(callResult.error); } console.log("Call Result:", callResult.result.toString()); console.log("Estimated Gas:", callResult.estimatedGas); console.log("Events:", callResult.events);} catch (error) { console.error("Call Error:", error.error);} * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call#best-practices "Direct link to best-practices") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure the contract address and calldata are correct before making a call. * Use the `height` parameter to simulate the call at a specific block height, if needed. * Handle errors gracefully using the `ICallRequestError` interface. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call#whats-next "Direct link to whats-next") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ After interacting with contracts using `call`, you can explore: * [Fetching Transaction Data](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data) * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call#method) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call#object-definitions) * [**Example Usage (Get Balance of a Public Key)**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call#example-usage-get-balance-of-a-public-key) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call#whats-next) --- # Fetching a Storage Slot | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/fetching-a-storage-slot#__docusaurus_skipToContent_fallback) This section is under development and will be updated soon with detailed information on how to use the `getStorageAt` method to fetch a storage slot from a smart contract on the OP\_NET network. --- # Sending Raw Transaction (Hex) | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#__docusaurus_skipToContent_fallback) On this page The `sendRawTransaction` method allows you to broadcast a raw Bitcoin transaction to the OP\_NET network. You can send fully signed transactions in hex format or partially signed transactions in PSBT format. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#method "Direct link to method") --------------------------------------------------------------------------------------------------------------------------------------------------------- sendRawTransaction(tx: string, psbt: boolean): Promise; * **Parameters**: * **`tx: string`**: The raw transaction in hexadecimal format. * **`psbt: boolean`**: * `true`: Indicates the transaction is in **Partially Signed Bitcoin Transaction (PSBT)** format. * `false`: Indicates the transaction is a fully signed raw transaction in hex format. * **Returns**: * **`Promise`**: An object containing details about the broadcast operation. * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#object-definitions "Direct link to object-definitions") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `BroadcastedTransaction` Object | **Field** | **Type** | **Description** | | --- | --- | --- | | **`success`** | `boolean` | Indicates whether the transaction was successfully broadcast. | | **`result`** | `string` | _(Optional)_ Transaction ID if the broadcast was successful. | | **`error`** | `string` | _(Optional)_ Error message if the broadcast failed. | | **`peers`** | `number` | _(Optional)_ Number of peers that accepted the transaction. | | **`identifier`** | `bigint \| string` | Unique identifier for the transaction, which could be the transaction ID or another reference. | * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ### **Sending a Fully Signed Raw Transaction**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#sending-a-fully-signed-raw-transaction "Direct link to sending-a-fully-signed-raw-transaction") const rawTransactionHex = "fce09cbe03..."; // Replace with your raw transaction hextry { const result = await provider.sendRawTransaction(rawTransactionHex, false); if (result.success) { console.log("Transaction Broadcasted Successfully:"); console.log("Transaction ID:", result.result); console.log("Peers Accepted:", result.peers); } else { console.error("Broadcast Failed:", result.error); }} catch (error) { console.error("Error Sending Transaction:", error.message);} ### **Sending a PSBT**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#sending-a-psbt "Direct link to sending-a-psbt") const psbtHex = "70736274ff0100..."; // Replace with your PSBT in hex formattry { const result = await provider.sendRawTransaction(psbtHex, true); if (result.success) { console.log("PSBT Broadcasted Successfully:"); console.log("Transaction ID:", result.result); console.log("Peers Accepted:", result.peers); } else { console.error("Broadcast Failed:", result.error); }} catch (error) { console.error("Error Sending PSBT:", error.message);} * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure the `tx` parameter is correctly formatted: * Use raw hex for fully signed transactions. * Use PSBT format when `psbt: true`. * Always validate the transaction locally before broadcasting to avoid unnecessary errors. * Handle network errors and failures gracefully. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#whats-next "Direct link to whats-next") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- After broadcasting a transaction, you can: * [Fetch Transaction Data](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-data) * [Analyze Transaction Receipts](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-transaction-receipt) * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#method) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#example-usage) * [**Sending a Fully Signed Raw Transaction**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#sending-a-fully-signed-raw-transaction) * [**Sending a PSBT**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#sending-a-psbt) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/send-raw-transaction-hex#whats-next) --- # Validating a Bitcoin Address for a Network | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network#__docusaurus_skipToContent_fallback) On this page The `validateAddress` method allows you to verify the validity of a Bitcoin address and determine its type (e.g., P2PKH, P2WPKH, P2TR) on a specific network. This method is useful for ensuring that addresses are correctly formatted and compatible with the network you are interacting with. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network#method "Direct link to method") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- validateAddress(addr: string | Address, network: Network): AddressTypes | null; * **Parameters**: * **`addr: string | Address`**: The Bitcoin address to validate. Can be a plain string or an `Address` object. * **`network: Network`**: The BitcoinJS network configuration (e.g., `networks.regtest`, `networks.testnet`). * **Returns**: * **`AddressTypes`**: Specifies the type of the address (e.g., `AddressTypes.P2PKH`, `AddressTypes.P2WPKH`). * **`null`**: If the address is invalid or does not match the provided network. * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network#object-definitions "Direct link to object-definitions") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `AddressTypes` Enum | **Type** | **Description** | | --- | --- | | `P2PKH` | Pay-to-Public-Key-Hash (Legacy address format). | | `P2SH_OR_P2SH_P2WPKH` | Pay-to-Script-Hash or P2SH-wrapped Pay-to-Witness-PKH. | | `P2PK` | Pay-to-Public-Key. | | `P2TR` | Pay-to-Taproot. | | `P2WPKH` | Pay-to-Witness-Public-Key-Hash (SegWit address). | | `P2OP` | Pay-to-OPNet (OP\_NET contract address). | * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ import { networks } from "@btc-vision/bitcoin";import { AddressTypes } from "@btc-vision/transaction";const address = "bcrt1q...";const addressType = provider.validateAddress(address, networks.regtest);if (addressType) { console.log(`Address is valid and of type: ${addressType}`); if (addressType === AddressTypes.P2TR) { console.log("This is a Taproot address!"); }} else { console.log("Invalid address for the specified network.");} * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure the `network` parameter matches the address type you are validating. An address valid on `testnet` may not be valid on `mainnet`. * Always check for `null` to avoid processing invalid addresses. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network#whats-next "Direct link to whats-next") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- After validating an address, you can: * [Fetch Public Key Information](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-publickey-from-address) * [Check Balances](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/getting-the-balance-of-an-address) * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network#method) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network#example-usage) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/validating-a-bitcoin-address-for-a-network#whats-next) --- # Fetching the Code of a Contract | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#__docusaurus_skipToContent_fallback) On this page The `getCode` method allows you to retrieve the bytecode and metadata of a deployed contract on the OP\_NET network. You can fetch the contract code by providing its address and specify whether you want only the raw bytecode or detailed contract metadata. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#method "Direct link to method") ---------------------------------------------------------------------------------------------------------------------------------------------------------------- getCode(address: string | Address, onlyBytecode?: boolean): Promise; * **Parameters**: * **`address: string | Address`**: The address of the contract whose code you want to fetch. * **`onlyBytecode?: boolean`** _(Optional)_: * `true`: Returns only the raw bytecode. * `false` or omitted: Returns comprehensive contract metadata (`ContractData`). * **Returns**: * **`Promise`**: * **`ContractData`**: Detailed contract metadata when `onlyBytecode` is `false`. * **`Buffer`**: Raw bytecode when `onlyBytecode` is `true`. * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#object-definitions "Direct link to object-definitions") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `ContractData` Object | **Field** | **Description** | | --- | --- | | **`contractAddress`** | The contract's main address. | | **`virtualAddress`** | Virtual address of the contract for internal operations. | | **`p2opAddress`** | P2OP address of the contract. | | **`bytecode`** | The raw bytecode of the contract. | | **`wasCompressed`** | Indicates if the bytecode was compressed during deployment. | | **`deployedTransactionId`** | The transaction ID of the contract's deployment. | | **`deployedTransactionHash`** | The hash of the transaction that deployed the contract. | | **`deployerPubKey`** | The public key of the deployer. | | **`contractSeed`** | The seed used during contract deployment. | | **`contractSaltHash`** | The salt hash associated with the contract. | | **`contractDeployer`** | The address of the contract deployer. | * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Fetching Full Contract Metadata**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#fetching-full-contract-metadata "Direct link to fetching-full-contract-metadata") import { ContractData } from "opnet";const contractAddress = "opr1exampleaddress...";const contractData = (await provider.getCode(contractAddress)) as ContractData;console.log("Contract Address:", contractData.contractAddress.toString());console.log("Bytecode (Hex):", contractData.bytecode.toString("hex"));console.log( "Deployer Public Key:", contractData.deployerPubKey.toString("hex"));console.log("Deployment Transaction ID:", contractData.deployedTransactionId); ### **Fetching Only the Raw Bytecode**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#fetching-only-the-raw-bytecode "Direct link to fetching-only-the-raw-bytecode") const bytecode = (await provider.getCode(contractAddress, true)) as Buffer;console.log("Contract Bytecode (Hex):", bytecode.toString("hex")); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#best-practices "Direct link to best-practices") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure the provided `address` corresponds to a valid deployed contract. * If the contract does not exist at the specified address, the method may return `null` or throw an error. * The `ContractData` object provides critical information for contract verification, auditing, and interaction. * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#method) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#example-usage) * [**Fetching Full Contract Metadata**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#fetching-full-contract-metadata) * [**Fetching Only the Raw Bytecode**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#fetching-only-the-raw-bytecode) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-the-code-of-a-contract#best-practices) --- # Introduction | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/smart-contract-development/introduction#__docusaurus_skipToContent_fallback) On this page OP\_NET enables developers to create advanced smart contracts on Bitcoin’s infrastructure, leveraging its security and decentralized nature while adding functionality such as token standards, advanced scripting, and contract-based dApps. This document provides an overview of smart contract development on OP\_NET and the supported languages. * * * **Supported Languages**[​](https://docs.opnet.org/developers/smart-contract-development/introduction#supported-languages "Direct link to supported-languages") --------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **1\. AssemblyScript**[​](https://docs.opnet.org/developers/smart-contract-development/introduction#1-assemblyscript "Direct link to 1-assemblyscript") AssemblyScript is a lightweight, type-safe language that compiles to WebAssembly (Wasm). It is ideal for developing OP\_NET smart contracts due to its simplicity and speed. Key Features of AssemblyScript * TypeScript-like syntax for ease of use. * Optimized for performance in resource-constrained environments. * Strongly typed to prevent runtime errors. * * * ### **2\. Rust**[​](https://docs.opnet.org/developers/smart-contract-development/introduction#2-rust "Direct link to 2-rust") Rust is a powerful, memory-safe language known for its performance and reliability. Developers can use Rust to write advanced OP\_NET contracts with fine-grained control over execution. Key Features of AssemblyScript * High performance for complex contract logic. * Rich ecosystem and libraries for various use cases. * Memory safety ensures fewer runtime vulnerabilities. * * * ### **3\. More to Come**[​](https://docs.opnet.org/developers/smart-contract-development/introduction#3-more-to-come "Direct link to 3-more-to-come") OP\_NET is continually evolving, and support for additional languages is planned. Stay tuned for updates as new language integrations become available. * * * **What’s Next?**[​](https://docs.opnet.org/developers/smart-contract-development/introduction#whats-next "Direct link to whats-next") -------------------------------------------------------------------------------------------------------------------------------------- * Explore [Setting Up Your Development Environment](https://docs.opnet.org/developers/getting-started/setting-up-environment/for-nodejs) to begin coding your first OP\_NET smart contract. * Learn about [Unified Accounts](https://docs.opnet.org/learn/unified-accounts) and their role in OP\_NET development. * [**Supported Languages**](https://docs.opnet.org/developers/smart-contract-development/introduction#supported-languages) * [**1\. AssemblyScript**](https://docs.opnet.org/developers/smart-contract-development/introduction#1-assemblyscript) * [**2\. Rust**](https://docs.opnet.org/developers/smart-contract-development/introduction#2-rust) * [**3\. More to Come**](https://docs.opnet.org/developers/smart-contract-development/introduction#3-more-to-come) * [**What’s Next?**](https://docs.opnet.org/developers/smart-contract-development/introduction#whats-next) --- # Storing Data on OP_NET | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#__docusaurus_skipToContent_fallback) On this page Managing data efficiently is a cornerstone of smart contract development. OP\_NET offers a variety of classes and methods to handle persistent storage, optimized for performance and scalability. This guide provides an overview of storage concepts, available classes, and best practices for working with data on OP\_NET. Key Concepts * **Array Usage and Performance Considerations** * Arrays may not be optimal for performance in OP\_NET contracts. * Storage classes provide more efficient alternatives for specific use cases, especially for large or complex datasets. * **Native Closest Pointer Search** * The `TickBitmap` class offers a high-performance method for retrieving the next initialized storage pointer. * Ideal for applications like order books, staking systems, and time-sensitive triggers. * * * **Storage Classes on OP\_NET**[​](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#storage-classes-on-op_net "Direct link to storage-classes-on-op_net") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OP\_NET provides specialized classes for managing different types of data in contract storage: ### **1\. StoredBoolean**[​](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#1-storedboolean "Direct link to 1-storedboolean") * Stores boolean values in a storage slot. * Optimized for boolean logic with minimal storage overhead. Usage Example import { Blockchain, OP_NET, StoredBoolean,} from "@btc-vision/btc-runtime/runtime";class MyContract extends OP_NET { private isActive: StoredBoolean = new StoredBoolean( Blockchain.nextPointer, false ); public toggleActive(): void { this.isActive.value = !this.isActive.value; } public getActiveState(): bool { return this.isActive.value; }} * * * ### **2\. StoredString**[​](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#2-storedstring "Direct link to 2-storedstring") * Manages string data with support for splitting across multiple slots for long strings. Usage Example import { Blockchain, OP_NET, StoredString,} from "@btc-vision/btc-runtime/runtime";class MyContract extends OP_NET { private storedName: StoredString = new StoredString( Blockchain.nextPointer, "default" ); public setName(name: string): void { this.storedName.value = name; } public getName(): string { return this.storedName.value; }} * * * ### **3\. StoredU256**[​](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#3-storedu256 "Direct link to 3-storedu256") * Handles `u256` values with built-in arithmetic operations and storage management. Usage Example import { Blockchain, OP_NET, StoredU256,} from "@btc-vision/btc-runtime/runtime";import { u256 } from "as-bignum/assembly";class MyContract extends OP_NET { private storedAmount: StoredU256 = new StoredU256( Blockchain.nextPointer, u256.fromU32(0), u256.Zero ); public addAmount(amount: u256): void { this.storedAmount.add(amount); } public getAmount(): u256 { return this.storedAmount.value; }} * * * ### **4\. AddressMemoryMap**[​](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#4-addressmemorymap "Direct link to 4-addressmemorymap") * Maps an address to a `u256` value, useful for creating key-value stores. Usage Example import { Address, AddressMemoryMap, Blockchain, OP_NET,} from "@btc-vision/btc-runtime/runtime";import { u256 } from "as-bignum/assembly";class MyContract extends OP_NET { private balances: AddressMemoryMap = new AddressMemoryMap( Blockchain.nextPointer, u256.Zero ); public setBalance(address: Address, balance: u256): void { this.balances.set(address, balance); } public getBalance(address: Address): u256 { return this.balances.get(address); }} * * * ### **5\. MultiAddressMemoryMap**[​](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#5-multiaddressmemorymap "Direct link to 5-multiaddressmemorymap") * Extends `AddressMemoryMap` to allow mapping multiple keys to values, ideal for multi-dimensional mappings. Usage Example import { Address, Blockchain, MultiAddressMemoryMap, OP_NET, Uint8ArrayMerger,} from "@btc-vision/btc-runtime/runtime";import { u256 } from "as-bignum/assembly";class MyContract extends OP_NET { private allowances: MultiAddressMemoryMap = new MultiAddressMemoryMap( Blockchain.nextPointer, u256.Zero ); public setAllowance(owner: Address, spender: Address, amount: u256): void { const ownerData = this.allowances.get(owner) || new Uint8ArrayMerger(owner, Blockchain.nextPointer, u256.Zero); ownerData.set(spender, amount); this.allowances.set(owner, ownerData); } public getAllowance(owner: Address, spender: Address): u256 { const ownerData = this.allowances.get(owner); if (!ownerData) { return u256.Zero; } return ownerData.get(spender) || u256.Zero; }} * * * ### **6\. Serializable**[​](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#6-serializable "Direct link to 6-serializable") * Used for managing complex data structures by serializing them into chunks stored across multiple slots. Usage Example import { BytesReader, BytesWriter, MemorySlotPointer, Serializable,} from "@btc-vision/btc-runtime/runtime";import { u256 } from "as-bignum/assembly";class ComplexData extends Serializable { private data: u256; constructor(pointer: u16, subPointer: MemorySlotPointer, data: u256) { super(pointer, subPointer); this.data = data; } public writeToBuffer(): BytesWriter { const writer = new BytesWriter(32); writer.writeU256(this.data); return writer; } public readFromBuffer(reader: BytesReader): void { this.data = reader.readU256(); } public get chunkCount(): number { throw new Error("Method not implemented."); } public exists(): boolean { throw new Error("Method not implemented."); }} * * * **TickBitmap: Native Closest Pointer Search**[​](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#tickbitmap-native-closest-pointer-search "Direct link to tickbitmap-native-closest-pointer-search") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The `TickBitmap` class provides efficient pointer management and storage access. Usage Example function nextInitializedTick( tickIndex: u64, valueAtLeast: u256, lte: boolean): Potential { const storagePointer = TickBitmap.getStoragePointer(this.token, tickIndex); const nextStoragePointer = Blockchain.getNextPointerGreaterThan( storagePointer, valueAtLeast, lte ); if (nextStoragePointer.isZero()) return null; return new Tick(storagePointer, valueAtLeast, nextStoragePointer);} * * * **Best Practices**[​](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------------------- * Leverage `StoredBoolean`, `StoredString`, and other classes for optimized storage management. * Always validate inputs and outputs to prevent storage corruption. * Use compact and efficient storage methods to reduce transaction fees. * Utilize `TickBitmap` for efficient navigation of complex datasets. * [**Storage Classes on OP\_NET**](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#storage-classes-on-op_net) * [**1\. StoredBoolean**](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#1-storedboolean) * [**2\. StoredString**](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#2-storedstring) * [**3\. StoredU256**](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#3-storedu256) * [**4\. AddressMemoryMap**](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#4-addressmemorymap) * [**5\. MultiAddressMemoryMap**](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#5-multiaddressmemorymap) * [**6\. Serializable**](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#6-serializable) * [**TickBitmap: Native Closest Pointer Search**](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#tickbitmap-native-closest-pointer-search) * [**Best Practices**](https://docs.opnet.org/developers/smart-contract-development/storing-data-on-opnet#best-practices) --- # Getting Block Witnesses | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#__docusaurus_skipToContent_fallback) On this page The `getBlockWitness` method allows you to retrieve witness data for a specified block height. This method is useful for validating block integrity and examining the cryptographic signatures associated with a block. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#method "Direct link to method") ------------------------------------------------------------------------------------------------------------------------------------------------------------ getBlockWitness( height?: BigNumberish, trusted?: boolean, limit?: number, page?: number): Promise; * **Parameters**: * **`height?: BigNumberish`**: _(Optional)_ The height of the block to fetch witnesses for. Defaults to the latest block if not provided. * **`trusted?: boolean`**: _(Optional)_ Whether to include only trusted witnesses. Defaults to `false`. * **`limit?: number`**: _(Optional)_ The maximum number of witnesses to fetch per page. * **`page?: number`**: _(Optional)_ The page number for paginated witness data. * **Returns**: * **`Promise`**: An array of `IBlockWitness` objects containing witness details for the specified block height(s). * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#object-definitions "Direct link to object-definitions") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ `IBlockWitness` Object | **Property** | **Type** | **Description** | | --- | --- | --- | | **`blockNumber`** | `bigint \| string` | The block number associated with the witnesses. | | **`witnesses`** | `IBlockWitnessAPI[]` | An array of witnesses for the specified block. | `IBlockWitnessAPI` Object | **Property** | **Type** | **Description** | | --- | --- | --- | | **`trusted`** | `boolean` | Whether the witness is trusted. | | **`signature`** | `string` | The cryptographic signature of the witness. | | **`identity`** | `string` | _(Optional)_ The identity of the witness. | | **`opnetPubKey`** | `string` | _(Optional)_ The OP\_NET public key of the witness. | * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#example-usage "Direct link to example-usage") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### **Fetching Witnesses for a Block**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#fetching-witnesses-for-a-block "Direct link to fetching-witnesses-for-a-block") const blockHeight = BigInt(100); // Replace with desired block heightconst witnesses = await provider.getBlockWitness(blockHeight);witnesses.forEach((blockWitness) => { console.log("Block Number:", blockWitness.blockNumber); blockWitness.witnesses.forEach((witness) => { console.log("Trusted:", witness.trusted); console.log("Signature:", witness.signature); console.log("Identity:", witness.identity ?? "N/A"); console.log("OP_NET Public Key:", witness.opnetPubKey ?? "N/A"); });}); ### **Paginated Witness Fetching**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#paginated-witness-fetching "Direct link to paginated-witness-fetching") const paginatedWitnesses = await provider.getBlockWitness( blockHeight, true, 10, 1);console.log("Paginated Witnesses:", paginatedWitnesses); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#best-practices "Direct link to best-practices") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ * Use the `trusted` parameter to filter witnesses based on their trust status. * For blocks with many witnesses, use the `limit` and `page` parameters to manage the response size. * If the `height` parameter is omitted, the latest block's witnesses will be fetched. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#whats-next "Direct link to whats-next") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- After retrieving block witnesses, you can: * [Fetch Block Data](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data) * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#method) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#example-usage) * [**Fetching Witnesses for a Block**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#fetching-witnesses-for-a-block) * [**Paginated Witness Fetching**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#paginated-witness-fetching) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness#whats-next) --- # Getting Reorganizations (Reorgs) | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-reorgs#__docusaurus_skipToContent_fallback) On this page The `getReorg` method allows you to fetch details about blockchain reorganizations. Reorgs occur when a previously accepted chain of blocks is replaced by an alternative chain due to a higher cumulative proof of work. This method is essential for tracking and analyzing potential changes in the blockchain. * * * **Method**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-reorgs#method "Direct link to method") ----------------------------------------------------------------------------------------------------------------------------------------------------- getReorg( fromBlock?: BigNumberish, toBlock?: BigNumberish): Promise; * **Parameters**: * **`fromBlock?: BigNumberish`**: _(Optional)_ The starting block number to query reorgs from. * **`toBlock?: BigNumberish`**: _(Optional)_ The ending block number to query reorgs until. * **Returns**: * **`Promise`**: An array of `ReorgInformation` objects containing details about detected reorganizations. * * * **Object Definitions**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-reorgs#object-definitions "Direct link to object-definitions") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `ReorgInformation` Object | **Property** | **Type** | **Description** | | --- | --- | --- | | **`fromBlock`** | `string \| bigint` | The block number where the reorganization starts. | | **`toBlock`** | `string \| bigint` | The block number where the reorganization ends (new chain's head). | | **`timestamp`** | `number` | The UNIX timestamp of when the reorganization occurred. | * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-reorgs#example-usage "Direct link to example-usage") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- const reorgs = await provider.getReorg(100, 200);reorgs.forEach((reorg) => { console.log("Reorg Start Block:", reorg.fromBlock); console.log("Reorg End Block:", reorg.toBlock); console.log( "Reorg Timestamp:", new Date(reorg.timestamp * 1000).toISOString() );}); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-reorgs#best-practices "Direct link to best-practices") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Ensure that the `fromBlock` and `toBlock` parameters are within the range of available blocks on the network. * Reorgs are rare but crucial events that can affect transaction finality and chain data integrity. * The `timestamp` property provides the exact time of the reorganization, enabling detailed analysis. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-reorgs#whats-next "Direct link to whats-next") ------------------------------------------------------------------------------------------------------------------------------------------------------------------- After analyzing reorg data, you can: * [Fetch Block Data](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data) * [Fetch Block Witnesses](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-block-witness) * [**Method**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-reorgs#method) * [**Object Definitions**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-reorgs#object-definitions) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-reorgs#example-usage) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-reorgs#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/get-reorgs#whats-next) --- # Batch Requests | OP_NET Docs [Skip to main content](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#__docusaurus_skipToContent_fallback) On this page The `callPayloadSingle`, `callMultiplePayloads`, and `buildJsonRpcPayload` methods allow you to send single or multiple JSON-RPC payloads to an OP\_NET node. Batch requests are an efficient way to group multiple operations into a single network call, reducing latency and improving performance. * * * **Available Methods**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#available-methods "Direct link to available-methods") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ### **1\. Single Payload Call**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#1-single-payload-call "Direct link to 1-single-payload-call") callPayloadSingle(payload: JsonRpcPayload): Promise; * **Parameters**: * **`payload: JsonRpcPayload`**: The JSON-RPC payload to send. * **Returns**: * **`Promise`**: The result of the single JSON-RPC call. * * * ### **2\. Multiple Payloads Call**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#2-multiple-payloads-call "Direct link to 2-multiple-payloads-call") callMultiplePayloads(payloads: JsonRpcPayload[]): Promise; * **Parameters**: * **`payloads: JsonRpcPayload[]`**: An array of JSON-RPC payloads to send. * **Returns**: * **`Promise`**: An array of results for each JSON-RPC call in the batch. * * * ### **3\. Build JSON-RPC Payload**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#3-build-json-rpc-payload "Direct link to 3-build-json-rpc-payload") buildJsonRpcPayload( method: T, params: unknown[]): JsonRpcPayload; * **Parameters**: * **`method: T`**: The JSON-RPC method to call. * **`params: unknown[]`**: An array of parameters for the method. * **Returns**: * **`JsonRpcPayload`**: The constructed JSON-RPC payload. * * * **Example Usage**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#example-usage "Direct link to example-usage") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ### **Build a Payload**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#build-a-payload "Direct link to build-a-payload") import { JSONRpcMethods } from "opnet";// Example: Get block data for block number 100const payload = provider.buildJsonRpcPayload( JSONRpcMethods.GET_BLOCK_BY_NUMBER, [100]); ### **Single Payload Call**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#single-payload-call "Direct link to single-payload-call") const result = await provider.callPayloadSingle(payload);if ("error" in result) { console.error("Error:", result.error.message);} else { console.log("Block Data:", result.result);} * * * ### **Batch Payload Call**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#batch-payload-call "Direct link to batch-payload-call") const payloads = [ provider.buildJsonRpcPayload(JSONRpcMethods.GET_BLOCK_BY_NUMBER, [100]), provider.buildJsonRpcPayload(JSONRpcMethods.GET_BLOCK_BY_NUMBER, [101]), // ... Add multiple payloads here];const batchResults = await provider.callMultiplePayloads(payloads);batchResults.forEach((result, index) => { if ("error" in result) { console.error(`Error for Block ${index + 100}:`, result.error.message); } else { console.log(`Block ${index + 100} Data:`, result.result); }}); * * * **Best Practices**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#best-practices "Direct link to best-practices") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Always handle errors for individual payloads in the batch response. * Batch requests significantly reduce the overhead of multiple network calls, making them ideal for high-performance applications. * Use the `buildJsonRpcPayload` method to ensure payloads are constructed correctly with the appropriate `JSONRpcMethods`. * * * **What’s Next?**[​](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#whats-next "Direct link to whats-next") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- After mastering batch requests, explore: * [Fetching Block Data](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/fetching-block-data) * [Advanced Interactions with Call](https://docs.opnet.org/developers/interacting-with-an-opnet-node/using-a-provider/interacting-with-smart-contracts-using-call) * [**Available Methods**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#available-methods) * [**1\. Single Payload Call**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#1-single-payload-call) * [**2\. Multiple Payloads Call**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#2-multiple-payloads-call) * [**3\. Build JSON-RPC Payload**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#3-build-json-rpc-payload) * [**Example Usage**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#example-usage) * [**Build a Payload**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#build-a-payload) * [**Single Payload Call**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#single-payload-call) * [**Batch Payload Call**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#batch-payload-call) * [**Best Practices**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#best-practices) * [**What’s Next?**](https://docs.opnet.org/developers/interacting-with-an-opnet-node/advanced-node-interactions/batch-requests#whats-next) ---