How to Write and Compile a Solidity Smart Contract

In this video, we'll write our first Solidity smart contract

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

Creating .bin

To compile our Solidity smart contract, we need a compiler. The main solidity compiler is solc.

https://github.com/ethereum/solidity

It's written in C++ and it's a good idea to use a formal release build for your production smart contracts.

That said, getting the C++ version of solc installed can sometimes be a pain. My recommendation is that you install solc before you deploy your first contracts on the production network, but for now, we can use the JavaScript version solcjs.

# this installs solcjs (not the c++ version of solc)
npm install -g solc

Solcjs's core code is generated using Emscripten to convert the C++ version of solc to JavaScript. This means it will work just fine, but know that the command-line options are different.

We can compile our contract by typing this:

solcjs --bin counter.sol

And let's take a look at the output:

This lesson preview is part of the Intro to Programming Ethereum ĐApps course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to Intro to Programming Ethereum ĐApps, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Intro to Programming Ethereum ĐApps

To compile our Solidity Smart Contract, we need a compiler. The main Solidity compiler is Sulk. It's written in C++ and it's a good idea to use a formal release build for your production smart contracts. That said, getting the C++ version of Sulk installed can sometimes be a pain. My recommendation is that you install Sulk before you deploy your first smart contracts to the production network, but for now, we can just use the JavaScript version, Sulk.js. To install Sulk.js, we'll run npm install -g_sulk. Remember, this installs Sulk.js, not the C++ version. Sulk.js is core code is generated using mScriptin, which converts the C++ version of Sulk into JavaScript. This means it'll work just fine, it's a little slow, but know that the command line options are different. There are other IDE-like tools we can use to compile our contracts, and we'll look at those. But since we're just getting started, I think it's clearest to just compile them by hand ourselves on the command line. We can compile our contract by typing this. Sulk.js-pin counter.sulk. Let's take a look at the output. Well, that's not exactly enlightening, but this is a hex encoded version of the bytecode of our script. There are other ways of viewing the opcodes that are clearer, but we don't need them right now. While we're here, another thing we need to generate is the ABI, which stands for Application Binary Interface. The ABI defines the interface to the functions on our contract. The reason we need this is because the encoding of our program is not self-describing. That is, you can't easily tell from the bytecode how each function should be called or what it returns. The A BI tells us how we can use a contract. And actually, we can just generate both of them at the same time like this. Sulk.js-bin-abicamter.sulk. Let's take a look at the ABI. And that's a bit compact, so I'm going to pipe it through jq for int and int ation and color. Reading this ABI, we see that we have an array with one entry for each function . Here we have get, which has outputs of a Uint 256, our increment function, and our constructor. We'll use this ABI when we call our contract as an object. Let's flip back to get and deploy this contract. First, start geth like we did in the earlier video. /bin/geth, pass the data to our and call the console. Now we're in a JavaScript console so we can declare variables, functions, etc. As a reminder, in an earlier video we created some accounts and mined some ETH. We'll need both the accounts and the ETH now, so if you don't have those, go back to that earlier video. The first thing that we're going to do is assign our contract hex code to a variable. It will help if you have two tabs open. I have a geth console in one and a shell in the other. So I'm going to cat, counter, soul, counter.bin. And here you can either select to copy and paste the code, or because I'm on a Mac, I'm going to use pbcopy. And flip back over to our geth console, we'll create a variable var countercode equals and then paste in our code into a string. Let's take a look. Now to create an instance of this contract on the Ethereum network, we need to send a transaction. Also, to send a transaction, it will cost some ETH, so we need to unlock our account first. Now it's time to send our transaction. We'll type ETH.send transaction from ETH account zero. And for data, we're going to pass our contract code. But hex strings must be prefixed with zero X. So we're going to pre-pend our countercode with the string zero X. For the third parameter, we're going to set gas. We haven't talked about gas yet, so just put 1 million here. The second argument to send transaction is a callback function, with the first argument being an error, if there was any, and the second argument being the transaction. We'll just console log both of those out. Notice in the output that we have contract equals a hash. This hash is the address of our contract. This is a permanent address, so make sure you save this value. We're going to need it. Here, we'll set it as the variable contract adder. One way we can check on our contract is using ETH.getcode. Here it says zero X, which means something isn't right. And the problem is, although we've submitted a transaction, we haven't mined it yet. So let's mine it now. This might take a second. All right, we'll stop the miner. Let's check ETH.getcode again. Great. If you call ETH.getcode and it says zero X, then something went wrong. A value of zero X means it didn't work. But here I can see my contract code, so we're good. We 've deployed our contract. Our code's permanent address is now stored at the value of contract adder. You can think of that address as your contract's personal domain name. It isn't pretty, but it's uniquely yours. Now that we have a contract on the blockchain, we can start using it.