Photo by Georgie Cobbs

Common questions for the curious in Solidity

David Sun
Wolverine Blockchain
10 min readApr 7, 2018

--

You have scoured the internet for introductory blogs on Solidity and smart contract development. Skimmed a few and got to know a little about the world of Solidity. If you haven’t, fear not. Here are a few great introductory posts on Solidity development.

For the more experienced developer,

Now that you have learned Solidity, you are ready to get your hands dirty. But man, it is tough to start in this world.

I thought to collect some thoughts here on my developing experience, deep dive into a few problems I faced developing my first smart contract, and some awesome resources/readings/inspiration to kickstart you from just “knowing Solidity” to “making ___ with Solidity”.

Questions and their answers I faced developing in Solidity

How much does storage size matter?

For the non-developers, there is a difference between storing data in memory and storage. Metaphorically, you can think of storing in memory and storage as an computer’s RAM versus hard drive. When data is in memory, it lasts as long as the current function execution; once its done, the memory is wiped. Storage, on the other hand, is data ON the blockchain. Between each function call, the data is persisted and can be used after the function is executed.

This is the main reason why storage costs gas; you are actually taking “space” on the ETH ledger, costing the nodes resources. With this in mind, Solidity developers are very conscious of the storage that a smart contract uses. But how lean do you have to be with storage?

In short, for the most part you do not have to be very strict with storage uses, but in some cases, it matters a ton.

To provide background, EVM stores data in 32 byte chunks (256 bits). The standard “uint”, which is 256 bit, allows you to store quite a massive number. The next question would be then: What if I don’t need such a massive number? Would a smaller uint like uint8 make it cheaper to store?

http://my.math.wsu.edu/help/matlab/uint8.html

Interestingly, it costs MORE gas to store an uint8 value in storage than a uint256. It is mostly due to how the EVM works. It stores that value in a 256 bit slot and then takes computational power to convert that 256 bit to a 8 bit form. That costs gas. It is noted that by version 0.4.18 of Solidity, the gas cost of converting the uint is marginally small. But this is a interesting point to note for any starting developers.

However, with this in mind, there is a case where using smaller values DO matter: structs. Structs, at a high level, are collections of data that collectively describes a certain object. A good example are colors; they are stored on computers as red, green, and blue values. For the computer to properly render a color, it needs all 3 of the rgb values. In this context, it makes sense to “bundle” the data into one structure.

struct Color {
uint red;
uint green;
uint blue;
}

In Solidity, structs work by talking all the values in it and “squeezing” them into 256 bit slots. That means storing 3 uint256 values in a struct takes 3 slots of storage versus 3 uint8 values that would only store in one slot.

// Takes 1 slot
struct Color {
uint8 r;
uint8 g;
uint8 b;
}
// Takes 3 slots
struct Color {
uint256 r;
uint256 g;
uint b;
}

For structs, it makes quite a big deal to store your values in the appropriately sized variable. It is worth incurring the conversion cost of a uint to a smaller value to store in a struct.

Tip 1: In many cases we need to use the “now” global variable to get the current time from UNIX epoch start in seconds. The number returns as a uint256. In fact, the current seconds in 2018 only need 31 bits. You can store the current time with 64 bits instead of 256 bits. (Even a 32 bit can work, by the time you overflow that number, it would be the year of 2108…)

Tip 2:

There is a “var” keyword. JS developers delight! There is implicit type conversion but not as crazy as JS. You can’t use var in function returns or parameters though. In functions you can do:

uint value = 9; 
var newValue = value;

Solc (the solidity compiler) knows that var is a uint value without you specifically noting it. This may save some headaches.

I am in no way implying that I like javascript’s mess with variables and conversions. I am a much bigger fan of type-strict languages like Swift.

How much does the pragma ‘0.4.__’ matter?

Beyond needing that line to compile the contract, the versioning makes quite a big difference. You can read about the current roadmap of each version here:

Each version is actively being developed upon, and new fixes and language features are added. For example, nested arrays are heavily limited in Solidity 0.4.20.

You can’t do this:

function doSomething(string[] strings) public {
//Do something
}

strings are simple array of chars (similar to c strings in c or c++). These are nested arrays and the compiler will fail. Who knows, in a future version support may come through.

Another example in 0.4.17:

We split the constant keyword for functions into pure (neither reads from nor writes to the state) and view (does not modify the state).

That is quite the change. Version 0.4.17 added two new reserved words and new functionality with them.

In short, this language and development environment is actively under development. EVM and Solidity can change and what version of Solidity you use will play a big deal of what you can or can’t do in the language.

