My experience with Solidity, the language of the Ethereum blockchain

The Smart Contract

Unlike Python, variables are statically typed instead of dynamically typed in Solidity. Statically typed languages have variables type-checked (enforced) at compile time: the compiler can detect when there is a type error and throw an exception before the code can run. In dynamically typed languages, a program will execute even if there is a type error and would only throw an exception or exit when a specific function/line with the type error gets executed.

State Variables

It is expensive to copy complex types such as arrays and structs, so they need to be handled differently to avoid taking up too much space. We have the options of storing them in memory, which is not persistent, or keeping them in storage — where state variables are located.

uint[] memory a = new uint[](7);

Gas

Gas is an indispensable part of activity on the Ethereum blockchain — it is attached to every transaction on the contract, not just in the form of value transfer. Executing a function in the contract is a transaction, and there is a cost attached to this execution (expressed in a unit of ether). Gas also protects against malicious attacks, making it unreasonably expensive to try to slow down or freeze the network with a large amount of transactions. So how is the gas cost of a transaction calculated?

Events

In my experience so far, events are the closest thing to print statements in Solidity. Events let us use EVM logging facilities which can be used to trigger JavaScript callbacks in the UI of a dApp, which can listen for these events. For example, when something happens in the smart contract itself, the frontend has a way to know that it took place.

event RecordingGift();function recordGift(uint _amount, string giftPurpose) {    RecordingGift();
// do something to add funds to a data structure that tracks gift money
}
var recordGiftEvent;RedEnvelope.deployed().then(function(instance){    envelope = instance;    recordGiftEvent = envelope.RecordingGift();    recordGiftEvent.watch(function(error, result){        if(!error){            console.log("Verifying merchant in contract! ", result);        } else {            console.log(error);        }   });}

Function Modifiers

Function modifiers in solidity allow us to assign and modify a function’s behavior. This could mean declaring a specific condition, such as: the owner is the only one that can execute a certain function, or a contract needs to contain a specific balance in order to perform an action:

modifier onlyOwner {
require(msg.sender == owner);
}
function addToCart(string _productName, uint _productId) onlyOwner public {}
contract parent{    modifier onlyOwner{        require(msg.sender == owner);        _; // only continue executing a function if the requirement is met    }}contract child is parent {    function doSomething() public onlyOwner {
// function body here
}
}

Mappings

Mappings behave similarly to hash tables — they have key-value pairs and the keys can be pretty much any type except for a mapping, a dynamically sized array, a contract, an enum and a struct. The value can be any type, including mappings.

Mapping (string => string) mapName;string[] public keyList;

Structs

Structs are a widely-used type not just in Solidity — it’s great for defining objects with multiple properties. For example, you can have a Product struct whose properties are price, name and id.

Inheritance

This is a concept most developers are familiar with, and just like Structs, it comes in handy when developing smart contracts in Solidity. For a contract to inherit another contract, we add is <name of parent contract> to the declaration of the inheriting contract:

contract Dog {    function Dog() public {        // constructor here    }    modifier onlyOwner {        require(msg.sender == owner);    }}contract Shibainu is Dog {
// contract inherits Dog
}

Closing thoughts

In general, I have found Solidity to be less verbose and “flexible” than other languages like Python, meaning that there is a wider gap between the goal I have in my mind and the code actually performing that goal without errors. However, it is still the best language for building smart contracts and Ethereum and has various people maintaining/developing.

  • Good object- and contract-oriented properties
  • Similar to Python’s interactive mode, we can also test contracts through the command line with tools like Truffle
  • Hard to debug and use print statements
  • Hard to import libraries — often have to clone the entire repo from Github
  • String parsing is the opposite of what it is in Python — limited and inflexible (cannot join 3 string slices at a time)
  • Still very early stages for making API calls

Relevant sources

https://en.wikipedia.org/wiki/Marginal_product_of_labor

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Julia Wu

Julia Wu

Building things. Prev. engineering at Brex, Apple, MSFT. More at juliawu.me