LogoLogo
WalletsEcosystemStart BuildingJoin the Community
  • Welcome to IoTeX 2.0
    • 💡Why IoTeX
    • 🪙Tokenomics
      • IOTX Utility in IoTeX 2.0
      • IOTX Emission, Deflation, and Re-Staking
    • 📖Whitepaper
    • ⚡Get Started
  • DePIN Infra Modules (DIM)
    • DIMs Overview
    • [IoTeX L1] DePIN Blockchain
      • Core Concepts
        • Consensus Mechanism
        • Voters and Delegates
        • Ethereum Virtual Machine
        • Accounts & Identities
        • Blockchain Actions
        • ERC20 and NFT Tokens
        • Smart Contracts
        • Interoperability
        • Governance
      • The IOTX Token
        • IOTX Token Exchange Support
        • Different Formats of the IOTX Token
        • IOTX Token Contracts
      • Wallets
        • Supported Wallet Apps
          • ioPay Mobile
          • IoTeX Web Wallet
          • OKX Wallet
          • Rabby Wallet
          • Metamask Desktop
          • Ledger Nano S & X
            • Use Ledger with Metamask
            • Use Ledger with Rabby Walet
            • Use Ledger with IoTeX Hub Portal
            • Migrate to the Ethereum Ledger App
          • IoTeX Desktop Wallet
          • 👩‍💻IoTeX HD Derivation Path
        • Buy IOTX Tokens
        • Execute Transactions
          • Transfer IOTX Tokens
          • Transfer ERC20 Tokens
          • Interact with Dapps
          • Explore transactions
        • Migrate Assets to a different wallet
      • Staking & Governance
        • About IoTeX Staking
        • IoTeX Staking Guide
          • Native staking
          • Staking as NFT
        • Join the Governance
          • Marshall DAO
          • Improvement Proposals
      • Exchange Integration
      • 👨‍💻Deploy Dapps on IoTeX
    • [ioID] DePIN Identities
      • ioID Specification
      • Overview of ioID
      • Registering Identities
      • 👩‍💻Integration Guide
        • Register a DePIN Project
        • Bind your Device NFT
        • Reserve Device ioIDs
        • Query Project Status
        • Register a Device
        • ioID Smart contracts quick reference
    • [W3bstream] DePIN Verification
      • Overview of W3bstream
      • Multi-Prover Architecture
      • 👨‍💻Build with W3bstream
        • Get Started
          • Sequencer Options
        • Build the Prover Code
          • Risc Zero
          • Halo2
          • zkWASM
        • Deploy to W3bstream
          • Create the Project File
          • W3bstream Outputs
          • Deploying Projects
          • Interacting with Projects
        • On-chain integration
          • Verify Risc0 Proofs
          • Verify Halo2 Proofs
          • Verify zkWASM profs
        • Sending Messages
      • 👩‍💻Node Operators
        • Configure a ZK Prover Node
        • Register your Node
    • [ioID-SDK] Hardware SDK
      • ioID-SDK Overview
      • Layered Architecture
      • Compatibility
      • Current Development Status
    • [MSP] Modular Security Pool
    • Third-Party DIMs
      • Data Sequencer Infras
      • Data Availability Infras
      • 👨‍💻W3bstream Tasks
  • Ecosystem
    • Assets on IoTeX
      • Mainstream Assets
      • IOTX and Derivatives
      • DePIN Tokens
      • MEME Coins
    • iotube Bridge
    • iotexscan Explorer
    • Ecosystem Apps
      • DePINScan
      • mimo DEX
      • ecosystem.iotex.io
    • "Powered by IoTeX" Devices
      • Pebble Tracker
        • Quick Start
        • Device Registration
        • Online Firmware Update
        • USB Firmware Update
        • Migrating to Pebble v2.0
          • 1.0 Device Registration
        • Tech Specs
        • Network Selection
        • Pebble Configuration
        • Query Pebble Data
        • Troubleshooting
        • Firmware Development
          • Hardware Setup
          • Build the Firmware
          • Flash the firmware
      • SenseCAP Indicator
      • UCam Home Camera
  • Builders
    • IoTeX Developer Portal
    • Dev Chat on Discord
    • Web3 Development
      • RPC Endpoints
      • Set up your Environment
      • Get Testnet IOTX Tokens
      • ioctl CLI
        • Installation
        • Create Accounts
        • Blockchain interaction
          • ioctl command reference
      • Chain Indexing
        • The Graph
        • SubQuery
        • IoTeX Analytics API
      • IoTeXscan API
      • Deterministic Deployment
      • Account Abstraction
        • Components of AA
        • 👩‍💻Creating new Accounts
        • 👨‍💻P256Account Example
      • Blob Transactions (EIP-4844)
      • Multicall3
      • EVM Precompiled Contracts
    • Building DePINs
      • ioID Step by Step Tutorial
        • Integrate ioID in the Device Firmware
        • Integrate ioID in your cloud
      • Decentralized WiFi Connectivity (DeWi)
        • Project Specification
        • The choice of Hardware
        • The Data API Service
        • DePIN Incentives Contract
    • Building DeFi
      • Deploy Tokens
        • Deploy an ERC20 Token
        • Deploy an NFT Token
      • Price Oracles
        • Chainlink Relayer
        • SupraOracles
      • Integrate IoTeX Staking
      • Liquid staking Dapps
    • Launch Dapps on IoTeX
      • Submit Tokens to the IoTeX Ecosystem
      • Submit tokens to the iotube bridge
      • Verify Smart Contracts
      • Audit your Contracts
      • Submit your Dapp to Portals
      • Useful tools
    • Node Operators
      • Fastblocks (Node as a Service)
      • Setup an IoTeX RPC Node
      • Run a Delegate Node
      • Rosetta API
    • Reference Docs
      • ioctl client
        • Accounts
        • HD Wallets
        • Aliases
        • Actions
        • Queries
        • Smart Contracts
        • Staking & Voting
        • Tokens
        • ioID Identities
        • W3bstream
        • Decentralized Identifiers (DID)
        • JWT Auth Tokens
      • Native IoTeX Development
        • IoTeX gRPC API
        • Account Cryptography
        • Address Conversion
        • Create Accounts
        • Estimate Gas Price
        • Make IOTX Transfers
        • Manage ERC20 Tokens
        • Smart Contract Interactions
        • ioPay Desktop
        • DID JWT Tokens
        • Calling any RPC method
      • Embedded Blockchain Clients
        • Arduino IDE
        • Linux Systems
        • PlatformIO
        • Examples
        • Tutorials
  • Participate
    • Crypto's Got Talent (CGT)
      • IoTeX x Polygon DePIN Grant
    • Governance
      • IoTeX Improvement Proposals
      • The Marshall DAO
    • Join the Community
    • Get in Touch
