> ## Documentation Index
> Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Function.getSelector

> Get 4-byte function selector from function ABI item

<Tabs />

## How Function Selectors Work

The function selector is the first 4 bytes of the keccak256 hash of the canonical function signature:

```typescript theme={null}
import { Keccak256 } from 'tevm'
// biome-ignore lint/suspicious/noShadowRestrictedNames: Function is the ABI namespace
import * as Function from 'tevm/Abi/function'

// Get canonical signature
const signature = Function.getSignature(transferFn)
// "transfer(address,uint256)"

// Hash with keccak256
const hash = Keccak256.hash(signature)
// "0xa9059cbb2ab09eb13591db4583a4daa828198961f519e24c10cbf0c16b83d8f6"

// Take first 4 bytes
const selector = hash.slice(0, 10)  // "0x" + 8 hex chars = 4 bytes
// "0xa9059cbb"
```

## Usage Examples

### Basic Usage

```typescript theme={null}
import { Function } from 'tevm'

const balanceOfFn = new Function({
  type: "function",
  name: "balanceOf",
  inputs: [{ type: "address", name: "owner" }],
  outputs: [{ type: "uint256" }]
})

const selector = balanceOfFn.getSelector()
console.log(selector)  // "0x70a08231"
```

### Matching Selectors

```typescript theme={null}
import { Function } from 'tevm'

const fn1 = new Function({
  type: "function",
  name: "transfer",
  inputs: [
    { type: "address", name: "to" },
    { type: "uint256", name: "amount" }
  ]
})

const fn2 = new Function({
  type: "function",
  name: "transfer",
  inputs: [
    { type: "address", name: "recipient" },
    { type: "uint256", name: "value" }
  ]
})

// Same signature = same selector (parameter names don't matter)
console.log(fn1.getSelector() === fn2.getSelector())  // true
```

### Detecting Function from Calldata

```typescript theme={null}
import { Function } from 'tevm'

const transferFn = new Function({
  type: "function",
  name: "transfer",
  inputs: [
    { type: "address", name: "to" },
    { type: "uint256", name: "amount" }
  ]
})

const approveFn = new Function({
  type: "function",
  name: "approve",
  inputs: [
    { type: "address", name: "spender" },
    { type: "uint256", name: "amount" }
  ]
})

// Extract selector from calldata
const calldata = "0xa9059cbb000000000000000000000000742d35cc6634c0532925a3b844bc9e7595f51e3e00000000000000000000000000000000000000000000000000000000000003e8"
const calldataSelector = calldata.slice(0, 10)  // "0xa9059cbb"

// Check which function was called
if (calldataSelector === transferFn.getSelector()) {
  console.log("Transfer function called")
}
```

### Building Function Registry

```typescript theme={null}
import { Function } from 'tevm'

const functions = [
  new Function({
    type: "function",
    name: "transfer",
    inputs: [
      { type: "address", name: "to" },
      { type: "uint256", name: "amount" }
    ]
  }),
  new Function({
    type: "function",
    name: "approve",
    inputs: [
      { type: "address", name: "spender" },
      { type: "uint256", name: "amount" }
    ]
  }),
  new Function({
    type: "function",
    name: "balanceOf",
    inputs: [{ type: "address", name: "owner" }]
  })
]

// Create selector → function mapping
const registry = new Map(
  functions.map(fn => [fn.getSelector(), fn])
)

// Look up function by selector
const selector = "0xa9059cbb"
const fn = registry.get(selector)
console.log(fn?.name)  // "transfer"
```

## Error Handling

```typescript theme={null}
import { Function } from 'tevm'

try {
  const fn = new Function({
    type: "function",
    name: "",  // Invalid: empty name
    inputs: []
  })
  fn.getSelector()
} catch (error) {
  console.error("Invalid function definition")
}
```

## Selector Collisions

While rare, 4-byte selectors can theoretically collide. The EVM uses only the selector to route calls, so two functions with different names but identical selectors would conflict:

```typescript theme={null}
// These would have different selectors (collision unlikely but possible)
const fn1 = new Function({
  type: "function",
  name: "transferFrom",
  inputs: [
    { type: "address", name: "from" },
    { type: "address", name: "to" },
    { type: "uint256", name: "amount" }
  ]
})

const fn2 = new Function({
  type: "function",
  name: "safeTransferFrom",
  inputs: [
    { type: "address", name: "from" },
    { type: "address", name: "to" },
    { type: "uint256", name: "amount" }
  ]
})

console.log(fn1.getSelector())  // "0x23b872dd"
console.log(fn2.getSelector())  // "0x42842e0e" (different)
```

## See Also

* [getSignature](/primitives/abi/function/get-signature) - Get canonical function signature string
* [encodeParams](/primitives/abi/function/encode-params) - Encode function calldata
* [decodeParams](/primitives/abi/function/decode-params) - Decode function parameters
