How to Write Smart Contracts
31.05.2021 | 6 min read
Ethereum’s founder Vitallik Buterin attributes the success of the Ethereum blockchain to the implementation of smart contracts. But what exactly are these contracts and why are they so important in blockchain technology?
A smart contract is a self-executing contract. The terms of the agreement between the buyer and the seller are directly written into lines of code. The code and the agreements contained within it exist across a distributed and decentralized blockchain network. It’s important to note that all transactions are trackable and irreversible. Smart contracts save time and conflict; and they are cheaper, faster and more secure than traditional payment systems.
In this post, you will learn how to write and deploy a smart contract. To get started, let's have a look at the fundamental coding language for smart contracts - Solidity.
Programming Languages for Implementing Smart Contracts
Here are just some of the functionalities that are included in Solidity:
- Supports multiple inheritances with C3 linearization.
- Support of state objects or variables, data types, and many more programming functions.
- Complex member variables for contracts containing structs and arbitrarily hierarchical mappings.
- Application Binary Interface facilitates several type-safe functions within a single contract.
Solidity is supported by a number of blockchain platforms, including Ethereum, Tendermint, Ethereum Classic, Counterparty, ErisDB, Hyperledger and Quorum.
But it’s important to note that Solidity is not the only language used to write Smart Contracts. There are others, such as Vyper, which is possibly the second most popular.
So now let's move onto the next step, in which we’ll go through what’s needed to deploy a Smart Contract.
Prerequisites for Deploying a Smart Contract
Before writing any code, you will first have to set your development environment. And it isn't straightforward to fly down the blockchain corridor without a basic understanding of smart contracts. The following two programs have high ratings and are the most preferred by the majority of DeFi developers.
- Local Setup - An environment for developers to implement and deploy enterprise-level smart contract applications. This development environment provides a wide array of decentralized tools to simplify the coding process and provide better flexibility. Setting up this environment might take some effort and time, but some dedication and love will get you through.
- Remix IDE - This environment offers smart contract development a platform to build and test their applications. The platform is fully online, and it's the best place for newbie smart contract developers to get started. There is no installation process, and the Integrated Development Environment (IDE) removes all barriers to entry, prototyping and ensures quick and easy validation of smart contract applications.
Using the Ethereum Virtual Machine (EVM)
EVM is the runtime compilation tool for running smart contracts built on top of the Ethereum blockchain. Think of a dedicated supercomputer/server that hosts all smart contracts. However, the environment is physical, just as its name suggests. A transaction fee powers each smart contract transaction running on the EVM. This transaction fee is measured through a unit called gas: the higher computing resources a transaction requires, the more gas is charged.
EVM operates using a set of instructions which are used to execute specific tasks. These are called Opcodes. There are around 140 of them today and they allow the EVM to compute almost anything using the right resources. For the purposes of simplification, these Opcodes can be split up into the following categories:
- Stack-manipulating opcodes (POP, PUSH, DUP, SWAP)
- Arithmetic/comparison/bitwise opcodes (ADD, SUB, GT, LT, AND, OR)
- Environmental opcodes (CALLER, CALLVALUE, NUMBER)
- Memory-manipulating opcodes (MLOAD, MSTORE, MSTORE8, MSIZE)
- Storage-manipulating opcodes (SLOAD, SSTORE)
- Program counter related opcodes (JUMP, JUMPI, PC, JUMPDEST)
- Halting opcodes (STOP, RETURN, REVERT, INVALID, SELFDESTRUCT)
Because we want to efficiently store opcodes, we can encode them to bytecode. Bytecode, also termed portable code or p-code, is a form of instruction set designed for efficient execution by a software interpreter.
But what then happens when we’re looking to deploy a smart contract? Well here, a regular transaction is created and some bytecode is added as input data. The bytecode acts as a constructor. It is needed to write initial variables to storage before copying the runtime bytecode to the contract’s code. Let’s take a look at how we will structure a smart contract.
Structuring a Smart Contract
To understand the structure of a Smart Contract, let’s look at a basic example from Soliditylang.
So what can we glean from the code here?
The source code - The first line tells us about the source code, which is licensed under the GPL version 3.0. The license specifiers are significant in situations where publishing the source code is the default.
The Solidity version - The second line shows us that the source code is written for Solidity version 0.4.16, or a newer version of the language up to, but not including version 0.9.0. Why is this important? It ensures that the contract isn’t compilable with a newer compiler version, where it could behave differently. Pragmas act as instructions for compilers about how to treat the source code.
As Soliditylang explains, “A contract in the sense of Solidity is a collection of code (its functions) and data (its state) that resides at a specific address on the Ethereum blockchain. The line uint storedData; declares a state variable called storedData of type uint (unsigned integer of 256 bits).” You might look at it like an individual slot in a database which you are able to query and change by calling functions of the code that manage the database.
In the above case, we can see that the contract defines the functions set and get, that can be used to modify or retrieve the value of the variable.
So what’s next? In its present state, this contract doesn’t do a great deal. However, it enables anyone to store a single number that is accessible to anyone else in the world without a method to prevent you from publishing this number. Anyone could call set again with a different value and overwrite your number, but the number is still stored in the history of the blockchain. Of course, at a later stage, you can impose access restrictions so that only you can alter the number.
Transactions in Smart Contracts
The whole idea of the blockchain is that it is a transactional database which is shared globally, meaning that everyone is able to access the database merely by being a network participant. If you want to change something in the database, you must do this via a transaction which is accepted by everyone else. The word transaction implies that the change you want to make (assume you want to change two values at the same time) is either not done at all or completely applied. Furthermore, while your transaction is being applied to the database, no other transaction can alter it.
As an example, imagine a table that lists the balances of all accounts in an electronic currency. If a transfer from one account to another is requested, the transactional nature of the database ensures that if the amount is subtracted from one account, it is always added to the other account. If due to whatever reason, adding the amount to the target account is not possible, the source account is also not modified.
Furthermore, a transaction is always cryptographically signed by the sender (creator). This makes it straightforward to guard access to specific modifications of the database.
Are you looking for expert advice about blockchain implementation at your company?
Get in touch with Sales Team Leader Dennis for a free blockchain consultation. You can contact me on firstname.lastname@example.org or call me on +48 793 200 141