Solidity - Smart Contract Language
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. For language specifications or implementations, please refer to the References below. The content of this chapter is based on various websites listed in the References.
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. Please refer to how to set the EVM version of solc.
v1.7.0 Protocol Upgrade - incompatible changes including Istanbul hard fork items and Klaytn's own items.
It has been enabled from block number #75,373,312
in case of Baobab network and #86,816,005
for the Cypress network.
v1.7.3 Protocol Upgrade - incompatible changes including Base Fee from the London hard fork.
It has been enabled from block number #80,295,291
in case of Baobab network and #86,816,005
for the Cypress network.
v1.8.0 Protocol Upgrade - incompatible changes including Base Fee from the London hard fork.
It has been enabled from block number #86,513,895
in case of Baobab network and #86,816,005
for the Cypress network.
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 in 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.
Other materials that are useful for getting started with Solidity include the following:
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 source code intended for real use.
L01: pragma solidity 0.5.12; // (required) version pragmaL02:L03: import "filename"; // (optional) importing other source filesL04:L05: // (optional) smart contract definitionL06: contract UserStorage {L07: mapping(address => uint) userData; // state variableL08: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 inL01
indicates the minimum compiler version. - The
import
statement inL03
imports all global symbols from "filename
". Thefilename
should be an actual file name. L05
-L20
define a smart contract calledUserStorage
. The keywordcontract
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 variableuserData
maintains a mapping betweenaddress
and auint
value. Theaddress
type holds a 20-byte address (Klaytn uses a 20-byte address similar to Ethereum). L09
defines a public functionset
that saves the valuex
inuserData
for the message's sender. The variablemsg.sender
is a special variable defined in Solidity that represents the address of the message (i.e., current call) sender. The keywordpublic
means that the function is part of the contract interface and can be called externally or internally.- The functions
get
inL13
andgetUserData
inL17
are declared withview
, which means that the functions promise not to modify any state variable. Their declarations includereturns (uint)
, which implies that they return auint
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 theoutput
directory.
solc --optimize --bin UserStorage.sol
- For better performance, the optimizer can be activated during compilation using the
--optimize
flag.
Some resources for compiling, deploying, and executing smart contracts are listed below.
- Using the Solidity command-line compiler
- Compiling contracts using Remix
- Running transactions with Remix
- Remix Learneth Tutorials
- Compiling contracts with Truffle
- Deploying contracts with Truffle
NOTE: This section will be updated in the future.
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.
- Debugging a transaction with Remix
- Tutorial on debugging transactions with Remix
- Debugging contracts with Truffle
NOTE: This section will be updated in the future.
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 best practices.
NOTE: This section will be updated in the future.