Lesson 3

Hello Solidity

2

In this chaper, we're going to create a very simple smart contract that stores some information on the blockchain which we'll then retrieve.


Ethereum has multiple high-level languages that you can use to write smart contracts, each inspired by another widely used language. The most popular one is called Solidity, and is loosely based on JavaScript. Because Solidity is by far the most mature Ethereum language, it's the one that the community strongly encourages developers to use right now.

Using Remix

Since it's a bit complicated to get started with Solidity on your local computer, we will use an online IDE called Remix to take our first steps as DApp programmers instead.


Don't worry if you are overwhelmed by all the buttons and toggles, we'll go through the interface step by step.


If you're entering the website for the first time, you'll see that there's a dummy contract called ballot.sol there already. Let's ignore that one and instead start from scratch by creating a new file called HelloWorld.sol in the left navigation menu.


Just click the "+" button on the top left...



...and type in the name of your file


Writing in Solidity

Now that we have a completely blank file, let's go through how Solidity works.


The first thing we need to specify is what version of Solidity our program should be interpreted in. This is done through a version pragma on the very first line:

The idea here is that we're preventing our program from being compiled by a compiler that's older than 0.4.00.4.0. The ^-symbol in the beginning also prevents it from being compiled by a compiler that's 0.5.00.5.0 or higher. We do this in order to minimise the risk of bugs that can occur if the code is compiled in unexpected or incompatible ways.


Next, it's time to write the actual contract code! We do this by using the special contract key word which declares a new contract. If you're used to object-oriented languages, you'll notice that it's similar to how classes are defined.

Contract names are usually PascalCased, so we'll call ours HelloWorld in order to stick with this convention.


Inside our contract, we'll add a state variable that stores our name as a string. By convention, variables use camelCase, so we'll call it myName.

Note that Solidity is statically typed, so you always need to define the type of your variable before you assign a value to it. A list of all types can be found in Solidity's documentation.


Finally, we want to be able to retrieve this value from our contract by calling a function. We'll call this function getMyName:

Notice that we need to specify the return value of a function in Solidity. Since we're just returning the myName string in this case, we write returns(string).

Resolving compiler warnings

If you've followed along so far and put the code in Remix, you've probably noticed that there are some warnings on the right-hand side of the window.


Seems like we have 2 warnings.


Every time you change something in your code, Remix will automatically try to compile it. Red fields indicate that the code failed to compile (because of syntax errors), and yellow fields indicate that it compiled with some warnings.


The first warning tells us that the visibility of our function hasn't been specified (and is therefore defaulting to "public"). There are actually 4 visibility types in Ethereum:

  1. public: anyone can call the function, including a consumer of the DApp.

  2. private: only the contract itself can call the function (in another function).

  3. internal: only this contract and all contracts deriving from it can call it.

  4. external: only consumers can call the function, and no other function in the contract itself can.

In my experience, public and private are by far the most used types.


Since we're currently just playing around, we don't mind setting the visibility to public. Note that even though Solidity defaults to this, it's considered good practice to always explicitly specify the visibility of your functions, in order to avoid potentially catastrophic oversights.

After doing this, there should only be one warning left. This one is slightly harder to decrypt:

What the compiler is really saying is that it's detecting that our function never mutates any state on the blockchain – it only reads from it. Therefore, we can use the view modifier to make that more clear:

When a function has a "view" modifier, you don't need to spend any ether to call them (even if they use operations that consume gas), since no transaction needs to be made. They are essentially "free to use".


There are 3 built-in modifiers that have an impact on the amount of ethers that are spent:

  1. view: is free to call, since it only "views" the state of the blockchain without changing it. It was previously known as constant.

  2. pure: also free to call and neither reads nor writes to the blockchain. It is used for "pure" functions where one input will always return the same output.

  3. payable: expects a certain amount of ether regardless of what the gas costs are. This is often used in token sale contracts, where the amount of money sent by the user can vary.

Running your contract

Now that the compiler is happy, head over to the "Run" tab so that we can try out our contract!



Here you can specify some options for creating your contract, like what (fake) address to upload it from for example.


We won't mess with any of these settings for now. Just make sure that the Environment is set to "JavaScript VM", and click on the pink "Create" button.


After clicking, you should see some messages appear in the Remix log.


It might not seem like much, but you actually just deployed your contract to an Ethereum address (although only in a virtual environment)!


Deploying a contract also uses gas, and costs a certain amount of ether. That's why, if you check the account address in the options, your balance should have slightly gone down from 100 ether to something closer to 99.


Now that the HelloWorld contract is up and running, you can call its getMyName function simply by pressing the blue button in the browser window that says "getMyName".


The red squares show the value that is returned once "getMyName" is called.


As you can see, the grey Remix logs the call in more detail and shows something like this:

Also, notice that your address balance did not change when calling the function, since it's a "view" function.

Adding a writeable function

So far so good, but what we really want to do is to let anyone change the name variable to something else. For this, we're going to add a new changeMyName function.

As you can see, this function differs from getMyName in a few ways. It does not use the view modifier, since it actually changes data stored on the blockchain, and it also doesn't return anything.


Arguments in Solidity functions are often prefixed with an underscore (_) to distinguish them from global state variables like myName. We will adopt this convention throughout the course.


Let's redeploy our contract by clicking the "Create" button once more.


After clicking "Create", you should see an updated instance of your contract, which includes the new "changeMyName" button.


Notice how the new "changeMyName" button is pink instead of blue to accentuate the fact that it's a writeable function.


You should now be able to type in a new name in the input field (don't forget to add double quotes around the name), click the "changeMyName" button, and fetch it by clicking "getMyName".

Congratulations, it seems like our code works, and you've just written your first Solidity contract! Getting and setting different kinds of state variables is a key concept that we'll be using over and over again.


In the next chapter, we'll look at how we can run this code locally on our computer instead of relying on Remix in the browser.

Comments

icon

Be the first to comment!