1Money Network
  • Getting Started
  • Overview
  • Developer Guide
  • Quick Start
  • User Guides
    • Custodians & Centralized Exchanges (CEXs)
    • Issuers
  • Validators
  • Integrations
    • Overview
    • Network Access
    • SDKs
      • Typescript
        • Get Started
        • API Methods
      • Golang
        • Get Started
        • API methods
      • Rust
    • REST APIs
      • Chains
        • Get Chain Id
      • Accounts
        • Get account by token
        • Get account nonce
      • Tokens
        • Issue token
        • Get token metadata
        • Update token metadata
        • Grant authority
        • Mint
        • Burn
        • Managelist
        • Pause/Unpause
      • Checkpoints
        • Get the latest Checkpoint number
        • Get checkpoint by number
        • Get checkpoint by hash
      • Transactions
        • Get transaction by hash
        • Get transaction receipt by hash
        • Submit payment
        • Submit cancellation
        • Estimate fee
    • Websocket
      • Subscribing & Unsubscribing
      • Retrieving Transaction Details
      • Keeping the connection alive
      • Stream | Checkpoints
    • Data Dictionary
      • Transaction Types
        • TokenCreate
        • TokenTransfer
        • TokenGrantAuthority
        • TokenRevokeAuthority
        • TokenBlacklistAccount
        • TokenWhitelistAccount
        • TokenMint
        • TokenBurn
        • TokenCloseAccount
        • TokenPause
        • TokenUnpause
        • TokenUpdateMetadata
          • TokenMetadata Structure
            • MetaDataKeyValuePair
        • Other Transaction Types (WiP)
  • Core Concepts
    • The 1Money Protocol
    • System Components
    • Account Model
    • Token Authority
    • Transactions and Instructions
    • Implementation and usability considerations
    • Security
Powered by GitBook
On this page
  1. Core Concepts

Account Model

PreviousSystem ComponentsNextToken Authority

Last updated 17 days ago

1Money implements an Account Model (vs UTXO) for its ledger, where, aside from asset positions, also contains properties governing different issuance functions. Account types include:

Account Types

StateAccount

StateAccount represents a standard user account that can participate in regular transactions.

Key Properties:

  • Nonce: A counter that increments with each transaction to prevent replay attacks

Use Cases:

  • Serving as the base account type for users to manage their token holdings


MintAccount

Mint accounts are specialized accounts that control the creation and management of tokens in the system. They represent the authority over a specific token type.

Key Properties:

  • Nonce: A counter for transaction sequencing

  • Token metadata and configuration

  • Authority information

Use Cases:

  • Creating new tokens

  • Minting additional token supply

  • Managing token authorities

  • Updating token metadata

  • Pausing/unpausing token transfers


TokenAccount

TokenAccount represents an account that holds a specific token type. It tracks the ownership and balance of tokens for a particular user.

You should be able to derive your token account based on your state account and mint account

Key Properties:

  • Mint: Address of the mint that issued this token

  • Amount: The token balance

  • Owner: Address of the account that owns these tokens

Use Cases:

  • Holding token balances

  • Transferring tokens between users

  • Tracking token ownership


Sample code of Typescript how to derive token account from state account and mint account

import { keccak256, hexToBytes, stringToBytes, bytesToHex } from 'viem';
export type Address = `0x${string}`;
/**
 * Derives the token account address given the wallet address and mint address.
 * 
 * Address is 20 byte, 160 bits. Let's say if we want to support 50 billion
 * accounts on 1money. That's about 36 bits. There are 124 bits remaining. In
 * other words, the collision probability is 1/2^124, which is very very low.
 * So, we will be fine to just use the hash of the wallet address and mint
 * address to derive the token account address.
 * 
 * @param walletAddress - The wallet address (20 bytes)
 * @param mintAddress - The mint address (20 bytes)
 * @returns The derived token account address
 */
export function deriveTokenAddress(
  walletAddress: string,
  mintAddress: string,
): Address {
  const walletBytes: Uint8Array = walletAddress.startsWith('0x')
    ? hexToBytes(walletAddress as Address)
    : stringToBytes(walletAddress);
  const mintBytes: Uint8Array = mintAddress.startsWith('0x')
    ? hexToBytes(mintAddress as Address)
    : stringToBytes(mintAddress);
  const combined = new Uint8Array(walletBytes.length + mintBytes.length);
  combined.set(walletBytes, 0);
  combined.set(mintBytes, walletBytes.length);
  const hashHex = keccak256(combined);
  const hashBytes = hexToBytes(hashHex);
  const addressBytes = hashBytes.slice(12);
  return bytesToHex(addressBytes) as Address;
}

Sample code of Go how to derive token account from state account and mint account

import (
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/crypto"
)

// DeriveTokenAccountAddress derives the token account address given the wallet address and mint address.
// 
// Address is 20 byte, 160 bits. Let's say if we want to support 50 billion
// accounts on 1money. That's about 36 bits. There are 124 bits remaining. In
// other words, the collision probability is 1/2^124, which is very very low.
// So, we will be fine to just use the hash of the wallet address and mint
// address to derive the token account address.
func DeriveTokenAccountAddress(walletAddress common.Address, mintAddress common.Address) common.Address {
    // Concatenate wallet address and mint address bytes
    buf := append(walletAddress.Bytes(), mintAddress.Bytes()...)
    
    // Calculate keccak256 hash
    hash := crypto.Keccak256(buf)
    
    // Return the last 20 bytes of the hash as the token account address
    return common.BytesToAddress(hash[12:])
}

StateAccount
MintAccount
TokenAccount