Intermediate

 

Solidity – Smart Contract Language

Welcome to our tutorial on Solidity, the smart contract programming language for the Klaytn blockchain network. Solidity is a contract-oriented, high-level programming language that is used to write smart contracts on the Ethereum and Klaytn blockchain platforms. It is designed to be similar to JavaScript, making it easy for developers with a background in that language to pick up. In this tutorial, we will explore the basics of Solidity, including the syntax, data types, and the most commonly used functions and libraries. We will also walk through the process of writing, testing, and deploying a simple smart contract on the Klaytn network. Whether you are a developer, researcher, or simply a blockchain enthusiast, this tutorial will provide valuable insights and hands-on experience in writing smart contracts with Solidity on the Klaytn network.

This chapter describes only the high-level concepts, development processes, and examples written in Solidity because Solidity is already well documented on its official websites.

Solidity and Klaytn

Solidity is a high-level, statically typed, contract-oriented language for implementing smart contracts on the Ethereum platform. Although Solidity was originally designed for Ethereum, it is general enough to write smart contracts; therefore, it can also be used for other blockchain platforms, such as Klaytn.

Klaytn is officially compatible with London Ethereum Virtual Machine (EVM) version. Backward compatibility is not guaranteed with other EVM versions on Klaytn. Thus, it is highly recommended to compile Solidity code with the Istanbul target option.

Development tools such as Remix (a browser-based IDE) and Truffle (a development framework) can be utilized when developing smart contracts for Klaytn. The Klaytn team will attempt to maintain compatibility between Ethereum’s development tools and Klaytn’s but may elect to provide the Klaytn smart contract developers with enhanced or updated versions of those tools when necessary.

It is convenient to utilize Remix or Truffle to develop smart contracts, but the Solidity compiler can be used locally, by building or installing it by following the instructions described on the web page below:

Note that there are two command-line Solidity compilers:

  • solc: the full-featured compiler

    • Covered in the Solidity documentation

  • solcjs: Javascript binding for solc

    • Maintained as a separate project solc-js

    • solcjs‘s command-line options are not compatible with those of solc.

How to Write a Smart Contract

This section presents an example of Solidity source code to provide readers with an idea of how smart contracts look and how to write a contract. Note that the code included here is provided solely for explanatory purposes; it is not intended for production purposes. In the code, (require) means that the line is required for any Solidity source file while (optional) indicates that the line is not always needed. The symbol Ln: is not part of the Solidity code and is included here only to show the line numbers. Please do not include these symbols in the source code intended for real use.

L01: pragma solidity 0.5.12;   // (required) version pragma
L02:
L03: import "filename";        // (optional) importing other source files
L04:
L05: // (optional) smart contract definition
L06: contract UserStorage {
L07:    mapping(address => uint) userData;  // state variable
L08:
L09:    function set(uint x) public {
L10:       userData[msg.sender] = x;
L11:    }
L12:
L13:    function get() public view returns (uint) {
L14:       return userData[msg.sender];
L15:    }
L16:
L17:    function getUserData(address user) public view returns (uint) {
L18:       return userData[user];
L19:    }
L20: }

The above code should be self-explanatory; thus people familiar with any other programming language can skip the following explanation in this section and jump to the next section. However, for those who do not gain a clear understanding of what the code does or those for whom Solidity is a first programming language, we include a short description of the source code below:

  • The portions of the code starting with a double forward slash (//) are comments rather than code; they are used to annotate and explain the code. The compiler ignores comments.

  • The pragma statement in L01 indicates the minimum compiler version. – The import statement in L03 imports all global symbols from “filename“. filename should be an actual file name.

  • L05L20 defines a smart contract called UserStorage. The keyword contract is located before the contract name and declares that the code represents a smart contract. Contracts in Solidity are similar to classes in object-oriented languages. Each contract can contain declarations for state variables, functions, function modifiers, events, struct types, and enum types. Furthermore, contracts can inherit from other contracts. The example code contains one contract definition, but a single Solidity file may contain more than one contract definition.

  • In L07, userData is a state variable for the mapping type. State variables are permanently stored in contract storage. The state variable userData maintains a mapping between address and a uint value. The address type holds a 20-byte address (Klaytn uses a 20-byte address similar to Ethereum).

  • L09 defines a public function set that saves the value x in userData for the message’s sender. The variable msg.sender is a special variable defined in Solidity that represents the address of the message (i.e., current call) sender. The keyword public means that the function is part of the contract interface and can be called externally or internally.

  • The functions get in L13 and getUserData in L17 are declared with view, which means that the functions promise not to modify any state variable. Their declarations include returns (uint), which implies that they return a uint value.

 

For more information concerning the syntax and semantics of the Solidity language, please refer to the Solidity documentation.

How to Compile, Deploy, and Execute

One way to compile Solidity code is to use the command-line compiler solc. This compiler can produce various outputs, ranging from simple binaries and assembly to an abstract syntax tree (parse tree). Assuming that the code above is saved in UserStorage.sol (L03 is excluded in the source file shown above), some examples of compiling the file UserStorage.sol are as follows.

$ solc --bin UserStorage.sol
  • This command will print the compilation output as a binary, i.e., bytecode.

solc -o output --bin --ast --asm UserStorage.sol
  • The compiler generates a binary (by --bin), an abstract syntax tree (by --ast), and assembly code (by --asm) as separate files in the output directory.

solc --optimize --bin UserStorage.sol
  • For better performance, the optimizer can be activated during compilation using the --optimize flag.

Debugging Smart Contracts

It is more difficult to debug Solidity code than to debug code written in other programming languages due to the lack of mature debugging tools. Below, we list some resources for Solidity debugging.

Smart Contract Best Practices

To eliminate security concerns and code quality issues from your smart contract, it is important to study and follow best practices in Solidity programming. Here, we show a reference for Solidity’s best practices.

With this, you complete this workshop successfully!!