103 Ethereum Solidity Developer Interview Questions
Need help passing your next interview on Solidity? This article provides you with top Solidity interview questions and answers so you can become an Ethereum Solidity Developer.
Join the DZone community and get the full member experience.
Join For FreeToday, Ethereum is considered the most popular and fully operational platform for creating decentralized applications.
There are hundreds of thousands of smart contracts currently working in the Ethereum blockchain that manage wallets, tokens, and applications, or are used to store funds.
To write smart contracts in the Ethereum environment, a JavaScript-like programming language, Solidity, was specially developed.
This article should help you pass the interview if you want to take a position as an Ethereum Solidity developer.
This article references Solidity version: 0.4.24.
Part 1: Solidity Source Files
1. What is a smart contract in Ethereum?
Smart contracts are often equated to software applications, but this is a reductive analogy; they’re more like the concept of classes in conventional object-oriented programming. A smart contract is a collection of code (its functions) and data (its state) that resides at a specific address on the Ethereum blockchain.
2. What are the source files?
These are the files that can contain an arbitrary number of contract definitions, including directives and pragma directives.
3. What extension does the source file have in Solidity?
.sol
4. How and why we should specify the so-called version pragma in smart contracts?
Source files can (and should) be annotated with a so-called version pragma to reject being compiled with future compiler versions that might introduce incompatible changes.
5. What happens if the smart contract does not specify the Solidity version?
A smart contract will not be compiled.
6. What are the features of the Solidity versions?
Versions that contain breaking changes have the form 0.x.0 or x.0.0
7. How can we specify the compiled version condition "Greater than or equal to"?
We can specify this condition using ^ or >= .
For example:
pragma solidity ^0.4.0; or pragma solidity >=0.4.0;
8. Can we specify the compile version condition "Greater than or equal to 0.4.20 and Less than 0.4.25?"
Yes. We can specify this condition like
pragma solidity >=0.4.20 <0.4.25;
9. What is the ABI of the contract?
ABI is the binary interface of the application. ABI is an interface between two software modules, one of which is often at the machine code level. In Ethereum, basically, you can encode Solidity contracts for EVM and, conversely, read data from transactions.
10. How can we import global symbols from one source file to another?
We can do this by using import statements.
11. What is the difference between import "./x" as x; and import "x" as x;?
We import "./x" as x; - imports a file x from the same directory as the current file.
Also, we import "x" as x; - in a global “include directory."
12. What does the file generated by the Solidity compiler contain?
The Solidity compiler automatically creates a JSON file that contains the contract metadata (information about the current contract).
Part 2: Creation of Contracts and Their Structure
13. Define the main components of a smart contract.
A contract contains state variables, functions, function modifiers, events, structures, and enums.
14. What is a constructor? What is it for?
It is a function that is executed once when a contract is created.
15. How can we create a constructor?
We can create a constructor with the constructor keyword.
16. Can the constructor be called after the creation of a smart contract?
No.
17. Can I create several constructors with a different number of parameters in a smart contract?
No. Only one constructor is allowed, and this means overloading is not supported.
18. Is a constructor mandatory?
A constructor is optional.
19. Can we create a private constructor? What will happen when we create a private constructor?
No. We get an error: TypeError: The Constructor must be public or internal.
20. How can we create a contract?
Contracts can be created “from outside” via Ethereum transactions or from within Solidity contracts.
21. How to create a smart contract from another smart contract?
If the contract wants to create another contract, the source code (and the binary) of the created contract has to be known to the creator. This means that cyclic creation dependencies are impossible.
22. What are the state variables?
State variables are values that are permanently stored in contract storage.
23. What does it mean when talking about state changing?
By changing the state, they understand how to:
Create/modify state variables
Use <address>.balance
Get access to any member of a block, tx, msg (except for msg.sig and msg.data)
Use the built-in assembly that contains a certain operation code
Create a contract
Call an external function that is not pure
24. Is there a difference in cost between the functions of creating a new state variable or changing it?
Yes. Creating is more expensive than changing.
Part 3: Data Location
25. What kinds of memory do you know for storing data of a smart contract?
The Ethereum virtual machine has three storage areas: storage, memory, and stack.
Also, the returndata (returned from the value function) and calldata are allocated.
26. In which case do we use memory type?
We use memory to store temporary variables.
27. What data is stored in storage?
State variables and, by default, all other local variables are stored in the storage.
28. In what type of memory are the function parameters stored by default? Can we change the location of the not return parameters? If so, what are the limits for this?
The default location for the parameters: memory.
Forced data location: parameters (not return) of external functions: calldata. You can change the location of the not return parameters using the keyword storage.
However, you can do this only for internal functions, and the parameters must be of type Array or Struct.
29. What is calldata ?
It is a non-modifiable, non-persistent area where function arguments are stored. Function parameters (not return parameters) of external functions are forced to calldata and behave mostly like memory.
30. What is stack?
Stack is a working memory and local variables.
stack - 1024 slots 32 bytes.
Part 4: Data Types
31. What are the different data types?
Booleans, Integers, Address, Arrays (also String, Bytes), Structs, Mappings, etc.
32. What data types refer to reference types?
Arrays (also String, Bytes), Structs, Mappings.
33. What is the difference between value types and reference types?
Value types are called this because variables of these types will always be passed by value, i.e. they are always copied when they are used as function arguments or in assignments.
Complex types, i.e. types that do not always fit into 256 bits, have to be handled more carefully than the value types we have already seen.
34. What is the difference between uint, uint8, uitn256, int, int8, int256?
Keywords uint8 to uint256 in steps of 8 (unsigned of 8 up to 256 bits) and int8 to int256. uint and int are aliases for uint256 and int256, respectively.
35. What is the feature of dividing integers in Solidity?
Division always truncates, but it does not truncate if both operators are literals (or literal expressions).
36. What is the address type?
Address holds a 20-byte value. Address types also have members and serve as a base for all contracts.
Starting with version 0.5.0, contracts do not derive from the address type, but can still be explicitly converted to address.
37. What address-related keywords do you know?
These include the following:
- <address>.balance (uint256): Returns the balance of the address in wei,
- <address>.send(uint256 amount), <address>.transfer(uint256 amount),
- <address>.call, <address>.callcode, <address>.delegatecall
This(current contract’s type): Explicitly converts to the address
-selfdestruct(address recipient): Destroys the current contract, sending its funds to the given address.
38. How can I get a balance from a variable of address type?
<address>.balance
39. In what units is the account balance returned for the <address> .balance?
wei.
40. In what units are sent ether using the <address>.transfer (uint256 amount) function? And how much does it cost (in gas)?
wei. 2300 gas.
41. What is the mapping type?
Mappings can be seen as hash tables, which are virtually initialized so that every possible key exists and is mapped to a value whose byte-representation is all zeros — a type’s default value.
The similarity ends here, though. The key data is not actually stored in a mapping, only in its keccak256 hash used to look up the value.
42. Can mapping be multi-level?
Yes.
43. In what type of memory are mapping variables stored?
Mappings are only allowed for state variables (or as storage reference types in internal functions).
44. What types of elements are allowed in memory arrays?
For storage arrays, the element type can be arbitrary (i.e. also other arrays, mappings, or structs).
For memory arrays, it cannot be a mapping and has to be an ABI type if it is an argument of a publicly-visible function.
45. How to initialize (create) an array?
uint[] arr = new uint[] (1);
46. How can I add a new element to an array?
someArray.push(newValue)
or
someArray.length++ ; someArray[someArray.length - 1] = newValue;
47. What is the bytes data type?
This is a dynamically-sized byte array. Not a value-type!
48. What is the string data type?
This is a dynamically-sized UTF-8-encoded string.
49. What is the difference between string and bytes?
String is equal to bytes, but it does not allow length or index access, for now.
As a rule of thumb, use bytes for arbitrary-length raw byte data and string for arbitrary-length string (UTF-8) data.
Bytes, in contrast to string, have a push function.
50. Why is it recommended to use the bytes32 type instead of the string type?
If the length of the string is known in advance, it is recommended to use bytes1 ... bytes32, since it is much cheaper, both for work and for storage.
51. What happens if I try to get a non-existent element of a static array?
We will get an error during contract execution, and the transaction will end with the status "Fail."
52. What is the difference between memory arrays and storage arrays?
Dynamic arrays can be resized in storage (not in memory) by changing the.length member. The size of memory arrays is fixed (but dynamic, i.e. it can depend on runtime parameters) once they are created.
For memory arrays, the element type cannot be a mapping and has to be an ABI type if it is an argument of a publicly-visible function.
53. What do you know about hexadecimal literals in Solidity?
Hexademical literals are prefixed with the keyword hex and are enclosed in double or single-quotes (hex"001122FF"). Their content must be a hexadecimal string.
Hexademical literals behave like string literals and have the same convertibility restrictions.
54. What is an enum? What are the restrictions on their use?
Enums are one way to create a user-defined type in Solidity. They are explicitly convertible to and from all integer types but implicit conversion is not allowed.
The explicit conversions check the value ranges at runtime and a failure causes an exception. Enums needs at least one member.
55. How can I get the numeric value of the enum?
If you want to get an enumeration value, use uint ( enum_variable
).
56. Can I declare an enum within an interface?
No.
57. What is Structs?
Structures are custom data types. They can be used in mappings or arrays, and they themselves contain arrays and mapping.
58. Is it possible for a struct to contain a member of its own type?
No.
59. How can I initialize Struct?
SomeStruct sm = SomeStruct({field: now, field2: ‘somefield’});
or
SomeStruct sm = SomeStruct({now, ‘somefield’});
Both entries are correct.
60. What types of conversion are allowed in Solidity?
Implicit and Explicit.
61. Is it mandatory to specify the type of the variable when it is created?
No. You can use the keyword var.
In this case, initialization is mandatory in the announcement.
62. In which case can you not use the var keyword?
The keyword var cannot be used for function parameters or for return parameters.
Part 5: Units
63. What Ether units are available in Solidity?
There are wei, finney, szabo or ether.
64. Which Ether unit is used when we have a currency without a postfix?
Ether currency numbers without a postfix are assumed to be Wei.
65. What Time units are available in Solidity?
Solidity presents the following time suffixes after literal numbers: seconds, minutes, hours, days, weeks and years.
66. Will expression “1 weeks == 7 days” return true or false?
True.
67. Will expression “1 month == 30 days” return true or false?
This code will not compile. “Month” is not a Time unit in Solidity.
68. Which value will return expression “65 == 65 days”?
False.
69. Can suffixes like seconds, minutes, hours apply to variables?
These suffixes cannot be applied to variables. If you want to interpret some input variable in e.g. days, you can do it in the following way:
function f(uint start, uint daysAfter) public {
if (now >= start + daysAfter * 1 days) {
...
}
}
Part 6: Special Variables and Functions
70. What is the global variable?
The current contract, explicitly convertible to Address.
71. To access a global variable, do I need to specify this?
No.
72. What is the global variable msg?
msg is a variable that contains properties that provide access to blockchain data, such as the sender of the transaction, the data transferred using the transaction, the first four bytes of calldata, the number of wei sent with the transaction.
73. What data is stored in the msg.sender variable?
msg.sender is the sender address of the current external (external) function call.
74. What is the difference between msg.sender and tx.origin ?
tx.origin — the sender of the transaction, msg.sender — the sender of the current call.
With msg.sender, the owner can be a contract.
With tx.origin, the owner can never be a contract.
In a simple chain of calls, A—> B—> C—> D inside D msg.sender will be C, and tx.origin will be A.
75. What data is stored in the variablemsg.value?
A number of wei sent with the message.
76. What is dangerous for transferring Ether with msg.sender.call.value (uint256 amount)?
A function can be called if a signature is not specified correctly.
77. What is dangerous for transferring Ether with msg.sender.send (uint256 amount)?
If something goes wrong, then send will not revert the transaction, but only return false.
There are some dangers in using send: the transfer fails if the call stack depth is at 1024 (this can always be forced by the caller), and it also fails if the recipient runs out of gas.
So, in order to make safe Ether transfers, always check the return value of send, use transfer, or even better: Use a pattern where the recipient withdraws the money.
78. What are the dangers of using the msg.sender.transfer (uint256 amount) function?
If we need to send some number of Ether to multiple addresses (7 000, for example), the success of the function call will depend on each specific address.
If Ether is not delivered to one address, the entire transaction will be rolled back.
79. There is a special way to call a message using delegatecall. What is its feature? Why is it not recommended to use?
With delegatecall, you can call the function of another smart contract in the context of the calling smart contract. That is, the data is read from the memory of the current contract. In fact, we allow another smart contract to make anything with the memory of the current contract.
If storage variables are accessed via a low-level delegatecall, the storage layout of the two contracts must align in order for the called contract to correctly access the storage variables of the calling contract by name.
This is, of course, not the case if storage pointers are passed as function arguments as in the case for the high-level libraries.
80. In which case will the <address> .call.value () be unavailable?
For the called function, it must be used the modifier payable.
81. In which cases may an error (exception) calling occur for another smart contract?
This will happen if the contract at the specified address does not exist or if there was an error within the called smart contract function. Lastly, this will occur if the gas runs out.
82. Is it possible to get the current time in Solidity? Can I rely on the specific function now()? Why is it not recommended to generate a random number using block.timestampnow or blockhash?
Do not rely on block.timestamp
, now and blockhash as a source of randomness, unless you know what you are doing.
Both the timestamp and the block hash can be influenced by miners to some degree. The current block timestamp must be strictly larger than the timestamp of the last block, but the only guarantee is that it will be somewhere between the timestamps of two consecutive blocks in the canonical chain.
83. Can we just use nonce from some specific blocks within the smart contract?
No. Nonce data is not available in the contract.
84. Why can I access only the last 256 blocks’ hashes?
The block hashes are not available for all blocks for scalability reasons. You can only access the hashes of the most recent 256 blocks; all other values will be zero.
85. Can I get current block hash? Current block number?
The hash of the current block cannot be obtained. Function blockhash(uint blockNumber) returns the hash of the given block, which only works for 256. Most recently, excluding current blocks deprecated in this version.
block.number (uint) returns the current block number.
86. What does the function keccak256 do?
keccak256(...) returns (bytes32): compute the Ethereum-SHA-3 (Keccak-256) hash of the (tightly packed) arguments.
Note that constants will be packed using the minimum number of bytes required to store them. This means that, for example, keccak256(0) == keccak256(uint8(0)) and keccak256(0x12345678) == keccak256(uint32(0x12345678)).
87. What happens to the ethers on the contract after calling the self-destruct function?
All ethers will be transferred to the address transmitted by the parameter to this function.
88. What parameters does the self-destruct function take?
We transfer the address from which all the ethers from the current smart contract will be transferred after completing the self-destruct function.
89. How much does the self-destruct function cost in gas? Is it more costly than transferring Ether from one account to another?
5000 gas.
A typical transferring Ether costs approximately 2100 gas.
90. What happens if I pass a non-existent account address to the self-destruct function?
First, the account will be created, and then, Ether will be transferred to it. However, such an operation will cost more.
91. Can I send Ether to a not yet deployed smart contract, knowing in advance its address?
Yes, you can. Then, when the smart contract is deployed, it will no longer have a zero balance. Writing the logic in the constructor, you should take it into account.
Part 7: Error Handling
92. How does error handling work in Solidity?
assert(bool condition)
: invalidates the transaction if the condition is not met.
require(bool condition)
: reverts if the condition is not me.
require(bool condition, string message)
: reverts if the condition is not met. Also provides an error message.
revert()
: abort execution and revert state changes
revert(string reason)
: abort execution and revert state changes, providing an explanatory string.
93. In which case should we use assert (bool) for error handling?
We should use this for internal errors.
94. In which case should we use require(bool condition) or require(bool condition, string message) for error handling?
require(bool condition)
is used for errors in inputs or external components.
require(bool condition, string message)
also provides an error message.
95. What does revert () or revert (string reason) do?
It aborts execution and reverts state changes.
Part 8: Events
96. What are events for? How can we listen to them?
Events allow the convenient usage of the EVM logging facilities, which in turn can be used to “call” JavaScript callbacks in the user interface of a dapp, which listen to these events.
97. Are events inherited? Can I override them?
Yes, events are inheritable members of contracts.
No, we cannot override them.
98. In which data structure are the event arguments stored? Are these data available from within the contract?
Arguments to be stored in the transaction’s log — a special data structure in the blockchain.
These logs are associated with the address of the contract and will be incorporated into the blockchain and stay there as long as a block is accessed. Log and event data is not accessible from within contracts.
99. What data are available to the listener of the event?
The event listener receives arguments from, to, and amount, which makes it easy to track transactions.
100. Give an example of how to subscribe to an event using web3.js?
Coin.Sent().watch({}, '', function(error, result) {
if (!error) {
console.log("Coin transfer: " + result.args.amount +
" coins were sent from " + result.args.from +
" to " + result.args.to + ".");
}
})
101. Describe low-level interface to logs?
It is also possible to access the low-level interface to the logging mechanism via the functions log0 , log1 , log2 , log3 , and log4. logi takes i + 1 parameter of type bytes32, where the first argument will be used for the data part of the log and the others as topics.
102. What is the indexed attribute used in events?
Up to three parameters can receive the attribute indexed, which will cause the respective arguments to be searched for. It is possible to filter for specific values of indexed arguments in the user interface.
103. What does the anonymous specifier mean for events?
This means that it is not possible to filter for specific anonymous events by name.
Opinions expressed by DZone contributors are their own.
Comments