Skip to content

Account Management

Tevm provides two key actions for managing account state: getAccountHandler and setAccountHandler.

getAccountHandler

The getAccountHandler action allows you to retrieve the current state of an account.

Parameters

type GetAccountParams = {
  // Required address of the account
  address: Address
  // Optional block tag to query state from
  blockTag?: 'latest' | 'pending' | 'earliest' | number
  // Whether to return storage (can be expensive)
  returnStorage?: boolean
}

Return Type

type GetAccountResult = {
  // Address of the account
  address: Address
  // Current nonce
  nonce: bigint
  // Balance in wei
  balance: bigint
  // Deployed bytecode (if contract)
  deployedBytecode: Hex
  // Storage root
  storageRoot: Hex
  // Code hash
  codeHash: Hex
  // Whether this is a contract
  isContract: boolean
  // Whether account is empty
  isEmpty: boolean
  // Storage (if returnStorage=true)
  storage?: { [key: Hex]: Hex }
  // Any errors that occurred
  errors?: TevmGetAccountError[]
}

Example

import { createTevmNode } from 'tevm'
import { getAccountHandler } from 'tevm/actions'
 
const node = createTevmNode()
 
const account = await getAccountHandler(node)({
  address: '0x...',
  blockTag: 'latest',
  returnStorage: true
})
 
console.log('Balance:', account.balance)
console.log('Nonce:', account.nonce)
if (account.isContract) {
  console.log('Code:', account.deployedBytecode)
  console.log('Storage:', account.storage)
}

setAccountHandler

The setAccountHandler action allows you to modify account state directly.

Parameters

type SetAccountParams = {
  // Required address to modify
  address: Address
  // New nonce value
  nonce?: bigint
  // New balance in wei
  balance?: bigint
  // New deployed bytecode
  deployedBytecode?: Hex
  // New storage values
  state?: { [key: Hex]: Hex }
}

Return Type

type SetAccountResult = {
  // Any errors that occurred
  errors?: TevmSetAccountError[]
}

Examples

1. Setting Account Balance

import { setAccountHandler } from 'tevm/actions'
 
await setAccountHandler(node)({
  address: '0x...',
  balance: parseEther('100')
})

2. Deploying Contract Code

await setAccountHandler(node)({
  address: contractAddress,
  deployedBytecode: '0x...',
  state: {
    // Initial storage values
    '0x0000...': '0x0000...'
  }
})

3. Modifying Multiple Properties

await setAccountHandler(node)({
  address: '0x...',
  nonce: 5n,
  balance: parseEther('10'),
  state: {
    [slot1]: value1,
    [slot2]: value2
  }
})

Best Practices

  1. Storage Management:

    // Avoid fetching storage unless needed
    const account = await getAccountHandler(node)({
      address: '0x...',
      returnStorage: false // default
    })
  2. State Consistency:

    // Check account exists before modifying
    const account = await getAccountHandler(node)({ address })
    if (!account.isEmpty) {
      await setAccountHandler(node)({
        address,
        balance: account.balance + amount
      })
    }
  3. Error Handling:

    const result = await setAccountHandler(node)({
      address: '0x...',
      balance: newBalance,
      throwOnFail: false
    })
     
    if (result.errors) {
      console.error('Failed to set account:', result.errors)
    }

Related Topics