Powered by GitBook
LogoLogo

This documentation portal is currently undergoing updates to align with the IoTeX 2.0 Whitepaper release. Information provided here may be incomplete, or out-of-date. Please use this portal for preliminary reference only, and check out the official IoTeX 2.0 Whitepaper for updated information.

  • .

2025 | IoTeX

On this page
  • IoTeX Staking Integration
  • Utilizing the Ethereum API
  • How it works
  • The Staking Virtual Contract
  • Examples
  • Retrieving the Contract Interface Using Metamask
  • Creating a new stake
  • Unstake a deposit
  • Withdraw an unstaked deposit
  • Read the details of a bucket
  • List the buckets owned by a specific address
  • Utilizing the Native API

Was this helpful?

Export as PDF
  1. Builders
  2. Building DeFi

Integrate IoTeX Staking

PreviousSupraOraclesNextLiquid staking Dapps

Last updated 11 months ago

Was this helpful?

IoTeX Staking Integration

In this section, we'll guide you through the process of integrating IoTeX Staking into staking platforms that offer Stake as a Service. Developers have two options for integrating IoTeX Staking into their systems: utilizing the Ethereum RPC API or IoTeX's native protocol. We recommend the Ethereum JSON RPC API because it offers compatibility with Ethereum development libraries and tools, making it the preferred choice for most developers.

Utilizing the Ethereum API

With the adoption of the improvement proposal, it became possible to perform staking actions on the IoTeX blockchain via Ethereum JSON RPC calls. This advancement allows for the creation and management of staking using regular Ethereum transactions. These transactions can be easily created with tools such as Web3.js and can be signed by wallets like Metamask.

How it works

The IoTeX blockchain allows staking actions through standard Ethereum API calls via a mechanism known as a "Virtual Contract". A virtual contract is essentially a designated blockchain address pre-set within the IoTeX protocol. Any transactions directed to this address are undergo a dedicated process by the protocol. Specifically, these transactions are expected to contain a payload which holds the encoded native message for the desired staking operation. The IoTeX protocol then decodes and performs the specific action included within the Ethereum transaction payload.

