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.
The canonical signature follows strict formatting rules:
- Function name - Exact name from ABI
- Opening parenthesis - No space after name
- Parameter types - Only types, no names
- Comma-separated - No spaces around commas
- Closing parenthesis - No trailing content
// Correct canonical signature
"transfer(address,uint256)"
// WRONG - includes parameter names
"transfer(address to, uint256 amount)"
// WRONG - has spaces
"transfer(address, uint256)"
// WRONG - includes return type
"transfer(address,uint256) returns (bool)"
Usage Examples
Basic Signature
import { Function } from 'tevm'
const balanceOfFn = new Function({
type: "function",
name: "balanceOf",
inputs: [{ type: "address", name: "owner" }],
outputs: [{ type: "uint256", name: "balance" }]
})
console.log(balanceOfFn.getSignature()) // "balanceOf(address)"
No Parameters
import { Function } from 'tevm'
const totalSupplyFn = new Function({
type: "function",
name: "totalSupply",
inputs: [],
outputs: [{ type: "uint256" }]
})
console.log(totalSupplyFn.getSignature()) // "totalSupply()"
Complex Parameter Types
import { Function } from 'tevm'
const swapFn = new Function({
type: "function",
name: "swap",
inputs: [
{ type: "uint256[]", name: "amounts" },
{ type: "address[]", name: "path" },
{
type: "tuple",
name: "params",
components: [
{ type: "uint256", name: "deadline" },
{ type: "address", name: "to" }
]
}
]
})
console.log(swapFn.getSignature())
// "swap(uint256[],address[],(uint256,address))"
Tuple Arrays
import { Function } from 'tevm'
const batchTransferFn = new Function({
type: "function",
name: "batchTransfer",
inputs: [
{
type: "tuple[]",
name: "transfers",
components: [
{ type: "address", name: "to" },
{ type: "uint256", name: "amount" }
]
}
]
})
console.log(batchTransferFn.getSignature())
// "batchTransfer((address,uint256)[])"
Computing Selector from Signature
import { Function } from 'tevm'
import { Keccak256 } from 'tevm'
const transferFn = new Function({
type: "function",
name: "transfer",
inputs: [
{ type: "address", name: "to" },
{ type: "uint256", name: "amount" }
]
})
// Get signature
const signature = transferFn.getSignature()
// "transfer(address,uint256)"
// Hash to get selector
const hash = Keccak256.hash(signature)
const selector = hash.slice(0, 10)
console.log(selector) // "0xa9059cbb"
// Or use getSelector() directly
console.log(transferFn.getSelector()) // "0xa9059cbb"
Type-Safe Signatures
TypeScript can infer the exact signature type:
import { Function } from 'tevm'
const transferFn = new Function({
type: "function",
name: "transfer",
inputs: [
{ type: "address", name: "to" },
{ type: "uint256", name: "amount" }
]
} as const)
const signature = transferFn.getSignature()
// ^-- Type: "transfer(address,uint256)"
Signature Comparison
Signatures are used to identify function uniqueness:
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 despite different parameter names
console.log(fn1.getSignature() === fn2.getSignature()) // true
console.log(fn1.getSignature()) // "transfer(address,uint256)"
For display purposes, you may want a human-readable format:
import { Function } from 'tevm'
const transferFn = new Function({
type: "function",
name: "transfer",
inputs: [
{ type: "address", name: "to" },
{ type: "uint256", name: "amount" }
],
outputs: [{ type: "bool", name: "success" }]
})
// Canonical signature (for hashing)
const canonical = transferFn.getSignature()
console.log(canonical) // "transfer(address,uint256)"
// Human-readable format (manual construction)
const readable = `function ${transferFn.name}(${transferFn.inputs.map(p => `${p.type} ${p.name}`).join(', ')}) returns (${transferFn.outputs.map(p => p.type).join(', ')})`
console.log(readable)
// "function transfer(address to, uint256 amount) returns (bool)"
Fixed vs Dynamic Arrays
Array notation in signatures:
import { Function } from 'tevm'
const fn = new Function({
type: "function",
name: "process",
inputs: [
{ type: "uint256[]", name: "dynamic" }, // Dynamic array
{ type: "uint256[3]", name: "fixed" }, // Fixed array
{ type: "bytes", name: "dynamicBytes" }, // Dynamic bytes
{ type: "bytes32", name: "fixedBytes" } // Fixed bytes
]
})
console.log(fn.getSignature())
// "process(uint256[],uint256[3],bytes,bytes32)"
Error Handling
import { Function } from 'tevm'
try {
const fn = new Function({
type: "function",
name: "", // Invalid: empty name
inputs: []
})
fn.getSignature()
} catch (error) {
console.error("Invalid function definition")
}
See Also
- getSelector - Get 4-byte selector from signature
- encodeParams - Encode function calldata
- format - Format ABI item to signature with parameter names