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
  • GetAccountMetadata()
  • GetTransactionByHash()
  • Creating an account
  • From an existing private key
  • Generating a new private key
  • Getting account details
  • Sending a transfer of IOTX
  • Signing a message
  • Storing the private key to persistent memory in the device
  • Sending a XRC20 token transfer
  • Calling a contract function

Was this helpful?

Export as PDF
  1. Builders
  2. Reference Docs
  3. Embedded Blockchain Clients

Examples

GetAccountMetadata()

Gets the account metadata for an IoTeX address.

AccountMeta accountMeta;
ResultCode result = connection.api.wallets.getAccount("io1xkx7y9ygsa3dlmvzzyvv8zm6hd6rmskh4dawyu", accountMeta);

If result is SUCCESS then the account metadata is be stored in accountMeta The account metadata contains the following fields:

  • address: the IoTeX address

  • balance: the balance in RAU

  • nonce: the account nonce

  • pendingNonce: the account's pending nonce

  • isContract: true if the address is a contract

GetTransactionByHash()

Gets the data for a transfer given the transaction hash.

ActionInfo_Transfer data;
ResultCode result = connection.api.wallets.getTransactionByHash("5444318f1a460c74d3e86918b640272d93d0b30e2bf2dc329dfd3faa636e52ec", data);

If result is SUCCESS then the action data is stored in data. The transfer action data contains the following fields:

{
  actHash
  blkHash
  timestamp
  blkHeight
  sender
  gasFee
  action {
    senderPublicKey
    signature
    core
    version
    nonce
    gasLimit
    gasPrice
    execution
    amount
    contract
    data
  }
}

Creating an account

We can create an account in the device from an existing private key, or generating a new private key.

From an existing private key

const char pkString[] = <private_key>;

// Convert the privte key hex string byte array
uint8_t pkBytes[IOTEX_PRIVATE_KEY_SIZE];
signer.str2hex(pkString, pkBytes, IOTEX_SIGNATURE_SIZE);

Account account(pkBytes);

Generating a new private key

// Generate a random private key
uint8_t pkBytes[IOTEX_PRIVATE_KEY_SIZE];
randomGenerator.fillRandom(pkBytes, sizeof(pkBytes));

// Create the account 
Account account(pkBytes);

Getting account details

Now that the account is created, you can get the address in Ethereum or IoTeX format, and the public/private keys:

// Create buffers for the account details
char publicKeyBuf[IOTEX_PUBLIC_KEY_C_STRING_SIZE] = {0};
char privateKeyBuf[IOTEX_PRIVATE_KEY_C_STRING_SIZE] = {0};
char ethAddressBuf[ETH_ADDRESS_C_STRING_SIZE] = {0};
char ioAddressBuf[IOTEX_ADDRESS_C_STRING_SIZE] = {0};

// Get the account details (ad hexadecimal strings)
account.getPublicKeyString(publicKeyBuf);
account.getPrivateKeyString(privateKeyBuf);
account.getEthereumAddress(ethAddressBuf);
account.getIotexAddress(ioAddressBuf);

Sending a transfer of IOTX

Sends a transfer of IOTX tokens

First create the account object:

// Private key of the origin address
const char pkString[] = <private_key>;

// Destination IoTeX address
char destinationAddr[IOTEX_ADDRESS_C_STRING_SIZE] = <destination_address>;

// Convert the private key and address hex strings to byte arrays
uint8_t pkBytes[IOTEX_PRIVATE_KEY_SIZE];
signer.str2hex(pkString, pkBytes, IOTEX_SIGNATURE_SIZE);

// Create the account object
Account originAccount(pkBytes);

// Get the IoTeX address
char originIotexAddr[IOTEX_ADDRESS_C_STRING_SIZE] = "";
originAccount.getIotexAddress(originIotexAddr);

Then query the blockchain to get the account nonce:

AccountMeta accMeta;
ResultCode result = connection.api.wallets.getAccount(originIotexAddr, accMeta);
IotexString nonceString = accMeta.pendingNonce;
uint64_t nonce = atoi(nonceString.c_str());

Now broadcast the transfer with the retrieved nonce:

// Amount of RAU to transfer. Eg: 1 RAU
char amount[IOTEX_ADDRESS_C_STRING_SIZE] = "1";

// Send the transfer 
uint8_t hash[IOTEX_HASH_SIZE] = {0};
result = originAccount.sendTokenTransferAction(connection, nonce, 20000000, "1000000000000", amount, destinationAddr, hash);

Signing a message

Signs a message.

First convert the private key to a byte array:

const char pkString[] = <private_key>;
uint8_t pkBytes[IOTEX_PRIVATE_KEY_SIZE];
signer.str2hex(pkString, pkBytes, IOTEX_SIGNATURE_SIZE);

Now sign the message

// Message to sign as a byte array
const uint8_t message[] = { 0xab, 0xcd };
uint8_t signature[IOTEX_SIGNATURE_SIZE] = {0};
signer.signMessage(message, sizeof(message), pkBytes, signature);

The signature is stored as a byte array in signature.

Storing the private key to persistent memory in the device