The Staking Virtual Contract

The address below is the pre-set address designated to symbolize the native staking contract. Ethereum transactions directed to this address will be converted into native staking actions by the IoTeX protocol upon decoding the actual staking action from the transaction payload.

To facilitate the task of reading the status of staking deposits on IoTeX through the Ethereum API, the same address can be utilized as a "Read Contract" to perform any type of read action on the status of staking.

|

Network
Address

Testnet & Mainnet

0x04c22afae6a03438b8fed74cb1cf441168df3f12

It's important to note that this isn't a conventional smart contract that is deployed and resides on the blockchain with a specific contract address. Rather, it's a pre-defined address recognized solely by the blockchain protocol, which processes incoming transactions in a unique manner. Its sole purpose is to facilitate access to the IoTeX protocol's staking actions for an Ethereum client. As a result, while you can send execution or read transactions to this address using the Ethereum JSON RPC API, you cannot call the same functions from another smart contract. This is because the virtual contract isn't visible to the EVM.

Examples

Interacting with the virtual contract via JSON-RPC is no different from interacting with a real EVM contract. Here are some examples on how to interact with IoTeX Native staking using the IIP12 virtual contract via a web3 client. For these demonstrations, we'll utilize the ethers.js library.

Retrieving the Contract Interface Using Metamask

import ethers from "ethers";

const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
// Make sure to assign the ABI to the abi variable
const stakingContract = new ethers.Contract('0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12', abi, signer);

Creating a new stake

The example below creates a new staking with a deposit amount of 100 IOTX, a duration of 91 days and the StakeLock option enabled. The resulting bucket of votes is assigned to the delegate "delegateName".

Contract function signature:

async function createStake(candName: string, amount: number, duration: number, autoStake: boolean, data: string[])

Code:

// 100 IOTX = 100 * 1e18
const transaction = await stakingContract.createStake('delegatename', '100000000000000000000', 91, true, []);
console.log(transaction); 

The resulting log would look like the following. Notice that, if the transaction is successful, then receipt.Status will equal 1:

{
    "receipt": {
        "to": "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12",
        "from": "0x1745a52aA2939422D603FB5035ECb0db686a647c",
        "contractAddress": null,
        "transactionIndex": 1,
        "gasUsed": {
            "type": "BigNumber",
            "hex": "0x2710"
        },
        "logsBloom": "0x00000000000008000000000000004000000000000002000000000000000000000000000000000000000000000000000000800000000040000000000008020000000000000000000000000000000000000000000000000000000040000100000000000080000000000000004000000000000000000000000000000000000000010000200080000000080200000000000000000000000000000000000000000000000000000000000000000000010000000000000000001000800000000000000000000000000000000000000000000000000000000000000000000000000000000000020240000000000000000000000000200000000008000000000000000000",
        "blockHash": "0x6c3532bae6db560a154018888f77b6d19ec0bc8cbb8c15614c432fd811781e26",
        "transactionHash": "0xb64b6c3cb492293d53a0e10fe582edbc7506960e4ae45fd13194eb9cd06f98a1",
        "logs": [
            {
                "transactionIndex": 1,
                "blockNumber": 26295171,
                "transactionHash": "0xb64b6c3cb492293d53a0e10fe582edbc7506960e4ae45fd13194eb9cd06f98a1",
                "address": "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12",
                "topics": [
                    "0x0000000000000000000000000000000000000000006372656174655374616b65"
                ],
                "data": "0x",
                "logIndex": 1,
                "blockHash": "0x6c3532bae6db560a154018888f77b6d19ec0bc8cbb8c15614c432fd811781e26"
            }
        ],
        "blockNumber": 26295171,
        "confirmations": 2,
        "cumulativeGasUsed": {
            "type": "BigNumber",
            "hex": "0x2710"
        },
        "status": 1,
        "type": 0,
        "byzantium": true
    },
    "hash": "0xb64b6c3cb492293d53a0e10fe582edbc7506960e4ae45fd13194eb9cd06f98a1"
}
*/

Unstake a deposit

Contract function signature:

function unstake(bucketIndex: string, data: string[])

Code:

const transaction = await stakingContract.unstake('1', []);

Withdraw an unstaked deposit