Tip: Note the version of the solidity code you see on Stack Overflow or on a blog. It makes quite a big deal sometimes and save you hours upon HOURS of ripping the hair out of your skull.

How much does those warnings the compiler throws matter?

While warnings do not stop your smart contract from compiling they do bring up some good points about your Solidity code. For the OCD crazed developer, the obvious answer is to resolve them all.

But really, be a smart developer (you are writing SMART contracts). Warnings can allow you to pick up on redundant behaviors, bugs, or missing reserved words. It makes your code readable and sometimes easier to upgrade to a later version. A warning may turn into a strictly enforced rule in a later version. It may also save you gas at times.

I commonly forget to add the “public”, “internal”, “private” keyword after my function declaration. The warnings notify me when I don’t do that; in many cases, it allows me to mitigate some major bugs.

On the other side, some warnings can be ignored. Like the one above, I was trying to conform to the ERC721 interface and was putting an empty string as a return in the tokenMetadata function. There isn’t really any smart way to resolve that problem without changing that function declaration.

Tip: Writing quality code is a collaborative effort. Look at crypto-kitties peer review bounty program.

If they are of any metric, I compiled their code on my computer and it threw warnings as well. It isn’t deadly to have a few if you are consciously deciding to address each warning or not.

In short, you are writing smart contracts, but first be a smart developer.

Does order of logic matter?

YES. YES. YES. Yes, the sequence of logic in computer science is imperative by nature. But in Solidity it can matter much more.

This blog written by an awesome friend highlights a serious problem of sequence. A hacker was able to exploit when “balance” was set to zero in a withdraw function by repeatedly calling the function before the previous calls was able to set the “balance” to zero. The hacker was able to drain this smart contract of its balance in no time. This is all because of a simple mistake with the order of logic.

When you write code that works with user balances, be conscious of how it is written. Consider this exploit and see if your code can prevent it. There are many other clever exploits but this definitely highlights a very alarming one.

Tip: Use this as a motivation to rigorously test and think through your logic. This WILL make you a better developer.

Can I “automate” or “schedule” tasks in Solidity?

In short, no you can’t. This is a BIG limitation for many potentially cool ideas for Dapps. There is no way to schedule a function call at midnight of every day. This is due to the nature of how the protocol of blockchain works; it is not a perpetually running server that can actively monitor the time. Some curious minds may bring up the use of the general block mining rate as a way to constantly monitor time and schedule tasks. This would not be possible because it would be costly for miners to run such computation for each smart contract every time they are mining a block.

Right now, developers are tackling this problem with their own ways. Unfortunately, it incurs more actions by users to make the experience truly harmonious. In an auction, the highest bidder has no way of automatically receiving the item auction when the auction ends. Instead, most contracts use a redeem function to allow the winners to retrieve the item after they won the bet. This puts the cost of automating tasks on the users and severely hamper potential applications of Solidity.

There are a few workarounds I have found:

This uses an outside source that you trust to trigger a call to your function. This strays from the decentralized spirit of your smart contract but gives you scheduled calls.

https://cranklin.wordpress.com/2018/02/12/lets-build-an-ethereum-lottery-contract-with-scheduled-triggers/

Tip: Be creative. We definitely are working with some limitations, but this has not stopped the likes of crypto-kittens. Learn from each other and let’s work together to build new techniques on top of Solidity.

These were just a few questions I had when I was tackling my first smart contract project. Thought to highlight them and the research I found behind each equation. I can be entirely wrong so please point out any inaccuracies.

General thoughts of developing with Solidity

Solidity development is a challenging and new space for developers of all experiences. It takes a certain kind of thinking and rigor to write quality smart contracts. The space is actively evolving and in need of input from developers. Joining the space is as much of a benefit for you (to add a skill to your resume) as it is for the community. We all want to see awesome new applications of smart contracts and want to learn from each other.

On another note, I think the blockchain world suffers greatly from the “silver bullet” dilemma. Smart contracts, ERC20, tokenizing things do not resolve every problem in the world. Matter of fact, I don’t think we can solve any problem with blockchain alone. We are currently seeing a world of a ton of different tokens, cryptos, and ICOs. It is like going to a Home Depot that only sell hammers but no raw materials. I am a believer of what blockchain can do but it doesn’t resolve everything. Consider how you can use smart contracts with what you previously were an expert in. I do not think you need to throw out what you previously know just to work in the decentralized space.

As a mostly self-taught developer, I can say confidently Solidity is making me a better programmer. As a learning experience, this has been very fruitful and I recommend any developer to give it a whirl.

--

--

David Sun
Wolverine Blockchain

Computer enthusiast, designer, absurdist, and probably too nerdy. bydavidsun.com (Freelancer!)