Solidity Smart Contracts 101
Solidity smart contracts have various uses ranging from multi signature wallets to decentralized exchanges. Solidity is one of the major web3 programming languages built specially for creating smart contracts and has therefore seen a steady increase in popularity.
This article will introduce you to Solidity smart contracts, how they work and their properties. We will also run through Solidity smart contract syntax and data types to get you started on interacting with Solidity smart contracts for your next project.
What is a Solidity smart contract?
A Solidity smart contract is a program written in Solidity, deployed to the Ethereum blockchain, and executed in the Ethereum Virtual Machine (EVM). Ethereum stores the smart contract code and data (its state) at a designated address.
When predetermined conditions are met, the program, or smart contract, stored on the blockchain is executed without the need of an intermediary. Smart contracts are, in other words, programs which govern the behavior of accounts within the Ethereum state.
You can write smart contracts in Solidity or any other EVM-compatible programming language. They must be compiled into bytecode first to be EVM compatible.
Solidity is an object-oriented, high-level language for writing smart contracts. Smart contracts written in Solidity can be used for various purposes like voting, crowdfunding, blind auctions, and multi-signature wallets.
How do smart contracts work?
Smart contracts are programs stored on the blockchain. A smart contract fortifies agreements between various parties in code and enforces rules automatically when pre-conditions are met. This means that all parties involved in the smart contract are immediately certain of the outcome, without time lost or involvement of a third party. Smart contracts can also automate workflows to trigger the next event upon execution.
Smart contracts that follow the ERC20 standard are considered ERC20 tokens. ERC20 tokens allow for the transfer of tokens between holders.
What are the properties of Solidity smart contracts?
Smart contracts are by nature, immutable and deterministic. This means that once a smart contract is deployed or built on Ethereum, it will never cease to exist unless conditions which trigger a self-destruct have been programmed within it. The code will always execute on the conditions it has been programmed to.
Additionally, smart contracts are deterministic since each network node is able to produce the same result when the same input is given for a method. Should different nodes arrive at different outputs on execution of the smart contract, the consensus protocol is violated and the smart contract is rendered unusable.
Also, smart contracts are permissionless, which means anyone in possession of ETH and has access to the internet is able to deploy a smart contract on Ethereum.
Finally, smart contracts are composable. This means that you can use smart contracts from other projects as building blocks for your project. Smart contracts can be thought of as open APIs where users do not need to write their own smart contract to become a dApp developer, users just need to know how to interact with them.
Solidity Smart Contract Syntax
While there are many resources available to help you get started learning Solidity, this section will outline the syntax used to write Solidity smart contracts.
Contracts in Solidity are similar to classes in object-oriented languages. Each contract can contain declarations of State Variables, Functions, Function Modifiers, Events, Errors, Struct Types and Enum Types. In this article we will discuss Constructors, State Variables and Integer Variables in further detail. Furthermore, contracts can inherit from other contracts.
There are also special contracts called libraries and interfaces.
2. Semantic Versioning
Solidity, like most softwares, uses semantic versioning. This means there are no big changes unless you are updating a major version. You can refer to the main breaking changes introduced to each Solidity version on the docs. The most updated version of Solidity is v0. 8.16, as of August 2022.
A constructor is called only once during deployment, or contract creation. A constructor is an optional function declared with the constructor keyword and allows you to run contract initialization code.
Before the constructor code is executed, state variables are initialized to their specified value if you initialize them inline, or their default value if you do not.
After the constructor has run, the final code of the contract is deployed to the blockchain.
If there is no constructor, the contract will assume the default constructor.
4. State Variables
State variables are variables whose values are stored in contract storage. Each function has its own scope, and state variables should always be defined outside of that scope.
State variables adhere to visibility. You can make state variables public with the public visibility keyword, which provides a getter function which other smart contracts can access.
In Solidity, a modifier amends the semantics of a function in a declarative way. In other words, modifiers change the behavior of the function to which they are attached. Modifiers are useful in eliminating code redundancy and can be reused to check for the same condition in multiple functions within a smart contract.
6. Integer variables
There are two types of integer variables in Solidity: unsigned integers (uint), and signed integers (int). A signed integer is a value data type that can store negative and positive values. An unsigned integer, on the other hand, has no sign and therefore is a value data type that must be non-negative.
Solidity Data Types
Like other programming languages, Solidity has various classifications of data types. However, Solidity is unique in that various elementary data types can be combined to form more complex data types. This section outlines the major data types in Solidity.
The possible values of booleans, denoted by bool in Solidity, are constants true and false.
String literals are written with either double or single-quotes. Strings can also be split into multiple consecutive parts, which can be helpful when dealing with long strings.
Fixed and ufixed refer respectively to signed and unsigned fixed point numbers of various sizes.
In Solidity, byte refers to 8-bit signed integers. Bits are stored in the memory with binary values of 0 or 1. In Solidity, the data type byte represents a sequence of bytes.
There are two types of byte types in Solidity, fixed-sized byte arrays and dynamically-sized byte arrays. The keyword bytesX is used to define variables where X denotes the sequence of bytes from 1 up to 32.
Bytes in Solidity represents a dynamic array of bytes. They are not, however, a value type.
The address holds a 20-byte value, which is the size of an Ethereum address. Hexadecimal literals that pass the address checksum test are of address type. Hexadecimal literals that are between 39 and 41 digits long and do not pass the checksum test produce an error. You can prepend (for integer types) or append (for bytesNN types) zeros to remove the error.
6. Payable Address
The payable address, denoted by address payable, is similar to the address but with additional members transfer and send. The distinction is necessary because a plain address may be a smart contract that is not built to accept Ether (ETH). An address payable is an address you can send Ether to.
Enums, also known as enumeration values in Solidity, are one way to create a user-defined type, which allows creating constant values, such as the names of integral constants. Enums make a smart contract easier to read and maintain as opposed to elementary value types.
Enums are explicitly convertible to and from all integer types, but implicit conversion is not allowed. The explicit conversion from integer checks at runtime that the value lies inside the range of the enum and causes a panic error otherwise. Enums therefore reduce the incidence of bugs in your code.
Enums require at least one member, and its default value when declared is the first member. Enums cannot have more than 256 members.
Arrays are a group of variables of the same data type, with each variable having a unique index. Arrays can have a compile-time fixed size, which makes them fixed arrays, or they can have a dynamic size, which makes them dynamic arrays.
Fixed-size arrays have a predefined size upon declaration. The new keyword cannot be used to introduce additional array members. Instead, the data variables must be initialized inline.
Dynamic-sized arrays do not have a predefined size when they are declared. Instead, their size is determined at run time.
Array elements can be of any type, including a mapping or a struct, a user-defined data structure.
In Solidity, mappings work like hash tables or dictionaries in other programming languages. Mappings work as a reference type and store data in the form of key-value pairs, where the key can be any of the inbuilt data types except for reference types, and the value can be any type.
If state variables of a mapping type are public, Solidity creates a getter function for you.
10. Structs (user-defined types)
A struct, or a structure, allows you to define new data types. Struct types can be used inside mappings and arrays and they can themselves contain nested mappings and arrays. However, It is not possible for a struct to contain a member of its own type since the size of the struct must be finite.
What is smart contract context?
A smart contract context provides information about the environment a transaction is running in. When a smart contract function is called via a transaction, the called function receives some extra information passed to it. Within a smart contract function you’ll have access to these context variables.
You have access to the message sender, gas prices, and the tests conducted at the transaction. Therefore, you have access to a bunch of context variables that you can use in your code’s logic interchangeably.
Sign Up for the Solidity Bootcamp to Learn More