Contract function signature:

function withdrawStake(bucketIndex: string, data: string[])

Code:

const transaction = await stakingContract.withdrawStake('1', []);

Read the details of a bucket

Contract function signature:

function bucketsByIndexes(indexes: string[])

Code:

const response = await stakingContract.bucketsByIndexes(['1']);
console.log(response); 

Example log output:

[
    [
        {
            "0": {
                "type": "BigNumber",
                "hex": "0xd9"
            },
            "1": "0xB7860456d0918B14d75EDb53216F5C9eb22859D8",
            "2": {
                "type": "BigNumber",
                "hex": "0x056bc75e2d63100000"
            },
            "3": 2,
            "4": {
                "type": "BigNumber",
                "hex": "0x64b60297"
            },
            "5": {
                "type": "BigNumber",
                "hex": "0x65236599"
            },
            "6": {
                "type": "BigNumber",
                "hex": "0x00"
            },
            "7": true,
            "8": "0x1745a52aA2939422D603FB5035ECb0db686a647c",
            "index": "1",
            "candidateAddress": "0xB7860456d0918B14d75EDb53216F5C9eb22859D8",
            "stakedAmount": "100000000000000000000",
            "stakedDuration": "2",
            "createTime": "1689649815",
            "stakeStartTime": "1696818585",
            "unstakeStartTime": "0",
            "autoStake": true,
            "owner": "0x1745a52aA2939422D603FB5035ECb0db686a647c"
        }
    ]
]

List the buckets owned by a specific address

Contract function signature:

function bucketsByVoter(voter: string, offset: string, limit: string)

Code:

const response = await stakingContract.bucketsByVoter('io1zaz6224zjw2z94srldgrtm9smd5x5eruzmulnv', '0', '10000'); 
console.log(response); // Response like following.

Example log output:

[
    [
        {
            "0": {
                "type": "BigNumber",
                "hex": "0xd2"
            },
            "1": "0x5D34b7115124B80863f20CB07D16E403A280C1Ce",
            "2": {
                "type": "BigNumber",
                "hex": "0x056bc75e2d63100000"
            },
            "3": 1,
            "4": {
                "type": "BigNumber",
                "hex": "0x649d4ca7"
            },
            "5": {
                "type": "BigNumber",
                "hex": "0x649d4ca7"
            },
            "6": {
                "type": "BigNumber",
                "hex": "0x00"
            },
            "7": true,
            "8": "0x1745a52aA2939422D603FB5035ECb0db686a647c",
            "index": "210",
            "candidateAddress": "0x5D34b7115124B80863f20CB07D16E403A280C1Ce",
            "stakedAmount": "100000000000000000000",
            "stakedDuration": "1",
            "createTime": "1688030375",
            "stakeStartTime": "1688030375",
            "unstakeStartTime": "0",
            "autoStake": true,
            "owner": "0x1745a52aA2939422D603FB5035ECb0db686a647c"
        },
        {
            "0": {
                "type": "BigNumber",
                "hex": "0xd4"
            },
            "1": "0xC0EdD40Ec22053B849cBb93181dD1651472d6430",
            "2": {
                "type": "BigNumber",
                "hex": "0x056bc75e2d63100000"
            },
            "3": 5,
            "4": {
                "type": "BigNumber",
                "hex": "0x64a2979d"
            },
            "5": {
                "type": "BigNumber",
                "hex": "0x64afb9f5"
            },
            "6": {
                "type": "BigNumber",
                "hex": "0x00"
            },
            "7": false,
            "8": "0x1745a52aA2939422D603FB5035ECb0db686a647c",
            "index": "212",
            "candidateAddress": "0xC0EdD40Ec22053B849cBb93181dD1651472d6430",
            "stakedAmount": "100000000000000000000",
            "stakedDuration": "5",
            "createTime": "1688377245",
            "stakeStartTime": "1689238005",
            "unstakeStartTime": "0",
            "autoStake": false,
            "owner": "0x1745a52aA2939422D603FB5035ECb0db686a647c"
        }
    ]
]

Utilizing the Native API

Unlike other implementations, staking in the IoTeX blockchain is incorporated into the network protocol instead of utilizing contracts. Consequently, developers can utilize the native IoTeX API, through the official , for staking management purposes.

IIP12
Visit the original IIP12 Proposal ->
Source Code
ABI
Antenna SDK
Explore the Native SDK on GitHub ->