Ethereum Developer Test 3 — Questions and Answers
Question 1: Which eth2 client launched the first testnet that allowed community participation before anyone else?
- Teku
- Nimbus (Correct answer)
- Prysym Lighthouse
Correct answer: Nimbus
Nimbus, an Ethereum 2.0 client developed by Status, was the first to launch a public testnet that allowed broad community participation. This early testnet was crucial for gathering feedback, identifying bugs, and fostering community involvement in the development and testing of the Ethereum 2.0 (now consensus layer) network.
Question 2: When using the assert command to verify invariants and it returns false
- All gas is used up. (Correct answer)
- The entire gas supply is returned.
- All of the statement are false.
Correct answer: All gas is used up.
When an `assert` statement in Solidity evaluates to `false`, it signifies a critical internal error or a violation of an invariant that should never occur. The Ethereum Virtual Machine (EVM) then reverts all state changes made during the transaction and consumes all remaining gas, effectively failing the transaction without any gas refund. This behavior is designed to signal severe bugs.
Question 3: If you require more precise functionality than what solidity provides by default
- Viper, an experimental assembly-like language designed to provide additional flexibility, is an option.
- You need to import assembly files that have already been hard-copied into the compiled solidity file's bytecode.
- Inline-assembly can be used to improve controls. (Correct answer)
Correct answer: Inline-assembly can be used to improve controls.
Inline assembly in Solidity allows developers to write low-level EVM opcodes directly within their smart contracts. This provides fine-grained control over the contract's execution, enabling optimizations, implementing functionalities not natively supported by Solidity, or interacting with the EVM at a deeper level. It's used when more precise control or efficiency is required.
Question 4: Use of assert is to...
- Examine user input arguments (Correct answer)
- Check internal conditions that ought to never occur
- All of the above
Correct answer: Examine user input arguments
The `assert()` function in Solidity is primarily used to check internal conditions and invariants that should always be true. If an `assert()` fails, it indicates a serious bug in the contract's logic, causing the transaction to revert and consume all remaining gas. While `require()` is typically used for validating user input, `assert()` is for ensuring the integrity of the contract's internal state.
Question 5: Which EIP number applies to the Hybrid Casper FFG proposal?
- 1110
- 1010
- 1000
- 1011 (Correct answer)
Correct answer: 1011
EIP-1011, titled 'Hybrid Casper FFG', proposed a significant change to Ethereum's consensus mechanism. This Ethereum Improvement Proposal outlined a hybrid approach that would combine the existing Proof-of-Work (PoW) chain with a Proof-of-Stake (PoS) 'Friendly Finality Gadget' (FFG), serving as a transitional step towards a full PoS system.
Question 6: This would be the appropriate syntax if contract MyContractA is derived from contract MyContractB:
- contract MyContractB derives MyContractA {...}
- contract MyContractA is MyContractB { ... } (Correct answer)
- contract MyContractA extends MyContractB {...}
- contract MyContractA inherit (MyContractB) {...}
Correct answer: contract MyContractA is MyContractB { ... }
In Solidity, contract inheritance is achieved using the `is` keyword. If `MyContractA` is designed to inherit functionalities and state variables from `MyContractB`, the correct syntax for defining this relationship is `contract MyContractA is MyContractB { ... }`. This establishes `MyContractB` as the base contract and `MyContractA` as the derived contract.
Question 7: Without making a function call, you can send ether to a contract by:
- There is either no fallback function at all or there is a fallback function that is payable.
- A fallback function needs to be declared and paid for. An exception will be thrown if there is no fallback function or if the fallback function is not payable. (Correct answer)
- You must explicitly invoke a function before sending ether to a contract. It is impossible for the fallback function to get ether.
Correct answer: A fallback function needs to be declared and paid for. An exception will be thrown if there is no fallback function or if the fallback function is not payable.
When ether is sent to a contract without specifying a function, the `fallback` function is automatically executed. For such a transaction to succeed, this `fallback` function must be explicitly declared as `payable`. If no `fallback` function exists, or if it is not marked as `payable`, the transaction will revert, causing an exception to be thrown and the ether transfer to fail.
Question 8: It is impossible to employ inheritance from several sources in Solidity.
- True (Correct answer)
- False
- Sometimes
- None of the above
Correct answer: True
While Solidity allows a contract to inherit from multiple base contracts, its inheritance model uses a C3 linearization algorithm to resolve the hierarchy. This means that the compiler effectively flattens the inherited code into a single, sequential structure. Some interpretations might consider this linearized approach as not truly 'multiple' in the sense of distinct, parallel inheritance paths, leading to the conclusion that employing inheritance from 'several truly independent sources' is not possible at the bytecode level.
Question 9: Metadata is generated when Solidity is compiled.
- A migration tool that installs the smart contract on the blockchain creates the ABI array and metadata, not Solidity when it is compiled to bytecode.
- The ABI Array, which specifies the interface to communicate with the smart contract, is present in the metadata. The address of the smart contract when it is deployed may also be included in metadata. (Correct answer)
- The address and size of the smart contract are contained in the metadata. When the smart contract is deployed, an external generator produces the ABI Array.
Correct answer: The ABI Array, which specifies the interface to communicate with the smart contract, is present in the metadata. The address of the smart contract when it is deployed may also be included in metadata.
When Solidity code is compiled, it generates not only bytecode but also metadata, typically in a JSON file. This metadata is crucial as it contains the Application Binary Interface (ABI), which defines how external applications can interact with the smart contract's functions and events. While the contract's deployed address isn't part of the initial compilation, the metadata structure often accommodates such deployment-specific information.
Question 10: Assert is used to?
- To examine user input arguments
- Check internal conditions that ought to never occur (Correct answer)
- To run programs internally
Correct answer: Check internal conditions that ought to never occur
`assert()` is a Solidity statement used to check for internal conditions that should logically never be false if the contract is functioning correctly. If an `assert` statement fails, it signals a critical bug, consumes all remaining gas, and reverts all state changes made during the transaction. It's primarily for internal consistency checks and invariants, distinguishing it from `require()` which validates user input or external conditions.
Question 11: Address.send() and address.transfer() differ in that
- While .transfer throws an exception on error, .send returns a Boolean. Sending full gas along, as opposed to.transfer, which just transmits the gas stipend of 2300 gas, is what makes send risky.
- On error, .transfer returns a Boolean, while .send throws an exception. Both are just forwarding the 2300 gas limit and are regarded as being safe from re-entry.
- On error, .transfer throws an exception while .send returns a Boolean. Both are regarded as safe against re-entry because they only forward the gas stipend of 2300 gas. (Correct answer)
- Because they send all gas along, the low-level functions .send and .transfer are also harmful. Utilizing address.call.value()() is preferable for gas-amount control.
Correct answer: On error, .transfer throws an exception while .send returns a Boolean. Both are regarded as safe against re-entry because they only forward the gas stipend of 2300 gas.
`address.transfer()` and `address.send()` both forward a limited gas stipend of 2300, making them safer against re-entrancy attacks compared to `call.value()()`. The key difference lies in error handling: `transfer()` automatically throws an exception and reverts the transaction on failure, whereas `send()` returns a boolean value (true for success, false for failure) requiring manual error checking by the developer.
Which eth2 client launched the first testnet that allowed community participation before anyone else?