Skip to content

Solidity Gotchas

andrewgordstewart edited this page Jun 5, 2018 · 4 revisions

All storage is 256-bits wide.

[TODO: What are the implications of this?] From the docs:

Each account has a persistent memory area which is called storage. Storage is a key-value store that maps 256-bit words to 256-bit words.

Right-bit-shifts

From here:

The results produced by shift right of negative values of signed integer types is different from those produced by other programming languages. In Solidity, shift right maps to division so the shifted negative values are going to be rounded towards zero (truncated). In other programming languages the shift right of negative values works like division with rounding down (towards negative infinity).

Data location

Whether or not a copy of data is made or a reference is created depends on the context. See the docs

Multi-dimensional arrays

link

As an example, an array of 5 dynamic arrays of uint is uint[][5] (note that the notation is reversed when compared to some other languages).

Transaction costs and testing

While testing the behaviour of functions that send ether between accounts, one needs to consider transaction costs. There are a couple of work-arounds for this:

  1. use web3.eth.sendTransaction({other_params, gasPrice: 0})
  2. designate accounts[0] to pay transaction fees, and use other accounts to test behaviour

(2) is limiting, since sometimes a function must be called by a particular user.

The Fallback function

The fallback function of a contract, which is an unnamed function, is called in two cases:

  1. when a function is called on a contract that has no function defined with the given signature
  2. when the contract receives ether, unless it's as a recipient of a coinbase transaction (aka miner block reward) or as a destination of a selfdestruct.

The function can't be overloaded. Hence, it does not exist by default, and so at a minimum, the following is required to receive ether through transfers.

  function () public payable {}

Read the docs for more details.

QUESTION: What behaviour would I want to be performed in both scenario 1 and 2?

SHA3

Ethereum includes the keccak function for computing hashes, but uses different padding rules from the SHA3 specification. As a result, keccak256(input) disagrees with the output of sha3(input) in other contexts.

Starting in version 1.0, web3.utils includes soliditySha3 which provides an implementation of ethereum's keccak256 function. However, note that (at the time of this comment) truffle uses version 0.20.x, which doesn't yet include soliditySha3.

Question: How can I compare ethereum keccak256 hashes and SHA3 hashes?

Library functions cannot be called with CALL

See the docs.

Tom: if you have a non-pure/view function in a library, calling it will cause a revert with no further explanation