Today, 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, applications or 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 of an Ethereum Solidity developer. It is divided into 2 parts, where I tried to consider all aspects and nuances of this language.

Solidity version: 0.4.24

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 this?

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 variable msg.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.tra nsfer (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. Moost 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 selfdestruct function?

All ethers will be transferred to the address transmitted by the parameter to this function.

88. What parameters does the selfdesctruct function take?

We transfer the address from which all the ethers from the current smart contract will be transferred after completing the selfdesctruct function.

89. How much does the selfdesctruct 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 selfdesctruct 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.

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.