# How to use Solidity programming

Solidity is used for crafting complex **Smart Contracts designed to operate on the Ethereum [blockchain](https://www.ionos.com/digitalguide/online-marketing/online-sales/blockchain/ "Blockchain")**. This language presents unique strategies that distinguish it from other programming languages.

## What is Solidity?

Solidity is a high-level programming language for creating smart contracts on the Ethereum blockchain. Smart contracts are **self-executing contracts that automate the exchange of assets between parties**. What is special about them is that no intermediaries are needed to ensure compliance with the smart contract.

Solidity [source code](https://www.ionos.com/digitalguide/websites/web-development/source-code-explained-definition-examples/ "Source code explained: Definition &amp; Examples") is compiled into bytecode and **deployed** on the Ethereum blockchain as a smart contract. Once done, the smart contract can be executed by any node on the network, and the state is stored on the blockchain. We show an example of a simple contract modeling an NFT vending machine:

```solidity
pragma Solidity 0.8.7;
contract NFTVendingMachine {
    // Declare state variables
    address public owner;
    mapping (address => uint) public nftBalance;
    // Run on deployment
    constructor() {
        owner = msg.sender;
        nftBalance[address(this)] = 100;
    }
    // Allow the owner to restock the NFT balance
    function restock(uint amount) public {
        require(msg.sender == owner, "Only the owner can restock.");
        nftBalance[address(this)] += amount;
    }
    // Allow anyone to purchase NFTs
    function purchase(uint amount) public payable {
        require(msg.value >= amount * 1 ether, "You must pay at least 1 ETH per NFT");
        require(nftBalance[address(this)] >= amount, "Not enough NFTs in stock to complete this purchase");
        nftBalance[address(this)] -= amount;
        nftBalance[msg.sender] += amount;
    }
}
```

## Which applications is Solidity suitable for?

Solidity is specifically designed for **creating distributed applications** or [DApps](https://www.ionos.com/digitalguide/websites/web-development/dapp/) running on the Ethereum Virtual Machine (EVM). Smart contracts are suitable for managing digital assets, creating decentralized exchanges, and implementing voting systems, among other things.

### Decentralized finances (DeFi)

Solidity is being used to develop DeFi applications such as **decentralized exchanges, credit and lending platforms, prediction markets, and [cryptocurrencies](https://www.ionos.com/digitalguide/online-marketing/online-sales/cryptocurrency/ "Cryptocurrency")**. DeFi has become one of the most popular use cases for blockchain technology. In the process, Solidity has become an indispensable tool for building DeFi applications on the Ethereum network.

### Non-fungible tokens

The [non-fungible token](https://www.ionos.com/digitalguide/online-marketing/online-sales/nft-non-fungible-token/ "NFT - Non-Fungible Token") (NFT), has enjoyed great popularity since the 2020s. NFTs are unique digital assets stored on the blockchain. They can be **digital artworks, sports memorabilia or artifacts from the gaming industry**. Solidity is used to create the smart contracts that power NFTs.

### Delivery chain management

Solidity can be used to create smart contracts for **monitoring and managing supply chains**. The contracts are used to automate various supply chain processes. These include tracking the movement of goods, verifying the authenticity of products, and processing payments between parties.

### Reconciliation systems

Solidity can be used to create smart contracts that **implement secure and transparent voting systems on the blockchain**. The contracts can be used to ensure that votes are counted correctly and that the voting process is fair and transparent.

## What are the pros and cons of Solidity?

While Solidity is a powerful language for constructing smart contracts on the Ethereum blockchain, it has its specific advantages and disadvantages that developers should consider when developing smart contracts. Nevertheless, crafting secure smart contracts demands a specific level of **proficiency and caution**.

As an illustration, below is a **smart contract that functions as a black hole**. Any Ether sent to the contract is permanently consumed, with no possibility of retrieving the Ether or making a payout:

```solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >= 0.9.0;
// This contract swallows all Ether sent to it
contract Blackhole {
    event Received(address, uint);
    receive() external payable {
            emit Received(msg.sender, msg.value);
    }
}
```

### Advantages of Solidity

- **Flexibility**: Solidity is a versatile language. It can be used to develop different smart contracts with a variety of use cases.
- **Security**: Solidity was created with a focus on security, incorporating characteristics such as access controls, exception handling, and failure mechanisms to aid developers in crafting secure contracts.
- **Ethereum compatibility**: Currently, Solidity is the preferred language for producing smart contracts on the Ethereum blockchain.
- **Distinct community**: A large community of blockchain developers works with Solidity, resulting in a plethora of resources for learning and problem-solving.

### Disadvantages of Solidity

- **Learning curve**: For developers who are new to blockchain and smart contract development, Solidity has a relatively steep learning curve.
- **Unchangeability**: Once a smart contract is deployed on the blockchain, it cannot be modified further. It follows that developers need to be extremely careful when writing and testing.
- **Lack of formal verification**: Solidity lacks built-in tools for formal code review. This necessitates that developers utilize external tools to guarantee the accuracy of their contracts.
- **Limited tooling**: Solidity’s tooling ecosystem is still in its nascent stages, which could result in issues with Integrated Development Environments (IDEs), testing frameworks, and other development tools.

## What is the basic syntax of Solidity?

Solidity is an **object-oriented programming language designed for smart contracts**. It takes inspiration from JavaScript, Python, and C++. The language’s syntax is similar to JavaScript, albeit with some intriguing idiosyncrasies.

### Variables in Solidity

At first glance, Solidity’s variable handling may appear similar to other programming languages. However, a critical distinction arises from the fact that the Ethereum Virtual Machine (EVM) serves as the execution environment. All **operations on the EVM, including data storage, incur a certain amount of “gas” cost**. Consequently, during programming, one must weigh the efficiency of an operation and determine how it can be implemented as efficiently as feasible.

In addition to regular variables, Solidity has **constants, which must be defined** during compiling. Constants necessitate less gas for storage:

```solidity
// Regular variable can be declared without defining
int a;
// Constant needs to be defined at declaration
int constant b = 51;
```

The same applies to `immutable` variables in that they require less gas and **cannot be changed after assignment**. Unlike `constant` variables, the assignment of immutable variables can be done at runtime.

### Control statements in Solidity

As an imperative programming language, Solidity supports familiar control statements, such as **branches and loops**. We show the code for selecting the larger of two numbers, `a` and `b`:

```solidity
int largerNumber = 0;
// If-else statement
if (a > b) {
    largerNumber = a;
} else {
        largerNumber = b;
}
```

The `for` **loop in Solidity** corresponds to the syntax known from JavaScript or C++:

```solidity
// Loop 10 times
for (int i = 0; i < 10; i++) {
    // …
}
```

The `while` **loop also works as usual**. We combine a termination condition with a numeric counter variable:

```solidity
bool continueLoop = true;
int counter = 0;
// Loop at most 10 times
while (continueLoop && counter < 10) {
    // …
    counter++;
}
```

### Simple types in Solidity

Solidity is a **statically-typed language** and supports the types commonly found in programming languages. Simple types that represent single values include Booleans, numbers, and strings.

Booleans in Solidity map the values `true` and `false`. They can be linked using the **known Boolean operators** and used in `if` statements:

```solidity
bool paymentReceived = true;
bool itemsStocked = true;
bool continueTransaction = paymentReceived && itemsStocked;
if (continueTransaction) {
    // ...
}
```

Solidity supports a **wide range of numeric types**. Integer numbers can be distinguished between signed (`int`) and unsigned (`uint`) numbers, where the latter may only be positive. Furthermore, the range of a number can be specified in steps of 8 bits, from `int8` via `int16` up to `int265`:

```solidity
uint8 smallNumber = 120;
int8 negativeNumber = -125;
int8 result = smallNumber + negativeNumber;
assert(result == -5)
```

Strings are used in Solidity mainly for generating status messages. The language supports **single and double quotes** as well as Unicode characters:

```Solidity
string message = 'Hello World';
string success = unicode"Transfer sent";
```

### Functions in Solidity

**Functions are a fundamental aspect** of Solidity, as in most programming languages. The definition of a function is similar to JavaScript, where the argument types must be explicitly specified. Additionally, a returns keyword is utilized to indicate the `return` value types.

```solidity
// Define a function
function addNumbers(int a, int b) returns (int) {
    return a + b;
}
```

The **call of a function** is done as usual:

```solidity
// Call the function
int result = addNumbers(2, 3);
```

Interestingly, **analogous to named arguments, return values in Solidity can also be named**. In this situation, assigning the corresponding variables in the function body suffices, and an explicit return via `return` is unnecessary:

```solidity
function divideNumbers(int dividend, int divisor) returns (int quotient) {
    quotient = dividend / divisor;
    // No `return` necessary
}
```

Similar to `constant` or `immutable` variables, in Solidity **functions can be marked as not state-modifying**. The keywords `view` and `pure` are used for this purpose. A `view` function doesn’t change the state, while a `pure` function additionally guarantees not to read state variables.

### Smart Contracts in Solidity

In addition to standard types, Solidity knows a handful of **smart contract specialized types**. The basic type is `address` and maps Ethereum addresses. Addresses that are `payable` can receive transfers in Ether. For this purpose, `payable` addresses provide `balance()` and `transfer()` methods.

```solidity
// Get address of this contract
address mine = address(this);
// Get payable external address
address payable other = payable(0x123);
// Transfer if balances fulfill conditions
if (other.balance < 10 && mine.balance >= 100) {
    other.transfer(10);
}
```

Building on the `address` type, the `contract` type exists as a central language construct. **Contracts correspond roughly to classes in object-oriented programming languages**. Thus, contracts bundle state data and functions and shield them from the outside world. Contracts support multiple inheritance, as known from Python or C++.

Contracts **usually begin with a `pragma` line** specifying the allowed Solidity version, followed by the actual definition:

```solidity
// Make sure Solidity version matches
pragma Solidity >=0.7.1 <0.9.0;
// Contract definition
contract Purchase {
    // Public state variables
    address seller;
    address buyer;
    
    // View-function
    function getSeller() external view returns (address) {
        return seller;
    }
}
```

Smart contracts can define **state data and functions**. As known from C++ and Java, one of three access levels can be defined in each case:

- `public`: The variable can be accessed **by reading and writing from within the contract**. Additionally, a `view` function is automatically generated as a getter for external read access.
- `internal`: The variable is **shielded** from external access. Read and write access is possible from within the contract as well as from inheriting contracts.
- `private`: like `internal`, but there’s **no access from inheriting contracts**

Functions can further be characterized as `external`. An `external` function **acts as part of the contract interface** and is used for external access. The `receive` function for receiving ether is a well-known example:

```solidity
// Define without `function` keyword
receive() external payable {
    // Handle Ether
}
```

### Modifiers in Solidity

Solidity has an intriguing language construct in the form of modifiers, which bear resemblance to Python’s decorators. Similar to Python, modifiers in Solidity are utilized to **alter the invocation of a function**. They are frequently employed to ensure that a specific condition is satisfied before executing a function:

```solidity
contract Sale {
    uint price;
    address payable owner;
    modifier onlyOwner {
        // Will throw error if called by anyone other than the owner
        require(
            msg.sender == owner,
            "Only owner can call this function."
        );
        // The wrapped function's body is inserted here
        _;
    }
    
    // `onlyOwner` wraps `changePrice`
    function changePrice(uint newPrice) public onlyOwner {
        // We'll only get here if the owner called this function
        price = newPrice;
    }
}
```

### Transaction management with Solidity

Solidity has a built-in transaction management. This can be used to ensure that an **ether transfer is either completely settled** or not settled at all. The language understands the `revert` keyword, which triggers a “roll-back” of a transaction. With the `error` keyword you can define your own error codes:

```solidity
// Custom error definition
error InsufficientPayment(uint256 paid, uint256 required);
// Contract representing a sale
contract Sale {
    uint price;
    // Purchase if enough ether transferred
    function purchase() public payable {
        if (msg.value < price) {
            revert InsufficientPayment(msg.value, price);
        }
        // Complete purchase
    }
}
```

Another **frequently encountered pattern** is the use of the `require()` function. This can be used analogously to `revert`:

```solidity
// Using `require()` function
if (!condition) revert("Error message");
// Equivalent to
require(condition, "Error message");
```


This is a markdown version of: [https://www.ionos.com/digitalguide/websites/web-development/solidity-programming/](https://www.ionos.com/digitalguide/websites/web-development/solidity-programming/) for AI/LLM consumption.