You can store the private key in the EEPROM or flash memory of your Arduino device, or in a text file in Linux.

First convert the private key to a byte array:

const char pkString[] = <private_key>;
uint8_t pkBytes[IOTEX_PRIVATE_KEY_SIZE];
signer.str2hex(pkString, pkBytes, IOTEX_SIGNATURE_SIZE);

First initialize the storage module (not needed for Nano33 IoT or Linux):

// The number of bytes we want to use for the EEPROM
// This is passed to EEPROM.begin()
// Should be at least IOTEX_PRIVATE_KEY_SIZE
uint32_t eepromSize = IOTEX_PRIVATE_KEY_SIZE;
storage.Initialize(eepromSize);

Now store the private key:

// Specify any address number between 0 and (eepromSize - IOTEX_PRIVATE_KEY_SIZE). 
// This is the EEPROM address where the private key is stored. 
// There needs to be suficcient space between eepromAddress and eepromSize to store the whole private key (at least IOTEX_PRIVATE_KEY_SIZE bytes)
const uint32_t eepromAddress = 0;
ResultCode result = storage.savePrivateKey(eepromAddress, pkBytes);

You can also read the private key that is stored in the device:

result = storage.readPrivateKey(eepromAddress, pkBytes);

Sending a XRC20 token transfer

First convert the private key to a byte array:

const char pkString[] = <private_key>;
uint8_t pkBytes[IOTEX_PRIVATE_KEY_SIZE];
signer.str2hex(pkString, pkBytes, IOTEX_SIGNATURE_SIZE);

Similarly, convert the destination address to a byte array:

const char destAddrString[] = "0x5840bf8e5d3f5b66EE52B9b933bDAC9682E386D0";
uint8_t destAddrBytes[ETH_ADDRESS_SIZE];
signer.str2hex(destAddrString, destAddrBytes, ETH_ADDRESS_SIZE);

Generate the contract call data:

// Amount to transfer
uint64_t value = 1000000000000000000;
uint8_t data[IOTEX_CONTRACT_ENCODED_TRANSFER_SIZE] = {0};
Xrc20Contract::generateCallDataForTransfer(destAddrBytes, value, data);
char callData[IOTEX_CONTRACT_ENCODED_TRANSFER_SIZE * 2 + 1] = {0};
signer.hex2str(data, IOTEX_CONTRACT_ENCODED_TRANSFER_SIZE, callData, sizeof(callData));

Create the account object and get the account metadata in order to obtain the nonce:

Account originAccount(pkBytes);
AccountMeta accMeta;
char originIotexAddr[IOTEX_ADDRESS_STRLEN] = {0};
originAccount.getIotexAddress(originIotexAddr);
connection.api.wallets.getAccount(originIotexAddr, accMeta);
int nonce = atoi(accMeta.pendingNonce.c_str());

Broadcast the XRC20 token transfer

// The token address. Eg: VITA token
const char tokenAddress[] = "io1hp6y4eqr90j7tmul4w2wa8pm7wx462hq0mg4tw";
uint8_t hash[IOTEX_HASH_SIZE] = {0};
ResultCode result = originAccount.sendExecutionAction(connection, atoi(accMeta.pendingNonce.c_str()), 20000000, "1000000000000", "0", tokenAddress, callData, hash);

Calling a contract function

First convert the private key to a byte array:

const char pkString[] = <private_key>;
uint8_t pkBytes[IOTEX_PRIVATE_KEY_SIZE];
signer.str2hex(pkString, pkBytes, IOTEX_SIGNATURE_SIZE);

Create the account object and get the account metadata in order to obtain the nonce:

Account originAccount(pk);
AccountMeta accMeta;
char originIotexAddr[IOTEX_ADDRESS_C_STRING_SIZE] = "";
originAccount.getIotexAddress(originIotexAddr);
ResultCode result = connection.api.wallets.getAccount(originIotexAddr, accMeta);
int nonce = atoi(accMeta.pendingNonce.c_str());

Create the function call parameters:

ParameterValue paramImei = MakeParamString(imei);
ParameterValue paramData = MakeParamBytes(data, sizeof(data), true);
ParameterValue paramSig = MakeParamBytes(signature, sizeof(signature), true);

Create the dictionary that contain the parameters and their values:

ParameterValuesDictionary params;
params.AddParameter("imei", paramImei);
params.AddParameter("data", paramData);
params.AddParameter("signature", paramSig);

Create the contract object:

// The contract abi as a serialized json string
String abi = <contract_abi_json_string>;
Contract contract(abi);

Generate the call data:

String callData = "";
contract.generateCallData("addData", params, callData);

Broadcast the contract execution action

uint8_t hash[IOTEX_HASH_SIZE] = {0};
result = originAccount.sendExecutionAction(connection, nonce, 20000000, "1000000000000", "0", contractAddress, callData, hash);
PreviousPlatformIONextTutorials

Last updated 11 months ago

Was this helpful?

This example shows how to call a contract function using the addData function of the contract with address io1n49gavyahsukdvvxxandkxephdx93n3atcrqur as an example. You can find the contract ABI .

here