Solidity Solidity Interfaces, ABIs, and Events 1 — Questions and Answers
Question 1: What is an interface in Solidity and what restrictions does it have?
- A contract-like definition with only function signatures and no implementation, state variables, or constructors (Correct answer)
- A contract that can only emit events and read storage
- An abstract contract that inherits from multiple parents
- A special file format for ABI definitions
Correct answer: A contract-like definition with only function signatures and no implementation, state variables, or constructors
Interfaces declare function signatures (no bodies), cannot have state variables or constructors, and all functions must be external — they define a contract's API without implementation.
Question 2: What is the Solidity ABI (Application Binary Interface) used for?
- It defines how to encode/decode function calls and return values between contracts and external callers (Correct answer)
- It is the compiled bytecode that runs on the EVM
- It is the storage layout of a contract's state variables
- It defines the event signatures emitted by a contract
Correct answer: It defines how to encode/decode function calls and return values between contracts and external callers
The ABI specifies the encoding format for function inputs/outputs (function selectors, parameter types, return types), enabling external tools and contracts to call functions correctly.
Question 3: How is a function selector computed in Solidity?
- It is the first 4 bytes of the keccak256 hash of the function's signature string (e.g., 'transfer(address,uint256)') (Correct answer)
- It is the first 4 bytes of the function's bytecode
- It is an incrementing counter assigned at compile time
- It is the keccak256 hash of the function name only
Correct answer: It is the first 4 bytes of the keccak256 hash of the function's signature string (e.g., 'transfer(address,uint256)')
A function selector is `bytes4(keccak256('functionName(type1,type2,...)'))` — the canonical signature string is hashed and the first 4 bytes are used as a compact identifier.
Question 4: What does `abi.encode` do differently from `abi.encodePacked`?
- abi.encode pads each value to 32 bytes with standard ABI encoding; abi.encodePacked concatenates values without padding (Correct answer)
- abi.encodePacked adds a length prefix while abi.encode does not
- abi.encode is only for external calls; abi.encodePacked is only for hashing
- They are identical in behavior
Correct answer: abi.encode pads each value to 32 bytes with standard ABI encoding; abi.encodePacked concatenates values without padding
`abi.encode` uses standard ABI encoding (32-byte aligned, with dynamic type offsets) suitable for external calls; `abi.encodePacked` produces compact concatenated bytes suitable for hashing.
Question 5: What is the risk of hash collisions when using `abi.encodePacked` with multiple dynamic types?
- Two different sets of inputs can produce the same packed encoding (e.g., ['aa','b'] and ['a','ab']) (Correct answer)
- Packed encoding truncates values longer than 32 bytes
- Dynamic types cause abi.encodePacked to revert
- Hashes from encodePacked expire after one block
Correct answer: Two different sets of inputs can produce the same packed encoding (e.g., ['aa','b'] and ['a','ab'])
Because `abi.encodePacked` omits length prefixes for dynamic types, different combinations of strings/bytes can produce identical byte sequences, enabling hash collision attacks.
Question 6: What does `abi.decode` do in Solidity?
- It decodes ABI-encoded bytes back into Solidity types, used for parsing return data from low-level calls (Correct answer)
- It validates that calldata is correctly formatted before execution
- It converts bytecode back to Solidity source code
- It decodes Base64-encoded metadata URIs
Correct answer: It decodes ABI-encoded bytes back into Solidity types, used for parsing return data from low-level calls
`abi.decode(data, (type1, type2))` parses ABI-encoded bytes back into typed Solidity variables, commonly used after low-level `call` or when processing cross-contract return values.
What is an interface in Solidity and what restrictions does it have?