# Klaytn Docs

{% hint style="info" %}
This is the archived documentation for Klatyn, which is no longer maintained. For up-to-date documentation, visit [our new doc site](https://docs.klaytn.foundation/).
{% endhint %}

Klaytn Docs introduces [Klaytn](http://klaytn.foundation), an enterprise-grade, service-centric platform that brings user-friendly blockchain experience to millions of users.

Read our [Lightpaper](https://klaytn.foundation/wp-content/uploads/Lightpaper.pdf).

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Klaytn Overview</strong></td><td>Want to know about Klaytn?</td><td></td><td><a href="/files/F4wrpdkvABtLgSvLPP2y">/files/F4wrpdkvABtLgSvLPP2y</a></td><td><a href="/pages/cEOSRVfTRJDQXBtETzCu">/pages/cEOSRVfTRJDQXBtETzCu</a></td></tr><tr><td><strong>Getting Started</strong></td><td>Want to start building on Klaytn?</td><td></td><td><a href="/files/d9d2XoJo2DmkMNxoNRGA">/files/d9d2XoJo2DmkMNxoNRGA</a></td><td><a href="/pages/UVfMGJMvK7PXsC1BRwOU">/pages/UVfMGJMvK7PXsC1BRwOU</a></td></tr><tr><td><strong>Node Operators</strong></td><td>Instructions on running Klaytn's nodes</td><td></td><td><a href="/files/8CbXsl9MVtDpZTh2Xc22">/files/8CbXsl9MVtDpZTh2Xc22</a></td><td><a href="/pages/Pz4QhJRUxpIWoPZGWKfZ">/pages/Pz4QhJRUxpIWoPZGWKfZ</a></td></tr><tr><td><strong>Awesome Klaytn</strong></td><td>Comprehensive list of resources from Klaytn's vast ecosystem</td><td></td><td><a href="/files/HRreaBlIQCHpvypAMWKR">/files/HRreaBlIQCHpvypAMWKR</a></td><td><a href="https://github.com/klaytn/awesome-klaytn">https://github.com/klaytn/awesome-klaytn</a></td></tr><tr><td><strong>Klaytn Developer Hub</strong></td><td>Klaytn's developer portal</td><td></td><td><a href="/files/ZhOIqKQBauu02qXjYlah">/files/ZhOIqKQBauu02qXjYlah</a></td><td><a href="http://developer.klaytn.foundation">http://developer.klaytn.foundation</a></td></tr><tr><td><strong>Klaytn Developer Forum</strong></td><td>Got a question? Visit our forum!</td><td></td><td><a href="/files/D125IRIyLOytWzEhhrHs">/files/D125IRIyLOytWzEhhrHs</a></td><td><a href="http://forum.klaytn.foundation">http://forum.klaytn.foundation</a></td></tr></tbody></table>


# Klaytn Overview

Klaytn is a highly optimized, BFT-based public blockchain that aims to meet the enterprise-grade reliability. Key design goals are;

* Immediate finality.
* High TPS that meets real-world use cases.
* Lower the cost of running Blockchain Applications.
* Lower the barriers to entry for end-users.
* Ease the technology adoption process for industry.

Klaytn launched its mainnet, [Cypress](https://scope.klaytn.com/), on Jun/27/2019 with the following specifications.

* 1-second block generation and confirmation time.
* 4,000 transactions per second.
* Low gas price that is almost 1/10 of Ethereum.
* Runs EVM (Ethereum Virtual Machine) and supports the execution of Solidity contracts.
* 19 reputable corporations worldwide initially formed Klaytn Governance Council to operate consensus nodes. The current number of consensus nodes is shown in the [Klaytnscope](https://scope.klaytn.com/).
* More than 50 initial service partners have committed to launch Blockchain Applications on Klaytn.

## Klaytn: The Big Picture <a href="#klaytn-the-big-picture" id="klaytn-the-big-picture"></a>

Klaytn can be partitioned into three logical subnetworks based on their roles and purposes. The below figure displays the high-level view of the Klaytn ecosystem.

![Klaytn Ecosystem and its Logical Subnetworks (CCN, ENN, SCN)](/files/R7bL7fr1Wt0n0H6m5MW4)

### Core Cell Network (CCN) <a href="#core-cell-network-ccn" id="core-cell-network-ccn"></a>

CCN consists of Core Cells (CCs) that verify and execute transactions submitted through Endpoint Nodes (ENs). CCN is responsible for creating and propagating blocks throughout the network.

### Endpoint Node Network (ENN) <a href="#endpoint-node-network-enn" id="endpoint-node-network-enn"></a>

ENN consists of Endpoint Nodes (ENs) that mainly create transactions, handle RPC API requests, and process data requests from service chains.

### Service Chain Network (SCN) <a href="#service-chain-network-scn" id="service-chain-network-scn"></a>

SCNs are Klaytn subnetworks composed of auxiliary blockchains independently operated by dApps (Decentralized Applications). Service chains are connected to the main chain via ENs.

**Core Cell Network** and **Endpoint Node Network** form a Klaytn main chain or mainnet. Blockchain Applications can run on the Klaytn main chain, Cypress, or can operate on their own blockchains called **Service Chains**. If you want to have a dedicated execution environment for your application that guarantees high TPS and configurable network policies, we recommend using Service Chain.

> To set up a Service Chain for your application, read the [installation and operation guide of Service Chain](/content/installation-guide/deployment/service-chain/getting-started).

## Klaytn Network Topology <a href="#klaytn-network-topology" id="klaytn-network-topology"></a>

In this section, we will describe the network topology of Klaytn main chain. A tiered network architecture with role-based node types is implemented in Klaytn to optimize the network performance.

### Role-based Node Types <a href="#role-based-node-types" id="role-based-node-types"></a>

Before we go over the Klaytn main chain network topology, we need to get familiar with the different types of Klaytn nodes.

#### Core Cell (CC): Consensus Node (CN) + Proxy Node (PN) <a href="#core-cell-cc-consensus-node-cn-proxy-node-pn" id="core-cell-cc-consensus-node-cn-proxy-node-pn"></a>

A Core Cell (CC) is composed of a single **Consensus Node (CN)** and two **Proxy Nodes (PNs)**. Consensus Nodes are participating in the block generation process, while Proxy Nodes provide the interface to the network. PNs transmit the transaction requests to the Consensus Nodes, and propagate the blocks down to the Endpoint Nodes.

> If you are interested in being a Core Cell Operator, read the [installation and operation guide of Core Cell](/content/installation-guide/deployment/core-cell/installation-guide/before-you-install).

#### Endpoint Node (EN) <a href="#endpoint-node-en" id="endpoint-node-en"></a>

ENs serve as endpoints for Klaytn network handling RPC API requests and processing data sent to and from service chains.

> To set up an Endpoint Node for your application, read the [installation and operation guide of Endpoint Node](/content/installation-guide/deployment/endpoint-node).

#### Bootnode <a href="#bootnode" id="bootnode"></a>

Bootnodes are special-type nodes operated by Klaytn to help newly joining nodes register to the network and to discover other nodes to connect with. CN bootnodes reside within the CNN and are not exposed to the public, while PN and EN bootnodes are publicly visible. PN bootnodes only allow permitted PNs to be registered, and let eligible PNs connect with ENs. EN bootnodes provide ENs with information on which PNs to connect to.

### Tiered Networks <a href="#tiered-networks" id="tiered-networks"></a>

CNs, PNs, and ENs form logical networks, Consensus Node Network (CNN), Proxy Node Network (PNN), and Endpoint Node Network (ENN), respectively.

Below figure shows the overall topology of Klaytn mainnet, where Core Cell Network (CCN) is further broken down into Consensus Node Network (CNN) and Proxy Node Network (PNN). Endpoint Node Network (ENN) is also shown as the surrounding network connected directly to PNN.

![Klaytn Main Chain Physical Topology and Tiered Architecture (CNN, PNN, and ENN)](/files/tPzIS0LEdGqJzaoLY4x9)

#### Consensus Node Network (CNN) <a href="#consensus-node-network-cnn" id="consensus-node-network-cnn"></a>

CNs form a full-mesh network among themselves called CNN. CNN applies BFT over a WAN (wide area network) and requires each CN to satisfy [stringent hardware and network resource requirements](/content/installation-guide/deployment/core-cell/system-requirements) to carry out BFT consensus at a sufficient performance level.

#### Proxy Node Network (PNN) <a href="#proxy-node-network-pnn" id="proxy-node-network-pnn"></a>

PNN consists of PNs. Typically, PNs maintain just one connection with a PN in a neighboring Core Cell. The number of peer connections is subject to change depending on the network configuration.

#### Endpoint Node Network (ENN) <a href="#endpoint-node-network-enn" id="endpoint-node-network-enn"></a>

The outermost subnetwork, ENN, is solely composed of ENs connected to each other and also to a number of PNs.

## Block Generation and Propagation <a href="#block-generation-and-propagation" id="block-generation-and-propagation"></a>

Block generation and propagation design, along with the consensus algorithm used, plays an important role in reducing the latency of a blockchain platform.

### Block Generation Cycle <a href="#block-generation-cycle" id="block-generation-cycle"></a>

A 'round' is a block generation cycle in Klaytn. Each round generates a new block, and is immediately followed by the start of a new round. Klaytn targets each round to be approximately one second, although block generation interval may be influenced by network traffic and node operation conditions.

#### Proposer and Committee Selection <a href="#proposer-and-committee-selection" id="proposer-and-committee-selection"></a>

In each round, Klaytn randomly but deterministically selects a Consensus Node (CN) as the proposer for the block to be created, and then selects a group of CNs as the committee for the given round. Klaytn is not directly involved in the selection of either the proposer or committee; instead, each CN uses a random number derived from the most recent block header to run a cryptographic operation which yields proof that the CN has (or has not) been selected for this round. The committee size should be Byzantine resistant; if the size of the CNN is small, all CNs (except the proposer) are eligible to be selected as committee members.

#### Block Proposal and Validation <a href="#block-proposal-and-validation" id="block-proposal-and-validation"></a>

Once selected, the proposer broadcasts its proof of selection for the round (i.e., a cryptographic proof verifiable by the public key of the proposer) to all CNs. Thereafter, the CNs selected as committee for the given round responds to the proposer with their own proofs of selection, notifying the proposer to whom to broadcast the new block to be proposed. The proposer then selects a set of transactions from its transaction pool and creates a block by ordering them. Lastly, the proposer executes consensus with the committee to agree upon and finalize the newly created block. Note that Klaytn plans to continuously improve its consensus algorithm to achieve higher security and efficiency.

### Block Propagation <a href="#block-propagation" id="block-propagation"></a>

A proposed block must receive signatures from more than two-thirds of the committee members to be successfully finalized. When the committee reaches consensus, the new block is propagated to all CNs and the consensus round ends. Once the new block is propagated to all CNs, the information of the newly created block can be made available to all Klaytn network participants by delivering block header and body data to ENN through PNN.

## Public Disclosure and Open Validation <a href="#public-disclosure-and-open-validation" id="public-disclosure-and-open-validation"></a>

Service providers and end-users on Klaytn network can freely validate block generation results and check if the CN committee have generated the block according to proper procedures. Such validation includes checking if the block header contains more than two-thirds of the committee signatures. All CNs must support open validation and are required to post their public keys (used to sign blocks) in a publicly accessible space (e.g., block headers). Open validation promotes transparency, deter censorship, and prevent malicious behaviors.

## Separated Propagation Channels for Blocks and Transactions (Multichannel Propagation) <a href="#separated-propagation-channels-for-blocks-and-transactions-multichannel-propagat" id="separated-propagation-channels-for-blocks-and-transactions-multichannel-propagat"></a>

A network's latency is heavily affected by its degree of congestion. Assuming the network's throughput remains constant, increased number of transactions will cause the network's latency to be proportionately delayed. Latency delay is a critical issue in dApps; typical users of legacy mobile apps or web services will not tolerate response time that takes more than a few seconds, and blockchain services have no reason to assume a higher user tolerance.

Klaytn adopts a multichannel approach in order to handle network congestion issues. By assigning separate propagation channels for transactions and blocks, Klaytn network is able to propagate newly created blocks in a timely manner even when the network faces heavy congestion with high number of transactions. In this way, Klaytn ensures that dApps on its network can stay responsive to end-user requests regardless of intermittent network traffic spikes.

## Block Rewards <a href="#block-rewards" id="block-rewards"></a>

For each round, block reward (which is the sum of 6.4 newly minted KLAY and transaction fees paid to process the block) will be distributed to the network participants according to preset distribution ratios. The proposer of the newly created block will receive 100% of the reward to be awarded to CNs, whereas the committee will receive none. Note that the probability of being selected as the proposer is influenced by the amount of KLAY staked by the CN, implying that a CN with more KLAY invested in the platform will probabilistically receive more rewards. Details of block reward distribution can be found in the [Klaytn Token Economy](/content/klaytn/design/token-economy) section.


# Why Klaytn

This document explains how Klaytn is different based on its the key design principles.

## Klaytn as a trust layer of metaverse <a href="#klaytn-as-a-trust-layer-of-metaverse" id="klaytn-as-a-trust-layer-of-metaverse"></a>

​ Klaytn is built to be the fundamental trust layer for the metaverse, respecting the participation and contribution from all communities, empowering and bringing them together in the new world. ​ The foremost design principle is; ​

{% hint style="success" %}
Helping the pioneers to easily build the applications and organize the community in scalable way.
{% endhint %}

​ As per this principle, Klaytn has been designed to meet the following requirements: ​

### High Performance <a href="#high-performance" id="high-performance"></a>

#### Throughput(TPS) and Finality <a href="#throughput-and-finality" id="throughput-and-finality"></a>

* Main chain should handle at least 4,000 TPS.
* Main chain should guarantee immediate transaction finality with one-second block generation time.
* See [Consensus Mechanism](/content/klaytn/design/consensus-mechanism). ​

#### Scalability <a href="#scalability" id="scalability"></a>

* Service chain is the default L2 solution for Klaytn 2.0 that is customizable and easily deployable. The service chain can have its own governance and connect to the Klaytn main chain to anchor data or transfer assets.
* See [Service Chain](/content/klaytn/scaling-solutions#service-chain). Enterprises or large networks often want to have their own dedicated execution environment. With the service chain, they can maintain an isolated high-performing execution environment that is not affected by other blockchain applications.
* Other scalability solutions will be available in the near future, such as sharding or rollups. ​

### Low Cost <a href="#low-cost" id="low-cost"></a>

* End-users should not be burdened with any higher transaction fee beyond what the traditional systems require.
* Transaction fee should be stable and be determined by the transaction complexity itself, and not the surrounding factors.
* See [Affordable Smart Contract Execution Cost](/content/klaytn/design/computation/klaytn-smart-contract#affordable-smart-contract-execution-cost) and [Transaction Fees](/content/klaytn/design/transaction-fees). For a gas price of 250 ston, a KLAY transfer would incur a fixed cost of 0.00525 KLAY. (21,000 Gas for KLAY transfer x (250 x 10^-9) == 0.00525 KLAY) ​

### Rapid Development <a href="#rapid-development" id="rapid-development"></a>

#### Ethereum Compatibility <a href="#ethereum-compatibility" id="ethereum-compatibility"></a>

* Development Tools: Any tooling that can run on Ethereum will run seamlessly within the Klaytn ecosystem by making Klaytn’s technical stack equivalent, from an interfacing and execution perspective, to the existing Ethereum stack. New tooling created in the Klaytn ecosystem could be reciprocally adopted within the Ethereum ecosystem.
* EVM and API: By building on top of existing Ethereum stacks we inherit any improvements made to the open-source codebases of EVM and supporting libraries. Supporting such equivalent Opcodes and stack logic in the Klaytn EVM environment would see execution behaviour is guaranteed equivalent; and supporting a set of JSON-RPC APIs with equivalent endpoint payload syntax guarantees full Ethereum interfacing equivalence. See [Solidity-Smart Contract Language](/content/smart-contract/solidity-smart-contract-language), and [Migrating Ethereum App to Klaytn](/content/dapp/tutorials/migrating-ethereum-app-to-klaytn).
* Core Development Contribution: Supporting Ethereum equivalence translates most to the mutual benefit to both the Klaytn and Ethereum ecosystems. The majority of Ethereum Improvement Proposals (EIPs) could be migrated and adopted to the Klaytn core development agenda, and in turn Klaytn Improvement Proposals (KIPs) could contribute to the advancement of Ethereum and EVM. When the development community contributes to one ecosystem, they are indeed contributing to both. ​

#### Open Source Infrastructure and Package <a href="#open-source-infrastructure-and-package" id="open-source-infrastructure-and-package"></a>

* Primary Infrastructure: tool sets for end-to-end blockchain integration and building. It includes SDKs and smart contract libraries, Wallets and chain explorers, distributed storage solutions, Oracle support and Bridges.
* Secondary Infrastructure: ecosystem for supporting products and services. It includes Integration/abstraction services, Stablecoin integrations, DAOs, NFT Marketplaces, DEX and DeFi and Traditional finance interfaces. ​

### Enhanced User Experience <a href="#enhanced-user-experience" id="enhanced-user-experience"></a>

#### Usability in Transaction <a href="#usability-in-transaction" id="usability-in-transaction"></a>

* Ability to transfer user's transaction fee to the application
* See [Fee Delegation](/content/klaytn/design/transactions#fee-delegation). Application operator can adjust the amount of subsidy for each transaction and implement more flexible business models such as freemium or subscription. Fee delegation will effectively lower user acquisition barriers. ​ ​

### A Full-suite, Protocol-level Eco Fund <a href="#contribution-reward" id="contribution-reward"></a>

* Klaytn is the first and the largest example in which the incentives supporting the ecosystem are encoded in an on-chain protocol tokenomics. 50% of the newly minted tokens are reinvested in the ecosystem.
* See [Klaytn Community Fund](/content/klaytn/design/token-economy#klaytn-community-fund) and [Klaytn Foundation Fund](/content/klaytn/design/token-economy#klaytn-foundation-fund). ​ ​

### Community Co-Building <a href="#community-co-building" id="community-co-building"></a>

* In addition to the protocol design, Klaytn will expand its territory through community co-building; it includes kinds of communities such as game guilds, investment DAOs, community DAOs, alliance with global players, etc. ​ Lastly, the ground rules: ​

{% hint style="success" %}
Klaytn does not sacrifice blockchain’s core characteristics to achieve the above-mentioned enhancements, and the protocol stays stable with strongly committed stakeholders.
{% endhint %}

### Transparency, Security and Decentralization <a href="#transparency-security-and-decentralization" id="transparency-security-and-decentralization"></a>

* Anyone can request transactions as well as retrieve and confirm transactions results on the blockchain.
* Klaytn is a decentralized network where no single malicious node can break the data integrity. ​

### Governance by DAOs, Builders and Enterprises Realizes Decentralization with Stability <a href="#governance-by-trusted-entities" id="governance-by-trusted-entities"></a>

* In addition to the current traditional enterprises as Klaytn Governance Council (GC), by bringing more decentralized entities such as DAOs and builders into the GC, we are opening up the potential to rebuild the entire Klaytn governance structure in an unprecedented way with hundreds of governance participants.


# Klaytn Design


# Consensus Mechanism

A consensus mechanism (algorithm) is a way of reaching a consensus between trustless entities. In blockchain technology, it is used to reach a consensus about if a block is valid or not. The performance of blockchain networks relies on the performance of the adopted consensus mechanisms, and it has a significant impact on the perceived usability of the Blockchain Applications.

Klaytn Mainnet Cypress exhibits the following performance.

* Handles 4,000 transactions per second.
* Immediate transaction finality.
* One-second block generation time.
* Over 50 consensus nodes can participate in the consensus process.

In the document, we will go over how Klaytn implemented the high-performing consensus process.

## Background <a href="#background" id="background"></a>

[Bitcoin](https://en.wikipedia.org/wiki/Bitcoin) is using [PoW](https://en.wikipedia.org/wiki/Proof_of_work) (Proof-of-Work), whereas Ethereum has recently shifted to [PoS](https://en.wikipedia.org/wiki/Proof_of_stake) (Proof-of-Stake), which decides on the block generating nodes by the stake of the node. Usually, these algorithms involve no communication between nodes in determining the validities of blocks.

So in these systems, a fork can happen which means two or more different blocks can be made on the same height. Usually, the "Longest chain wins" rule is applied to solve the fork condition. It means that those forks will be merged into a single canonical chain eventually, but it also means a list of blocks can be reverted in some period of time when it belongs to the shorter chain. So in these algorithms, there is no guarantee of the finality of blocks and transactions. The finality can only be achieved probabilistically after a period of time, which is still can't be 100% guaranteed.

This lack of finality is a very difficult issue in customer-facing services that use blockchain platforms. Because it has to wait until forks are resolved and enough blocks are stacked after the transfer to believe the transaction is not reversible. This has a negative effect both on users and service providers.

A simple example of this issue can be demonstrated in financial services. Say a user transferred money to someone, and the service can't verify that the transfer is valid until 30 to 60 minutes have passed. Because it has to wait until the forks have been merged into a single chain and several blocks are stacked after the transfer to be sure that the transaction is not reversible.

### PBFT (Practical Byzantine Fault Tolerance) <a href="#pbft-practical-byzantine-fault-tolerance" id="pbft-practical-byzantine-fault-tolerance"></a>

To prevent the above issues, we need other algorithms that guarantee the finality. BFT algorithm is one of those, first [published](https://dl.acm.org/citation.cfm?doid=357172.357176) in 1982 by Lamport, Shostak, Pease. In 1999, Miguel Castro and Barbara Liskov introduced "Practical Byzantine Fault Tolerance" ([PBFT](http://www.pmg.csail.mit.edu/papers/bft-tocs.pdf)) which provides high-performance state machine replication.

In the PoW algorithm stated above, though each node receives and validates blocks, there are no message exchanges between nodes to reach a consensus. But in PBFT, each node communicates with other participating nodes to reach a consensus and the finality of the block can be guaranteed as soon as nodes were able to reach a consensus.

The communication between nodes basically progresses as shown below. But there are some variants which reflect each system's characteristics.

![PBFT message flow](/files/tt2OiuA0b2N5tkwqnKvQ)

As shown above, a participating node in PBFT basically communicates with all nodes in the network in several phases. This characteristic limits the number of nodes because the communication volume increases exponentially as the number of nodes increases.

## Consensus Mechanism in Klaytn <a href="#consensus-mechanism-in-klaytn" id="consensus-mechanism-in-klaytn"></a>

Klaytn is aiming to be an Enterprise-ready and Service-centric platform. Therefore we need to solve the finality problem written above and the network should be able to allow many nodes to participate in the network. To make this possible, Klaytn is using an optimized version of Istanbul BFT, which implements PBFT with modifications to deal with blockchain network's characteristics.

In Klaytn, there are three types of nodes, CN (Consensus Node), PN (Proxy Node) and EN (Endpoint Node). CNs are managed by CCOs (Core Cell Operators) and are in charge of block generation. These blocks are verified by all nodes in the network. Please refer to [here](/content/klaytn#klaytn-network-topology) to know more about this network topology.

![Network topology](/files/tPzIS0LEdGqJzaoLY4x9)

Klaytn achieves fast finality by adopting and improving Istanbul BFT. Because validation and consensus are done for each block there is no fork and the block's finality is guaranteed instantly as soon as the consensus is made.

And also the issue of increasing communication volume in the BFT algorithm is solved by utilizing randomly selected `Committee`. CNs collectively form a `Council` and on each block generation, part of them are selected as a member of `Committee` using a VRF (Verifiable Random Function).

![Concept of council and committee](/files/8zvyJbGeOkiiAz2c87jy)

Because consensus messages are exchanged only between the committee members, the communication volume can be limited under the designed level even though the total number of CNs increases.

Currently, Klaytn Mainnet Cypress can provide a high throughput of 4,000 transactions per second with one-second block generation interval. More than 50 consensus nodes can participate in the CNN (Consensus Node Network) at the moment and the number will continuously increase as Klaytn continues to aggressively optimize the algorithm.


# Accounts

## Klaytn Accounts <a href="#klaytn-accounts" id="klaytn-accounts"></a>

### Overview of Account, State, and Address <a href="#overview-of-account-state-and-address" id="overview-of-account-state-and-address"></a>

An account in Klaytn is a data structure containing information about a person's balance or a smart contract. Klaytn's state is the collection of all its accounts' states - that is, the past and current state of all data stored across Klaytn's accounts. When a transaction is executed on a Klaytn node, the state of Klaytn consequently changes across all its nodes. The state should be the same across all nodes in the Klaytn network if they have processed the same blocks in the same order. State information of each account is associated with a 20-byte address, which is used to identify each account.

### Decoupling Key Pairs From Addresses <a href="#decoupling-key-pairs-from-addresses" id="decoupling-key-pairs-from-addresses"></a>

An account in a typical blockchain platform is associated with a cryptographically processed address of a certain length that usually looks like this: "0x0fe2e20716753082222b52e753854f40afddffd2". This address is strongly coupled with a key pair. If a key pair is chosen, the address is derived from the public key. This has many disadvantages in terms of user experience. Some of them are the following:

* It is impossible for users to have addresses they want.
* It is impossible for users to use multiple key pairs to increase security of their accounts.
* It is impossible for users to change the account's key pair when the private key is accidentally exposed or when users want to update the private key periodically to increase the account's security.

Those are big hurdles that users cannot think of an address as an identifier in the blockchain platform. To clear this hurdle, Klaytn provides a feature that users can choose their addresses and key pairs. With this feature, users can choose addresses that they want and they can use multiple key pairs to increase security. The number of key pairs can be one or more, and the key pairs can have different roles. For details of multiple key pairs or role-based keys, please refer to [Multiple Key Pairs & Role-Based Keys](#multiple-key-pairs-and-role-based-keys).

It is worth noting that Klaytn also supports the old scheme that a key pair and an address are strongly coupled.

### Multiple Key Pairs and Role-Based Keys <a href="#multiple-key-pairs-and-role-based-keys" id="multiple-key-pairs-and-role-based-keys"></a>

As described before, when the private key is stolen, exposed, or somehow compromised, there is nothing to do to restore the account’s security: the best option is to generate another key pair to create a new account, and migrate the balance from the old compromised account to the new one. Lack of support for advanced key schemes such as multi-sig or usage-specific key is yet another source of major inconvenience. To address those problems more efficiently, Klaytn accounts provide the following capabilities:

* Klaytn account allows the key pair associated with the account to be changed.
* Klaytn account supports multiple key pairs, along with the ability to assign each key with different purpose.
* Klaytn account maintains compatibility with accounts having a single key that is strongly coupled with the address.

By utilizing Klaytn account’s role-based multi-key support, end-users can better handle real-life security risk situations such as private key mismanagement. For example, when a user realizes that his or her private key has been exposed, the user can simply replace the compromised private key by removing the exposed key pair from his or her account and creating a new key pair to replace them. This could be achieved by using a dedicated key used for updating account information, created in advance and stored separately from the compromised private key.

### Human-Readable Address (HRA) <a href="#human-readable-address-hra" id="human-readable-address-hra"></a>

Although the address scheme (e.g., "0x0fe2e20716753082222b52e753854f40afddffd2") has its own strengths in that it efficiently protects the privacy of account holders, it also proposes major problems in terms of end-user experience. First, it is very difficult for a human brain to memorize, or even recognize, such addresses, making them prone to input mistakes and various human errors that often lead to non-trivial financial damages. Second, such scheme takes away from end-users the power to choose one’s own preferred identity handle that’s easier to memorize or use. Combined, these problems are among the toughest usability hurdles that cause dApp user experience for typical end-users (who are more accustomed to the simpler, frictionless user experience offered by legacy mobile apps or services) to be perceived as alien, incomprehensible, and severely inconvenient. To overcome such challenges without undergoing architectural modifications at large-scale and while preserving backward compatibility, Klaytn opts to provide a mapping between a 20-byte address to a 20-byte length text string that end-users could assign their own preferred values to. This feature in Klaytn is called human-readable address (HRA). Currently, this feature is under development, and we will provide more information when it is ready.

### Klaytn Wallet Key Format <a href="#klaytn-wallet-key-format" id="klaytn-wallet-key-format"></a>

Klaytn wallet key format is provided to easily handle a private key along with the corresponding address. It makes easier for a user to maintain his/her private key with an address. The format is `0x{private key}0x{type}0x{address in hex}` in hexadecimal notation, where `{type}` must be `00`. Other values are reserved. An example is shown below:

```
0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d80x000xa94f5374fce5edbc8e2a8697c15331677e6ebf0b
```

This format is currently supported in [Klaytn Wallet](/content/dapp/developer-tools/getting-started/klaytn-wallet).

### Klaytn Account Types <a href="#klaytn-account-types" id="klaytn-account-types"></a>

There are two types of accounts in Klaytn: externally owned accounts (EOAs), and smart contract accounts (SCAs).

#### Externally Owned Accounts (EOAs) <a href="#externally-owned-accounts-eoas" id="externally-owned-accounts-eoas"></a>

Externally owned accounts have information such as nonce and balance. This type of accounts does not have code or storage. EOAs are controlled by private keys and do not have code associated with them. An EOA can be created using key pairs and subsequently controlled by anyone with the key pairs. The account key is described in the section [Account Key](#account-key).

**Attributes**

| Attribute     | Type                       | Description                                                                                                                                                                                                                                                                                                                                    |
| ------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type          | uint8 (Go)                 | The type of externally owned accounts. It must be **0x1** for EOAs.                                                                                                                                                                                                                                                                            |
| nonce         | uint64 (Go)                | A sequence number used to determine the order of transactions. The transaction to be processed next has the same nonce with this value.                                                                                                                                                                                                        |
| balance       | \*big.Int (Go)             | The amount of KLAY the account has.                                                                                                                                                                                                                                                                                                            |
| humanReadable | bool (Go)                  | A boolean value indicating that the account is associated with a human-readable address. Since [HRA](#human-readable-address-hra) is under development, this value is false for all accounts.                                                                                                                                                  |
| key           | [AccountKey](#account-key) | The key associated with this account. This field can be any of [AccountKeyLegacy](#accountkeylegacy), [AccountKeyPublic](#accountkeypublic), [AccountKeyFail](#accountkeyfail), [AccountKeyWeightedMultisig](#accountkeyweightedmultisig), [AccountKeyRoleBased](#accountkeyrolebased). Signatures in transactions are verified with this key. |

#### Smart Contract Accounts (SCAs) <a href="#smart-contract-accounts-scas" id="smart-contract-accounts-scas"></a>

In contrast to EOAs, SCAs have code associated with them and are controlled by their code. SCAs are created by smart contract deployment transactions; once deployed, an SCA cannot initiate new transactions by itself and must be triggered by another account, either by an EOA or another SCA.

**Attributes**

| Attribute     | Type                       | Description                                                                                                                                                                                                                                                                                                                                    |
| ------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type          | uint8 (Go)                 | The type of smart contract accounts. It must be **0x2** for SCAs.                                                                                                                                                                                                                                                                              |
| nonce         | uint64 (Go)                | A sequence number used to determine the order of transactions. The transaction to be processed next has the same nonce with this value.                                                                                                                                                                                                        |
| balance       | \*big.Int (Go)             | The amount of KLAY the account has.                                                                                                                                                                                                                                                                                                            |
| humanReadable | bool (Go)                  | A boolean value indicating that the account is associated with a human-readable address. Since [HRA](#human-readable-address-hra) is under development, this value is false for all accounts.                                                                                                                                                  |
| key           | [AccountKey](#account-key) | The key associated with this account. This field can be any of [AccountKeyLegacy](#accountkeylegacy), [AccountKeyPublic](#accountkeypublic), [AccountKeyFail](#accountkeyfail), [AccountKeyWeightedMultisig](#accountkeyweightedmultisig), [AccountKeyRoleBased](#accountkeyrolebased). Signatures in transactions are verified with this key. |
| codeHash      | \[]byte (Go)               | The hash of the account's smart contract code. This value is immutable, which means it is set only when the smart contract is created.                                                                                                                                                                                                         |
| storageRoot   | \[32]byte (Go)             | A 256-bit hash of the root of the Merkle Patricia Trie that contains the values of all the storage variables in the account.                                                                                                                                                                                                                   |
| codeFormat    | uint8 (Go)                 | Supporting interpreter version. Up to 16 can be set. Currently, it supports EVM(0x00) only.                                                                                                                                                                                                                                                    |
| vmVersion     | uint8 (Go)                 | The protocol upgrade (hard fork) information at contract deployment time (ex. 0x0(constantinople), 0x1(istanbul,london,...)). Up to 16 can be used. It is automatically created with the contract.                                                                                                                                             |

{% hint style="success" %}
NOTE: From klaytn v1.7.0 onwards, vmVersion attribute will be added to the Smart Contract Account.
{% endhint %}

### Klaytn Account Type ID <a href="#klaytn-account-type-id" id="klaytn-account-type-id"></a>

Below are the Account Type ID assigned to each Account Type.

| Account Type                   | Account Type ID |
| ------------------------------ | --------------- |
| Externally Owned Account (EOA) | 0x1             |
| Smart Contract Account (SCA)   | 0x2             |

## Account Key <a href="#account-key" id="account-key"></a>

An account key represents the key structure associated with an account.

### AccountKeyNil <a href="#accountkeynil" id="accountkeynil"></a>

AccountKeyNil represents an empty key. If an account tries to have an AccountKeyNil object, the transaction will be failed. AccountKeyNil is used only for TxTypeAccountUpdate transactions with role-based keys. For example, if an account tries to update RoleAccountUpdate key only, the key field of the TxTypeAccountUpdate transaction would be:

`[AccountKeyNil, NewKey, AccountKeyNil]`

Then, only the RoleAccountUpdate key is updated. Other roles are not updated. Refer to the [AccountKeyRoleBased](#accountkeyrolebased) for more detail.

#### Attributes <a href="#attributes" id="attributes"></a>

No attributes for AccountKeyNil.

#### RLP Encoding <a href="#rlp-encoding" id="rlp-encoding"></a>

`0x80`

### AccountKeyLegacy <a href="#accountkeylegacy" id="accountkeylegacy"></a>

AccountKeyLegacy is used for the account having an address derived from the corresponding key pair. If an account has AccountKeyLegacy, the transaction validation process is done like below (as typical Blockchain platforms did):

* Get the public key from `ecrecover(txhash, txsig)`.
* Get the address of the public key.
* The address is the sender.

#### Attributes <a href="#attributes" id="attributes"></a>

| Attribute | Type       | Description                                          |
| --------- | ---------- | ---------------------------------------------------- |
| Type      | uint8 (Go) | The type of AccountKeyLegacy. This must be **0x01**. |

#### RLP Encoding <a href="#rlp-encoding" id="rlp-encoding"></a>

`0x01c0`

### AccountKeyPublic <a href="#accountkeypublic" id="accountkeypublic"></a>

AccountKeyPublic is used for accounts having one public key.\
If an account has an AccountKeyPublic object, the transaction validation process is done like below:

* Get the public key derived from `ecrecover(txhash, txsig)`.
* Check that the derived public key is the same as the corresponding

  account's public key.

#### Attributes <a href="#attributes" id="attributes"></a>

| Attribute | Type           | Description                                          |
| --------- | -------------- | ---------------------------------------------------- |
| Type      | uint8 (Go)     | The type of AccountKeyPublic. This must be **0x02**. |
| Key       | \[33]byte (Go) | Key should be a compressed public key on S256 curve. |

#### RLP Encoding <a href="#rlp-encoding" id="rlp-encoding"></a>

`0x02 + encode(CompressedPubKey)`

**NOTE**: CompressedPubKey is a public key in a compressed format defined in [SEC1](https://www.secg.org/SEC1-Ver-1.0.pdf). In short, 0x02{PubkeyX} if PubkeyY is an even number or 0x03{PubkeyX} otherwise.

#### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

```javascript
prvkey 0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b
pubkeyX 0xdbac81e8486d68eac4e6ef9db617f7fbd79a04a3b323c982a09cdfc61f0ae0e8
pubkeyY 0x906d7170ba349c86879fb8006134cbf57bda9db9214a90b607b6b4ab57fc026e

RLP: 0x02a102dbac81e8486d68eac4e6ef9db617f7fbd79a04a3b323c982a09cdfc61f0ae0e8
```

### AccountKeyFail <a href="#accountkeyfail" id="accountkeyfail"></a>

If an account has the key AccountKeyFail, the transaction validation process always fails. It can be used for smart contract accounts so that a transaction sent from the smart contract account always fails.

#### Attributes <a href="#attributes" id="attributes"></a>

| Attribute | Type       | Description                                       |
| --------- | ---------- | ------------------------------------------------- |
| Type      | uint8 (Go) | The type of AcccountKeyFail. It must be **0x03**. |

#### RLP Encoding <a href="#rlp-encoding" id="rlp-encoding"></a>

`0x03c0`

### AccountKeyWeightedMultiSig <a href="#accountkeyweightedmultisig" id="accountkeyweightedmultisig"></a>

AccountKeyWeightedMultiSig is an account key type containing a threshold and WeightedPublicKeys which contains a list consisting of a public key and its weight. In order for a transaction to be valid for an account associated with AccountKeyWeightedMultiSig, the following conditions should be satisfied:

* The weighted sum of the signed public keys should be larger than the threshold.
* The invalid signature should not be included in the transaction.
* The number of signed public keys should be less than the number of weightedPublicKeys.

{% hint style="success" %}
NOTE: The following multiSig validation logic has changed with the `IstanbulEVM` protocol upgrade, or the "hard fork".

* The invalid signature should not be included in the transaction.
* The number of signed public keys should be less than the number of weightedPublicKeys. If you want the previous document, please refer to [previous document](/content/klaytn/design/transaction-fees/transaction-fees-previous).

`IstanbulEVM` protocol upgrade block number is as follows.

* Baobab Testnet: `#75373312`
* Cypress Mainnet: `#86816005`
  {% endhint %}

#### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                      | Description                                                                                                                    |
| ------------------ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Type               | uint8 (Go)                | The type of AccountKeyWeightedMultiSig. This must be **0x04**.                                                                 |
| Threshold          | uint (Go)                 | Validation threshold. To be a valid transaction, the weight sum of signatures should be larger than or equal to the threshold. |
| WeightedPublicKeys | \[]{uint, \[33]byte} (Go) | A list of weighted public keys. A weighted public key contains a compressed public key and its weight.                         |

#### RLP Encoding <a href="#rlp-encoding" id="rlp-encoding"></a>

`0x04 + encode([threshold, [[weight, CompressedPubKey1], [weight2, CompressedPubKey2]]])`

#### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

```javascript
Threshold 3
Key0 Weight: 1
PubkeyX 0xc734b50ddb229be5e929fc4aa8080ae8240a802d23d3290e5e6156ce029b110e
PubkeyY 0x61a443ac3ffff164d1fb3617875f07641014cf17af6b7dc38e429fe838763712
Key1 Weight: 1
PubkeyX 0x12d45f1cc56fbd6cd8fc877ab63b5092ac77db907a8a42c41dad3e98d7c64dfb
PubkeyY 0x8ef355a8d524eb444eba507f236309ce08370debaa136cb91b2f445774bff842
Key2 Weight: 1
PubkeyX 0xea9a9f85065a00d7b9ffd3a8532a574035984587fd08107d8f4cbad6b786b0cd
PubkeyY 0xb95ebb02d9397b4a8faceb58d485d612f0379a923ec0ddcf083378460a56acca
Key3 Weight: 1
PubkeyX 0x8551bc489d62fa2e6f767ba87fe93a62b679fca8ff3114eb5805e6487b51e8f6
PubkeyY 0x4206aa84bc8955fcbfcc396854228aa63ebacd81b7311a31ab9d71d90b7ec3d7

RLP: 0x04f89303f890e301a102c734b50ddb229be5e929fc4aa8080ae8240a802d23d3290e5e6156ce029b110ee301a10212d45f1cc56fbd6cd8fc877ab63b5092ac77db907a8a42c41dad3e98d7c64dfbe301a102ea9a9f85065a00d7b9ffd3a8532a574035984587fd08107d8f4cbad6b786b0cde301a1038551bc489d62fa2e6f767ba87fe93a62b679fca8ff3114eb5805e6487b51e8f6
```

### AccountKeyRoleBased <a href="#accountkeyrolebased" id="accountkeyrolebased"></a>

AccountKeyRoleBased represents a role-based key. The roles are specified at [Roles](#roles).

#### Attributes <a href="#attributes" id="attributes"></a>

| Attribute | Type                 | Description                                                                                                                            |
| --------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Type      | uint8 (Go)           | The type of AccountKeyRoleBased. It must be **0x05**.                                                                                  |
| Keys      | \[]{AccountKey} (Go) | A list of keys. A key can be any of AccountKeyNil, AccountKeyLegacy, AccountKeyPublic, AccountKeyFail, and AccountKeyWeightedMultiSig. |

#### Roles <a href="#roles" id="roles"></a>

Roles of AccountKeyRoleBased are defined as below:

| Role              | Description                                                                                                                                                                                                                       |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| RoleTransaction   | Index 0. Default key. Transactions other than TxTypeAccountUpdate should be signed by the key of this role.                                                                                                                       |
| RoleAccountUpdate | Index 1. TxTypeAccountUpdate transaction should be signed by this key. If this key is not present in the account, TxTypeAccountUpdate transaction is validated using RoleTransaction key.                                         |
| RoleFeePayer      | Index 2. If this account wants to send tx fee instead of the sender, the transaction should be signed by this key. If this key is not present in the account, a fee-delegated transaction is validated using RoleTransaction key. |

#### RLP Encoding <a href="#rlp-encoding" id="rlp-encoding"></a>

`0x05 + encode([key1, key2, key3])`

Note that key1, key2, and key3 can be any of above keys (AccountKeyNil, AccountKeyLegacy, AccountKeyPublic, AccountKeyFail, and AccountKeyWeightedMultiSig).

#### Omissible and Expandable Roles <a href="#omissible-and-expandable-roles" id="omissible-and-expandable-roles"></a>

The roles can be omitted from the last index, and the omitted roles are mapped to the first role. However, a role in the middle cannot be omitted, which means RoleTransaction and RoleFeePayer cannot be set without RoleAccountUpdate. For example, if a role-based key is set to `0x05 + encode([key1, key2])`, RoleFeePayer works as if the key is set like `0x05 + encode([key1, key2, key1])`.

This feature allows for more roles to be added in the future. If a new role is provided, the new role of accounts already created with old roles is mapped to the first role.

#### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

```javascript
RoleTransaction Key
PubkeyX 0xe4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512d
PubkeyY 0x0a5735a23ce1654b14680054a993441eae7c261983a56f8e0da61280758b5919
RoleAccountUpdate Key
Threshold: 2
Key0 Weight:1
PubkeyX 0xe4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512d
PubkeyY 0x0a5735a23ce1654b14680054a993441eae7c261983a56f8e0da61280758b5919
Key1 Weight:1
PubkeyX 0x36f6355f5b532c3c1606f18fa2be7a16ae200c5159c8031dd25bfa389a4c9c06
PubkeyY 0x6fdf9fc87a16ac359e66d9761445d5ccbb417fb7757a3f5209d713824596a50d
RoleFeePayer Key
PubkeyX 0xc8785266510368d9372badd4c7f4a94b692e82ba74e0b5e26b34558b0f081447
PubkeyY 0x94c27901465af0a703859ab47f8ae17e54aaba453b7cde5a6a9e4a32d45d72b2

RLP: 0x05f898a302a103e4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512db84e04f84b02f848e301a103e4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512de301a10336f6355f5b532c3c1606f18fa2be7a16ae200c5159c8031dd25bfa389a4c9c06a302a102c8785266510368d9372badd4c7f4a94b692e82ba74e0b5e26b34558b0f081447
```

## Account Key Type ID <a href="#account-key-type-id" id="account-key-type-id"></a>

Below are the Account Key Type ID assigned to each Account Key Type.

| Account Key Type           | Account Key Type ID |
| -------------------------- | ------------------- |
| AccountKeyLegacy           | 0x01                |
| AccountKeyPublic           | 0x02                |
| AccountKeyFail             | 0x03                |
| AccountKeyWeightedMultiSig | 0x04                |
| AccountKeyRoleBased        | 0x05                |


# Transactions

## Transactions Overview <a href="#transactions-overview" id="transactions-overview"></a>

A transaction in a blockchain platform is a message sent between nodes that changes the state of the blockchain. For example, when a transaction that sends 10 KLAY from Alice’s account to Bob’s is executed, Alice's balance decreases by 10 KLAY, and Bob's balance increases by 10 KLAY. Note that a transaction cannot be interleaved with another transaction because a transaction is an atomic operation. A typical blockchain transaction has components as shown below:

| Components | Description                                                                                                                                                                                                                                                                                                                                    |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| value      | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                 |
| to         | The account address that will receive the transferred value.                                                                                                                                                                                                                                                                                   |
| input      | Data attached to the transaction, used for transaction execution.                                                                                                                                                                                                                                                                              |
| v, r, s    | The cryptographic signature generated by the sender to let the receiver obtain the sender's address.                                                                                                                                                                                                                                           |
| nonce      | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                             |
| gas        | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                                                       |
| gasPrice   | A multiplier to get how much the sender will pay in tokens. The amount of tokens the sender will pay is calculated via `gas` \* `gasPrice`. For example, the sender will pay 10 KLAY for a transaction fee if gas is 10 and gasPrice is 10^18. Unit of KLAY is described [here](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |

## Klaytn Transactions <a href="#klaytn-transactions" id="klaytn-transactions"></a>

While typical Blockchain platforms provide a single transaction type, Klaytn provides multiple transaction types that empower transactions with new capabilities and optimizations for memory footprint and performance.

### Signature Validation of Transactions <a href="#signature-validation-of-transactions" id="signature-validation-of-transactions"></a>

In typical blockchain platforms, the address is derived from the public key which is derived again from the transaction signature. This is possible only if the address and the key pair are strongly coupled.

Since a key pair is decoupled from the address in Klaytn, the sender address cannot be derived using the transaction signature. This is why Klaytn transaction types except TxTypeLegacyTransaction have the field `from`. In Klaytn, to validate a transaction, the [AccountKey](/content/klaytn/design/accounts#account-key) of `from` is obtained, and the obtained key is used to validate the transaction signature.

### Fee Delegation <a href="#fee-delegation" id="fee-delegation"></a>

To provide businesses with the necessary flexibility in their business model design, Klaytn provides a number of fee-delegated versions for its basic transaction types. These variants enable service providers to subsidize their end-user activities by paying for their transaction fees instead. Transaction fee subsidization can be further detailed by using transactions with the Ratio parameter, letting service providers designate the percentage of fees they would cover. Fee-delegation transactions require at least two signatures: one from the sender, and another from the fee payer.

### SenderTxHash <a href="#sendertxhash" id="sendertxhash"></a>

SenderTxHash is a hash of a transaction without the fee payer's address and signature. The transaction hash of a fee-delegated transaction is not determined yet until the fee payer signs the transaction. To track a fee-delegated transaction, the sender should get the transaction hash derived from the complete transaction containing the signatures from both the sender and the fee payer. Since it is very hard for the sender to get the transaction hash, Klaytn provides a SenderTxHash as well as the transaction hash. To find the complete fee-delegated transaction in the Klaytn network, the sender generates the SenderTxHash and requests a transaction object via [klay\_getTransactionBySenderTxHash](https://github.com/klaytn/klaytn-docs/blob/main/docs/bapp/json-rpc/api-references/klay/transaction.md#klay_gettransactionbysendertxhash). How to get the SenderTxHash depends on each transaction type, which is described in the description of each transaction type.

Each transaction type is described in detail:

|                        | Basic                                                                                                  | Fee Delegation                                                                                                                          | Partial Fee Delegation                                                                                                                                            |
| ---------------------- | ------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Legacy                 | [TxTypeLegacyTransaction](/content/klaytn/design/transactions/basic#txtypelegacytransaction)           | N/A                                                                                                                                     | N/A                                                                                                                                                               |
| ValueTransfer          | [TxTypeValueTransfer](/content/klaytn/design/transactions/basic#txtypevaluetransfer)                   | [TxTypeFeeDelegatedValueTransfer](/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfer)                   | [TxTypeFeeDelegatedValueTransferWithRatio](/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedvaluetransferwithratio)                   |
| ValueTransferMemo      | [TxTypeValueTransferMemo](/content/klaytn/design/transactions/basic#txtypevaluetransfermemo)           | [TxTypeFeeDelegatedValueTransferMemo](/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfermemo)           | [TxTypeFeeDelegatedValueTransferMemoWithRatio](/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedvaluetransfermemowithratio)           |
| SmartContractDeploy    | [TxTypeSmartContractDeploy](/content/klaytn/design/transactions/basic#txtypesmartcontractdeploy)       | [TxTypeFeeDelegatedSmartContractDeploy](/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedsmartcontractdeploy)       | [TxTypeFeeDelegatedSmartContractDeployWithRatio](/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedsmartcontractdeploywithratio)       |
| SmartContractExecution | [TxTypeSmartContractExecution](/content/klaytn/design/transactions/basic#txtypesmartcontractexecution) | [TxTypeFeeDelegatedSmartContractExecution](/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedsmartcontractexecution) | [TxTypeFeeDelegatedSmartContractExecutionWithRatio](/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedsmartcontractexecutionwithratio) |
| AccountUpdate          | [TxTypeAccountUpdate](/content/klaytn/design/transactions/basic#txtypeaccountupdate)                   | [TxTypeFeeDelegatedAccountUpdate](/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedaccountupdate)                   | [TxTypeFeeDelegatedAccountUpdateWithRatio](/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedaccountupdatewithratio)                   |
| Cancel                 | [TxTypeCancel](/content/klaytn/design/transactions/basic#txtypecancel)                                 | [TxTypeFeeDelegatedCancel](/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedcancel)                                 | [TxTypeFeeDelegatedCancelWithRatio](/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedcancelwithratio)                                 |
| ChainDataAnchoring     | [TxTypeChainDataAnchoring](/content/klaytn/design/transactions/basic#txtypechaindataanchoring)         | [TxTypeFeeDelegatedChainDataAnchoring](/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedchaindataanchoring)         | [TxTypeFeeDelegatedChainDataAnchoringWithRatio](/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedchaindataanchoringwithratio)         |


# Basic

## TxTypeLegacyTransaction <a href="#txtypelegacytransaction" id="txtypelegacytransaction"></a>

TxTypeLegacyTransaction represents a type of transactions existed previously in Klaytn. Since this transaction type exists to support compatibility, it only works with EOAs associated with [AccountKeyLegacy](/content/klaytn/design/accounts#accountkeylegacy). EOAs associated with other account key types should use other transaction types such as TxTypeValueTransfer, TxTypeSmartContractExecution, and so on. This type of transaction can create an account, transfer tokens, deploy a smart contract, execute a smart contract, or perform a mix of aforementioned. This transaction type will initiate the following changes.

1. The sender's balance decreases by the amount of the transaction fee.
2. The sender's nonce increases by one.
3. If `to` does not exist on Klaytn, an EOA associated with [AccountKeyLegacy](/content/klaytn/design/accounts#accountkeylegacy) is created.
4. `value` KLAY is transferred from the sender to the recipient.
5. If `to` is nil, it is regarded as a smart contract deployment transaction. The smart contract code must be passed as `input`.
6. If `to` is a smart contract, the smart contract function specified in `input` is executed.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute | Type                  | Description                                                                                                                                                                                                                                                                                                                      |
| --------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| value     | \*big.Int (Go)        | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                   |
| to        | \*common.Address (Go) | The account address that will receive the transferred value.                                                                                                                                                                                                                                                                     |
| input     | \[]byte (Go)          | Data attached to the transaction, used for transaction execution.                                                                                                                                                                                                                                                                |
| v, r, s   | \*big.Int (Go)        | The cryptographic signature generated by the sender to let the receiver obtain the sender's address.                                                                                                                                                                                                                             |
| nonce     | uint64 (Go)           | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                               |
| gas       | uint64 (Go)           | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                                         |
| gasPrice  | \*big.Int (Go)        | A multiplier to get how much the sender will pay in tokens. The amount of tokens the sender will pay is calculated via `gas` \* `gasPrice`. For example, the sender will pay 10 KLAY for a transaction fee if gas is 10 and gasPrice is 10^18. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |

### RLP Encoding for Signature <a href="#rlp-encoding-for-signature" id="rlp-encoding-for-signature"></a>

To make a signature of this transaction type, RLP serialization should be done like the following:

```javascript
SigRLP = encode([nonce, gasPrice, gas, to, value, input, chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
SenderTxHashRLP = encode([nonce, gasPrice, gas, to, value, input, v, r, s])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
TxHashRLP = encode([nonce, gasPrice, gas, to, value, input, v, r, s])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xe68204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a8431323334018080
SigHash 0x40e73366650cddb7affcf5af39efa864b2c68c42b5329044fc86a12b26c4edc7
Signature f845f84325a0b2a5a15550ec298dc7dddde3774429ed75f864c82caeb5ee24399649ad731be9a029da1014d16f2011b3307f7bbe1035b6e699a4204fc416c763def6cefd976567
TxHashRLP 0xf8668204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a843132333425a0b2a5a15550ec298dc7dddde3774429ed75f864c82caeb5ee24399649ad731be9a029da1014d16f2011b3307f7bbe1035b6e699a4204fc416c763def6cefd976567
TxHash e434257753bf31a130c839fec0bd34fc6ea4aa256b825288ee82db31c2ed7524
SenderTxHashRLP 0xf8668204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a843132333425a0b2a5a15550ec298dc7dddde3774429ed75f864c82caeb5ee24399649ad731be9a029da1014d16f2011b3307f7bbe1035b6e699a4204fc416c763def6cefd976567
SenderTxHash e434257753bf31a130c839fec0bd34fc6ea4aa256b825288ee82db31c2ed7524

    TX(e434257753bf31a130c839fec0bd34fc6ea4aa256b825288ee82db31c2ed7524)
    Contract: false
    From:     a94f5374fce5edbc8e2a8697c15331677e6ebf0b
    To:       7b65b75d204abed71587c9e519a89277766ee1d0
    Nonce:    1234
    GasPrice: 0x19
    GasLimit  0xf4240
    Value:    0xa
    Data:     0x31323334
    V:        0x25
    R:        0xb2a5a15550ec298dc7dddde3774429ed75f864c82caeb5ee24399649ad731be9
    S:        0x29da1014d16f2011b3307f7bbe1035b6e699a4204fc416c763def6cefd976567
    Hex:      f8668204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a843132333425a0b2a5a15550ec298dc7dddde3774429ed75f864c82caeb5ee24399649ad731be9a029da1014d16f2011b3307f7bbe1035b6e699a4204fc416c763def6cefd976567
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0xeff95d8c57d668aa274a0eaeff942ecc2cfca4c71f71ae9fdaba92735cd79b9e",
  "blockNumber": "0x1",
  "contractAddress": null,
  "from": "0x33c97827c33d8c5e07eb263ed6ec5c229e8b4752",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0x5208",
  "input": "0x",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x0",
  "senderTxHash": "0xff0e9a45aa8741d528baf84069cd3b52c43a51bf7cf69d896672c3c909507888",
  "signatures": [
    {
      "V": "0x25",
      "R": "0xed8aa552324101a99792860d479cd488b7f67af0b9205968748bddcda52da6de",
      "S": "0x524dbf481ea1d77c20f4d4354cc208c3149ddfa06f7ab53a03ad82d2d7fed3"
    }
  ],
  "status": "0x1",
  "to": "0xd03227635c90c7986f0e3a4e551cefbca8c55316",
  "transactionHash": "0xff0e9a45aa8741d528baf84069cd3b52c43a51bf7cf69d896672c3c909507888",
  "transactionIndex": "0x0",
  "type": "TxTypeLegacyTransaction",
  "typeInt": 0,
  "value": "0x174876e800"
}
```

## TxTypeValueTransfer <a href="#txtypevaluetransfer" id="txtypevaluetransfer"></a>

TxTypeValueTransfer is used when a user wants to send KLAY. As Klaytn provides multiple transaction types to make each transaction type serve a single purpose, TxTypeValueTransfer is limited to send KLAY to an externally owned account. Therefore, TxTypeValueTransfer is accepted only if `to` is an externally owned account. To transfer KLAY to a smart contract account, use [TxTypeSmartContractExecution](#txtypesmartcontractexecution) instead. The following changes will be made by this transaction type.

1. The sender's balance decreases by the amount of the transaction fee.
2. The sender's nonce increases by one.
3. `value` KLAY is transferred from the sender to the recipient.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute    | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type         | uint8 (Go)                                | The type of TxTypeValueTransfer. This must be 0x08.                                                                                                                                                                                                                                                                                                |
| nonce        | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice     | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas          | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |
| to           | common.Address (Go)                       | The account address that will receive the transferred value.                                                                                                                                                                                                                                                                                       |
| value        | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |
| from         | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| txSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |

### RLP Encoding for Signature <a href="#rlp-encoding-for-signature" id="rlp-encoding-for-signature"></a>

To make a transaction signature, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, txSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization with the given parameters and the information of the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf839b5f4088204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b018080
SigHash 0xaa7665566c9508140bb91e36a948fc8f61c4518400a69562432d17e064f3ce43
Signature f845f84325a0f3d0cd43661cabf53425535817c5058c27781f478cb5459874feaa462ed3a29aa06748abe186269ff10b8100a4b7d7fea274b53ea2905acbf498dc8b5ab1bf4fbc
TxHashRLP 0x08f87a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a0f3d0cd43661cabf53425535817c5058c27781f478cb5459874feaa462ed3a29aa06748abe186269ff10b8100a4b7d7fea274b53ea2905acbf498dc8b5ab1bf4fbc
TxHash 762f130342569e9669a4d8547f1248bd2554fbbf3062d63a97ce28bfa97aa9d7
SenderTxHashRLP 0x08f87a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a0f3d0cd43661cabf53425535817c5058c27781f478cb5459874feaa462ed3a29aa06748abe186269ff10b8100a4b7d7fea274b53ea2905acbf498dc8b5ab1bf4fbc
SenderTxHash 762f130342569e9669a4d8547f1248bd2554fbbf3062d63a97ce28bfa97aa9d7

    TX(762f130342569e9669a4d8547f1248bd2554fbbf3062d63a97ce28bfa97aa9d7)
    Type:          TxTypeValueTransfer
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Signature:     [{"V":"0x25","R":"0xf3d0cd43661cabf53425535817c5058c27781f478cb5459874feaa462ed3a29a","S":"0x6748abe186269ff10b8100a4b7d7fea274b53ea2905acbf498dc8b5ab1bf4fbc"}]
    Hex:           08f87a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a0f3d0cd43661cabf53425535817c5058c27781f478cb5459874feaa462ed3a29aa06748abe186269ff10b8100a4b7d7fea274b53ea2905acbf498dc8b5ab1bf4fbc
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0xeff95d8c57d668aa274a0eaeff942ecc2cfca4c71f71ae9fdaba92735cd79b9e",
  "blockNumber": "0x1",
  "contractAddress": null,
  "from": "0x33c97827c33d8c5e07eb263ed6ec5c229e8b4752",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0x5208",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x1",
  "senderTxHash": "0x8c18c9a609d2b22c921ce0b282e64924bf073e84f7c3850d99ec71da4054f79d",
  "signatures": [
    {
      "V": "0x25",
      "R": "0x94e059980bce9f3ba5f09e5021ad4f32d7d9cfda938c2d38c989cd4a406e7ba",
      "S": "0x3ca52ee9d23954a278e6a30f3ec40951b26fb8b3f784c236c5bb1d5c9a8b2c82"
    }
  ],
  "status": "0x1",
  "to": "0x75c3098be5e4b63fbac05838daaee378dd48098d",
  "transactionHash": "0x8c18c9a609d2b22c921ce0b282e64924bf073e84f7c3850d99ec71da4054f79d",
  "transactionIndex": "0x1",
  "type": "TxTypeValueTransfer",
  "typeInt": 8,
  "value": "0x21e19e0c9bab2400000"
}
```

## TxTypeValueTransferMemo <a href="#txtypevaluetransfermemo" id="txtypevaluetransfermemo"></a>

TxTypeValueTransferMemo is used when a user wants to send KLAY with a specific message. TxTypeValueTransferMemo is accepted only if `to` is an externally owned account. To transfer KLAY to a smart contract account, use [TxTypeSmartContractExecution](#txtypesmartcontractexecution) instead. The following changes will be made by this transaction type.

1. The sender's balance decreases by the amount of the transaction fee.
2. The sender's nonce increases by one.
3. `value` KLAY is transferred from the sender to the recipient.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute    | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type         | uint8 (Go)                                | The type of TxTypeValueTransferMemo. This must be 0x10.                                                                                                                                                                                                                                                                                            |
| nonce        | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice     | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas          | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |
| to           | common.Address (Go)                       | The account address that will receive the transferred value.                                                                                                                                                                                                                                                                                       |
| value        | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |
| from         | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| input        | \[]byte (Go)                              | Data attached to the transaction. The message should be passed to this attribute.                                                                                                                                                                                                                                                                  |
| txSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |

### RLP Encoding for Signature <a href="#rlp-encoding-for-signature" id="rlp-encoding-for-signature"></a>

To make a transaction signature, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf841b83cf83a108204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6f018080
SigHash 0x23dd6ca2c023a152cad636ac8ed0a1a7962d3eb4cb7f3c50e34c0cc42e37d48a
Signature f845f84325a07d2b0c89ee8afa502b3186413983bfe9a31c5776f4f820210cffe44a7d568d1ca02b1cbd587c73b0f54969f6b76ef2fd95cea0c1bb79256a75df9da696278509f3
TxHashRLP 0x10f8808204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6ff845f84325a07d2b0c89ee8afa502b3186413983bfe9a31c5776f4f820210cffe44a7d568d1ca02b1cbd587c73b0f54969f6b76ef2fd95cea0c1bb79256a75df9da696278509f3
TxHash 6c7ee543c24e5b928b638a9f4502c1eca69103f5467ed4b6a2ed0ea5aede2e6b
SenderTxHashRLP 0x10f8808204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6ff845f84325a07d2b0c89ee8afa502b3186413983bfe9a31c5776f4f820210cffe44a7d568d1ca02b1cbd587c73b0f54969f6b76ef2fd95cea0c1bb79256a75df9da696278509f3
SenderTxHash 6c7ee543c24e5b928b638a9f4502c1eca69103f5467ed4b6a2ed0ea5aede2e6b

    TX(6c7ee543c24e5b928b638a9f4502c1eca69103f5467ed4b6a2ed0ea5aede2e6b)
    Type:          TxTypeValueTransferMemo
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Signature:     [{"V":"0x25","R":"0x7d2b0c89ee8afa502b3186413983bfe9a31c5776f4f820210cffe44a7d568d1c","S":"0x2b1cbd587c73b0f54969f6b76ef2fd95cea0c1bb79256a75df9da696278509f3"}]
    Data:          36383635366336633666
    Hex:           10f8808204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6ff845f84325a07d2b0c89ee8afa502b3186413983bfe9a31c5776f4f820210cffe44a7d568d1ca02b1cbd587c73b0f54969f6b76ef2fd95cea0c1bb79256a75df9da696278509f3
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x7ad6ed1f9955be00db8fb5452125f0e9a3c0856abb5b4cc4aed91ffc134321da",
  "blockNumber": "0x1",
  "contractAddress": null,
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0x53fc",
  "input": "0x68656c6c6f",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x4",
  "senderTxHash": "0x7311ef305064f2a6997c16cc8b5fc3fdf301549e7b7d0baa3a995a8e79479e5e",
  "signatures": [
    {
      "V": "0x25",
      "R": "0xd63673e1be7919e7ca42de64931c853fc568557b151e9b335df94b22de3a600f",
      "S": "0x57bc916a50856b4d197f6856f16370f72f3bb0ac411b1da793fdb5bb7066966f"
    }
  ],
  "status": "0x1",
  "to": "0x75c3098be5e4b63fbac05838daaee378dd48098d",
  "transactionHash": "0x7311ef305064f2a6997c16cc8b5fc3fdf301549e7b7d0baa3a995a8e79479e5e",
  "transactionIndex": "0x4",
  "type": "TxTypeValueTransferMemo",
  "typeInt": 16,
  "value": "0x989680"
}
```

## TxTypeSmartContractDeploy <a href="#txtypesmartcontractdeploy" id="txtypesmartcontractdeploy"></a>

TxTypeSmartContractDeploy deploys a smart contract to the given address. The following changes will be made by this transaction type.

1. The sender's balance decreases by the amount of the transaction fee.
2. The sender's nonce increases by one.
3. A smart contract is deployed with the code in `input`. The deployed address will be returned via `contractAddress` in the receipt.
4. `value` KLAY is transferred from the sender to the recipient.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute     | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type          | uint8 (Go)                                | The type of TxTypeSmartContractDeploy. This must be 0x28.                                                                                                                                                                                                                                                                                          |
| nonce         | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice      | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas           | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |
| to            | \*common.Address (Go)                     | The account address that will receive the transferred value. Currently, this value must be nil. Specifying the address will be supported in the future.                                                                                                                                                                                            |
| value         | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |
| from          | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| input         | \[]byte (Go)                              | Data attached to the transaction, used for transaction execution.                                                                                                                                                                                                                                                                                  |
| humanReadable | bool (Go)                                 | This must be false since human-readable address is not supported yet. If true, the transaction will be rejected.                                                                                                                                                                                                                                   |
| codeFormat    | uint8 (Go)                                | The code format of smart contract code. The supported value for now is EVM(0x00) only.                                                                                                                                                                                                                                                             |
| txSignatures  | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |

### RLP Encoding for Signature <a href="#rlp-encoding-for-signature" id="rlp-encoding-for-signature"></a>

To make a signature of this transaction type, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction signature of the fee payer, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat, txSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf90240b9023af90237288204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f00290180018080
SigHash 0xa921fa892d5dec0837bd32c1fb77fc3b2df57ec0b0c4eea79192c79883ed543c
Signature f845f84325a0fcd107738fb47750ba727610aefd6d5f51ac8163d62ce500e7ab7e15defe7088a0383d68220d0266490ea4173c1d7847f22fcbe22f8c8125e1c0589189845c902a
TxHashRLP 0x28f9027d8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f00290180f845f84325a0fcd107738fb47750ba727610aefd6d5f51ac8163d62ce500e7ab7e15defe7088a0383d68220d0266490ea4173c1d7847f22fcbe22f8c8125e1c0589189845c902a
TxHash e983f38b814891990f3ca57028c2230dc7e907eb313c827e7c99fadcc9b4c58b
SenderTxHashRLP 0x28f9027d8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f00290180f845f84325a0fcd107738fb47750ba727610aefd6d5f51ac8163d62ce500e7ab7e15defe7088a0383d68220d0266490ea4173c1d7847f22fcbe22f8c8125e1c0589189845c902a
SenderTxHash e983f38b814891990f3ca57028c2230dc7e907eb313c827e7c99fadcc9b4c58b

    TX(e983f38b814891990f3ca57028c2230dc7e907eb313c827e7c99fadcc9b4c58b)
    Type:          TxTypeSmartContractDeploy
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Signature:     [{"V":"0x25","R":"0xfcd107738fb47750ba727610aefd6d5f51ac8163d62ce500e7ab7e15defe7088","S":"0x383d68220d0266490ea4173c1d7847f22fcbe22f8c8125e1c0589189845c902a"}]
    Data:          363038303630343035323334383031353631303031303537363030303830666435623530363130316465383036313030323036303030333936303030663330303630383036303430353236303034333631303631303036313537363366666666666666663763303130303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303630303033353034313636333161333964386566383131343631303038303537383036333633353335383662313436313030613735373830363337306130383233313134363130306361353738303633666436623765663831343631303066383537356233333630303039303831353236303031363032303532363034303831323038303534333439303831303139303931353538313534303139303535303035623334383031353631303038633537363030303830666435623530363130303935363130313064353635623630343038303531393138323532353139303831393030333630323030313930663335623631303063383733666666666666666666666666666666666666666666666666666666666666666666666666666666663630303433353136363130313133353635623030356233343830313536313030643635373630303038306664356235303631303039353733666666666666666666666666666666666666666666666666666666666666666666666666666666663630303433353136363130313437353635623334383031353631303130343537363030303830666435623530363130306338363130313539353635623630303035343831353635623733666666666666666666666666666666666666666666666666666666666666666666666666666666663136363030303930383135323630303136303230353236303430383132303830353433343930383130313930393135353831353430313930353535363562363030313630323035323630303039303831353236303430393032303534383135363562333336303030393038313532363030313630323035323630343038313230383035343930383239303535393038313131313536313031616635373630343035313333393038323135363130386663303239303833393036303030383138313831383538383838663139333530353035303530313536313031396335373631303161663536356233333630303039303831353236303031363032303532363034303930323038313930353535623530353630306131363536323761376137323330353832303632376361343662623039343738613031353736323830366363303063343331323330353031313138633763323663333061633538633465303965353163346630303239
    HumanReadable: true
    CodeFormat:    CodeFormatEVM
    Hex:           28f9027d8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f00290180f845f84325a0fcd107738fb47750ba727610aefd6d5f51ac8163d62ce500e7ab7e15defe7088a0383d68220d0266490ea4173c1d7847f22fcbe22f8c8125e1c0589189845c902a
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "codeFormat": "0x0",
  "contractAddress": "0x636f6e74726163742e6b6c6179746e0000000000",
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x0",
  "gasUsed": "0xee6e343d",
  "humanReadable": true,
  "input": "0x608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0xa",
  "senderTxHash": "0x78a5633ee5b453ed2f00937e65945a3b76e96623634e1555e2f15d44930168af",
  "signatures": [
    {
      "V": "0x25",
      "R": "0x369d892dc24786111fd8f0308e8a6518708727257e95b3281865508faa0a768b",
      "S": "0x12fc22c390a89484d1cb70e1f19c4fa8a203b1406044ee9c263264876f0dd724"
    }
  ],
  "status": "0x1",
  "to": "0x636f6e74726163742e6b6c6179746e0000000000",
  "transactionHash": "0x78a5633ee5b453ed2f00937e65945a3b76e96623634e1555e2f15d44930168af",
  "transactionIndex": "0x3",
  "type": "TxTypeSmartContractDeploy",
  "typeInt": 40,
  "value": "0x0"
}
```

## TxTypeSmartContractExecution <a href="#txtypesmartcontractexecution" id="txtypesmartcontractexecution"></a>

TxTypeSmartContractExecution executes a smart contract with the given data in `input`. TxTypeSmartContractExecution is accepted only if `to` is a smart contract account. To transfer KLAY to an externally owned account, use [TxTypeValueTransfer](#txtypevaluetransfer) instead. The following changes will be made by this transaction type.

1. If `to` is a smart contract account, the code is executed based on `input`. Otherwise, this transaction will be rejected.
2. The sender's balance decreases by the amount of the transaction fee.
3. The sender's nonce increases by one.
4. If `value` was provided, `value` KLAY is transferred from the sender to the `to` smart contract. The contract should have a payable fallback function to receive KLAY.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute    | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type         | uint8 (Go)                                | The type of TxTypeSmartContractExecution. This must be 0x30.                                                                                                                                                                                                                                                                                       |
| nonce        | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice     | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas          | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |
| to           | common.Address (Go)                       | The address of the smart contract account to be executed.                                                                                                                                                                                                                                                                                          |
| value        | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |
| from         | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| input        | \[]byte (Go)                              | Data attached to the transaction, used for transaction execution.                                                                                                                                                                                                                                                                                  |
| txSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |

### RLP Encoding for Signature <a href="#rlp-encoding-for-signature" id="rlp-encoding-for-signature"></a>

To make a signature of this transaction type, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf860b85bf859308204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b2018080
SigHash 0x197ea7d262f74489934d6cbcf8baa3bec169c16ad672fef4a9f8148864c9cdce
Signature f845f84326a0e4276df1a779274fbb04bc18a0184809eec1ce9770527cebb3d64f926dc1810ba04103b828a0671a48d64fe1a3879eae229699f05a684d9c5fd939015dcdd9709b
TxHashRLP 0x30f89f8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b2f845f84326a0e4276df1a779274fbb04bc18a0184809eec1ce9770527cebb3d64f926dc1810ba04103b828a0671a48d64fe1a3879eae229699f05a684d9c5fd939015dcdd9709b
TxHash 23bb192bd58d56527843eb63225c5213f3aded95e4c9776f1ff0bdd8ee0b6826
SenderTxHashRLP 0x30f89f8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b2f845f84326a0e4276df1a779274fbb04bc18a0184809eec1ce9770527cebb3d64f926dc1810ba04103b828a0671a48d64fe1a3879eae229699f05a684d9c5fd939015dcdd9709b
SenderTxHash 23bb192bd58d56527843eb63225c5213f3aded95e4c9776f1ff0bdd8ee0b6826

    TX(23bb192bd58d56527843eb63225c5213f3aded95e4c9776f1ff0bdd8ee0b6826)
    Type:          TxTypeSmartContractExecution
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Signature:     [{"V":"0x26","R":"0xe4276df1a779274fbb04bc18a0184809eec1ce9770527cebb3d64f926dc1810b","S":"0x4103b828a0671a48d64fe1a3879eae229699f05a684d9c5fd939015dcdd9709b"}]
    Data:          363335333538366230303030303030303030303030303030303030303030303062633539353166303535613835663431613362363266643666363861623764653736643239396232
    Hex:           30f89f8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b2f845f84326a0e4276df1a779274fbb04bc18a0184809eec1ce9770527cebb3d64f926dc1810ba04103b828a0671a48d64fe1a3879eae229699f05a684d9c5fd939015dcdd9709b
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "contractAddress": null,
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0xfedc",
  "input": "0x6353586b0000000000000000000000000fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0xd",
  "senderTxHash": "0xe216873dedd72d8d67a9f5e51eb5a7ed2b5f34bca334adff7a3601d6d3e2e132",
  "signatures": [
    {
      "V": "0x26",
      "R": "0x68fe3dfd1ff3ea14427f157b5837cb6eb0b00fd0497e1c80897de1935200f0",
      "S": "0x6b84fbedcb4ff785120890596fad3f797c178cda8908f3b02ee0a4442fbf4189"
    }
  ],
  "status": "0x1",
  "to": "0x636f6e74726163742e6b6c6179746e0000000000",
  "transactionHash": "0xe216873dedd72d8d67a9f5e51eb5a7ed2b5f34bca334adff7a3601d6d3e2e132",
  "transactionIndex": "0x6",
  "type": "TxTypeSmartContractExecution",
  "typeInt": 48,
  "value": "0xa"
}
```

## TxTypeAccountUpdate <a href="#txtypeaccountupdate" id="txtypeaccountupdate"></a>

TxTypeAccountUpdate updates the key of the given account. The following changes will apply by this transaction type.

1. The sender's balance decreases by the amount of the transaction fee.
2. The sender's nonce increases by one.
3. The account's key is updated with `key`.
4. Once this type of transaction is executed, transactions sent from the account afterward will be validated with the new `key`.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute    | Type                                      | Description                                                                                                                                                                                                                                                                                                                      |
| ------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type         | uint8 (Go)                                | The type of TxTypeAccountUpdate. This must be 0x20.                                                                                                                                                                                                                                                                              |
| nonce        | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                               |
| gasPrice     | \*big.Int (Go)                            | A multiplier to get how much the sender will pay in tokens. The amount of tokens the sender will pay is calculated via `gas` \* `gasPrice`. For example, the sender will pay 10 KLAY for a transaction fee if gas is 10 and gasPrice is 10^18. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas          | uint64 (Go)                               | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                                         |
| from         | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                               |
| key          | AccountKey (Go)                           | [AccountKey](/content/klaytn/design/accounts#account-key) to be updated to the account.                                                                                                                                                                                                                                          |
| txSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                 |

### RLP Encoding for Signature <a href="#rlp-encoding-for-signature" id="rlp-encoding-for-signature"></a>

To make a signature of this transaction type, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, from, rlpEncodedKey]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, rlpEncodedKey, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, from, rlpEncodedKey, txSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf849b844f842208204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d018080
SigHash 0xa0d3f1d2b4f061c3a5d9c22c7bb621aa821162b42b4db6cf1888defc2473e0ab
Signature f845f84325a0f7d479628f05f51320f0842193e3f7ae55a5b49d3645bf55c35bee1e8fd2593aa04de8eab5338fdc86e96f8c49ed516550f793fc2c4007614ce3d2a6b33cf9e451
TxHashRLP 0x20f8888204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33df845f84325a0f7d479628f05f51320f0842193e3f7ae55a5b49d3645bf55c35bee1e8fd2593aa04de8eab5338fdc86e96f8c49ed516550f793fc2c4007614ce3d2a6b33cf9e451
TxHash 8c70627d6b637c7d033ead083fc5e43e5cad10c704a86dd9bda7ac104a0e5ad0
SenderTxHashRLP 0x20f8888204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33df845f84325a0f7d479628f05f51320f0842193e3f7ae55a5b49d3645bf55c35bee1e8fd2593aa04de8eab5338fdc86e96f8c49ed516550f793fc2c4007614ce3d2a6b33cf9e451
SenderTxHash 8c70627d6b637c7d033ead083fc5e43e5cad10c704a86dd9bda7ac104a0e5ad0

    TX(8c70627d6b637c7d033ead083fc5e43e5cad10c704a86dd9bda7ac104a0e5ad0)
    Type:          TxTypeAccountUpdate
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Key:           AccountKeyPublic: S256Pubkey:{"x":"0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d","y":"0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3"}
    Signature:     [{"V":"0x25","R":"0xf7d479628f05f51320f0842193e3f7ae55a5b49d3645bf55c35bee1e8fd2593a","S":"0x4de8eab5338fdc86e96f8c49ed516550f793fc2c4007614ce3d2a6b33cf9e451"}]
    Hex:           20f8888204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33df845f84325a0f7d479628f05f51320f0842193e3f7ae55a5b49d3645bf55c35bee1e8fd2593aa04de8eab5338fdc86e96f8c49ed516550f793fc2c4007614ce3d2a6b33cf9e451
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "contractAddress": null,
  "from": "0x636f6c696e2e6b6c6179746e0000000000000000",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0xa028",
  "key": "0x02a1034ef27ba4b7d1ae09b166744c5b7ee4a7a0cc5c76b2e5d74523a0a4fb56db3191",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x0",
  "senderTxHash": "0x3f154903f92a179007b45b807af2d971ada9a23657e80bf5c18a75ac6516fd0b",
  "signatures": [
    {
      "V": "0x25",
      "R": "0x757827ec43eafdc150ecb35423699ceaea41b13dd07f8620e2231a7b0e278149",
      "S": "0x59d43ed3e0ed0f9d69d0c08ccca29913a8b138c000029f878f61337220a1ca1b"
    }
  ],
  "status": "0x1",
  "transactionHash": "0x3f154903f92a179007b45b807af2d971ada9a23657e80bf5c18a75ac6516fd0b",
  "transactionIndex": "0x0",
  "type": "TxTypeAccountUpdate",
  "typeInt": 32
}
```

## TxTypeCancel <a href="#txtypecancel" id="txtypecancel"></a>

TxTypeCancel cancels the execution of the transaction with the same nonce in the transaction pool. This transaction type is useful when a submitted transaction seems unprocessed for a certain amount of time. There are several cases that a transaction seems unprocessed: 1. The transaction was lost somewhere and did not reach any of the consensus nodes. 2. The transaction has not been processed yet in any of the consensus nodes. 3. The transaction was processed, but the block containing the transaction has not been received.

From the client side, it is very hard to figure out the exact reason because to figure out the reason, it is required to look inside all the consensus nodes. However, connecting to any of the consensus nodes from the public is prohibited. Under this situation, in typical blockchain platforms, the user often submits another transaction with a higher gas price to replace the old transaction. However, because the gas price is fixed in Klaytn, replacing the old transaction with a higher gas price is not applicable.

If the transaction remains unprocessed, the other transactions with higher nonce cannot be processed because the nonce determines the execution order of transactions.

To solve this problem, Klaytn provides a transaction type TxTypeCancel. If a user encountered such a situation, a transaction of TxTypeCancel can be submitted.

Each of the above situations is handled as follows: 1. If the old transaction was lost, this TxTypeCancel transaction is executed and included in a block. 2. If the old transaction has not been processed yet, this TxTypeCancel replaces the old transaction. Then, it is executed and included in a block. 3. if the old transaction was already executed, the nonce has been increased, therefore this TxTypeCancel transaction is discarded due to the lower nonce.

Note that the TxTypeCancel transaction is the only transaction that is capable of replacing a transaction with the same nonce. Other transaction types cannot replace the transactions with the same nonce.

The following changes can occur by this transaction type. 1. The sender's balance decreases by the amount of the transaction fee. 2. The sender's nonce increases by one.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute    | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type         | uint8 (Go)                                | The type of TxTypeCancel. This must be 0x38.                                                                                                                                                                                                                                                                                                       |
| nonce        | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed. For the `TxTypeCancel` transaction, this value must match the nonce that the target transaction to be canceled was using.                                                                       |
| gasPrice     | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas          | uint64 (Go)                               | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                                                           |
| from         | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| txSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |

Outcome:

1. If there is a transaction with the same nonce, it is replaced with this cancel transaction.
2. If no same nonce, this transaction is just inserted as a normal transaction.
3. The cancel transaction is not replaced with other transaction types.

### RLP Encoding for Signature <a href="#rlp-encoding-for-signature" id="rlp-encoding-for-signature"></a>

To make a transaction signature, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, from]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, from, txSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xe39fde388204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0b018080
SigHash 0xaaac6d71ad921e8a12e92c47d0b0654a20d8d9a4ff70d83f78661ccdf062ce9a
Signature f845f84325a0fb2c3d53d2f6b7bb1deb5a09f80366a5a45429cc1e3956687b075a9dcad20434a05c6187822ee23b1001e9613d29a5d6002f990498d2902904f7f259ab3358216e
TxHashRLP 0x38f8648204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a0fb2c3d53d2f6b7bb1deb5a09f80366a5a45429cc1e3956687b075a9dcad20434a05c6187822ee23b1001e9613d29a5d6002f990498d2902904f7f259ab3358216e
TxHash 10d135d590cb587cc45c1f94f4a0e3b8c24d24a6e4243f09ca395fb4e2450413
SenderTxHashRLP 0x38f8648204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a0fb2c3d53d2f6b7bb1deb5a09f80366a5a45429cc1e3956687b075a9dcad20434a05c6187822ee23b1001e9613d29a5d6002f990498d2902904f7f259ab3358216e
SenderTxHash 10d135d590cb587cc45c1f94f4a0e3b8c24d24a6e4243f09ca395fb4e2450413

    TX(10d135d590cb587cc45c1f94f4a0e3b8c24d24a6e4243f09ca395fb4e2450413)
    Type:          TxTypeCancel
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Signature:     [{"V":"0x25","R":"0xfb2c3d53d2f6b7bb1deb5a09f80366a5a45429cc1e3956687b075a9dcad20434","S":"0x5c6187822ee23b1001e9613d29a5d6002f990498d2902904f7f259ab3358216e"}]
    Hex:           38f8648204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a0fb2c3d53d2f6b7bb1deb5a09f80366a5a45429cc1e3956687b075a9dcad20434a05c6187822ee23b1001e9613d29a5d6002f990498d2902904f7f259ab3358216e
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "contractAddress": null,
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0x5208",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x10",
  "senderTxHash": "0x0370adf89b2463d3d1fd894d6328929c931ef0cc3a8f1481affedd2e9c88d9d6",
  "signatures": [
    {
      "V": "0x26",
      "R": "0xad73f30acfb80090cba8d3f4be4696e65f8eb7c36b85aac06a9bea350d10578f",
      "S": "0x7ec2d6f052d8f916d12db2e0310381201888cb12d3a3696da80cab5195833706"
    }
  ],
  "status": "0x1",
  "transactionHash": "0x0370adf89b2463d3d1fd894d6328929c931ef0cc3a8f1481affedd2e9c88d9d6",
  "transactionIndex": "0x9",
  "type": "TxTypeCancel",
  "typeInt": 56
}
```

## TxTypeChainDataAnchoring <a href="#txtypechaindataanchoring" id="txtypechaindataanchoring"></a>

TxTypeChainDataAnchoringTransaction is a transaction that anchors service chain data to the Klaytn mainchain. Service chains periodically send this type of transaction to the Klaytn mainchain to ensure its security and credibility of data. For more details about the data anchoring, see [Anchoring](https://github.com/klaytn/klaytn-docs/blob/main/docs/node/service-chain/references/anchoring.md). Be mindful that it is not allowed to send this transaction via RPC. Currently, this transaction is executed through private p2p channels for security reasons. This transaction does not change the state of the Klaytn blockchain except the sender's nonce being increased by one.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute    | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type         | uint8 (Go)                                | The type of TxTypeChainDataAnchoringTransaction. This must be 0x48.                                                                                                                                                                                                                                                                                |
| nonce        | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice     | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas          | uint64 (Go)                               | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                                                           |
| from         | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| input        | \[]byte (Go)                              | Data of the service chain.                                                                                                                                                                                                                                                                                                                         |
| txSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |

### RLP Encoding for Signature <a href="#rlp-encoding-for-signature" id="rlp-encoding-for-signature"></a>

To make a signature of this transaction type, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, from, anchoredData]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, anchoredData, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, from, anchoredData, txSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf8cfb8caf8c8488204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8a8f8a6a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000405018080
SigHash 0x07e07c69a12e384c16d94157c99d0a6fbae1d99f5d54501bfdc5937bbee7c792
Signature f845f84325a0e58b9abf9f33a066b998fccaca711553fb4df425c9234bbb3577f9d9775bb124a02c409a6c5d92277c0a812dd0cc553d7fe1d652a807274c3786df3292cd473e09
TxHashRLP 0x48f9010e8204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8a8f8a6a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000405f845f84325a0e58b9abf9f33a066b998fccaca711553fb4df425c9234bbb3577f9d9775bb124a02c409a6c5d92277c0a812dd0cc553d7fe1d652a807274c3786df3292cd473e09
TxHash 4aad85735e777795d24aa3eab51be959d8ebdf9683083d85b66f70b7170f2ea3
SenderTxHashRLP 0x48f9010e8204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8a8f8a6a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000405f845f84325a0e58b9abf9f33a066b998fccaca711553fb4df425c9234bbb3577f9d9775bb124a02c409a6c5d92277c0a812dd0cc553d7fe1d652a807274c3786df3292cd473e09
SenderTxHash 4aad85735e777795d24aa3eab51be959d8ebdf9683083d85b66f70b7170f2ea3

    TX(4aad85735e777795d24aa3eab51be959d8ebdf9683083d85b66f70b7170f2ea3)
    Type:          TxTypeChainDataAnchoring
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Signature:     [{"V":"0x25","R":"0xe58b9abf9f33a066b998fccaca711553fb4df425c9234bbb3577f9d9775bb124","S":"0x2c409a6c5d92277c0a812dd0cc553d7fe1d652a807274c3786df3292cd473e09"}]
    Hex:           48f9010e8204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8a8f8a6a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000405f845f84325a0e58b9abf9f33a066b998fccaca711553fb4df425c9234bbb3577f9d9775bb124a02c409a6c5d92277c0a812dd0cc553d7fe1d652a807274c3786df3292cd473e09
    AnchoredData:  f8a6a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000405
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "contractAddress": null,
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0x93a8",
  "input": "0xf8a6a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000405",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x13",
  "senderTxHash": "0x28b56268d18b116b08b1673caad80212f271d6e36ceef225b44c6d2a1f0413db",
  "signatures": [
    {
      "V": "0x26",
      "R": "0x7049656869a9442d26ed0c2cbf15812dc486580d03f1cc6373104410225e1e7b",
      "S": "0x3c58fd9ae9390e6484e965572821846445983d9b5eb7866aa4113c56a5bf253e"
    }
  ],
  "status": "0x1",
  "transactionHash": "0x28b56268d18b116b08b1673caad80212f271d6e36ceef225b44c6d2a1f0413db",
  "transactionIndex": "0xc",
  "type": "TxTypeChainDataAnchoring",
  "typeInt": 72
}
```


# Fee Delegation

## TxTypeFeeDelegatedValueTransfer <a href="#txtypefeedelegatedvaluetransfer" id="txtypefeedelegatedvaluetransfer"></a>

TxTypeFeeDelegatedValueTransfer is used when a user wants to send KLAY. As Klaytn provides multiple transaction types to make each transaction type serve a single purpose, TxTypeFeeDelegatedValueTransfer is limited to send KLAY to an externally owned account. Therefore, TxTypeFeeDelegatedValueTransfer is accepted only if `to` is an externally owned account. To transfer KLAY to a smart contract account, use [TxTypeFeeDelegatedSmartContractExecution](#txtypefeedelegatedsmartcontractexecution) instead. The following changes will be made by this transaction type.

1. The fee payer's balance decreases by the amount of the transaction fee.
2. The sender's nonce increases by one.
3. `value` KLAY is transferred from the sender to the recipient.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedValueTransfer. This must be 0x09.                                                                                                                                                                                                                                                                                    |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |
| to                 | common.Address (Go)                       | The account address that will receive the transferred value.                                                                                                                                                                                                                                                                                       |
| value              | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([ encode([type, nonce, gasPrice, gas, to, value, from]), feePayer, chainid, 0, 0 ])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, txSignatures, feePayer, feePayerSignatures])`
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf839b5f4098204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b018080
SigHash 0xb86e4cc0955f7c2cda1b36038c9d43a2724fc956c11e09c37625379b7eb2bd21
Signature f845f84325a09f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956a06bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf84eb5f4098204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0x3e7c5f40e826d1d22493be59bf62928dc397de5c972bd9bfa3fe5206c24a5f82
SignatureFeePayer f845f84326a0f45cf8d7f88c08e6b6ec0b3b562f34ca94283e4689021987abb6b0772ddfd80aa0298fe2c5aeabb6a518f4cbb5ff39631a5d88be505d3923374f65fdcf63c2955b
TxHashRLP 0x09f8d68204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a09f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956a06bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0f45cf8d7f88c08e6b6ec0b3b562f34ca94283e4689021987abb6b0772ddfd80aa0298fe2c5aeabb6a518f4cbb5ff39631a5d88be505d3923374f65fdcf63c2955b
TxHash e1e07f9971153499fc8c7bafcdaf7abc20b37aa4c18fb1e53a9bfcc259e3644c
SenderTxHashRLP 0x09f87a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a09f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956a06bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7
SenderTxHash 40f8c94e01e07eb5353f6cd4cd3eabd5893215dd53a50ba4b8ff9a447ac51731

    TX(e1e07f9971153499fc8c7bafcdaf7abc20b37aa4c18fb1e53a9bfcc259e3644c)
    Type:          TxTypeFeeDelegatedValueTransfer
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Signature:     [{"V":"0x25","R":"0x9f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956","S":"0x6bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeePayerSig:   [{"V":"0x26","R":"0xf45cf8d7f88c08e6b6ec0b3b562f34ca94283e4689021987abb6b0772ddfd80a","S":"0x298fe2c5aeabb6a518f4cbb5ff39631a5d88be505d3923374f65fdcf63c2955b"}]
    Hex:           09f8d68204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a09f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956a06bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0f45cf8d7f88c08e6b6ec0b3b562f34ca94283e4689021987abb6b0772ddfd80aa0298fe2c5aeabb6a518f4cbb5ff39631a5d88be505d3923374f65fdcf63c2955b
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x7ad6ed1f9955be00db8fb5452125f0e9a3c0856abb5b4cc4aed91ffc134321da",
  "blockNumber": "0x1",
  "contractAddress": null,
  "feePayer": "0x029fdce0457db02f05c4be9f67b7115cb8ea15ca",
  "feePayerSignatures": [
    {
      "V": "0x26",
      "R": "0x984e9d43c496ef39ef2d496c8e1aee695f871e4f6cfae7f205ddda1589ca5c9e",
      "S": "0x46647d1ce8755cd664f5fb4eba3082dd1a13817488029f3869662986b7b1a5ae"
    }
  ],
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0x7918",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x2",
  "senderTxHash": "0x6a8cf9a2f6d16561303445309d4f210c8be862f0d0c0e6f4998775fef9b4f957",
  "signatures": [
    {
      "V": "0x25",
      "R": "0x368b3324b37831b51711a2eba2a7608438a2bd5956ccecbcdb07d9163ff8bc87",
      "S": "0x7ee2e86ad6f01c867b2ced9d69e614ba22e539726451400fccdd56acbbc7a6f7"
    }
  ],
  "status": "0x1",
  "to": "0x75c3098be5e4b63fbac05838daaee378dd48098d",
  "transactionHash": "0xea4341b5c95fd5a0c3a8a15a4177ab6394725c24f722a9e31f53474a6dcf086a",
  "transactionIndex": "0x2",
  "type": "TxTypeFeeDelegatedValueTransfer",
  "typeInt": 9,
  "value": "0x21e19e0c9bab2400000"
}
```

## TxTypeFeeDelegatedValueTransferMemo <a href="#txtypefeedelegatedvaluetransfermemo" id="txtypefeedelegatedvaluetransfermemo"></a>

TxTypeFeeDelegatedValueTransferMemo is used when a user wants to send KLAY with a specific message. TxTypeFeeDelegatedValueTransferMemo is accepted only if `to` is an externally owned account. To transfer KLAY to a smart contract account, use [TxTypeFeeDelegatedSmartContractExecution](#txtypefeedelegatedsmartcontractexecution) instead. The following changes will be made by this transaction type.

1. The fee payer's balance decreases by the amount of the transaction fee.
2. The sender's nonce increases by one.
3. `value` KLAY is transferred from the sender to the recipient.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Description                               | Type                                                                                                                                                                                                                                                                                                                                               | An example value |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedValueTransferMemo. This must be 0x11.                                                                                                                                                                                                                                                                                |                  |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |                  |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |                  |
| gas                | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |                  |
| to                 | common.Address (Go)                       | The account address that will receive the transferred value.                                                                                                                                                                                                                                                                                       |                  |
| value              | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |                  |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |                  |
| input              | \[]byte (Go)                              | Data attached to the transaction. The message should be passed to this attribute.                                                                                                                                                                                                                                                                  |                  |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |                  |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |                  |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |                  |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf841b83cf83a118204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6f018080
SigHash 0x3333b9336d431ffa53b795fedcf03cc2217cea3f26825ea5cbf7d69f0b99fde9
Signature f845f84326a064e213aef0167fbd853f8f9989ef5d8b912a77457395ccf13d7f37009edd5c5ba05d0c2e55e4d8734fe2516ed56ac628b74c0eb02aa3b6eda51e1e25a1396093e1
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf856b83cf83a118204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6f945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0xed015096fb27764f576415e23576228cbf7c4fdad464ea7ffc3a1856dfe391c9
SignatureFeePayer f845f84326a087390ac14d3c34440b6ddb7b190d3ebde1a07d9a556e5a82ce7e501f24a060f9a037badbcb12cda1ed67b12b1831683a08a3adadee2ea760a07a46bdbb856fea44
TxHashRLP 0x11f8dc8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6ff845f84326a064e213aef0167fbd853f8f9989ef5d8b912a77457395ccf13d7f37009edd5c5ba05d0c2e55e4d8734fe2516ed56ac628b74c0eb02aa3b6eda51e1e25a1396093e1945a0043070275d9f6054307ee7348bd660849d90ff845f84326a087390ac14d3c34440b6ddb7b190d3ebde1a07d9a556e5a82ce7e501f24a060f9a037badbcb12cda1ed67b12b1831683a08a3adadee2ea760a07a46bdbb856fea44
TxHash 8f68882f6192a53ba470aeca1e83ed9b9e519906a91256724b284dee778b21c9
SenderTxHashRLP 0x11f8808204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6ff845f84326a064e213aef0167fbd853f8f9989ef5d8b912a77457395ccf13d7f37009edd5c5ba05d0c2e55e4d8734fe2516ed56ac628b74c0eb02aa3b6eda51e1e25a1396093e1
SenderTxHash fffaa2b38d4e684ea70a89c78fc7b2659000d130c76ad721d68175cbfc77c550

    TX(8f68882f6192a53ba470aeca1e83ed9b9e519906a91256724b284dee778b21c9)
    Type:          TxTypeFeeDelegatedValueTransferMemo
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Signature:     [{"V":"0x26","R":"0x64e213aef0167fbd853f8f9989ef5d8b912a77457395ccf13d7f37009edd5c5b","S":"0x5d0c2e55e4d8734fe2516ed56ac628b74c0eb02aa3b6eda51e1e25a1396093e1"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeePayerSig:   [{"V":"0x26","R":"0x87390ac14d3c34440b6ddb7b190d3ebde1a07d9a556e5a82ce7e501f24a060f9","S":"0x37badbcb12cda1ed67b12b1831683a08a3adadee2ea760a07a46bdbb856fea44"}]
    Data:          36383635366336633666
    Hex:           11f8dc8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6ff845f84326a064e213aef0167fbd853f8f9989ef5d8b912a77457395ccf13d7f37009edd5c5ba05d0c2e55e4d8734fe2516ed56ac628b74c0eb02aa3b6eda51e1e25a1396093e1945a0043070275d9f6054307ee7348bd660849d90ff845f84326a087390ac14d3c34440b6ddb7b190d3ebde1a07d9a556e5a82ce7e501f24a060f9a037badbcb12cda1ed67b12b1831683a08a3adadee2ea760a07a46bdbb856fea44
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x7ad6ed1f9955be00db8fb5452125f0e9a3c0856abb5b4cc4aed91ffc134321da",
  "blockNumber": "0x1",
  "contractAddress": null,
  "feePayer": "0x029fdce0457db02f05c4be9f67b7115cb8ea15ca",
  "feePayerSignatures": [
    {
      "V": "0x25",
      "R": "0xb5d80dc924c51f58eb674a142ebfd8ca1c0bc722bc85b001a5a6905ba8226b1",
      "S": "0x79852418faacd4407aee4a461a08602fcf6a3a3cb63b9ba69d70ffe2f5fe3cd"
    }
  ],
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0x7b0c",
  "input": "0x68656c6c6f",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x5",
  "senderTxHash": "0x5a4e42bac0b2bc8dda4ee82bfafc83e7f156f74d81d367a3db430abd40b2cd47",
  "signatures": [
    {
      "V": "0x26",
      "R": "0xe8f5484b057b542c80f16c5bb8707e040619c3dc9ac5628d2797aa3d8a2fc0d0",
      "S": "0x5d598f2f10283ded6f6e6a216f4278b27fdf4d431272fa090064ac0fd3fc8102"
    }
  ],
  "status": "0x1",
  "to": "0x75c3098be5e4b63fbac05838daaee378dd48098d",
  "transactionHash": "0x66fe4d1abdf15a250f9391646e0242c8e4c3310250ca316d8fd00856aac16172",
  "transactionIndex": "0x5",
  "type": "TxTypeFeeDelegatedValueTransferMemo",
  "typeInt": 17,
  "value": "0x989680"
}
```

## TxTypeFeeDelegatedSmartContractDeploy <a href="#txtypefeedelegatedsmartcontractdeploy" id="txtypefeedelegatedsmartcontractdeploy"></a>

TxTypeFeeDelegatedSmartContractDeploy deploys a smart contract with fee delegation. The following changes will be made by this transaction type.

1. The fee payer's balance decreases by the amount of the transaction fee.
2. The sender's nonce increases by one.
3. A smart contract is deployed with the code in `input`. The deployed address will be returned via `contractAddress` in the receipt.
4. `value` KLAY is transferred from the sender to the recipient.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedSmartContractDeploy. This must be 0x29.                                                                                                                                                                                                                                                                              |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |
| to                 | \*common.Address (Go)                     | The account address that will receive the transferred value. Currently, this value must be nil. Specifying the address will be supported in the future.                                                                                                                                                                                            |
| value              | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| input              | \[]byte (Go)                              | Data attached to the transaction, used for transaction execution.                                                                                                                                                                                                                                                                                  |
| humanReadable      | bool (Go)                                 | This must be false since human-readable address is not supported yet. If true, the transaction will be rejected.                                                                                                                                                                                                                                   |
| codeFormat         | uint8 (Go)                                | The code format of smart contract code. The supported value for now is EVM(0x00) only.                                                                                                                                                                                                                                                             |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input,humanReadable, codeFormat, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf90240b9023af90237298204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f00290180018080
SigHash 0xfd5e0726c763d117d07e5e688889ab7e4d0d1164d1bbca26a9d4ee629cbd875b
Signature f845f84325a04ea37b8ecfed93795a9f99b1e4d554df6fb05a361965a7655abd4e4c4422a9e5a00b05e3fffe5a3c0892eaff31466f6c47b7edad80703d395d65bbfc1a2c6a2570
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf90255b9023af90237298204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f00290180945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0xb7ea4d9d8c4d20ac6fd6cfffcaf89ae7d217d7450820b3b40d9ea29a0f01a1b2
SignatureFeePayer f845f84326a0c6738376304dfb32c77649bddd4ade925b947876cfe6b1fd2c06a2e4394504cca023817ba66a6b7c92fcf23f2d5506ea2a673aae5f1a1e4d742367971ae58a1576
TxHashRLP 0x29f902d98204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f00290180f845f84325a04ea37b8ecfed93795a9f99b1e4d554df6fb05a361965a7655abd4e4c4422a9e5a00b05e3fffe5a3c0892eaff31466f6c47b7edad80703d395d65bbfc1a2c6a2570945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0c6738376304dfb32c77649bddd4ade925b947876cfe6b1fd2c06a2e4394504cca023817ba66a6b7c92fcf23f2d5506ea2a673aae5f1a1e4d742367971ae58a1576
TxHash a457cc54b5cfd35eb61baa5ad61398fdcecab4c83693815addf00ca7166cb87e
SenderTxHashRLP 0x29f9027d8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f00290180f845f84325a04ea37b8ecfed93795a9f99b1e4d554df6fb05a361965a7655abd4e4c4422a9e5a00b05e3fffe5a3c0892eaff31466f6c47b7edad80703d395d65bbfc1a2c6a2570
SenderTxHash f3bca26fc8b50bfbcc1e94bc792ee6489cff14056e7e9aa2b074abb385f2139f

    TX(a457cc54b5cfd35eb61baa5ad61398fdcecab4c83693815addf00ca7166cb87e)
    Type:          TxTypeFeeDelegatedSmartContractDeploy
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Data:          363038303630343035323334383031353631303031303537363030303830666435623530363130316465383036313030323036303030333936303030663330303630383036303430353236303034333631303631303036313537363366666666666666663763303130303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303630303033353034313636333161333964386566383131343631303038303537383036333633353335383662313436313030613735373830363337306130383233313134363130306361353738303633666436623765663831343631303066383537356233333630303039303831353236303031363032303532363034303831323038303534333439303831303139303931353538313534303139303535303035623334383031353631303038633537363030303830666435623530363130303935363130313064353635623630343038303531393138323532353139303831393030333630323030313930663335623631303063383733666666666666666666666666666666666666666666666666666666666666666666666666666666663630303433353136363130313133353635623030356233343830313536313030643635373630303038306664356235303631303039353733666666666666666666666666666666666666666666666666666666666666666666666666666666663630303433353136363130313437353635623334383031353631303130343537363030303830666435623530363130306338363130313539353635623630303035343831353635623733666666666666666666666666666666666666666666666666666666666666666666666666666666663136363030303930383135323630303136303230353236303430383132303830353433343930383130313930393135353831353430313930353535363562363030313630323035323630303039303831353236303430393032303534383135363562333336303030393038313532363030313630323035323630343038313230383035343930383239303535393038313131313536313031616635373630343035313333393038323135363130386663303239303833393036303030383138313831383538383838663139333530353035303530313536313031396335373631303161663536356233333630303039303831353236303031363032303532363034303930323038313930353535623530353630306131363536323761376137323330353832303632376361343662623039343738613031353736323830366363303063343331323330353031313138633763323663333061633538633465303965353163346630303239
    HumanReadable: true
    CodeFormat:    CodeFormatEVM
    Signature:     [{"V":"0x25","R":"0x4ea37b8ecfed93795a9f99b1e4d554df6fb05a361965a7655abd4e4c4422a9e5","S":"0xb05e3fffe5a3c0892eaff31466f6c47b7edad80703d395d65bbfc1a2c6a2570"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeePayerSig:   [{"V":"0x26","R":"0xc6738376304dfb32c77649bddd4ade925b947876cfe6b1fd2c06a2e4394504cc","S":"0x23817ba66a6b7c92fcf23f2d5506ea2a673aae5f1a1e4d742367971ae58a1576"}]
    Hex:           29f902d98204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f00290180f845f84325a04ea37b8ecfed93795a9f99b1e4d554df6fb05a361965a7655abd4e4c4422a9e5a00b05e3fffe5a3c0892eaff31466f6c47b7edad80703d395d65bbfc1a2c6a2570945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0c6738376304dfb32c77649bddd4ade925b947876cfe6b1fd2c06a2e4394504cca023817ba66a6b7c92fcf23f2d5506ea2a673aae5f1a1e4d742367971ae58a1576
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "codeFormat": "0x0",
  "contractAddress": "0x636f6e7472616374322e6b6c6179746e00000000",
  "feePayer": "0x029fdce0457db02f05c4be9f67b7115cb8ea15ca",
  "feePayerSignatures": [
    {
      "V": "0x25",
      "R": "0x614fd887f4702627156132c9d56584207d1eaff529ee2967431eeaba924678f9",
      "S": "0x6b883a4467ca95a0ee75567062cb6d35629e9a22faeb8a711896488ce2cc4ed9"
    }
  ],
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x0",
  "gasUsed": "0xee6e5b4d",
  "humanReadable": true,
  "input": "0x608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0xb",
  "senderTxHash": "0xf8f83c7a4a334430f403b20d84db492fac43ebabbd9676d731e11460d01a2160",
  "signatures": [
    {
      "V": "0x26",
      "R": "0xf3c521fea307b39bfa914b4835112bad18f89a627d639ddabe70c20af99d29a5",
      "S": "0x5179048cf993049b380f8cf7017c6e83b23da7883d2728208fe6161808594f44"
    }
  ],
  "status": "0x1",
  "to": "0x636f6e7472616374322e6b6c6179746e00000000",
  "transactionHash": "0x39b8a31f0c02a951615e3497d68a6534b8c8cc565e514ceafec53ee7ff50b8d9",
  "transactionIndex": "0x4",
  "type": "TxTypeFeeDelegatedSmartContractDeploy",
  "typeInt": 41,
  "value": "0x0"
}
```

## TxTypeFeeDelegatedSmartContractExecution <a href="#txtypefeedelegatedsmartcontractexecution" id="txtypefeedelegatedsmartcontractexecution"></a>

TxTypeFeeDelegatedSmartContractExecution executes a smart contract with the given data in `input`. Fee will be paid by the given fee payer. TxTypeFeeDelegatedSmartContractExecution is accepted only if `to` is a smart contract account. To transfer KLAY to an externally owned account, use [TxTypeFeeDelegatedValueTransfer](#txtypefeedelegatedvaluetransfer) instead. The following changes will be made by this transaction type.

1. If `to` is a smart contract account, the code is executed based on `input`. Otherwise, this transaction will be rejected.
2. The fee payer's balance decreases by the amount of the transaction fee.
3. The sender's nonce increases by one.
4. If `value` was provided, `value` KLAY is transferred from the sender to the `to` smart contract. The contract should have a payable fallback function to receive KLAY.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedSmartContractExecution. This must be 0x31.                                                                                                                                                                                                                                                                           |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |
| to                 | common.Address (Go)                       | The address of the smart contract account to be executed.                                                                                                                                                                                                                                                                                          |
| value              | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| input              | \[]byte (Go)                              | Data attached to the transaction, used for transaction execution.                                                                                                                                                                                                                                                                                  |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf860b85bf859318204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b2018080
SigHash 0xa5dd93af9f96fa316f0ddd84f10acb2e6eb41baaec3b42f9068c38aa1618f7e1
Signature f845f84325a0253aea7d2c37160da45e84afbb45f6b3341cf1e8fc2df4ecc78f14adb512dc4fa022465b74015c2a8f8501186bb5e200e6ce44be52e9374615a7e7e21c41bc27b5
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf875b85bf859318204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b2945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0xf547d9d0041912e0daa2db2b65170a9e833877cd8482f405a11b03429fcbd554
SignatureFeePayer f845f84326a0e7c51db7b922c6fa2a941c9687884c593b1b13076bdf0c473538d826bf7b9d1aa05b0de2aabb84b66db8bf52d62f3d3b71b592e3748455630f1504c20073624d80
TxHashRLP 0x31f8fb8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b2f845f84325a0253aea7d2c37160da45e84afbb45f6b3341cf1e8fc2df4ecc78f14adb512dc4fa022465b74015c2a8f8501186bb5e200e6ce44be52e9374615a7e7e21c41bc27b5945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0e7c51db7b922c6fa2a941c9687884c593b1b13076bdf0c473538d826bf7b9d1aa05b0de2aabb84b66db8bf52d62f3d3b71b592e3748455630f1504c20073624d80
TxHash ef46f28c54b3d90a183e26f406ca1d5cc2b6e9fbb6cfa7c85a10330ffadf54b0
SenderTxHashRLP 0x31f89f8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b2f845f84325a0253aea7d2c37160da45e84afbb45f6b3341cf1e8fc2df4ecc78f14adb512dc4fa022465b74015c2a8f8501186bb5e200e6ce44be52e9374615a7e7e21c41bc27b5
SenderTxHash 3cd3380f4206943422d5d5b218dd66d03d60d19a109f9929ea12b52a230257cb

    TX(ef46f28c54b3d90a183e26f406ca1d5cc2b6e9fbb6cfa7c85a10330ffadf54b0)
    Type:          TxTypeFeeDelegatedSmartContractExecution
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Data:          363335333538366230303030303030303030303030303030303030303030303062633539353166303535613835663431613362363266643666363861623764653736643239396232
    Signature:     [{"V":"0x25","R":"0x253aea7d2c37160da45e84afbb45f6b3341cf1e8fc2df4ecc78f14adb512dc4f","S":"0x22465b74015c2a8f8501186bb5e200e6ce44be52e9374615a7e7e21c41bc27b5"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeePayerSig:   [{"V":"0x26","R":"0xe7c51db7b922c6fa2a941c9687884c593b1b13076bdf0c473538d826bf7b9d1a","S":"0x5b0de2aabb84b66db8bf52d62f3d3b71b592e3748455630f1504c20073624d80"}]
    Hex:           31f8fb8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b2f845f84325a0253aea7d2c37160da45e84afbb45f6b3341cf1e8fc2df4ecc78f14adb512dc4fa022465b74015c2a8f8501186bb5e200e6ce44be52e9374615a7e7e21c41bc27b5945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0e7c51db7b922c6fa2a941c9687884c593b1b13076bdf0c473538d826bf7b9d1aa05b0de2aabb84b66db8bf52d62f3d3b71b592e3748455630f1504c20073624d80
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "contractAddress": null,
  "feePayer": "0x029fdce0457db02f05c4be9f67b7115cb8ea15ca",
  "feePayerSignatures": [
    {
      "V": "0x25",
      "R": "0x1c7de2c83542b623ba47722f310c0e5893486eef4eed70b634d456262fb430a7",
      "S": "0x177929c52669c4b9433565a76e53723b702bae8142debe1981062f59f25062ab"
    }
  ],
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x0",
  "gasUsed": "0xb0bc",
  "input": "0x6353586b0000000000000000000000000fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0xe",
  "senderTxHash": "0xffd354e4e271ff94a7459c2f1bc0df20dc112a83f5625ff7e31d196444f72710",
  "signatures": [
    {
      "V": "0x25",
      "R": "0xefc6fec3dae47a08941712f637c95dbc46ef2afd3d16e68da602a878c0bba047",
      "S": "0x938a5374edcea0503df8e7af906a7642f7e935eab7c489b7ca8b976a8e5ab7e"
    }
  ],
  "status": "0x1",
  "to": "0x636f6e74726163742e6b6c6179746e0000000000",
  "transactionHash": "0x658a118112ffb0c06adecd59b0f11b58cf7d8afd7ec5e5d323cfca021c3dcb37",
  "transactionIndex": "0x7",
  "type": "TxTypeFeeDelegatedSmartContractExecution",
  "typeInt": 49,
  "value": "0xa"
}
```

## TxTypeFeeDelegatedAccountUpdate <a href="#txtypefeedelegatedaccountupdate" id="txtypefeedelegatedaccountupdate"></a>

TxTypeFeeDelegatedAccountUpdate updates the key of the given account. The transaction fee is paid by the fee payer. The following changes will take place by this transaction type.

1. The fee payer's balance decreases by the amount of the transaction fee.
2. The sender's nonce increases by one.
3. The account's key is updated with `key`.
4. Once this type of transaction is executed, transactions sent from the account afterward will be validated with the new `key`.
5. The transaction fee is paid by the fee payer.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                                      | Description                                                                                                                                                                                                                                                                                                                      |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeAccountUpdate. This must be 0x21.                                                                                                                                                                                                                                                                              |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                               |
| gasPrice           | \*big.Int (Go)                            | A multiplier to get how much the sender will pay in tokens. The amount of tokens the sender will pay is calculated via `gas` \* `gasPrice`. For example, the sender will pay 10 KLAY for a transaction fee if gas is 10 and gasPrice is 10^18. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                                         |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                               |
| key                | AccountKey (Go)                           | [AccountKey](/content/klaytn/design/accounts#account-key) to be updated to the account.                                                                                                                                                                                                                                          |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                 |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                    |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                      |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, from, rlpEncodedKey]), chainid, 0, 0])`
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from, rlpEncodedKey]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, rlpEncodedKey, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, from, rlpEncodedKey, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf849b844f842218204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d018080
SigHash 0x78437953e6beb985ea3ccbee8d6a648a09d11249389477a32c7094fc7b8765ef
Signature f845f84326a0ab69d9adca15d9763c4ce6f98b35256717c6e932007658f19c5a255de9e70ddaa026aa676a3a1a6e96aff4a3df2335788d614d54fb4db1c3c48551ce1fa7ac5e52
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf85eb844f842218204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0x1026d3ac74f56b52453d656b084d06798479b8bcfda1868d8beaa23e36f3aeb3
SignatureFeePayer f845f84326a0f295cd69b4144d9dbc906ba144933d2cc535d9d559f7a92b4672cc5485bf3a60a0784b8060234ffd64739b5fc2f2503939340ab4248feaa6efcf62cb874345fe40
TxHashRLP 0x21f8e48204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33df845f84326a0ab69d9adca15d9763c4ce6f98b35256717c6e932007658f19c5a255de9e70ddaa026aa676a3a1a6e96aff4a3df2335788d614d54fb4db1c3c48551ce1fa7ac5e52945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0f295cd69b4144d9dbc906ba144933d2cc535d9d559f7a92b4672cc5485bf3a60a0784b8060234ffd64739b5fc2f2503939340ab4248feaa6efcf62cb874345fe40
TxHash 756ff5d3912a4089659614d42a218eee59e602a5992bddca383c2d295c6637bb
SenderTxHashRLP 0x21f8888204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33df845f84326a0ab69d9adca15d9763c4ce6f98b35256717c6e932007658f19c5a255de9e70ddaa026aa676a3a1a6e96aff4a3df2335788d614d54fb4db1c3c48551ce1fa7ac5e52
SenderTxHash f56937017bd3b75c637ba5b4ce90df20c166006a2a529b42e808bc806159b98f

    TX(756ff5d3912a4089659614d42a218eee59e602a5992bddca383c2d295c6637bb)
    Type:          TxTypeFeeDelegatedAccountUpdate
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Key:           AccountKeyPublic: S256Pubkey:{"x":"0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d","y":"0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3"}
    Signature:     [{"V":"0x26","R":"0xab69d9adca15d9763c4ce6f98b35256717c6e932007658f19c5a255de9e70dda","S":"0x26aa676a3a1a6e96aff4a3df2335788d614d54fb4db1c3c48551ce1fa7ac5e52"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeePayerSig:   [{"V":"0x26","R":"0xf295cd69b4144d9dbc906ba144933d2cc535d9d559f7a92b4672cc5485bf3a60","S":"0x784b8060234ffd64739b5fc2f2503939340ab4248feaa6efcf62cb874345fe40"}]
    Hex:           21f8e48204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33df845f84326a0ab69d9adca15d9763c4ce6f98b35256717c6e932007658f19c5a255de9e70ddaa026aa676a3a1a6e96aff4a3df2335788d614d54fb4db1c3c48551ce1fa7ac5e52945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0f295cd69b4144d9dbc906ba144933d2cc535d9d559f7a92b4672cc5485bf3a60a0784b8060234ffd64739b5fc2f2503939340ab4248feaa6efcf62cb874345fe40
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "contractAddress": null,
  "feePayer": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "feePayerSignatures": [
    {
      "V": "0x25",
      "R": "0x3b019642e5ae37f3ecbf85e6fc1ee77e51d1618299367bcedd816d0da6afb1e0",
      "S": "0x5c12c87811a74183f8b56b707fa90a916b1c641652c93e52300f5cee36141d73"
    }
  ],
  "from": "0x636f6c696e322e6b6c6179746e00000000000000",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0xc738",
  "key": "0x02a1034ef27ba4b7d1ae09b166744c5b7ee4a7a0cc5c76b2e5d74523a0a4fb56db3191",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x0",
  "senderTxHash": "0xf4e7ef082451d4a3c8ad7c4348fc99c965a9c130bfc98d7971f3103e3dcfda3c",
  "signatures": [
    {
      "V": "0x26",
      "R": "0xd4cb16abcdf92969dc45efacaa5827ad55738fbda08a3dbaf0f0553643084a6",
      "S": "0x23f8055933b416cf15568a017e0a11e0a5c0a8f65477f6ec71de0bf837f4a681"
    }
  ],
  "status": "0x1",
  "transactionHash": "0xeb0c14d903db38deee116ac8a0d620e6ca6aa79e4f91393abbddfa30810b9d43",
  "transactionIndex": "0x2",
  "type": "TxTypeFeeDelegatedAccountUpdate",
  "typeInt": 33
},
```

## TxTypeFeeDelegatedCancel <a href="#txtypefeedelegatedcancel" id="txtypefeedelegatedcancel"></a>

TxTypeFeeDelegatedCancel cancels the execution of the transaction with the same nonce in the transaction pool. For more details, see [TxTypeCancel](/content/klaytn/design/transactions/basic#txtypecancel).

The following changes will apply by this transaction type. 1. The fee payer's balance decreases by the amount of the transaction fee. 2. The sender's nonce increases by one.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeCancel. This must be 0x39.                                                                                                                                                                                                                                                                                                       |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                                                           |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, from]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, from, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xe39fde398204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0b018080
SigHash 0xd36c4277f4aa1d483a5fc4d656aeea50416c28adddb27a234d320290bd2a343c
Signature f845f84326a08409f5441d4725f90905ad87f03793857d124de7a43169bc67320cd2f020efa9a060af63e87bdc565d7f7de906916b2334336ee7b24d9a71c9521a67df02e7ec92
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf8389fde398204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0b945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0x15859ecc06acbd2dd5820c5968a85590826d1f6affb938e89559558ac4f86a24
SignatureFeePayer f845f84326a0044d5b25e8c649a1fdaa409dc3817be390ad90a17c25bc17c89b6d5d248495e0a073938e690d27b5267c73108352cf12d01de7fd0077b388e94721aa1fa32f85ec
TxHashRLP 0x39f8c08204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84326a08409f5441d4725f90905ad87f03793857d124de7a43169bc67320cd2f020efa9a060af63e87bdc565d7f7de906916b2334336ee7b24d9a71c9521a67df02e7ec92945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0044d5b25e8c649a1fdaa409dc3817be390ad90a17c25bc17c89b6d5d248495e0a073938e690d27b5267c73108352cf12d01de7fd0077b388e94721aa1fa32f85ec
TxHash 96b39d3ab849127d31a5f7b5c882ca9ba408cd9d875052640d51a64f8c4acbb2
SenderTxHashRLP 0x39f8648204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84326a08409f5441d4725f90905ad87f03793857d124de7a43169bc67320cd2f020efa9a060af63e87bdc565d7f7de906916b2334336ee7b24d9a71c9521a67df02e7ec92
SenderTxHash cc6c2673398903b3d906a3023b41636fc08bd1bddd5aa1602116091638f48447

    TX(96b39d3ab849127d31a5f7b5c882ca9ba408cd9d875052640d51a64f8c4acbb2)
    Type:          TxTypeFeeDelegatedCancel
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Signature:     [{"V":"0x26","R":"0x8409f5441d4725f90905ad87f03793857d124de7a43169bc67320cd2f020efa9","S":"0x60af63e87bdc565d7f7de906916b2334336ee7b24d9a71c9521a67df02e7ec92"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeePayerSig:   [{"V":"0x26","R":"0x44d5b25e8c649a1fdaa409dc3817be390ad90a17c25bc17c89b6d5d248495e0","S":"0x73938e690d27b5267c73108352cf12d01de7fd0077b388e94721aa1fa32f85ec"}]
    Hex:           39f8c08204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84326a08409f5441d4725f90905ad87f03793857d124de7a43169bc67320cd2f020efa9a060af63e87bdc565d7f7de906916b2334336ee7b24d9a71c9521a67df02e7ec92945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0044d5b25e8c649a1fdaa409dc3817be390ad90a17c25bc17c89b6d5d248495e0a073938e690d27b5267c73108352cf12d01de7fd0077b388e94721aa1fa32f85ec
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "contractAddress": null,
  "feePayer": "0x029fdce0457db02f05c4be9f67b7115cb8ea15ca",
  "feePayerSignatures": [
    {
      "V": "0x25",
      "R": "0x26a7c88e1fc77400f2a4c7911966a5e51b0873e3f26daf9d6519b93e3f3db6a3",
      "S": "0x560e5fa8d53ebf899eb48353bf14794c76784240a6a212f5ddbe7f1684088f3f"
    }
  ],
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0x7918",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x11",
  "senderTxHash": "0x2fea0ff37b8b936d4c06f29b98c4bd200827423fb445f931eb64725aefcda053",
  "signatures": [
    {
      "V": "0x26",
      "R": "0xcfdb5b3ff6c87a8f18ae606b371d1e569c56d35a737831b89052c5a8ef19d049",
      "S": "0x1ee63bd5a01c45d0c6f1b36a29e1c01b56baa719f008c556bc9054ac5a64bd8d"
    }
  ],
  "status": "0x1",
  "transactionHash": "0xf475e714b30aef0b79d46c9482289f3fbe51f1e44bcbc99a90ac8e25672bc969",
  "transactionIndex": "0xa",
  "type": "TxTypeFeeDelegatedCancel",
  "typeInt": 57
}
```

## TxTypeFeeDelegatedChainDataAnchoring <a href="#txtypefeedelegatedchaindataanchoring" id="txtypefeedelegatedchaindataanchoring"></a>

TxTypeFeeDelegatedChainDataAnchoring is a fee-delegated transaction that anchors service chain data to the Klaytn mainchain. Service chains periodically send this type of transaction to the Klaytn mainchain to ensure its security and credibility of data. For more details about the data anchoring, see [Anchoring](/content/installation-guide/deployment/service-chain/references/anchoring). As it is a fee-delegated transaction as well, its transaction fee is charged to the fee payer. Be mindful that it is not allowed to send this transaction via RPC. Currently, this transaction is executed through private p2p channels for security reasons. This transaction does not change the state of the Klaytn blockchain except the sender's nonce being increased by one.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedChainDataAnchoring. This must be 0x49.                                                                                                                                                                                                                                                                               |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                                                           |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| input              | \[]byte (Go)                              | Data of the service chain.                                                                                                                                                                                                                                                                                                                         |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, from, anchoredData]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from, anchoredData]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, anchoredData, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, from, anchoredData, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x01
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf8dbb8d6f8d449118505d21dba0085174876e80094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8aff8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000004058006018080
SigHash 0x92e385b4a162170ee87b2b2e598f686b1d16f385d98ad626147305624abec0b3
Signature 0xf845f84326a0afe41edc9cce1185ab9065ca7dbfb89ab5c7bde3602a659aa258324124644142a0317848698248ba7cc057b8f0dd19a27b52ef904d29cb72823100f1ed18ba2bb3
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf8f0b8d6f8d449118505d21dba0085174876e80094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8aff8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000000040580069433f524631e573329a550296f595c820d6c65213f018080
SigHashFeePayer 0x4d58fdf276fde1e221b6bab8c6621ae1639b00a7a70d2bd0a114001692a3a7d1
SignatureFeePayer 0xf845f84325a0309e46db21a1bf7bfdae24d9192aca69516d6a341ecce8971fc69cff481cee76a04b939bf7384c4f919880307323a5e36d4d6e029bae1887a43332710cdd48f174
TxHashRLP 0x49f90176118505d21dba0085174876e80094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8aff8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000004058006f845f84326a0afe41edc9cce1185ab9065ca7dbfb89ab5c7bde3602a659aa258324124644142a0317848698248ba7cc057b8f0dd19a27b52ef904d29cb72823100f1ed18ba2bb39433f524631e573329a550296f595c820d6c65213ff845f84325a0309e46db21a1bf7bfdae24d9192aca69516d6a341ecce8971fc69cff481cee76a04b939bf7384c4f919880307323a5e36d4d6e029bae1887a43332710cdd48f174
TxHash 0xecf1ec12937065617f9b3cd07570452bfdb75dc36404c4f37f78995c6dc462af
SenderTxHashRLP 0x49f9011a118505d21dba0085174876e80094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8aff8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000004058006f845f84326a0afe41edc9cce1185ab9065ca7dbfb89ab5c7bde3602a659aa258324124644142a0317848698248ba7cc057b8f0dd19a27b52ef904d29cb72823100f1ed18ba2bb3
SenderTxHash 0x4f5c00ea8f6346baa7d4400dfefd72efa5ec219561ebcebed7be8a2b79d52bcd

	TX(ecf1ec12937065617f9b3cd07570452bfdb75dc36404c4f37f78995c6dc462af)
	Type:          TxTypeFeeDelegatedChainDataAnchoring
	From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
	Nonce:         17
	GasPrice:      0x5d21dba00
	GasLimit:      0x174876e800
	AnchoredData:  f8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000004058006
	Signature:     [{"V":"0x26","R":"0xafe41edc9cce1185ab9065ca7dbfb89ab5c7bde3602a659aa258324124644142","S":"0x317848698248ba7cc057b8f0dd19a27b52ef904d29cb72823100f1ed18ba2bb3"}]
	FeePayer:      0x33f524631e573329a550296F595c820D6c65213f
	FeePayerSig:   [{"V":"0x25","R":"0x309e46db21a1bf7bfdae24d9192aca69516d6a341ecce8971fc69cff481cee76","S":"0x4b939bf7384c4f919880307323a5e36d4d6e029bae1887a43332710cdd48f174"}]
	Hex:           49f90176118505d21dba0085174876e80094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8aff8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000004058006f845f84326a0afe41edc9cce1185ab9065ca7dbfb89ab5c7bde3602a659aa258324124644142a0317848698248ba7cc057b8f0dd19a27b52ef904d29cb72823100f1ed18ba2bb39433f524631e573329a550296f595c820d6c65213ff845f84325a0309e46db21a1bf7bfdae24d9192aca69516d6a341ecce8971fc69cff481cee76a04b939bf7384c4f919880307323a5e36d4d6e029bae1887a43332710cdd48f174
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
    "blockHash": "0x170a32e16b6fdced144d5104f5aecf753878bd9f1a7d87ddccc2e6d2ba27354c",
    "blockNumber": "0x2",
    "contractAddress": null,
    "feePayer": "0x33f524631e573329a550296f595c820d6c65213f",
    "feePayerSignatures": [
        {
            "V": "0x25",
            "R": "0x309e46db21a1bf7bfdae24d9192aca69516d6a341ecce8971fc69cff481cee76",
            "S": "0x4b939bf7384c4f919880307323a5e36d4d6e029bae1887a43332710cdd48f174"
        }
    ],
    "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
    "gas": "0x174876e800",
    "gasPrice": "0x5d21dba00",
    "gasUsed": "0xbd74",
    "input": "0xf8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000004058006",
    "logs": [],
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "nonce": "0x11",
    "senderTxHash": "0x4f5c00ea8f6346baa7d4400dfefd72efa5ec219561ebcebed7be8a2b79d52bcd",
    "signatures": [
        {
            "V": "0x26",
            "R": "0xafe41edc9cce1185ab9065ca7dbfb89ab5c7bde3602a659aa258324124644142",
            "S": "0x317848698248ba7cc057b8f0dd19a27b52ef904d29cb72823100f1ed18ba2bb3"
        }
    ],
    "status": "0x1",
    "transactionHash": "0xecf1ec12937065617f9b3cd07570452bfdb75dc36404c4f37f78995c6dc462af",
    "transactionIndex": "0xa",
    "type": "TxTypeFeeDelegatedChainDataAnchoring",
    "typeInt": 73
}
```


# Partial Fee Delegation

## TxTypeFeeDelegatedValueTransferWithRatio <a href="#txtypefeedelegatedvaluetransferwithratio" id="txtypefeedelegatedvaluetransferwithratio"></a>

TxTypeFeeDelegatedValueTransferWithRatio is used when a user wants to send KLAY. As Klaytn provides multiple transaction types to make each transaction type serve a single purpose, TxTypeFeeDelegatedValueTransferWithRatio is limited to send KLAY to an externally owned account. Therefore, TxTypeFeeDelegatedValueTransferWithRatio is accepted only if `to` is an externally owned account. To transfer KLAY to a smart contract account, use [TxTypeFeeDelegatedSmartContractExecutionWithRatio](#txtypefeedelegatedsmartcontractexecutionwithratio) instead. The following changes will be made by this transaction type.

1. The fee payer's balance decreases by the given ratio of the transaction fee.
2. The sender's balance decreases by the remaining transaction fee. e.g., If the `feeRatio` is 30, 30% of the fee will be paid by the fee payer, and the remaining 70% of the fee will be paid by the sender.
3. The sender's nonce increases by one.
4. `value` KLAY is transferred from the sender to the recipient.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedValueTransferWithRatio. This must be 0x0a.                                                                                                                                                                                                                                                                           |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |
| to                 | common.Address (Go)                       | The account address that will receive the transferred value.                                                                                                                                                                                                                                                                                       |
| value              | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| feeRatio           | uint8 (Go)                                | Fee ratio of the fee payer. The valid range is between 1 and 99. Zero(0) is not allowed. 100 and above are not allowed as well.                                                                                                                                                                                                                    |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, feeRatio]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, feeRatio]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, feeRatio, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, feeRatio, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf83ab6f50a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b1e018080
SigHash 0x0f7d520cd00034299b36004c21b571263dbb9a77edbd5920c4136f7f74050d9d
Signature f845f84325a0dde32b8241f039a82b124fe94d3e556eb08f0d6f26d07dcc0f3fca621f1090caa01c8c336b358ab6d3a2bbf25de2adab4d01b754e2fb3b9b710069177d54c1e956
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf84fb6f50a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b1e945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0x38123c30a5f83db853e9ae4e8dd8d4f6aa6840415acffb8dbf18b2050463dec4
SignatureFeePayer f845f84326a0091ecf53f91bb97bb694f2f2443f3563ac2b646d651497774524394aae396360a044228b88f275aa1ec1bab43681d21dc7e3a676786ed1906f6841d0a1a188f88a
TxHashRLP 0x0af8d78204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b1ef845f84325a0dde32b8241f039a82b124fe94d3e556eb08f0d6f26d07dcc0f3fca621f1090caa01c8c336b358ab6d3a2bbf25de2adab4d01b754e2fb3b9b710069177d54c1e956945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0091ecf53f91bb97bb694f2f2443f3563ac2b646d651497774524394aae396360a044228b88f275aa1ec1bab43681d21dc7e3a676786ed1906f6841d0a1a188f88a
TxHash 83a89f4debd8e9d6374b987e25132b3a4030c9cf9ace2fc6e7d1086fcea2ce40
SenderTxHashRLP 0x0af87b8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b1ef845f84325a0dde32b8241f039a82b124fe94d3e556eb08f0d6f26d07dcc0f3fca621f1090caa01c8c336b358ab6d3a2bbf25de2adab4d01b754e2fb3b9b710069177d54c1e956
SenderTxHash 4711ed4023e821425968342c1d50063b6bc3176b1792b7075cfeee3656d450f6

    TX(83a89f4debd8e9d6374b987e25132b3a4030c9cf9ace2fc6e7d1086fcea2ce40)
    Type:          TxTypeFeeDelegatedValueTransferWithRatio
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Signature:     [{"V":"0x25","R":"0xdde32b8241f039a82b124fe94d3e556eb08f0d6f26d07dcc0f3fca621f1090ca","S":"0x1c8c336b358ab6d3a2bbf25de2adab4d01b754e2fb3b9b710069177d54c1e956"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeeRatio:      30
    FeePayerSig:   [{"V":"0x26","R":"0x91ecf53f91bb97bb694f2f2443f3563ac2b646d651497774524394aae396360","S":"0x44228b88f275aa1ec1bab43681d21dc7e3a676786ed1906f6841d0a1a188f88a"}]
    Hex:           0af8d78204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b1ef845f84325a0dde32b8241f039a82b124fe94d3e556eb08f0d6f26d07dcc0f3fca621f1090caa01c8c336b358ab6d3a2bbf25de2adab4d01b754e2fb3b9b710069177d54c1e956945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0091ecf53f91bb97bb694f2f2443f3563ac2b646d651497774524394aae396360a044228b88f275aa1ec1bab43681d21dc7e3a676786ed1906f6841d0a1a188f88a
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x7ad6ed1f9955be00db8fb5452125f0e9a3c0856abb5b4cc4aed91ffc134321da",
  "blockNumber": "0x1",
  "contractAddress": null,
  "feePayer": "0x029fdce0457db02f05c4be9f67b7115cb8ea15ca",
  "feePayerSignatures": [
    {
      "V": "0x25",
      "R": "0xb8583f638efefb297922aa8b8a30cf451a30e266126d52da03ba9ead0fbb1ccd",
      "S": "0x4bc5ca3756f88d857d115b128b00babe5b3c0b089f087a0b30a9ced269e00603"
    }
  ],
  "feeRatio": "0x14",
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0x8ca0",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x3",
  "senderTxHash": "0xac372c68d2937383d4344a2d187e70b207c76160eb407b68e08c944b919328de",
  "signatures": [
    {
      "V": "0x26",
      "R": "0x1a8d5bf583843ceba87943569a34a8a6caa18a9ab5e4cf6914d8048e607787bc",
      "S": "0x27458275c84adcb8144b4596946111f1a539643941de74f587fa69a7df98ed1b"
    }
  ],
  "status": "0x1",
  "to": "0x75c3098be5e4b63fbac05838daaee378dd48098d",
  "transactionHash": "0x670ff613022278cc2551a7e4669d8911f1658ffaa4dcc3695b14f39194a8a38c",
  "transactionIndex": "0x3",
  "type": "TxTypeFeeDelegatedValueTransferWithRatio",
  "typeInt": 10,
  "value": "0x989680"
}
```

## TxTypeFeeDelegatedValueTransferMemoWithRatio <a href="#txtypefeedelegatedvaluetransfermemowithratio" id="txtypefeedelegatedvaluetransfermemowithratio"></a>

TxTypeFeeDelegatedValueTransferMemoWithRatio is used when a user wants to send KLAY with a specific message. TxTypeFeeDelegatedValueTransferMemoWithRatio is accepted only if `to` is an externally owned account. To transfer KLAY to a smart contract account, use [TxTypeFeeDelegatedSmartContractExecutionWithRatio](#txtypefeedelegatedsmartcontractexecutionwithratio) instead. The following changes will be made by this transaction type.

1. The fee payer's balance decreases by the fee ratio of the amount of the transaction fee.
2. The sender's balance decreases by the remaining transaction fee. e.g., If the `feeRatio` is 30, 30% of the fee will be paid by the fee payer, and the remaining 70% of the fee will be paid by the sender.k
3. The sender's nonce increases by one.
4. `value` KLAY is transferred from the sender to the recipient.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Description                               | Type                                                                                                                                                                                                                                                                                                                                               |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedValueTransferMemoWithRatio. This must be 0x12.                                                                                                                                                                                                                                                                       |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |
| to                 | common.Address (Go)                       | The account address that will receive the transferred value.                                                                                                                                                                                                                                                                                       |
| value              | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| input              | \[]byte (Go)                              | Data attached to the transaction. The message should be passed to this attribute.                                                                                                                                                                                                                                                                  |
| feeRatio           | uint8 (Go)                                | Fee ratio of the fee payer. The valid range is between 1 and 99. Zero(0) is not allowed. 100 and above are not allowed as well.                                                                                                                                                                                                                    |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, feeRatio]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, feeRatio]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, feeRatio, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, feeRatio, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf842b83df83b128204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6f1e018080
SigHash 0x50eef45abe0743dce17e40db185d1d85607245a545f7517a52b90f3673aff689
Signature f845f84326a0769f0afdc310289f9b24decb5bb765c8d7a87a6a4ae28edffb8b7085bbd9bc78a06a7b970eea026e60ac29bb52aee10661a4222e6bdcdfb3839a80586e584586b4
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf857b83df83b128204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6f1e945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0x09583a871c38a4860e336bfa5f16003feec75e710cfd9186c37892cee7d9775b
SignatureFeePayer f845f84325a0c1c54bdc72ce7c08821329bf50542535fac74f4bba5de5b7881118a461d52834a03a3a64878d784f9af91c2e3ab9c90f17144c47cfd9951e3588c75063c0649ecd
TxHashRLP 0x12f8dd8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6f1ef845f84326a0769f0afdc310289f9b24decb5bb765c8d7a87a6a4ae28edffb8b7085bbd9bc78a06a7b970eea026e60ac29bb52aee10661a4222e6bdcdfb3839a80586e584586b4945a0043070275d9f6054307ee7348bd660849d90ff845f84325a0c1c54bdc72ce7c08821329bf50542535fac74f4bba5de5b7881118a461d52834a03a3a64878d784f9af91c2e3ab9c90f17144c47cfd9951e3588c75063c0649ecd
TxHash abcb0fd8ebb8f62ac899e5211b9ba47fe948a8efd815229cc4ed9cd781464f15
SenderTxHashRLP 0x12f87b8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b1ef845f84326a0769f0afdc310289f9b24decb5bb765c8d7a87a6a4ae28edffb8b7085bbd9bc78a06a7b970eea026e60ac29bb52aee10661a4222e6bdcdfb3839a80586e584586b4
SenderTxHash 2c4e8cd3c68a4aacae51c695e857cfc1a019037ca71d8cd1e8ca56ec4eaf55b1

    TX(abcb0fd8ebb8f62ac899e5211b9ba47fe948a8efd815229cc4ed9cd781464f15)
    Type:          TxTypeFeeDelegatedValueTransferMemoWithRatio
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Signature:     [{"V":"0x26","R":"0x769f0afdc310289f9b24decb5bb765c8d7a87a6a4ae28edffb8b7085bbd9bc78","S":"0x6a7b970eea026e60ac29bb52aee10661a4222e6bdcdfb3839a80586e584586b4"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeeRatio:      30
    FeePayerSig:   [{"V":"0x25","R":"0xc1c54bdc72ce7c08821329bf50542535fac74f4bba5de5b7881118a461d52834","S":"0x3a3a64878d784f9af91c2e3ab9c90f17144c47cfd9951e3588c75063c0649ecd"}]
    Data:          36383635366336633666
    Hex:           12f8dd8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0b8568656c6c6f1ef845f84326a0769f0afdc310289f9b24decb5bb765c8d7a87a6a4ae28edffb8b7085bbd9bc78a06a7b970eea026e60ac29bb52aee10661a4222e6bdcdfb3839a80586e584586b4945a0043070275d9f6054307ee7348bd660849d90ff845f84325a0c1c54bdc72ce7c08821329bf50542535fac74f4bba5de5b7881118a461d52834a03a3a64878d784f9af91c2e3ab9c90f17144c47cfd9951e3588c75063c0649ecd
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x7ad6ed1f9955be00db8fb5452125f0e9a3c0856abb5b4cc4aed91ffc134321da",
  "blockNumber": "0x1",
  "contractAddress": null,
  "feePayer": "0x029fdce0457db02f05c4be9f67b7115cb8ea15ca",
  "feePayerSignatures": [
    {
      "V": "0x26",
      "R": "0x1f71cc0dee26dce62a987d189650ee62a6751fcde1c7f7915abaf6c0137930da",
      "S": "0x585115c7eecb3a88e3805a90be8cb6458f245029274a781afd2b867579ff73fa"
    }
  ],
  "feeRatio": "0x1e",
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0x8e94",
  "input": "0x68656c6c6f",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x6",
  "senderTxHash": "0xe68e9194c5448d17137f00aae392ade4d8a143c1ae4f3c5a2340a332bce009e4",
  "signatures": [
    {
      "V": "0x25",
      "R": "0x60e5da74cc0f7d73b57dc4b2a5bb7dd05d40757b47febc079e3a43769878abc3",
      "S": "0x68e16f2a7bce21e16cebbe22a3624aa5edd814dd74a70ab8aaf850cd7a4b757f"
    }
  ],
  "status": "0x1",
  "to": "0x75c3098be5e4b63fbac05838daaee378dd48098d",
  "transactionHash": "0xda18ebcf420af8a0a7acf6636711540f71b8bb65bc86e960e6a6bbb665a062f3",
  "transactionIndex": "0x6",
  "type": "TxTypeFeeDelegatedValueTransferMemoWithRatio",
  "typeInt": 18,
  "value": "0x989680"
}
```

## TxTypeFeeDelegatedSmartContractDeployWithRatio <a href="#txtypefeedelegatedsmartcontractdeploywithratio" id="txtypefeedelegatedsmartcontractdeploywithratio"></a>

TxTypeFeeDelegatedSmartContractDeployWithRatio deploys a smart contract. The given ratio of the transaction fee is paid by the fee payer. The following changes will be made by this transaction type.

1. The fee payer's balance decreases by the fee ratio of the amount of the transaction fee.
2. The sender's balance decreases by the remaining transaction fee. e.g., If the `feeRatio` is 30, 30% of the fee will be paid by the fee payer, and the remaining 70% of the fee will be paid by the sender.
3. The sender's nonce increases by one.
4. A smart contract is deployed with the code in `input`. The deployed address will be returned via `contractAddress` in the receipt.
5. `value` KLAY is transferred from the sender to the recipient.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedSmartContractDeployWithRatio. This must be 0x2a.                                                                                                                                                                                                                                                                     |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |
| to                 | \*common.Address (Go)                     | The account address that will receive the transferred value. Currently, this value must be nil. Specifying the address will be supported in the future.                                                                                                                                                                                            |
| value              | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| input              | \[]byte (Go)                              | Data attached to the transaction, used for transaction execution.                                                                                                                                                                                                                                                                                  |
| humanReadable      | bool (Go)                                 | This must be false since human-readable address is not supported yet. If true, the transaction will be rejected.                                                                                                                                                                                                                                   |
| feeRatio           | uint8 (Go)                                | Fee ratio of the fee payer. The valid range is between 1 and 99. Zero(0) is not allowed. 100 and above are not allowed as well.                                                                                                                                                                                                                    |
| codeFormat         | uint8 (Go)                                | The code format of smart contract code. The supported value for now is EVM(0x00) only.                                                                                                                                                                                                                                                             |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, humanReadable, feeRatio, codeFormat]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, humanReadable, feeRatio, codeFormat]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, humanReadable, feeRatio, codeFormat, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, humanReadable, feeRatio, codeFormat, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf90241b9023bf902382a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029011e80018080
SigHash 0x000db9e2246975d7242e2fb45279ff42bc0269e544e3b1589ea78e760775cc2c
Signature f845f84326a0cfe8dc29d31916b3f661a4774cb8d44d39ae700a9fb6ca04327f84bbe4de1486a01616e09ced403420cac1363d14e705b7a323518b1ce5124b16f06871c00ac424
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf90256b9023bf902382a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029011e80945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0xedd4031ccfb27867cbd856192cec0a538ab25f6bc632f3075bf7be8368983cea
SignatureFeePayer f845f84325a0e29dae81defc027f059cd6a55ff74156b9c5bdb811460f09fc8d167c01aaaea1a04eba34d4d5ebbce60e4998f03b7a4658263bb21063ddf68ad3b088d670de47c8
TxHashRLP 0x2af902da8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029011e80f845f84326a0cfe8dc29d31916b3f661a4774cb8d44d39ae700a9fb6ca04327f84bbe4de1486a01616e09ced403420cac1363d14e705b7a323518b1ce5124b16f06871c00ac424945a0043070275d9f6054307ee7348bd660849d90ff845f84325a0e29dae81defc027f059cd6a55ff74156b9c5bdb811460f09fc8d167c01aaaea1a04eba34d4d5ebbce60e4998f03b7a4658263bb21063ddf68ad3b088d670de47c8
TxHash 54b6f267c2dd508ffdd9d41fd6d04847ad975cede8fcd4d5af58ca959c534946
SenderTxHashRLP 0x2af9027e8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029011e80f845f84326a0cfe8dc29d31916b3f661a4774cb8d44d39ae700a9fb6ca04327f84bbe4de1486a01616e09ced403420cac1363d14e705b7a323518b1ce5124b16f06871c00ac424
SenderTxHash 57dfef9c923cba182cca00fa65d45aaf619613d843d585d3c4026a3bd0797366

    TX(54b6f267c2dd508ffdd9d41fd6d04847ad975cede8fcd4d5af58ca959c534946)
    Type:          TxTypeFeeDelegatedSmartContractDeployWithRatio
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Data:          363038303630343035323334383031353631303031303537363030303830666435623530363130316465383036313030323036303030333936303030663330303630383036303430353236303034333631303631303036313537363366666666666666663763303130303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303630303033353034313636333161333964386566383131343631303038303537383036333633353335383662313436313030613735373830363337306130383233313134363130306361353738303633666436623765663831343631303066383537356233333630303039303831353236303031363032303532363034303831323038303534333439303831303139303931353538313534303139303535303035623334383031353631303038633537363030303830666435623530363130303935363130313064353635623630343038303531393138323532353139303831393030333630323030313930663335623631303063383733666666666666666666666666666666666666666666666666666666666666666666666666666666663630303433353136363130313133353635623030356233343830313536313030643635373630303038306664356235303631303039353733666666666666666666666666666666666666666666666666666666666666666666666666666666663630303433353136363130313437353635623334383031353631303130343537363030303830666435623530363130306338363130313539353635623630303035343831353635623733666666666666666666666666666666666666666666666666666666666666666666666666666666663136363030303930383135323630303136303230353236303430383132303830353433343930383130313930393135353831353430313930353535363562363030313630323035323630303039303831353236303430393032303534383135363562333336303030393038313532363030313630323035323630343038313230383035343930383239303535393038313131313536313031616635373630343035313333393038323135363130386663303239303833393036303030383138313831383538383838663139333530353035303530313536313031396335373631303161663536356233333630303039303831353236303031363032303532363034303930323038313930353535623530353630306131363536323761376137323330353832303632376361343662623039343738613031353736323830366363303063343331323330353031313138633763323663333061633538633465303965353163346630303239
    HumanReadable: true
    Signature:     [{"V":"0x26","R":"0xcfe8dc29d31916b3f661a4774cb8d44d39ae700a9fb6ca04327f84bbe4de1486","S":"0x1616e09ced403420cac1363d14e705b7a323518b1ce5124b16f06871c00ac424"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeeRatio:      30
    CodeFormat:    CodeFormatEVM
    FeePayerSig:   [{"V":"0x25","R":"0xe29dae81defc027f059cd6a55ff74156b9c5bdb811460f09fc8d167c01aaaea1","S":"0x4eba34d4d5ebbce60e4998f03b7a4658263bb21063ddf68ad3b088d670de47c8"}]
    Hex:           2af902da8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bb901fe608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029011e80f845f84326a0cfe8dc29d31916b3f661a4774cb8d44d39ae700a9fb6ca04327f84bbe4de1486a01616e09ced403420cac1363d14e705b7a323518b1ce5124b16f06871c00ac424945a0043070275d9f6054307ee7348bd660849d90ff845f84325a0e29dae81defc027f059cd6a55ff74156b9c5bdb811460f09fc8d167c01aaaea1a04eba34d4d5ebbce60e4998f03b7a4658263bb21063ddf68ad3b088d670de47c8
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "codeFormat": "0x0",
  "contractAddress": "0x636f6e7472616374332e6b6c6179746e00000000",
  "feePayer": "0x029fdce0457db02f05c4be9f67b7115cb8ea15ca",
  "feePayerSignatures": [
    {
      "V": "0x25",
      "R": "0x9dbd19852ce8d1bc36389c73aa45733ccd2af0186d78952ca2b7bf3828227c02",
      "S": "0x184f60af32203d5abd0e1ac8820887cc96189d4efc1ccddb5fb966e29a07c9cf"
    }
  ],
  "feeRatio": "0x21",
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x0",
  "gasUsed": "0xee6e6ed5",
  "humanReadable": true,
  "input": "0x608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0xc",
  "senderTxHash": "0xe24e58467268601dc5131fb9719ebbb4bed16244af05c37d916a92c98a6a62a5",
  "signatures": [
    {
      "V": "0x26",
      "R": "0xb9497df1dd5c37786570f26745112fb828fb7b6de851bc11562eab77a76462b1",
      "S": "0x6231f2945f01004e68388ad1103cb00fd4f3f8b782667030d99779ecd47d7462"
    }
  ],
  "status": "0x1",
  "to": "0x636f6e7472616374332e6b6c6179746e00000000",
  "transactionHash": "0x32944e85f2255b7ebc1101b136938a758295d57dca1203b997e7ee7873dd9eec",
  "transactionIndex": "0x5",
  "type": "TxTypeFeeDelegatedSmartContractDeployWithRatio",
  "typeInt": 42,
  "value": "0x0"
}
```

## TxTypeFeeDelegatedSmartContractExecutionWithRatio <a href="#txtypefeedelegatedsmartcontractexecutionwithratio" id="txtypefeedelegatedsmartcontractexecutionwithratio"></a>

TxTypeFeeDelegatedSmartContractExecution executes a smart contract with the given data in `input`. TxTypeFeeDelegatedSmartContractExecutionWithRatio is accepted only if `to` is a smart contract account. To transfer KLAY to an externally owned account, use [TxTypeFeeDelegatedValueTransferWithRatio](#txtypefeedelegatedvaluetransferwithratio) instead. The following changes will be made by this transaction type.

1. If `to` is a smart contract account, the code is executed based on `input`. Otherwise, this transaction will be rejected.
2. The fee payer's balance decreases by the fee ratio of the amount of the transaction fee.
3. The sender's balance decreases by the remaining transaction fee. e.g., If the `feeRatio` is 30, 30% of the fee will be paid by the fee payer, and the remaining 70% of the fee will be paid by the sender.
4. The sender's nonce increases by one.
5. If `value` was provided, `value` KLAY is transferred from the sender to the `to` smart contract. The contract should have a payable fallback function to receive KLAY.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedSmartContractExecutionWithRatio. This must be 0x32.                                                                                                                                                                                                                                                                  |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of gas the transaction is allowed to use.                                                                                                                                                                                                                                                                                       |
| to                 | common.Address (Go)                       | The address of the smart contract account to be executed.                                                                                                                                                                                                                                                                                          |
| value              | \*big.Int (Go)                            | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                                                                     |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| input              | \[]byte (Go)                              | Data attached to the transaction, used for transaction execution.                                                                                                                                                                                                                                                                                  |
| feeRatio           | uint8 (Go)                                | Fee ratio of the fee payer. The valid range is between 1 and 99. Zero(0) is not allowed. 100 and above are not allowed as well.                                                                                                                                                                                                                    |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, feeRatio]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, feeRatio]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, feeRatio, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, feeRatio, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf861b85cf85a328204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b21e018080
SigHash 0x1eeea77acecdd102a070ead80a00f388e039c11d813e6d4a63ec90bd0186b210
Signature f845f84326a074ccfee18dc28932396b85617c53784ee366303bce39a2401d8eb602cf73766fa04c937a5ab9401d2cacb3f39ba8c29dbcd44588cc5c7d0b6b4113cfa7b7d9427b
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf876b85cf85a328204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b21e945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0x8a13f42530219cddb490108e38c48e7b58bc02a82f4d797d8f4d85eb16f6d6a5
SignatureFeePayer f845f84325a04a4997524694d535976d7343c1e3a260f99ba53fcb5477e2b96216ec96ebb565a00f8cb31a35399d2b0fbbfa39f259c819a15370706c0449952c7cfc682d200d7c
TxHashRLP 0x32f8fc8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b21ef845f84326a074ccfee18dc28932396b85617c53784ee366303bce39a2401d8eb602cf73766fa04c937a5ab9401d2cacb3f39ba8c29dbcd44588cc5c7d0b6b4113cfa7b7d9427b945a0043070275d9f6054307ee7348bd660849d90ff845f84325a04a4997524694d535976d7343c1e3a260f99ba53fcb5477e2b96216ec96ebb565a00f8cb31a35399d2b0fbbfa39f259c819a15370706c0449952c7cfc682d200d7c
TxHash b204e530f2a7f010d65b6f0f7639d1e9fc8add73e3a0ff1551b11585c36d3bdb
SenderTxHashRLP 0x32f8a08204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b21ef845f84326a074ccfee18dc28932396b85617c53784ee366303bce39a2401d8eb602cf73766fa04c937a5ab9401d2cacb3f39ba8c29dbcd44588cc5c7d0b6b4113cfa7b7d9427b
SenderTxHash d5e22319cbf020d422d8ba3a07da9d99b9300826637af85b4e061805dcb2c1b0

    TX(b204e530f2a7f010d65b6f0f7639d1e9fc8add73e3a0ff1551b11585c36d3bdb)
    Type:          TxTypeFeeDelegatedSmartContractExecutionWithRatio
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    To:            0x7b65B75d204aBed71587c9E519a89277766EE1d0
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Value:         0xa
    Data:          363335333538366230303030303030303030303030303030303030303030303062633539353166303535613835663431613362363266643666363861623764653736643239396232
    Signature:     [{"V":"0x26","R":"0x74ccfee18dc28932396b85617c53784ee366303bce39a2401d8eb602cf73766f","S":"0x4c937a5ab9401d2cacb3f39ba8c29dbcd44588cc5c7d0b6b4113cfa7b7d9427b"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeeRatio:      30
    FeePayerSig:   [{"V":"0x25","R":"0x4a4997524694d535976d7343c1e3a260f99ba53fcb5477e2b96216ec96ebb565","S":"0xf8cb31a35399d2b0fbbfa39f259c819a15370706c0449952c7cfc682d200d7c"}]
    Hex:           32f8fc8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0ba46353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b21ef845f84326a074ccfee18dc28932396b85617c53784ee366303bce39a2401d8eb602cf73766fa04c937a5ab9401d2cacb3f39ba8c29dbcd44588cc5c7d0b6b4113cfa7b7d9427b945a0043070275d9f6054307ee7348bd660849d90ff845f84325a04a4997524694d535976d7343c1e3a260f99ba53fcb5477e2b96216ec96ebb565a00f8cb31a35399d2b0fbbfa39f259c819a15370706c0449952c7cfc682d200d7c
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "contractAddress": null,
  "feePayer": "0x029fdce0457db02f05c4be9f67b7115cb8ea15ca",
  "feePayerSignatures": [
    {
      "V": "0x26",
      "R": "0xfd7cbb13af34814ae5072b7078e9d98ca1806859f452c7369c88fed70150ddee",
      "S": "0x6edee3341b62a2ef1488636a9395bc236ebcdfebc76ee3c933d48a65ea89440e"
    }
  ],
  "feeRatio": "0x42",
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x0",
  "gasUsed": "0xc444",
  "input": "0x6353586b0000000000000000000000000fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0xf",
  "senderTxHash": "0x5545f40855ac02770f8738629d2e81bd3d04df3d90bb2b6e676a10e747c0d946",
  "signatures": [
    {
      "V": "0x26",
      "R": "0xaf1fdf0874424ed6d86b1408d24e2dff36046669cf9d99282bec4a50713adfa6",
      "S": "0x20f25bf30b0d906cee734396914a5497076a7f50ce83954b09c9f46415af8f1"
    }
  ],
  "status": "0x1",
  "to": "0x636f6e74726163742e6b6c6179746e0000000000",
  "transactionHash": "0xc4af8d6b3353ad3ad240a747d185a094c6e751373c3c08c669eb37c50f01b7b1",
  "transactionIndex": "0x8",
  "type": "TxTypeFeeDelegatedSmartContractExecutionWithRatio",
  "typeInt": 50,
  "value": "0xa"
}
```

## TxTypeFeeDelegatedAccountUpdateWithRatio <a href="#txtypefeedelegatedaccountupdatewithratio" id="txtypefeedelegatedaccountupdatewithratio"></a>

TxTypeFeeDelegatedAccountUpdateWithRatio updates the key of the given account. The given ratio of the transaction fee is paid by the fee payer. The following changes will take place by this transaction type.

1. The fee payer's balance decreases by the fee ratio of the amount of the transaction fee.
2. The sender's balance decreases by the remaining transaction fee. e.g., If the `feeRatio` is 30, 30% of the fee will be paid by the fee payer, and the remaining 70% of the fee will be paid by the sender.
3. The sender's nonce increases by one.
4. The account's key is updated with `key`.
5. Transactions sent from the account afterward will be validated with this `key`, once this transaction is executed.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                                      | Description                                                                                                                                                                                                                                                                                                                      |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedAccountUpdateWithRatio. This must be 0x22.                                                                                                                                                                                                                                                         |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                               |
| gasPrice           | \*big.Int (Go)                            | A multiplier to get how much the sender will pay in tokens. The amount of tokens the sender will pay is calculated via `gas` \* `gasPrice`. For example, the sender will pay 10 KLAY for a transaction fee if gas is 10 and gasPrice is 10^18. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                                         |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                               |
| key                | AccountKey (Go)                           | [AccountKey](/content/klaytn/design/accounts#account-key) to be updated to the account.                                                                                                                                                                                                                                          |
| feeRatio           | uint8 (Go)                                | Fee ratio of the fee payer. The valid range is between 1 and 99. Zero(0) is not allowed. 100 and above are not allowed as well.                                                                                                                                                                                                  |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                 |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                    |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                      |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, from, rlpEncodedKey, feeRatio]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from, rlpEncodedKey, feeRatio]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, rlpEncodedKey, feeRatio, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, from, rlpEncodedKey, feeRatio, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf84ab845f843228204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d1e018080
SigHash 0x706ba7cd01e44008077a2abeafc3aacd64cbf210f49c64983f295a2e4cc03216
Signature f845f84326a00e5929f96dec2b41343a9e6f0150eef08741fe7dcece88cc5936c49ed19051dca05a07b07017190e0baba32bdf6352f5a358a2798ed3c56e704a63819b87cf8e3f
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf85fb845f843228204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d1e945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0xd2a51cefec667747890e6bd11fd068e8796b5446f77e152367eaa3cf98c96b30
SignatureFeePayer f845f84326a0cf8d102de7c6b0a41d3f02aefb7e419522341734c98af233408298d0c424c04ba00286f89cab4668f728d7c269997116a49b80cec8776fc64e60588a9268571e35
TxHashRLP 0x22f8e58204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d1ef845f84326a00e5929f96dec2b41343a9e6f0150eef08741fe7dcece88cc5936c49ed19051dca05a07b07017190e0baba32bdf6352f5a358a2798ed3c56e704a63819b87cf8e3f945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0cf8d102de7c6b0a41d3f02aefb7e419522341734c98af233408298d0c424c04ba00286f89cab4668f728d7c269997116a49b80cec8776fc64e60588a9268571e35
TxHash 276f02c25ca4ced081dcfbb836755ced574993b047e648a583ed8d4144b3813f
SenderTxHashRLP 0x22f8898204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d1ef845f84326a00e5929f96dec2b41343a9e6f0150eef08741fe7dcece88cc5936c49ed19051dca05a07b07017190e0baba32bdf6352f5a358a2798ed3c56e704a63819b87cf8e3f
SenderTxHash e1d87538509549f4a1eb418f986bc53dc77b7eec3b2150f75cd787951d3e4b7f

    TX(276f02c25ca4ced081dcfbb836755ced574993b047e648a583ed8d4144b3813f)
    Type:          TxTypeFeeDelegatedAccountUpdateWithRatio
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Key:           AccountKeyPublic: S256Pubkey:{"x":"0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d","y":"0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3"}
    Signature:     [{"V":"0x26","R":"0xe5929f96dec2b41343a9e6f0150eef08741fe7dcece88cc5936c49ed19051dc","S":"0x5a07b07017190e0baba32bdf6352f5a358a2798ed3c56e704a63819b87cf8e3f"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeeRatio:      30
    FeePayerSig:   [{"V":"0x26","R":"0xcf8d102de7c6b0a41d3f02aefb7e419522341734c98af233408298d0c424c04b","S":"0x286f89cab4668f728d7c269997116a49b80cec8776fc64e60588a9268571e35"}]
    Hex:           22f8e58204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0ba302a1033a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d1ef845f84326a00e5929f96dec2b41343a9e6f0150eef08741fe7dcece88cc5936c49ed19051dca05a07b07017190e0baba32bdf6352f5a358a2798ed3c56e704a63819b87cf8e3f945a0043070275d9f6054307ee7348bd660849d90ff845f84326a0cf8d102de7c6b0a41d3f02aefb7e419522341734c98af233408298d0c424c04ba00286f89cab4668f728d7c269997116a49b80cec8776fc64e60588a9268571e35
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "contractAddress": null,
  "feePayer": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "feePayerSignatures": [
    {
      "V": "0x25",
      "R": "0xfa3690925bae82ba662abe6d3af8993b7a7994d9f922cb1ae83c59c4a26a3b70",
      "S": "0x2bd481ddf40cb813dde5f67db0e3a6ad9ea46758ef97580a709b301c21530246"
    }
  ],
  "feeRatio": "0xb",
  "from": "0x636f6c696e332e6b6c6179746e00000000000000",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "gasUsed": "0xdac0",
  "key": "0x02a102c8785266510368d9372badd4c7f4a94b692e82ba74e0b5e26b34558b0f081447",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x0",
  "senderTxHash": "0x74be8f01f10a497dbe9ed10659ac8c4579b37f8b5022b9f7eec6362262d44845",
  "signatures": [
    {
      "V": "0x25",
      "R": "0xd17d2ae2290b35c560289797c955fa5dc1cc25606cfd198584665917da6795ff",
      "S": "0x7bc0450ff7319ccdbf50d38095501b895717cac775c6897d2381e7182aa25742"
    }
  ],
  "status": "0x1",
  "transactionHash": "0x90ccbf85ffd1f7e74620840fd9d270e030c6719e3c7b70bb8796c1cedf02fe88",
  "transactionIndex": "0x1",
  "type": "TxTypeFeeDelegatedAccountUpdateWithRatio",
  "typeInt": 34
}
```

## TxTypeFeeDelegatedCancelWithRatio <a href="#txtypefeedelegatedcancelwithratio" id="txtypefeedelegatedcancelwithratio"></a>

TxTypeFeeDelegatedCancelWithRatio cancels the execution of the transaction with the same nonce in the transaction pool. For more details, see [TxTypeCancel](/content/klaytn/design/transactions/basic#txtypecancel).

The following changes will apply by this transaction type. 1. The fee payer's balance decreases by the given fee ratio of the amount of the transaction fee. 2. The sender's balance decreases by the remaining transaction fee. 3. The sender's nonce increases by one.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Description                               | Type                                                                                                                                                                                                                                                                                                                                               |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedCancelWithRatio. This must be 0x3a.                                                                                                                                                                                                                                                                                  |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                                                           |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| feeRatio           | uint8 (Go)                                | Fee ratio of the fee payer. The valid range is between 1 and 99. Zero(0) is not allowed. 100 and above are not allowed as well.                                                                                                                                                                                                                    |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, from, feeRatio]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <the sender's private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from, feeRatio]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, feeRatio, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPricke, gas, from, feeRatio, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x1
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xe4a0df3a8204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0b1e018080
SigHash 0xeccd1585e8e105bc034a72190c3e9312b5407736686aa0d34b1ad75320871014
Signature f845f84326a072efa47960bef40b536c72d7e03ceaf6ca5f6061eb8a3eda3545b1a78fe52ef5a062006ddaf874da205f08b3789e2d014ae37794890fc2e575bf75201563a24ba9
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf839a0df3a8204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0b1e945a0043070275d9f6054307ee7348bd660849d90f018080
SigHashFeePayer 0xf71b0b22d72ef59a063a865ee844e1ba0a103d707f06fb7013b3372ed169c705
SignatureFeePayer f845f84326a06ba5ef20c3049323fc94defe14ca162e28b86aa64f7cf497ac8a5520e9615614a04a0a0fc61c10b416759af0ce4ce5c09ca1060141d56d958af77050c9564df6bf
TxHashRLP 0x3af8c18204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0b1ef845f84326a072efa47960bef40b536c72d7e03ceaf6ca5f6061eb8a3eda3545b1a78fe52ef5a062006ddaf874da205f08b3789e2d014ae37794890fc2e575bf75201563a24ba9945a0043070275d9f6054307ee7348bd660849d90ff845f84326a06ba5ef20c3049323fc94defe14ca162e28b86aa64f7cf497ac8a5520e9615614a04a0a0fc61c10b416759af0ce4ce5c09ca1060141d56d958af77050c9564df6bf
TxHash 63604ebf68bfee51b2e3f54ddb2f19f9ea72d32b3fc70877324531ecda25817a
SenderTxHashRLP 0x3af8658204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0b1ef845f84326a072efa47960bef40b536c72d7e03ceaf6ca5f6061eb8a3eda3545b1a78fe52ef5a062006ddaf874da205f08b3789e2d014ae37794890fc2e575bf75201563a24ba9
SenderTxHash c0818be4cffbacfe29be1134e0267e10fd1afb6571f4ccc95dcc67a788bab5e7

    TX(63604ebf68bfee51b2e3f54ddb2f19f9ea72d32b3fc70877324531ecda25817a)
    Type:          TxTypeFeeDelegatedCancelWithRatio
    From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
    Nonce:         1234
    GasPrice:      0x19
    GasLimit:      0xf4240
    Signature:     [{"V":"0x26","R":"0x72efa47960bef40b536c72d7e03ceaf6ca5f6061eb8a3eda3545b1a78fe52ef5","S":"0x62006ddaf874da205f08b3789e2d014ae37794890fc2e575bf75201563a24ba9"}]
    FeePayer:      0x5A0043070275d9f6054307Ee7348bD660849D90f
    FeeRatio:      30
    FeePayerSig:   [{"V":"0x26","R":"0x6ba5ef20c3049323fc94defe14ca162e28b86aa64f7cf497ac8a5520e9615614","S":"0x4a0a0fc61c10b416759af0ce4ce5c09ca1060141d56d958af77050c9564df6bf"}]
    Hex:           3af8c18204d219830f424094a94f5374fce5edbc8e2a8697c15331677e6ebf0b1ef845f84326a072efa47960bef40b536c72d7e03ceaf6ca5f6061eb8a3eda3545b1a78fe52ef5a062006ddaf874da205f08b3789e2d014ae37794890fc2e575bf75201563a24ba9945a0043070275d9f6054307ee7348bd660849d90ff845f84326a06ba5ef20c3049323fc94defe14ca162e28b86aa64f7cf497ac8a5520e9615614a04a0a0fc61c10b416759af0ce4ce5c09ca1060141d56d958af77050c9564df6bf
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
  "blockHash": "0x82983fe294d286e76486760e6904369285554e1744af16786c2393a956fb4ec4",
  "blockNumber": "0x2",
  "contractAddress": null,
  "feePayer": "0x029fdce0457db02f05c4be9f67b7115cb8ea15ca",
  "feePayerSignatures": [
    {
      "V": "0x25",
      "R": "0x26c8b5038e9f7ff580f3323b8a06b6eb1b6ab13cac11c30de6c9b64230bdb992",
      "S": "0x6c4be67ace8551237e675da2b7b32ec2d7d7e07abf2eb299ebec6cc444460e13"
    }
  ],
  "feeRatio": "0x58",
  "from": "0x0fcda0f2efbe1b4e61b487701ce4f2f8abc3723d",
  "gas": "0x174876e800",
  "gasPrice": "0x0",
  "gasUsed": "0x8ca0",
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x12",
  "senderTxHash": "0xc9d2f558f6883bfea5113ce900499354fcb0004ff901dec51db7a5d80c3a7868",
  "signatures": [
    {
      "V": "0x26",
      "R": "0x88a484d1cc59824e05b933348df6ebe7b82ac68766a85e2aa5636c136ee2834c",
      "S": "0x104fee953e1a015f26b35da57acf15aa01eb5c6c0e79965200c3fe813003a4fe"
    }
  ],
  "status": "0x1",
  "transactionHash": "0x50c6840fee3297a8ff745025cb4fd27a7e662395620ad615458ea22034f37f6c",
  "transactionIndex": "0xb",
  "type": "TxTypeFeeDelegatedCancelWithRatio",
  "typeInt": 58
}
```

## TxTypeFeeDelegatedChainDataAnchoringWithRatio <a href="#txtypefeedelegatedchaindataanchoringwithratio" id="txtypefeedelegatedchaindataanchoringwithratio"></a>

TxTypeFeeDelegatedChainDataAnchoringWithRatio is a fee-delegated transaction, with the ratio, that anchors service chain data to the Klaytn mainchain. Service chains periodically send this type of transaction to the Klaytn mainchain to ensure its security and credibility of data. For more details about the data anchoring, see [Anchoring](/content/installation-guide/deployment/service-chain/references/anchoring). As it is a fee-delegated transaction with the given ratio as well, the fee payer bears only the given portion of the transaction fee based on the given ratio and the sender pays the rest. Be mindful that it is not allowed to send this transaction via RPC. Currently, this transaction is executed through private p2p channels for security reasons. This transaction does not change the state of the Klaytn blockchain except the sender's nonce being increased by one.

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute          | Type                                      | Description                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | uint8 (Go)                                | The type of TxTypeFeeDelegatedChainDataAnchoringWithRatio. This must be 0x4a.                                                                                                                                                                                                                                                                      |
| nonce              | uint64 (Go)                               | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                                                                 |
| gasPrice           | \*big.Int (Go)                            | A unit price of gas in `peb` the sender will pay for a transaction fee. The amount of transaction fee is calculated as `gas` \* `gasPrice`. For example, if the transaction consumes 10 units of gas and gasPrice is 10^18, the transaction fee will be 10 KLAY. See [Unit of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay). |
| gas                | uint64 (Go)                               | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                                                           |
| from               | common.Address (Go)                       | The address of the sender. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                 |
| feeRatio           | uint8 (Go)                                | Fee ratio of the fee payer. The valid range is between 1 and 99. Zero(0) is not allowed. 100 and above are not allowed as well.                                                                                                                                                                                                                    |
| input              | \[]byte (Go)                              | Data of the service chain.                                                                                                                                                                                                                                                                                                                         |
| txSignatures       | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The sender's signatures. For more details, see [Signature Validation of Transactions](/content/klaytn/design/transactions#signature-validation-of-transactions).                                                                                                                                                                                   |
| feePayer           | common.Address (Go)                       | The address of the fee payer.                                                                                                                                                                                                                                                                                                                      |
| feePayerSignatures | \[]{\*big.Int, \*big.Int, \*big.Int} (Go) | The fee payer's signatures.                                                                                                                                                                                                                                                                                                                        |

### RLP Encoding for Signature of the Sender <a href="#rlp-encoding-for-signature-of-the-sender" id="rlp-encoding-for-signature-of-the-sender"></a>

To make a signature of the sender, RLP serialization should be done like the following:

```javascript
SigRLP = encode([encode([type, nonce, gasPrice, gas, from, anchoredData, feeRatio]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for Signature of the Fee Payer <a href="#rlp-encoding-for-signature-of-the-fee-payer" id="rlp-encoding-for-signature-of-the-fee-payer"></a>

To make a signature of the fee payer, RLP serialization should be done like the following:

```javascript
SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from, anchoredData, feeRatio]), feePayer, chainid, 0, 0])
SigFeePayerHash = keccak256(SigFeePayerRLP)
SignatureFeePayer = sign(SigFeePayerHash, <the fee payer's private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To make a SenderTxHash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, anchoredData, feeRatio, txSignatures])
SenderTxHash = keccak256(SenderTxHashRLP)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, RLP serialization should be done like the following:

```javascript
txSignatures (a single signature) = [[v, r, s]]
txSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
feePayerSignatures (a single signature) = [[v, r, s]]
feePayerSignatures (two signatures) = [[v1, r1, s1], [v2, r2, s2]]
TxHashRLP = type + encode([nonce, gasPrice, gas, from, anchoredData, feeRatio, txSignatures, feePayer, feePayerSignatures])
TxHash = keccak256(TxHashRLP)
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of RLP serialization and the transaction object:

```javascript
ChainID 0x01
PrivateKey 0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8
PublicKey.X 0x3a514176466fa815ed481ffad09110a2d344f6c9b78c1d14afc351c3a51be33d
PublicKey.Y 0x8072e77939dc03ba44790779b7a1025baf3003f6732430e20cd9b76d953391b3
SigRLP 0xf8dcb8d7f8d54a128505d21dba0085174876e80094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8aff8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000405800658018080
SigHash 0xd79dbb964bee2d3807e214a247141a1fcb066a67de99e90750aac4a2a0b776de
Signature 0xf845f84326a0c612a243bcb3b98958e9cce1a0bc0e170291b33a7f0dbfae4b36dafb5806797da00c734423492ecc21cc53238147c359676fcec43fcc2a0e021d87bb1da49f0abf
FeePayerPrivateKey 0xb9d5558443585bca6f225b935950e3f6e69f9da8a5809a83f51c3365dff53936
FeePayerPublicKey.X 0x327434d4cfc66ef8857d431419e9deebdc53a3e415edcc55382e2d417b8dd102
FeePayerPublicKey.Y 0x65fc97045707faf7b8f81ac65089d4cc71f69ad0bf1bc8559bc24f13fc284ced
SigRLPFeePayer 0xf8f1b8d7f8d54a128505d21dba0085174876e80094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8aff8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000004058006589433f524631e573329a550296f595c820d6c65213f018080
SigHashFeePayer 0xa824ff743912239d0665d2fd43a66d57138c92834e9d338b66bcca4a0bee8fbd
SignatureFeePayer 0xf845f84325a0a3e40598b67e2bcbaa48fdd258b9d1dcfcc9cc134972560ba042430078a769a5a06707ea362e588e4e5869cffcd5a058749d823aeff13eb95dc1146faff561df32
TxHashRLP 0x4af90177128505d21dba0085174876e80094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8aff8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000405800658f845f84326a0c612a243bcb3b98958e9cce1a0bc0e170291b33a7f0dbfae4b36dafb5806797da00c734423492ecc21cc53238147c359676fcec43fcc2a0e021d87bb1da49f0abf9433f524631e573329a550296f595c820d6c65213ff845f84325a0a3e40598b67e2bcbaa48fdd258b9d1dcfcc9cc134972560ba042430078a769a5a06707ea362e588e4e5869cffcd5a058749d823aeff13eb95dc1146faff561df32
TxHash 0xc01a7c3ece18c115b58d7747669ec7c31ec5ab031a88cb49ad85a31f6dbbf915
SenderTxHashRLP 0x4af9011b128505d21dba0085174876e80094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8aff8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000405800658f845f84326a0c612a243bcb3b98958e9cce1a0bc0e170291b33a7f0dbfae4b36dafb5806797da00c734423492ecc21cc53238147c359676fcec43fcc2a0e021d87bb1da49f0abf
SenderTxHash 0xa0670c01fe39feb2d2442adf7df1957ade3c5abcde778fb5edf99c80c06aa53c

	TX(c01a7c3ece18c115b58d7747669ec7c31ec5ab031a88cb49ad85a31f6dbbf915)
	Type:          TxTypeFeeDelegatedChainDataAnchoringWithRatio
	From:          0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B
	Nonce:         18
	GasPrice:      0x5d21dba00
	GasLimit:      0x174876e800
	AnchoredData:  f8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000004058006
	Signature:     [{"V":"0x26","R":"0xc612a243bcb3b98958e9cce1a0bc0e170291b33a7f0dbfae4b36dafb5806797d","S":"0xc734423492ecc21cc53238147c359676fcec43fcc2a0e021d87bb1da49f0abf"}]
	FeePayer:      0x33f524631e573329a550296F595c820D6c65213f
	FeeRatio:      88
	FeePayerSig:   [{"V":"0x25","R":"0xa3e40598b67e2bcbaa48fdd258b9d1dcfcc9cc134972560ba042430078a769a5","S":"0x6707ea362e588e4e5869cffcd5a058749d823aeff13eb95dc1146faff561df32"}]
	Hex:           4af90177128505d21dba0085174876e80094a94f5374fce5edbc8e2a8697c15331677e6ebf0bb8aff8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000405800658f845f84326a0c612a243bcb3b98958e9cce1a0bc0e170291b33a7f0dbfae4b36dafb5806797da00c734423492ecc21cc53238147c359676fcec43fcc2a0e021d87bb1da49f0abf9433f524631e573329a550296f595c820d6c65213ff845f84325a0a3e40598b67e2bcbaa48fdd258b9d1dcfcc9cc134972560ba042430078a769a5a06707ea362e588e4e5869cffcd5a058749d823aeff13eb95dc1146faff561df32
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

```javascript
{
    "blockHash": "0xee6c72b7d99019a941b47d77507abe015c3f00d3ff9122a2eec33d846107b842",
    "blockNumber": "0x2",
    "contractAddress": null,
    "feePayer": "0x33f524631e573329a550296f595c820d6c65213f",
    "feePayerSignatures": [
        {
            "V": "0x25",
            "R": "0xa3e40598b67e2bcbaa48fdd258b9d1dcfcc9cc134972560ba042430078a769a5",
            "S": "0x6707ea362e588e4e5869cffcd5a058749d823aeff13eb95dc1146faff561df32"
        }
    ],
    "feeRatio": "0x58",
    "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
    "gas": "0x174876e800",
    "gasPrice": "0x5d21dba00",
    "gasUsed": "0xd0fc",
    "input": "0xf8ad80b8aaf8a8a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000004058006",
    "logs": [],
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "nonce": "0x12",
    "senderTxHash": "0xa0670c01fe39feb2d2442adf7df1957ade3c5abcde778fb5edf99c80c06aa53c",
    "signatures": [
        {
            "V": "0x26",
            "R": "0xc612a243bcb3b98958e9cce1a0bc0e170291b33a7f0dbfae4b36dafb5806797d",
            "S": "0xc734423492ecc21cc53238147c359676fcec43fcc2a0e021d87bb1da49f0abf"
        }
    ],
    "status": "0x1",
    "transactionHash": "0xc01a7c3ece18c115b58d7747669ec7c31ec5ab031a88cb49ad85a31f6dbbf915",
    "transactionIndex": "0xb",
    "type": "TxTypeFeeDelegatedChainDataAnchoringWithRatio",
    "typeInt": 74
}
```


# Ethereum

Klaytn provides wrapped transaction types to support Ethereum compatibility. Ethereum transaction types in Klaytn have the same attributes and RLP encoding schemes with Ethereum's design except for the single-byte type delimiter called `EthereumTxTypeEnvelope`. Therefore, users can successfully deploy transactions generated by Ethereum development tools on Klaytn. The type delimiter is also omitted when users use `eth` namespace APIs, so they can use Klaytn just as if they were using Ethereum. Using `klay` namespace APIs, users can deploy and retrieve Ethereum formatted transactions as a type of Klaytn transactions without getting confused with the existing Klaytn transaction types.

## EthereumTxTypeEnvelope <a href="#ethereumtxtypeenvelope" id="ethereumtxtypeenvelope"></a>

EthereumTxTypeEnvelope is a single-byte prefix for raw transactions that denotes Ethereum transaction types. Ethereum has adopted an extendable transaction type scheme from [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) and it uses a type numbering system that conflicts with Klaytn's. To resolve the conflict between two different transaction type schemes, Klaytn has introduced `EthereumTxTypeEnvelope` which allows for separation and expansion for future Ethereum transaction types.

`EthereumTxTypeEnvelope` is an additional type delimiter and used only for raw transactions and type numbering. It is not used for transaction hash or signature hash. For that purpose, `EthereumTransactionType` as defined in EIPs is used.

* EthereumTxTypeEnvelope: `0x78`
* TxHashRLP : EthereumTransactionType || TransactionPayload
* RawTransaction : EthereumTxTypeEnvelope || EthereumTransactionType || TransactionPayload

## TxTypeEthereumAccessList <a href="#txtypeethereumaccesslist" id="txtypeethereumaccesslist"></a>

`TxTypeEthereumAccessList` represents a type of Ethereum transaction specified in [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930). This transactions type contains an access list, a list of addresses and storage keys that the transaction is supposed to access. Since this transaction type exists to support compatibility, it only works with EOAs associated with \[AccountKeyLegacy]. EOAs associated with other account key types should use other transaction types such as `TxTypeValueTransfer`, `TxTypeSmartContractExecution`, and so on. This transaction type can create accounts, transfer tokens, deploy/execute smart contracts or a mix of the aforementioned.

{% hint style="success" %}
NOTE: Klaytn networks can process this transaction type after the `EthTxTypeCompatibleBlock`
{% endhint %}

{% hint style="success" %}
NOTE: This transaction type only supports the format of the Ethereum transaction type. Unlike [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930), there are no benefits in terms of transaction fee from using access list.
{% endhint %}

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute  | Type                  | Description                                                                                                                                                                                                                                                         |
| ---------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type       | uint8 (Go)            | The type of `TxTypeEthereumAccessList` that is a concatenation of `EthereumTxTypeEnvelope` and `EthereumTransactionType`. This must be 0x7801.                                                                                                                      |
| chainId    | \*big.Int (Go)        | The destination chain ID.                                                                                                                                                                                                                                           |
| nonce      | uint64 (Go)           | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                  |
| gasPrice   | \*big.Int (Go)        | A multiplier to get how much the sender will pay in tokens. The amount of tokens the sender will pay is calculated via `gas` \* `gasPrice`. For example, the sender will pay 10 KLAY for a transaction fee if gas is 10 and gasPrice is 10^18. See \[Unit of KLAY]. |
| gas        | uint64 (Go)           | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                            |
| to         | \*common.Address (Go) | The account address that will receive the transferred value.                                                                                                                                                                                                        |
| value      | \*big.Int (Go)        | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                      |
| data       | \[]byte (Go)          | Data attached to the transaction, used for transaction execution.                                                                                                                                                                                                   |
| accessList | type.AccessList (Go)  | A list of addresses and storage keys consisting of \[]\(common.Address, \[]common.Hash).                                                                                                                                                                            |
| v, r, s    | \*big.Int (Go)        | The cryptographic signature generated by the sender to let the receiver obtain the sender's address.                                                                                                                                                                |

### RLP Encoding for Signature <a href="#rlp-encoding-for-signature" id="rlp-encoding-for-signature"></a>

To make a signature for this transaction type, the RLP serialization proceeds as follows:

{% hint style="success" %}
NOTE: This type of transaction should be signed with London Signer
{% endhint %}

```javascript
SigRLP = EthereumTransactionType || encode([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To obtain `SenderTxHash` for this transaction type, the RLP serialization proceeds as follows:

```javascript
SenderTxHashRLP = EthereumTransactionType || encode([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, v, r, s])
SenderTxHash = keccak256(SenderTxHashRLP)
Signature = sign(SenderTxHash, <private key>)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To make a transaction hash, the RLP serialization proceeds as follows:

```javascript
TxHashRLP = EthereumTransactionType || encode([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, v, r, s])
TxHash = keccak256(TxHashRLP)
```

### Raw Transaction <a href="#raw-transaction" id="raw-transaction"></a>

```javascript
RawTx = EthereumTxTypeEnvelope || EthereumTransactionType || encode([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, v, r, s])
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of the RLP serialization and the transaction object:

```javascript
    TX(3a3ab67168de40b1f8a2141a70a4e2f551f90d7814b2fbcb3ac99ad8d8d0b641)
    Contract: false
    Chaind:   0x2
    From:     a94f5374fce5edbc8e2a8697c15331677e6ebf0b
    To:       7b65b75d204abed71587c9e519a89277766ee1d0
    Nonce:    1234
    GasPrice: 0x19
    GasLimit  0xf4240
    Value:    0xa
    Data:     0x31323334
    AccessList: [{0000000000000000000000000000000000000001 [0000000000000000000000000000000000000000000000000000000000000000]}]
    V:        0x1
    R:        0xbfc80a874c43b71b67c68fa5927d1443407f31aef4ec6369bbecdb76fc39b0c0
    S:        0x193e62c1dd63905aee7073958675dcb45d78c716a9a286b54a496e82cb762f26
    Hex:      7801f8a1028204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a8431323334f838f7940000000000000000000000000000000000000001e1a0000000000000000000000000000000000000000000000000000000000000000001a0bfc80a874c43b71b67c68fa5927d1443407f31aef4ec6369bbecdb76fc39b0c0a0193e62c1dd63905aee7073958675dcb45d78c716a9a286b54a496e82cb762f26
        

```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

The return of `eth_getTransactionByHash`

```javascript
{
  "blockHash": "0x7bd7e8a92ecaa5781a15a8b6fff589f8ac8a79325b517a1ba5d5f2f3d7af1b00",
  "blockNumber": "0x1c8f4b",
  "from": "0x5618e15ec2916bbe6cf2cce20ce31e61d6062cac",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "hash": "0x3f67e48c2090f560234f555cd4edf7853b6327aa9a6a795be1efe3f360dac118",
  "input": "0x1122",
  "nonce": "0x11",
  "to": "0x5dce87b5bfcde54023811b168dc97a9f10913957",
  "transactionIndex": "0x0",
  "value": "0x186a0",
  "type": "0x1",
  "accessList": [
      {
          "address": "0x0000000000000000000000000000000000000001",
          "storageKeys": [
              "0x0000000000000000000000000000000000000000000000000000000000000000"
          ]
      }
  ],
  "chainId": "0x2710",
  "v": "0x1",
  "r": "0xebb2d2144293c257e27aaa1d22156f322b0d2d7385257f186c117899d791f174",
  "s": "0x5cea970287c9f0f9754050a552c458c066d8f3b3e4639f561b22ce4cb7553ac0"
}
```

The return of `klay_getTransactionByHash`

```javascript
{
  "accessList": [
      {
          "address": "0x0000000000000000000000000000000000000001",
          "storageKeys": [
              "0x0000000000000000000000000000000000000000000000000000000000000000"
          ]
      }
  ],
  "blockHash": "0x7bd7e8a92ecaa5781a15a8b6fff589f8ac8a79325b517a1ba5d5f2f3d7af1b00",
  "blockNumber": "0x1c8f4b",
  "chainID": "0x2710",
  "from": "0x5618e15ec2916bbe6cf2cce20ce31e61d6062cac",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "hash": "0x3f67e48c2090f560234f555cd4edf7853b6327aa9a6a795be1efe3f360dac118",
  "input": "0x1122",
  "nonce": "0x11",
  "senderTxHash": "0x3f67e48c2090f560234f555cd4edf7853b6327aa9a6a795be1efe3f360dac118",
  "signatures": [
      {
          "V": "0x1",
          "R": "0xebb2d2144293c257e27aaa1d22156f322b0d2d7385257f186c117899d791f174",
          "S": "0x5cea970287c9f0f9754050a552c458c066d8f3b3e4639f561b22ce4cb7553ac0"
      }
  ],
  "to": "0x5dce87b5bfcde54023811b168dc97a9f10913957",
  "transactionIndex": "0x0",
  "type": "TxTypeEthereumAccessList",
  "typeInt": 30721,
  "value": "0x186a0"
}
```

## TxTypeEthereumDynamicFee <a href="#txtypeethereumdynamicfee" id="txtypeethereumdynamicfee"></a>

`TxTypeEthereumDynamicFee` represents a type of Ethereum transaction specified in [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559). This transaction type contains `gasTipCap` and `gasFeeCap` instead of `gasPrice`. Since this transaction type exists to support compatibility, it only works with EOAs associated with \[AccountKeyLegacy]. EOAs associated with other account key types should use other transaction types such as `TxTypeValueTransfer`, `TxTypeSmartContractExecution`, and so on. This type of transaction can create accouns, transfer tokens, deploy/execute smart contracts, or a mix of the aforementioned.

{% hint style="success" %}
NOTE: Klaytn networks can process this transaction type after the `EthTxTypeCompatibleBlock`
{% endhint %}

{% hint style="success" %}
NOTE: Currently, this type of transaction only supports the format of the Ethereum transaction type. Unlike [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930), there are no benefits in terms of transaction fees from using access list.
{% endhint %}

{% hint style="success" %}
NOTE: Since Klaytn has a fixed gas price, `gasTipCap` and `gasFeeCap` should take the gas price for the respective network, which is 250 ston at the time of writing.
{% endhint %}

### Attributes <a href="#attributes" id="attributes"></a>

| Attribute  | Type                  | Description                                                                                                                                                                                                                                                                                                  |
| ---------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| type       | uint8 (Go)            | The type of `TxTypeEthereumDynamicFee` that is a concatenation of `EthereumTxTypeEnvelope` and `EthereumTransactionType`. It must be `0x7802`.                                                                                                                                                               |
| chainId    | \*big.Int (Go)        | The destination chain ID.                                                                                                                                                                                                                                                                                    |
| nonce      | uint64 (Go)           | A value used to uniquely identify a sender’s transaction. If two transactions with the same nonce are generated by a sender, only one is executed.                                                                                                                                                           |
| gasTipCap  | \*big.Int (Go)        | A multiplier to get how much the sender will pay in addition to `baseFee`. Since Klaytn has a fixed gas price, `gasTipCap` and `gasFeeCap` should take the gas price for the respective network, which is 250 ston at the time of writing.                                                                   |
| gasFeeCap  | \*big.Int (Go)        | A multiplier to get how much the sender will pay in tokens. The amount of tokens the sender will pay is calculated via `gas` \* `gasFeeCap`. Since Klaytn has a fixed gas price, `gasTipCap` and `gasFeeCap` should take the gas price for the respective network, which is 250 ston at the time of writing. |
| gas        | uint64 (Go)           | The maximum amount of transaction fee the transaction is allowed to use.                                                                                                                                                                                                                                     |
| to         | \*common.Address (Go) | The account address that will receive the transferred value.                                                                                                                                                                                                                                                 |
| value      | \*big.Int (Go)        | The amount of KLAY in `peb` to be transferred.                                                                                                                                                                                                                                                               |
| data       | \[]byte (Go)          | Data attached to the transaction, used for transaction execution.                                                                                                                                                                                                                                            |
| accessList | type.AccessList (Go)  | A list of addresses and storage keys consisting of \[]\(common.Address, \[]common.Hash).                                                                                                                                                                                                                     |
| v, r, s    | \*big.Int (Go)        | The cryptographic signature generated by the sender to let the receiver obtain the sender's address.                                                                                                                                                                                                         |

### RLP Encoding for Signature <a href="#rlp-encoding-for-signature" id="rlp-encoding-for-signature"></a>

To make a signature for this transaction type, the RLP serialization proceeds as follows:

{% hint style="success" %}
NOTE: This type of transaction should be signed with London Signer
{% endhint %}

```javascript
SigRLP = EthereumTransactionType || encode([chainId, nonce, gasTipCap, gasFeeCap, gasLimit, to, value, data, accessList])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
```

### RLP Encoding for SenderTxHash <a href="#rlp-encoding-for-sendertxhash" id="rlp-encoding-for-sendertxhash"></a>

To obtain `SenderTxHash` for this transaction type, the RLP serialization proceeds as follows:

```javascript
SenderTxHashRLP = EthereumTransactionType || encode([chainId, nonce, gasTipCap, gasFeeCap, gasLimit, to, value, data, accessList, v, r, s])
SenderTxHash = keccak256(SenderTxHashRLP)
Signature = sign(SenderTxHash, <private key>)
```

### RLP Encoding for Transaction Hash <a href="#rlp-encoding-for-transaction-hash" id="rlp-encoding-for-transaction-hash"></a>

To obtain a transaction hash, the RLP serialization proceeds as follows:

```javascript
TxHashRLP = EthereumTransactionType || encode([chainId, nonce, gasTipCap, gasFeeCap, gasLimit, to, value, data, accessList, v, r, s])
TxHash = keccak256(TxHashRLP)
```

### Raw Transaction <a href="#raw-transaction" id="raw-transaction"></a>

```javascript
RawTx = EthereumTxTypeEnvelope || EthereumTransactionType || encode([chainId, nonce, gasTipCap, gasFeeCap, gasLimit, to, value, data, accessList, v, r, s])
```

### RLP Encoding (Example) <a href="#rlp-encoding-example" id="rlp-encoding-example"></a>

The following shows the result of the RLP serialization and the transaction object:

```javascript
    TX(be74e122acf00c2f257e8698ecf01140b58b2880de3f24d0875730425eccb45a)
    Contract: false
    Chaind:   0x2
    From:     a94f5374fce5edbc8e2a8697c15331677e6ebf0b
    To:       7b65b75d204abed71587c9e519a89277766ee1d0
    Nonce:    1234
    GasTipCap: 0x19
    GasFeeCap: 0x19
    GasLimit  0xf4240
    Value:    0xa
    Data:     0x31323334
    AccessList: [{0000000000000000000000000000000000000001 [0000000000000000000000000000000000000000000000000000000000000000]}]
    V:        0x0
    R:        0xca14aa0bada2da7ca1b143c16e2dd4a69f2a1e77ce54c7f6d440fe828a777f4f
    S:        0x117f0f78aed398b2995b5ee7c67ace25d52be3c72c1384c2aaa9683b351556
    Hex:      7802f8a1028204d21919830f4240947b65b75d204abed71587c9e519a89277766ee1d00a8431323334f838f7940000000000000000000000000000000000000001e1a0000000000000000000000000000000000000000000000000000000000000000080a0ca14aa0bada2da7ca1b143c16e2dd4a69f2a1e77ce54c7f6d440fe828a777f4f9f117f0f78aed398b2995b5ee7c67ace25d52be3c72c1384c2aaa9683b351556
```

### RPC Output (Example) <a href="#rpc-output-example" id="rpc-output-example"></a>

The following shows a transaction object returned via JSON RPC.

The return of `eth_getTransactionByHash`

```javascript
{
  "blockHash": "0x55792fe186e3d1515fe35a68c2c8d7977b2d7db184d80526f906c53222b77833",
  "blockNumber": "0x1c944d",
  "from": "0x5618e15ec2916bbe6cf2cce20ce31e61d6062cac",
  "gas": "0x174876e800",
  "gasPrice": "0x5d21dba00",
  "maxFeePerGas": "0x5d21dba00",
  "maxPriorityFeePerGas": "0x5d21dba00",
  "hash": "0x5db239963029ad9ef6c3331b10ae455638316e330b0efdae2cc1f8e86884e66e",
  "input": "0x1122",
  "nonce": "0x13",
  "to": "0xa0f1633f4c666d7fe5ba912bd5caf03d3655ac31",
  "transactionIndex": "0x0",
  "value": "0x186a0",
  "type": "0x2",
  "accessList": [
      {
          "address": "0x0000000000000000000000000000000000000001",
          "storageKeys": [
              "0x0000000000000000000000000000000000000000000000000000000000000000"
          ]
      }
  ],
  "chainId": "0x2710",
  "v": "0x1",
  "r": "0x27e007cbe79fd8cc9b89dd798bdd5aa62d038273bf006c7c3b40e13a938ab807",
  "s": "0x6209bb328855f02fa2671fecb41efd9f191b03ecab5e580227fa2a0674879384"
}
```

The return of `klay_getTransactionByHash`

```javascript
{
  "accessList": [
      {
          "address": "0x0000000000000000000000000000000000000001",
          "storageKeys": [
              "0x0000000000000000000000000000000000000000000000000000000000000000"
          ]
      }
  ],
  "blockHash": "0x55792fe186e3d1515fe35a68c2c8d7977b2d7db184d80526f906c53222b77833",
  "blockNumber": "0x1c944d",
  "chainId": "0x2710",
  "from": "0x5618e15ec2916bbe6cf2cce20ce31e61d6062cac",
  "gas": "0x174876e800",
  "hash": "0x5db239963029ad9ef6c3331b10ae455638316e330b0efdae2cc1f8e86884e66e",
  "input": "0x1122",
  "maxFeePerGas": "0x5d21dba00",
  "maxPriorityFeePerGas": "0x5d21dba00",
  "nonce": "0x13",
  "senderTxHash": "0x5db239963029ad9ef6c3331b10ae455638316e330b0efdae2cc1f8e86884e66e",
  "signatures": [
      {
          "V": "0x1",
          "R": "0x27e007cbe79fd8cc9b89dd798bdd5aa62d038273bf006c7c3b40e13a938ab807",
          "S": "0x6209bb328855f02fa2671fecb41efd9f191b03ecab5e580227fa2a0674879384"
      }
  ],
  "to": "0xa0f1633f4c666d7fe5ba912bd5caf03d3655ac31",
  "transactionIndex": "0x0",
  "type": "TxTypeEthereumDynamicFee",
  "typeInt": 30722,
  "value": "0x186a0"
}
```


# Computation


# Klaytn Smart Contract

Smart contracts in Klaytn are programs that implement business logics, games, libraries, token transfers, or any type of code interacting with the Klaytn blockchain. When conditions described in the smart contract are met, the contract executes immediately. The terms within smart contracts are described in programming language; their contents data are stored as their state.

Klaytn provides several ways to write and execute smart contracts on the Klaytn network. First, Klaytn supports Solidity and maintains interoperability with Ethereum development toolkits such as Remix or Truffle. Smart contracts written in Solidity can be compiled using existing Solidity compilers and execute on Klaytn without additional work. Since Solidity is the de facto standard contract programming language in Ethereum and is backed by active communities, Klaytn supports the language to provide developers with the most familiar development environment onto which Ethereum DApp developers could easily migrate their existing work.

In the future, Klaytn plans to accommodate smart contracts written in various programming languages, in order to extend support to a broader range of potential developers and provide them with development experience they feel they're most familiar with. Going forward, Klaytn will continue to explore various programming languages that developers find interesting.

## Affordable Smart Contract Execution Cost <a href="#affordable-smart-contract-execution-cost" id="affordable-smart-contract-execution-cost"></a>

One of the reasons that blockchains charge fees on smart contract executions is to utilize limited resources efficiently by preventing poorly or maliciously written contracts from running. That is, a blockchain platform increases the financial cost of running smart contracts intentionally (1) to induce developers to write efficient code, and (2) to deter adversaries in launching attacks by minimizing the expected financial gains. With a successful strategy, the fees charged on normal executions should be small, although the fees from malicious executions should be large. Although Ethereum’s opcode-based fee model is useful in discouraging wasting of resources, it may also dampen ordinary smart contract executions due to high gas prices on some opcodes (e.g., state write), hindering the adoption of blockchain technologies. To address this problem, Klaytn plans to use an opcode-based fixed fee model with low unit cost per opcode. This is made possible by dramatically increasing scalability of blockchain protocol.

Opcode cost is directly related to the amount of resources that the platform can use. The Ethereum state write cost is high since the storage, and the network bandwidth required to record and propagate the changed states are limited. Conversely, if a blockchain has abundant resources (e.g., CPU time, storage, network bandwidth), then the unit cost per opcode can be substantially lower than that of Ethereum, and the cost difference between opcodes can be minimized. Klaytn aims to lower opcode unit cost by vertically scaling each CN node (i.e., acquiring high-end hardware), parallelizing computation (i.e., logical scaling via service chain), and horizontally scaling physical clusters.


# Execution Model

This page describes the execution model, the data structures, and the life cycle of Klaytn smart contracts.

## Execution Model <a href="#execution-model" id="execution-model"></a>

Transactions can be generated by platform APIs as described in [Platform API Specification](/content/dapp/json-rpc/api-references). These transactions are sent to *Consensus Nodes (CNs)* to be stored in a block. The CNs check whether each received transaction is valid. Valid transactions are stored in the transaction pool; otherwise, they are discarded. A CN selects the executable transactions in the current block in its transaction pool and executes them one by one.

To execute a transaction, the sender must pay some amount of KLAY as a transaction fee. This transaction fee in KLAY is calculated based on gas and a multiplier, *i.e.*, unit price. A gas is the fundamental unit of computation. Every operation executed on a Klaytn node consumes a predefined amount of gas. The exact amount of KLAY required for the transaction is calculated by the formula illustrated in [Transaction Fees](/content/klaytn/design/transaction-fees). The transaction can fail if the sender submits a transaction accompanied by insufficient gas. A transaction can also fail if the sender's account has an insufficient balance.

When a transaction is executed successfully, it is included in the current block. A CN gathers transactions until it reaches block gas limit or block time limit. Then, the CN makes a block with the transactions. This step requires filling several fields in the block. For example, it must calculate the hash values of transactions, receipts, state, etc. After all required fields have been completed, the CN generates a block hash.

When block generation is complete, the block is propagated to all the other CNs. The other CNs all verify the propagated block and reach consensus on the verification results by using the BFT consensus algorithm. When the verification process completes successfully by the majority of CNs, the block is stored in the blockchain. Because the BFT consensus algorithm satisfies the immediate finality property, the block is final and will never be removed. After a block is finalized, the execution of all the transactions in that block are irreversibly guaranteed, and their execution results can be returned to the sender if requested.

### Restrictions on Transaction Execution <a href="#restrictions-on-transaction-execution" id="restrictions-on-transaction-execution"></a>

Klaytn's Baobab and Cypress networks currently have the following restrictions on the transaction execution:

* A transaction must set its gas price to Klaytn's [unit price](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay), *i.e.*, 250 ston.
* A transaction which has bigger execution cost than the computation cost limit will be discarded. Please refer to [computation cost](/content/klaytn/design/computation/computation-cost)

## Data Structures <a href="#data-structures" id="data-structures"></a>

### Account <a href="#account" id="account"></a>

An account in Klaytn blockchain platform is a data structure containing information about a person's balance or a smart contract. Klaytn redesigns its account model to provide better DX and UX. Detailed information about the account model can be found [here](/content/klaytn/design/accounts).

### Transaction <a href="#transaction" id="transaction"></a>

A transaction in a blockchain platform is a message sent between nodes that changes the state of the blockchain. Klaytn also redesigns its transaction model. Transactions are separated into various types according to their own purposes to find chances of performance optimization and to support the redesigned account model. Detailed information about the transaction model can be found [here](/content/klaytn/design/transactions).

### State <a href="#state" id="state"></a>

Klaytn's **state** is a collection of account states. This state must be the same across Klaytn nodes if they have processed the same blocks in the same order. The state is changed when a transaction is executed on a Klaytn node.

The table below shows the account data that are stored in the state.

| Component   | Description                                                                                                                                                                                           |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| nonce       | An integer value indicating the number of transactions executed by this account. When submitting a transaction, the nonce of the transaction should be equal to the account's nonce.                  |
| balance     | An integer value showing the amount of KLAY that this account currently has.                                                                                                                          |
| storageRoot | A 256-bit hash of the root of the Merkle Patricia Trie that contains the values of all the storage variables in the account.                                                                          |
| codeHash    | The hash of the account's bytecode. This value is immutable, which means it is set only when the smart contract is created. If the account is an EOA or an EA, this value is set to the hash of null. |

### Block <a href="#block" id="block"></a>

A block is a crucial element of the Klaytn blockchain because the blockchain literally consists of a chain of blocks. The table below shows the components in a block.

| Component        | Description                                                                                                         |
| ---------------- | ------------------------------------------------------------------------------------------------------------------- |
| baseFeePerGas    | The base fee per gas. This value is returned only when EthTxTypeCompatibleBlock is activated for that block number. |
| blockScore       | Former difficulty. Always 1 in the BFT consensus engine                                                             |
| extraData        | The "extra data" field of this block.                                                                               |
| gasUsed          | The total used gas by all transactions in this block.                                                               |
| governanceData   | RLP encoded governance configuration                                                                                |
| logsBloom        | The bloom filter for the logs of the block. `null` when it is pending block.                                        |
| number           | The block number. `null` when it is pending block.                                                                  |
| parentHash       | The hash of the block's parent block.                                                                               |
| proposer         | The address of the block proposer.                                                                                  |
| receiptsRoot     | The root of the receipts trie of the block.                                                                         |
| reward           | The address receiving block reward.                                                                                 |
| size             | Integer the size of this block in bytes.                                                                            |
| stateRoot        | The root of the final state trie of the block.                                                                      |
| totalBlockScore  | Integer of the total blockScore of the chain until this block.                                                      |
| transactionsRoot | The root of the transaction trie of the block.                                                                      |
| timestamp        | The Unix timestamp for when the block was collated.                                                                 |
| timestampFoS     | The fraction of a second of the timestamp for when the block was collated.                                          |
| transactions     | Array of transaction objects, or 32-byte transaction hashes depending on the last given parameter.                  |
| voteData         | RLP encoded governance vote of the proposer                                                                         |

## Smart Contract <a href="#smart-contract" id="smart-contract"></a>

A *smart contract* consists of a collection of code (functions) and data (state) that resides at a specific address on the Klaytn blockchain. Contract accounts are able to pass messages between each other as well as perform practically Turing complete computation. Contracts exist on the blockchain in Klaytn-specific binary formats. Currently, Klaytn supports one binary format --Ethereum Virtual Machine (EVM) bytecode; however, other formats will be supported in the future.

### Creating Smart Contracts <a href="#creating-smart-contracts" id="creating-smart-contracts"></a>

A smart contract can be created in the Klaytn blockchain by sending a transaction to an empty address with the binary as data. The binary can be in various formats; however, Klaytn currently supports one binary format, EVM bytecode. It is worth pointing out that this transaction requires a payment for execution. The account balance on the sender's account will be reduced according to the transaction fee model after the transaction has been stored in a block. After some time, the transaction should appear in a block, which confirms that the state it entails reached a consensus. At this point, the smart contract now exists in the Klaytn blockchain. As [eip-3541](https://eips.ethereum.org/EIPS/eip-3541) is brought at the Kore hardfork, deployment of a new code starting with the 0xEF byte is not allowed.

### Executing Smart Contracts <a href="#executing-smart-contracts" id="executing-smart-contracts"></a>

A function of a smart contract can be called and executed either by sending a transaction to the smart contract or by calling the function locally in the node. When a function is called by sending a transaction, the function is executed by processing a transaction. This entails a cost in KLAY for sending the transaction, and the call will be recorded forever on the blockchain. The return value of calls made in this manner is the hash of the transaction. When the function is invoked locally, it is executed locally in the Klaytn Virtual Machine (KLVM), and the call returns the return value of the function. Calls made in this manner are not recorded on the blockchain; thus, they cannot modify the internal state of the contract. This type of call is referred to as a constant function call. Calls made in this manner do not cost any KLAY. Constant function calls should be used when only the return value is of interest, while a transaction should be used when side effects on the contract state are of interest.

### Disabling Smart Contracts <a href="#disabling-smart-contracts" id="disabling-smart-contracts"></a>

Because smart contracts exist in the Klaytn blockchain, they cannot be deleted; they can only be disabled. For now, Klaytn has adopted the same process for disabling a Klaytn smart contract as is used for disabling smart contracts in Ethereum. For example, the Klaytn smart contract for KLVM can be disabled by using the [`selfdestruct(address recipient)`](https://solidity.readthedocs.io/en/v0.5.6/introduction-to-smart-contracts.html#self-destruct) call in Solidity (or the KLVM opcode `SELFDESTRUCT`). The Klaytn team will also provide ways to disable smart contracts for other execution environments.

### Upgrading Smart Contracts <a href="#upgrading-smart-contracts" id="upgrading-smart-contracts"></a>

Klaytn will provide ways to upgrade a deployed smart contract to address the inconvenient user experience with existing blockchains. For example, deployed services on blockchains are difficult to upgrade. Klaytn will provide frameworks and smart contract libraries to enable service providers (SPs) to upgrade deployed services and migrate service information. Klaytn will provide this feature carefully by considering the following requirements.

* Only authorized accounts or the owner of a smart contract should be able to upgrade the smart contract.
* Upgraded smart contracts should be able to manipulate existing data maintained by the old smart contract.
* Other smart contracts that refer to the old smart contracts should be able to determine whether to use newer, upgraded versions of those smart contracts.


# Computation Cost

Since Klaytn aims to maintain 1-second block time, the execution time of transactions has to be managed. Here are three approaches to achieve that:

1. Limiting the gas limit of a transaction
2. Limiting the execution time of a transaction
3. Limiting the computation cost of a transaction

Limiting the gas limit of a transaction was not a feasible solution because the concept of the gas represents the current exchange value of the various resources in the blockchain platform such as computation, storage, network bandwidth, and so on. It is not suitable as a metric for the transaction execution time.

Limiting the execution time of a transaction was not feasible either because the execution time can vary between nodes on the blockchain platform. For example, consider the case in which we limit the execution time of a transaction to be 100 milli-second. If a node executes a transaction in 90 ms and another node executes it in 110 ms, the two nodes cannot reach a consensus. Hence, this solution is not appropriate.

The last approach is to limit the computation cost of a transaction. We modelled the computation cost of each EVM opcode based on its actual execution time and limit the sum of computation cost of a transaction. With this approach, we eliminate other factors and only count the normalized execution time unit, and nodes can reach a consensus as well.

Therefore, we chose the third option for Klaytn. For now, the limit of the execution cost is set to 100,000,000. Since the limit is determined by the platform, developers should be aware of the computation cost of a transaction. To calculate the computation cost of a transaction, Klaytn provides [klay\_estimateComputationCost](/content/dapp/json-rpc/api-references/klay/transaction#klay_estimatecomputationcost). The usage is almost the same as [klay\_estimateGas](/content/dapp/json-rpc/api-references/klay/transaction#klay_estimategas).

## Computation Cost of Opcodes <a href="#computation-cost-of-opcodes" id="computation-cost-of-opcodes"></a>

The below table shows the computation cost of EVM opcodes. The computation cost was determined based on experiments.

{% hint style="success" %}
NOTE: Computation costs have changed with the `Kore` hardfork. If you want the previous document, please refer to [previous document](/content/klaytn/design/computation/computation-cost/computation-cost-previous).

`Kore` hardfork block numbers are as follows.

* Baobab Testnet: `#111736800`
* Cypress Mainnet: `#119750400`
  {% endhint %}

| Opcode         | ComputationCost |
| -------------- | --------------: |
| STOP           |               0 |
| ADD            |             150 |
| MUL            |             200 |
| SUB            |             219 |
| DIV            |             404 |
| SDIV           |             739 |
| MOD            |             812 |
| SMOD           |             560 |
| ADDMOD         |            1410 |
| MULMOD         |            1760 |
| EXP            |            5000 |
| SIGNEXTEND     |             481 |
| LT             |             201 |
| GT             |             264 |
| SLT            |             176 |
| SGT            |             222 |
| EQ             |             220 |
| ISZERO         |             165 |
| AND            |             288 |
| OR             |             160 |
| XOR            |             454 |
| NOT            |             364 |
| BYTE           |             589 |
| SHL            |             478 |
| SHR            |             498 |
| SAR            |             834 |
| SHA3           |            2465 |
| ADDRESS        |             284 |
| BALANCE        |            1407 |
| ORIGIN         |             210 |
| CALLER         |             188 |
| CALLVALUE      |             149 |
| CALLDATALOAD   |             596 |
| CALLDATASIZE   |             194 |
| CALLDATACOPY   |             100 |
| CODESIZE       |             145 |
| CODECOPY       |             898 |
| GASPRICE       |             131 |
| EXTCODESIZE    |            1481 |
| EXTCODECOPY    |            1000 |
| RETURNDATASIZE |              10 |
| RETURNDATACOPY |              40 |
| EXTCODEHASH    |            1000 |
| BLOCKHASH      |             500 |
| COINBASE       |             189 |
| TIMESTAMP      |             265 |
| NUMBER         |             202 |
| PREVRANDAO     |            1498 |
| GASLIMIT       |             166 |
| CHAINID        |             120 |
| SELFBALANCE    |             374 |
| POP            |             140 |
| MLOAD          |             376 |
| MSTORE         |             288 |
| MSTORE8        |            5142 |
| SLOAD          |             835 |
| SSTORE         |            1548 |
| JUMP           |             253 |
| JUMPI          |             176 |
| PC             |             147 |
| MSIZE          |             137 |
| GAS            |             230 |
| JUMPDEST       |              10 |
| PUSH0          |              80 |
| PUSH1          |             120 |
| PUSH2          |             120 |
| PUSH3          |             120 |
| PUSH4          |             120 |
| PUSH5          |             120 |
| PUSH6          |             120 |
| PUSH7          |             120 |
| PUSH8          |             120 |
| PUSH9          |             120 |
| PUSH10         |             120 |
| PUSH11         |             120 |
| PUSH12         |             120 |
| PUSH13         |             120 |
| PUSH14         |             120 |
| PUSH15         |             120 |
| PUSH16         |             120 |
| PUSH17         |             120 |
| PUSH18         |             120 |
| PUSH19         |             120 |
| PUSH20         |             120 |
| PUSH21         |             120 |
| PUSH22         |             120 |
| PUSH23         |             120 |
| PUSH24         |             120 |
| PUSH25         |             120 |
| PUSH26         |             120 |
| PUSH27         |             120 |
| PUSH28         |             120 |
| PUSH29         |             120 |
| PUSH30         |             120 |
| PUSH31         |             120 |
| PUSH32         |             120 |
| DUP1           |             190 |
| DUP2           |             190 |
| DUP3           |             176 |
| DUP4           |             142 |
| DUP5           |             177 |
| DUP6           |             165 |
| DUP7           |             147 |
| DUP8           |             157 |
| DUP9           |             138 |
| DUP10          |             174 |
| DUP11          |             141 |
| DUP12          |             144 |
| DUP13          |             157 |
| DUP14          |             143 |
| DUP15          |             237 |
| DUP16          |             149 |
| SWAP1          |             141 |
| SWAP2          |             156 |
| SWAP3          |             145 |
| SWAP4          |             135 |
| SWAP5          |             115 |
| SWAP6          |             146 |
| SWAP7          |             199 |
| SWAP8          |             130 |
| SWAP9          |             160 |
| SWAP10         |             134 |
| SWAP11         |             147 |
| SWAP12         |             128 |
| SWAP13         |             121 |
| SWAP14         |             114 |
| SWAP15         |             197 |
| SWAP16         |             128 |
| LOG0           |             100 |
| LOG1           |            1000 |
| LOG2           |            1000 |
| LOG3           |            1000 |
| LOG4           |            1000 |
| PUSH           |               0 |
| DUP            |               0 |
| SWAP           |               0 |
| CREATE         |            2094 |
| CALL           |            5000 |
| CALLCODE       |            4000 |
| RETURN         |               0 |
| DELEGATECALL   |             696 |
| CREATE2        |           10000 |
| STATICCALL     |           10000 |
| REVERT         |               0 |
| SELFDESTRUCT   |               0 |
| BASEFEE        |             198 |


# Computation Cost (Previous docs)

Since Klaytn aims to maintain 1-second block time, the execution time of transactions has to be managed. Here are three approaches to achieve that:

1. Limiting the gas limit of a transaction
2. Limiting the execution time of a transaction
3. Limiting the computation cost of a transaction

Limiting the gas limit of a transaction was not a feasible solution because the concept of the gas represents the current exchange value of the various resources in the blockchain platform such as computation, storage, network bandwidth, and so on. It is not suitable as a metric for the transaction execution time.

Limiting the execution time of a transaction was not feasible either because the execution time can vary between nodes on the blockchain platform. For example, consider the case in which we limit the execution time of a transaction to be 100 milli-second. If a node executes a transaction in 90 ms and another node executes it in 110 ms, the two nodes cannot reach a consensus. Hence, this solution is not appropriate.

The last approach is to limit the computation cost of a transaction. We modelled the computation cost of each EVM opcode based on its actual execution time and limit the sum of computation cost of a transaction. With this approach, we eliminate other factors and only count the normalized execution time unit, and nodes can reach a consensus as well.

Therefore, we chose the third option for Klaytn. For now, the limit of the execution cost is set to 100,000,000. Since the limit is determined by the platform, developers should be aware of the computation cost of a transaction. To calculate the computation cost of a transaction, Klaytn provides [klay\_estimateComputationCost](/content/dapp/json-rpc/api-references/klay/transaction#klay_estimateComputationCost). The usage is almost the same as [klay\_estimateGas](/content/dapp/json-rpc/api-references/klay/transaction#klay_estimateGas).

## Computation Cost of Opcodes <a href="#computation-cost-of-opcodes" id="computation-cost-of-opcodes"></a>

The below table shows the computation cost of EVM opcodes. The computation cost was determined based on experiments.

{% hint style="success" %}
NOTE: This document contains computation costs used before the activation of the protocol upgrade. If you want the latest document, please refer to [latest document](/content/klaytn/design/computation/computation-cost).
{% endhint %}

| Opcode         | ComputationCost |
| -------------- | --------------: |
| STOP           |               0 |
| ADD            |             150 |
| MUL            |             200 |
| SUB            |             219 |
| DIV            |             404 |
| SDIV           |             739 |
| MOD            |             812 |
| SMOD           |             560 |
| ADDMOD         |            3349 |
| MULMOD         |            4757 |
| EXP            |            5000 |
| SIGNEXTEND     |             481 |
| LT             |             201 |
| GT             |             264 |
| SLT            |             176 |
| SGT            |             222 |
| EQ             |             220 |
| ISZERO         |             165 |
| AND            |             288 |
| OR             |             160 |
| XOR            |             657 |
| NOT            |            1289 |
| BYTE           |             589 |
| SHL            |            1603 |
| SHR            |            1346 |
| SAR            |            1815 |
| SHA3           |            2465 |
| ADDRESS        |             284 |
| BALANCE        |            1407 |
| ORIGIN         |             210 |
| CALLER         |             188 |
| CALLVALUE      |             149 |
| CALLDATALOAD   |             596 |
| CALLDATASIZE   |             194 |
| CALLDATACOPY   |             100 |
| CODESIZE       |             145 |
| CODECOPY       |             898 |
| GASPRICE       |             131 |
| EXTCODESIZE    |            1481 |
| EXTCODECOPY    |            1000 |
| RETURNDATASIZE |              10 |
| RETURNDATACOPY |              40 |
| EXTCODEHASH    |            1000 |
| BLOCKHASH      |             500 |
| COINBASE       |             189 |
| TIMESTAMP      |             265 |
| NUMBER         |             202 |
| DIFFICULTY     |             180 |
| GASLIMIT       |             166 |
| POP            |             140 |
| MLOAD          |             376 |
| MSTORE         |             288 |
| MSTORE8        |            5142 |
| SLOAD          |             835 |
| SSTORE         |            1548 |
| JUMP           |             253 |
| JUMPI          |             176 |
| PC             |             147 |
| MSIZE          |             137 |
| GAS            |             230 |
| JUMPDEST       |              10 |
| PUSH1          |             120 |
| PUSH2          |             120 |
| PUSH3          |             120 |
| PUSH4          |             120 |
| PUSH5          |             120 |
| PUSH6          |             120 |
| PUSH7          |             120 |
| PUSH8          |             120 |
| PUSH9          |             120 |
| PUSH10         |             120 |
| PUSH11         |             120 |
| PUSH12         |             120 |
| PUSH13         |             120 |
| PUSH14         |             120 |
| PUSH15         |             120 |
| PUSH16         |             120 |
| PUSH17         |             120 |
| PUSH18         |             120 |
| PUSH19         |             120 |
| PUSH20         |             120 |
| PUSH21         |             120 |
| PUSH22         |             120 |
| PUSH23         |             120 |
| PUSH24         |             120 |
| PUSH25         |             120 |
| PUSH26         |             120 |
| PUSH27         |             120 |
| PUSH28         |             120 |
| PUSH29         |             120 |
| PUSH30         |             120 |
| PUSH31         |             120 |
| PUSH32         |             120 |
| DUP1           |             190 |
| DUP2           |             190 |
| DUP3           |             176 |
| DUP4           |             142 |
| DUP5           |             177 |
| DUP6           |             165 |
| DUP7           |             147 |
| DUP8           |             157 |
| DUP9           |             138 |
| DUP10          |             174 |
| DUP11          |             141 |
| DUP12          |             144 |
| DUP13          |             157 |
| DUP14          |             143 |
| DUP15          |             237 |
| DUP16          |             149 |
| SWAP1          |             141 |
| SWAP2          |             156 |
| SWAP3          |             145 |
| SWAP4          |             135 |
| SWAP5          |             115 |
| SWAP6          |             146 |
| SWAP7          |             199 |
| SWAP8          |             130 |
| SWAP9          |             160 |
| SWAP10         |             134 |
| SWAP11         |             147 |
| SWAP12         |             128 |
| SWAP13         |             121 |
| SWAP14         |             114 |
| SWAP15         |             197 |
| SWAP16         |             128 |
| LOG0           |             100 |
| LOG1           |            1000 |
| LOG2           |            1000 |
| LOG3           |            1000 |
| LOG4           |            1000 |
| PUSH           |               0 |
| DUP            |               0 |
| SWAP           |               0 |
| CREATE         |            2094 |
| CALL           |            5000 |
| CALLCODE       |            4000 |
| RETURN         |               0 |
| DELEGATECALL   |             696 |
| CREATE2        |           10000 |
| STATICCALL     |           10000 |
| REVERT         |               0 |
| SELFDESTRUCT   |               0 |


# Klaytn Virtual Machine

{% hint style="success" %}
NOTE: KLVM has changed with the `Kore` hardfork. If you want the previous document, please refer to [previous document](/content/klaytn/design/computation/klaytn-virtual-machine/klaytn-virtual-machine-previous).

`Kore` hardfork block numbers are as follows.

* Baobab Testnet: `#111736800`
* Cypress Mainnet: `#119750400`
  {% endhint %}

## Overview <a href="#overview" id="overview"></a>

The current version of the Klaytn Virtual Machine (KLVM) is derived from the Ethereum Virtual Machine (EVM). The content of this chapter is based primarily on the [Ethereum Yellow Paper](https://github.com/ethereum/yellowpaper). KLVM is continuously being improved by the Klaytn team, thus this document could be updated frequently. Please do not regard this document as the final version of the KLVM specification. As described in the Klaytn position paper, the Klaytn team also plans to adopt other virtual machines or execution environments in order to strengthen the capability and performance of the Klaytn platform. This chapter presents a specification of KLVM and the differences between KLVM and EVM.

KLVM is a virtual state machine that formally specifies Klaytn's execution model. The execution model specifies how the system state is altered given a series of bytecode instructions and a small tuple of environmental data. KLVM is a quasi-Turing-complete machine; the *quasi* qualification stems from the fact that the computation is intrinsically bounded through a parameter, *gas*, which limits the total amount of computation performed.

KLVM executes Klaytn virtual machine code (or Klaytn bytecode) which consists of a sequence of KLVM instructions. The KLVM code is the programming language used for accounts on the Klaytn blockchain that contain code. The KLVM code associated with an account is executed every time a message is sent to that account; this code has the ability to read/write from/to storage and send messages.

## KLVM Specification <a href="#klvm-specification" id="klvm-specification"></a>

### Conventions <a href="#conventions" id="conventions"></a>

We use the following notations and conventions in this document.

* `A := B`
  * `:=` is used to define `A` as `B`.
* We use the terms "smart contract" and "contract" interchangeably.
* We use the terms "opcode" as the "operation code/operation"

### Symbols <a href="#symbols" id="symbols"></a>

The following tables summarize the symbols used in the KLVM specification.

#### Blockchain-Related Symbols <a href="#blockchain-related-symbols" id="blockchain-related-symbols"></a>

| Symbol     | Description                           |
| ---------- | ------------------------------------- |
| `BC`       | Blockchain                            |
| `B`        | Block                                 |
| `B_header` | The block header of the present block |

#### State-Related Symbols <a href="#state-related-symbols" id="state-related-symbols"></a>

| Symbol           | Description                                |
| ---------------- | ------------------------------------------ |
| `S`              | State                                      |
| `S_system`       | System state                               |
| `S_machine`      | Machine state                              |
| `P_modify_state` | The permission to make state modifications |

#### Transaction-Related Symbols <a href="#transaction-related-symbols" id="transaction-related-symbols"></a>

| Symbol    | Description                                                                                                                                              |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `T`       | Transaction                                                                                                                                              |
| `T_code`  | A byte array containing machine code to be executed                                                                                                      |
| `T_data`  | A byte array containing the input data to the execution; if the execution agent is a transaction, this would be the transaction data.                    |
| `T_value` | A value, in peb, passed to the account as part of the execution procedure; if the execution agent is a transaction, this would be the transaction value. |
| `T_depth` | The depth of the present message-call or contract-creation stack (*i.e.*, the number of `CALL`s or `CREATE`s being executed at present)                  |

#### Gas-Related Symbols <a href="#gas-related-symbols" id="gas-related-symbols"></a>

| Symbol    | Description                                                       |
| --------- | ----------------------------------------------------------------- |
| `G`       | Gas                                                               |
| `G_rem`   | Remaining gas for computation                                     |
| `G_price` | The price of gas in the transaction that originated the execution |

#### Address-Related Symbols <a href="#address-related-symbols" id="address-related-symbols"></a>

| Symbol            | Description                                                                                                                              |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `A`               | Address                                                                                                                                  |
| `A_code_owner`    | The address of the account that owns the executing code                                                                                  |
| `A_tx_sender`     | The sender address of the transaction that originated the current execution                                                              |
| `A_code_executor` | the address of the account that initiated code execution; if the execution agent is a transaction, this would be the transaction sender. |

#### Functions <a href="#functions" id="functions"></a>

|   Symbol  | Description                                                                                                   |
| :-------: | ------------------------------------------------------------------------------------------------------------- |
| `F_apply` | A function that applies a transaction with input to a given state and returns the resultant state and outputs |

### Basics <a href="#basics" id="basics"></a>

KLVM is a simple stack-based architecture. The word size of the machine (and thus the size of stack items) is 256-bit. This was chosen to facilitate the Keccak-256 hash scheme and the elliptic-curve computations. The memory model is a simple word-addressed byte array. The stack has a maximum size of 1024. The machine also has an independent storage model; this is similar in concept to the memory but rather than a byte array, it is a word-addressable word array. Unlike memory, which is volatile, storage is nonvolatile and is maintained as part of the system state. All locations in both storage and memory are initially well-defined as zero.

The machine does not follow the standard von Neumann architecture. Rather than storing program code in generally accessible memory or storage, code is stored separately in virtual read-only memory and can be interacted with only through specialized instructions.

The machine can execute exception code for several reasons, including stack underflows and invalid instructions. Similar to an out-of-gas exception, these exceptions do not leave state changes intact. Rather, the virtual machine halts immediately and reports the issue to the execution agent (either the transaction processor or, recursively, the spawning execution environment), which will be addressed separately.

### Fees Overview <a href="#fees-overview" id="fees-overview"></a>

Fees (denominated in gas) are charged under three distinct circumstances. Sometimes, some policies may be omitted.

* The first and most common is the `constantGas`. It's a fee intrinsic to the computation of the operation.
* Second, gas may be deducted to form the payment for a subordinate message call or contract creation; this forms part of the payment for `CREATE`, `CALL` and `CALLCODE`.
* Finally, gas may be charged due to an increase in memory usage.

Over an account's execution, the total fee payable for memory-usage payable is proportional to the smallest multiple of 32 bytes that are required to include all memory indices (whether for read or write) in the range. This fee is paid on a just-in-time basis; consequently, referencing an area of memory at least 32 bytes greater than any previously indexed memory will result in an additional memory usage fee. Due to this fee, it is highly unlikely that addresses will ever exceed the 32-bit bounds. That said, implementations must be able to manage this eventuality.

Storage fees have a slightly nuanced behavior. To incentivize minimization of the use of storage (which corresponds directly to a larger state database on all nodes), the execution fee for an operation that clears an entry from storage is not only waived but also elicits a qualified refund; in fact, this refund is effectively paid in advance because the initial usage of a storage location costs substantially more than normal usage.

#### Fee Schedule <a href="#fee-schedule" id="fee-schedule"></a>

The fee schedule `G` is a tuple of 37 scalar values corresponding to the relative costs, in gas, of a number of abstract operations that a transaction may incur. Also, there's gas items to calculate the gas of the precompiled contracts called by `CALL_*` opcodes. For other tables such as `intrinsic gas cost` or `key validation gas cost`, please refer to [this document](/content/klaytn/design/transaction-fees)

**Scalar values representing `constantGas` of an opcode**

| Name                                           | Value |                                                        Name in code | Opcodes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ---------------------------------------------- | ----: | ------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `G_base`                                       |     2 |                                                        GasQuickStep | <p><code>ADDRESS</code>, <code>ORIGIN</code>, <code>CALLER</code>, <code>CALLVALUE</code>, <code>CALLDATASIZE</code>,<br><code>CODESIZE</code>, <code>GASPRICE</code>, <code>COINBASE</code>, <code>TIMESTAMP</code>, <code>NUMBER</code>,<br><code>PREVRANDAO(originally it was difficulty)</code>, <code>GASLIMIT</code>,<br><code>RETURNDATASIZE</code>, <code>POP</code>, <code>PC</code>, <code>MSIZE</code>, <code>GAS</code>,<br><code>CHAINID(added at istanbul hardfork)</code>,<br><code>BASEFEE(added at london Hardfork)</code>,<br><code>PUSH0(added at shanghai Hardfork)</code></p> |
| `G_verylow`                                    |     3 |                                                      GasFastestStep | <p><code>ADD</code>, <code>SUB</code>, <code>LT</code>, <code>GT</code>, <code>SLT</code>, <code>SGT</code>, <code>EQ</code>, <code>ISZERO</code>, <code>AND</code>,<br><code>OR</code>, <code>XOR</code>, <code>NOT</code>, <code>BYTE</code>, <code>CALLDATALOAD</code>,<br><code>MLOAD</code>, <code>MSTORE</code>, <code>MSTORE8</code>, <code>PUSH</code>, <code>DUP</code>, <code>SWAP</code></p>                                                                                                                                                                                            |
| `G_low`                                        |     5 |                                                         GasFastStep | <p><code>MUL</code>, <code>DIV</code>, <code>SDIV</code>, <code>MOD</code>, <code>SMOD</code>, <code>SIGNEXTEND</code>,<br><code>SELFBALANCE(added at istanbul hardfork)</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                |
| `G_mid`                                        |     8 |                                                          GasMidStep | `ADDMOD`, `MULMOD`, `JUMP`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `G_high`                                       |    10 |                                                         GasSlowStep | `JUMPI`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `G_selfdestruct`                               |  5000 |                                                     SelfdestructGas | `SELFDESTRUCT`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| <p><code>G\_warmStorageReadCost</code><br></p> |   100 | <p>WarmStorageReadCostEIP2929<br>(newly added at Kore hardfork)</p> | <p><code>EXTCODECOPY</code>, <code>EXTCODESIZE</code>, <code>EXTCODEHASH</code>, <code>BALANCE</code>,<br><code>CALL</code>, <code>CALLCODE</code>, <code>STATICCALL</code>, <code>DELEGATECALL</code></p>                                                                                                                                                                                                                                                                                                                                                                                         |
| `G_blockhash`                                  |    20 |                                                          GasExtStep | `BLOCKHASH`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `G_jumpdest`                                   |     1 |                                                         JumpdestGas | `JUMPDEST`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `G_sha3`                                       |    30 |                                                             Sha3Gas | `SHA3`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `G_create`                                     | 32000 |                                                           CreateGas | `CREATE`, `CREATE2`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

**Scalar values used to calculate the gas based on memory and log usage**

| Name         | Value | Name in Code | Description                                                                   |
| ------------ | ----: | -----------: | ----------------------------------------------------------------------------- |
| `G_memory`   |     3 |    MemoryGas | Amount of gas paid for every additional word when expanding memory            |
| `G_copy`     |     3 |      CopyGas | Partial payment for `COPY` operations, multiplied by words copied, rounded up |
| `G_log`      |   375 |       LogGas | Partial payment for a `LOG` operation                                         |
| `G_logdata`  |     8 |   LogDataGas | Amount of gas paid for each byte in a `LOG` operation's data                  |
| `G_logtopic` |   375 |  LogTopicGas | Amount of gas paid for each topic of a `LOG` operation                        |

**Scalar values used to calculate the gas of the particular opcode**

| Name              | Value | Name in Code                      | Description                                                                                                                    |
| ----------------- | ----: | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `G_sset`          | 20000 | SstoreSetGas                      | Amount of gas paid when the storage value when set storage                                                                     |
| `G_sreset`        |  5000 | SstoreResetGas                    | Amount of gas paid when the storage value remains unchanged at zero or is set to zero                                          |
| `G_coldSloadCost` |  2100 | ColdSloadCostEIP2929              | Amount of gas paid when the storage value is not in accessList                                                                 |
| `R_sclear`        | 15000 | SstoreClearsScheduleRefundEIP3529 | `G_sreset` - `G_coldSloadCost` + `TxAccessListStorageKeyGas (1900)`                                                            |
| `G_exp`           |    10 | ExpGas                            | Partial payment                                                                                                                |
| `G_expbyte`       |    50 | ExpByte                           | Partial payment when multiplied by `ceil(log_256(exponent))`                                                                   |
| `G_selfdestruct`  |  5000 | SelfdestructGas                   | Amount of gas paid for a `SELFDESTRUCT` operation                                                                              |
| `G_callvalue`     |  9000 | CallValueTransferGas              | Amount of gas paid for a nonzero value transfer                                                                                |
| `G_callstipend`   |  2300 | CallStipend                       | Free gas given at beginning of call for a nonzero value transfer                                                               |
| `G_newaccount`    | 25000 | CallNewAccountGas                 | Amount of gas paid when creating an account. It is also be defined as `CreateBySelfdestructGas` with `SELFDESTRUCT` operation. |
| `G_codedeposit`   |   200 | CreateDataGas                     | Amount of gas paid per byte for a creating a contract that succeeds in placing code into state                                 |
| `G_sha3word`      |     6 | Sha3WordGas                       | Amount of gas paid for each word (rounded up) for an `SHA3` input data                                                         |

**Items to calculate the precompiled contracts gas**

Precompiled contracts are special kind of contracts which usually perform complex cryptographic computations and are initiated by other contracts.

For example, gas cost can be calculated simply like below, but some gas cost calculation functions are very complex. So I would not explain the exact gas cost calculation function here.

```
# ecrecover, sha256hash, ripemd160hash, dataCopy
Gas = XXXBaseGas + (number of words * XXXPerWordGas)

# validateSender
Gas = number of signatures * ValidateSenderGas
```

| Address | Precompiled contracts | Item                                         | Value        |
| ------- | --------------------- | -------------------------------------------- | ------------ |
| 0x01    | ecrecover             | EcrecoverGas                                 | 3000         |
| 0x02    | sha256hash            | Sha256BaseGas, Sha256PerWordGas              | 60, 12       |
| 0x03    | ripemd160hash         | Ripemd160BaseGas, Ripemd160PerWordGas        | 600, 120     |
| 0x04    | dataCopy              | IdentityBaseGas, IdentityPerWordGas          | 15, 3        |
| 0x05    | bigModExp             | ModExpQuadCoeffDiv                           | 20           |
| 0x06    | bn256Add              | Bn256AddGas                                  | 150          |
| 0x07    | bn256ScalarMul        | Bn256ScalarMulGas                            | 6000         |
| 0x08    | bn256Pairing          | Bn256PairingBaseGas, Bn256PairingPerPointGas | 45000, 34000 |
| 0x09    | blake2f               | -                                            | -            |
| 0xFD    | vmLog                 | VMLogBaseGas, VMLogPerByteGas                | 100, 20      |
| 0xFE    | feePayer              | FeePayerGas                                  | 300          |
| 0xFF    | validateSender        | ValidateSenderGas                            | 5000         |

#### Gas calculation during contract execution <a href="#gas-calculation-during-contract-execution" id="gas-calculation-during-contract-execution"></a>

The gas cost of one transaction is calculated through the methods described below. First, gas is added according to the transaction type and input. Then, if the contract is executed, opcodes are executed one by one until the execution ends or `STOP` operation appears. In the process, the cost is charged according to the `constantGas` defined for each opcode and the additionally defined gas calculation method.

Here, I will briefly explain the gas calculation logic during contract execution using the fee schedule variables defined above. As this explanation assumes a general situation, the unusual situations such as revert appears is not considered.

* add `constantGas` defined in each opcode to gas
  * e.g. if an opcode is `MUL`, add `G_low` to gas
  * e.g. if an opcode is `CREATE2`, add `G_create` to gas
* add the gas which is calculated through additionally defined gas calculation method
  * For `LOG'N'`, where N is \[0,1,2,3,4], add `G_log + memoryGasCost * g_logdata + N x G_logtopic` to gas
  * For `EXP`, add `G_exp + byteSize(stack.back(1)) x G_expbyte` to gas
  * For `CALLDATACOPY` or `CODECOPY` or `RETURNDATACOPY`, add `wordSize(stack.back(2)) x G_copy` to gas
  * For `EXTCODECOPY`,
    * add `wordSize(stack.back(3)) x G_copy` to gas
    * \[***eip2929***] If an address is not in AccessList, add it to accessList and add `G_coldSloadCost - G_warmStorageReadCost` to gas
  * For `EXTCODESIZE` or `EXTCODEHASH` or `BALANCE`,
    * \[***eip2929***] If an address is not in AccessList, add it to accessList and add `G_coldSloadCost - G_warmStorageReadCost` to gas
  * For `SHA3`, add `G_sha3 + wordSize(stack.back(1)) x G_sha3word` to gas
  * For `RETURN`, `REVERT`, `MLoad`, `MStore8`, `MStore`, add `memoryGasCost` to gas
  * For `CREATE`, add `memoryGasCost + size(contract.code) x G_codedeposit` to gas
  * For `CREATE2`, add `memoryGasCost + size(data) x G_sha3word + size(contract.code) x G_codedeposit` to gas
  * For `SSTORE`,
    * \[***eip2929***] If a slot(contractAddr, slot) is not in AccessList, add it to accessList and add `G_coldSloadCost` to gas
    * If it just reads the slot (no-op), add `G_warmStorageReadCost` to gas
    * If it creates a new slot, add `G_sset` to gas
    * If it deletes the slot, add `G_sreset-G_coldSloadCost` to gas and add `R_sclear` to refund
    * If it recreates the slot once exists before, add `G_warmStorageReadCost` to gas and subtract `R_sclear` from refund
    * If it deletes the slot once exists before, add `R_sclear` to refund
    * If it resets to the original inexistent slot, add `G_warmStorageReadCost` to gas and add `G_sset - G_warmStorageReadCost` to refund
    * IF it resets to the original existing slot, add `G_warmStorageReadCost` to gas and add `G_sreset - G_coldSloadCost - G_warmStorageReadCost` to refund
  * For `SLOAD`,
    * \[***eip2929***] If a slot(contractAddr, slot) is not in AccessList, add it to accessList and add `G_coldSloadCost` to gas
    * \[***eip2929***] If a slot(contractAddr, slot) is in AccessList, add `G_warmStorageReadCost` to gas
  * For `CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`,
    * \[***eip2929***] If an address is not in AccessList, add it to accessList and add `G_coldSloadCost` to gas
    * if it is `CALL` and `CALLCODE` and if it transfers value, add `G_callvalue` to gas
    * if it is `CALL` and if it transfers value and if it is a new account, add `G_newaccount` to gas
    * if the callee contract is precompiled contracts, calculate precompiled contract gas cost and add it to gas
    * add `memoryGasCost + availableGas - availableGas/64, where availableGas = contract.Gas - gas` to gas
  * For `SELFDESTRUCT`,
    * \[***eip2929***] If an address is not in AccessList, add it to accessList and add `G_coldSloadCost` to gas
    * if it transfers value and if is a new account, add `G_newaccount` to gas

### Execution Environment <a href="#execution-environment" id="execution-environment"></a>

The execution environment consists of the system state `S_system`, the remaining gas for computation `G_rem`, and the information `I` that the execution agent provides. `I` is a tuple defined as shown below:

`I := (B_header, T_code, T_depth, T_value, T_data, A_tx_sender, A_code_executor, A_code_owner, G_price, P_modify_state)`

The execution model defines the function `F_apply`, which can compute the resultant state `S_system'`, the remaining gas `G_rem'`, the accrued substate `A` and the resultant output `O_result` when given these definitions. For the present context, we will define it as follows:

`(S_system', G_rem', A, O_result) = F_apply(S_system, G_rem, I)`

where we must remember that `A`, the accrued substate, is defined as the tuple of the suicides set `Set_suicide`, the log series `L`, the touched accounts `Set_touched_accounts` and the refunds `G_refund`:

`A := (Set_suicide, L, Set_touched_accounts, G_refund)`

### Execution Overview <a href="#execution-overview" id="execution-overview"></a>

In most practical implementations, `F_apply` will be modeled as an iterative progression of the pair comprising the full system state `S_system` and the machine state `S_machine`. Formally, we define it recursively with a function `X` that uses an iterator function `O` (which defines the result of a single cycle of the state machine) together with functions `Z`, which determines if the present state is an exceptional halted machine state, and `H`, which specifies the output data of an instruction if and only if the present state is a normal halted machine state.

The empty sequence, denoted as `()`, is not equal to the empty set, denoted as `Set_empty`; this is important when interpreting the output of `H`, which evaluates to `Set_empty` when execution is to continue but to a series (potentially empty) when execution should halt.

`F_apply(S_machine, G_rem, I, T) := (S_system', S_machine,g', A, o)`

* `(S_system', S_machine,g', A, ..., o) := X((S_system, S_machine, A^0, I))`
* `S_machine,g := G_rem`
* `S_machine,pc := 0`
* `S_machine,memory := (0, 0, ...)`
* `S_machine,i := 0`
* `S_machine,stack := ()`
* `S_machine,o := ()`
* `X((S_system, S_machine, A, I)) :=`
  * `(Set_empty, S_machine, A^0, I, Set_empty)` if `Z(S_system, S_machine, I)`
  * `(Set_empty, S_machine', A^0, I, o)` if `w = REVERT`
  * `O(S_system, S_machine, A, I) · o` if `o != Set_empty`
  * `X(O(S_system, S_machine, A, I))` otherwise

where

* `o := H(S_machine, I)`
* `(a, b, c, d) · e := (a, b, c, d, e)`
* `S_machine' := S_machine` except

  `S_machine,g' := S_machine,g - C(S_system, S_machine, I)`

  * This means that when we evaluate `F_apply`, we

    extract the remaining gas `S_machine,g'` from the

    resultant machine state `S_machine'`.

`X` is thus cycled (recursively here, but implementations are generally expected to use a simple iterative loop) until either `Z` becomes true, indicating that the present state is exceptional and that the machine must be halted and any changes are discarded, or until `H` becomes a series (rather than the empty set), indicating that the machine has reached a controlled halt.

#### Machine State <a href="#machine-state" id="machine-state"></a>

The machine state `S_machine` is defined as a tuple `(g, pc, memory, i, stack)`, which represent the available gas, the program counter `pc` (64-bit unsigned integer), the memory contents, the active number of words in memory (counting continuously from position 0), and the stack contents. The memory contents `S_machine,memory` are a series of zeroes of size 2^256.

For ease of reading, the instruction mnemonics written in small-caps (*e.g.*, `ADD`) should be interpreted as their numeric equivalents; the full table of instructions and their specifics is given in the [Instruction Set](https://github.com/klaytn/klaytn-docs/blob/main/docs/klaytn/design/computation/klaytn-virtual-machine/klaytn-virtual-machine/README.md#instruction-set) section.

To define `Z`, `H` and `O`, we define `w` as the current operation to be executed:

* `w := T_code[S_machine,pc]` if `S_machine,pc < len(T_code)`
* `w :=STOP` otherwise

### Instruction Set <a href="#instruction-set" id="instruction-set"></a>

NOTE: This section will be filled in the future.

## How KLVM Differs From EVM <a href="#how-klvm-differs-from-evm" id="how-klvm-differs-from-evm"></a>

As mentioned earlier, the current KLVM is based on EVM; thus, its specification currently is very similar to that of EVM. Some differences between KLVM and EVM are listed below.

* KLVM uses Klaytn's gas units, such as peb, ston, or KLAY.
* KLVM does not accept a gas price from the user; instead, it uses a platform-defined value as the gas price.

The Klaytn team will try to maintain compatibility between KLVM and EVM, but as Klaytn becomes increasingly implemented and evolves, the KLVM specification will be updated, and there will probably be more differences compared to EVM.

NOTE: This section will be updated in the future.


# Klaytn Virtual Machine (Previous docs)

{% hint style="success" %}
NOTE: This document contains the KLVM used before the activation of the protocol upgrade. If you want the latest document, please refer to [latest document](/content/klaytn/design/computation/klaytn-virtual-machine).
{% endhint %}

## Overview <a href="#overview" id="overview"></a>

The current version of the Klaytn Virtual Machine (KLVM) is derived from the Ethereum Virtual Machine (EVM). The content of this chapter is based primarily on the [Ethereum Yellow Paper](https://github.com/ethereum/yellowpaper). KLVM is continuously being improved by the Klaytn team, thus this document could be updated frequently. Please do not regard this document as the final version of the KLVM specification. As described in the Klaytn position paper, the Klaytn team also plans to adopt other virtual machines or execution environments in order to strengthen the capability and performance of the Klaytn platform. This chapter presents a specification of KLVM and the differences between KLVM and EVM.

KLVM is a virtual state machine that formally specifies Klaytn's execution model. The execution model specifies how the system state is altered given a series of bytecode instructions and a small tuple of environmental data. KLVM is a quasi-Turing-complete machine; the *quasi* qualification stems from the fact that the computation is intrinsically bounded through a parameter, *gas*, which limits the total amount of computation performed.

KLVM executes Klaytn virtual machine code (or Klaytn bytecode) which consists of a sequence of KLVM instructions. The KLVM code is the programming language used for accounts on the Klaytn blockchain that contain code. The KLVM code associated with an account is executed every time a message is sent to that account; this code has the ability to read/write from/to storage and send messages.

## KLVM Specification <a href="#klvm-specification" id="klvm-specification"></a>

### Conventions <a href="#conventions" id="conventions"></a>

We use the following notations and conventions in this document.

* `A := B`
  * `:=` is used to define `A` as `B`.
* We use the terms "smart contract" and "contract" interchangeably.
* We use the terms "opcode" as the "operation code/operation"

### Symbols <a href="#symbols" id="symbols"></a>

The following tables summarize the symbols used in the KLVM specification.

#### Blockchain-Related Symbols <a href="#blockchain-related-symbols" id="blockchain-related-symbols"></a>

| Symbol     | Description                           |
| ---------- | ------------------------------------- |
| `BC`       | Blockchain                            |
| `B`        | Block                                 |
| `B_header` | The block header of the present block |

#### State-Related Symbols <a href="#state-related-symbols" id="state-related-symbols"></a>

| Symbol           | Description                                |
| ---------------- | ------------------------------------------ |
| `S`              | State                                      |
| `S_system`       | System state                               |
| `S_machine`      | Machine state                              |
| `P_modify_state` | The permission to make state modifications |

#### Transaction-Related Symbols <a href="#transaction-related-symbols" id="transaction-related-symbols"></a>

| Symbol    | Description                                                                                                                                              |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `T`       | Transaction                                                                                                                                              |
| `T_code`  | A byte array containing machine code to be executed                                                                                                      |
| `T_data`  | A byte array containing the input data to the execution; if the execution agent is a transaction, this would be the transaction data.                    |
| `T_value` | A value, in peb, passed to the account as part of the execution procedure; if the execution agent is a transaction, this would be the transaction value. |
| `T_depth` | The depth of the present message-call or contract-creation stack (*i.e.*, the number of `CALL`s or `CREATE`s being executed at present)                  |

#### Gas-Related Symbols <a href="#gas-related-symbols" id="gas-related-symbols"></a>

| Symbol    | Description                                                       |
| --------- | ----------------------------------------------------------------- |
| `G`       | Gas                                                               |
| `G_rem`   | Remaining gas for computation                                     |
| `G_price` | The price of gas in the transaction that originated the execution |

#### Address-Related Symbols <a href="#address-related-symbols" id="address-related-symbols"></a>

| Symbol            | Description                                                                                                                              |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `A`               | Address                                                                                                                                  |
| `A_code_owner`    | The address of the account that owns the executing code                                                                                  |
| `A_tx_sender`     | The sender address of the transaction that originated the current execution                                                              |
| `A_code_executor` | the address of the account that initiated code execution; if the execution agent is a transaction, this would be the transaction sender. |

#### Functions <a href="#functions" id="functions"></a>

|   Symbol  | Description                                                                                                   |
| :-------: | ------------------------------------------------------------------------------------------------------------- |
| `F_apply` | A function that applies a transaction with input to a given state and returns the resultant state and outputs |

### Basics <a href="#basics" id="basics"></a>

KLVM is a simple stack-based architecture. The word size of the machine (and thus the size of stack items) is 256-bit. This was chosen to facilitate the Keccak-256 hash scheme and the elliptic-curve computations. The memory model is a simple word-addressed byte array. The stack has a maximum size of 1024. The machine also has an independent storage model; this is similar in concept to the memory but rather than a byte array, it is a word-addressable word array. Unlike memory, which is volatile, storage is nonvolatile and is maintained as part of the system state. All locations in both storage and memory are initially well-defined as zero.

The machine does not follow the standard von Neumann architecture. Rather than storing program code in generally accessible memory or storage, code is stored separately in virtual read-only memory and can be interacted with only through specialized instructions.

The machine can execute exception code for several reasons, including stack underflows and invalid instructions. Similar to an out-of-gas exception, these exceptions do not leave state changes intact. Rather, the virtual machine halts immediately and reports the issue to the execution agent (either the transaction processor or, recursively, the spawning execution environment), which will be addressed separately.

### Fees Overview <a href="#fees-overview" id="fees-overview"></a>

Fees (denominated in gas) are charged under three distinct circumstances.

* The first and most common is the `constantGas`. It's a fee intrinsic to the computation of the operation.
* Second, gas may be deducted to form the payment for a subordinate message call or contract creation; this forms part of the payment for `CREATE`, `CALL` and `CALLCODE`.
* Finally, gas may be charged due to an increase in memory usage.

Over an account's execution, the total fee payable for memory-usage payable is proportional to the smallest multiple of 32 bytes that are required to include all memory indices (whether for read or write) in the range. This fee is paid on a just-in-time basis; consequently, referencing an area of memory at least 32 bytes greater than any previously indexed memory will result in an additional memory usage fee. Due to this fee, it is highly unlikely that addresses will ever exceed the 32-bit bounds. That said, implementations must be able to manage this eventuality.

Storage fees have a slightly nuanced behavior. To incentivize minimization of the use of storage (which corresponds directly to a larger state database on all nodes), the execution fee for an operation that clears an entry from storage is not only waived but also elicits a qualified refund; in fact, this refund is effectively paid in advance because the initial usage of a storage location costs substantially more than normal usage.

#### Fee Schedule <a href="#fee-schedule" id="fee-schedule"></a>

The fee schedule `G` is a tuple of 37 scalar values corresponding to the relative costs, in gas, of a number of abstract operations that a transaction may incur. Also, there's gas items to calculate the gas of the precompiled contracts called by `CALL_*` opcodes. For other tables such as `intrinsic gas cost` or `key validation gas cost`, please refer to [this document](/content/klaytn/design/transaction-fees)

**Scalar values representing `constantGas` of an opcode**

| Name            | Value |   Name in code | Opcodes                                                                                                                                                                                                                                                                                                                                                                                                 |
| --------------- | ----: | -------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `G_base`        |     2 |   GasQuickStep | <p><code>ADDRESS</code>, <code>ORIGIN</code>, <code>CALLER</code>, <code>CALLVALUE</code>, <code>CALLDATASIZE</code>,<br><code>CODESIZE</code>, <code>GASPRICE</code>, <code>COINBASE</code>, <code>TIMESTAMP</code>, <code>NUMBER</code>,<br><code>DIFFICULTY</code>, <code>GASLIMIT</code>, <code>RETURNDATASIZE</code>, <code>POP</code>, <code>PC</code>, <code>MSIZE</code>, <code>GAS</code></p>  |
| `G_verylow`     |     3 | GasFastestStep | <p><code>ADD</code>, <code>SUB</code>, <code>LT</code>, <code>GT</code>, <code>SLT</code>, <code>SGT</code>, <code>EQ</code>, <code>ISZERO</code>, <code>AND</code>,<br><code>OR</code>, <code>XOR</code>, <code>NOT</code>, <code>BYTE</code>, <code>CALLDATALOAD</code>,<br><code>MLOAD</code>, <code>MSTORE</code>, <code>MSTORE8</code>, <code>PUSH</code>, <code>DUP</code>, <code>SWAP</code></p> |
| `G_low`         |     5 |    GasFastStep | `MUL`, `DIV`, `SDIV`, `MOD`, `SMOD`, `SIGNEXTEND`                                                                                                                                                                                                                                                                                                                                                       |
| `G_mid`         |     8 |     GasMidStep | `ADDMOD`, `MULMOD`, `JUMP`                                                                                                                                                                                                                                                                                                                                                                              |
| `G_high`        |    10 |    GasSlowStep | `JUMPI`                                                                                                                                                                                                                                                                                                                                                                                                 |
| `G_blockhash`   |    20 |     GasExtStep | `BLOCKHASH`                                                                                                                                                                                                                                                                                                                                                                                             |
| `G_balance`     |   400 |     BalanceGas | `BALANCE`                                                                                                                                                                                                                                                                                                                                                                                               |
| `G_sload`       |   200 |       SloadGas | `SLOAD`                                                                                                                                                                                                                                                                                                                                                                                                 |
| `G_jumpdest`    |     1 |    JumpdestGas | `JUMPDEST`                                                                                                                                                                                                                                                                                                                                                                                              |
| `G_sha3`        |    30 |        Sha3Gas | `SHA3`                                                                                                                                                                                                                                                                                                                                                                                                  |
| `G_call`        |   700 |        CallGas | `CALL`, `CALLCODE`, `STATICCALL`, `DELEGATECALL`                                                                                                                                                                                                                                                                                                                                                        |
| `G_create`      | 32000 |      CreateGas | `CREATE`, `CREATE2`                                                                                                                                                                                                                                                                                                                                                                                     |
| `G_extcodesize` |   700 | ExtcodeSizeGas | `EXTCODESIZE`                                                                                                                                                                                                                                                                                                                                                                                           |
| `G_extcodehash` |   400 | ExtcodeHashGas | `EXTCODEHASH`                                                                                                                                                                                                                                                                                                                                                                                           |

**Scalar values used to calculate the gas based on memory and log usage**

| Name         | Value | Name in Code | Description                                                                   |
| ------------ | ----: | -----------: | ----------------------------------------------------------------------------- |
| `G_memory`   |     3 |    MemoryGas | Amount of gas paid for every additional word when expanding memory            |
| `G_copy`     |     3 |      CopyGas | Partial payment for `COPY` operations, multiplied by words copied, rounded up |
| `G_log`      |   375 |       LogGas | Partial payment for a `LOG` operation                                         |
| `G_logdata`  |     8 |   LogDataGas | Amount of gas paid for each byte in a `LOG` operation's data                  |
| `G_logtopic` |   375 |  LogTopicGas | Amount of gas paid for each topic of a `LOG` operation                        |

**Scalar values used to calculate the gas of the particular opcode**

| Name             | Value | Name in Code                   | Description                                                                                                                    |
| ---------------- | ----: | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `G_sset`         | 20000 | SstoreSetGas                   | Amount of gas paid when the storage value when set storage                                                                     |
| `G_sreset`       |  5000 | SstoreResetGas, SstoreClearGas | Amount of gas paid when the storage value remains unchanged at zero or is set to zero                                          |
| `R_sclear`       | 15000 | SstoreRefundGas                | Refund Gas given (added to the refund counter) when the storage value is set to zero from nonzero                              |
| `G_exp`          |    10 | ExpGas                         | Partial payment                                                                                                                |
| `G_expbyte`      |    50 | ExpByte                        | Partial payment when multiplied by `ceil(log_256(exponent))`                                                                   |
| `G_selfdestruct` |  5000 | SelfdestructGas                | Amount of gas paid for a `SELFDESTRUCT` operation                                                                              |
| `R_selfdestruct` | 24000 | SelfdestructRefundGas          | Refund Gas given (added to the refund counter) for self-destructing an account                                                 |
| `G_callvalue`    |  9000 | CallValueTransferGas           | Amount of gas paid for a nonzero value transfer                                                                                |
| `G_callstipend`  |  2300 | CallStipend                    | Free gas given at beginning of call for a nonzero value transfer                                                               |
| `G_newaccount`   | 25000 | CallNewAccountGas              | Amount of gas paid when creating an account. It is also be defined as `CreateBySelfdestructGas` with `SELFDESTRUCT` operation. |
| `G_codedeposit`  |   200 | CreateDataGas                  | Amount of gas paid per byte for a creating a contract that succeeds in placing code into state                                 |
| `G_sha3word`     |     6 | Sha3WordGas                    | Amount of gas paid for each word (rounded up) for an `SHA3` input data                                                         |

**Items to calculate the precompiled contracts gas**

Precompiled contracts are special kind of contracts which usually perform complex cryptographic computations and are initiated by other contracts.

For example, gas cost can be calculated simply like below, but some gas cost calculation functions are very complex. So I would not explain the exact gas cost calculation function here.

```
# ecrecover, sha256hash, ripemd160hash, dataCopy
Gas = XXXBaseGas + (number of words * XXXPerWordGas)

# validateSender
Gas = number of signatures * ValidateSenderGas
```

| Address | Precompiled contracts | Item                                         | Value        |
| ------- | --------------------- | -------------------------------------------- | ------------ |
| 0x01    | ecrecover             | EcrecoverGas                                 | 3000         |
| 0x02    | sha256hash            | Sha256BaseGas, Sha256PerWordGas              | 60, 12       |
| 0x03    | ripemd160hash         | Ripemd160BaseGas, Ripemd160PerWordGas        | 600, 120     |
| 0x04    | dataCopy              | IdentityBaseGas, IdentityPerWordGas          | 15, 3        |
| 0x05    | bigModExp             | ModExpQuadCoeffDiv                           | 20           |
| 0x06    | bn256Add              | Bn256AddGas                                  | 150          |
| 0x07    | bn256ScalarMul        | Bn256ScalarMulGas                            | 6000         |
| 0x08    | bn256Pairing          | Bn256PairingBaseGas, Bn256PairingPerPointGas | 45000, 34000 |
| 0x09    | vmLog                 | VMLogBaseGas, VMLogPerByteGas                | 100, 20      |
| 0x10    | feePayer              | FeePayerGas                                  | 300          |
| 0x11    | validateSender        | ValidateSenderGas                            | 5000         |

#### Gas calculation during contract execution <a href="#gas-calculation-during-contract-execution" id="gas-calculation-during-contract-execution"></a>

The gas cost of one transaction is calculated through the methods described below. First, gas is added according to the transaction type and input. Then, if the contract is executed, opcodes are executed one by one until the execution ends or `STOP` operation appears. In the process, the cost is charged according to the `constantGas` defined for each opcode and the additionally defined gas calculation method.

Below is a brief explanation of the gas calculation logic during contract execution using the fee schedule variables defined above. As it assumes a general situation, unusual situations such as revert appears is not considered.

* add `constantGas` defined in each opcode to gas
  * e.g. if an opcode is `MUL`, add `G_low` to gas
  * e.g. if an opcode is `CREATE2`, add `G_create` to gas
* add the gas which is calculated through additionally defined gas calculation method
  * For `LOG'N'`, where N is \[0,1,2,3,4], add `G_log + memoryGasCost * g_logdata + N x G_logtopic` to gas
  * For `EXP`, add `G_exp + byteSize(stack.back(1)) x G_expbyte` to gas
  * For `CALLDATACOPY` or `CODECOPY` or `RETURNDATACOPY`, add `wordSize(stack.back(2)) x G_copy` to gas
  * For `EXTCODECOPY`, add `wordSize(stack.back(3)) x G_copy` to gas
  * For `SHA3`, add `G_sha3 + wordSize(stack.back(1)) x G_sha3word` to gas
  * For `RETURN`, `REVERT`, `MLoad`, `MStore8`, `MStore`, add `memoryGasCost` to gas
  * For `CREATE`, add `memoryGasCost + size(contract.code) x G_codedeposit`
  * For `CREATE2`, add `memoryGasCost + size(data) x G_sha3word + size(contract.code) x G_codedeposit` to gas
  * For `SSTORE`,
    * From a zero-value address to a non-zero value (NEW VALUE), add `G_sset` to gas
    * From a non-zero value address to a zero-value address (DELETE), add `G_sreset` to gas and add `R_sclear` to refund
    * From a non-zero to a non-zero (CHANGE), add `G_sreset` to gas
  * For `CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`,
    * if it is `CALL` and `CALLCODE` and if it transfers value, add `G_callvalue` to gas
    * if it is `CALL` and if it transfers value and if it is a new account, add `G_newaccount` to gas
    * if the callee contract is precompiled contracts, calculate precompiled contract gas cost and add it to gas
    * add `memoryGasCost + availableGas - availableGas/64, where availableGas = contract.Gas - gas` to gas
  * For `SELFDESTRUCT`,
    * if it transfers value and if is a new account, add `G_newaccount` to gas
    * if the contract has not suicided yet, add `R_selfdestruct` to refund

### Execution Environment <a href="#execution-environment" id="execution-environment"></a>

The execution environment consists of the system state `S_system`, the remaining gas for computation `G_rem`, and the information `I` that the execution agent provides. `I` is a tuple defined as shown below:

`I := (B_header, T_code, T_depth, T_value, T_data, A_tx_sender, A_code_executor, A_code_owner, G_price, P_modify_state)`

The execution model defines the function `F_apply`, which can compute the resultant state `S_system'`, the remaining gas `G_rem'`, the accrued substate `A` and the resultant output `O_result` when given these definitions. For the present context, we will define it as follows:

`(S_system', G_rem', A, O_result) = F_apply(S_system, G_rem, I)`

where we must remember that `A`, the accrued substate, is defined as the tuple of the suicides set `Set_suicide`, the log series `L`, the touched accounts `Set_touched_accounts` and the refunds `G_refund`:

`A := (Set_suicide, L, Set_touched_accounts, G_refund)`

### Execution Overview <a href="#execution-overview" id="execution-overview"></a>

In most practical implementations, `F_apply` will be modeled as an iterative progression of the pair comprising the full system state `S_system` and the machine state `S_machine`. Formally, we define it recursively with a function `X` that uses an iterator function `O` (which defines the result of a single cycle of the state machine) together with functions `Z`, which determines if the present state is an exceptional halted machine state, and `H`, which specifies the output data of an instruction if and only if the present state is a normal halted machine state.

The empty sequence, denoted as `()`, is not equal to the empty set, denoted as `Set_empty`; this is important when interpreting the output of `H`, which evaluates to `Set_empty` when execution is to continue but to a series (potentially empty) when execution should halt.

`F_apply(S_machine, G_rem, I, T) := (S_system', S_machine,g', A, o)`

* `(S_system', S_machine,g', A, ..., o) := X((S_system, S_machine, A^0, I))`
* `S_machine,g := G_rem`
* `S_machine,pc := 0`
* `S_machine,memory := (0, 0, ...)`
* `S_machine,i := 0`
* `S_machine,stack := ()`
* `S_machine,o := ()`
* `X((S_system, S_machine, A, I)) :=`
  * `(Set_empty, S_machine, A^0, I, Set_empty)` if `Z(S_system, S_machine, I)`
  * `(Set_empty, S_machine', A^0, I, o)` if `w = REVERT`
  * `O(S_system, S_machine, A, I) · o` if `o != Set_empty`
  * `X(O(S_system, S_machine, A, I))` otherwise

where

* `o := H(S_machine, I)`
* `(a, b, c, d) · e := (a, b, c, d, e)`
* `S_machine' := S_machine` except

  `S_machine,g' := S_machine,g - C(S_system, S_machine, I)`

  * This means that when we evaluate `F_apply`, we

    extract the remaining gas `S_machine,g'` from the

    resultant machine state `S_machine'`.

`X` is thus cycled (recursively here, but implementations are generally expected to use a simple iterative loop) until either `Z` becomes true, indicating that the present state is exceptional and that the machine must be halted and any changes are discarded, or until `H` becomes a series (rather than the empty set), indicating that the machine has reached a controlled halt.

#### Machine State <a href="#machine-state" id="machine-state"></a>

The machine state `S_machine` is defined as a tuple `(g, pc, memory, i, stack)`, which represent the available gas, the program counter `pc` (64-bit unsigned integer), the memory contents, the active number of words in memory (counting continuously from position 0), and the stack contents. The memory contents `S_machine,memory` are a series of zeroes of size 2^256.

For ease of reading, the instruction mnemonics written in small-caps (*e.g.*, `ADD`) should be interpreted as their numeric equivalents; the full table of instructions and their specifics is given in the [Instruction Set](#instruction-set) section.

To define `Z`, `H` and `O`, we define `w` as the current operation to be executed:

* `w := T_code[S_machine,pc]` if `S_machine,pc < len(T_code)`
* `w :=STOP` otherwise

### Instruction Set <a href="#instruction-set" id="instruction-set"></a>

NOTE: This section will be filled in the future.

## How KLVM Differs From EVM <a href="#how-klvm-differs-from-evm" id="how-klvm-differs-from-evm"></a>

As mentioned earlier, the current KLVM is based on EVM; thus, its specification currently is very similar to that of EVM. Some differences between KLVM and EVM are listed below.

* KLVM uses Klaytn's gas units, such as peb, ston, or KLAY.
* KLVM does not accept a gas price from the user; instead, it uses a platform-defined value as the gas price.

The Klaytn team will try to maintain compatibility between KLVM and EVM, but as Klaytn becomes increasingly implemented and evolves, the KLVM specification will be updated, and there will probably be more differences compared to EVM.

NOTE: This section will be updated in the future.


# Storage


# State Migration

As more blocks are added to the blockchain, chain data also pile up. Chain data are necessary for node operation, so they are stored in the node storage as a data structure called trie, and ultimately in a database called LevelDB. So with more blocks, comes more chain data in the storage, along with increasing cost. Klaytn, therefore, provides a feature called State Migration that allows you to reduce the amount of required storage space.

State Migration targets state tries, which comprise most of the chain data. It deletes state trie nodes that are not required for processing new blocks. It only leaves the state trie nodes that are reachable from the state trie root of a specific block. After State Migration, you are only left with the latest data required for node synchronization, consisting of state trie nodes of the target block as well as newly added blocks.

Note that a node can't read old states from blocks previous to the target block after State Migration. In other words, you can't return the balance from an old block number using the `klay_getBalance` API.

More details on the mechanism of State Migration can be found below: [Klaytn v1.5.0 State Migration: Saving Node Storage](https://medium.com/klaytn/klaytn-v1-5-0-state-migration-saving-node-storage-1358d87e4a7a) [Klaytn State Migration: An Efficient Way to Reduce Blockchain Data](https://medium.com/klaytn/klaytn-state-migration-an-efficient-way-to-reduce-blockchain-data-6615a3b36523)

To use State Migration, please refer to [`Chaindata Migration`](https://docs.klaytn.foundation/content/operation-guide/chaindata-migration) page of Operation Guide.


# StateDB Live Pruning

StateDB Live Pruning is a new technique to resolve the same problem as [State Migration](/content/klaytn/design/storage/state-migration) (data in the state trie keeps accumulating).

In StateDB, data is stored in a data structure known as StateTrie. When state data is altered in a block, multiple nodes within the Trie are modified, and the new or updated data is then stored. As the Klaytn network continues to expand, the volume of data corresondingly increases. This challenge has been mitigated through State Migration, which involves the continuous deletion of old data, thereby conserving storage spaces. Nonetheless, State Migration has its own drawbacks, as it requires traversing the entire Trie and must be triggered manually. To counteract these limitations, the StateDB Live Pruning technique was introduced.

To effectively eliminate historical data without having to traverse the entire StateTrie, it is imperative to ascertain whether a TrieNode is outdated or not at a specific time. In the original StateTrie structure, a single TrieNode could be part of multiple StateTries. Consequently, even if the state of a specific block is updated at a given point in time, some TrieNodes may be redundantly used and cannot be readily deleted. This issue is referred to as the hash duplication problem.

StateDB Live Pruning resolves this problem of State Trie by adding a unique 7-byte serial index after the 32-byte Hash, thus solving this challenge. This ensures that all nodes of any state trie are unique and can safely delete StateTrie before a specific block.

```
Hash: Keccak256 - 32-byte Hash key
ExtHash: Keccak256 - 32-byte Hash Key + 7-byte Serial index
```

Furthermore, the StateRoot is not be changed in a block since we still calculate origianl hash value from extended hash. In order to obtain the State Root value, the 7-byte Serial index added to ExtHash is removed, and the Hash is recalculated to obtain the same State Root value as before, making it backward compatible.

For more information, see this [medium blog](https://medium.com/klaytn/strong-efficient-management-of-blockchain-data-capacity-with-statedb-live-pruning-strong-6aaa09b05f91).

StateDB Live Pruning deletes data 48 hours (default) after the information has changed, so features related to querying StateDB are not supported such as past accounts balance, contract execution on outdated blocks, etc. Please carefully consider the purpose of the node you are operating before deciding to activate the StateDB Live Pruning feature.

To use StateDB Live Pruning, the following environment should be set up:

1. Use a binary of klaytn v1.11.0 or higher.
2. Please download the pruned DB snapshot from this [link](https://packages.klaytn.net/cypress/pruning-chaindata/) if you don't want to synchronize all blocks from the genesis block.
3. (Optional) Add the flag `--state.live-pruning-retention <value>` for how long recent states are retained. Default value is 172800 (48 hours)
4. Refer to the following link to set the DB location and restart the node with `--state.live-pruning` added [chaindata-change](https://ko.docs.klaytn.foundation/content/operation-guide/chaindata-change) section.


# Transaction Fees

{% hint style="success" %}
NOTE: The transaction fee has changed with the `Kore` hardfork. If you want the previous document, please refer to [previous document](/content/klaytn/design/transaction-fees/transaction-fees-previous).

`Kore` hardfork block numbers are as follows.

* Baobab Testnet: `#111736800`
* Cypress Mainnet: `#119750400`
  {% endhint %}

The transaction fee of one transaction is calculated as follows:

```
Transaction fee := (Gas used) x (GasPrice)
```

As an easy-to-understand analogy in this regard, suppose you're filling up gas at a gas station. The gas price is determined by the refinery every day, and today's price is $2. If you fill 15L up, then you would pay $30 = 15L x $2/1L for it, and the $30 will be paid out of your bank account. Also, the transaction will be recorded in the account book.

Transaction fee works just the same as above. The network determines the gas price for every block. Suppose the gas price for the current block is 30 ston. If a transaction submitted by `from` account was charged 21000 gas, then 630000 ston = (21000 gas \* 30 ston) would be paid out of the `from` account. Also, the transaction will be recorded in the block, and it will be applied in the state of all blockchain nodes.

Summing it up again, this calculated transaction fee is subtracted from the sender's or fee payer's account. However, the fee can be deducted from the balance only if the transaction is created by klay\_sendTransaction/eth\_sendTransaction. Because the other transactions cannot change the state since they cannot be included in the block. They are just a simulation in some way.

This is an overall explanation of the transaction fee, and from this point, we would give a detailed explanation of how gas price is determined and how the gas is calculated.

## GasPrice Overview <a href="#gas-price-overview" id="gas-price-overview"></a>

Unlike the ethereum, Klaytn used the fixed gas price, called `unitPrice` at first. However, since magma hardfork, Klaytn started to use dynamic gas price which concept is newly redesined by modifying the Ethereum's basefee, so called `Effective Gas Price`. Since there have been many changes about gas price, it can be pretty confusing on what value to set for gasPrice. So, we've made a guide on how to set the gas price below.

| Network  | Before BaseFee                                                                                                                      | After BaseFee                                                                                                                                                                                                             |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| klaytn   | <p>tx parameter gasPrice: network-defined. must be set as the <code>unitPrice</code><br>gasPrice: use the tx parameter gasPrice</p> | <p>tx parameter gasPrice: user-defined. It means the price the most you can pay<br>(e.g. suggestGasPrice = 2\*latestBlock.baseFee )<br>gasPrice: dynamic gasPrice, <code>baseFee</code>, which is defined by network.</p> |
| Ethereum | <p>tx parameter gasPrice: user-defined. it means the price the most you can pay.<br>gasPrice: use the tx parameter gasPrice</p>     | <p>tx parameter gasPrice: user-defined. It means the price the most you can pay.<br>gasPrice: dynamic gasPrice, <code>baseFee+tip</code>, which is defined by network.</p>                                                |

### Dynamic Gas Fee Mechanism <a href="#dynamic-gas-fee-mechanism" id="dynamic-gas-fee-mechanism"></a>

Since the magma hard fork, a dynamic gas fee mechanism has replaced the existing fixed fee policy. Dynamic gas fee policy provides a stable service to users by preventing network abuse and storage overuse. The gas fee changes according to the network situation. Seven parameters affect the `base fee(gas fee)`:

1. PREVIOUS\_BASE\_FEE: Base fee of the previous block
2. GAS\_USED\_FOR\_THE\_PREVIOUS\_BLOCK: Gas used to process all transactions of the previous block
3. GAS\_TARGET: The gas amount that determines the increase or decrease of the base fee (30 million at the moment)
4. MAX\_BLOCK\_GAS\_USED\_FOR\_BASE\_FEE: Implicit block gas limit to enforce the max basefee change rate (60 million at the moment)
5. BASE\_FEE\_DELTA\_REDUCING\_DENOMINATOR: The value to set the maximum base fee change to 5% per block (20 at the moment, can be changed later by governance)
6. UPPER\_BOUND\_BASE\_FEE: The maximum value for the base fee (750 ston at the moment, can be changed later by governance)
7. LOWER\_BOUND\_BASE\_FEE: The minimum value for the base fee (25 ston at the moment, can be changed later by governance)

### Base Fee <a href="#base-fee" id="base-fee"></a>

The basic idea of this algorithm is that the `base fee` would go up if the gas used exceeds the base gas and vice versa. It is closely related to the number of transactions in the network and the gas used in the process. There is an upper and lower limit for the `base fee` to prevent the fee from increasing or decreasing indefinitely. There is also a cap for the gas and an adjustment value for the fluctuation to prevent abrupt changes in the `base fee`. The values can be changed by governance.

```
(BASE_FEE_CHANGE_RATE) = (GAS_USED_FOR_THE_PREVIOUS_BLOCK - GAS_TARGET)
(ADJUSTED_BASE_FEE_CHANGE_RATE) = (BASE_FEE_CHANGE_RATE) / (GAS_TARGET) / (BASE_FEE_DELTA_REDUCING_DENOMINATOR)
(BASE_FEE_CHANGE_RANGE) = (PREVIOUS_BASE_FEE) * (ADJUSTED_BASE_FEE_CHANGE_RATE)
(BASE_FEE) = (PREVIOUS_BASE_FEE) + (BASE_FEE_CHANGE_RANGE) 
```

The `base fee` is calculated for every block; there could be changes every second. Transactions from a single block use the same `base fee` to calculate transaction fees. Only transactions with a gas price higher than the block `base fee` can be included in the block. Half of the transaction fee for each block is burned (BURN\_RATIO = 0.5, cannot be changed by governance).

> NOTE: An important feature that sets Klaytn apart from Ethereum's EIP-1559 is that it does not have tips. Klaytn follows the First Come, First Served(FCFS) principle for its transactions.

## Gas Overview <a href="#gas-overview" id="gas-overview"></a>

Every action that changes the state of the blockchain requires gas. While processing the transactions in a block, such as sending KLAY, using KIP-7 tokens, or executing a contract, the user has to pay for the computation and storage usage. The payment amount is decided by the amount of `gas` required.

`Gas` required is computed by adding up the next two gases;

* `IntrinsicGas` is a gas that is statically charged based on the configuration of the transaction, such as the datasize of the transaction.
* `ContractExecutionGas`, on the other hand, is a gas that is dynamically calculated due to the contract execution.

In here, we would focus on how `IntrinsicGas` is organized. For the `ContractExecutionGas`, the klvm documentation describes it in detail, so please refer [klvm docs](/content/klaytn/design/computation/klaytn-virtual-machine).

Coming back to `IntrinsicGas`, a transaction's `intrinsicGas` can be calculated by adding up the next four factors.

```
IntrinsicGasCost = KeyCreationGas + KeyValidationGas + PayloadGas + TxTypedGas
```

* `PayloadGas` is calculated based on the size of the data field in the tx.
* `KeyCreationGas` is calculated when the transaction registers new keys. Only applicable in `accountUpdate` transaction.
* `KeyValidationGas` is calculated based on the number of signatures.
* `TxTypedGas` is defined based on the transaction types.

Before we get into the detail, keep in mind that not all key types apply the keyGases (`KeyCreationGas` and `KeyValidationGas`).

| Key Type  | Are those keyGases applicable?     |
| --------- | ---------------------------------- |
| Nil       | No                                 |
| Legacy    | No                                 |
| Fail      | No                                 |
| Public    | Yes                                |
| MultiSig  | Yes                                |
| RoleBased | Depending on key types in the role |

### KeyCreationGas <a href="#keycreationgas" id="keycreationgas"></a>

The KeyCreationGas is calculated as `(number of registering keys) x TxAccountCreationGasPerKey (20000)`.\
Please Keep in mind that Public key type always has only one registering key, so the gas would be always 20000.

### KeyValidationGas <a href="#keyvalidationgas" id="keyvalidationgas"></a>

The KeyValidationGas is calculated as `(number of signatures - 1) x TxValidationGasPerKey(15000)`.\
Please keep in mind that Public key type always has only one signature key, so the gas would be always zero.

A Klaytn transaction can also have a feePayer, so the total KeyValidationGas is like this.

```
KeyValidationGas =  (KeyValidationGas for a sender) + (KeyValidationGas for a feePayer)
```

### PayloadGas <a href="#payloadgas" id="payloadgas"></a>

Calculating `PayloadGas` is simple. It is calculated as `(number_of_bytes_of_tx_input) x TxDataGas(100)`

### TxTypedGas <a href="#txtypedgas" id="txtypedgas"></a>

There are three types of transactions in klaytn; `base`, `feeDelegated`, and `feeDelegatedWithFeeRatio`.

For example,

* TxTypeValueTransfer is the `base` type of the valueTransaction transaction.
* TxTypeFeeDelegatedValueTransfer is a `feeDelegated` type of the valueTransfer transaction.
* TxTypeFeeDelegatedValueTransferWithRatio is a `feeDelegatedWithRatio` type of the valueTransfer transaction.

This is important when calculating TxTypedGas:

* First, check the TxType is `feeDelegated` or `feeDelegatedWithFeeRatio`.
  * If the TxType is `feeDelegated`, add `TxGasFeeDelegated(10000)` to TxTypedGas
  * If the TxType is `feeDelegatedWithFeeRatio`, add `TxGasFeeDelegatedWithRatio (15000)` to TxTypedGas
* Second, check the transaction creates contract or not.
  * If the transaction creates contract, add `TxGasContractCreation (53000)` to TxTypedGas.
  * Otherwise, add `TxGas (21000)` to TxTypedGas.

For example,

* If it's legacyTransaction and creates contract, the TxTypedGas would be `0 + TxGasContractCreation(53000)`.
* If it's TxTypeFeeDelegatedValueTransfer, the TxTypedGas would be `TxGasFeeDelegated(10000) + TxGas (21000)`
* If it's TxTypeFeeDelegatedSmartContractDeployWithRatio, the TxTypedGas would be `TxGasFeeDelegatedWithRatio (15000) + TxGasContractCreation (53000)`


# Transaction Fees (Previous docs)

{% hint style="success" %}
NOTE: This document contains the transaction fee used before the activation of the protocol upgrade. If you want the latest document, please refer to [latest document](/content/klaytn/design/transaction-fees).
{% endhint %}

The transaction fee of one transaction is calculated as follows:

```
Transaction fee := (Gas used) x (GasPrice)
```

As an easy-to-understand analogy in this regard, suppose you're filling up gas at a gas station. The gas price is determined by the refinery every day, and today's price is $2. If you fill 15L up, then you would pay $30 = 15L x $2/1L for it, and the $30 will be paid out of your bank account. Also, the transaction will be recorded in the account book.

Transaction fee works just the same as above. The network determines the gas price for every block. Suppose the gas price for the current block is 30 ston. If a transaction submitted by `from` account was charged 21000 gas, then 630000 ston = (21000 gas \* 30 ston) would be paid out of the `from` account. Also, the transaction will be recorded in the block, and it will be applied in the state of all blockchain nodes.

Summing it up again, this calculated transaction fee is subtracted from the sender's or fee payer's account. However, the fee can be deducted from the balance only if the transaction is created by klay\_sendTransaction/eth\_sendTransaction. Because the other transactions cannot change the state since they cannot be included in the block. They are just a simulation in some way.

This is an overall explanation of the transaction fee, and from this point, we would give a detailed explanation of how gas price is determined and how the gas is calculated.

## Unit Price Overview <a href="#unit-price-overview" id="unit-price-overview"></a>

`Unit price` is the price for a single gas. The unit price (also called `gas price`) is set in the system by the governance. It cannot be changed by user. The current value of the unit price can be obtained by calling the `klay.gasPrice` API.

In Ethereum, users set the gas price for each transaction, and miners choose which transactions to be included in their block to maximize their reward. It is something like bidding for limited resources. This approach has been working because it is market-based. However, the transaction cost fluctuates and often becomes too high to guarantee the execution.

To solve the problem, Klaytn is using a fixed unit price and the price can be adjusted by the governance council. This policy ensures that every transaction will be handled equally and be guaranteed to be executed. Therefore, users do not need to struggle to determine the right unit price.

### Transaction Validation against Unit Price <a href="#transaction-validation-against-unit-price" id="transaction-validation-against-unit-price"></a>

Klaytn only accepts transactions with gas prices, which can be set by the user, that are equal to the unit price of Klaytn; it rejects transactions with gas prices that are different from the unit price in Klaytn.

### Unit Price Error <a href="#unit-price-error" id="unit-price-error"></a>

The error message `invalid unit price` is returned when the gas price of a transaction is not equal to the unit price of Klaytn.

### Transaction Replacement <a href="#transaction-replacement" id="transaction-replacement"></a>

Klaytn currently does not provide a way to replace a transaction using the unit price but may support different methods for the transaction replacement in the future. Note that in Ethereum, a transaction with a given nonce can be replaced by a new one with a higher gas price.

## Gas Overview <a href="#gas-overview" id="gas-overview"></a>

Every action that changes the state of the blockchain requires gas. While processing the transactions in a block, such as sending KLAY, using KIP-7 tokens, or executing a contract, the user has to pay for the computation and storage usage. The payment amount is decided by the amount of `gas` required.

`Gas` required is computed by adding up the next two gases;

* `IntrinsicGas` is a gas that is statically charged based on the configuration of the transaction, such as the datasize of the transaction.
* `ContractExecutionGas`, on the other hand, is a gas that is dynamically calculated due to the contract execution.

In here, we would focus on how `IntrinsicGas` is organized. For the `ContractExecutionGas`, the klvm documentation describes it in detail, so please refer [klvm docs](/content/klaytn/design/computation/klaytn-virtual-machine/klaytn-virtual-machine-previous).

Coming back to `IntrinsicGas`, a transaction's `intrinsicGas` can be calculated by adding up the next four factors.

```
IntrinsicGasCost = KeyCreationGas + KeyValidationGas + PayloadGas + TxTypedGas
```

* `PayloadGas` is calculated based on the size of the data field in the tx.
* `KeyCreationGas` is calculated when the transaction registers new keys. Only applicable in `accountUpdate` transaction.
* `KeyValidationGas` is calculated based on the number of signatures.
* `TxTypedGas` is defined based on the transaction types.

Before we get into the detail, keep in mind that not all key types apply the keyGases (`KeyCreationGas` and `KeyValidationGas`).

| Key Type  | Are those keyGases applicable?     |
| --------- | ---------------------------------- |
| Nil       | No                                 |
| Legacy    | No                                 |
| Fail      | No                                 |
| Public    | Yes                                |
| MultiSig  | Yes                                |
| RoleBased | Depending on key types in the role |

### KeyCreationGas <a href="#keycreationgas" id="keycreationgas"></a>

The KeyCreationGas is calculated as `(number of registering keys) x TxAccountCreationGasPerKey (20000)`.\
Please Keep in mind that Public key type always has only one registering key, so the gas would be always 20000.

### KeyValidationGas <a href="#keyvalidationgas" id="keyvalidationgas"></a>

The KeyValidationGas is calculated as `(number of keys - 1) x TxValidationGasPerKey(15000)`.\
Please keep in mind that Public key type always has only one signature key, so the gas would be always zero.

A Klaytn transaction can also have a feePayer, so the total KeyValidationGas is like this.

```
KeyValidationGas =  (KeyValidationGas for a sender) + (KeyValidationGas for a feePayer)
```

### PayloadGas <a href="#payloadgas" id="payloadgas"></a>

`PayloadGas` is calculated as below.

```
# legacy-typed transaction
PayloadGas = number_of_zero_bytes x TxDataZeroGas (4) + number_of_nonzero_bytes x TxDataNonZeroGas (68)`

# non legacy-typed transaction
PayloadGas = number_of_bytes * TxDataGas (100)
```

### TxTypedGas <a href="#txtypedgas" id="txtypedgas"></a>

There are three types of transactions in klaytn; `base`, `feeDelegated`, and `feeDelegatedWithFeeRatio`.

For example,

* TxTypeValueTransfer is the `base` type of the valueTransaction transaction.
* TxTypeFeeDelegatedValueTransfer is a `feeDelegated` type of the valueTransfer transaction.
* TxTypeFeeDelegatedValueTransferWithRatio is a `feeDelegatedWithRatio` type of the valueTransfer transaction.

This is important when calculating TxTypedGas:

* First, check the TxType is `feeDelegated` or `feeDelegatedWithFeeRatio`.
  * If the TxType is `feeDelegated`, add `TxGasFeeDelegated(10000)` to TxTypedGas
  * If the TxType is `feeDelegatedWithFeeRatio`, add `TxGasFeeDelegatedWithRatio (15000)` to TxTypedGas
* Second, check the transaction creates contract or not.
  * If the transaction creates contract, add `TxGasContractCreation (53000)` to TxTypedGas.
  * Otherwise, add `TxGas (21000)` to TxTypedGas.

For example,

* If it's legacyTransaction and creates contract, the TxTypedGas would be `0 + TxGasContractCreation(53000)`.
* If it's TxTypeFeeDelegatedValueTransfer, the TxTypedGas would be `TxGasFeeDelegated(10000) + TxGas (21000)`
* If it's TxTypeFeeDelegatedSmartContractDeployWithRatio, the TxTypedGas would be `TxGasFeeDelegatedWithRatio (15000) + TxGasContractCreation (53000)`


# Klaytn native coin - KLAY

## KLAY <a href="#klay" id="klay"></a>

KLAY is the main internal transferable cryptocurrency of Klaytn and is used to pay transaction fees when creating or executing smart contracts or when transferring KLAY.

KLAY is a necessary element--a fuel--for operating the Klaytn distributed application platform. It is a form of payment made by the clients of the platform to the consensus nodes (CNs) executing the requested operations. To put it another way, KLAY is an incentive; it ensures that developers write high-quality applications (wasteful code costs more) and that the network remains healthy (CNs are compensated for the resources they contribute).

## Units of KLAY <a href="#units-of-klay" id="units-of-klay"></a>

Klaytn uses the following unit system for KLAY.

* `peb` is the smallest currency unit.
* `ston` is an alias for `Gpeb` and introduced for convenience.
* A `KLAY` is 10^18 peb.

| Unit  | peb value | peb                                       |
| ----- | --------- | ----------------------------------------- |
| peb   | 1 peb     | 1                                         |
| kpeb  | 10^3 peb  | 1,000                                     |
| Mpeb  | 10^6 peb  | 1,000,000                                 |
| Gpeb  | 10^9 peb  | 1,000,000,000                             |
| ston  | 10^9 peb  | 1,000,000,000                             |
| uKLAY | 10^12 peb | 1,000,000,000,000                         |
| mKLAY | 10^15 peb | 1,000,000,000,000,000                     |
| KLAY  | 10^18 peb | 1,000,000,000,000,000,000                 |
| kKLAY | 10^21 peb | 1,000,000,000,000,000,000,000             |
| MKLAY | 10^24 peb | 1,000,000,000,000,000,000,000,000         |
| GKLAY | 10^27 peb | 1,000,000,000,000,000,000,000,000,000     |
| TKLAY | 10^30 peb | 1,000,000,000,000,000,000,000,000,000,000 |

#### APIs Related to KLAY Units <a href="#apis-related-to-klay-units" id="apis-related-to-klay-units"></a>

`klay.toPeb` and `klay.fromPeb` are convenient APIs for converting between KLAY units.

```
$ ./klay attach data/dd/klay.ipc
...
> klay.fromPeb(25, "peb")
"25"
> klay.fromPeb(25, "Gpeb")
"0.000000025"
> klay.fromPeb(25, "ston")
"0.000000025"
> klay.fromPeb(25, "KLAY")
"0.000000000000000025"
> klay.toPeb(25, "peb")
"25"
> klay.toPeb(25, "ston")
"25000000000"
> klay.toPeb(25, "KLAY")
"25000000000000000000"
```

You can get the list of all units supported by `klay.toPeb` and `klay.fromPeb` by sending an invalid unit string such as the one below.

```
> klay.toPeb(1, "something-does-not-exist")
Error: This unit doesn't exist, please use one of the following units
"noKLAY": "0"
"peb": "1"
"kpeb": "1000"
"Mpeb": "1000000"
"Gpeb": "1000000000"
"ston": "1000000000"
"uKLAY": "1000000000000"
"mKLAY": "1000000000000000"
"KLAY": "1000000000000000000"
"kKLAY": "1000000000000000000000"
"MKLAY": "1000000000000000000000000"
"GKLAY": "1000000000000000000000000000"
"TKLAY": "1000000000000000000000000000000"

    at web3.js:2170:19
    at web3.js:2255:49
    at <anonymous>:1:1
```


# Token Economy

## Overview <a href="#overview" id="overview"></a>

Klaytn’s token economy is designed to create sustainable funding structures for empowering its ecosystem, growth initiatives, and strategic investments. Many public blockchain projects have monetary systems that solely incentivize their node operators (miners or block producers), focusing only on the technical aspect of network maintenance. However, such designs miss out on the importance of incentivizing other types of participants who contribute to the growth of the network’s token economy or invest in long-term growth prospects. In contrast, Klaytn’s token economy is designed to compensate more diverse forms of contributions from a wider range of participants, and has built-in funding structure to procure sustained resources to fuel future growth initiatives and strategically sourced investment projects in addition to maintaining its blockchain nodes.

## Funding Structure <a href="#funding-structure" id="funding-structure"></a>

Klaytn’s funding structure runs continuously with Klaytn network’s block generation. With every new block, newly issued KLAY and the sum of transaction fees used in the block (collectively called “block reward”) are aggregated and distributed to the following three destination accounts in accordance to the predetermined ratio:

* Klaytn Governance Council (GC) Reward:
  * GC Block Proposer Reward: 10%
  * GC Staking Award: 40%
* Klaytn Community Fund (KCF): 30%
* Klaytn Foundation Fund (KFF): 20%

6.4 KLAY will be minted for every new block. This implies that approximately 200 million KLAY will be minted annually, which is equivalent to 2% annual inflation against the 10 billion KLAY issued at genesis (the annual inflation rate is subject to change through the Klaytn Governance Process). Transaction fee is charged per OPCODE and is metered according to the transaction fee table. For detailed information on the transaction fee table, please refer to [Transaction Fees](/content/klaytn/design/transaction-fees).

## Klaytn Governance Council Reward <a href="#klaytn-governance-council-reward" id="klaytn-governance-council-reward"></a>

Klaytn Governance Council is the collective group of Core Cell Operators (CCOs). Council members are responsible for maintaining Core Cells (CCs), which makes the Council an essential body in the Klaytn ecosystem responsible for providing the underlying infrastructure. To become a Council member, the candidate must undergo a qualification review by the Klaytn Governance Process and must stake at least 5 million KLAY. The Klaytn Governance Council Reward is a structure for incentivizing Council members to continue to provide a stable foundation for the Klaytn ecosystem.

### Klaytn Governance Council Reward Mechanism <a href="#klaytn-governance-council-reward-mechanism" id="klaytn-governance-council-reward-mechanism"></a>

For every block, a Committee composed of randomly selected Council members is formed. Each Committee has one member assigned the role of Proposer; all other Committee members assume the role of Validators. When a block is successfully created and added to the Klaytn blockchain, the Proposer of the said block is rewarded with 100% of the block reward. The probability of a Council member being selected a Proposer is proportional to the amount of KLAY staked by the member; that is, the more KLAY a member stakes, the more likely that the member will be selected as a Proposer and potentially claim the block reward.

As long as the minimum 5 million KLAY staking requirement is met, Klaytn Governance Council members can freely stake or unstake his or her own KLAY. Staking information is updated every 86,400 blocks, and newly staked KLAY comes info effect two update cycles later from when the staking is completed. Withdrawing staked KLAY requires one week of delay to prevent malicious members from immediately exiting.

To prevent monopolized claiming of Klaytn Governance Council Reward by small groups of highly invested Council members, Gini coefficient may be used to adjust the effective amount of staked KLAY. The application formula is as follows, where G stands for gini coefficient of Governance Council's KLAY staking distribution:

* *Adjusted staking amount = (Council member's staking amount)^(1/1+G)*

### Penalty for Misbehaving Council Members <a href="#penalty-for-misbehaving-council-members" id="penalty-for-misbehaving-council-members"></a>

A Council member may be subject to penalties for conducting misbehaviors defined below. In the future, more penalty rules can be established and refined through the Klaytn Governance Process.

Causing Safety Failure:

* A Council member selected as Proposer may not create more than one block in the same height
* A Council member selected as Proposer may not intentionally omit certain transactions

Causing Liveness Failure:

* A Council member selected as Proposer must create a valid block
* A Council member selected as Validator must validate the block proposed by the Proposer

## Klaytn Community Fund <a href="#klaytn-community-fund" id="klaytn-community-fund"></a>

The Klaytn Community Fund (KCF) was established to support Klaytn's mission of enabling greater transparency and verifiability. It's important to keep in mind that the former Klaytn Growth Fund (KGF) and Klaytn Improvement Reserve (KIR) have merged to become the new Klaytn Community Fund (KCF).

The Klaytn Community Fund will be used to fund activities that improves the Klaytn ecosystem, such as:

1. **Rewarding Proof of Contribution**: The KCF will provide follow-up support, such as gas fee support to projects that have made significant on-chain contributions to the Klaytn ecosystem among services that have already been developed.
2. **Building our Developer Community**: The KCF will support various initiatives including hackathons, development education programs, collaborative research with the industry, and collaboration with various DAOs to foster and grow the Klaytn developer community.
3. **Fostering Ecosystem Services and Infrastructure**: The KCF will support essential ecosystem infrastructure, alongside the development of services with clear utility and provide marketing support.
4. **Klaytn Eco Fund Indirect Investment**: The KCF will make indirect mid-to long-term investments by entrusting specialized crypto VCs, and most of the profits generated upon subsequent investment recovery will be returned to the Klaytn ecosystem.

The administration of the Klaytn Community Fund follows a process in which the GC reviews and approves the use of funds in public forums on [Klaytn Square](https://square.klaytn.foundation/Home). The Foundation will submit a budget proposal for each category to the GC for approval. Within the approved budget, each specific use will be reviewed and approved again by the GC. In the meantime, the KCF is currently being run as a [pilot program](https://klaytn.foundation/kcf-grant-pilot/) and interested parties can visit the [Klaytn Governance Forum](https://govforum.klaytn.foundation/t/operational-procedures-of-the-kcf-grant-program-pilot/288) for more details about the program.

## Klaytn Foundation Fund <a href="#klaytn-foundation-fund" id="klaytn-foundation-fund"></a>

Klaytn Foundation Fund (KFF) is an operational fund that will focus on this two main categories:

1. **Ecosystem Support**: This includes providing minor financial assistance, securing new GC members, liquidity provisions, and developing / funding services led by the Foundation.
2. **Foundation Operations**: This includes operating expenses such as development, accounting, infrastructure operations, marketing, and labor, as well as financial management and investment attraction costs.

Similar to KCF, KFF will be executed autonomously and transparently after obtaining approval from the GC via on-chain voting.

For more information, kindly read this [article](https://medium.com/klaytn/klaytn-tokenomics-optimization-governance-proposal-securing-a-sustainable-verifiable-token-1efd2a49b04e).


# Governance

## Overview <a href="#overview" id="overview"></a>

### Klaytn Governance: Taking the First Step to Decentralization <a href="#klaytn-governance-taking-the-first-step-to-decentralization" id="klaytn-governance-taking-the-first-step-to-decentralization"></a>

The Klaytn Governance Council is a council that has the right to decide various governance matters. To secure its reliability, the early members of the Governance Council have been limited to trusted organizations. This was chosen for the sake of efficiency in the platform's development and stabilization stage. Klaytn reached the stage by joining hands with 31 Governance Council Members and a seamless operation of the Klaytn Mainnet.

Klaytn believes that Klaytn governance should lead Klaytn’s growth aligned with the transition of our world. One of the key transitions in the world is coming from the growth of the metaverse. The technological advancements are ushering in a more metaversified world. In particular, we are witnessing the growth of the influence of non-traditional entities such as Decentralized Autonomous Organizations (DAOs) and builders. As an organization operating on smart contracts without a centralized structure, DAOs will be a core entity in the metaverse. Builders will have more influence by contributing to the operation and growth of the metaverse.

We are reorganizing our governance structure to better accommodate to the changing world. In addition to traditional enterprises, Klaytn is opening up the Membership of the Klaytn Governance Council to the non-traditional entities mentioned above.

By introducing a stake-based governance model and eliminating the Gini Coefficient from Klaytn’s voting mechanism, Klaytn enables governance participants who can gather more support from Klaytn Communities to shape Klaytn in line with their preference. Entities who can make a proper decision in a Metaversified world will have more influence in the Klaytn GC. We believe DAOs and builders will lead the scene in the future.

When the level of metaversification crosses the critical threshold, Klaytn governance will be fully decentralized with various types of entities. Ultimately, Klaytn will evolve into a DAO of DAOs and a platform for DAOs to communicate the voices of Klaytn Communities through on-chain mechanisms.

## Governance Topics <a href="#governance-topics" id="governance-topics"></a>

The main topics that can be decided through the governance structure include the following three areas, and proposals that require additional decision making may be introduced in a regular meeting or temporary meeting for review. The Klaytn Governance Council must make decisions that are best for the growth of Klaytn.

* **Technology**
  * Matters related to the technical update of the platform. Here the issues on the blockchain's basic structure (e.g., Account Structure), new features (e.g., L2 solution), or software update schedule are included.
* **Economy**
  * Issues relating to additional issuance of KLAY and its distribution structure, changes in transaction fees, and Klaytn Improvement Reserve spending approval etc. are included in this category.
* **Governing Rule**
  * The governance subjects and processes, as well as the rules for the responsibilities and rights of governing bodies, are included in this category.

## Governance Process <a href="#governance-process" id="governance-process"></a>

Klaytn principally aims for the governance process to occur within the protocol (on-chain). Through this process, the votes will be recorded on the blockchain, and the results will be carried out following the vote. As the platform grows, more matters will be handled through on-chain governance.

### General Governance Process <a href="#general-governance-process" id="general-governance-process"></a>

The initial governance process proceeds in the following order: proposal introduction, statement of opinion submitted by advisors, voting by council members, and various follow-up procedures depending on the result of the vote.

Those who have the right to introduce proposals can make sure each proposal is voted on by introducing it. Once the proposal is introduced, the advisors must conduct expert analysis on the proposal and submit a statement of opinion with their results.

During the initial phase of Klaytn governance, the Klaytn Governance Council members will have the right to vote on the introduced proposals and will reference the advisors' statements of opinion to vote on what they believe to be the best option. If the number of votes passes the threshold, the proposal will pass; if not, the proposal will be dismissed. In its initial phase, the voting process may be replaced by a discussion process facilitated by the Klaytn foundation. The follow-up measures for an approved proposal will be led by the chairman, and the chairman has the responsibility to carry out all the proposals that have been passed by the council during his or her term.

## Governance Roadmap <a href="#governance-roadmap" id="governance-roadmap"></a>

The bodies participating in governance must act in consideration of Klaytn’s long-term benefits rather than just for their personal interests, and they must actively participate in the governance process. Additionally, all participants that contribute to the network as Klaytn Governance Council members must secure computing resources that are greater than the platform requirements and stake a set amount KLAY of their own or from third parties. For smooth operations in development and stabilization of the platform, Klaytn Foundation will take on many roles in governance related matters in the initial development phase. In the future, however, other bodies will gradually take on greater roles in the decision-making process, and they will have the right to participate independently.

* **Development Phase**: The initial development phase after the mainnet launch must quickly see parameter adjustments, new feature developments, etc. For this to be possible, many issues will be decided through gathering the opinions of the Klaytn Governance Council members, service providers, and community members. To secure initial stabilization, Klaytn Foundation will lead the decision-making process. Additionally, all decided matters will be transparently shared with the public.
* **Stabilization Phase**: The Klaytn Governance Council has governing rights on many proposals and this phase will gradually begin starting Jan 2021. For special matters such as those concerning platform development, and matters that directly affect the overall Klaytn ecosystem, Klaytn foundation may facilitate the discussion and execution.
* **Decentralization Phase**: Following the stabilization period, a number of non-traditional entities such as DAOs and builders may be brought into the decision-making process for additional opinions. Decentralization phase may be gradually achieved through multiple stages with different governing rules and participants.


# Multi-Channel

A Klaytn node can be run with **Multi-channel**.

If a node is executed with multi-channel configuration, 2 ports are set up for communication. On the otherhand, if a node is executed with single channel configuration, 1 port is set up. If 2 multi-channel nodes are trying to connect, a connection is established using 2 ports. Otherwise, they will use 1 port for communication.

A multi-channel node can be enabled through the flag `--multichannel`. If you use [`kend`](/content/installation-guide/deployment/endpoint-node/installation-guide/startup-the-en), multi-channel is enabled by default due to the statement `MULTICHANNEL=1` in [`kend.conf`](/content/installation-guide/deployment/endpoint-node/installation-guide/configuration). To disable multi-channel, please replace the statement with `MULTICHANNEL=0`. If you want to run a node with specific ports, flags `port` and `subport` can be used. If you want to specify ports values of a connecting peer, check out [KNI](/content/klaytn/design/kni).

## Architecture <a href="#architecture" id="architecture"></a>

![Multi-Channel Server](/files/s1xsvPNPYw5Tk6GPJHVj)

The picture above shows a connection between two multi-channel nodes. Two ports, mainport (A) and subport (B), transfer different messages.

* **Mainport**(A) is used to transfer messages related to blocks and consensus protocols.
  * Block messages include requests and responses of the hash, header, body and receipt of a block.
  * Consensus messages include Request, Preprepare, Prepare, Commit and RoundChange. The meaning of the messages can be found in [PBFT](/content/klaytn/design/consensus-mechanism#pbft-practical-byzantine-fault-tolerance).
* **Subport**(B) is for transferring transaction messages.

![Single Channel Server](/files/blK0NArmzY93h1kyeHRl)

The picture shows a connection between two single channel nodes or between a single channel node and a multi-channel node. In this case, all messages related to blocks, transactions, and consensus protocols are transported via the same port.

## Ports <a href="#multichannel-port" id="multichannel-port"></a>

To set port numbers in KNI, please refer to [the KNI scheme](/content/klaytn/design/kni).

* Single Channel : A single channel node uses one port (default is 32323).
* Multi-Channel: A multi-channel node uses two ports. The ports can be specified in `port` and `subport`. In Klaytn, the default values of `port` and `subport` are 32323 and 32324, respectively.
  * You might not set `subport` when connecting to multi-channel node. In this case, at first, a Klaytn node tries to connect using a single-channel. In handshake process, the actual peer's port numbers are revealed. If the peer is a multi-channel node, the ongoing connection will be canceled and a reconnection will be made with the updated ports.


# KNI

**KNI (Klaytn Network Identifier)** is a URL scheme to identify a Klaytn node. Its syntax is shown below:

```
kni://<nodeID>@<hostname>:<port>?subport=<subport>&discport=<discport>
```

![KNI scheme](/files/M1KxkdMrpxoJx7Kzd5j6)

**nodeID** is a 512-bit public key corresponding to the node's private key. It is used to verify communication with peers on p2p network.

**hostname** describes the address of a node, located between `@` and `:`. The address format can be one of the following:

* IPv4 dotted decimal (`192.0.2.1`)
* IPv6 (`[2001:db8::68]`)
* IPv4-mapped IPv6 (`[2001:db8:3c4d:15::abcd:ef12]`)
* Domain name (`your.node.com`)

**port** is used to make connections with peer nodes through TCP. In Klaytn, the default `port` is `32323` and the default `subport` is `32324`. Note that the default `subport` is configured as `port + 1` in `kend.conf`. Depending on the number of TCP listening ports, Klaytn offers two [types of connections](/content/klaytn/design/multiport).

**discport** is used for checking if the known neighbors are reachable klaytn nodes and fetching their neighbors' addresses for new connections. Note that this is a UDP port. By default, the UDP port, or `discport`, uses the same port with the TCP port. If the node uses a different port for `discport`, it can be specified by the `discport` query parameter.

The following two URLs shows a KNI example of a node having IP address `10.0.0.1` and TCP listening port `32323` and `32324`. If `discport` is omitted, it is set to the UDP port of `32323`, same as the value of `port`.

```
kni://a979...163c@10.0.0.1:32323                 # either single-channel or multi-channel peer with omitted subport
kni://a979...163c@10.0.0.1:32323?subport=32324   # multi-channel peer
```

The next two shows KNI examples of nodes having `discport` of `30301`.

```
kni://a979...163c@10.0.0.1:32323?discport=30301                 # either single-channel or multi-channel peer with omitted subport
kni://a979...163c@10.0.0.1:32323?subport=32324&discport=30301   # multi-channel peer
```

If you want to know how to generate a KNI of a node, please refer to [Node Key & Node URI Creation](/content/installation-guide/deployment/core-cell/installation-guide/before-you-install#node-key-node-uri-creation). The KNI scheme is used in node discovery protocol, [setting `static-nodes.json` file](/content/installation-guide/deployment/core-cell/installation-guide/proxy-node-setup/configuration#install-static-nodes-json), [addPeer API](/content/dapp/json-rpc/api-references/admin#admin_addpeer), [bootnodes option](/content/operation-guide/configuration#properties) and etc.


# Scaling Solutions

### Service Chain <a href="#service-chain" id="service-chain"></a>

Service chains in Klaytn are auxiliary blockchains independent from the Klaytn main chain, tailored for individual dApp requiring special node configurations, customized security levels, or exceptionally high throughput that makes deploying the dApp on the main chain inconvenient or economically infeasible.

While there are fully-decentralized scaling solutions, due to their difficult interfaces such as challenge or exit and non-immediate finality, we take a different approach in Klaytn’s Service Chain by sacrificing the full decentralization for better usability, instant finality, high performance, and high availability.

Klaytn service chains may be used for various service-specific goals, and can connect to the main chain for multiple reasons including data anchoring (periodic storing of block hashes from the service chain onto the main chain to compensate for the decreased security of the service chain due to the smaller number of nodes) or value transfer (interchain transfer of KLAY, Klaytn’s native unit of value, and the tokens issued by dApps).

### Network <a href="#network" id="network"></a>

Service chains connected to Klaytn main chain are collectively called Service Chain Network. Note that the method of connection between service chains and the main chain may change in Klaytn’s future iterations.

![Figure 1. Klaytn Main Chain and Service Chain](/files/LpV0dVZG0ctS5feFxyLd)

Figure 1 shows the network topology of service chains being used to meet various business needs, connected with Klaytn main chain to expand the Klaytn network.

![Figure 2. Main Chain and Service Chain Connection using Main/Sub-Bridge Model](/files/oJm3XSqpLjLKQrrMw7XW)

Figure 2 shows an example of SCN (Service Chain Consensus Node) connected directly with Klaytn main chain’s EN (Endpoint Node) using a main/sub-bridge model in using the service chain’s features.

### Features <a href="#features" id="features"></a>

Service Chain expands and augments Klaytn by providing a data integrity mechanism and supporting token transfers between different chains.

#### Data Anchoring <a href="#data-anchoring" id="data-anchoring"></a>

For data integrity, Service Chain can automatically anchor every service chain block hash as a special transaction to the main chain. This data anchoring can ensure to the service users that the data in the service chain cannot be altered once it is created.

#### Value Transfer <a href="#value-transfer" id="value-transfer"></a>

To help the service providers (SPs) to easily migrate service users and values across chains, transferring tokens, such as KLAY (Klaytn's native unit of value) and Klaytn tokens issued by dApps, between different chains can be enabled. Users can easily request to transfer tokens to other chains by sending a transaction to a special contract, called bridge contract.


# Getting Started

Try and get familiar with Klaytn. This chapter is the starting point of your journey to Klaytn dApps.


# Deploying Smart Contract Using Foundry

![](/files/vHUq0K3glgMV4GlG6XpY)

## Introduction

Foundry is a smart contract development framework written in Rust that enables developers to manage and compile contracts, run tests, deploy contracts, and interact with the network from the command line via solidity scripts.

Foundry consists of four main CLI tools that allow for fast and modular smart contract development, namely:

* [Forge](https://github.com/foundry-rs/foundry/tree/master/forge): You can deploy, test, and compile smart contracts using Forge.
* [Cast](https://github.com/foundry-rs/foundry/tree/master/cast): Cast has made it simple to interact with EVM smart contracts. This includes obtaining chain data, sending transactions, and other things.
* [Anvil](https://github.com/foundry-rs/foundry/tree/master/anvil): Do you need to spin up a local node? Anvil is a local node environment offered by Foundry.
* [Chisel](https://github.com/foundry-rs/foundry/blob/master/chisel): Fast, useful, and verbose solidity REPL.

In this guide, you will:

* Create a simple foundry project.
* Compile and test a sample smart contract using Foundry.
* Deploy smart contracts using Foundry to the Klaytn Baobab Network.
* Explore forking mainnet with cast and anvil.

## Pre-requisites

To follow this tutorial, the following are the prerequisites:

* Code editor: a source-code editor such [VS-Code](https://code.visualstudio.com/download).
* [MetaMask](https://docs.klaytn.foundation/dapp/tutorials/connecting-metamask#install-metamask): used to deploy the contracts, sign transactions and interact with the contracts.
* RPC Endpoint: you can get this from one of the supported [endpoint providers](https://docs.klaytn.foundation/content/dapp/rpc-service/public-en).
* Test KLAY from [Faucet](https://baobab.wallet.klaytn.foundation/faucet): fund your account with sufficient KLAY.
* Install [Rust](https://www.rust-lang.org/tools/install) and [Foundry](https://github.com/foundry-rs/foundry#installation).

## Setting Up Your Development Environment

To check if your foundry installation was successful, run the command below:

```bash
forge -V
```

**Output**

![](/files/Zlq9OJuDEheoTLLOGBEP)

After successfully installing foundry, you now have access to the CLI tools (forge, cast, anvil, chisel) available in foundry. Let's set up a foundry project in the following steps:

**Step 1**: To start a new project, run the command below:

```bash
forge init foundry_example 
```

**Step 2**: Navigate into your project folder.

```bash
cd foundry_example
ls	 
```

After initializing a foundry project, your current directory should include:

* **src**: the default directory for your smart contracts.
* **tests**: the default directory for tests.
* **foundry.toml**: the default project configuration file.
* **lib**: the default directory for project dependencies.
* **script**: the default directory for solidity scripting files.

## Sample smart contract

In this section, we will be using the sample counter contract in the initialized foundry project. The `counter.sol` file in the `src/` folder should look like this:

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
contract Counter {
    uint256 public number;
    function setNumber(uint256 newNumber) public {
        number = newNumber;
    }
    function increment() public {
        number++;
    }
}
```

**Code Walkthrough**

This is your smart contract. **Line 1** shows it uses the Solidity version 0.8.13 or greater. From **lines 4-12**, a smart contract `Counter` is created. This contract simply stores a new number using the **setNumber** function and increments it by calling the **increment** function.

## Testing smart contract

Foundry allows us to write tests in solidity as opposed to writing tests in javascript in other smart contract development frameworks. In our initialized foundry project, the `test/Counter.t.sol` is an example of a test written in solidity. The code looks like this:

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import "forge-std/Test.sol";
import "../src/Counter.sol";
contract CounterTest is Test {
    Counter public counter;
    function setUp() public {
        counter = new Counter();
        counter.setNumber(0);
    }
    function testIncrement() public {
        counter.increment();
        assertEq(counter.number(), 1);
    }
    function testSetNumber(uint256 x) public {
        counter.setNumber(x);
        assertEq(counter.number(), x);
    }
}
```

The code above shows you imported forge standard library and Counter.sol.

The tests above check the following:

* Is the number increasing?
* Is the number equal to the set number?

To check if your test works fine, run the following command:

```bash
forge test
```

**Output**

![](/files/GxznndSrbeQZAcKASIe4)

To learn more about writing tests, advanced testing, and other features, refer to [Foundry's documentation](https://book.getfoundry.sh/forge/tests).

## Compiling your contracts

Compile your contract with this command:

```bash
forge build 
```

## Deploying your contracts

To deploy a contract using foundry, you must provide an RPC URL and a private key of the account that will deploy the contract. Take a look at the list of [rpc-providers](https://docs.klaytn.foundation/content/dapp/rpc-service/public-en) on Klaytn to find your rpc-url, and create an account using [MetaMask](https://docs.klaytn.foundation/dapp/tutorials/connecting-metamask#install-metamask).

**Step 1**: To deploy your contract to the Klaytn Baobab network, run the command below:

```bash
$ forge create --rpc-url <your_rpc_url> --private-key <your_private_key> src/Counter.sol:Counter
```

**Example**

```bash
forge create --rpc-url https://klaytn-baobab-rpc.allthatnode.com:8551/qtKkeUE8ZEPI2cs0OHloJ6seI4Wfy36N --private-key hhdhdhdhprivatekeyhdhdhdhud src/Counter.sol:Counter
```

**WARNING: Replace the private key argument with your private key from MetaMask. Be very careful not to expose your private key.**

**Output**

![](/files/NkxnSElZSsSsDhXDWesU)

**Step 2**: Open [Klaytnscope](https://baobab.scope.klaytn.com/tx/0x669e39c9661fdab59aa34989b58b3f89376a93f846a0c71d2858918f58a307e2?tabId=internalTx) to check if the counter contract deployed successfully.

**Step 3**: Copy and paste the transaction hash in the search field and press Enter. You should see the recently deployed contract.

![](/files/CryimVzlrXPW7GSmo2pk)

## Interacting with the contract

After successfully deploying your smart contract, you will want to call and execute functions right. Let's get to interact with the deployed contracts on Klaytn Baobab Network using [Cast](https://book.getfoundry.sh/reference/cast/cast-send.html). In this section, you will learn how to use the [cast call](https://book.getfoundry.sh/reference/cast/cast-call) to execute the `read-only` function and [cast send](https://book.getfoundry.sh/reference/cast/cast-send) to execute `write` functions.

**A. cast call**: To get the number stored in the contract, you will be calling the `number` function. Run the command below to see this in action.

```bash
cast call YOUR_CONTRACT_ADDRESS "number()" --rpc-url RPC-API-ENDPOINT-HERE
```

**Example**

```bash
cast call 0xe4d576c447733da7ca9197e88d34a74c3c865cff "number()" --rpc-url https://klaytn-baobab-rpc.allthatnode.com:8551/qtKkeUE8ZEPI2cs0OHloJ6seI4Wfy36N
```

**Output**

![](/files/QULeDNuq5p3JLpAVZ4wo)

You should get this data in hexadecimal format:

```bash
0x0000000000000000000000000000000000000000000000000000000000000000
```

However to get your desired result, use cast to convert the above result. In this case, the data is a number, so you can convert it into base 10 to get the result 0:

```bash
cast --to-base 0x0000000000000000000000000000000000000000000000000000000000000000 10
```

**Output**

![](/files/dxgvO4KjJoSaNKTxzZZo)

**B. cast send**: To sign and publish a transaction such as executing a `setNumber` function in the counter contract, run the command below:

```bash
cast send --rpc-url=<RPC-URL> <CONTRACT-ADDRESS> “setNumber(uint256)” arg --private-key=<PRIVATE-KEY>
```

**Example**

```bash
cast send --rpc-url=https://klaytn-baobab-rpc.allthatnode.com:8551/qtKkeUE8ZEPI2cs0OHloJ6seI4Wfy36N  0xe4d576c447733da7ca9197e88d34a74c3c865cff "setNumber(uint256)"  10 --private-key=<private key>
```

**Output**

![](/files/hnP4WEG7ErWBV0q1MVLZ)

**Crosscheck Number**

```bash
cast call 0xe4d576c447733da7ca9197e88d34a74c3c865cff "number()" --rpc-url https://klaytn-baobab-rpc.allthatnode.com:8551/qtKkeUE8ZEPI2cs0OHloJ6seI4Wfy36N
```

**Output**

![](/files/i7taIA2MP6mrMol6G82h)

You should get this data in hexadecimal format:

```bash
0x000000000000000000000000000000000000000000000000000000000000000a
```

However to get your desired result, use cast to convert the above result. In this case, the data is a number, so you can convert it into base 10 to get the result 10:

```bash
cast --to-base 0x000000000000000000000000000000000000000000000000000000000000000a 10
```

**Output**

![](/files/YYQon5zdUJiXzNmTAiMJ)

## Forking Mainnet with Cast and Anvil

Foundry allows us to fork the mainnet to a local development network ([Anvil](https://book.getfoundry.sh/reference/anvil/)). Also, you can interact and test with contracts on a real network using [Cast](https://book.getfoundry.sh/reference/cast/).

### Getting Started

Now that you have your Foundry project up and running, you can fork the mainnet (cypress) by running the command below:

```bash
anvil --fork-url rpc-url
```

**Example**

```bash
anvil --fork-url https://archive-en.cypress.klaytn.net
```

**Output**

![](/files/OWss4FlaIK11aL0gprUh)

After successfully running this command, your terminal looks like the above image. You'll have 10 accounts created with their public and private keys as well 10,000 prefunded tokens. The forked chain's RPC server is listening at `127.0.0.1:8545`.

To verify you have forked the network, you can query the latest block number:

```bash
curl --data '{"method":"eth_blockNumber","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 
```

You can convert the result from the task above using [hex to decimal](https://www.rapidtables.com/convert/number/hex-to-decimal.html). You should get the latest block number from the time you forked the network. To verify this, cross-reference the block number on [Klaytnscope](https://klaytnscope.com/block/118704896?tabId=txList).

### Illustration

In this section, you will learn how to transfer oUSDC tokens from someone who holds oUSDC to an account created by Anvil (0x70997970C51812dc3A010C7d01b50e0d17dc79C8 - Bob)

**Transferring oUSDC**

Go to Klaytnscope and search for holders of oUSDC tokens (here). Let's pick a random account. In this example, we will be using `0x8e61241e0525bd45cfc43dd7ba0229b422545bca`.

Let's export our contracts and accounts as environment variables:

```bash
export BOB=0x70997970C51812dc3A010C7d01b50e0d17dc79C8
export oUSDC=0x754288077d0ff82af7a5317c7cb8c444d421d103
export oUSDCHolder=0x8e61241e0525bd45cfc43dd7ba0229b422545bca
```

We can check Bob’s balance using cast call:

```bash
cast call $oUSDC \
  "balanceOf(address)(uint256)" \
  $BOB
```

**Output**

![](/files/enqI5Yaa7sYVpIskWpBD)

Similarly, we can also check our oUSDC holder’s balance using cast call:

```bash
cast call $oUSDC \
  "balanceOf(address)(uint256)" \
  $oUSDCHolder
```

**Output**

![](/files/Kl5lCpJ9mkuIvfTSPXiS)

Let's transfer some tokens from the lucky user to Alice using cast send:

```bash
cast rpc anvil_impersonateAccount $oUSDCHolder    
cast send $oUSDC \
--unlocked \
--from $oUSDCHolder\
 "transfer(address,uint256)(bool)" \
 $BOB \
 1000000
```

**Output**

![](/files/NjGAYDRmgvtSGRhqVCYD)

Let's check that the transfer worked:

```bash
cast call $oUSDC \
  "balanceOf(address)(uint256)" \
  $BOB
```

**Output**

![](/files/wevCcN2gR8AeCCRtpaSn)

```bash
cast call $oUSDC \
  "balanceOf(address)(uint256)" \
  $oUSDCHolder
```

**Output**

![](/files/adtpDVp1ZZOHxxaJxkam)

For more in-depth guide on foundry, please refer to [Foundry Docs](https://book.getfoundry.sh/). Also, you can find the full implementation of the code for this guide on [GitHub](https://github.com/klaytn/examples/tree/main/foundry).


# Deploying Smart Contract Using Hardhat

![](/files/zY2kUIk8B5fMjq53pveY)

## Introduction

This section will guide you through deploying a Soulbound Token to the Klaytn Baobab Network using [Hardhat](https://hardhat.org/).

Hardhat is a smart-contract development environment that will help you:

* Develop and compile smart contracts.
* Debug, test, and deploy smart contracts and dApps.

Soul-bound tokens(SBTs) are non-transferable NFTs. Meaning once acquired, they cannot be sold or transferred to another user. To learn more about SBTs, how it works and their use case, you can check out this [reference article](https://vitalik.ca/general/2022/01/26/soulbound.html) published by Vitalik Buterin.

By the end of this guide you will be able to:

* Set up a Hardhat project on Klaytn.
* Create a simple soul-bound token.
* Compile your smart contract using Hardhat.
* Test, deploy, and interact with your smart contract using Hardhat.
* Explore Hardhat forking feature.

## Pre-requisites

To follow this tutorial, the following are the prerequisites:

* Code editor: a source-code editor such [VS-Code](https://code.visualstudio.com/download).
* [Metamask](https://docs.klaytn.foundation/dapp/tutorials/connecting-metamask#install-metamask): used to deploy the contracts, sign transactions and interact with the contracts.
* RPC Endpoint: you can get this from one of the supported [Endpoint Providers](https://docs.klaytn.foundation/content/dapp/rpc-service/public-en).
* Test KLAY from [Faucet](https://baobab.wallet.klaytn.foundation/faucet): fund your account with sufficient KLAY.
* [NodeJS and NPM](https://nodejs.org/en/)

## Setting Up Your Development Environment

To make use of hardhat, we need to set up our development environment and get hardhat installed. Let's do this in the following steps:

**Step 1**: Create a project directory

```bash
mkdir soulbound-tokens
cd soulbound-tokens
```

**Step 2**: Initialize an npm project

Paste this command in your terminal to create a package.json file

```bash
npm init -y
```

**Step 3**: Install hardhat and other dependencies:

* Paste the code below in your terminal to install hardhat

```bash
npm install --save-dev hardhat
```

* Paste the code below to install other dependencies

```bash
npm install dotenv @klaytn/contracts
```

> Note: This installs other dependencies needed for this project ranging from `hardhat`, `klaytn/contract`, `dotenv` et al.

**Step 4**: Initialise a hardhat project:

Run the command below to initiate an hardhat project

```bash
npx hardhat
```

For this guide, you'll be selecting a typescript project as seen below:

![](/files/9XtLLqlXaJwHnaR7o5Hg)

![](/files/IikCuKHDM2ThK5ipY7HC)

> Note: While initializing the project, you will get a prompt to install `hardhat-toolbox` plugin. The plugin bundles all the commonly used packages and Hardhat plugins recommended to start developing with Hardhat.

After initializing a hardhat project, your current directory should include:

**contracts/** – this folder contains smart contract code.

**scripts/** – this folder contains code that deploys your contracts on the blockchain network.

**test/** – this folder contains all unit tests that test your smart contract.

**hardhat.config.js** – this file contains configurations important for the work of Hardhat and the deployment of the soul-bound token.

**Step 5**: Create a .env file

Now create your .env file in the project folder. This file helps us load environment variables from an .env file into process.env.

* Paste this command in your terminal to create a .env file

```bash
touch .env
```

* After creating our file, let's configure our .env file to look like this:

```js
 KLAYTN_BAOBAB_URL= "Your Baobab RPC link"
 PRIVATE_KEY= "your private key copied from MetaMask wallet"
```

> Note: You can also choose to use the [configuration variable](https://hardhat.org/hardhat-runner/docs/guides/configuration-variables) functionality provided by hardhat to configure variables that shouldn't be included in the code repository.

**Step 6**: Setup Hardhat Configs

Modify your `hardhat.config.js` with the following configurations:

```js
require("@nomicfoundation/hardhat-toolbox");
require('dotenv').config()


module.exports = {
  solidity: "0.8.17",
  networks: {
    baobab: {
      url: process.env.KLAYTN_BAOBAB_URL || "",
      gasPrice: 250000000000,
      accounts:
        process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],
    }
  }
};
```

Now that we have our development environment all set, let's get into writing our soul-bound token smart contract.

## Creating SBT Smart Contract

In this section, you will use the [Klaytn Contracts](https://github.com/klaytn/klaytn-contracts): a library for secure smart contract development built on a solid foundation of community-vetted code. It is a fork of open zeppelin contracts.

> Note: You already installed this library in **step 3** of the `Setting Development Environment` section.

**Step 1**: Select the contracts folder in the Explorer pane, click the New File button and create a new file named `SBT.sol`

**Step 2**: Open the file and paste the following code:

```js
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "@klaytn/contracts/KIP/token/KIP17/KIP17.sol";
import "@klaytn/contracts/utils/Counters.sol";
import "@klaytn/contracts/access/Ownable.sol";

contract SoulBoundToken is KIP17, Ownable {
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;

    constructor() KIP17("SoulBoundToken", "SBT") {}

    function safeMint(address to) public onlyOwner {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);
    }


    function _beforeTokenTransfer(address from, address to, uint256) pure override internal {
        require(from == address(0) || to == address(0), "This a Soulbound token. It cannot be transferred.");
    }

    function _burn(uint256 tokenId) internal override(KIP17) {
        super._burn(tokenId);
    }
}
```

**Code Walkthrough**

This is your smart contract. **line 1** shows that Hardhat uses the Solidity version 0.8.7 or greater. Other than that, it imports KIP17.sol and other supporting contracts. From **lines 6-12**, a smart contract that inherits KIP17 is been created. Also, the token name and symbol was passed in the constructor.

As you can see in the code above, the token name and symbol have been set to **SoulBoundToken** and **SBT** respectively. You can change the token name and symbol to anything you desire.

One major thing in this contract is that it prohibits token transfer, which makes the issued tokens soulbond.

## Testing SBT Smart Contract

In this section, we would be testing some of our contract functionalities.

**Step 1**: In the Explorer pane, select the test folder and click the New File button to create a new file named `sbtTest.js`

**Step 2**: Copy the code below in the `sbtTest.js` file.

```js
// This is an example test file. Hardhat will run every *.ts file in `test/`,
// so feel free to add new ones.

// Hardhat tests are normally written with Mocha and Chai.

// We import Chai to use its asserting functions here.
const { expect } = require("chai");

// We use `loadFixture` to share common setups (or fixtures) between tests.
// Using this simplifies your tests and makes them run faster, by taking
// advantage of Hardhat Network's snapshot functionality.
const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers");

// `describe` is a Mocha function that allows you to organize your tests.
// Having your tests organized makes debugging them easier. All Mocha
// functions are available in the global scope.
//
// `describe` receives the name of a section of your test suite, and a
// callback. The callback must define the tests of that section. This callback
// can't be an async function.
describe("Token contract", function () {
  // We define a fixture to reuse the same setup in every test. We use
  // loadFixture to run this setup once, snapshot that state, and reset Hardhat
  // Network to that snapshot in every test.
  async function deployTokenFixture() {
    // Get the ContractFactory and Signers here.
    const [owner, addr1, addr2] = await ethers.getSigners();

    // To deploy our contract, we just have to call ethers.deployContract() and call the 
    // waitForDeployment() method, which happens onces its transaction has been
    // mined.

    const sbtContract = await ethers.deployContract("SoulBoundToken");

    await sbtContract.waitForDeployment();

    // Fixtures can return anything you consider useful for your tests
    return { sbtContract, owner, addr1, addr2 };
  }

  // You can nest describe calls to create subsections.
  describe("Deployment", function () {
    // `it` is another Mocha function. This is the one you use to define each
    // of your tests. It receives the test name, and a callback function.
    //
    // If the callback function is async, Mocha will `await` it.
    it("Should mint SBT to owner", async function () {
      const { sbtContract, owner } = await loadFixture(deployTokenFixture);
      const safemint = await sbtContract.safeMint(owner.address);
      expect(await sbtContract.ownerOf(0)).to.equal(owner.address);
    });
  });

  describe("Transactions", function () {
    it("Should prohibit token transfer using transferFrom", async function () {
      const { sbtContract, owner, addr1 } = await loadFixture(
        deployTokenFixture
      );

      const safemintTx = await sbtContract.safeMint(owner.address);

      // prohibit token transfer of token id (0) from owner to addr1
      await expect(
        sbtContract.transferFrom(owner.address, addr1.address, 0)
      ).to.be.reverted;
  });

  it("Should prohibit token transfer using safeTransferFrom", async function () {
    const { sbtContract, owner, addr1 } = await loadFixture(
      deployTokenFixture
    );

    const safemintTx = await sbtContract.safeMint(owner.address);

    // prohibit token transfer of token id (0) from owner to addr1
    await expect(sbtContract['safeTransferFrom(address,address,uint256)'](
      owner.address,
      addr1.address,
      0 
  )).to.be.reverted;
});


});

})
```

In the code you just copied, line 7 & 12 shows you imported expect from [Chai](https://www.chaijs.com/api/bdd/) and [loadFixture](https://hardhat.org/tutorial/testing-contracts#reusing-common-test-setups-with-fixtures) from hardhat-network-helpers.

The tests above check the following:

* Is the owner of a particular token id the same as who it was minted to?
* Did it prohibit transfer of tokens between accounts?

**Step 3**: To run your test, run the command below:

```bash
npx hardhat test test/sbtTest.ts 
```

![](/files/j522gv7ymnEj4aC0MDld)

For more in-depth guide on testing, please check [Hardhat testing](https://hardhat.org/hardhat-runner/docs/guides/test-contracts).

## Deploying the smart contract

Scripts are JavaScript/Typescript files that help you deploy contracts to the blockchain network. In this section, you will create a script for the smart contract.

**Step 1**: In the Explorer pane, select the "scripts" folder and click the New File button to create a new file named `sbtDeploy.js`.

**Step 2**: Copy and paste the following code inside the file.

> Note: input your MetaMask wallet address in the `deployerAddr` variable.

```js
const { ethers } = require("hardhat");

async function main() {

  const deployerAddr = "Your Metamask wallet address";
  const deployer = await ethers.getSigner(deployerAddr);

  console.log(`Deploying contracts with the account: ${deployer.address}`);
  console.log(`Account balance: ${(await deployer.provider.getBalance(deployerAddr)).toString()}`);


  const sbtContract = await ethers.deployContract("SoulBoundToken");
  await sbtContract.waitForDeployment();

console.log(`Congratulations! You have just successfully deployed your soul bound tokens.`);
console.log(`SBT contract address is ${sbtContract.target}. You can verify on https://baobab.scope.klaytn.com/account/${sbtContract.target}`);
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
```

**Step 3**: In the terminal, run the following command which tells Hardhat to deploy your SBT token on the Klaytn Test Network (Baobab)

```bash
npx hardhat run scripts/sbtDeploy.js --network baobab
```

![](/files/XeJRI6aScOt81bpgSfX1)

**Step 4**: Open [Klaytnscope](https://baobab.scope.klaytn.com/) to check if the SBT token has been deployed successfully.

**Step 5**: Copy and paste the deployed contract address in the search field and press Enter. You should see the recently deployed contract.

![](/files/SSehz4nexCWinYoJnb4e)

## Hardhat Forking

Hardhat provides developers the functionality of simulating the mainnet (at any given block) to a local development network. One of the major benefit of this feature is that it enables developers to interact with deployed contract and also write test for complex cases.

For this feature to work effectively, you need to connect to an archive node. You can read more about this feature [here](https://hardhat.org/hardhat-network/docs/guides/forking-other-networks#forking-other-networks)

### Forking Mainnet

Now that we have our Hardhat project set up let’s fork the Klaytn Mainnet using Hardhat. Open your terminal and run this command

```bash
npx hardhat node --fork <YOUR ARCHIVE NODE URL>

npx hardhat node --fork https://archive-en.cypress.klaytn.net
```

You can also configure `hardhat.config.js` - Hardhat Network to always do this:

```
networks: {
  hardhat: {
    forking: {
      url: "<YOUR ARCHIVE NODE URL>",
    }
  }
}
```

**Output**

![](/files/LBzlBblwWV83BvKHdm33)

After successfully running this command, your terminal looks like the above image. You'll have 20 development accounts that are pre-funded with 10,000 test tokens.

The forked chain's RPC server is listening at `http://127.0.0.1:8545/`. You can verify the forked network by querying the latest block number. Let's try to make a cURL to the RPC to get the block number. Open a new terminal window and use the following command:

```bash
curl --data '{"method":"eth_blockNumber","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 
```

**Output**

![](/files/MoFq9mp50KWndfaQGcVl)

The output is an hexadecimal as seen above. To get the block number from the hex, convert the hex to a decimal using this [tool](https://www.rapidtables.com/convert/number/hex-to-decimal.html). You should get the latest block number from the time you forked the network. You can confirm the block number on [klaytnscope](https://scope.klaytn.com/).

### Forking at a Block

With hardhat, you can fork the mainnet at a particular block. In that case, let’s fork the chain at block number `105701850`.

```bash
npx hardhat node --fork <YOUR ARCHIVE NODE URL> --fork-block-number 105701850

npx hardhat node --fork https://archive-en.cypress.klaytn.net --fork-block-number 105701850
```

To confirm the forked chain at the stated block, open a new terminal window and use the following command:

```bash
curl --data '{"method":"eth_blockNumber","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 
```

![](/files/d1WBsFTY4IAOiMcmmaMs)

The output returns hexadecimal which when converted using this [tool](https://www.rapidtables.com/convert/number/hex-to-decimal.html) should be equal to `105701850`.

For more in-depth guide on Hardhat, please refer to [Hardhat Docs](https://hardhat.org/hardhat-runner/docs/getting-started). Also, you can find the full implementation of the code for this guide on [GitHub](https://github.com/klaytn/examples/tree/main/hardhat/soulbound-tokens)


# Deploying Smart Contract Using Thirdweb

![](/files/zaVwTd5jJtwHs9k0IHJv)

## Introduction <a href="#introduction" id="introduction"></a>

This section will guide you through deploying a Marketplace contract and a corresponding NFT collection contract to Klaytn Network using [ThirdWeb](https://portal.thirdweb.com/). Thirdweb is a complete web3 development framework that provides everything you need to connect your apps and games to decentralized networks.

Marketplace contract allows users to list NFTs for direct sale or auction, thus enhancing the buying and selling of NFTs, just like it’s done on OpenSea.

By the end of this guide, you will be able to:

* create and customize contracts using thirdweb.
* compile, deploy, and interact with your smart contract using thirdweb.

## Getting Started <a href="#getting-started" id="getting-started"></a>

In this article, we will explore the different means to create, customize, and deploy contracts using thirdweb, viz.

* Using the thirdweb dashboard
* Using the thirdweb CLI

For this guide, we will be demonstrating how to deploy a MarketPlace contract using the thirdweb dashboard and also deploying a corresponding nft collection to be listed on the marketplace using the thirdweb CLI.

> Note: We will not be explaining the mechanics of the marketplace contract as our focus is to explore thirdweb dashboard and CLI for creating, deploying, and interacting with smart contracts.

## Creating and deploying marketplace contract using thirdweb dashboard <a href="#creating-and-deploying-thirdweb-dashboard" id="creating-and-deploying-thirdweb-dashboard"></a>

In this section, we will create and deploy a marketplace contract using thirdweb dashboard. To do this, follow the steps below:

1. Head over to [thirdweb dashboard](https://thirdweb.com/dashboard?ref=blog.thirdweb.com) and select the **MarketPlace** contract from the list of contracts.

![](/files/kj5CV4hQrFM0Xbr5PsKr)

2. Click **Deploy Now** in the contract overview dashboard.

![](/files/h5cRgFMXUI0JkeCJX1cf)

3. Configure the marketplace contract to include the following parameters: the **name** of the marketplace, its **description**, and **image**.

![](/files/R4iEWBeSCAJWeMbGYEA2)

4. Click **Deploy Now** as seen in the image above and wait for the transaction to complete.

![](/files/lbfmqefAzj6MLc2ibCNh)

Once the transaction has been successfully executed, you can verify your deployment by pasting the contract address in the search bar of [Klaytnscope](https://klaytnscope.com/).

## Creating and deploying an NFT collection contract using thirdweb CLI <a href="#creating-deploying-using-thirdweb-cli" id="creating-deploying-using-thirdweb-cli"></a>

In this section, we will create and deploy the NFT collection to be listed in our Marketplace using [thirdweb CLI](https://portal.thirdweb.com/cli?ref=blog.thirdweb.com). To do this, follow the steps below:

### Creating the contract <a href="#creating-the-contract" id="creating-the-contract"></a>

1. Run this command in your terminal to create your contract:

```bash
npx thirdweb create --contract
```

2. Enter your preferred values for the command-line prompts:

   i. Give your project a name.

   ii. Choose your preferred framework: **Hardhat** or **Foundry**.

   iii. Name your smart contract.

   iv. Choose the type of base contract: **Empty**, **ERC20**, **ERC721**, or **ERC1155**. Add any desired **extensions**. For this tutorial, we will select ERC721 and setting the extension to none.

![](/files/mslLGxjz1CMDUI9QUybG)

3. Once created, navigate to your project’s root directory and open your project in your preferred code editor.
4. If you open the contracts folder, your contract should look like this:

```js
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@thirdweb-dev/contracts/base/ERC721Base.sol";
contract nftcollection is ERC721Base {
      constructor(
        address _defaultAdmin,
        string memory _name,
        string memory _symbol,
        address _royaltyRecipient,
        uint128 _royaltyBps
    )
        ERC721Base(
            _defaultAdmin,
            _name,
            _symbol,
            _royaltyRecipient,
            _royaltyBps
        )
    {}
}
```

The contract above demonstrates basic [ERC721Base](https://github.com/thirdweb-dev/contracts/blob/main/contracts/base/ERC721Base.sol) functionality. It imports and inherits the **ERC721Base** contract, and it also implements the required methods, including the constructor and its dependent parameters.

You can modify the contract to your desired custom logic, and once done, your contract is ready for deployment.

### Deploying the contract <a href="#deploying-the-contracts" id="deploying-the-contracts"></a>

1. Navigate to your project root folder and run the command in your terminal:

```bash
npx thirdweb deploy
```

Executing this command will trigger the following actions:

* detects the framework (hardhat, foundry)
* compiles all the contracts in the current directory.
* allows you to select which contract(s) you wish to deploy.
* upload your compiled smart contract code (in the form of an Application Binary Interface, or ABI) to IPFS.

2. When deployment is complete, a dashboard interface will open to fill out the remaining parameters.
   * **\_name**: contract name
   * **\_symbol**: symbol or "ticker"
   * **\_royaltyRecipient**: wallet address to receive royalties from secondary sales
   * **\_royaltyBps**: basis points (bps) that will be given to the royalty recipient for each secondary sale, e.g., 500 = 5%
3. Select `Klaytn Mainnet Cypress` as the network to deploy the contract to.

![](/files/yeu8XDioBfZaF2eS075V)

4. Once your smart contract is deployed, you can manage additional settings and functionalities through its dashboard. For example, you can upload NFTs, configure permissions and access control, and add new features.

You can learn more about thirdweb deploy command in this [deploy guide](https://portal.thirdweb.com/deploy/getting-started).

## Interacting with deployed contracts <a href="#interacting-with-deployed-contracts" id="interacting-with-deployed-contracts"></a>

In this section, we will mint an NFT and also transferring it to another account using the **mint** and **transferfrom** function respectively. Let's go over it in the following steps:

### Minting the NFT <a href="#minting-nft" id="minting-nft"></a>

1. Navigate to the newly deployed contract (**puppyKlan-NC**) dashboard.
2. Click on the **mint** function in the **NFTs** tab under the contract dashboard.

![](/files/8Bnu1wYX5c0yB238Ogdn)

3. Fill in the parameters needed for minting the NFT: **name**, **media**, **description**, and **properties**.

![](/files/nZD6jwyk3R8DLtTRJZf5)

4. Verify your input and click the **Mint NFT** button.
5. Confirm the transaction and wait for it to complete. Once done, you should see your NFT added to the dashboard, like below:

![](/files/ZZfTRCcMSrVBCrz20HiO)

### Transferring the NFT to a new owner <a href="#transferring-nft-to-new-owner" id="transferring-nft-to-new-owner"></a>

1. Head to the Explorer tab in the contract (**puppyKlan-NC**) dashboard.
2. Select the **transferFrom** function under the Write tab, as shown below.
3. Fill in the necessary function arguments: from (address), to (address), and id (uint256).

![](/files/NGq6U0WlCxn3DYeOVXcf)

4. Confirm the transaction and wait for it to complete.

## Conclusion <a href="#conclusion" id="conclusion"></a>

Congratulations! if you made it to the end of this guide. If you have any questions, visit the [Klaytn Forum](https://forum.klaytn.foundation/) or reach out to the [official thirdweb support](https://support.thirdweb.com/). However, below is a list of useful resources you might need while further building with Thirdweb on Klaytn.

* [Thirdweb Docs](https://portal.thirdweb.com/)
* [How to build a dApp using Thirdweb](https://blog.thirdweb.com/guides/how-to-build-a-dapp/)
* [Create your own NFT marketplace with NextJS and TypeScript](https://blog.thirdweb.com/guides/nft-marketplace-with-typescript-next/)


# Deploying Smart Contract Using KEN

![](/files/9MPib4cblkleiWt1HFq8)

Before you start, let's get familiar with several Klaytn-specific terms.

* **Endpoint Node (EN)**: A node that handles the JSON-RPC API requests to the Klaytn network. Endpoint Node does not participate in the consensus.
* **KLAY**: Klaytn native coin.
* **caver-js**: A JavaScript implementation of Klaytn JSON-RPC APIs.
* **Baobab**: Klaytn testnet
* **Cypress**: Klaytn mainnet

This step by step guide will walk you through the process of launching an Endpoint Node (EN) of Baobab testnet and building a basic smart contract with your new account. The tutorial consists of two parts, setting up an EN and deploying a smart contract through your EN.

> This guide uses the **Baobab** testnet because deploying a smart contract and submitting a transaction require transaction fees in KLAY. For the development purpose, testnet KLAY can be obtained from the [Baobab faucet](https://baobab.wallet.klaytn.foundation/faucet).

## 1. Launch an Endpoint Node and Add Baobab testnet KLAY to your Account (Linux, Mac) <a href="#id-1-launch-an-endpoint-node-and-add-baobab-testnet-klay-to-your-account-linux-mac" id="id-1-launch-an-endpoint-node-and-add-baobab-testnet-klay-to-your-account-linux-mac"></a>

The first part of this tutorial explains how to launch an EN, create a new account, and top up your account with the faucet in the Baobab Klaytn Wallet.

* [Launch an Endpoint Node](/content/getting-started/quick-start/launch-an-en)
* [Top up your Account](/content/getting-started/quick-start/top-up-your-account)

## 2. Deploying a Smart Contract: KlaytnGreeter <a href="#id-2-deploying-a-smart-contract-klaytngreeter" id="id-2-deploying-a-smart-contract-klaytngreeter"></a>

The second of this guide shows how to create smart contracts and deploy them on the Klaytn Baobab network. Before getting into developing smart contracts, you need to set up the development tools, install caver-js and Truffle.

* [Install Development Tools](/content/getting-started/quick-start/install-development-tools)
* [Deploy a Smart Contract](/content/getting-started/quick-start/deploy-a-smart-contract)
* [Check the Deployment](/content/getting-started/quick-start/check-the-deployment)


# Launch an Endpoint Node

## Download and Initialize an Endpoint Node (EN) <a href="#download-and-initialize-an-endpoint-node-en" id="download-and-initialize-an-endpoint-node-en"></a>

Unzip the provided [ken binary package](/content/installation-guide/deployment/download#get-the-packages) and copy the files into the klaytn folder.\
**Note**: Please download appropriate package starting with `ken`.

For Mac users, unzip the downloaded file with the following command.

```bash
$ tar zxf ken-baobab-vX.X.X-X-darwin-amd64.tar.gz
$ export PATH=$PATH:$PWD/ken-darwin-amd64/bin
```

For Linux users, unzip the downloaded file with the following command.

```bash
$ tar zxf ken-baobab-vX.X.X-X-linux-amd64.tar.gz
$ export PATH=$PATH:$PWD/ken-linux-amd64/bin
```

You should create a data directory to store the blockchain data. In this tutorial, we will create a `kend_home` folder in the home directory.

```bash
$ mkdir -p ~/kend_home
```

## Configuring the EN <a href="#configuring-the-en" id="configuring-the-en"></a>

The configuration file, `kend.conf`, is located under `ken-xxxxx-amd64/conf/`. For the details of configurable parameters, you can refer to the [EN Configuration Guide](/content/operation-guide/configuration). To launch an EN of Baobab testnet, please update the `kend.conf` file accordingly as follows.

```
# cypress, baobab is only available if you don't specify NETWORK_ID.
NETWORK="baobab"
# if you specify NETWORK_ID, a private network is created.
NETWORK_ID=
...
RPC_API="klay,net" # net module should be opened for truffle later on.
...
DATA_DIR=~/kend_home
```

## Launching the EN <a href="#launching-the-en" id="launching-the-en"></a>

To launch the EN, execute the following command.

```bash
$ kend start
 Starting kend: OK
```

## Checking the EN <a href="#checking-the-en" id="checking-the-en"></a>

To check if the EN is running, execute the following command.

```bash
$ kend status
kend is running
```

## Checking the log of the EN <a href="#checking-the-log-of-the-en" id="checking-the-log-of-the-en"></a>

To check the log of the EN, execute the following command.

```bash
$ tail -f ~/kend_home/logs/kend.out
...
INFO[03/26,15:37:49 +09] [5] Imported new chain segment                blocks=1    txs=0  mgas=0.000  elapsed=2.135ms   mgasps=0.000    number=71340 hash=f15511…c571da cache=155.56kB
...
```

## Troubleshooting <a href="#troubleshooting" id="troubleshooting"></a>

Please refer to the [Troubleshooting](/content/operation-guide/errors-and-troubleshooting) if you have trouble in launching the Klaytn Endpoint Node.


# Top up your Account

## Attaching to the Console <a href="#attaching-to-the-console" id="attaching-to-the-console"></a>

Klaytn Endpoint Node comes with JavaScript console. From the console command line, you can initiate part of Klaytn API calls to your EN. To attach to the JavaScript console, execute the following command.

```bash
$ ken attach ~/kend_home/klay.ipc
Welcome to the Klaytn JavaScript console

!instance: Klaytn/vX.X.X/XXXX-XXXX/goX.X.X
 datadir: ~/kend_home
 modules: admin:1.0 debug:1.0 governance:1.0 istanbul:1.0 klay:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0
 
 >
```

**NOTE**: You must wait until it downloads all the blocks. Enter `klay.blockNumber` in a console and check whether it matches the current block number [here](https://baobab.scope.klaytn.com/)

**NOTE**: Type `klay` or `personal` to get the list of available functions.

## Creating a New Klaytn Account <a href="#creating-a-new-klaytn-account" id="creating-a-new-klaytn-account"></a>

To create a new Klaytn account from the JavaScript console, execute the following command. Your private key will be encrypted with the passphrase you enter.

```javascript
> personal.newAccount()
Passphrase:  # enter your passphrase
Repeat passphrase:
"0x75a59b94889a05c03c66c3c84e9d2f8308ca4abd" # created account address
```

Keystore file will be created under `keystore` folder in the EN data directory, `DATA_DIR` set in the `kend.conf`. If you follows the quick start default guideline, it must be `~/kend_home/keystore/`.

```javascript
$ ls ~/kend_home/keystore/
UTC--2019-06-24T11-20-15.590879000Z--75a59b94889a05c03c66c3c84e9d2f8308ca4abd
```

## Unlocking the Klaytn Account <a href="#unlocking-the-klaytn-account" id="unlocking-the-klaytn-account"></a>

To unlock the created account, execute the following command. It unlocks the account for 300 seconds. **Note**: If you want to manually set the unlock duration, refer to this [link](/content/dapp/json-rpc/api-references/personal#personal_unlockaccount). **`WARNING`**: Unlocking an account could be very dangerous if not done carefully. There are chances that your tokens will be taken away by hackers if your EN is hacked by a hacker. To use safer method, refer to this [deployment guide using private key](/content/dapp/tutorials/count-dapp/6.-deploy-contract#deploy-method-1-by-private-key)

```javascript
> personal.unlockAccount('75a59b94889a05c03c66c3c84e9d2f8308ca4abd') # account address to unlock
Unlock account 75a59b94889a05c03c66c3c84e9d2f8308ca4abd
Passphrase: # enter your passphrase
true
```

## Getting testnet KLAY from the Baobab Faucet <a href="#getting-testnet-klay-from-the-baobab-faucet" id="getting-testnet-klay-from-the-baobab-faucet"></a>

* Using the Baobab faucet in KlaytnWallet.
* Access [https://baobab.wallet.klaytn.foundation](https://baobab.wallet.klaytn.foundation/).
* You can either create a new account from the Wallet or use the keystore file you created from the EN JavaScript console above to log into the Wallet.
* Go to "KLAY Faucet" from the left pane menu, and click the "Run Faucet" button to get 150 KLAY.

  You can run the KLAY Faucet once every 24 hours.
* If you created a new account to get KLAY, then send the KLAY to your created account on the EN.

## Checking the Balance in Your Account <a href="#checking-the-balance-in-your-account" id="checking-the-balance-in-your-account"></a>

To see the balance of your account, execute the following command.

The default unit is peb (1 KLAY = 10^18 peb). More information about KLAY units can be found at [Units of KLAY](/content/klaytn/design/klaytn-native-coin-klay#units-of-klay).

```javascript
> klay.getBalance('75a59b94889a05c03c66c3c84e9d2f8308ca4abd') # enter your account address
1e+21  # 1000 KLAY
```

## Exiting the Console <a href="#exiting-the-console" id="exiting-the-console"></a>

To leave the javascript console, execute the following command.

```javascript
> exit
$
```


# Install Development Tools

## Installing caver-js <a href="#installing-caver-js" id="installing-caver-js"></a>

We recommend to create a klaytn project directory such that:

```bash
$ mkdir $HOME/klaytn
```

> You need `npm` and `node.js` installed to proceed. Please refer to [get-npm](https://www.npmjs.com/get-npm) and [node.js](https://nodejs.org/en/) for installation on your system.

​[caver-js](/content/dapp/sdk/caver-js) is a JSON RPC framework for the Klaytn network (equivalent to web3.js in Ethereum). Before installing caver-js, you must generate `package.json` file via `npm init` command, and then type `npm install caver-js` to install caver-js.

```bash
$ npm init # initialize npm at the klaytn project directory
$ npm install caver-js
```

**NOTE**: If you already installed caver-js, please update it to the latest version.

```bash
$ npm cache clean --force # initialize npm cache
$ npm install caver-js@latest # update caver-js to the latest version
```

If you receive the following errors while updating the caver-js, remove `.git` folder in the `websocket` directory.

```bash
npm ERR! path /Users/username/klaytn/node_modules/websocket
npm ERR! code EISGIT
npm ERR! git /Users/username/klaytn/node_modules/websocket: Appears to be a git repo or submodule.
npm ERR! git     /Users/username/klaytn/node_modules/websocket
npm ERR! git Refusing to remove it. Update manually,
npm ERR! git or move it out of the way first.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/username/.npm/_logs/2019-06-25T01_49_37_032Z-debug.log​

$ rm /Users/username/klaytn/node_modules/websocket/.git
```

**Note:** For all the function calls that begin with `web3.eth...` in web3.js, should be replaced with `caver.klay...`.

`web3.eth.sendTransaction({ ... })` (X)

`caver.klay.sendTransaction({ ... })` (O)

## Installing Truffle <a href="#installing-truffle" id="installing-truffle"></a>

In this tutorial, Truffle is used to compile and deploy smart contracts written in Solidity. Currently, Klaytn supports Truffle version 4.1.15. For further information about Truffle, refer to the following sites:

* Truffle repository - <https://github.com/trufflesuite/truffle>​
* Truffle documents - <https://trufflesuite.com/docs>​

We can install Truffle either

1\) globally using npm by executing the following commands:

```bash
$ sudo npm install -g truffle@4.1.15
$ cd /usr/local/lib/node_modules/truffle
$ sudo npm install solc@0.5.6
$ cd -
```

or

2\) locally, i.e., in your local directory, by executing the followings:

```bash
# Assuming you are in $HOME/klaytn/.
$ npm install truffle@4.1.15
$ cd node_modules/truffle
$ npm install solc@0.5.6
$ cd -
$ ln -s node_modules/truffle/build/cli.bundled.js truffle
$ export PATH=`pwd`:$PATH
```

## Installing vvisp <a href="#installing-vvisp" id="installing-vvisp"></a>

vvisp is an easy-to-use cli tool/framework for developing smart contracts, provided by [HEACHI LABS](https://henesis.io/). You can easily set environment, deploy and execute Klaytn smart contracts with a single-command. It supports the Truffle framework, so developers familiar with Truffle can use vvisp without difficulty.

Here, we introduce how to install vvisp and use it to set up the Klaytn dApp development environment.

* vvisp repository - <https://github.com/HAECHI-LABS/vvisp>​
* vvisp document - <https://github.com/HAECHI-LABS/vvisp/blob/dev/README_KLAYTN.md>​

vvisp can be easily installed if you have npm or yarn by executing the following command:

```bash
$ npm install -g @haechi-labs/vvisp
# or if you use yarn
$ yarn global add @haechi-labs/vvisp
```

Upon installation, you can utilize the vvisp command to ensure it has been installed properly. **NOTE**: You should use version over **v2.1.0**.

```bash
$ vvisp
Usage: vvisp <command> [options]

where <command> is one of: compile, console, deploy-contract, deploy-service, flatten, gen-script, init

Options:
  -v, --version  output the version number
  -h, --help     output usage information

Commands:

   compile [files...]                       compile the smart contracts

   console [script-api-path]                run interactive shell to execute contract scripts

   deploy-contract <file> [arguments...]    deploy the smart contracts

   deploy-service                           deploy or upgrade smart contract service using the deployment configure file

   flatten <files...>                       flatten the smart contracts

   gen-script [files...]                    generate javascript libraries communicating the smart contracts

   init [name]                              initialize directory to use vvisp

# you can check installed version.
$ vvisp --version
v2.1.0
```


# Deploy a Smart Contract

Now we are ready to develop and deploy Klaytn smart contracts!

## Creating a Project Directory <a href="#creating-a-project-directory" id="creating-a-project-directory"></a>

First of all, create a directory where the source code locates.

```bash
$ mkdir klaytn-testboard
$ cd klaytn-testboard
```

## Initializing Truffle <a href="#initializing-truffle" id="initializing-truffle"></a>

Initialize Truffle for contract deployment.

```bash
$ truffle init
```

## Writing a Simple Smart Contract in Solidity <a href="#writing-a-simple-smart-contract-in-solidity" id="writing-a-simple-smart-contract-in-solidity"></a>

Create `KlaytnGreeter.sol` at `klaytn-testboard/contracts` directory.

```bash
$ cd contracts
$ touch KlaytnGreeter.sol
$ vi KlaytnGreeter.sol
```

Write the following code in KlaytnGreeter.sol.

```
pragma solidity 0.5.6;
contract Mortal {
    /* Define variable owner of the type address */
    address payable owner;
    /* This function is executed at initialization and sets the owner of the contract */
    constructor () public { owner = msg.sender; }
    /* Function to recover the funds on the contract */
    function kill() public payable { if (msg.sender == owner) selfdestruct(owner); }
}

contract KlaytnGreeter is Mortal {
    /* Define variable greeting of the type string */
    string greeting;
    /* This runs when the contract is executed */
    constructor (string memory _greeting) public {
        greeting = _greeting;
    }
    /* Main function */
    function greet() public view returns (string memory) {
        return greeting;
    }
}
```

## Modifying the Migration Script <a href="#modifying-the-migration-script" id="modifying-the-migration-script"></a>

```bash
$ cd ..
$ cd migrations
$ vi 1_initial_migration.js
```

Modify `1_initial_migration.js` as the following.

```javascript
const Migrations = artifacts.require("./Migrations.sol");
const KlaytnGreeter = artifacts.require("./KlaytnGreeter.sol");
module.exports = function(deployer) {
  deployer.deploy(Migrations);
  deployer.deploy(KlaytnGreeter, 'Hello, Klaytn');
};
```

## Deploying a Smart Contract using Truffle <a href="#deploying-a-smart-contract-using-truffle" id="deploying-a-smart-contract-using-truffle"></a>

Enter Klaytn's network information into truffle.js.

**`WARNING`**: Currently Klaytn Baobab network's gasPrice is fixed to 25 Gpeb (**It returns an error if you attempt to use any other number**).

```bash
$ cd ..
$ vi truffle-config.js
```

Modify configuration as below

```javascript
// truffle-config.js
module.exports = {
    networks: {
        klaytn: {
            host: '127.0.0.1',
            port: 8551,
            from: '0x75a59b94889a05c03c66c3c84e9d2f8308ca4abd', // enter your account address
            network_id: '1001', // Baobab network id
            gas: 20000000, // transaction gas limit
            gasPrice: 25000000000, // gasPrice of Baobab is 25 Gpeb
        },
    },
    compilers: {
      solc: {
        version: "0.5.6"    // Specify compiler's version to 0.5.6
      }
  }
};
```

Deploy the contract using the following command.

**NOTE**: Use `--network` to select which network to deploy and `--reset` to overwrite.

**NOTE**: Make sure that your Klaytn node is running.

Your contract address is displayed followed \`KlaytnGreeter:

```bash
$ truffle deploy --network klaytn --reset
Using network 'klaytn'.
Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x0f5108bd9e51fe6bf71dfc472577e3f55519e0b5d140a99bf65faf26830acfca
  Migrations: 0x97b1b3735c8f2326a262dbbe6c574a8ea1ba0b7d
  Deploying KlaytnGreeter...
  ... 0xcba53b6090cb4a118359b27293ba95116a8f35f66ae50fbd23ae1081ce9ffb9e
  KlaytnGreeter: [SAVE THIS ADDRESS!!] # this is your smart contract address
Saving successful migration to network...
  ... 0x14eb68727ca5a0ac767441c9b7ab077336f9311f71e9854d42c617aebceeec72
Saving artifacts...
```

**`WARNING`**: It returns an error when your account is locked.

```bash
Running migration: 1_initial_migration.js
  Replacing Migrations...
  ... undefined
Error encountered, bailing. Network state unknown. Review successful transactions manually.
Error: authentication needed: password or unlock
```

This is how you unlock your account.

```javascript
> personal.unlockAccount('0x775a59b94889a05c03c66c3c84e9d2f8308ca4abd')
Unlock account 0x75a59b94889a05c03c66c3c84e9d2f8308ca4abd
Passphrase:
true
```

And then you are ready to go. Try deploy again.


# Check the Deployment

## Checking the Deployed Byte Code using caver-js <a href="#checking-the-deployed-byte-code-using-caver-js" id="checking-the-deployed-byte-code-using-caver-js"></a>

Use `getCode` for checking the byte code of the deployed smart contract.

First, create a test file and open it.

```bash
$ touch test-klaytn.js
$ open test-klaytn.js
```

Write the following test code. Make sure you enter the contract address you just deployed.

```javascript
// test-klaytn.js
const Caver = require('caver-js');
const caver = new Caver('http://127.0.0.1:8551');
// enter your smart contract address
const contractAddress = '0x65ca27ed42abeef230a37317a574058ff1372b34'
caver.klay.getCode(contractAddress).then(console.log);
```

Run the code.

```bash
$ node test-klaytn.js
0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b514610051578063cfae321714610068575b600080fd5b34801561005d57600080fd5b506100666100f8565b005b34801561007457600080fd5b5061007d610189565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100bd5780820151818401526020810190506100a2565b50505050905090810190601f1680156100ea5780820380516001836020036101000a031916815260200191505b509250505060405180...
```

## Calling functions in the Deployed Smart Contract <a href="#calling-functions-in-the-deployed-smart-contract" id="calling-functions-in-the-deployed-smart-contract"></a>

Use JavaScript to call the `greet()` in the contract.

**NOTE**: In order to call specific functions in smart contracts, you need an ABI (Application Binary Interface) file. When Truffle deploys your contract, it automatically creates .json file at `./build/contracts/` which contains `abi` property.

Append the following lines to the test code written above.

```javascript
// test-klaytn.js
const Caver = require('caver-js');
const caver = new Caver('http://127.0.0.1:8551');
// enter your smart contract address
const contractAddress = '0x65ca27ed42abeef230a37317a574058ff1372b34'

caver.klay.getCode(contractAddress).then(console.log);
// add lines
const KlaytnGreeter = require('./build/contracts/KlaytnGreeter.json');
// enter your smart contract address
const klaytnGreeter = new caver.klay.Contract(KlaytnGreeter.abi, contractAddress);
klaytnGreeter.methods.greet().call().then(console.log);
```

Run the test code.

```bash
$ node test-klaytn.js
0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b514610051578063cfae321714610068575b600080fd5b34801561005d57600080fd5b506100666100f8565b005b34801561007457600080fd5b5061007d610189565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100bd5780820151... # This is from caver.klay.getCode
Hello, Klaytn # This is from KlyatnGreeter.methods.greet()
```

**If you got "Hello, Klaytn", you've completed the task. Congrats!**


# Account Management

**`WARNING`**: Remember your password. If you lose the password of your account, you will not be able to access that account. **There is no** ***forgot my password*** **option here. Never forget it.**

Klaytn provides two handy command-line tools, `ken` and `JavaScript console`, for developers to manage accounts. Note that exporting your private key in an unencrypted format is NOT supported.

## ken <a href="#ken" id="ken"></a>

The Klaytn Endpoint Node binary `ken` provides account management via the `account` command. The command `account` lets you create new accounts, lists all existing accounts, imports a private key into a new account, migrates to the newest key format, and changes your password.

### Usage <a href="#usage" id="usage"></a>

```bash
$ ken account <command> [options...] [arguments...]
```

**Commands**

```bash
$ ken account -help
...
COMMANDS:
     list    Print summary of existing accounts
     new     Create a new account
     update  Update an existing account
     import  Import a private key into a new account
...
```

You can get info about subcommands by `ken account <command> --help`.

```
$ ken account list --help
list [command options] [arguments...]

Print a short summary of all accounts

KLAY OPTIONS:
  --dbtype value                        Blockchain storage database type ("leveldb", "badger") (default: "leveldb")
  --datadir "/Users/ethan/Library/KEN"  Data directory for the databases and keystore
  --keystore                            Directory for the keystore (default = inside the datadir)

DATABASE OPTIONS:
  --db.no-partitioning  Disable partitioned databases for persistent storage
```

### Data Directory <a href="#data-directory" id="data-directory"></a>

Keystore files are stored under `<DATADIR>/keystore`. You can specify the data directory as below. It is highly recommended to execute `ken account` command with `--datadir` option. Make the data directory point to the `DATA_DIR` set in the `kend.conf` to seamlessly share the accounts with your Endpoint Node.

```bash
$ ken account new --datadir <DATADIR>
$ ken account new --datadir "~/kend_home"
```

If you do not specify the data directory, the default location is as follows.

* Mac: `~/Library/KEN`
* Linux: `~/.ken`

## JavaScript Console <a href="#javascript-console" id="javascript-console"></a>

To connect to the JavaScript console, an EN must be in running status. For more information, see [Launching an EN](/content/getting-started/quick-start/launch-an-en). Start an EN and attach to the console as follows.

### Usage <a href="#usage" id="usage"></a>

```bash
$ kend start
Starting kend: OK

$ ken attach ~/kend_home/klay.ipc
Welcome to the Klaytn JavaScript console!

instance: Klaytn/vX.X.X/XXXX-XXXX/goX.X.X
 datadir: ~/kend_home
 modules: admin:1.0 debug:1.0 governance:1.0 istanbul:1.0 klay:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0

>
```

**Commands**

Type `personal` or `klay` to get the list of available functions. In this tutorial, we are going to visit the following functions.

```bash
> personal.newAccount()
> personal.importRawKey()
> personal.unlockAccount()
> klay.accounts
> klay.getBalance()
```

### Data Directory <a href="#data-directory" id="data-directory"></a>

When you create an account, the keystore file is stored under `<DATADIR>/keystore`. The `<DATADIR>` is the `DATA_DIR` set in the `kend.conf`. If you follow the quick start guide with the given example, it must be `~/kend_home`.


# Creating Accounts

## Creating a New Account <a href="#creating-a-new-account" id="creating-a-new-account"></a>

This will create a new account and print the address on the screen. A keystore file is created under the data directory.

**Klaytn Keystore File**

When you create an account, a keystore file is created. The keystore file is an encrypted version of your unique Klaytn private key that you will use to sign your transactions. The keystore file name has the following format:

* `UTC--<created_at UTC ISO8601>-<address hex>`

It is safe to transfer the entire directory or the individual keystore file therein between Klaytn nodes. Note that in case you are adding keys to your node from a different node, the order of accounts may change. So make sure you do not rely on the index in your scripts or code snippets.

### ken <a href="#ken" id="ken"></a>

```bash
$ ken account new --datadir <DATADIR>
$ ken account new --password <passwordfile> --datadir <DATADIR>
$ ken account new --password <(echo $mypassword) --datadir <DATADIR>
```

**`WARNING`**: Note that using a password file is meant for testing only; it is a bad idea to save your password in a file or expose it in any other way. If you use the password flag with a password file, best to make sure the file is not readable or even listable for anyone but you. You achieve this with:

```bash
$ touch /path/to/password
$ chmod 700 /path/to/password
$ cat > /path/to/password
I type my pass here
^D
```

### JavaScript Console <a href="#javascript-console" id="javascript-console"></a>

On the console, you can call the following function to create an account:

```javascript
> personal.newAccount("passphrase")
```

The account is saved in an encrypted format. You **must** remember this passphrase to unlock your account in the future.

## Importing an Account <a href="#importing-an-account" id="importing-an-account"></a>

You can import an account using a keyfile. The keyfile is assumed to contain an unencrypted private key as canonical EC raw bytes encoded into hex. In simpler terms, it is a private key in plain text without the leading `0x`.

This imports an unencrypted private key from the given keyfile, creates a new account, generates a keystore file under the data directory, and prints the address in the console. You must remember the passphrase to unlock your account in the future.

**NOTE**: If you can directly copy your keystore files to another Klaytn instance, this import/export mechanism is not needed.

### ken <a href="#ken-1" id="ken-1"></a>

```bash
$ ken account import --datadir <datadir> <keyfile>
$ ken account import --password <passwordfile> --datadir <datadir> <keyfile>
```

### JavaScript Console <a href="#javascript-console-1" id="javascript-console-1"></a>

```bash
> personal.importRawKey('{private key}', 'mypassword')
"0xfa415bb3e6231f488ff39eb2897db0ef3636dd32"​

// Using a Klaytn wallet key
> personal.importRawKey('{private key}0x000x{address}', 'mypassword')
"0xfa415bb3e6231f488ff39eb2897db0ef3636dd32"
```


# Managing Accounts

## List Your Accounts <a href="#list-your-accounts" id="list-your-accounts"></a>

This will return the list of all accounts created under the data directory.

### ken <a href="#ken" id="ken"></a>

From the command line, call the CLI with:

```bash
$ ken account list --datadir <DATADIR>
$ ken account list --datadir ~/kend_home
Account #0: {bfc22a57999459b0c2ce6337deb9287e7a970e02} keystore:///Users/username/kend_home/keystore/UTC--2019-03-26T07-02-58.524962000Z--bfc22a57999459b0c2ce6337deb9287e7a970e02
Account #1: {47bd2e9565cbe1789454718d6cf1778d7ea557aa} keystore:///Users/username/kend_home/keystore/UTC--2019-03-26T07-04-44.840061000Z--47bd2e9565cbe1789454718d6cf1778d7ea557aa
```

**NOTE**: This order of returned account list can change if you copy keystore files from other nodes or remove the files. Therefore, make sure you either do not rely on the index or make sure if you copy or remove keystore files you check and update your account indexes in your scripts.

### JavaScript Console <a href="#javascript-console" id="javascript-console"></a>

When using the console:

```javascript
> klay.accounts
["bfc22a57999459b0c2ce6337deb9287e7a970e02", "47bd2e9565cbe1789454718d6cf1778d7ea557aa"]
```

## Unlock Accounts <a href="#unlock-accounts" id="unlock-accounts"></a>

If you want to use an account non-interactively, you need to unlock it.

### ken <a href="#ken" id="ken"></a>

You can unlock accounts and start the EN on the command line with the `--unlock "{address},{address}"` option which takes a comma-separated list of accounts (in hex or index) as an argument so you can unlock the accounts programmatically for one session. This is useful if you want to use your account from dApps via RPC. `--unlock` will unlock the first account in the list. This is useful when you created your account programmatically, you do not need to know the actual account to unlock it.

Create an account and start a node with the account unlocked:

```bash
$ ken account new --password <(echo this is not secret) --datadir <DATADIR>
$ ken --password <(echo "this is not secret") --unlock primary --datadir <DATADIR> --rpccorsdomain localhost --verbosity 6 2>> log.log
```

If you want to start a node with a specific account unlocked, you can use an address or an index which refers to the address position in the account list (and corresponds to the order of creation).

```bash
$ ken --unlock "0" --datadir <DATADIR>
$ ken --unlock "2" --datadir <DATADIR>
$ ken --unlock "bfc22a57999459b0c2ce6337deb9287e7a970e02" --datadir <DATADIR>
```

The command line allows you to unlock multiple accounts. In this case, the argument to unlock is a comma-separated list of account addresses or indexes.

```bash
$ ken --unlock "0x407d73d8a49eeb85d32cf465507dd71d507100c1,0,5,e470b1a7d2c9c5c6f03bbaa8fa20db6d404a0c32" --datadir <DATADIR>
```

If this construction is used non-interactively, your password file will need to contain the respective passwords for the accounts in question, one per line.

### JavaScript Console <a href="#javascript-console" id="javascript-console"></a>

On the console you can also unlock accounts (one at a time) for a duration (in seconds).

```javascript
> personal.unlockAccount(address, "password", 300)
```

Note that we do NOT recommend using the password argument here, since the console history is logged, so you may compromise your account. You have been warned.

## Check Account Balance <a href="#check-account-balance" id="check-account-balance"></a>

### ken <a href="#ken" id="ken"></a>

n/a

### JavaScript Console <a href="#javascript-console" id="javascript-console"></a>

To check your account balance:

```javascript
> klay.fromPeb(klay.getBalance("{account}"), "KLAY")
6.5
```

Print all balances with a JavaScript function:

```javascript
function checkAllBalances() {
    var totalBal = 0;
    for (var acctNum in klay.accounts) {
        var acct = klay.accounts[acctNum];

        var acctBal = klay.fromPeb(klay.getBalance(acct), "KLAY");
        totalBal += parseFloat(acctBal);

        console.log("klay.accounts[" + acctNum + "]: \t" + acct + " \tbalance: " + acctBal + "KLAY");

    }

    console.log("Total balance: " + totalBal + " KLAY");
};
```

That can then be executed with:

```javascript
> checkAllBalances();
klay.accounts[0]: 0xd1ade25ccd3d550a7eb532ac759cac7be09c2719  balance: 63.11848 KLAY
klay.accounts[1]: 0xda65665fc30803cb1fb7e6d86691e20b1826dee0  balance: 0 KLAY
klay.accounts[2]: 0xe470b1a7d2c9c5c6f03bbaa8fa20db6d404a0c32  balance: 1 KLAY
klay.accounts[3]: 0xf4dd5c3794f1fd0cdc0327a83aa472609c806e99  balance: 6 KLAY
```

Since this function will disappear after restarting `ken`, it can be helpful to store commonly used functions to be called later.

First, save the `checkAllBalances()` function definition to a file on your computer. For example, `/Users/username/klayload.js`. Then load the file from the interactive console:

```javascript
> loadScript("/Users/username/klayload.js")
true
```

The file will modify your JavaScript environment as if you have typed the commands manually. Feel free to experiment!


# Development Environment

**Klaytn Networks**

* Baobab testnet
* Cypress mainnet

**Endpoint Node**

* Your [Endpoint Node](/content/installation-guide/deployment/endpoint-node) is needed to connect to the Klaytn network and to issue an API call or send a transaction.
* `ken` is a Klaytn Endpoint Node binary. `ken` exposes two interfaces, a [command-line interface](/content/installation-guide/deployment/endpoint-node/ken-cli-commands) and the [JSON-RPC APIs](/content/dapp/json-rpc). `ken` runs on Linux and MacOS.
* `ken` CLI comes with several utility and node management functions.

**Smart Contract Development**

* [Klaytn Plugin for Remix](https://ide.klaytn.foundation) - Klaytn Plugin for Remix, a browser-based compiler and IDE.
* [Truffle](https://github.com/trufflesuite/truffle) - An open-source tool for developing smart contracts in Solidity.
* [Hardhat](https://hardhat.org/hardhat-runner/docs/getting-started) - A development environment for smart contracts and dApps.
* [Foundry](https://book.getfoundry.sh/) - Foundry is a smart contract development toolchain.
* [Thirdweb](https://portal.thirdweb.com/) - Thirdweb is a complete web3 development framework that provides services to build, manage, and analyze web3 applications

**Klaytn SDKs**

* [caver-js](/content/dapp/sdk/caver-js) : A JavaScript library that implements the Klaytn JSON-RPC APIs.
* [caver-java](/content/dapp/sdk/caver-java) : A Java library that implements the Klaytn JSON-RPC APIs.

**Klaytn Toolkits**

* [Klaytnscope](https://scope.klaytn.com/) - A block and transaction explorer.
* [Klaytn Wallet](https://wallet.klaytn.com/) - A browser-based account management tool.
* [Klaytn Contracts Wizard](https://wizard.klaytn.foundation/) - An interactive generator to bootstrap your smart contract and learn about Klaytn Contracts.


# Getting KLAY

### Baobab Testnet and Faucet <a href="#baobab-testnet-and-faucet" id="baobab-testnet-and-faucet"></a>

The **testnet KLAY** faucet runs on the Baobab network. The faucet can be accessed from the [Baobab Klaytn Wallet](https://baobab.wallet.klaytn.foundation). To receive testnet KLAY, you should have a valid Klaytn account.

* Load your account into the wallet using your private key or keystore file. Testnet KLAY will be sent to the loaded account.
* Clicking `Run Faucet` button will send you 5 testnet KLAY and update your balance. Note that you can run the faucet for each account once every 24 hours.

### KLAY Exchange List <a href="#klay-exchange-list" id="klay-exchange-list"></a>

KLAY is listed on various exchanges. Please find the list of KLAY exchanges through the following links.

* [KLAY exchanges listed at CoinGecko](https://www.coingecko.com/en/coins/klay#markets)
* [KLAY exchanges listed at CoinMarketCap](https://coinmarketcap.com/currencies/klaytn/markets/)


# Smart Contract

This section covers the development resources for the Smart Contract development.

To write smart contracts, Klaytn currently supports [Solidity](https://github.com/ethereum/solidity) as the primary programming language. Solidity is adopted in Klaytn because it is a *de facto* standard contract programming language for Ethereum and has a large user base and an active community. The Klaytn team decided to provide the users with familiar development experience so that the Ethereum DApp developers could easily experiment with or migrate their existing smart contracts to Klaytn.

In the future, Klaytn also plans to support writing smart contracts using other programming languages. The Klaytn team is investigating various favorable programming languages that developers might embrace.


# 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](#references) below. The content of this chapter is based on various websites listed in the [References](#references).

## Solidity and Klaytn <a href="#solidity-and-klaytn" id="solidity-and-klaytn"></a>

[Solidity](https://github.com/ethereum/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](https://solidity.readthedocs.io/en/latest/using-the-compiler.html#setting-the-evm-version-to-target).

{% hint style="success" %}
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.
{% endhint %}

Development tools such as [Remix](https://remix.ethereum.org/) (a browser-based IDE) and [Truffle](https://github.com/trufflesuite/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:

* [Installing the Solidity Compiler](https://docs.soliditylang.org/en/latest/installing-solidity.html)

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](https://github.com/ethereum/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:

* [Top Solidity tutorials](https://medium.com/coinmonks/top-solidity-tutorials-4e7adcacced8)

## How to Write a Smart Contract <a href="#how-to-write-a-smart-contract" id="how-to-write-a-smart-contract"></a>

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 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.
* `L05` - `L20` define 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](https://docs.soliditylang.org/).

## How to Compile, Deploy, and Execute <a href="#how-to-compile-deploy-and-execute" id="how-to-compile-deploy-and-execute"></a>

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.

```bash
$ solc --bin UserStorage.sol
```

* This command will print the compilation output as a binary, *i.e.*, bytecode.

```bash
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.

```bash
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](https://docs.soliditylang.org/en/latest/using-the-compiler.html)
* [Compiling contracts using Remix](https://remix-ide.readthedocs.io/en/stable/compile.html)
* [Running transactions with Remix](https://remix-ide.readthedocs.io/en/stable/run.html)
* [Remix Learneth Tutorials](https://remix-ide.readthedocs.io/en/latest/remix_tutorials_learneth.html)
* [Compiling contracts with Truffle](https://trufflesuite.com/docs/truffle/getting-started/compiling-contracts)
* [Deploying contracts with Truffle](https://trufflesuite.com/docs/truffle/getting-started/running-migrations)

NOTE: This section will be updated in the future.

## Debugging Smart Contracts <a href="#debugging-smart-contracts" id="debugging-smart-contracts"></a>

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](https://remix-ide.readthedocs.io/en/latest/debugger.html)
* [Tutorial on debugging transactions with Remix](https://remix-ide.readthedocs.io/en/latest/tutorial_debug.html)
* [Debugging contracts with Truffle](https://trufflesuite.com/docs/truffle/getting-started/using-the-truffle-debugger/)

NOTE: This section will be updated in the future.

## Smart Contract Best Practices <a href="#smart-contract-best-practices" id="smart-contract-best-practices"></a>

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.

* [Smart Contract Security Best Practices](https://github.com/ConsenSys/smart-contract-best-practices)

NOTE: This section will be updated in the future.

## References <a href="#references" id="references"></a>

* [Solidity GitHub page](https://github.com/ethereum/solidity)
* [Solidity documentation](https://solidity.readthedocs.io/en/latest/index.html)
* [Remix documentation](https://remix-ide.readthedocs.io/en/latest/)
* [Truffle documentation](https://trufflesuite.com/docs/truffle/)


# Precompiled Contracts

Klaytn provides several useful precompiled contracts. These contracts are implemented in the platform itself as a native implementation. The precompiled contracts from address 0x01 through 0x09 are the same as those in Ethereum. Klaytn additionally implements precompiled contracts from 0x3fd through 0x3ff to support new Klaytn features.

{% hint style="success" %}
NOTE: Three precompiled contract addresses have been changed, and **blake2F** was added after the `IstanbulEVM` protocol upgrade, or the "hard fork".

`IstanbulEVM` protocol upgrade block number is as follows.

* Baobab Testnet: `#75373312`
* Cypress Mainnet: `#86816005`

Contracts deployed before the protocol upgrade should use the original addresses.

* case 1) The contracts deployed in Baobab at block number `#75373310` recognizes 0x09, 0x0a, and 0x0b as addresses of vmLog, feePayer, and validateSender, respectively, and blake2f cannot be used.
* case 2) The contracts deployed in Baobab at block number `#75373314` recognizes 0x09 as the address of blake2f, and recognizes 0x3fd, 0x3fe, and 0xff as addresses of vmLog, feePayer, and validateSender.

If you want the previous document, please refer to [previous document](/content/smart-contract/precompiled-contracts/precompiled-contracts-previous).
{% endhint %}

| precompiled contract | addresses used in the contracts deployed before v1.7.0 protocol update activation | address used in the contracts deployed after v1.7.0 protocol update activation |
| -------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| vmLog                | 0x09                                                                              | 0x3fd                                                                          |
| feePayer             | 0x0a                                                                              | 0x3fe                                                                          |
| validateSender       | 0x0b                                                                              | 0x3ff                                                                          |

## Address 0x01: ecrecover(hash, v, r, s) <a href="#address-0x-01-ecrecover-hash-v-r-s" id="address-0x-01-ecrecover-hash-v-r-s"></a>

The address 0x01 implements ecrecover. It returns the address from the given signature by calculating a recovery function of ECDSA. Its function prototype is as follows:

```
function ecrecover(bytes32 hash, bytes8 v, bytes32 r, bytes32 s) returns (address);
```

## Address 0x02: sha256(data) <a href="#address-0x-02-sha-256-data" id="address-0x-02-sha-256-data"></a>

The address 0x02 implements SHA256 hash. It returns a SHA256 hash from the given data. Its function prototype is as follows:

```
function sha256(bytes data) returns (bytes32);
```

## Address 0x03: ripemd160(data) <a href="#address-0x-03-ripemd-160-data" id="address-0x-03-ripemd-160-data"></a>

The address 0x03 implements RIPEMD160 hash. It returns a RIPEMD160 hash from the given data. Its function prototype is as follows:

```
function ripemd160(bytes data) returns (bytes32);
```

## Address 0x04: datacopy(data) <a href="#address-0x-04-datacopy-data" id="address-0x-04-datacopy-data"></a>

The address 0x04 implements datacopy (i.e., identity function). It returns the input data directly without any modification. This precompiled contract is not supported by the Solidity compiler. The following code with inline assembly can be used to call this precompiled contract.

```
function callDatacopy(bytes memory data) public returns (bytes memory) {
    bytes memory ret = new bytes(data.length);
    assembly {
        let len := mload(data)
        if iszero(call(gas, 0x04, 0, add(data, 0x20), len, add(ret,0x20), len)) {
            invalid()
        }
    }

    return ret;
}     
```

## Address 0x05: bigModExp(base, exp, mod) <a href="#address-0x05-bigmodexp-base-exp-mod" id="address-0x05-bigmodexp-base-exp-mod"></a>

The address 0x05 implements the formula `base**exp % mod`. It returns the result from the given data. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract. Note that although this precompiled contract supports an arbitrary length of inputs, the below code uses a fixed length of inputs as an example.

```
function callBigModExp(bytes32 base, bytes32 exponent, bytes32 modulus) public returns (bytes32 result) {
    assembly {
        // free memory pointer
        let memPtr := mload(0x40)

        // length of base, exponent, modulus
        mstore(memPtr, 0x20)
        mstore(add(memPtr, 0x20), 0x20)
        mstore(add(memPtr, 0x40), 0x20)

        // assign base, exponent, modulus
        mstore(add(memPtr, 0x60), base)
        mstore(add(memPtr, 0x80), exponent)
        mstore(add(memPtr, 0xa0), modulus)

        // call the precompiled contract BigModExp (0x05)
        let success := call(gas, 0x05, 0x0, memPtr, 0xc0, memPtr, 0x20)
        switch success
        case 0 {
            revert(0x0, 0x0)
        } default {
            result := mload(memPtr)
        }
    }
}
```

## Address 0x06: bn256Add(ax, ay, bx, by) <a href="#address-0x-06-bn-256-add-ax-ay-bx-by" id="address-0x-06-bn-256-add-ax-ay-bx-by"></a>

The address 0x06 implements a native elliptic curve point addition. It returns an elliptic curve point representing `(ax, ay) + (bx, by)` such that (ax, ay) and (bx, by) are valid points on the curve bn256. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.

```
function callBn256Add(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns (bytes32[2] memory result) {
    bytes32[4] memory input;
    input[0] = ax;
    input[1] = ay;
    input[2] = bx;
    input[3] = by;
    assembly {
        let success := call(gas, 0x06, 0, input, 0x80, result, 0x40)
        switch success
        case 0 {
            revert(0,0)
        }
    }
}
```

## Address 0x07: bn256ScalarMul(x, y, scalar) <a href="#address-0x-07-bn-256-scalarmul-x-y-scalar" id="address-0x-07-bn-256-scalarmul-x-y-scalar"></a>

The address 0x07 implements a native elliptic curve multiplication with a scalar value. It returns an elliptic curve point representing `scalar * (x, y)` such that (x, y) is a valid curve point on the curve bn256. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.

```
function callBn256ScalarMul(bytes32 x, bytes32 y, bytes32 scalar) public returns (bytes32[2] memory result) {
    bytes32[3] memory input;
    input[0] = x;
    input[1] = y;
    input[2] = scalar;
    assembly {
        let success := call(gas, 0x07, 0, input, 0x60, result, 0x40)
        switch success
        case 0 {
            revert(0,0)
        }
    }
}
```

## Address 0x08: bn256Pairing(a1, b1, a2, b2, a3, b3, ..., ak, bk) <a href="#address-0x-08-bn-256-pairing-a-1-b-1-a-2-b-2-a-3-b-3-ak-bk" id="address-0x-08-bn-256-pairing-a-1-b-1-a-2-b-2-a-3-b-3-ak-bk"></a>

The address 0x08 implements elliptic curve paring operation to perform zkSNARK verification. For more information, see [EIP-197](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md). This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.

```
function callBn256Pairing(bytes memory input) public returns (bytes32 result) {
    // input is a serialized bytes stream of (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k
    uint256 len = input.length;
    require(len % 192 == 0);
    assembly {
        let memPtr := mload(0x40)
        let success := call(gas, 0x08, 0, add(input, 0x20), len, memPtr, 0x20)
        switch success
        case 0 {
            revert(0,0)
        } default {
            result := mload(memPtr)
        }
    }
}
```

## Address 0x09: blake2F(rounds, h, m, t, f) <a href="#address-0x-3fc-vmlog-str" id="address-0x-3fc-vmlog-str"></a>

The address 0x09 implements BLAKE2b F compression function. For more information, see [EIP-152](https://eips.ethereum.org/EIPS/eip-152). This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.

```
function callBlake2F(uint32 rounds, bytes32[2] memory h, bytes32[4] memory m, bytes8[2] memory t, bool f) public view returns (bytes32[2] memory) {
    bytes32[2] memory output;

    bytes memory args = abi.encodePacked(rounds, h[0], h[1], m[0], m[1], m[2], m[3], t[0], t[1], f);

    assembly {
        if iszero(staticcall(not(0), 0x09, add(args, 32), 0xd5, output, 0x40)) {
            revert(0, 0)
        }
    }

    return output;
}
```

## Address 0x3fd: vmLog(str) <a href="#address-0x-3fc-vmlog-str" id="address-0x-3fc-vmlog-str"></a>

The address 0x3FD prints the specified string `str` to a specific file or passes it to the logger module. For more information, see [debug\_setVMLogTarget](/content/dapp/json-rpc/api-references/debug/logging#debug_setvmlogtarget). Note that this precompiled contract should be used only for debugging purposes, and it is required to enable the `--vmlog` option when the Klaytn node starts. Also, the log level of the Klaytn node should be 4 or more to see the output of vmLog. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.

```
function callVmLog(bytes memory str) public {
    address(0x3fd).call(str);
}
```

## Address 0x3fe: feePayer() <a href="#address-0x-3fd-feepayer" id="address-0x-3fd-feepayer"></a>

The address 0x3FE returns a fee payer of the executing transaction. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.

```
function feePayer() internal returns (address addr) {
    assembly {
        let freemem := mload(0x40)
        let start_addr := add(freemem, 12)
        if iszero(call(gas, 0x3fe, 0, 0, 0, start_addr, 20)) {
          invalid()
        }
        addr := mload(freemem)
    }
}
```

## Address 0x3ff: validateSender() <a href="#address-0x-3fe-validatesender" id="address-0x-3fe-validatesender"></a>

The address 0x3FF validates the sender's signature with the message. Since Klaytn [decouples key pairs from addresses](/content/klaytn/design/accounts#decoupling-key-pairs-from-addresses), it is required to validate that a signature is properly signed by the corresponding sender. To do that, this precompiled contract receives three parameters:

* The sender's address to get the public keys
* The message hash that is used to generate the signature
* The signatures that are signed by the sender's private keys with the given message hash

The precompiled contract validates that the given signature is properly signed by the sender's private keys. Note that Klaytn natively support multi signatures, which means there can be multiple signatures. The signature must be 65 bytes long.

```
function ValidateSender(address sender, bytes32 msgHash, bytes sigs) public returns (bool) {
    require(sigs.length % 65 == 0);
    bytes memory data = new bytes(20+32+sigs.length);
    uint idx = 0;
    uint i;
    for( i = 0; i < 20; i++) {
        data[idx++] = (bytes20)(sender)[i];
    }
    for( i = 0; i < 32; i++ ) {
        data[idx++] = msgHash[i];
    }
    for( i = 0; i < sigs.length; i++) {
        data[idx++] = sigs[i];
    }
    assembly {
        // skip length header.
        let ptr := add(data, 0x20)
        if iszero(call(gas, 0x3ff, 0, ptr, idx, 31, 1)) {
          invalid()
        }
        return(0, 32)
    }
}
```


# Precompiled Contracts (Previous docs)

Klaytn provides several useful precompiled contracts. These contracts are implemented in the platform itself as a native implementation. The precompiled contracts from address 0x01 through 0x08 are the same as those in Ethereum. Klaytn additionally implements precompiled contracts from 0x09 through 0x0B to support new Klaytn features.

{% hint style="success" %}
NOTE: This document contains the gas table used before the activation of the protocol upgrade. If you want the latest document, please refer to [latest document](/content/smart-contract/precompiled-contracts).
{% endhint %}

## Address 0x01: ecrecover(hash, v, r, s) <a href="#address-0x-01-ecrecover-hash-v-r-s" id="address-0x-01-ecrecover-hash-v-r-s"></a>

The address 0x01 implements ecrecover. It returns the address from the given signature by calculating a recovery function of ECDSA. Its function prototype is as follows:

```
function ecrecover(bytes32 hash, bytes8 v, bytes32 r, bytes32 s) returns (address);
```

## Address 0x02: sha256(data) <a href="#address-0x-02-sha-256-data" id="address-0x-02-sha-256-data"></a>

The address 0x02 implements SHA256 hash. It returns a SHA256 hash from the given data. Its function prototype is as follows:

```
function sha256(bytes data) returns (bytes32);
```

## Address 0x03: ripemd160(data) <a href="#address-0x-03-ripemd-160-data" id="address-0x-03-ripemd-160-data"></a>

The address 0x03 implements RIPEMD160 hash. It returns a RIPEMD160 hash from the given data. Its function prototype is as follows:

```
function ripemd160(bytes data) returns (bytes32);
```

## Address 0x04: datacopy(data) <a href="#address-0x-04-datacopy-data" id="address-0x-04-datacopy-data"></a>

The address 0x04 implements datacopy (i.e., identity function). It returns the input data directly without any modification. This precompiled contract is not supported by the Solidity compiler. The following code with inline assembly can be used to call this precompiled contract.

```
function callDatacopy(bytes memory data) public returns (bytes memory) {
    bytes memory ret = new bytes(data.length);
    assembly {
        let len := mload(data)
        if iszero(call(gas, 0x04, 0, add(data, 0x20), len, add(ret,0x20), len)) {
            invalid()
        }
    }

    return ret;
}     
```

## Address 0x05: bigModExp(base, exp, mod) <a href="#address-0x05-bigmodexp-base-exp-mod" id="address-0x05-bigmodexp-base-exp-mod"></a>

The address 0x05 implements the formula `base**exp % mod`. It returns the result from the given data. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract. Note that although this precompiled contract supports an arbitrary length of inputs, the below code uses a fixed length of inputs as an example.

```
function callBigModExp(bytes32 base, bytes32 exponent, bytes32 modulus) public returns (bytes32 result) {
    assembly {
        // free memory pointer
        let memPtr := mload(0x40)

        // length of base, exponent, modulus
        mstore(memPtr, 0x20)
        mstore(add(memPtr, 0x20), 0x20)
        mstore(add(memPtr, 0x40), 0x20)

        // assign base, exponent, modulus
        mstore(add(memPtr, 0x60), base)
        mstore(add(memPtr, 0x80), exponent)
        mstore(add(memPtr, 0xa0), modulus)

        // call the precompiled contract BigModExp (0x05)
        let success := call(gas, 0x05, 0x0, memPtr, 0xc0, memPtr, 0x20)
        switch success
        case 0 {
            revert(0x0, 0x0)
        } default {
            result := mload(memPtr)
        }
    }
}
```

## Address 0x06: bn256Add(ax, ay, bx, by) <a href="#address-0x-06-bn-256-add-ax-ay-bx-by" id="address-0x-06-bn-256-add-ax-ay-bx-by"></a>

The address 0x06 implements a native elliptic curve point addition. It returns an elliptic curve point representing `(ax, ay) + (bx, by)` such that (ax, ay) and (bx, by) are valid points on the curve bn256. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.

```
function callBn256Add(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns (bytes32[2] memory result) {
    bytes32[4] memory input;
    input[0] = ax;
    input[1] = ay;
    input[2] = bx;
    input[3] = by;
    assembly {
        let success := call(gas, 0x06, 0, input, 0x80, result, 0x40)
        switch success
        case 0 {
            revert(0,0)
        }
    }
}
```

## Address 0x07: bn256ScalarMul(x, y, scalar) <a href="#address-0x-07-bn-256-scalarmul-x-y-scalar" id="address-0x-07-bn-256-scalarmul-x-y-scalar"></a>

The address 0x07 implements a native elliptic curve multiplication with a scalar value. It returns an elliptic curve point representing `scalar * (x, y)` such that (x, y) is a valid curve point on the curve bn256. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.

```
function callBn256ScalarMul(bytes32 x, bytes32 y, bytes32 scalar) public returns (bytes32[2] memory result) {
    bytes32[3] memory input;
    input[0] = x;
    input[1] = y;
    input[2] = scalar;
    assembly {
        let success := call(gas, 0x07, 0, input, 0x60, result, 0x40)
        switch success
        case 0 {
            revert(0,0)
        }
    }
}
```

## Address 0x08: bn256Pairing(a1, b1, a2, b2, a3, b3, ..., ak, bk) <a href="#address-0x-08-bn-256-pairing-a-1-b-1-a-2-b-2-a-3-b-3-ak-bk" id="address-0x-08-bn-256-pairing-a-1-b-1-a-2-b-2-a-3-b-3-ak-bk"></a>

The address 0x08 implements elliptic curve paring operation to perform zkSNARK verification. For more information, see [EIP-197](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md). This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.

```
function callBn256Pairing(bytes memory input) public returns (bytes32 result) {
    // input is a serialized bytes stream of (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k
    uint256 len = input.length;
    require(len % 192 == 0);
    assembly {
        let memPtr := mload(0x40)
        let success := call(gas, 0x08, 0, add(input, 0x20), len, memPtr, 0x20)
        switch success
        case 0 {
            revert(0,0)
        } default {
            result := mload(memPtr)
        }
    }
}
```

## Address 0x09: vmLog(str) <a href="#address-0x-09-vmlog-str" id="address-0x-09-vmlog-str"></a>

The address 0x09 prints the specified string `str` to a specific file or passes it to the logger module. For more information, see [debug\_setVMLogTarget](https://github.com/klaytn/klaytn-docs/blob/main/docs/smart-contract/dapp/json-rpc/api-references/debug/logging.md#debug_setvmlogtarget). Note that this precompiled contract should be used only for debugging purposes, and it is required to enable the `--vmlog` option when the Klaytn node starts. Also, the log level of the Klaytn node should be 4 or more to see the output of vmLog. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.

```
function callVmLog(bytes memory str) public {
    address(0x09).call(str);
}
```

## Address 0x0A: feePayer() <a href="#address-0x-0-a-feepayer" id="address-0x-0-a-feepayer"></a>

The address 0x0A returns a fee payer of the executing transaction. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.

```
function feePayer() internal returns (address addr) {
    assembly {
        let freemem := mload(0x40)
        let start_addr := add(freemem, 12)
        if iszero(call(gas, 0x0a, 0, 0, 0, start_addr, 20)) {
          invalid()
        }
        addr := mload(freemem)
    }
}
```

## Address 0x0B: validateSender() <a href="#address-0x-0-b-validatesender" id="address-0x-0-b-validatesender"></a>

The address 0x0B validates the sender's signature with the message. Since Klaytn [decouples key pairs from addresses](https://github.com/klaytn/klaytn-docs/blob/main/docs/smart-contract/klaytn/design/accounts.md#decoupling-key-pairs-from-addresses), it is required to validate that a signature is properly signed by the corresponding sender. To do that, this precompiled contract receives three parameters:

* The sender's address to get the public keys
* The message hash that is used to generate the signature
* The signatures that are signed by the sender's private keys with the given message hash

The precompiled contract validates that the given signature is properly signed by the sender's private keys. Note that Klaytn natively support multi signatures, the signatures can be multiple. The length of a signature must be 65 byte long.

```
function ValidateSender(address sender, bytes32 msgHash, bytes sigs) public returns (bool) {
    require(sigs.length % 65 == 0);
    bytes memory data = new bytes(20+32+sigs.length);
    uint idx = 0;
    uint i;
    for( i = 0; i < 20; i++) {
        data[idx++] = (bytes20)(sender)[i];
    }
    for( i = 0; i < 32; i++ ) {
        data[idx++] = msgHash[i];
    }
    for( i = 0; i < sigs.length; i++) {
        data[idx++] = sigs[i];
    }
    assembly {
        // skip length header.
        let ptr := add(data, 0x20)
        if iszero(call(gas, 0x0b, 0, ptr, idx, 31, 1)) {
          invalid()
        }
        return(0, 32)
    }
}
```


# IDE and Tools

This page contains the list of development tools that is available to help smart contract development on Klaytn.

#### [Remix Online IDE](https://github.com/klaytn/klaytn-docs/blob/main/docs/toolkit/klaytn-ide.md) <a href="#remix-ide" id="remix-ide"></a>

* Remix Online IDE is a powerful toolset for developing, deploying, debugging, and testing EVM-compatible smart contracts. You can write, compile, deploy and execute smart contracts on Klaytn from Remix IDE, using Klaytn Plugin.

#### [Klaytn Contracts Wizard](https://wizard.klaytn.foundation/) <a href="#klaytn-contract-wizard" id="klaytn-contract-wizard"></a>

* Klaytn Contracts Wizard is an interactive generator to bootstrap your smart contract and learn about Klaytn Contracts. This is based on OpenZeppelin Wizard.

#### [Truffle](/content/smart-contract/ide-and-tools/truffle) <a href="#truffle" id="truffle"></a>

* Klaytn smart contracts written in Solidity can be compiled and deployed using Truffle. At the moment, Klaytn supports up to Truffle v5.0.26.

#### [Kaikas](/content/dapp/developer-tools/getting-started/kaikas) <a href="#kaikas" id="kaikas"></a>

* Kaikas is a browser extension wallet for the Klaytn Network. Kaikas empowers you to store and interact with KLAY and your Klaytn-based tokens. Kaikas also enables you to sign transactions from web-based Klaytn dApps in realtime.

#### [Klaytn Wallet](/content/dapp/developer-tools/getting-started/klaytn-wallet) <a href="#klaytn-wallet" id="klaytn-wallet"></a>

* Klaytn Wallet is a browser-based account management tool for the Decentralized Application (dApp) developers. You can create/load your accounts, review your account balance, and transfer KLAY. You can also register your own Klaytn tokens to test basic behaviors.

#### [Klaytnscope](/content/dapp/developer-tools/getting-started-4/klaytnscope) <a href="#klaytnscope" id="klaytnscope"></a>

* Klaytnscope is the block explorer for the Klaytn Network. You can browse and inspect your transactions on the browser.


# Truffle

## Compatibility with Truffle <a href="#compatibility-with-truffle" id="compatibility-with-truffle"></a>

In Klaytn, a smart contract written in Solidity can be compiled and deployed via Truffle. At the moment, Klaytn supports up to Truffle v5.0.26, the latest version at the time of writing. Please find details about Truffle on the websites below.

* [Truffle overview](https://trufflesuite.com/docs/truffle/overview)
* [Truffle repository](https://github.com/trufflesuite/truffle)

You can install Truffle as the following:

```
$ sudo npm install -g truffle
```

If you have a local EN running, you can deploy contracts directly with truffle framework. For more details, refer to this [link](/content/getting-started/quick-start/deploy-a-smart-contract#deploying-a-smart-contract-using-truffle).

If you want to deploy with a remote EN node, you should use [truffle-hdwallet-provider-klaytn](https://www.npmjs.com/package/truffle-hdwallet-provider-klaytn).

## Configuring truffle-hdwallet-provider-klaytn <a href="#configuring-truffle-hdwallet-provider-klaytn" id="configuring-truffle-hdwallet-provider-klaytn"></a>

truffle-hdwallet-provider-klaytn is a JavaScript HD wallet provider forked from truffle-hdwallet-provider.

Install as the following:

```
$ nvm use 10
$ yarn install truffle-hdwallet-provider-klaytn@1.0.18
```

```
$ nvm use 12 # for node v12 and higher
$ yarn install truffle-hdwallet-provider-klaytn@1.4.1
```

Set `truffle-config.js` as below.

### Using a mnemonic <a href="#using-a-mnemonic" id="using-a-mnemonic"></a>

```javascript
const HDWalletProvider = require("truffle-hdwallet-provider-klaytn");

const mnemonic = "mountains supernatural bird ...";

module.exports = {
  networks: {
    development: {
      host: "localhost",
      port: 8551,
      network_id: "*", // Match any network id
    },
    klaytn: {
      provider: () => {
        const mnemonic = JSON.parse(
          fs.readFileSync(path.resolve(__dirname) + "/mnemonics.js")
        );

        return new HDWalletProvider(
          mnemonic,
          "https://public-en-baobab.klaytn.net",
          0,
          mnemonic.length
        );
      },
      network_id: "1001", //Klaytn baobab testnet's network id
      gas: "8500000",
      gasPrice: null,
    },
    kasBaobab: {
      provider: () => {
        const option = {
          headers: [
            {
              name: "Authorization",
              value:
                "Basic " +
                Buffer.from(accessKeyId + ":" + secretAccessKey).toString(
                  "base64"
                ),
            },
            { name: "x-chain-id", value: "1001" },
          ],
          keepAlive: false,
        };
        return new HDWalletProvider(
          mnemonic,
          new Caver.providers.HttpProvider(
            "https://node-api.klaytnapi.com/v1/klaytn",
            option
          )
        );
      },
      network_id: "1001", //Klaytn baobab testnet's network id
      gas: "8500000",
      gasPrice: "25000000000",
    },
    kasCypress: {
      provider: () => {
        const option = {
          headers: [
            {
              name: "Authorization",
              value:
                "Basic " +
                Buffer.from(accessKeyId + ":" + secretAccessKey).toString(
                  "base64"
                ),
            },
            { name: "x-chain-id", value: "8217" },
          ],
          keepAlive: false,
        };
        return new HDWalletProvider(
          cypressMnemonic,
          new Caver.providers.HttpProvider(
            "https://node-api.klaytnapi.com/v1/klaytn",
            option
          )
        );
      },
      network_id: "8217", //Klaytn baobab testnet's network id
      gas: "8500000",
      gasPrice: "25000000000",
    },
    baobab: {
      provider: () => {
        return new HDWalletProvider(mnemonic, "http://your.baobab.en:8551");
      },
      network_id: "1001", //Klaytn baobab testnet's network id
      gas: "8500000",
      gasPrice: null,
    },
    cypress: {
      provider: () => {
        return new HDWalletProvider(mnemonic, "http://your.cypress.en:8551");
      },
      network_id: "8217", //Klaytn mainnet's network id
      gas: "8500000",
      gasPrice: null,
    },
  },
};
```

### Using a private key <a href="#using-a-private-key" id="using-a-private-key"></a>

```javascript
const HDWalletProvider = require("truffle-hdwallet-provider-klaytn");

const privateKey = "0x123 ...";

module.exports = {
  networks: {
    development: {
      host: "localhost",
      port: 8551,
      network_id: "*", // Match any network id
    },
    klaytn: {
      provider: () => {
        const pks = JSON.parse(
          fs.readFileSync(path.resolve(__dirname) + "/privateKeys.js")
        );

        return new HDWalletProvider(
          pks,
          "https://public-en-baobab.klaytn.net",
          0,
          pks.length
        );
      },
      network_id: "1001", //Klaytn baobab testnet's network id
      gas: "8500000",
      gasPrice: null,
    },
    kasBaobab: {
      provider: () => {
        const option = {
          headers: [
            {
              name: "Authorization",
              value:
                "Basic " +
                Buffer.from(accessKeyId + ":" + secretAccessKey).toString(
                  "base64"
                ),
            },
            { name: "x-chain-id", value: "1001" },
          ],
          keepAlive: false,
        };
        return new HDWalletProvider(
          privateKey,
          new Caver.providers.HttpProvider(
            "https://node-api.klaytnapi.com/v1/klaytn",
            option
          )
        );
      },
      network_id: "1001", //Klaytn baobab testnet's network id
      gas: "8500000",
      gasPrice: "25000000000",
    },
    kasCypress: {
      provider: () => {
        const option = {
          headers: [
            {
              name: "Authorization",
              value:
                "Basic " +
                Buffer.from(accessKeyId + ":" + secretAccessKey).toString(
                  "base64"
                ),
            },
            { name: "x-chain-id", value: "8217" },
          ],
          keepAlive: false,
        };
        return new HDWalletProvider(
          cypressPrivateKey,
          new Caver.providers.HttpProvider(
            "https://node-api.klaytnapi.com/v1/klaytn",
            option
          )
        );
      },
      network_id: "8217", //Klaytn baobab testnet's network id
      gas: "8500000",
      gasPrice: "25000000000",
    },
    baobab: {
      provider: () => {
        return new HDWalletProvider(privateKey, "http://api.baobab.klaytn.net:8651");
      },
      network_id: "1001", //Klaytn baobab testnet's network id
      gas: "8500000",
      gasPrice: null,
    },
    cypress: {
      provider: () => {
        return new HDWalletProvider(privateKey, "https://public-en-cypress.klaytn.net");
      },
      network_id: "8217", //Klaytn mainnet's network id
      gas: "8500000",
      gasPrice: null,
    },
  },
};
```

**WARNING: Be very careful not to expose your mneomonic or private key.**

Deploying on Klaytn :

```bash
$ truffle deploy --network baobab  # testnet
$ truffle deploy --network cypress # mainnet
```

Making transaction on Klaytn : (using an example from [Truffle Docs quick start - Creating a project](https://www.trufflesuite.com/docs/truffle/quickstart#creating-a-project))

```bash
$ truffle console --network baobab
truffle(baobab)> Migrations.deployed().then(function(instance) {return instance.setCompleted(3)}) // making transaction
{
  tx: '0x734676311194c1ab8e004e2990e414b7b47a9d0a8506682707f5db03fa6dcee0',
  receipt: {
    blockHash: '0xdf9d77ef893a70b3a3f073525cdf5b2ee36620a3ac81815437788e4cf121678d',
    blockNumber: 65284860,
    contractAddress: null,
    from: '0x50c82047a414d2aad88ae67a5f02c311d2d86e69',
    gas: '0x500000',
    gasPrice: '0x5d21dba00',
    gasUsed: 27001,
    input: '0xfdacd5760000000000000000000000000000000000000000000000000000000000000003',
    logs: [],
    logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
    nonce: '0x1047',
    senderTxHash: '0x734676311194c1ab8e004e2990e414b7b47a9d0a8506682707f5db03fa6dcee0',
    signatures: [ [Object] ],
    status: true,
    to: '0x69527b5f0078ae1757b631af155fa9be21ef6a85',
    transactionHash: '0x734676311194c1ab8e004e2990e414b7b47a9d0a8506682707f5db03fa6dcee0',
    transactionIndex: 0,
    type: 'TxTypeLegacyTransaction',
    typeInt: 0,
    value: '0x0',
    cumulativeGasUsed: undefined,
    rawLogs: []
  },
  logs: []
}

truffle(baobab)> Migrations.deployed().then(function(instance) {return instance.last_completed_migration.call()}) // read public variable
BN { negative: 0, words: [ 3, <1 empty item> ], length: 1, red: null }
```


# Sample Contracts


# KlaytnGreeter

`KlaytnGreeter` is a simple contract that returns a greeting message. Greeting message is set when the contract is deployed.

## Writing KlaytnGreeter <a href="#writing-klaytngreeter" id="writing-klaytngreeter"></a>

```
pragma solidity 0.5.6;
contract Mortal {
    /* Define variable owner of the type address */
    address payable owner;
    /* This function is executed at initialization and sets the owner of the contract */
    constructor () public { owner = msg.sender; }
    /* Function to recover the funds on the contract */
    function kill() public { if (msg.sender == owner) selfdestruct(owner); }
}

contract KlaytnGreeter is Mortal {
    /* Define variable greeting of the type string */
    string greeting;
    /* This runs once when the contract is created */
    constructor (string memory _greeting) public {
        greeting = _greeting;
    }
    /* Main function */
    function greet() public view returns (string memory) {
        return greeting;
    }
}
```

## Deploying KlaytnGreeter using Remix Online IDE <a href="#deploying-klaytngreeter-using-klaytn-ide" id="deploying-klaytngreeter-using-klaytn-ide"></a>

* Please visit [Klaytn Plugin for Remix](https://ide.klaytn.foundation) and create a `KlaytnGreeter` contract. The complete source code was given in the above.
* Prepare your account which will be used to deploy the contract.
  * If you do not have an account yet, create one at <https://baobab.wallet.klaytn.foundation/create> or <https://toolkit.klaytn.foundation/account/accountKeyLegacy>.
  * Get some test KLAY from the faucet - <https://baobab.wallet.klaytn.foundation/faucet>
* Deploy the contract with initial parameter, a greeting message.
* After deploying, you can invoke `greet` from the IDE.

## References <a href="#references" id="references"></a>

For the details of contract deployment and the Remix Online IDE usage guideline, please refer to the following documents.

* [Remix Online IDE](/content/smart-contract/ide-and-tools#klaytn-ide)
* [Truffle](/content/smart-contract/ide-and-tools#truffle)
* [Deploy Guide](/content/smart-contract/deploy-guide)


# ERC-20

## Introduction <a href="#introduction" id="introduction"></a>

This tutorial helps you to create an example ERC-20 compatible token that conforms to the [Klaytn Token Standards](/content/smart-contract/token-standard), especially [Fungible Token Standard (ERC-20)](/content/smart-contract/token-standard#fungible-token-standard-kip-7).

[ERC-20 Token Standard](https://eips.ethereum.org/EIPS/eip-20) defines two events and 9 methods (including 3 optional methods) as below. ERC-20-compatible tokens are token contracts that implements the following interface.

```
function name() public view returns (string) //optional
function symbol() public view returns (string) //optional
function decimals() public view returns (uint8) //optional
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256 balance)
function transfer(address _to, uint256 _value) public returns (bool success)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
function approve(address _spender, uint256 _value) public returns (bool success)
function allowance(address _owner, address _spender) public view returns (uint256 remaining)

event Transfer(address indexed _from, address indexed _to, uint256 _value)
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
```

Based on above interface, developers may customize tokens by adding new features and logics, and deploy on Klaytn network. For more information, refer to official [ERC-20 documentation](https://eips.ethereum.org/EIPS/eip-20).

In this tutorial, you are going to implement `MyERC20.sol`, an ERC-20 compatible token. This token will issue a predefined amount of tokens and sends all of the tokens to the contract owner on its deploy.

`MyERC20.sol` is based on OpenZeppelin's ERC20 implementation. A major part of the code in this tutorial is forked from [OpenZeppelin 2.3 ](https://github.com/OpenZeppelin/openzeppelin-solidity/releases/tag/v2.3.0)and following Solidity files are used to implement `MyERC20.sol`.

* <https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/token/ERC20/IERC20.sol>
* <https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/token/ERC20/ERC20.sol>
* <https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/token/ERC20/ERC20Detailed.sol>
* <https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/math/SafeMath.sol>

The rest of this tutorial is organized as follows.

* [1. Writing ERC-20 smart contract](/content/smart-contract/sample-contracts/erc-20/1-erc20)
  * 1.1 Overall structure of `MyERC20` code with whole `MyERC20` code
  * 1.2 Take a look at important functions
* [2. Deploying smart contract](/content/smart-contract/sample-contracts/erc-20/2-erc20)
  * 2.1 Deploying smart contract using Klaytn IDE
  * 2.2 Deploying smart contract using truffle
* [3. Interacting between ERC-20 token and Klaytn wallet](/content/smart-contract/sample-contracts/erc-20/3-erc20)


# 1. Writing ERC-20 Smart Contract

## 1.1 Overall structure of MyERC20 <a href="#id-1-1-overall-structure-of-myerc20" id="id-1-1-overall-structure-of-myerc20"></a>

The complete source code of `MyERC20.sol` is given below. In this implementation, `constructor` invokes `_mint` to mint a predefined amount of token on contract deploy.

```
pragma solidity ^0.5.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see `ERC20Detailed`.
 */
interface IERC20 {
    function totalSupply() external view returns (uint256);

    function balanceOf(address account) external view returns (uint256);

    function transfer(address recipient, uint256 amount) external returns (bool);

    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 amount) external returns (bool);

    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(address indexed owner, address indexed spender, uint256 value);
}

library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

/**
 * @dev Implementation of the `IERC20` interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using `_mint`.
 * For a generic mechanism see `ERC20Mintable`.
 *
 * *For a detailed writeup see our guide [How to implement supply
 * mechanisms](https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226).*
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an `Approval` event is emitted on calls to `transferFrom`.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard `decreaseAllowance` and `increaseAllowance`
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See `IERC20.approve`.
 */
contract MyERC20 is IERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    // NOTE Start of https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/token/ERC20/ERC20Detailed.sol
    string private _name;
    string private _symbol;
    uint8 private _decimals;

    constructor (string memory name, string memory symbol, uint8 decimals) public {
        _name = name;
        _symbol = symbol;
        _decimals = decimals;

        _mint(msg.sender, 100000 * 10 ** uint256(decimals)); // CAUTION!
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei.
     *
     * > Note that this information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * `IERC20.balanceOf` and `IERC20.transfer`.
     */
    function decimals() public view returns (uint8) {
        return _decimals;
    }
    // NOTE End of https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/token/ERC20/ERC20Detailed.sol

    uint256 private _totalSupply;

    /**
     * @dev See `IERC20.totalSupply`.
     */
    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See `IERC20.balanceOf`.
     */
    function balanceOf(address account) public view returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See `IERC20.transfer`.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public returns (bool) {
        _transfer(msg.sender, recipient, amount);
        return true;
    }

    /**
     * @dev See `IERC20.allowance`.
     */
    function allowance(address owner, address spender) public view returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See `IERC20.approve`.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public returns (bool) {
        _approve(msg.sender, spender, value);
        return true;
    }

    /**
     * @dev See `IERC20.transferFrom`.
     *
     * Emits an `Approval` event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of `ERC20`;
     *
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `value`.
     * - the caller must have allowance for `sender`'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to `approve` that can be used as a mitigation for
     * problems described in `IERC20.approve`.
     *
     * Emits an `Approval` event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
        _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to `approve` that can be used as a mitigation for
     * problems described in `IERC20.approve`.
     *
     * Emits an `Approval` event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
        _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to `transfer`, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a `Transfer` event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _balances[sender] = _balances[sender].sub(amount);
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a `Transfer` event with `from` set to the zero address.
     *
     * Requirements
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal {
        require(account != address(0), "ERC20: mint to the zero address");

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

     /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a `Transfer` event with `to` set to the zero address.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 value) internal {
        require(account != address(0), "ERC20: burn from the zero address");

	_balances[account] = _balances[account].sub(value);
        _totalSupply = _totalSupply.sub(value);
        emit Transfer(account, address(0), value);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
     *
     * This is internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an `Approval` event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = value;
        emit Approval(owner, spender, value);
    }

    /**
     * @dev Destoys `amount` tokens from `account`.`amount` is then deducted
     * from the caller's allowance.
     *
     * See `_burn` and `_approve`.
     */
    function _burnFrom(address account, uint256 amount) internal {
        _burn(account, amount);
        _approve(account, msg.sender, _allowances[account][msg.sender].sub(amount));
    }
}
```

`MyERC20.sol` consists of one interface `IERC20`, one library `SafeMath` and one contract `MyERC20` which implements `IERC20` interface.

* `IERC20` interface defines mandatory interface described at [ERC-20 specification](https://eips.ethereum.org/EIPS/eip-20).
* `SafeMath` library defines wrappers over Solidity's arithmetic operations with added overflow checks for safe calculation of `uint256` type of Solidity.
* `MyERC20` implements `IERC20` interfaces and also defines three optional methods described at [ERC-20 specification](https://eips.ethereum.org/EIPS/eip-20).
  * In addition to ERC20, `constructor` is defined and this constructor is used to define a new ERC20 token name and symbol, and to mint a predefined amount of token. `constructor` is called once on its first deploy.

## 1.2 Take a look at important methods <a href="#id-1-2-take-a-look-at-important-methods" id="id-1-2-take-a-look-at-important-methods"></a>

Let's take a look at some important methods in detail.

### (1) `function balanceOf(address account) external view returns (uint256);` <a href="#id-1-function-balanceof-address-account-external-view-returns-uint256" id="id-1-function-balanceof-address-account-external-view-returns-uint256"></a>

`balanceOf` is a mandatory method of ERC-20. `balanceOf` returns the balance of the given address.

```
    function balanceOf(address account) public view returns (uint256) {
        return _balances[account];
    }
```

`balanceOf` just returns of value of key `account` stored in `_balances` which is `mapping (address => uint256)` type as below.

```
    mapping (address => uint256) private _balances;
```

If there is no key `account` available in `_balances`, then it just returns `0`.

### (2) `function transfer(address recipient, uint256 amount) external returns (bool);` <a href="#id-2-function-transfer-address-recipient-uint256-amount-external-returns-bool" id="id-2-function-transfer-address-recipient-uint256-amount-external-returns-bool"></a>

`transfer` is a mandatory method of ERC-20. `transfer` transfers `amount` of tokens to `recipient`, and MUST fire the `Transfer` event. The function SHOULD throw if the message caller’s account balance does not have enough tokens to spend.

`transfer` just invokes internal method `_transfer` which implements actual transfer and event as below.

```
    function transfer(address recipient, uint256 amount) public returns (bool) {
        _transfer(msg.sender, recipient, amount);
        return true;
    }
```

`_transfer` implements actual behavior of `transfer` method of ERC-20.

In addition, it prevents sending token from or to zero address using `require` as below.

```
    function _transfer(address sender, address recipient, uint256 amount) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _balances[sender] = _balances[sender].sub(amount);
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }
```

### (3) `function approve(address spender, uint256 amount) external returns (bool);` <a href="#id-3-function-approve-address-spender-uint256-amount-external-returns-bool" id="id-3-function-approve-address-spender-uint256-amount-external-returns-bool"></a>

`approve` is a mandatory method of ERC-20. `approve` allows `spender` to withdraw from your account multiple times, up to the `amount`. If this function is called multiple times, it simply resets the allowance to `amount`.

`approve` just invokes internal method `_approve` which implements actual behavior of `approve`. `msg.sender` is passed as the account `owner`.

```
    function approve(address spender, uint256 value) public returns (bool) {
        _approve(msg.sender, spender, value);
        return true;
    }

    function _approve(address owner, address spender, uint256 value) internal {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = value;
        emit Approval(owner, spender, value);
    }
```

`_approve` updates `_allowances` which is a 2-dimensional dictionary maintaining allowed `value` for `spender` from specific `address`.

```
    mapping (address => mapping (address => uint256)) private _allowances;
```

### (4) `function _mint(address account, uint256 amount) internal` <a href="#id-4-function-_mint-address-account-uint256-amount-internal" id="id-4-function-_mint-address-account-uint256-amount-internal"></a>

`_mint` is not part of ERC-20. However we need a way to create new ERC-20 tokens and introduced `_mint` to create new tokens in this implementation as below.

```
    function _mint(address account, uint256 amount) internal {
        require(account != address(0), "ERC20: mint to the zero address");

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }
```

`_mint` is an internal method and can be invoked inside of this contract.

In `MyERC20.sol`, `_mint` is invoked only once from `constructor` when deploying the smart contract to mint a predefined amount of token.

If you want to issue additional tokens after deploying the smart contract, you have to introduce a new public method such as `mint`. The method should be implemented with CAUTION because only authorized users should be able to mint tokens.

Please take a look at OpenZeppelin example [ERC20Mintable.sol](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/token/ERC20/ERC20Mintable.sol) for more detail.


# 2. Deploying Smart Contract

You can use Remix Online IDE or use Truffle to deploy `MyERC20` smart contract.

## 2.1 Deploying smart contract using Remix Online IDE <a href="#id-2-1-deploying-smart-contract-using-klaytn-ide" id="id-2-1-deploying-smart-contract-using-klaytn-ide"></a>

* Please visit [Klaytn Plugin for Remix](https://ide.klaytn.foundation) and create a `MyERC20` contract. The complete source code was given at [Writing ERC-20 Smart Contract](/content/smart-contract/sample-contracts/erc-20/1-erc20).
* Prepare your account which will be used to deploy the contract.
  * If you do not have an account yet, create one at <https://baobab.wallet.klaytn.foundation/create> or <https://toolkit.klaytn.foundation/account/accountKeyLegacy>.
  * Get some test KLAY from the faucet - <https://baobab.wallet.klaytn.foundation/faucet>
* Let's deploy `MyERC20.sol` with the deploy parameters of `BAOBABTOKEN`, `BAO` and `8`.

![ERC20-1-deploy](/files/vfVwM1JGs2r8LnljyHTP)

After deploying, you can invoke `balanceOf` with your account, which was used to deploy the contract. You will find there are `10000000000000` tokens available in your account as below. Because you set `decimal` as `8` when deploying the contract above, it minted a fixed number of `100000` tokens in the constructor, with one token having a decimal value of `10^8`. `totalSupply` method will return the total supply of tokens minted which should be also `10000000000000`.

![ERC20-2-owner-token](/files/fZ19sOVFbhnPLo1LOJcD)

`MyERC20` is now live !

## 2.2 Deploying smart contract using truffle <a href="#id-2-2-deploying-smart-contract-using-truffle" id="id-2-2-deploying-smart-contract-using-truffle"></a>

You should have installed [node.js](https://nodejs.org/) in your environment. Please take a look at [Installing Node.js via package manager](https://nodejs.org/en/download/package-manager/) to install node.js using package manager in various environment.

```
$ mkdir klaytn
$ cd klaytn
$ npm init # initialize npm at the erc20token directory
$ npm install truffle@4.1.15
$ npm install caver-js@latest # installing caver-js
$ ln -s node_modules/truffle/build/cli.bundled.js truffle
$ export PATH=`pwd`:$PATH
```

Now you have installed truffle and caver-js which are required to deploy smart contract.

Let's prepare `truffle` and a smart contract `MyERC20.sol`.

```
$ mkdir myerc20
$ cd myerc20
$ truffle init
```

Now you will have following directory structures.

```
.
├── contracts
│   ├── Migrations.sol
├── migrations
│   └── 1_initial_migration.js
└── truffle-config.js
```

Now write `MyERC20.sol` and locate it to `contracts` directory.

Also edit `1_initial_migration.js` as below to deploys `MyERC20` contract with initial parameters of `BAOBABTOKEN`, `BAO` and `8`. The token name is set to `BAOBABTOKEN` and the token symbol to `BAO`. Token has decimal value `10^8`. Note that when you query the `totalSupply` of `BAOBABTOKEN` for example, it returns `10^13`, not `10^5`, because solidity does not support floating point, the number of tokens always represented as a natural number in the smallest denomination.

```javascript
const Migrations = artifacts.require("./Migrations.sol");
const MyERC20 = artifacts.require("./MyERC20.sol");
module.exports = function(deployer) {
  deployer.deploy(Migrations);
  deployer.deploy(MyERC20, 'BAOBABTOKEN', 'BAO', 8);
};
```

You also have to edit `truffle-config.js` as shown below to deploy a smart contract to Klaytn network. This is the same step described in [Deploying a Smart Contract using Truffle](/content/getting-started/quick-start/deploy-a-smart-contract#deploying-a-smart-contract-using-truffle).

```
// truffle-config.js
module.exports = {
    networks: {
        baobab: {
            host: '127.0.0.1',
            port: 8551,
            from: '0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd', // enter your account address
            network_id: '1001', // Baobab network id
            gas: 20000000, // transaction gas limit
            gasPrice: 250000000000, // gasPrice of Baobab is 250 ston
        },
    },
    compilers: {
      solc: {
        version: "0.5.12"    // Specify compiler's version to 0.5.12
      }
  }
};
```

Now you are all ready and can deploy `MyERC20.sol` as below.

```
$ truffle deploy --network baobab --reset
Compiling ./contracts/MyERC20.sol...
Writing artifacts to ./build/contracts

Using network 'baobab'.

Running migration: 1_initial_migration.js
  Replacing Migrations...
  ... 0x5a947f076f4570dff8ff18b1ae3557e27dd69c92ce38a3c97fad8f5355914066
  Migrations: 0x0d737e9865e5fc4c1ff53744fd2c13c52a44b9bc
  Deploying MyERC20...
  ... 0x1571e80552dab1d67260e8914e06d9b16ccae16fb698c750f6a09aab12517bc1
  MyERC20: 0xc4c8257ED9B4eB6422fDe29B1eCe5Ce301e637e1
Saving successful migration to network...
  ... 0x5b984b3f79c425d80470a96d5badb857fc05e7f31d94423044ae3119c639aa77
Saving artifacts...
```

It shows that the transaction hash for deploying `MyERC20` is `0x1571e80552dab1d67260e8914e06d9b16ccae16fb698c750f6a09aab12517bc1` and the address of `MyERC20` is `0xc4c8257ED9B4eB6422fDe29B1eCe5Ce301e637e1`.

Now `MyERC20` is live !


# 3. Interacting with ERC-20 token from Klaytn Wallet

You can use [Baobab Klaytn Wallet](https://baobab.wallet.klaytn.foundation) to query your balance and transfer the ERC-20 compatible `BAOBABTOKEN` you just deployed.

You can add ERC-20 compatible token in your wallet with the address of the deployed `MyERC20` contract as below.

![ERC20-3-Add\_token](/files/gyCEQEEtK5yVXYbrbhKp)

After adding the ERC-20 token in the wallet app, the balance of your `BAOBABTOKEN` will be shown in addition to the balance of KLAY as below. You can see there is `100000` `BAO` tokens in the account.

![ERC20-4-wallet-token](/files/qr0FYGEnvvoZgqHCIRJX)


# ERC-721

## Introduction <a href="#introduction" id="introduction"></a>

This tutorial helps you to create an example ERC-721 compatible token that conforms to [Klaytn Token Standards](/content/smart-contract/token-standard), especially [Non-fungible Token Standard (ERC-721)](/content/smart-contract/token-standard#non-fungible-token-standard-kip-17).

[ERC-721 Non-Fungible Token Standard](https://eips.ethereum.org/EIPS/eip-721) defines three events and 10 methods as below. `supportsInterface` of ERC-721 is derived from [ERC-165 Standard Interface Detection](https://eips.ethereum.org/EIPS/eip-165) and ERC-165 is a part of ERC-721. ERC-721 compatible tokens are the token contracts that implement ERC-721 and ERC-165 interfaces as below.

```solidity
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

function balanceOf(address _owner) external view returns (uint256);
function ownerOf(uint256 _tokenId) external view returns (address);
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
function approve(address _approved, uint256 _tokenId) external payable;
function setApprovalForAll(address _operator, bool _approved) external;
function getApproved(uint256 _tokenId) external view returns (address);
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
function supportsInterface(bytes4 interfaceID) external view returns (bool);
```

Based on above interface, developers may customize tokens by adding new features and logics, and deploy on Klaytn network. For more information, refer to official [ERC-721 specification](https://eips.ethereum.org/EIPS/eip-721).

In this tutorial, you are going to implement `MyERC721Card.sol` which implements a card-type non-fungible token, i.e. `MyERC721Card`, which is an ERC-721 token. Each `MyERC721Card` has name and level, e.g. "King" with level 1, "Queen" with level 1.

`MyERC721Card.sol` is based on OpenZeppelin's ERC721 implementation. A major part of the code in this tutorial is forked from [OpenZeppelin 2.3 ](https://github.com/OpenZeppelin/openzeppelin-solidity/releases/tag/v2.3.0).

The rest of this tutorial is organized as follows.

* [1. Writing ERC-721 smart contract](/content/smart-contract/sample-contracts/erc-721/1-erc721)
  * 1.1 Overall structure of `MyERC721Card` code with whole `MyERC721Card` code
  * 1.2 Take a look at important functions
* [2. Deploying smart contract](/content/smart-contract/sample-contracts/erc-721/2-erc721)
  * 2.1 Deploying smart contract using Remix Online IDE
  * 2.2 Deploying smart contract using truffle


# 1. Writing ERC-721 Smart Contract

## 1.1 Overall structure of MyERC721Card <a href="#id-1-1-overall-structure-of-myerc721card" id="id-1-1-overall-structure-of-myerc721card"></a>

The complete source code of `MyERC721Card.sol` is given below.

```
pragma solidity ^0.5.0;

// https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/utils/Address.sol
/**
 * @dev Collection of functions related to the address type,
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * This test is non-exhaustive, and there may be false-negatives: during the
     * execution of a contract's constructor, its address will be reported as
     * not containing a contract.
     *
     * > It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }
}

// https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/math/SafeMath.sol
/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

// https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/drafts/Counters.sol
/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the SafeMath
 * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
 * directly accessed.
 */
library Counters {
    using SafeMath for uint256;

    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        counter._value += 1;
    }

    function decrement(Counter storage counter) internal {
        counter._value = counter._value.sub(1);
    }
}

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * [EIP](https://eips.ethereum.org/EIPS/eip-165).
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others (`ERC165Checker`).
 *
 * For an implementation, see `ERC165`.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

/**
 * @dev Implementation of the `IERC165` interface.
 *
 * Contracts may inherit from this and call `_registerInterface` to declare
 * their support of an interface.
 */
contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () internal {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See `IERC165.supportsInterface`.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See `IERC165.supportsInterface`.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
contract IERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of NFTs in `owner`'s account.
     */
    function balanceOf(address owner) public view returns (uint256 balance);

    /**
     * @dev Returns the owner of the NFT specified by `tokenId`.
     */
    function ownerOf(uint256 tokenId) public view returns (address owner);

    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     * 
     *
     * Requirements:
     * - `from`, `to` cannot be zero.
     * - `tokenId` must be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this
     * NFT by either `approve` or `setApproveForAll`.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public;
    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     * Requirements:
     * - If the caller is not `from`, it must be approved to move this NFT by
     * either `approve` or `setApproveForAll`.
     */
    function transferFrom(address from, address to, uint256 tokenId) public;
    function approve(address to, uint256 tokenId) public;
    function getApproved(uint256 tokenId) public view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) public;
    function isApprovedForAll(address owner, address operator) public view returns (bool);


    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
} 

// https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/token/ERC721/IERC721Receiver.sol
/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract IERC721Receiver {
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     * after a `safeTransfer`. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onERC721Received.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the ERC721 contract address is always the message sender.
     * @param operator The address which called `safeTransferFrom` function
     * @param from The address which previously owned the token
     * @param tokenId The NFT identifier which is being transferred
     * @param data Additional data with no specified format
     * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
    public returns (bytes4);
}

// https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.3.0/contracts/token/ERC721/ERC721.sol
contract ERC721 is ERC165, IERC721 {
    using SafeMath for uint256;
    using Address for address;
    using Counters for Counters.Counter;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from token ID to owner
    mapping (uint256 => address) private _tokenOwner;

    // Mapping from token ID to approved address
    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from owner to number of owned token
    mapping (address => Counters.Counter) private _ownedTokensCount;

    // Mapping from owner to operator approvals
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    constructor () public {
        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
    }

    /**
     * @dev Gets the balance of the specified address.
     * @param owner address to query the balance of
     * @return uint256 representing the amount owned by the passed address
     */
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");

        return _ownedTokensCount[owner].current();
    }

    /**
     * @dev Gets the owner of the specified token ID.
     * @param tokenId uint256 ID of the token to query the owner of
     * @return address currently marked as the owner of the given token ID
     */
    function ownerOf(uint256 tokenId) public view returns (address) {
        address owner = _tokenOwner[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");

        return owner;
    }

    /**
     * @dev Approves another address to transfer the given token ID
     * The zero address indicates there is no approved address.
     * There can only be one approved address per token at a given time.
     * Can only be called by the token owner or an approved operator.
     * @param to address to be approved for the given token ID
     * @param tokenId uint256 ID of the token to be approved
     */
    function approve(address to, uint256 tokenId) public {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(msg.sender == owner || isApprovedForAll(owner, msg.sender),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Gets the approved address for a token ID, or zero if no address set
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to query the approval of
     * @return address currently approved for the given token ID
     */
    function getApproved(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev Sets or unsets the approval of a given operator
     * An operator is allowed to transfer all tokens of the sender on their behalf.
     * @param to operator address to set the approval
     * @param approved representing the status of the approval to be set
     */
    function setApprovalForAll(address to, bool approved) public {
        require(to != msg.sender, "ERC721: approve to caller");

        _operatorApprovals[msg.sender][to] = approved;
        emit ApprovalForAll(msg.sender, to, approved);
    }

    /**
     * @dev Tells whether an operator is approved by a given owner.
     * @param owner owner address which you want to query the approval of
     * @param operator operator address which you want to query the approval of
     * @return bool whether the given operator is approved by the given owner
     */
    function isApprovedForAll(address owner, address operator) public view returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev Transfers the ownership of a given token ID to another address.
     * Usage of this method is discouraged, use `safeTransferFrom` whenever possible.
     * Requires the msg.sender to be the owner, approved, or operator.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function transferFrom(address from, address to, uint256 tokenId) public {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");

        _transferFrom(from, to, tokenId);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
        transferFrom(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether the specified token exists.
     * @param tokenId uint256 ID of the token to query the existence of
     * @return bool whether the token exists
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        address owner = _tokenOwner[tokenId];
        return owner != address(0);
    }

    /**
     * @dev Returns whether the given spender can transfer a given token ID.
     * @param spender address of the spender to query
     * @param tokenId uint256 ID of the token to be transferred
     * @return bool whether the msg.sender is approved for the given token ID,
     * is an operator of the owner, or is the owner of the token
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _tokenOwner[tokenId] = to;
        _ownedTokensCount[to].increment();

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use _burn(uint256) instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(address owner, uint256 tokenId) internal {
        require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own");

        _clearApproval(tokenId);

        _ownedTokensCount[owner].decrement();
        _tokenOwner[tokenId] = address(0);

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(uint256 tokenId) internal {
        _burn(ownerOf(tokenId), tokenId);
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to transferFrom, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _clearApproval(tokenId);

        _ownedTokensCount[from].decrement();
        _ownedTokensCount[to].increment();

        _tokenOwner[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Internal function to invoke `onERC721Received` on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * This function is deprecated.
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        internal returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }

        bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data);
        return (retval == _ERC721_RECEIVED);
    }

    /**
     * @dev Private function to clear current approval of a given token ID.
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _clearApproval(uint256 tokenId) private {
        if (_tokenApprovals[tokenId] != address(0)) {
            _tokenApprovals[tokenId] = address(0);
        }
    }
}

contract MyERC721Card is ERC721{

    struct Card {
        string  name;  // Name of the Card
        uint256 level; // Level of the Card
    }

    Card[] public cards; // First Item has Index 0
    address public owner;

    constructor () public {
        owner = msg.sender; // owner of MyERC721Card contract who can create a new card
    }

    function mintCard(string memory name, address account) public {
        require(owner == msg.sender); // Only the Owner can create Items
        uint256 cardId = cards.length; // Unique card ID
        cards.push(Card(name, 1));
        _mint(account, cardId); // Mint a new card
    }

}
```

`MyERC721Card.sol` consists of one interface(`IERC165`), three libraries(`Address`, `SafeMath` and `Counters`) and four contracts(`ERC165`, `IERC721`, `IERC721Receiver` and `MyERC721Card`).

* `IERC165` interface defines interface described at [ERC-165 specification](https://eips.ethereum.org/EIPS/eip-165).
* `Address` library defines `isContract` method to test whether an `account` is a contract or not.
* `SafeMath` library defines wrappers over Solidity's arithmetic operations with added overflow checks for safe calculation of `uint256` type of Solidity.
* `Counters` library defines counters that can only be incremented or decremented by one. This is used to track the number of elements in issuing ERC721 ids.
* `ERC165` implements `IERC165` interface.
* `IERC721` defines interface described at [ERC-721 specification](https://eips.ethereum.org/EIPS/eip-721) which also includes ERC-165.
* `IERC721Receiver` defines `onERC721Received` used from `MyERC721Card` contract.
* `ERC721` implements `IERC721` and `ERC165`.
* `MyERC721Card` implements a card type non-fungible token with name and level using `ERC721` and only the owner of `MyERC721Card` contract can mint new cards.

## 1.2 Take a look at important methods <a href="#id-1-2-take-a-look-at-important-methods" id="id-1-2-take-a-look-at-important-methods"></a>

Let's take a look at some important methods in detail.

### (1) `constructor` of ERC721 and `_INTERFACE_ID_ERC721` <a href="#id-1-constructor-of-erc721-and-_interface_id_erc721" id="id-1-constructor-of-erc721-and-_interface_id_erc721"></a>

`constructor` registers `_INTERFACE_ID_ERC721` which is a 4 bytes hash derived from ERC-721 interfaces as below.

```
    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    constructor () public {
        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
    }
```

After registering, `supportsInterface` interface of ERC-721 and ERC-165 returns `true` when invoked for `_INTERFACE_ID_ERC721` and tells this contract is implementing ERC-721 interfaces.

### (2) `function balanceOf(address owner) public view returns (uint256 balance);` <a href="#id-2-function-balanceof-address-owner-public-view-returns-uint256-balance" id="id-2-function-balanceof-address-owner-public-view-returns-uint256-balance"></a>

`balanceOf` is a mandatory method of ERC-721. `balanceOf` returns the number of NFTs in `owner`'s account.

```
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");

        return _ownedTokensCount[owner].current();
    }
```

`balanceOf` just returns a current count from the `Counter` object that the `owner` maintains in `_ownedTokensCount`.

```
    // Mapping from owner to number of owned token
    mapping (address => Counters.Counter) private _ownedTokensCount;
```

### (3) `safeTransferFrom` and `transferFrom` <a href="#id-3-safetransferfrom-and-transferfrom" id="id-3-safetransferfrom-and-transferfrom"></a>

These functions transfer the ownership of a given token ID to another address. There are two `safeTransferFrom` methods required by ERC-721, one with `data` and one without `data`. Both methods work identically to each other except that the one without `data` just set `data` to `""`. `safeTransferFrom` invokes `transferFrom` with more checks as below and `safeTransferFrom` is preferred over `transferFrom` which is also a mandatory method of ERC-721.

```
    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
        transferFrom(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    function transferFrom(address from, address to, uint256 tokenId) public {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");

        _transferFrom(from, to, tokenId);
    }
```

`safeTransferFrom` checks whether the `to` address is able to receive the token. `_checkOnERC721Received` has the verification logic. If `to` address is a contract, then the contract should implement `onERC721Received` interface of ERC-721 and return correct 4 bytes hash to receive ERC-721 token as below.

```
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        internal returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }

        bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data);
        return (retval == _ERC721_RECEIVED);
    }
```

`_transferFrom` actually transfers ownership of a given `tokenId` as below.

```
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _clearApproval(tokenId);

        _ownedTokensCount[from].decrement();
        _ownedTokensCount[to].increment();

        _tokenOwner[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }
```

### (4) `function _mint(address to, uint256 tokenId) internal` <a href="#id-4-function-_mint-address-to-uint256-tokenid-internal" id="id-4-function-_mint-address-to-uint256-tokenid-internal"></a>

`_mint` is not part of ERC-721. However we need a way to create new ERC-721 tokens and introduced `_mint` to create new tokens in this implementation as below.

```
    function _mint(address to, uint256 tokenId) internal {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _tokenOwner[tokenId] = to;
        _ownedTokensCount[to].increment();

        emit Transfer(address(0), to, tokenId);
    }
```

`_mint` is an internal method and can be invoked inside of this contract. In `MyERC721Card.sol`, `_mint` is invoked only from the `mintCard` method in the `MyERC721Card` contract. Only the owner of the smart contract can invoke `mintCard`.

```
    function mintCard(string name, address account) public {
        require(owner == msg.sender); // Only the Owner can create Items
        uint256 cardId = cards.length; // Unique card ID
        cards.push(Card(name, 1));
        _mint(account, cardId); // Mint a new card
    }
```


# 2. Deploying Smart Contract

You can use Remix Online IDE or use truffle to deploy above `MyERC721Card` smart contract.

## 2.1 Deploying smart contract using Remix Online IDE <a href="#id-2-1-deploying-smart-contract-using-klaytn-ide" id="id-2-1-deploying-smart-contract-using-klaytn-ide"></a>

* Please visit [Klaytn Plugin for Remix](https://ide.klaytn.foundation) and create a `MyERC721Card` contract. The complete source code is given at [Writing ERC-721 Smart Contract](/content/smart-contract/sample-contracts/erc-721/1-erc721).
* Create an account to deploy the contract with.
  * If you do not have an account yet, create one at <https://baobab.wallet.klaytn.foundation/create> or <https://toolkit.klaytn.foundation/account/accountKeyLegacy>.
  * Get some test KLAY from the faucet - <https://baobab.wallet.klaytn.foundation/faucet>
* Let's deploy `MyERC721Card.sol` as below.

![ERC721-1-deploy](/files/dk4uzH85uSP9rwGu0Geh)

Now `MyERC721Card` is live! You can mint and transfer cards which are ERC-721 compatible non-fungible tokens.

Let's mint two cards, i.e. `King` and `Queen` cards, for account `0x2645BA5Be42FfEe907ca8e9d88f6Ee6dAd8c1410` as below.

![ERC721-2-mint-king](/files/psDXKLj0YjpDvx3dW3uE) ![ERC721-3-mint-queen](/files/C76AcqbKdqVjZILV3ed9)

Now we have minted two cards and let's check the status of these `MyERC721Card` non-fungible token.

![ERC721-4-cards-status](/files/MRIFlNK8T0ESOfJiCEMd)

* `balanceOf` shows that account `0x2645BA5Be42FfEe907ca8e9d88f6Ee6dAd8c1410` has two cards.
* `cards` with parameter `1` shows that `MyERC721Card` with token ID `1` is a `Queen` of level 1.
* `ownerOf` with parameter `0` shows that owner of `MyERC721Card` with token ID `0` is `0x2645BA5Be42FfEe907ca8e9d88f6Ee6dAd8c1410`.

## 2.2 Deploying smart contract using truffle <a href="#id-2-2-deploying-smart-contract-using-truffle" id="id-2-2-deploying-smart-contract-using-truffle"></a>

You should have installed [node.js](https://nodejs.org/) in your environment. Please take a look at [Installing Node.js via package manager](https://nodejs.org/en/download/package-manager/) to install node.js using package manager in various environment.

```
$ mkdir klaytn
$ cd klaytn
$ npm init # initialize npm at the erc20token directory
$ npm install truffle@4.1.15
$ npm install caver-js@latest # installing caver-js
$ ln -s node_modules/truffle/build/cli.bundled.js truffle
$ export PATH=`pwd`:$PATH
```

Now you have installed truffle and caver-js which are required to deploy smart contracts.

Let's prepare `truffle` and a smart contract `MyERC721Card.sol`.

```
$ mkdir myerc721
$ cd myerc721
$ truffle init
```

Now you will have following directory structures.

```
.
├── contracts
│   ├── Migrations.sol
├── migrations
│   └── 1_initial_migration.js
└── truffle-config.js
```

After write `MyERC721Card.sol` and locate it to `contracts` directory, directory structure will be as follows.

Now you will have following directory structures.

```
.
├── contracts
│   ├── Migrations.sol
│   └── MyERC721Card.sol
├── migrations
│   └── 1_initial_migration.js
└── truffle-config.js
```

Also, edit `1_initial_migration.js` as shown below to deploy the `MyERC721Card` contract.

```javascript
const Migrations = artifacts.require("./Migrations.sol");
const MyERC721Card = artifacts.require("./MyERC721Card.sol");
module.exports = function(deployer) {
  deployer.deploy(Migrations);
  deployer.deploy(MyERC721Card)
};
```

You also have to configure `truffle-config.js` to deploy the smart contract to Klaytn network. This is the same step described at [Deploying a Smart Contract using Truffle](/content/getting-started/quick-start/deploy-a-smart-contract#deploying-a-smart-contract-using-truffle)

```
// truffle-config.js
module.exports = {
    networks: {
        baobab: {
            host: '127.0.0.1',
            port: 8551,
            from: '0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd', // enter your account address
            network_id: '1001', // Baobab network id
            gas: 20000000, // transaction gas limit
            gasPrice: 250000000000, // gasPrice of Baobab is 250 ston
        },
    },
    compilers: {
      solc: {
        version: "0.5.12"    // Specify compiler's version to 0.5.12
      }
  }
};
```

Now you are all ready, let's deploy `MyERC721Card.sol` using the following command.

```
$ truffle deploy --network baobab --reset
Compiling ./contracts/MyERC721Card.sol...
Writing artifacts to ./build/contracts

Using network 'baobab'.

Running migration: 1_initial_migration.js
  Replacing Migrations...
  ... 0x5a947f076f4570dff8ff18b1ae3557e27dd69c92ce38a3c97fad8f5355914066
  Migrations: 0x0d737e9865e5fc4c1ff53744fd2c13c52a44b9bc
  Deploying MyERC721Card...
  ... 0x1571e80552dab1d67260e8914e06d9b16ccae16fb698c750f6a09aab12517bc1
  MyERC721Card: 0xc3d282926871c505f334d0f2c85ad52758347831
Saving successful migration to network...
  ... 0x5b984b3f79c425d80470a96d5badb857fc05e7f31d94423044ae3119c639aa77
Saving artifacts...
```

The console output shows that the transaction hash for deploying `MyERC721Card` is `0x1571e80552dab1d67260e8914e06d9b16ccae16fb698c750f6a09aab12517bc1` and the address of `MyERC721Card` is `0xc3d282926871c505f334d0f2c85ad52758347831`.


# Testing Guide

In this section, we'll introduce how to test smart contracts. Because any transaction on the blockchain is not reversible, testing your smart contract is crucial before you deploy the contract.

## Testing with Truffle <a href="#testing-with-truffle" id="testing-with-truffle"></a>

Truffle provides an automated testing framework. This framework lets you write simple and manageable tests in two different ways:

* In `Javascript` and `TypeScript`, for exercising your contracts from the outside world, just like application.
* In `Solidity`, for exercising your contracts in advanced, bare-to-the-metal scenarios.

### 1) Getting started <a href="#id-1-getting-started" id="id-1-getting-started"></a>

We will follow the [Deployment Guide using Truffle](/content/smart-contract/deploy-guide#truffle) to create a contract and deploy it. But, before we deploy it, we will add a setter function `setGreet` to the contract for testing purposes. The source code is given below.

**NOTE:** We have made some modifications to the contract for testing.

Below is KlaytnGreeting contract source code.

```
pragma solidity 0.5.6;

contract Mortal {
    /* Define variable owner of the type address */
    address payable owner;
    /* This function is executed at initialization and sets the owner of the contract */
    constructor () public { owner = msg.sender; }
    /* Function to recover the funds on the contract */
    function kill() public payable { if (msg.sender == owner) selfdestruct(owner); }
}

contract KlaytnGreeter is Mortal {
    /* Define variable greeting of the type string */
    string greeting;

    /* This runs when the contract is executed */
    constructor (string memory _greeting) public {
        greeting = _greeting;
    }

    /* Main function */
    function greet() public view returns (string memory) {
        return greeting;
    }

    /* Newly added function for testing. */
    function setGreet(string memory _greeting) public {
        // only owner can change greeting message
        require(msg.sender == owner, "Only owner is allowed.");
        greeting = _greeting;
    }
}
```

We will test 1) `greet()` function whether it returns "Hello, Klaytn" message properly, 2) `setGreet()` function whether it sets new greeting message properly and reverts when non-owner account attempts to update the greeting.

First, we will install the Chai assertions library (or any different assertions library you use) for generic assertions, and the truffle-assertions library for the smart contract assertions.

```
npm install --save-dev chai truffle-assertions
```

### 2) Writing test in Solidity <a href="#id-2-writing-test-in-solidity" id="id-2-writing-test-in-solidity"></a>

Testing with Solidity can be a little bit more intuitive than JavaScript tests. Solidity test contracts live alongside JavaScript tests as .sol files.

Create a file called `TestKlaytnGreeting.sol` in the `test` folder. The Truffle suite provides us with helper libraries for testing, so we need to import those. Let's take a look at the example Solidity test:

```
pragma solidity ^0.5.6;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/HashMarket.sol";
```

* Assert : It gives us access to various testing functions, like `Assert.equals()`, `Assert.greaterThan()`, etc.
* DeployedAddresses : Every time you change your contract, you must redeploy it to a new address. You can get the deployed contract addresses through this library.

Now, Let's write a test code.

```
pragma solidity ^0.5.6;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/KlaytnGreeter.sol";

contract TestKlaytnGreeter {

    function testGreetingMessage() public {
        // DeployedAddresses.KlaytnGreeter() handles contract address.
        KlaytnGreeter greeter = KlaytnGreeter(DeployedAddresses.KlaytnGreeter());

        string memory expectedGreet = "Hello Klaytn";

        string memory greet = greeter.greet();

        Assert.equal(greet, expectedGreet, "greeting message should match");
    }
}
```

Run your Solidity test code.

```
$ truffle test
# Output
Using network 'development'.


Compiling your contracts...
===========================
> Compiling ./test/TestKlaytnGreeter.sol



  TestKlaytnGreeter
    1) testGreetingMessage

    Events emitted during test:
    ---------------------------


    ---------------------------


  0 passing (5s)
  1 failing

  1) TestKlaytnGreeter
       testGreetingMessage:
     Error: greeting message should match (Tested: Hello, Klaytn, Against: Hello Klaytn)
      at result.logs.forEach.log (/Users/jieunkim/.nvm/versions/node/v10.16.0/lib/node_modules/truffle/build/webpack:/packages/core/lib/testing/soliditytest.js:71:1)
      at Array.forEach (<anonymous>)
      at processResult (/Users/jieunkim/.nvm/versions/node/v10.16.0/lib/node_modules/truffle/build/webpack:/packages/core/lib/testing/soliditytest.js:69:1)
      at process._tickCallback (internal/process/next_tick.js:68:7)
```

Oops, we failed. Let's check the error message,`Error: greeting message should match (Tested: Hello, Klaytn, Against: Hello Klaytn)`. I can notice the missed `',(comma)'` at *string memory expectedGreet = "Hello Klaytn"*.\
Fix the code and run the test again.

```
$ truffle test
# Output
Using network 'development'.


Compiling your contracts...
===========================
> Compiling ./test/TestKlaytnGreeter.sol



  TestKlaytnGreeter
    ✓ testGreetingMessage (58ms)


  1 passing (5s)
```

Congratulations! Your test has passed.

### 3) Writing test in JavaScript <a href="#id-3-writing-test-in-javascript" id="id-3-writing-test-in-javascript"></a>

Truffle uses the [Mocha](https://mochajs.org/) testing framework and [Chai](https://www.chaijs.com/) assertion library to provide a solid framework for JavaScript test. JavaScript test gives you more flexibility and enables you to write more complex tests.

Let's create a file and name it `0_KlaytnGreeting.js` under `test` directory.\
The test code is:

```javascript
// Interacting directly with KlaytnGreeter contract
const KlaytnGreeter = artifacts.require("./KlaytnGreeter.sol");
const truffleAssert = require('truffle-assertions');

contract("KlaytnGreeter", async(accounts) => {
    // store the contract instance at a higher level 
    // to enable access from all functions.
    var klaytnGreeterInstance;
    var owner = accounts[0];
    var greetMsg = "Hello, Klaytn";

    // This will run before each test proceed.
    before(async function() {
        // set contract instance into a variable
        klaytnGreeterInstance = await KlaytnGreeter.new(greetMsg, {from:owner});
    })

    it("#1 check Greeting message", async function() {
        // set the expected greeting message
        var expectedGreeting = greetMsg;
        var greet= await klaytnGreeterInstance.greet();
        assert.equal(expectedGreeting, greet, "greeting message should match");
        
    })

    it("#2 update greeting message.", async function() {
        var newGreeting = "Hi, Klaytn";
        
        await klaytnGreeterInstance.setGreet(newGreeting, { from:owner });
        var greet = await klaytnGreeterInstance.greet();
        assert.equal(newGreeting, greet, "greeting message should match");
    });

    it("#3 [Failure test] Only owner can change greeting.", async function() {
        var fakeOwner = accounts[1];        
        await truffleAssert.fails(klaytnGreeterInstance.setGreet(greetMsg, { from:fakeOwner }));
    });
});
```

If you are unfamiliar with `Mocha` unit test, please check the [Mocha document](https://mochajs.org/#getting-started).

* Use `contract()` instead of `describe()`\
  Structurally, the Truffle test code shouldn't be much different from the usual test code of Mocha. Your test should contain the code that Mocha will recognize it as an automated test. The difference between Mocha and Truffle test is the contract() function.\
  **NOTE** the use of the `contract()` function, and the `accounts` array for specifying available Klaytn accounts.
* Contract abstractions within your tests\
  Since Truffle has no way of detecting which contract you'll need to interact with during test, you should specify the contract explicitly. One way to do this is by using the `artifacts.require()` method.
* `it` syntax\
  This represents each test case with description. The description will print on the console on test-run.
* `truffle-assertion` library\
  This library allows you to easily test reverts or other failures by offering the `truffleAssert.reverts()` and `truffleAssert.fails()` functions.

The output should like the following:

```
Using network 'development'.


Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.



  Contract: KlaytnGreeter
    ✓ #1 check Greeting message
    ✓ #2 update greeting message. (46ms)
    ✓ #3 [Failure test] Only owner can change greeting.


  3 passing (158ms)
```

Congratulations! Your test has passed.

### 4) Specifying test <a href="#id-4-specifying-test" id="id-4-specifying-test"></a>

You can choose the test file to be executed.

```
truffle test ./test/0_KlaytnGreeting.js
```

For more details, please check [Truffle testing](https://www.trufflesuite.com/docs/truffle/testing/testing-your-contracts) and [Truffle commands](https://www.trufflesuite.com/docs/truffle/reference/truffle-commands#test) for details.


# Deployment Guide

There are various ways of deploying a smart contract on Klaytn. This document provides a step-by-step guide to deploy a sample contract using various tools. We assume that you have a Klaytn account with enough KLAY to pay the transaction fee. To create an account, please visit [Klaytn Wallet](/content/dapp/developer-tools/getting-started/klaytn-wallet).

## Remix Online IDE <a href="#remix-ide" id="remix-ide"></a>

Open your internet browser and go to [Klaytn Plugin for Remix](https://ide.klaytn.foundation).

* Add a new file.

![](/files/QijRekap6G1Z4LQnt46h)

* Copy and paste the following sample code (or any code you want to deploy) in the new file. The code consists of two contracts called Mortal and KlaytnGreeter, and it allows you to run a simple "Hello World!".

```
pragma solidity 0.5.12;

contract Mortal {
    /* Define variable owner of the type address */
    address payable owner;
    /* This function is executed at initialization and sets the owner of the contract */
    constructor () public { owner = msg.sender; }
    /* Function to recover the funds on the contract */
    function kill() public payable { if (msg.sender == owner) selfdestruct(owner); }
}

contract KlaytnGreeter is Mortal {
    /* Define variable greeting of the type string */
    string greeting;
    /* This runs when the contract is executed */
    constructor (string memory _greeting) public {
        greeting = _greeting;
    }
    /* Main function */
    function greet() public view returns (string memory) {
        return greeting;
    }
}
```

* Select Compiler in the icon panel. Choose the desired EVM environment. For the Klaytn networks, you can choose between Baobab (testnet) and Cypress (mainnet). Click `Compile` when the sample code is ready to be complied before actual deployment.

![](/files/UFFw08P8FZjxEY4V5Tyh)

* Now we can deploy the contract. Click on the Klaytn logo in the icon panel. Import an account by clicking the plus button next to `Account`. Make sure that the account has sufficient KLAY to pay for the transaction of deploying the smart contracts required.

![](/files/1UgZ42EXIwNJ7DwouKLM)

* Set Gas limit and Value to send.
  * You may need to set higher Gas limit if you are deploying a more complicated contract. In this example, you can leave it as it is.
  * Set `Value` to 0 unless you want to send `KLAY` to the contract at the time of deployment.
* Enter "Hello World!" as an argument for constructor function and click on `Deploy` button.

![](/files/UfrqexgIWdOkQ76mfHcd)

* If the contract is successfully deployed, you will see the corresponding transaction receipt and detailed result in the terminal.
* You can interact with the contract by clicking on the function buttons. The functions are represented in different colors. `constant` or `pure` functions in Solidity have blue buttons (`greet` in the example) and do not create a new transaction, so they don't cost any gas. Red buttons (`kill` in the example) represent `payable` functions that change the state on the blockchain, consume gas and can accept value. Orange buttons are for `non-payable` functions that change the contract state but do NOT accept a value.

![](/files/atYb1QXNiopHOtk04pxx)

For more details, please refer to this [link](https://github.com/klaytn/klaytn-docs/blob/main/docs/toolkit/klaytn-ide.md).

## Truffle <a href="#truffle" id="truffle"></a>

Truffle is the most popular framework for smart contract deployment and execution.

* Install via the following command.

```
$ sudo npm install -g truffle
```

* Set up a project directory, and install .`truffle-hdwallet-provider-klaytn`

```
$ mkdir hello-klaytn
$ cd hello-klaytn
$ truffle init
$ npm install truffle-hdwallet-provider-klaytn
```

* Create `KlaytnGreeter.sol` under `/contracts` directory and copy the following code.

```
pragma solidity 0.5.6;

contract Mortal {
    /* Define variable owner of the type address */
    address payable owner;
    /* This function is executed at initialization and sets the owner of the contract */
    constructor () public { owner = msg.sender; }
    /* Function to recover the funds on the contract */
    function kill() public payable { if (msg.sender == owner) selfdestruct(owner); }
}

contract KlaytnGreeter is Mortal {
    /* Define variable greeting of the type string */
    string greeting;
    /* This runs when the contract is executed */
    constructor (string memory _greeting) public {
        greeting = _greeting;
    }
    /* Main function */
    function greet() public view returns (string memory) {
        return greeting;
    }
}
```

* Modify `/migrations/1_initial_migration.js` as in the following.

```
const Migrations = artifacts.require("./Migrations.sol");
const KlaytnGreeter = artifacts.require("./KlaytnGreeter.sol");
module.exports = function(deployer) {
  deployer.deploy(Migrations);
  deployer.deploy(KlaytnGreeter, 'Hello, Klaytn');
};
```

* Set `truffle-config.js` as below. Make sure you enter the private key of an account that has enough `KLAY` to deploy the contract.

```
const HDWalletProvider = require("truffle-hdwallet-provider-klaytn");

const privateKey = "0x3de..." // Enter your private key;

module.exports = {
  networks: {
    development: {
      host: "localhost",
      port: 8545,
      network_id: "*" // Match any network id
    },
    testnet: {
      provider: () => new HDWalletProvider(privateKey, "https://your.baobab.en.url:8651"),
      network_id: '1001', //Klaytn baobab testnet's network id
      gas: '8500000',
      gasPrice: null
    },
    mainnet: {
      provider: () => new HDWalletProvider(privateKey, "https://your.cypress.en.url:8651"),
      network_id: '8217', //Klaytn mainnet's network id
      gas: '8500000',
      gasPrice: null
    }
  },
  compilers: {
    solc: {
      version: "0.5.6"
    }
  }
};
```

*NOTE*: This example is not recommended for production use. Be very careful when dealing with private keys.

* Deploying on Klaytn testnet.

```
$ truffle deploy --network testnet
```

* Deploying on Klaytn mainnet.

```
$ truffle deploy --network mainnet
```

For more details refer to this [link](/content/smart-contract/ide-and-tools/truffle).

## VVISP <a href="#vvisp" id="vvisp"></a>

vvisp is an easy-to-use CLI tool/framework for developing smart contracts, provided by HEACHI LABS. You can easily set environment, deploy and execute Klaytn smart contracts with a single command. Refer to the following link for more details.

* <https://henesis.gitbook.io/vvisp/deploying-smart-contracts>

## solc & caver-js <a href="#solc-caver-js" id="solc-caver-js"></a>

Another way to deploy contracts is manually compiling contracts with solc and deploying them with caver-js.

* Create `KlaytnGreeter.sol` and write the following code.

```
pragma solidity 0.5.6;

contract Mortal {
    /* Define variable owner of the type address */
    address payable owner;
    /* This function is executed at initialization and sets the owner of the contract */
    constructor () public { owner = msg.sender; }
    /* Function to recover the funds on the contract */
    function kill() public payable { if (msg.sender == owner) selfdestruct(owner); }
}

contract KlaytnGreeter is Mortal {
    /* Define variable greeting of the type string */
    string greeting;
    /* This runs when the contract is executed */
    constructor (string memory _greeting) public {
        greeting = _greeting;
    }
    /* Main function */
    function greet() public view returns (string memory) {
        return greeting;
    }
}
```

* Install solc 0.5.6.

```
$ sudo npm install -g solc@0.5.6
```

* Compile the contract.

```
$ solcjs KlaytnGreeter.sol --bin
```

* Install caver-js.

```
$ npm install caver-js.
```

* Create `deploy.js` in the same directory with the following code.

```
const Caver = require("caver-js");
const caver = new Caver("https://public-en-baobab.klaytn.net")

const walletInstance = caver.klay.accounts.privateKeyToAccount(
  '0x3de0c9...' // enter your private key to deploy contract with
);
caver.klay.accounts.wallet.add(walletInstance);

const fs = require('fs')
const bytecode = fs.readFileSync('./KlaytnGreeter_sol_KlaytnGreeter.bin') // compiled output

const constructorType = ['string']  // enter appropriate constructor type
const constructorValue = ['Hello, Klaytn!']

const params = caver.klay.abi.encodeParameters(constructorType, constructorValue);

caver.klay.sendTransaction({
  from: caver.klay.accounts.wallet[0].address,
  gas: "50000000",
  data: bytecode.toString() + params.substring(2, params.length)
})
.once("receipt", receipt => {
  console.log(receipt)
})
.once("error", error => {
  console.log(error);
})
```

*NOTE*: This example is not recommended for production use. Be very careful when dealing with private keys.

* Deploy the contract using node environment.

```
$ node deploy.js
```


# Klaytn Compatible Tokens

Klaytn Compatible Token (KCT) is a special type of smart contract that implements certain technical specifications. Everyone who wants to issue tokens on top of Klaytn must follow the specification.

Token standards are defined in Klaytn such as [KIP-7](https://kips.klaytn.foundation/KIPs/kip-7) and [KIP-17](https://kips.klaytn.foundation/KIPs/kip-17).

Other KCTs can be defined to meet certain technical specifications. If anyone needs other token standards, please visit [Klaytn Improvement Proposal](https://github.com/klaytn/KIPs) and propose a new token standard.

## Fungible Token Standard (KIP-7) <a href="#fungible-token-standard-kip-7" id="fungible-token-standard-kip-7"></a>

Fungible tokens are tokens that have properties of uniformity and divisibility. Every fungible token is interchangeable as each unit of token possesses the same value. Just like every dollar bill has the same value of one dollar. Since fungibility is essential feature to crypto currency in most cases, large proportion of blockchain tokens are fungible tokens.

To implement these properties with smart contracts, KIP-7 token standard can be used. KIP-7-compatible tokens implement the following interface. Please note that [KIP-13](https://kips.klaytn.foundation/KIPs/kip-13) must be implemented together. For wallet applications, [wallet interface](https://kips.klaytn.foundation/KIPs/kip-7#wallet-interface) can be implemented.

```solidity
// IKIP7
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);

function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function safeTransfer(address recipient, uint256 amount, bytes data) external;
function safeTransfer(address recipient, uint256 amount) external;
function safeTransferFrom(address sender, address recipient, uint256 amount, bytes data) external;
function safeTransferFrom(address sender, address recipient, uint256 amount) external;

// IKIP7Metadata (optional)
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);

// IKIP7Mintable (optional)
function mint(address _to, uint256 _amount) external returns (bool);
function isMinter(address _account) external view returns (bool);
function addMinter(address _account) external;
function renounceMinter() external;

// IKIP7Burnable (optional)
function burn(uint256 _amount) external;
function burnFrom(address _account, uint256 _amount) external;

// IKIP7Pausable (optional)
event Paused(address _account);
event Unpaused(address _account);

function paused() external view returns (bool);
function pause() external;
function unpause() external;
function isPauser(address _account) external view returns (bool);
function addPauser(address _account) external;
function renouncePauser() external;
```

Based on the interface above, developers may customize tokens by adding new features and logics, and deploy them on Klaytn network.

For more information, refer to the official [KIP-7 documentation](https://kips.klaytn.foundation/KIPs/kip-7).

* An example implementation is available at <https://github.com/klaytn/klaytn-contracts/blob/main/contracts/KIP/token/KIP7/KIP7.sol>.

## Non-fungible Token Standard (KIP-17) <a href="#non-fungible-token-standard-kip-17" id="non-fungible-token-standard-kip-17"></a>

Non-fungible token (NFT) is a special type of token that represents a unique asset. As the name non-fungible implies, every single token is unique and non-divisible. This uniqueness of non-fungible token opens up new horizons of asset digitization. For example, it can be used to represent digital art, game items, or any kind of unique assets and allow people to trade them.

For example, a blockchain collection game [Cryptokitties](https://www.cryptokitties.co/) implements non-fungible token to represent different kitties that have different genetic information. Every kitty is unique and non-interchangeable, resulting in different values for different kitty tokens.

To implement non-fungible token, [KIP-17](https://kips.klaytn.foundation/KIPs/kip-17) can be used. KIP-17 token contracts implement the following interface. Please note that [KIP-13](https://kips.klaytn.foundation/KIPs/kip-13) must be implemented together. For wallet applications, [wallet interface](https://kips.klaytn.foundation/KIPs/kip-17#wallet-interface) can be implemented.

```solidity
// IKIP17
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

function balanceOf(address _owner) external view returns (uint256);
function ownerOf(uint256 _tokenId) external view returns (address);
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) external payable;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
function approve(address _approved, uint256 _tokenId) external payable;
function setApprovalForAll(address _operator, bool _approved) external;
function getApproved(uint256 _tokenId) external view returns (address);
function isApprovedForAll(address _owner, address _operator) external view returns (bool);

// IKIP17Metadata (optional)
function name() external view returns (string _name);
function symbol() external view returns (string _symbol);
function tokenURI(uint256 _tokenId) external view returns (string);

// IKIP17Enumerable (optional)
function totalSupply() external view returns (uint256);
function tokenByIndex(uint256 _index) external view returns (uint256);
function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);

// IKIP17Mintable (optional)
function mint(address _to, uint256 _tokenId) public returns (bool);
function isMinter(address _account) public view returns (bool);
function addMinter(address _account) public;
function renounceMinter() public;

// IKIP17MetadataMintable (optional)
function mintWithTokenURI(address _to, uint256 _tokenId, string memory _tokenURI) public returns (bool);
function isMinter(address _account) public view returns (bool);
function addMinter(address _account) public;
function renounceMinter() public;

// IKIP17Burnable (optional)
function burn(uint256 _tokenId) public;

// IKIP17Pausable (optional)
event Paused(address _account);
event Unpaused(address _account);
function paused() public view returns (bool);
function pause() public;
function unpause() public;
function isPauser(address _account) public view returns (bool);
function addPauser(address _account) public;
function renouncePauser() public;
```

Based on the interface above, developers may customize tokens by adding new features and logics, and deploy them on Klaytn network.

For more information, refer to the official [KIP-17 documentation](https://kips.klaytn.foundation/KIPs/kip-17).

* An example implementation is available at <https://github.com/klaytn/klaytn-contracts/blob/main/contracts/KIP/token/KIP17/KIP17.sol>.

## Token Standards for Klaytn Service Chain <a href="#token-standards-for-klaytn-service-chain" id="token-standards-for-klaytn-service-chain"></a>

Service chain refers to Klaytn's side chain that anchors to Klaytn's main blockchain network. When implementing a service chain, special type of contracts are used to support value transfer between the main chain and the service chain. These contracts are currently under development, and when they are ready, the token specifications for Klaytn service chain will be provided on KlaytnDocs.

## Notes on ERC-20 and ERC-721 <a href="#notes-on-erc-20-and-erc-721" id="notes-on-erc-20-and-erc-721"></a>

Since Klaytn published KIP-7 and KIP-17 as its token standards, it is recommended to implement fungible and non-fungible token contracts according to KIP-7 and KIP-17, respectively, rather than following ERC-20 and ERC-721. KIP-7 and KIP-17 are based on ERC-20 and ERC-721, but they are tailored for Klaytn and thus more suitable on Klaytn ecosystem. Yet ERC-20 and ERC-721 are still supported on Klaytn network, they may not be compatible with various tools in Klaytn ecosystem. For more information about the differences on token standards, please visit [KIP-7](https://kips.klaytn.foundation/KIPs/kip-7#differences-with-erc-20) and [KIP-17](https://kips.klaytn.foundation/KIPs/kip-17#differences-from-erc-721).


# Porting Ethereum Contract

In most cases, you can use Ethereum contracts on Klaytn without any modification. However, be aware of the following two issues.

## Solidity Support <a href="#solidity-support" id="solidity-support"></a>

* Baobab network is currently compatible with **London** Ethereum Virtual Machine (EVM).
* Cypress network is currently compatible with **London** Ethereum Virtual Machine (EVM).

{% hint style="success" %}
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.
{% endhint %}

Backward compatibility is not guaranteed with other EVM versions on Klaytn. Thus, it is highly recommended compiling Solidity code with the correct target option according to the protocol upgrade status.

* Baobab: --evm-version london
* Cypress: --evm-version london
* Others(private/service chain): determined according to the protocol upgrade status

Please refer to [how to set the EVM version of solc](https://solidity.readthedocs.io/en/latest/using-the-compiler.html#setting-the-evm-version-to-target).

An example command is shown below:

```
$ solc --evm-version london contract.sol
```

## Decoupled Key Pairs <a href="#decoupled-key-pairs" id="decoupled-key-pairs"></a>

Klaytn [decouples key pairs from addresses](/content/klaytn/design/accounts#decoupling-key-pairs-from-addresses). If user [updates account](/content/klaytn/design/transactions/basic#txtypeaccountupdate), the private key for a specific account is replaced with another one. Most cases this will not affect your business logic. However if your business logic includes ecrecover, you should consider using validateSender. For more details, refer to [here](/content/smart-contract/precompiled-contracts).


# Run a Node


# Deployment

Try and get familiar with Klaytn. This chapter is the starting point of your journey to Klaytn dApps.


# Endpoint Node

## Intended Audience <a href="#intended-audience" id="intended-audience"></a>

* Anyone who wants to send transactions or query the state of Klaytn network using [Klaytn APIs](/content/dapp/json-rpc) needs to do so via an Endpoint Node.
* Endpoint Nodes are the interface to the Klaytn Network.

## Endpoint Node Overview <a href="#endpoint-node-overview" id="endpoint-node-overview"></a>

An Endpoint Node has the following roles and functions.

* Synchronize the blockchain data.
* Validate the blocks newly received.
* Handles query requests.
* Transmits transaction requests to the Proxy Nodes.

The Endpoint Node install binary comes with the following interfaces and utilities.

* JSON-RPC APIs: JSON-RPC server runs inside the node, and it exposes [APIs](/content/dapp/json-rpc) for Blockchain Application development. It has several node management APIs as well.
* Command-line Interface: Provides account management and node configuration functions. An interactive JavaScript console is also provided, that is attached to the node. JavaScript console implements most of the [caver-js APIs](/content/dapp/sdk/caver-js).


# System Requirements

Running an Endpoint Node (EN) requires relatively higher hardware specifications compared to the ones for Ethereum or other blockchains, because EN has to validate blocks generated by the full-fledged Consensus Nodes equipped with enterprise-grade hardware.

For the ENs, the following specifications are recommended.

## H/W Specification <a href="#h-w-specification" id="h-w-specification"></a>

### Cloud VM <a href="#cloud-vm" id="cloud-vm"></a>

#### Recommended Specification <a href="#recommended-specification-based-on-aws" id="recommended-specification-based-on-aws"></a>

| vCPU | Memory (GiB) | Storage (GiB) | Disk Bandwidth (Mbps) | Network Bandwidth (Gbps) |
| ---- | ------------ | ------------- | --------------------- | ------------------------ |
| 8    | 64           | > 3,000       | 3,500                 | Up to 10                 |

### Bare-metal Machine <a href="#bare-metal-machine" id="bare-metal-machine"></a>

We do not specify the exact physical machine specification for EN, but any physical machine having hardware configuration similar to the one in the Cloud VM section would be sufficient to operate an EN.

## Storage Requirements <a href="#storage-requirements" id="storage-requirements"></a>

Assuming 100 TPS in average, 300 bytes average transaction size, and 1-second block latency, the expected EN daily storage requirement is 2.5 GB/day (=300x100x86400).

## Operating System <a href="#operating-system" id="operating-system"></a>

Recommended environment is [Amazon Linux 2](https://aws.amazon.com/ko/about-aws/whats-new/2017/12/introducing-amazon-linux-2/). Klaytn binaries are fully tested on Amazon Linux 2, but they should work on other linux-based environments as well. macOS binaries are also provided for development purpose.


# Installation Guide


# Download

You can get packages for EN in the [download page](/content/installation-guide/deployment/download).


# Installation Guide

You can download the latest version of the `ken` on [Download](/content/installation-guide/deployment/endpoint-node/installation-guide/download) page.

## Linux Archive Distribution <a href="#linux-archive-distribution" id="linux-archive-distribution"></a>

The archive file consists of the executable binary and the configuration file structured as follows.

**Note**: Do NOT alter the file structure or file name. If you change it, the node may not function correctly.

```
- bin
  |- ken
  |- kend
- conf
  |- kend.conf
```

| File Name      | File Description                 |
| -------------- | -------------------------------- |
| bin/ken        | EN executable file               |
| bin/kend       | EN start/termination script file |
| conf/kend.conf | EN configuration file            |

### Installation <a href="#installation" id="installation"></a>

The installation is the uncompression of the downloaded package where you want to install the package.

```
$ tar zxf ken-vX.X.X-linux-amd64.tar.gz
```

Or,

```
$ tar zxf ken-baobab-vX.X.X-linux-amd64.tar.gz
```

**Note**: it is recommended that the uncompressed directory `ken-linux-amd64/bin` path should be added to the environment variable `$PATH` to run the `ken` and `kend` globally. As an example,

```
$ export PATH=$PATH:~/downloaded/path/ken-linux-amd64/bin
```

The other sections assume that the path is added to the variable.

## RPM Distribution (RHEL/CentOS/Fedora) <a href="#rpm-rhel-centos-fedora" id="rpm-rhel-centos-fedora"></a>

### Install downloaded RPM <a href="#install-downloaded-rpm" id="install-downloaded-rpm"></a>

You can install the downloaded RPM file with the following `yum` command.

```
$ yum install kend-vX.X.X.el7.x86_64.rpm
```

Or,

```
$ yum install kend-baobab-vX.X.X.el7.x86_64.rpm
```

### Install from Klaytn Yum Repo <a href="#install-from-klaytn-yum-repo" id="install-from-klaytn-yum-repo"></a>

Alternatively, you can install `kend` from the Klaytn Yum repo, run:

```
$ sudo curl -o /etc/yum.repos.d/klaytn.repo https://packages.klaytn.net/config/rhel/7/prod.repo && sudo yum install kend
```

### Installed Location <a href="#installed-location" id="installed-location"></a>

The installed files are located as follows.

| File Name | Location                 |
| --------- | ------------------------ |
| ken       | /usr/bin/ken             |
| kend.conf | /etc/kend/conf/kend.conf |


# Configuration

The EN configuration is to create a data directory and to set up the environment variables on the configuration file `kend.conf`.

1. Create the EN data directory.
2. Configure the EN with `kend.conf`.

## EN Data Directory Creation <a href="#en-data-directory-creation" id="en-data-directory-creation"></a>

Considering the fact that the size of Klaytn blockchain data keeps increasing, it is recommended to use a big enough storage. You need to create the directory on your desired path.

```
$ sudo mkdir -p /var/kend/data
```

## Update the Configuration File <a href="#update-the-configuration-file" id="update-the-configuration-file"></a>

Configuration File Location:

* For the archive distribution, the config directory location defaults to `$INSTALL_PATH/ken-linux-amd64/conf/`.
* For the package distribution, the config directory defaults to `/etc/kend/conf/`.

### Add Data Directory <a href="#add-data-directory" id="add-data-directory"></a>

You should update the data directory environment variable `$DATA_DIR` on the configuration file `kend.conf`.

```
DATA_DIR=/var/kend/data
```

## Fast Sync (Optional) <a href="#fast-sync-optional" id="fast-sync-optional"></a>

Each EN maintains a copy of the network's chain data. If a node is out of sync, it can obtain this data from other nodes in the network -- a process known as syncing. When a new EN is first started, it must download the entire chain data from the network.

To accelerate this process, you may perform a fast sync by downloading a snapshot of the chain data before starting the EN. This can dramatically reduce the time the EN will spend syncing on first start.

Download the latest chaindata snapshot from the [Cypress snapshot archive](http://packages.klaytn.net/cypress/chaindata/) or [Baobab snapshot archive](http://packages.klaytn.net/baobab/chaindata/). Before starting `kend`, extract the snapshot inside the DATA\_DIR you configured in `kend.conf`.

For example:

```bash
$ tar -C ~/kend_home -xvf klaytn-cypress-chaindata-latest.tar.gz
```

Or,

```bash
$ tar -C ~/kend_home -xvf klaytn-baobab-chaindata-latest.tar.gz
```

After the data is extracted, you may start the EN normally.

You can refer to detailed information in the [Chaindata change](/content/operation-guide/chaindata-change)

## &#x20;<a href="#en-start-stop-status" id="en-start-stop-status"></a>


# Startup the EN

You can start or stop the Endpoint Node using the following commands.

**start**

```bash
$ kend start
Starting kend: OK
```

**stop**

```bash
$ kend stop
Shutting down kend: Killed
```

**status**

```bash
$ kend status
kend is running
```


# Testing the Installation

It is time to check that Endpoint Node is successfully installed and it is working as expected after installation.

## Process Status <a href="#process-status" id="process-status"></a>

It is possible to check the status of EN's process using the status commands `systemctl` and `kend`.

### systemctl <a href="#systemctl" id="systemctl"></a>

`systemctl` is installed along with the RPM, and the status of EN can be checked as follows.

```bash
$ systemctl status kend.service
● kend.service - (null)
   Loaded: loaded (/etc/rc.d/init.d/kend; bad; vendor preset: disabled)
   Active: active (running) since Wed 2019-01-09 11:42:39 UTC; 1 months 4 days ago
     Docs: man:systemd-sysv-generator(8)
  Process: 29636 ExecStart=/etc/rc.d/init.d/kend start (code=exited, status=0/SUCCESS)
 Main PID: 29641 (ken)
   CGroup: /system.slice/kend.service
           └─29641 /usr/local/bin/ken --networkid 1000 --datadir /kend_home --port 32323 --srvtype fasthttp --metrics --prometheus --verbosity 3 --txpool.global...

Jan 09 11:42:39 ip-10-11-2-101.ap-northeast-2.compute.internal systemd[1]: Starting (null)...
Jan 09 11:42:39 ip-10-11-2-101.ap-northeast-2.compute.internal kend[29636]: Starting kend: [  OK  ]
Jan 09 11:42:39 ip-10-11-2-101.ap-northeast-2.compute.internal systemd[1]: Started (null).
```

You can check the current status such as `Active: active (running)` in the example above.

### kend <a href="#kend" id="kend"></a>

`kend` is installed along with the package, and the status of EN can be checked as follows.

```bash
$ kend status
kend is running
```

## Logs <a href="#logs" id="logs"></a>

The log is stored in `kend.out` file located in the path defined in the `LOG_DIR` field of the `kend.conf` file. When the node works properly, you can see that each block is imported per second as follows.

Example:

```bash
$ tail kend.out
INFO[02/13,07:02:24 Z] [35] Commit new mining work                    number=11572924 txs=0 elapsed=488.336µs
INFO[02/13,07:02:25 Z] [5] Imported new chain segment                blocks=1 txs=0 mgas=0.000     elapsed=1.800ms   mgasps=0.000       number=11572924 hash=f46d09…ffb2dc cache=1.59mB
INFO[02/13,07:02:25 Z] [35] Commit new mining work                    number=11572925 txs=0 elapsed=460.485µs
INFO[02/13,07:02:25 Z] [35] 🔗 block reached canonical chain           number=11572919 hash=01e889…524f02
INFO[02/13,07:02:26 Z] [14] Committed                                 address=0x1d4E05BB72677cB8fa576149c945b57d13F855e4 hash=1fabd3…af66fe number=11572925
INFO[02/13,07:02:26 Z] [5] Imported new chain segment                blocks=1 txs=0 mgas=0.000     elapsed=1.777ms   mgasps=0.000       number=11572925 hash=1fabd3…af66fe cache=1.59mB
INFO[02/13,07:02:26 Z] [35] Commit new mining work                    number=11572926 txs=0 elapsed=458.665µs
INFO[02/13,07:02:27 Z] [14] Committed                                 address=0x1d4E05BB72677cB8fa576149c945b57d13F855e4 hash=60b9aa…94f648 number=11572926
INFO[02/13,07:02:27 Z] [5] Imported new chain segment                blocks=1 txs=0 mgas=0.000     elapsed=1.783ms   mgasps=0.000       number=11572926 hash=60b9aa…94f648 cache=1.59mB
INFO[02/13,07:02:27 Z] [35] Commit new mining work      
```

## Queries <a href="#queries" id="queries"></a>

### ken console <a href="#ken-console" id="ken-console"></a>

Klaytn provides a CLI client: `ken console`. Another way of using the client is to connect to the process via IPC (inter-process communication). The IPC file `klay.ipc` is located in the `data` directory on an EN.

Please execute the following command and check out the result.

```
$ ken attach /var/kend/data/klay.ipc
Welcome to the Klaytn JavaScript console!

instance: Klaytn/vX.X.X/XXXX-XXXX/goX.X.X
 datadir: /var/kend/data
 modules: admin:1.0 debug:1.0 governance:1.0 istanbul:1.0 klay:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0
 >
```

You can check the usable commands on [API Document](/content/dapp/json-rpc)

The useful APIs to check the status of EN:

* `klay.blockNumber` (to get the latest block number)
* `net.peerCount` (to get the number of the connected Klaytn nodes currently)

### klay.blockNumber <a href="#klay-blocknumber" id="klay-blocknumber"></a>

You can get the latest block number to see if blocks are propagated properly.

```
> klay.blockNumber
11573819
```

### net.peerCount <a href="#net-peercount" id="net-peercount"></a>

```
> net.peerCount
14
```

The above command line returns the number of nodes that the EN connects to.


# ken CLI commands

`ken` is a command-line interface for Klaytn Endpoint Node.

```bash
USAGE:
   ken [options] command [command options] [arguments...]
```

## Commands <a href="#commands" id="commands"></a>

`ken` has the following commands.

```bash
COMMANDS:
   account     Manage accounts
   attach      Start an interactive JavaScript environment (connect to node)
   console     Start an interactive JavaScript environment
   dumpconfig  Show configuration values
   dumpgenesis Dump genesis block JSON configuration to stdout (This command is supoported from Klaytn v1.7.0.)
   init        Bootstrap and initialize a new genesis block
   snapshot    A set of commands based on the snapshot
   version     Show version number
   help, h     Shows a list of commands or help for one command
```

To get a detailed usage guideline for each command, give `-h` option.

```bash
$ ken account -h
Manage accounts, list all existing accounts, import a private key into a new
account, create a new account or update an existing account.
 ...
Keys are stored under <DATADIR>/keystore.
It is safe to transfer the entire directory or the individual keys therein
between klay nodes by simply copying.

Make sure you backup your keys regularly.

USAGE:
   ken account command [command options] [arguments...]

COMMANDS:
     list    Print summary of existing accounts
     new     Create a new account
     update  Update an existing account
     import  Import a private key into a new account
```

```bash
$ ken init -h
init [command options] [arguments...]

The init command initializes a new genesis block and definition for the network.
This is a destructive action and changes the network in which you will be
participating.
 ...
```

## JavaScript Console <a href="#javascript-console" id="javascript-console"></a>

Klaytn Endpoint Node comes with JavaScript console. From the console command line, you can initiate part of Klaytn API calls to your EN. To attach to the JavaScript console, execute the following command.

```bash
$ ken attach ~/kend_home/klay.ipc
Welcome to the Klaytn JavaScript console

!instance: Klaytn/vX.X.X/XXXX-XXXX/goX.X.X
 datadir: ~/kend_home
 modules: admin:1.0 debug:1.0 governance:1.0 istanbul:1.0 klay:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0

 >
```

`attach` command connects to the running node, while `console` command launches a node and connects to it.

```bash
   attach      Start an interactive JavaScript environment (connect to node)
   console     Start an interactive JavaScript environment
```

### Module APIs <a href="#module-apis" id="module-apis"></a>

If you type the module name on the console prompt, you will see the available properties and functions of the module. For the details of functions, please see [Klaytn API](/content/dapp/json-rpc).

```javascript
> personal
{
  listAccounts: [...],
  listWallets: [...],
  deriveAccount: function(),
  ecRecover: function(),
  getListAccounts: function(callback),
  getListWallets: function(callback),
  importRawKey: function(),
  lockAccount: function(),
  ...
}

> personal.listAccounts
["0x960dba2500ab529693ef8e299210768aa0d55ec8", "0x09a04dc9ac3cd92de5ff0d45ae50ff1b618305d9", "0x36662211c072dadbf5fc1e087ddebd36df986abd", "0xbf9683cf04520eeba6d936a3478de29437c5d048"]
> 
```


# JSON-RPC APIs

Endpoint Node exposes JSON-RPC APIs. You can enable/disable APIs as follows. For the detailed API specification, please refer to the [JSON-RPC APIs](/content/dapp/json-rpc).

**NOTE**: Offering an API over the HTTP (`rpc`) or WebSocket (`ws`) interfaces will give everyone access to the APIs who can access this interface (DApps, browser tabs, etc). Be careful about which APIs you enable. By defaulti, Klaytn enables all APIs over the IPC (`ipc`) interface but for `rpc` and `ws` required modules have to be explicitly enabled.

### Enabling APIs <a href="#enabling-apis" id="enabling-apis"></a>

#### From Commandline <a href="#from-commandline" id="from-commandline"></a>

To offer the APIs over the Klaytn RPC endpoints, please specify them with the `--${interface}api` command-line argument where `${interface}` can be `rpc` for the HTTP endpoint or `ws` for the WebSocket endpoint.

`ipc` offers all APIs over the unix socket (Unix) or named pipe (Windows) endpoint without any flag.

You can launch a Klaytn node with specific APIs you want to add like the example below. But keep in mind that you can't change APIs once you launch the node.

Example) launching a Klaytn node with `klay` and `net` modules enabled:

```shell
$ ken --rpcapi klay,net --rpc --{other options}
```

The HTTP RPC interface must be explicitly enabled using the `--rpc` flag.

#### Using Configuration <a href="#using-configuration" id="using-configuration"></a>

Please update the `RPC_ENABLE`, `RPC_API`, `WS_ENABLE` and `WS_API` properties in the [Configuration File](/content/operation-guide/configuration).

### Querying Enabled APIs <a href="#querying-enabled-apis" id="querying-enabled-apis"></a>

To determine which APIs an interface provides, the `modules` JSON-RPC method can be invoked. For example over an `rpc` interface:

**IPC**

```javascript
$ echo '{"jsonrpc":"2.0","method":"rpc_modules","params":[],"id":1}' | nc -U klay.ipc
```

**HTTP**

```shell
$ curl -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"rpc_modules","params":[],"id":1}' https://public-en-baobab.klaytn.net
```

will give all enabled modules including the version number:

```
{
   "jsonrpc":"2.0",
   "id":1,
   "result":{
      "admin":"1.0",
      "debug":"1.0",
      "klay":"1.0",
      "miner":"1.0",
      "net":"1.0",
      "personal":"1.0",
      "rpc":"1.0",
      "txpool":"1.0",
      "web3":"1.0"
   }
}
```

### Disabling unsafe debug APIs <a href="#disabling-unsafe-debug-apis" id="disabling-unsafe-debug-apis"></a>

Some debug namespace APIs are unsafe/unappropriate to be opened to public. We recommend you to provide the debug namespace APIs to authorized users only. However, if you want to maintain a public EN and provide debug namespace APIs to the public, we strongly recommend you to set the `rpc.unsafe-debug.disable` flag which will disable APIs that are unsafe/unappropriate to be opened to the public and enable only a subset of the debug namespace APIs.

The enabled APIs are as follows:

* [VM Tracing](/content/dapp/json-rpc/api-references/debug/tracing) APIs, however with limited functionality (only [pre-defined tracers](/content/dapp/json-rpc/api-references/debug/tracing#tracing-options) are allowed)
* debug\_dumpBlock, debug\_dumpStateTrie, debug\_getBlockRlp, debug\_getModifiedAccountsByHash, debug\_getModifiedAccountsByNumber, debug\_getBadBlocks, debug\_getModifiedStorageNodesByNumber
* debug\_metrics

To set the `rpc.unsafe-debug.disable` flag, append the following line in the `kend.conf` file.

```
ADDITIONAL="$ADDITIONAL --rpc.unsafe-debug.disable"
```


# Core Cell

## Intended Audience <a href="#intended-audience" id="intended-audience"></a>

* Core Cell Operators
* If your interest is in making and running Blockchain Applications on Klaytn, you don't need to maintain a Core Cell. You need to run an [Endpoint Node](/content/installation-guide/deployment/endpoint-node) instead to make your application interact with Klaytn network.

## Core Cell Overview <a href="#core-cell-overview" id="core-cell-overview"></a>

Core Cell (CC) is an entity that is participating in the consensus process, and is in charge of executing transactions and generating blocks. A Klaytn Core Cell (CC) consists of the following components.

* Consensus Node (CN): Consensus Nodes are participating in the block generation process.
* Proxy Node (PN): Proxy Nodes provide the interface to the network. PNs transmit the transaction requests to the Consensus Nodes, and propagate the blocks down to the Endpoint Nodes.

It is recommended that a Core Cell consists of one CN with two or more PNs. A CN connects to other CNs within the Core Cell Network to perform consensus. CNs only accept connections from their PNs in the same Core Cell to receive transaction requests and propagate blocks to the network. PNs accepts connections from any ENs within the Endpoint Node Network.

![Core Cell Overview](/files/9G3448JpTuMSqck7HFg9)

| Name | Description                                                                                                                                                                                                                                                                | Network Security                                                                                                                                                                                                                                                                    | Quantity                                               |
| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| CN   | A node that creates a new block with other CNs in the Core Cell Network                                                                                                                                                                                                    | A network is composed of permissioned CNs. (Requires IP access control).                                                                                                                                                                                                            | 1 unit                                                 |
| PN   | <p>- A node that submits transactions received from the Klaytn Endpoint Node Network to the CN.<br>- It propagates the created blocks to Klaytn Endpoint Node Network.<br>- It can scale out horizontally depending on the number of ENs in the Endpoint Node Network.</p> | <p>- It is connected to the CN in the Core Cell, and its IP and Ports are required to be public to accept connections from other Klaytn nodes on the Internet.<br>- It can connect to other PNs in other Core Cell via PN bootnode.<br>- It can connect to ENs via EN bootnode.</p> | At least 1 PN required. 2 or more PNs are recommended. |


# System Requirements

## H/W Specification <a href="#h-w-specification" id="h-w-specification"></a>

The network performance is measured based on the worst hardware specification within the network. According to the blockchain network structure, it is only possible to be scaled up vertically (increasing hardware capacity). Hence, it is recommended that all the nodes within the network should have the best hardwares having the similar specifications with each other at least.

If you're curious about the rationale of this hardware spec, the medium article [Determining optimal hardware specs for Klaytn node operators](https://klaytn.foundation/node-operator-optimal-specs/) would help you understand.

The following sections show the recommended specifications for both CNs and PNs.

### Bare-metal Server <a href="#bare-metal-server" id="bare-metal-server"></a>

| Category | Specification                                                                                                                                                               |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Server   | Intel® Server System [M50CYP1UR212](https://www.intel.sg/content/www/xa/en/products/sku/214842/intel-server-system-m50cyp1ur212/specifications.html)                        |
| CPU      | Intel® Xeon 8358 2.60 GHz (32-core/64-thread)                                                                                                                               |
| Memory   | 128GB (32GB \* 4)                                                                                                                                                           |
| Storage  | 3TB (or larger size) SSD (The preferred storage size and configuration could differ depending on the chain data size. Please consult the Klaytn Team for more information.) |

Note that this is a recommended hardware specification for CNs and PNs, not an exact requirement. Any physical machine with similar hardware configurations would be sufficient to operate a CN or a PN.

### Cloud VM <a href="#cloud-vm" id="cloud-vm"></a>

#### Recommended Specification for AWS <a href="#recommended-specification-for-aws" id="recommended-specification-for-aws"></a>

| Node Type |    Model    | vCPU | Memory (GiB) | Storage size (GiB) | Storage speed (IOPS) | Price (Seoul region, USD/h) |
| :-------: | :---------: | :--: | :----------: | :----------------: | :------------------: | :-------------------------: |
|     CN    | m6i.8xlarge |  32  |      128     |   3,000 (Minimum)  |         9,000        |            1.888            |
|     PN    | m6i.4xlarge |  16  |      64      |   3,000 (Minimum)  |         9,000        |            0.944            |

This storage specification is derived from AWS EBS SSD (gp3) specification.

The information above is from <https://aws.amazon.com/ec2/instance-types/> and <https://aws.amazon.com/ec2/pricing/on-demand/> and may be changed by AWS.

#### Recommended Specification for Azure <a href="#recommended-specification-for-azure" id="recommended-specification-for-azure"></a>

| Node Type |  Model  | vCPU | Memory (GiB) | Storage type (GiB) | Storage speed (IOPS) | Price (Korea Central, USD/h) |
| :-------: | :-----: | :--: | :----------: | :----------------: | :------------------: | :--------------------------: |
|     CN    | D32s v5 |  32  |      128     |     P50 (4096)     |         7500         |             1.888            |
|     PN    | D16s v5 |  16  |      64      |     P50 (4096)     |         7500         |             0.944            |

This storage specification is derived from Azure Premium Disk specification.

The information above is from <https://azure.microsoft.com/en-us/pricing/details/virtual-machines/series/> and <https://azure.microsoft.com/en-us/pricing/details/managed-disks/#pricing> and may be changed by Microsoft.

## Storage Requirements <a href="#storage-requirements" id="storage-requirements"></a>

Assuming 100 TPS in average, 300 bytes average transaction size, and 1-second block latency, the expected daily storage requirement is about 2.5 GB/day (=300x100x86400).

## Operating System <a href="#operating-system" id="operating-system"></a>

Recommended environment is compatible with RHEL (7.8 or later). Klaytn binaries are fully tested on Amazon Linux 2, but they should work on other linux-based environments as well. macOS binaries are also provided for development purpose.


# Network Configuration

A Core Cell can be made up of:

* multiple subnets (recommended)
* a single subnet

## A Core Cell with Multiple Subnets <a href="#a-core-cell-with-multiple-subnets" id="a-core-cell-with-multiple-subnets"></a>

It is recommended to have a two-layer subnet which is used in general web services such as DB + AppServer and Proxy Web Servers. This design of the subnet has more advantages on the security.

Since monitoring servers are also required for managing all servers as another layer, the following section describes how to setup a Core Cell with a three-layer subnet.

The three-layer subnet consists of the following:

* CN Subnet
* PN Subnet
* Management (Mgmt) Subnet

### CN Subnet <a href="#cn-subnet" id="cn-subnet"></a>

A CN Subnet consists of CN servers in Core Cells. The working CN in a Core Cell is only one, but spare one should be prepared for high availability. IP/Port of all CNs within the Core Cell Network (CCN) must be opened to each other because they try to connect to the others from the outside of the Core Cell. (This connection information can be received from Baobab operators.) The internal communication with other subnets in the Core Cell requires to open default port (32323: default Klaytn P2P port number) in order to connect to PNs of the PN Subnet. Furthermore, it is necessary to open other ports such as the CN monitoring port (61001) for the monitoring server and the SSH port (22) for the management purpose. If the multichannel feature is used, another port (32324: default multichannel port) should be opened as well.

![CN Subnet](/files/4ilfhqYjoo93evwHAgE0)

| Origin Subnet | Target Subnet     | Ingress                             | Egress |
| ------------- | ----------------- | ----------------------------------- | ------ |
| CN Subnet     | PN Subnet         | P2P: 32323 (32324 for multichannel) | All    |
| CN Subnet     | Mgmt Subnet       | SSH: 22, Monitoring: 61001          | All    |
| CN Subnet     | Public (Internet) | each CN's IP and P2P port           | All    |

### PN Subnet <a href="#pn-subnet" id="pn-subnet"></a>

A PN Subnet consists of the PN servers to provide services in order to connect to the external ENs.

A PN subnet is connected to the following nodes:

* CNs in Core Cells
* Some PNs of other Core Cells
* Core Cell Management Servers (Mgmt, Monitoring)
* EN nodes

![PN Subnet](/files/gsNkK0IUhTDNUlJBCumR)

| Origin Subnet | Target Subnet     | Ingress                             | Egress |
| ------------- | ----------------- | ----------------------------------- | ------ |
| PN Subnet     | CN Subnet         | P2P: 32323 (32324 for multichannel) | All    |
| PN Subnet     | Mgmt Subnet       | SSH: 22, Monitoring: 61001          | All    |
| PN Subnet     | Public (Internet) | P2P: 32323                          | All    |

### Mgmt Subnet <a href="#mgmt-subnet" id="mgmt-subnet"></a>

A Mgmt Subnet is a gateway subnet for the operator to enter into the Core Cell nodes through ssh. A VPN server may be necessary to make the connection together with a monitoring server and a management server installed with a tool to manage the Core Cell nodes.

![Management Subnet](/files/UjkW3iaDpnEKNuAlvLjY)

| Origin Subnet | Target Subnet     | Ingress                         | Egress |
| ------------- | ----------------- | ------------------------------- | ------ |
| Mgmt Subnet   | CN Subnet         | All                             | All    |
| Mgmt Subnet   | PN Subnet         | All                             | All    |
| Mgmt Subnet   | Public (Internet) | VPN (tcp): 443, VPN (udp): 1194 | All    |

## A Core Cell with a Single Subnet <a href="#a-core-cell-with-a-single-subnet" id="a-core-cell-with-a-single-subnet"></a>

A single subnet of a Core Cell is built for the development/test purpose or under the difficult circumstances to create multiple subnets.

All nodes are setup under a single CC subnet. Firewall setup is also necessary for the CN to connect to other CNs within the CNN using P2P port (32323, 32324 for multichannel option). The P2P port of the PN is opened to connect with ENs in Endpoint Node Network (ENN) and PNs in the Core Cell Network (CNN). Additionally, an optional VPN and monitoring servers are required to be managed remotely.

![CC with a Single Subnet](/files/myjDqZCMhTIqgOdru1U2)


# Installation Guide


# Download

You can get packages for CN, and PN in the [download page](/content/installation-guide/deployment/download).


# Before You Install

Before installing the Klaytn package, it is required to create the associated node information to enroll your node URIs. The Kgen package is provided for CC operators, please follow the steps in the order shown below.

1. Download `kgen` Package
2. Node Key & Node URI Creation
3. Node URI Enrollment

## Download `kgen` Package <a href="#download-kgen-package" id="download-kgen-package"></a>

First of all, you can download the latest version of `kgen` package depending on your operating systems on [Download](/content/installation-guide/deployment/core-cell/installation-guide/download) page.

You can find the `kgen` binary file under the `bin` directory.

## Node Key & Node URI Creation <a href="#node-key-node-uri-creation" id="node-key-node-uri-creation"></a>

The node key and the node URI are created only once at the beginning. The node URI must be shared with other Core Cells of the Core Cell Network. A CN connects to other CNs and a PN connects to a CN and some PNs using the created node URI. A node URI is created based on the node key by using the downloaded `kgen`. The below command line creates `nodekey` as well as `node_info.json`.

`kgen` takes the associated IP and Port number as follows.

```
$ kgen --ip "123.456.789.012" --port 32323 --file
$ ls
nodekey node_info.json
```

The `nodekey` is a 64-byte hexadecimal string which is a private key used in the node internally. This private key must be present at the Klaytn data directory and be careful not to lose it.

```
$ cat nodekey
f08f2118c455a6c9c9b5e035d3571e570a719ea61771e268546e796a264acc2b
$ mv nodekey ~/kcnd_home
```

The created file `node_info.json` includes the following contents.

| Key Name    | Description                       | Example                                                                                                                                                                  |
| ----------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| NodeAddress | an address of the associated node | 0xc8a23d67f2471066fa1b07270651fea7e5c0cf78                                                                                                                               |
| NodeKey     | the node key (a.k.a private key)  | aaa7248dfdf19418ae9121a0f39db39c5c27a3e404ea7c1b8e020ca8dbe7e71a                                                                                                         |
| NodeURI     | node URI                          | kni://4f2f47f3bf35a2c576d3345e6e9c49b147d510c05832d2458709f63c3c90c76ead205975d944ed65e77dd4c6f63ebe1ef21d60da95952bc1e200e7487f4d9e1b\@123.456.789.012:32323?discport=0 |

`node_info.json` contains the node information in a JSON format as follows.

```
$ cat node_info.json
{
    "NodeAddress": "0xc8a23d67f2471066fa1b07270651fea7e5c0cf78",
    "NodeKey": "aaa7248dfdf19418ae9121a0f39db39c5c27a3e404ea7c1b8e020ca8dbe7e71a",
    "NodeURI": "kni://4f2f47f3bf35a2c576d3345e6e9c49b147d510c05832d2458709f63c3c90c76ead205975d944ed65e77dd4c6f63ebe1ef21d60da95952bc1e200e7487f4d9e1b@123.456.789.012:32323?discport=0"
}
```

## Node URI Enrollment <a href="#node-uri-enrollment" id="node-uri-enrollment"></a>

The created node URI should be enrolled to participate in the Core Cell Network (CCN). The process of the enrollment is as follows.

1. Create a node URI using `kgen` (`node_info.json`) which contains the associated IP and Port number.
2. Send the information to the official Klaytn email address (`bootstrap@klaytn.com` for Cypress or `baobab@klaytn.com` for Baobab).

The enrolled information should be sent to the official Klaytn email address. The format is as follows.

In case of CN,

```
Company: Kakao
CN URI : kni://
4f2f47f3bf35a2c576d3345e6e9c49b147d510c05832d2458709f63c3c90c76ead205975d944ed65e77dd4c6f63ebe1ef21d60da95952bc1e200e7487f4d9e1b@123.456.789.012:32323?discport=0
```

In case of PN,

```
Company: Kakao
PN URI : kni://
4f2f47f3bf35a2c576d3345e6e9c49b147d510c05832d2458709f63c3c90c76ead205975d944ed65e77dd4c6f63ebe1ef21d60da95952bc1e200e7487f4d9e1b@123.456.789.012:32323?discport=0
```


# Consensus Node Setup


# Installation Guide

You can download the latest version of the `kcn` on [Download](/content/installation-guide/deployment/core-cell/installation-guide/download) page.

## Linux Archive Distribution <a href="#linux-archive-distribution" id="linux-archive-distribution"></a>

The archive file consists of the executable binary and the configuration file structured as follows.

**Note**: Do NOT alter the file structure or file name. If you change it, the node may not function correctly.

```
- bin
  |- kcn
  |- kcnd
- conf
  |- kcnd.conf
```

| File Name      | File Description                 |
| -------------- | -------------------------------- |
| bin/kcn        | CN executable file               |
| bin/kcnd       | CN start/termination script file |
| conf/kcnd.conf | CN configuration file            |

### Installation <a href="#installation" id="installation"></a>

The installation is the uncompression of the downloaded package where you want to install the package.

```bash
$ tar zxf kcn-vX.X.X-linux-amd64.tar.gz
```

Or,

```bash
$ tar zxf kcn-baobab-vX.X.X-linux-amd64.tar.gz
```

**Note**: it is recommended that the uncompressed directory `kcn-linux-amd64/bin` path should be added to the environment variable `$PATH` to run the `kcn` and `kcnd` globally. As an example,

```bash
$ export PATH=$PATH:~/downloaded/path/kcn-linux-amd64/bin
```

The other sections assume that the path is added to the variable.

## RPM Distribution (RHEL/CentOS/Fedora) <a href="#rpm-rhel-centos-fedora" id="rpm-rhel-centos-fedora"></a>

### Install downloaded RPM <a href="#install-downloaded-rpm" id="install-downloaded-rpm"></a>

You can install the downloaded RPM file with the following `yum` command.

```bash
$ yum install kcnd-vX.X.X.el7.x86_64.rpm
```

Or,

```bash
$ yum install kcnd-baobab-vX.X.X.el7.x86_64.rpm
```

### Install from Klaytn Yum Repo <a href="#install-from-klaytn-yum-repo" id="install-from-klaytn-yum-repo"></a>

Alternatively, you can install `kcnd` from the Klaytn Yum repo, run:

```bash
$ sudo curl -o /etc/yum.repos.d/klaytn.repo https://packages.klaytn.net/config/rhel/7/prod.repo && sudo yum install kcnd
```

### Installed Location <a href="#installed-location" id="installed-location"></a>

The installed files are located as follows.

| File Name | Location                 |
| --------- | ------------------------ |
| kcn       | /usr/bin/kcn             |
| kcnd.conf | /etc/kcnd/conf/kcnd.conf |


# Configuration

The CN configuration is to create a data directory and set up several values in the configuration file `kcnd.conf`.

1. Create the CN data directory.
2. Install node key
3. Configure the CN with `kcnd.conf`.

## CN Data Directory Creation <a href="#cn-data-directory-creation" id="cn-data-directory-creation"></a>

Considering the fact that the size of Klaytn blockchain data is always increased, it is recommended to use a big enough storage. You may need to create the directory on your desired path.

```bash
$ mkdir -p /var/kcnd/data
```

## Install Node Key <a href="#install-node-key" id="install-node-key"></a>

In order to operate a CN, a `nodekey` is required. The KCN binary will create a new one for you if you do not have it. If you have one, you need to put your `nodekey` into the CN data directory. The way to create a `nodekey` is described in the '[Before You Install](/content/installation-guide/deployment/core-cell/installation-guide/before-you-install)' section. The following command line copies the `nodekey` into the CN data directory.

```bash
$ cp nodekey /var/kcnd/data
```

## Update the Configuration File <a href="#update-the-configuration-file" id="update-the-configuration-file"></a>

Configuration File Location:

* For the archive distribution, the config directory location defaults to `$INSTALL_PATH/kcn-linux-amd64/conf/`.
* For the package distribution, the config directory defaults to `/etc/kcnd/conf/`.

### Add Data Directory <a href="#add-data-directory" id="add-data-directory"></a>

You should update the data directory environment variable `$DATA_DIR` on the configuration file `kcnd.conf`.

```
...
DATA_DIR=/var/kcnd/data
...
```

### Setup Rewardbase <a href="#setup-rewardbase" id="setup-rewardbase"></a>

As a reward of participating in the consensus of the Klaytn network, CN operator will receive KLAY. For this reason, it is required to set an address on the configuration file `kcnd.conf`.

The ways to create a new account are various, but the `kcn` also provides the functionality. You can check the help message with the following command.

```bash
$ kcn account new --help
```

One of the example of doing this procedure is as follows. First of all, you need to create a new account which the reward KLAY will be sent to.

```bash
$ kcn account new --datadir ~/kcnd_home
INFO[03/15,09:04:43 +09] [17] Setting connection type                   nodetype=cn conntype=-0
INFO[03/15,09:04:43 +09] [17] Maximum peer count                        KLAY=25 LES=0 total=25
INFO[03/15,09:04:43 +09] [17] SBN is disabled.
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {d13f7da0032b1204f77029dc1ecbf4dae2f04241}
```

As a result of this, it will create the associated keystore on the path that you define. Next, you need to put the created address in the file `kcnd.conf` file as follows.

```
...
REWARDBASE="d13f7da0032b1204f77029dc1ecbf4dae2f04241"
...
```

Keep in mind that the keystore and the password that you created is significantly important, so you must be careful to manage them. See more details about `kcnd.conf` on the [Configuration File](/content/operation-guide/configuration) section.

## Fast Sync (Optional) <a href="#fast-sync-optional" id="fast-sync-optional"></a>

Each CN maintains a copy of the network's chain data. If a node is out of sync, it can obtain this data from other nodes in the network -- a process known as syncing. When a new CN is first started, it must download the entire chain data from the network.

To accelerate this process, you may perform a fast sync by downloading a snapshot of the chain data before starting the CN. This can dramatically reduce the time the CN will spend syncing on first start.

Download the latest chaindata snapshot from the [Cypress snapshot archive](http://packages.klaytn.net/cypress/chaindata/) or [Baobab snapshot archive](http://packages.klaytn.net/baobab/chaindata/). Before starting `kcnd`, extract the snapshot inside the DATA\_DIR you configured in `kcnd.conf`.

For example:

```bash
$ tar -C ~/kcnd_home -xvf klaytn-cypress-chaindata-latest.tar.gz
```

Or,

```bash
$ tar -C ~/kcnd_home -xvf klaytn-baobab-chaindata-latest.tar.gz
```

After the data is extracted, you may start the CN normally.

You can refer to detailed information in the [Chaindata change](/content/operation-guide/chaindata-change)


# Startup the CN

## CN Start/Stop <a href="#cn-start-stop" id="cn-start-stop"></a>

You can start/stop the Klaytn service with the following `systemctl` command.

**Note**: This requires root privileges.

**start**

```bash
$ systemctl start kcnd.service

```

**stop**

```bash
$ systemctl stop kcnd.service

```

**status**

```bash
$ systemctl status kcnd.service

```

## Troubleshooting <a href="#troubleshooting" id="troubleshooting"></a>

If you meet the following error,

```bash
Failed to start kcnd.service: Unit not found.
```

reload the systemd manager configuration with the following command.

```bash
$ systemctl daemon-reload
```

## Export BLS public key info <a href="#export-bls-public-key-info" id="export-bls-public-key-info"></a>

If the network has activated or will activate the Randao hardfork, each CN maintainer must submit its BLS public key info to the [KIP-113 smart contract](https://kips.klaytn.foundation/KIPs/kip-113).

The BLS public key info can be calculated from the nodekey. To extract it, first start the node. Then use the command:

```
$ kcn account bls-info --datadir /var/kcnd/data
```

As a result, `bls-publicinfo-NODEID.json` file will be created.


# Proxy Node Setup


# Installation Guide

You can download the latest version of the `kpn` on [Download](/content/installation-guide/deployment/core-cell/installation-guide/download) page.

## Linux Archive Distribution <a href="#linux-archive-distribution" id="linux-archive-distribution"></a>

The archive file consists of the executable binary and the configuration file structured as follows.

**Note**: Do NOT alter the file structure or file name. If you change it, the node may not function correctly.

```
- bin
  |- kpn
  |- kpnd
- conf
  |- kpnd.conf
```

| File Name      | File Description                 |
| -------------- | -------------------------------- |
| bin/kpn        | PN executable file               |
| bin/kpnd       | PN start/termination script file |
| conf/kpnd.conf | PN configuration file            |

### Installation <a href="#installation" id="installation"></a>

The installation is the uncompression of the downloaded package where you want to install the package.

```bash
$ tar zxf kpn-vX.X.X-linux-amd64.tar.gz
```

Or,

```bash
$ tar zxf kpn-baobab-vX.X.X-linux-amd64.tar.gz
```

**Note**: it is recommended that the uncompressed directory `kpn-linux-amd64/bin` path should be added to the environment variable `$PATH` to run the `kpn` and `kpnd` globally. As an example,

```bash
$ export PATH=$PATH:~/downloaded/path/kpn-linux-amd64/bin
```

The other sections assume that the path is added to the variable.

## RPM Distribution (RHEL/CentOS/Fedora) <a href="#rpm-rhel-centos-fedora" id="rpm-rhel-centos-fedora"></a>

### Install downloaded RPM <a href="#install-downloaded-rpm" id="install-downloaded-rpm"></a>

You can install the downloaded RPM file with the following `yum` command.

```bash
$ yum install kpnd-vX.X.X.el7.x86_64.rpm
```

Or,

```bash
$ yum install kpnd-baobab-vX.X.X.el7.x86_64.rpm
```

### Install from Klaytn Yum Repo <a href="#install-from-klaytn-yum-repo" id="install-from-klaytn-yum-repo"></a>

Alternatively, you can install `kpnd` from the Klaytn Yum repo, run:

```bash
$ sudo curl -o /etc/yum.repos.d/klaytn.repo https://packages.klaytn.net/config/rhel/7/prod.repo && sudo yum install kpnd
```

### Installed Location <a href="#installed-location" id="installed-location"></a>

The installed files are located as follows.

| File Name | Location                 |
| --------- | ------------------------ |
| kpn       | /usr/bin/kpn             |
| kpnd.conf | /etc/kpnd/conf/kpnd.conf |


# Configuration

The PN configuration is to create a data directory and set up several values in the configuration file `kpnd.conf`.

1. Create a PN Data Directory
2. Install node key
3. Install `static-node.json`
4. Configure the PN with `kpnd.conf`.

## PN Data Directory Creation <a href="#pn-data-directory-creation" id="pn-data-directory-creation"></a>

Considering the fact that the size of Klaytn blockchain data is always increased, it is recommended to use a big enough storage. You may need to create the directory on your desired path.

```bash
$ mkdir -p /var/kpnd/data
```

## Install Node Key <a href="#install-node-key" id="install-node-key"></a>

In order to operate a PN, a `nodekey` is required. The KPN binary will create a new one for you if you do not have it. If you have one, you need to put your `nodekey` into the PN data directory. The way to create a `nodekey` is in the "[Before You Install](/content/installation-guide/deployment/core-cell/installation-guide/before-you-install)" section. The following command line copies the `nodekey` into the PN data directory.

```bash
$ cp nodekey /var/kpnd/data
```

## Install `static-nodes.json` <a href="#install-static-nodes-json" id="install-static-nodes-json"></a>

The `static-nodes.json` should be created from the PN operator. It contains the addresses that your PN is connected to. It is recommended to add the addresses including your CN and a PN from another Core Cell. Please contact to the Klaytn official email for more details (`bootstrap@klaytn.com` for Cypress or `baobab@klaytn.com` for Baobab).

**static-nodes.json**

```
[
  "kni://4f2f47f3bf35a2c576d3345e6e9c49b147d510c05832d2458709f63c3c90c76ead205975d944ed65e77dd4c6f63ebe1ef21d60da95952bc1e200e7487f4d9e1b@10.11.2.101:32323?discport=0&ntype=cn",
  "kni://8dee912aeda2ccfaa4fe421f015d4d75c2e3fd4aab75fa399b42767caad33531e57f3356b4a4af374593e33ec4320e1325aa2390a7be2489fa6b5724894680eb@10.11.2.102:32323?discport=0&ntype=pn"
]
```

The node URI of the PN is in the "[Before You Install](/content/installation-guide/deployment/core-cell/installation-guide/before-you-install)" section. (Note: This IP address is different from CN public IP.) The following command line copies the `static-nodes.json` file into the PN data directory.

```bash
$ cp static-nodes.json /var/kpnd/data
```

## Update the Configuration File <a href="#update-the-configuration-file" id="update-the-configuration-file"></a>

Configuration File Location:

* For the archive distribution, the config directory location defaults to `$INSTALL_PATH/kpn-linux-amd64/conf/`.
* For the package distribution, the config directory defaults to `/etc/kpnd/conf/`.

### Add Data Directory <a href="#add-data-directory" id="add-data-directory"></a>

You should update the data directory environment variable `$DATA_DIR` on the configuration file `kpnd.conf`.

```
...
DATA_DIR=/var/kpnd/data
...
```

## Fast Sync (Optional) <a href="#fast-sync-optional" id="fast-sync-optional"></a>

Each PN maintains a copy of the network's chain data. If a node is out of sync, it can obtain this data from other nodes in the network -- a process known as syncing. When a new PN is first started, it must download the entire chain data from the network.

To accelerate this process, you may perform a fast sync by downloading a snapshot of the chain data before starting the PN. This can dramatically reduce the time the PN will spend syncing on first start.

Download the latest chaindata snapshot from the [Cypress snapshot archive](http://packages.klaytn.net/cypress/chaindata/) or [Baobab snapshot archive](http://packages.klaytn.net/baobab/chaindata/). Before starting `kpnd`, extract the snapshot inside the DATA\_DIR you configured in `kpnd.conf`.

For example:

```
$ tar -C /var/kpnd/data -xvf klaytn-cypress-chaindata-latest.tar.gz
```

Or,

```
$ tar -C /var/kpnd/data -xvf klaytn-baobab-chaindata-latest.tar.gz
```

After the data is extracted, you may start the PN normally.

You can refer to detailed information in the [Chaindata change](https://github.com/klaytn/klaytn-docs/blob/main/docs/operation-guide/chaindata-change/README.md)


# Startup the PN

## PN Start/Stop <a href="#pn-start-stop" id="pn-start-stop"></a>

You can start/stop the Klaytn service with the following `systemctl` command.

**Note**: This requires root privileges.

**start**

```bash
$ systemctl start kpnd.service

```

**stop**

```bash
$ systemctl stop kpnd.service

```

**status**

```bash
$ systemctl status kpnd.service

```

## Troubleshooting <a href="#troubleshooting" id="troubleshooting"></a>

If you meet the following error,

```bash
Failed to start kpnd.service: Unit not found.
```

reload the systemd manager configuration with the following command.

```bash
$ systemctl daemon-reload
```


# Testing the Core Cell

It is time to check that Core Cell is successfully installed and it is working as expected after installation.

## Process Status <a href="#process-status" id="process-status"></a>

It is possible to check the status of CN/PN's process using the status commands `systemctl` and `kcnd/kpnd`.

### systemctl <a href="#systemctl" id="systemctl"></a>

`systemctl` is installed along with the RPM and the status of CN/PN can be checked as follows.

```bash
$ systemctl status kcnd.service
● kcnd.service - (null)
   Loaded: loaded (/etc/rc.d/init.d/kcnd; bad; vendor preset: disabled)
   Active: active (running) since Wed 2019-01-09 11:42:39 UTC; 1 months 4 days ago
     Docs: man:systemd-sysv-generator(8)
  Process: 29636 ExecStart=/etc/rc.d/init.d/kcnd start (code=exited, status=0/SUCCESS)
 Main PID: 29641 (kcn)
   CGroup: /system.slice/kcnd.service
           └─29641 /usr/local/bin/kcn --networkid 1000 --datadir /kcnd_home --port 32323 --srvtype fasthttp --metrics --prometheus --verbosity 3 --txpool.global...

Jan 09 11:42:39 ip-10-11-2-101.ap-northeast-2.compute.internal systemd[1]: Starting (null)...
Jan 09 11:42:39 ip-10-11-2-101.ap-northeast-2.compute.internal kcnd[29636]: Starting kcnd: [  OK  ]
Jan 09 11:42:39 ip-10-11-2-101.ap-northeast-2.compute.internal systemd[1]: Started (null).
```

You can check the current status such as `Active: active (running)` in the above example.

### kcnd (kpnd) <a href="#kcnd-kpnd" id="kcnd-kpnd"></a>

`kcnd` (or `kpnd`) is installed along with the package and the status of CN/PN can be checked as follows.

```bash
$ kcnd status
kcnd is running
```

## Logs <a href="#logs" id="logs"></a>

The log is stored in `kcnd.out` (or `kpnd.out`) file located in the path defined in the `LOG_DIR` field of the `kcnd.conf` (or `kpnd.conf`) file. When the node works properly, you can see that each block is created per second as follows.

Example:

```bash
$ tail kcnd.out
INFO[02/13,07:02:24 Z] [35] Commit new mining work                    number=11572924 txs=0 elapsed=488.336µs
INFO[02/13,07:02:25 Z] [5] Imported new chain segment                blocks=1 txs=0 mgas=0.000     elapsed=1.800ms   mgasps=0.000       number=11572924 hash=f46d09…ffb2dc cache=1.59mB
INFO[02/13,07:02:25 Z] [35] Commit new mining work                    number=11572925 txs=0 elapsed=460.485µs
INFO[02/13,07:02:25 Z] [35] 🔗 block reached canonical chain           number=11572919 hash=01e889…524f02
INFO[02/13,07:02:26 Z] [14] Committed                                 address=0x1d4E05BB72677cB8fa576149c945b57d13F855e4 hash=1fabd3…af66fe number=11572925
INFO[02/13,07:02:26 Z] [5] Imported new chain segment                blocks=1 txs=0 mgas=0.000     elapsed=1.777ms   mgasps=0.000       number=11572925 hash=1fabd3…af66fe cache=1.59mB
INFO[02/13,07:02:26 Z] [35] Commit new mining work                    number=11572926 txs=0 elapsed=458.665µs
INFO[02/13,07:02:27 Z] [14] Committed                                 address=0x1d4E05BB72677cB8fa576149c945b57d13F855e4 hash=60b9aa…94f648 number=11572926
INFO[02/13,07:02:27 Z] [5] Imported new chain segment                blocks=1 txs=0 mgas=0.000     elapsed=1.783ms   mgasps=0.000       number=11572926 hash=60b9aa…94f648 cache=1.59mB
INFO[02/13,07:02:27 Z] [35] Commit new mining work                    number=11572927 txs=0 elapsed=483.436µs
```

## kcn console (kpn console) <a href="#kcn-console-kpn-console" id="kcn-console-kpn-console"></a>

Klaytn provides a CLI client: `kcn console` (or `kpn console`). However, a CN/PN may disable the RPC interface for the client due to the security reason. Another way of using the client is to connect to the process via IPC (inter-process communication).

The IPC file `klay.ipc` is located in the `data` directory on a CN/PN.

Please execute the following command and check out the result.

In case of a CN,

```bash
$ ken attach /var/kend/data/klay.ipc
Welcome to the Klaytn JavaScript console!

instance: Klaytn/vX.X.X/XXXX-XXXX/goX.X.X
 datadir: /var/kend/data
 modules: admin:1.0 debug:1.0 governance:1.0 istanbul:1.0 klay:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0
 >
```

In case of a PN,

```bash
 $ kpn attach /var/kpnd/data/klay.ipc
 Welcome to the Klaytn JavaScript console!

 instance: Klaytn/vX.X.X/XXXX-XXXX/goX.X.X
 coinbase: 0x67f68fdd9740fd7a1ac366294f05a3fd8df0ed40
 at block: 11573551 (Wed, 13 Feb 2019 07:12:52 UTC)
  datadir: /var/kpnd/data
  modules: admin:1.0 debug:1.0 istanbul:1.0 klay:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0
  >
```

You can check the usable commands on [API Document](https://github.com/klaytn/klaytn-docs/blob/main/docs/installation-guide/dapp/json-rpc/README.md)

The useful APIs to check the status of a CN/PN:

* `klay.blockNumber` (to get the latest block number)
* `net.peerCount` (to get the number of the connected Klaytn nodes currently)

### klay.blockNumber <a href="#klay-blocknumber" id="klay-blocknumber"></a>

You can get the latest block number to see if blocks are created (for CNs) or propagated (for CNs and PNs) properly based on your node type.

```javascript
> klay.blockNumber
11573819
```

### net.peerCount <a href="#net-peercount" id="net-peercount"></a>

```javascript
> net.peerCount
14
```

The above command line returns a different value based on the node type.

* CN: the number of connected CNs + the number of connected PNs.
* PN: the number of connected CNs + the number of connected PNs + the number of connected ENs.


# Monitoring Setup

## Overview <a href="#overview" id="overview"></a>

The Klaytn team provides a site for monitoring the Klaytn CCN at <http://cypress.klaytn.net:3000>. The `telegraf` monitoring agent is installed in each CN/PN of the CC to collect metrics and send them to the monitoring server. Once installed, you may visit the monitoring site to view the metrics of the Klaytn CCs.

The installation process is as follows:

1. Install `telegraf` in the CN/PNs
2. Configure `telegraf`
3. Start `telegraf`

## Telegraf Installation <a href="#telegraf-installation" id="telegraf-installation"></a>

Telegraf Installation Guide (Amazon Linux 2 users, see below): <https://docs.influxdata.com/telegraf/latest/introduction/installation/>

**Note for Amazon Linux 2**

To install Telegraph on Amazon Linux 2, you may use InfluxData's RHEL 7 yum repo as follows:

```
cat <<EOF | sudo tee /etc/yum.repos.d/influxdb.repo
[influxdb]
name = InfluxDB Repository - RHEL 7
baseurl = https://repos.influxdata.com/rhel/7/\$basearch/stable
enabled = 1
gpgcheck = 1
gpgkey = https://repos.influxdata.com/influxdb.key
EOF
```

## Telegraf Setup <a href="#telegraf-setup" id="telegraf-setup"></a>

### Enable monitoring in kcnd/kpnd <a href="#enable-monitoring-in-kcnd-kpnd" id="enable-monitoring-in-kcnd-kpnd"></a>

/etc/kcnd/conf/kcnd.conf

```
...
METRICS=1
PROMETHEUS=1
...
```

**Check**

You may confirm that the above two options are enabled by checking that port 61001 is open.

```
$ netstat -ntap | grep 61001
tcp        0      0 :::61001        :::*       LISTEN      8989/kcn
```

**Configure Telegraf service**

Copy the following file to the `telegraf` configuration directory (`/etc/telegraf/telegraf.d/`), and edit `nodetype`, `instance`, and `hostname` appropriately for each node:

```
[global_tags]
  # Change "cn" to "pn" for PN installation
  nodetype = "cn"

  # The CN/PN name (e.g. `example-cn`, `example-pn`)
  instance = "<hostname>"

[agent]
  # The CN/PN name (e.g. `example-cn`, `example-pn`)
  hostname = "<hostname>"

[[outputs.influxdb]]
  urls = [ "http://localhost:" ]
  database = "klaytn_cypress"

[[inputs.prometheus]]
  urls = [ "http://localhost:61001/metrics" ]
```

Change the following in `/etc/telegraf/telegraf.conf`:

* Comment out the `[[outputs.influxdb]]` section

**Start Telegraf**

```
$ systemctl restart telegraf
```

## Grafana <a href="#grafana" id="grafana"></a>

If each CN/PN has the above configuration and agent, you can check the metrics at the following URL:

<http://cypress.klaytn.net:3000>

As a CC operator, you may request an account by providing your company name and email address in the Slack channel. Please note that only CC operators are allowed to request a Grafana account.


# H/A Setup

Configuring the CN for high availability is critical for effectively operating a Core Cell. The recommended high availability scheme depends on whether the Core Cell is deployed on physical or cloud infrastructure.

## Active-Standby (recommended for bare-metal) <a href="#active-standby-recommended-for-bare-metal" id="active-standby-recommended-for-bare-metal"></a>

In this configuration, two CN nodes are installed in active-standby configuration. During normal operation the active node participates in block generation, while the standby only synchronizes chaindata from the network. This configuration ensures that the standby CN node has a fresh copy of the chaindata in the event of a failure in the active node.

### Setup <a href="#setup" id="setup"></a>

1. Create a backup of the active CN's `nodekey`.
2. Install a standby CN. The configuration is the same as the active CN except:
   * The standby should use a different `nodekey`
   * Add the addresses of the PNs to `$DATA_DIR/static-nodes.json`

### Failover <a href="#failover" id="failover"></a>

1. Stop the standby CN: `sudo systemctl stop kcnd`
2. Replace the `nodekey` of the standby with the `nodekey` of the failed active CN.
3. Reassign the IP address of the active CN to the standby CN.
4. Start the standby CN and verify that it is in sync with the network: `sudo systemctl start kcnd`

## Machine Image & Snapshot (recommended for cloud) <a href="#machine-image-snapshot-recommended-for-cloud" id="machine-image-snapshot-recommended-for-cloud"></a>

Cloud infrastructure allows operators to replace failed nodes much more quickly, so it is not necessary to operate a second standby CN. Instead, it is sufficient to ensure that a new CN can be quickly provisioned and provided with a updated copy of the chaindata.

The exact terminology and procedure may vary across different cloud environments. The procedure below is based on AWS (specifically EC2 and EBS), but can be adapted for other cloud platforms.

### Setup <a href="#setup" id="setup"></a>

1. Create a backup of the active CN's `nodekey`.
2. Each time the CN configuration or software is updated, create a machine image (e.g. AMI). Do not include the volume containing `DATA_DIR` in this image -- this will be obtained separately.

### Failover <a href="#failover" id="failover"></a>

Use any of the CC's PN nodes to obtain a chaindata snapshot:

1. Connect to any PN node and stop kpnd: `sudo systemctl stop kpnd`. It is important to stop kpnd first, to ensure data consistency.
2. Using the AWS console, create a snapshot of the volume containing the PN's `DATA_DIR`.
3. Start kpnd: `sudo systemctl start kpnd`

Create a new CN using the base CN image and the chaindata image:

1. Create an instance using the CN image (created in "Setup" above).
2. Attach a volume created from the snapshot of the PN's `$DATA_DIR`.
3. Remove all files from the volume except `$DATA_DIR/klay/chaindata`. Confirm that the `DATA_DIR` set in `kcnd.conf` matches the directory containing the chaindata. It may be necessary to rename the directory if the name is different.
4. Copy the `nodekey` of the failed CN to `$DATA_DIR/klay/nodekey`.
5. Reassign the IP address of the failed CN to the replacement.
6. Start kcnd: `sudo systemctl start kcnd`
7. Verify the CN is in sync with the network.

## Additional Considerations <a href="#additional-considerations" id="additional-considerations"></a>

Reassigning the public IP of the failed CN to the replacement CN will allow the replacement to connect immediately to other CNs. If the IP changes, the new CN will not be able to connect to the network until all other CCOs have updated their firewall configurations.


# Service Chain

## Intended Audience <a href="#intended-audience" id="intended-audience"></a>

* dApp developers who need high TPS, minimal transaction fees, or data privacy.
* Anyone who wants to build a local private network or a ledger database for testing.

## Service Chain Overview <a href="#service-chain-overview" id="service-chain-overview"></a>

Klaytn Service Chain provides the following features.

* Immediate finality.
* Cross-chain token transfer.
* Data anchoring to the main chain.
* Multi-sig bridge contract to meet enterprise security requirements.

![](/files/oJm3XSqpLjLKQrrMw7XW)

Read the [Klaytn Scaling Solution](/content/klaytn/scaling-solutions) for more details about the Service Chain.


# Getting Started

By following the steps in this section, you will quickly set up and run a ServiceChain network, an independent blockchain network connected to the Klaytn testnet.

This tutorial provides a step-by-step guide for setting up a ServiceChain network and connecting it to the Klaytn Baobab network. You will also learn how to enable periodic anchoring and cross-chain value transfer. In order to operate the actual blockchain services with the ServiceChain, we will explain High Availability, building a ServiceChain hierarchically, and value transfer between sibling ServiceChains.

* [Setting up a 4-node ServiceChain](/content/installation-guide/deployment/service-chain/getting-started/4nodes-setup-guide)
* [Connecting to Baobab](/content/installation-guide/deployment/service-chain/getting-started/en-scn-connection)
* [Cross-chain Value Transfer](/content/installation-guide/deployment/service-chain/getting-started/value-transfer)
* [HA for ServiceChain](/content/installation-guide/deployment/service-chain/getting-started/ha-for-sc)
* [Nested ServiceChain](/content/installation-guide/deployment/service-chain/getting-started/nested-sc)
* [Value Transfer between Sibling ServiceChains](/content/installation-guide/deployment/service-chain/getting-started/value-transfer-between-sibling)


# Setting up a 4-node Service Chain

This section covers how to set up a multi-node ServiceChain. We will set up a 4-consensus-node ServiceChain with `chainID` 1002, as you can see in the blue border box in the figure below.

![](/files/lDOWOiKGxTklIzzfc4lQ)

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* Download packages for `kscn`, `homi` binary from [Download](/content/installation-guide/deployment/download).
* 4 Linux or MacOS servers
* Minimum hardware requirements
  * CPU: 4-core (Intel Xeon or equivalent), RAM: 16GB, HDD: 50GB
  * Please refer to [System Requirements](/content/installation-guide/deployment/service-chain/references/system-requirements) for more explanation.

### Step 0: Install SCN on all nodes <a href="#install-scn" id="install-scn"></a>

The installation is the uncompression of the downloaded package. Extract the SCN archive on each server.

```console
$ tar xvf kscn-vX.X.X-XXXXX-amd64.tar.gz
x kscn-XXXXX-amd64/
x kscn-XXXXX-amd64/conf/
x kscn-XXXXX-amd64/conf/kscnd.conf
x kscn-XXXXX-amd64/bin/
x kscn-XXXXX-amd64/bin/kscnd
x kscn-XXXXX-amd64/bin/kscn
```

For the convenience, we will add the binary path to $PATH. Use the actual path on your node.

```console
$ export PATH=$PATH:~/path/to/kscn-XXXXX-amd64/bin
```

SCN also provides various RPM distributions like RHEL, CentOS, and Fedora. For more information, please refer to [Installation](/content/installation-guide/deployment/service-chain/references/scn/installation).

```console
$ curl -o /etc/yum.repos.d/klaytn.repo https://packages.klaytn.net/config/rhel/7/prod.repo
  % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed
     100 118 100 118 0 0 1113 0 --:--:-- --:--:-- --:--:-- 1102 

$ yum list | grep klaytn 
packages-klaytn-prod 31 kB/s | 2.9 kB 00:00 
homi.x86_64           v1.8.0-0.el7      packages-klaytn-prod 
kbnd.x86_64           v1.8.0-0.el7      packages-klaytn-prod 
kcnd.x86_64           v1.8.0-0.el7      packages-klaytn-prod 
kcnd-baobab.x86_64    v1.8.0-0.el7      packages-klaytn-prod 
kend.x86_64           v1.8.0-0.el7      packages-klaytn-prod 
kend-baobab.x86_64    v1.8.0-0.el7      packages-klaytn-prod 
kgen.x86_64           v1.8.0-0.el7      packages-klaytn-prod 
kpnd.x86_64           v1.8.0-0.el7      packages-klaytn-prod 
kpnd-baobab.x86_64    v1.8.0-0.el7      packages-klaytn-prod 
kscnd.x86_64          v1.8.0-0.el7      packages-klaytn-prod 
ksend.x86_64          v1.8.0-0.el7      packages-klaytn-prod 
kspnd.x86_64          v1.8.0-0.el7      packages-klaytn-prod 

$ yum install kscnd
```

### Step 1: Create genesis.json and nodekeys <a href="#step-1-create-genesis-json-and-a-key" id="step-1-create-genesis-json-and-a-key"></a>

We will use homi utility to generate the needful files. `homi` is a utility that automatically generates scripts, configuration files, and private keys necessary to configure the Klaytn blockchain. You can execute homi from any Linux/Mac PC.

First, extract the homi archive you downloaded.

```console
$ tar xvf homi-vX.X.X-XXXXX-amd64.tar.gz
x homi-XXXXX-amd64/
x homi-XXXXX-amd64/bin/
x homi-XXXXX-amd64/bin/homi
```

Go to the `bin` folder and execute `homi` with following options to generate the files. `homi setup --gen-type local --cn-num 4 --test-num 1 --servicechain --chainID 1002 --p2p-port 22323 -o homi-output` Since Baobab's `chainID` is 1001, for convenience, the `chainID` of the ServiceChain constructed in this example is set to 1002. When operating a blockchain by launching an actual service, it is recommended to use it after registering a new chainID value at <https://chainlist.defillama.com/> so that chainID does not overlap with other ServiceChains. The ServiceChain port is set to 22323, which is the default port.

```console
$ ./homi setup --gen-type local --cn-num 4 --test-num 1 --servicechain --chainID 1002 --p2p-port 22323 -o homi-output
Created :  homi-output/keys/passwd1
Created :  homi-output/keys/passwd2
Created :  homi-output/keys/passwd3
Created :  homi-output/keys/passwd4
Created :  homi-output/scripts/genesis.json
Created :  homi-output/keys/nodekey1
Created :  homi-output/keys/validator1
Created :  homi-output/keys/nodekey2
Created :  homi-output/keys/validator2
Created :  homi-output/keys/nodekey3
Created :  homi-output/keys/validator3
Created :  homi-output/keys/nodekey4
Created :  homi-output/keys/validator4
Created :  homi-output/scripts/static-nodes.json
Created :  homi-output/keys_test/testkey1
Created :  homi-output/keys_test/keystore1/0xdC7218621513f71d609653d22C39d79d558d9CDC
Created :  homi-output/Klaytn.json
Created :  homi-output/Klaytn_txpool.json
```

Among the outputs, we will use `nodekey*`, `genesis.json` and `static-nodes.json` in the subsequent steps.

### Step 2: Customize static-nodes.json <a href="#step-2-customize-static-nodes-json" id="step-2-customize-static-nodes-json"></a>

Open `homi-output/scripts/static-nodes.json` in a text editor then update the IP addresses and ports with the actual values of your nodes. In this example, it is assumed that the IP of each SCN node in the ServiceChain is as shown in the figure below. Remember the port you assigned here, as it will be used later in step 4.

![](/files/SXR7GS6wXcfWykVKDLAp)

```json
[
     "kni://38693ad4b17ff77...23153@192.168.0.1:22323?discport=0\u0026ntype=cn",
     "kni://f36d969b16f7337...1329b@192.168.0.2:22323?discport=0\u0026ntype=cn",
     "kni://16e55d8921ab034...b2bec@192.168.0.3:22323?discport=0\u0026ntype=cn",
     "kni://0973e792a421c1d...bbd71@192.168.0.4:22323?discport=0\u0026ntype=cn"
]
```

After you update `static-nodes.json`, upload the output folders(`homi-output`) to all SCNs, i.e. SCN-L2-01, SCN-L2-02, SCN-L2-03, SCN-L2-04 nodes in this example.

```console
$ scp -r path/to/homi-output/ user@192.168.0.1:~/
$ scp -r path/to/homi-output/ user@192.168.0.2:~/
$ scp -r path/to/homi-output/ user@192.168.0.3:~/
$ scp -r path/to/homi-output/ user@192.168.0.4:~/
```

### Step 3: Node initialization <a href="#step-3-node-initialization" id="step-3-node-initialization"></a>

Now, we will initialize each node using the genesis file. On each node, execute the following command. It will create the data folder storing the chain data and logs on your home directory. You can change the data folder using the `--datadir` directive. In this example, we set the data folder to `\~/data`.

```console
$ kscn --datadir ~/data init ~/homi-output/scripts/genesis.json

$ ls ~/data
keystore	klay		kscn
```

### Step 4: Install `nodekey` and `static-nodes.json` <a href="#step-4-install-nodekey" id="step-4-install-nodekey"></a>

On every SCNs, copy `static-nodes.json` to the data folder.

```console
$ cp ~/homi-output/scripts/static-nodes.json ~/data/
```

In step 1, we generated 4 nodekeys. Assign each node key to the SCN and copy the matching `nodekey` to each SCN's data folder. For example, use `nodekey1` for SCN-L2-01(192.168.0.1) node and use `nodekey2`, `nodekey3` and `nodekey4` for SCN-L2-02(192.168.0.2), SCN-L2-03(192.168.0.3) and SCN-L2-04(192.168.0.4) respectively.

```console
$ cp ~/homi-output/keys/nodekey{1..4} ~/data/klay/nodekey
```

![](/files/5iy6VgvUODuxUV3SkQMY)

### Step 5: Configure nodes <a href="#step-5-configure-nodes" id="step-5-configure-nodes"></a>

On every SCNs, go to the kscn installation folder and edit `conf/kscnd.conf` as follows. `PORT` is the port used to set up `homi`, and `SC_SUB_BRIDGE` is required for connecting bridges in the next section. For now, just set it to 0. In `DATA_DIR`, enter the data folder used in step 3.

```
...
PORT=22323
...
SC_SUB_BRIDGE=0
...
DATA_DIR=~/data
...
```

### Step 6: Start nodes <a href="#step-6-start-nodes" id="step-6-start-nodes"></a>

Execute the following command on all SCN nodes.

```console
$ kscnd start
Starting kscnd: OK
```

You can check block generation status by watching `klay.blockNumber`. If this number is not 0, the node is working fine.

```console
$ kscn attach --datadir ~/data
> klay.blockNumber
10
```

If you want to stop a node, you can use the command `kscnd stop`

### (Example) Creation and confirmation of a value transfer transaction <a href="#example-creation-and-confirmation-of-a-value-transfer-transaction" id="example-creation-and-confirmation-of-a-value-transfer-transaction"></a>

Now the 4-node ServiceChain is up and running. We will execute a value transfer transaction in the ServiceChain to confirm the installation.

![](/files/VxUfIXAr7wr29L2yLGAb)

#### Step 1: Import the test account <a href="#step-1-import-the-test-account" id="step-1-import-the-test-account"></a>

`testkey1` was automatically generated by `homi` in step 1. KLAY is allocated to the test account as described in the `genesis.json` which was also generated by `homi`.

```console
$ kscn account import --datadir ~/data ~/homi-output/keys_test/testkey1
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {80119c31cdae67c42c8296929bb4f89b2a52cec4}
```

#### Step 2: Unlock the account <a href="#step-2-unlock-the-account" id="step-2-unlock-the-account"></a>

Unlocking the account is possible only through the console of the SCN node that imported `testkey1`.

```console
$ kscn attach --datadir ~/data
> personal.unlockAccount("80119c31cdae67c42c8296929bb4f89b2a52cec4")
Unlock account 80119c31cdae67c42c8296929bb4f89b2a52cec4
Passphrase:
true
```

#### Step 3: Send a transaction and check the balance <a href="#step-3-send-a-transaction-and-check-the-balance" id="step-3-send-a-transaction-and-check-the-balance"></a>

```console
> klay.sendTransaction({from: "80119c31cdae67c42c8296929bb4f89b2a52cec4", to: "305c6cc464d5fe1e624679695a20d641a01688e1", value: 10})
"0xa0e7102e8f14200cec8d964aacc1c9ed7c22271078b2b213170c64333cbca8a3"
> klay.getBalance("305c6cc464d5fe1e624679695a20d641a01688e1")
10
```

{% hint style="info" %}
The simplest form of ServiceChain is having one SCN. The ServiceChain illustrated in this tutorial is a 4-node ServiceChain. You can, however, set up a single-node ServiceChain if you wish. Simply pass `--cn-num 1` instead of `--cn-num 4` to homi in 'Step 1:Create genesis.json and nodekeys'.

At least 4 nodes are required to tolerate byzantine faults. Therefore, the minimum number of SCNs to achieve high availability under the BFT algorithm is 4. Having 2 SCN nodes is not enough, because if one SCN fails, the other one cannot reach a consensus on its own.
{% endhint %}


# Connecting to Baobab

This section covers how to connect your 4-node ServiceChain network to the Baobab network. You will set up a Baobab EN and connect the EN with one of your SCNs. Then you will enable the anchoring feature to put ServiceChain block information onto the Baobab network.

![](/files/yKWog2p34wIqf12SFBdO)

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* 1 Linux or MacOS server for EN
* Minimum hardware requirements for testing
  * CPU: 4-core (Intel Xeon or equivalent), RAM: 16GB, HDD: 50GB
  * Please refer to the [System Requirements](/content/installation-guide/deployment/service-chain/references/system-requirements) for more explanation.
* Download the Baobab EN executable. For the full list of downloadable binaries, see [Download](/content/installation-guide/deployment/download).
* Assumptions and Limitations
  * A ServiceChain network is installed and running. Please refer to [Setting up a 4-node Service Chain](/content/installation-guide/deployment/service-chain/getting-started/4nodes-setup-guide) to setup a network.
  * A Baobab EN.
  * One EN can only connect to one SCN since only one-to-one connection is supported.
  * Every SCN does not have to connect to the EN.

### Step 0: Install Baobab EN <a href="#install-baobab-en" id="install-baobab-en"></a>

The installation is the uncompression of the downloaded package. Extract the archive on the EN server.

```bash
EN-01$ tar xvf ken-baobab-vX.X.X-XXXXX-amd64.tar.gz
```

### Step 1: Preparing genesis.json <a href="#step-1-preparing-genesis-json" id="step-1-preparing-genesis-json"></a>

From the EN server, download the `genesis.json` for `Baobab` network.

```
EN-01$ curl -X GET https://packages.klaytn.net/baobab/genesis.json -o ~/genesis.json
```

### Step 2: EN Node Initialization <a href="#step-2-en-node-initialization" id="step-2-en-node-initialization"></a>

Now, we will initialize the EN node using the genesis file. Execute the following command. It will create the data folder storing the chain data and logs on your home directory. You can change the data folder using the `--datadir` directive.

```
EN-01$ ken init --datadir ~/data ~/genesis.json
```

### Step 3: Configure the EN Node <a href="#step-3-configure-the-en-node" id="step-3-configure-the-en-node"></a>

Go to the ken installation folder and rename `mv kend_baobab.conf kend.conf`, then edit `conf/kend.conf` as follows.

```
...
NETWORK="baobab"
...
SC_MAIN_BRIDGE=1
...
DATA_DIR=~/data
...
```

### Step 4: Start the EN Node <a href="#step-4-start-the-en-node" id="step-4-start-the-en-node"></a>

```
EN-01$ kend start
Starting kscnd: OK
```

You can check block sync status by watching `klay.blockNumber`. If this number is not 0, the node is working fine. Downloading all blocks on the Baobab network may take a long time depending on network conditions and hardware performance, so we recommend using [Fast Sync](/content/installation-guide/deployment/endpoint-node/installation-guide/configuration) to synchronize blocks.

```
EN-01$ ken attach --datadir ~/data
> klay.blockNumber
21073
```

If you want to stop a node, you can use the command `kend stop`

### Step 5: Check KNI of EN Node <a href="#step-5-check-kni-of-en-node" id="step-5-check-kni-of-en-node"></a>

Take note of EN-01's KNI which is the information used to connect from an SCN-L2-01 node. This value will be used in the next step when generating `main-bridges.json`.

```
EN-01$ ken attach --datadir ~/data
> mainbridge.nodeInfo.kni
"kni://0f7aa6499553...25bae@[::]:50505?discport=0"
```

![](/files/7BfzyXfHKL9lor874V8U)

### Step 6: Create main-bridges.json <a href="#step-6-create-main-bridges-json" id="step-6-create-main-bridges-json"></a>

Log on to an SCN-L2-01 (note: not the EN-01 node) and create `main-bridges.json` on `~/data`. Replace `[::]` located after `@` letter with EN-01 node's IP address.

```
SCN-L2-01$ echo '["kni://0f7aa6499553...25bae@192.168.1.1:50505?discport=0"]' > ~/data/main-bridges.json
```

### Step 7: Configure SCN then Restart kscn <a href="#step-7-configure-scn-then-restart-kscn" id="step-7-configure-scn-then-restart-kscn"></a>

From the SCN-L2-01 node's shell, edit `kscn-XXXXX-amd64/conf/kscnd.conf`. If `SC_SUB_BRIDGE` is set to 1, data anchoring starts automatically when the SCN-L2-01 node starts. In this example, `SC_PARENT_CHAIN_ID` is set to 1001 because the `chainID` of the parent chain, Baobab, is 1001. `SC_ANCHORING_PERIOD` is the parameter that decides the period to send an anchoring tx to the main chain. By setting the value to 10, you configure the node to perform anchoring every 10 blocks. The default value is 1.

```
...
SC_SUB_BRIDGE=1
...
SC_PARENT_CHAIN_ID=1001
...
SC_ANCHORING_PERIOD=10
...
```

Restart kscn by executing the following command:

```
SCN-L2-01$ kscnd stop
Shutting down kscnd: Killed
SCN-L2-01$ kscnd start
Starting kscnd: OK
```

Check if the SCN-L2-01 is connected to the EN-01 by checking `subbridge.peers.length`

```
SCN-L2-01$ kscn attach --datadir ~/data
> subbridge.peers.length
1
```

### Anchoring <a href="#anchoring" id="anchoring"></a>

After finishing the EN-01 and SCN-L2-01 connection, you can log ServiceChain block information on the parent chain via Anchoring. In this section, you will top up a parent operator account, enable Anchoring, and check the anchored block number.

#### Step 1: Get KLAY to test anchoring <a href="#step-1-get-klay-to-test-anchoring" id="step-1-get-klay-to-test-anchoring"></a>

Anchoring requires SCN-L2-01 to make an anchoring transaction to Baobab. So `subbridge.parentOperator` account should have enough KLAY to pay the transaction fee. Get some KLAY from [Baobab Wallet Faucet](https://baobab.wallet.klaytn.foundation/) and transfer some KLAY to the `parentOperator`. For data anchoring in real service, `parentOperator` needs to have enough KLAY for transaction fee.

```
SCN-L2-01$ kscn attach --datadir ~/data
> subbridge.parentOperator
"0x3ce216beeafc62d20547376396e89528e1d778ca"
```

![](/files/rEy00HEKSfiFdm7RArZT)

#### Step 2: Start Anchoring <a href="#step-2-start-anchoring" id="step-2-start-anchoring"></a>

To start anchoring, execute the following command:

```
SCN-L2-01$ kscn attach --datadir ~/data
> subbridge.anchoring(true)
true
```

After anchoring starts, you can check the latest block anchored to Baobab by using `subbridge.latestAnchoredBlockNumber`. Please note that this only works after the EN already followed up on the latest block of Baobab. By default, SCN-L2-01 tries anchoring on every block from the block on which anchoring is turned on. The anchoring period can be set by changing `SC_ANCHORING_PERIOD`. If the value is set to 10, the node tries anchoring when the block number is a multiple of 10.

```
SCN-L2-01$ kscn attach --datadir ~/data
> subbridge.latestAnchoredBlockNumber
100
```

![](/files/rBi2HAVXYGT4GCGY9J1J)


# Cross-Chain Value Transfer

This section will explain how to enable ERC-20 value transfer between Baobab network and your ServiceChain with the provided test code. You will add KLAY to the operator account and deploy bridge and ERC-20 contracts. Then you will register the contract address on SCN. And you will test an ERC-20 value transferring.

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* We assume that you installed the ServiceChain, and connected the ServiceChain to the Baobab EN by the instructions in [Connecting to Baobab](/content/installation-guide/deployment/service-chain/getting-started/en-scn-connection).
* Clone the repository [servicechain-value-transfer-examples](https://github.com/klaytn/servicechain-value-transfer-examples).
* Install `Node.js` (v14) and `npm` ([How to install](https://nodejs.org/en/download/package-manager/))
  * This example leverages two packages, axios and caver-js, which both support v14.

### ERC-20 Token Transfer (one-step) <a href="#erc-20-token-transfer-onestep" id="erc-20-token-transfer-onestep"></a>

#### Step 1: Add KLAY to the operator accounts. <a href="#step-1-add-klay-to-the-operator-accounts" id="step-1-add-klay-to-the-operator-accounts"></a>

Connect to the SCN and check the account addresses by executing `subbridge.parentOperator` and `subbridge.childOperator`.

```
$ kscn attach --datadir ~/data
> subbridge.childOperator
"0x10221f7f9355017cd0c11444e7eecb99621bacce"
> subbridge.parentOperator
"0x3ce216beeafc62d20547376396e89528e1d778ca"
```

![](/files/pQ2VfWvXPgq6K2KPVWCI)

`subbridge.parentOperator` and `subbridge.childOperator` must have enough KLAY to send a transaction. Note that `subbridge.parentOperator` is an account on the Baobab network, and `subbridge.childOperator` is an account on the ServiceChain network. Create a test account on a [Baobab Wallet](https://baobab.wallet.klaytn.foundation/) and get test KLAY from the faucet. Then send some KLAY to the `parentOperator`. `childOperator` has to get KLAY from the test account generated by `homi` ([Refer to EN Setup and SCN Connection Guide](/content/installation-guide/deployment/service-chain/getting-started/en-scn-connection)).

```
$ kscn account import ~/homi-output/keys_test/testkey1
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {80119c31cdae67c42c8296929bb4f89b2a52cec4}
```

```
$ kscn attach --datadir ~/data
> personal.unlockAccount("80119c31cdae67c42c8296929bb4f89b2a52cec4")
Unlock account 80119c31cdae67c42c8296929bb4f89b2a52cec4
Passphrase:
True
> klay.sendTransaction({from:"80119c31cdae67c42c8296929bb4f89b2a52cec4", to:subbridge.childOperator, value: web3.toPeb(1000, "KLAY")})
"0x84caab84ebf0c4bb4ecf0a7849f1de3e479f1863a95f70c51047a7ca7bc64b33"
```

Check if the operator accounts have enough balance. You can query from the console of the SCN node where the subbridge is installed as follows:

```
> klay.getBalance(subbridge.childOperator)
1e+21
> subbridge.childOperatorBalance
1e+21
> subbridge.parentOperatorBalance
1e+18
```

#### Step 2: Deploy Contracts <a href="#step-2-deploy-contracts" id="step-2-deploy-contracts"></a>

* Connect to the SCN and prepare the node environment for contract deployment. Clone the repository [servicechain-value-transfer-examples](https://github.com/klaytn/servicechain-value-transfer-examples).

![](/files/bJeXLmNJi3ve6WW5uhn1)

In this step, we would deploy both the bridge contract and token contract in the parent as well as the child chain. Token contracts are for mint/transfer test and bridge contracts are used to listen/handle value transfer requests.

```bash
$ git clone https://github.com/klaytn/servicechain-value-transfer-examples
$ cd servicechain-value-transfer-examples
$ npm install
$ cd erc20
```

On a text editor, edit the `bridge_info.json` as below.

* Replace `url` in the `child` section (SCN node on ServiceChain network) with your SCN node IP and the proper port number from `RPC_PORT` in `kscnd.conf`.
* Replace `child.key` with `testkey1` that was generated by `homi`.
* Set `child.operator` to the `subbridge.childOperator` address that we examined in the previous step.
* Replace `url` in the `parent` section (EN node on Baobab network) with your EN node IP and the proper port number from `RPC_PORT` in `kend.conf`.
* Replace `parent.key` with the private key of the test account created from [Baobab Wallet](https://baobab.wallet.klaytn.foundation/) in the previous step.
* Set `parent.operator` as the `subbridge.parentOperator` of the previous step.

```
{
     "child" : {
         "url": "http://192.168.0.1:7551",
         "key": "0x66cb283353589a10866b58d388e9d956e5a9c873a8c78fa4411d460c19c494ea",
         "operator": "0x10221f7f9355017cd0c11444e7eecb99621bacce"
     },
     "parent" : {
         "url": "http://192.168.0.5:8551",
         "key": "0x26f4b5ac42ceabcfd3b23a991fdbfc792d10ce700a99582fdf9185a8f163b790",
         "operator": "0x3ce216beeafc62d20547376396e89528e1d778ca"
     }
 }
```

Perform the token deployment by running the command `node erc20-deploy.js`. This script deploys both the bridge contract and the token contract, and it outputs API usage to initialize bridge pair.

```
$ node erc20-deploy.js
------------------------- erc20-deploy START -------------------------
> info.bridge: 0xEa024d8101E112330f2d7B1a7e7932034E206721
> info.token: 0xbE641028610F628835C36F12bE62d54d74308D70
> info.bridge: 0xA5af6Ffe13b367626B5AdF827DdE7438E3Db4463
> info.token: 0x52F8Fa79Fa6D37b18b7AC8f9Ca835373f3C9270f
> subbridge.registerBridge("0xEa024d8101E112330f2d7B1a7e7932034E206721", "0xA5af6Ffe13b367626B5AdF827DdE7438E3Db4463")
> subbridge.subscribeBridge("0xEa024d8101E112330f2d7B1a7e7932034E206721", "0xA5af6Ffe13b367626B5AdF827DdE7438E3Db4463")
> subbridge.registerToken("0xEa024d8101E112330f2d7B1a7e7932034E206721", "0xA5af6Ffe13b367626B5AdF827DdE7438E3Db4463", "0xbE641028610F628835C36F12bE62d54d74308D70", "0x52F8Fa79Fa6D37b18b7AC8f9Ca835373f3C9270f")
------------------------- erc20-deploy END -------------------------
```

#### Step 3: Token transfer <a href="#step-3-token-transfer" id="step-3-token-transfer"></a>

![](/files/162YwQBdxqgdnKHOPlEI)

Perform token transfer with the command `node erc20-transfer-1step.js`. This one-step token transfer requires modification of an ERC-20 token implementation. If you don't want to modify the token contract or you have a token contract that is already deployed, please refer to [ERC-20 Token Transfer (two-step)](#erc-20-token-transfer-twostep).

```
$ node erc20-transfer-1step.js
------------------------- erc20-transfer-1step START -------------------------
alice balance: 0
requestValueTransfer..
alice balance: 100
------------------------- erc20-transfer-1step END -------------------------
```

If the result is `alice balance: 100`, then it has been executed successfully.

### ERC-20 Token Transfer (two-step) <a href="#erc-20-token-transfer-twostep" id="erc-20-token-transfer-twostep"></a>

Run erc20-transfer-2step.js for the two-step transfer example. With this two-step token transfer example, unmodified ERC-20 token contracts can be used. The two-step transfer consists of two function calls: (1) approve the bridge contract first, and then (2) call the contract function `requestERC20Transfer()`. We do not deploy contracts in this section since we already deployed both bridge and token contracts. You must deploy first if you didn't deploy them. You can deploy the contract using `node erc20-deploy.js`.

```
$ node erc20-transfer-2step.js
> ------------------------- erc20-transfer-2step START -------------------------
> alice balance: 100
> requestValueTransfer..
> alice balance: 200
------------------------- erc20-transfer-2step END -------------------------
```

### KIP-7 Token Transfer via ERC-20 Interface (two-step) <a href="#kip-7-token-transfer-via-erc-20-interface-two-step" id="kip-7-token-transfer-via-erc-20-interface-two-step"></a>

[KIP-7](https://kips.klaytn.foundation/KIPs/kip-7) is a token standard compatible with ERC-20. We can call `requestERC20Transfer()` function to a KIP-7 token contract to transfer KIP-7 tokens between a parent chain and a child chain. In the case of sending KIP-7 tokens via the ERC-20 interface, we call the `approve()` function to allow the bridge to send the tokens on behalf of the transaction sender. Then call the `requestERC20Transfer()` function. The below command deploys the bridge contract and a KIP-7 contract.

```
$ node kip7-deploy.js
> ------------------------- kip7-deploy START -------------------------
> info.bridge: 0x04e929Cd2A08acd28a210369407D8Ca237Edd8FE
> info.token: 0xE0E2fC6C7d1eB069153E0c12a4C87B01586b39e7
> info.bridge: 0xEb502159A4B4E876B1cb423f250DCC0d276e01b6
> info.token: 0xd4f02Ca1d49674056A9ec78fbBDc9e1e97726A4F
> subbridge.registerBridge("0x04e929Cd2A08acd28a210369407D8Ca237Edd8FE", "0xEb502159A4B4E876B1cb423f250DCC0d276e01b6")
> subbridge.subscribeBridge("0x04e929Cd2A08acd28a210369407D8Ca237Edd8FE", "0xEb502159A4B4E876B1cb423f250DCC0d276e01b6")
> subbridge.registerToken("0x04e929Cd2A08acd28a210369407D8Ca237Edd8FE", "0xEb502159A4B4E876B1cb423f250DCC0d276e01b6", "0xE0E2fC6C7d1eB069153E0c12a4C87B01586b39e7", "0xd4f02Ca1d49674056A9ec78fbBDc9e1e97726A4F")
------------------------- kip7-deploy END -------------------------
```

The below command is an example of sending KIP-7 tokens using the ERC-20 interface with `requestERC20Transfer()`.

```
$ node kip7-transfer-2step-erc20-interface.js
> ------------------------- kip7-transfer-2step-erc20-interface START -------------------------
> alice balance: 0
> requestValueTransfer..
> alice balance: 100
> ------------------------- kip7-transfer-2step-erc20-interface END -------------------------
```

Please refer [service-chain-value-transfer-example](https://github.com/klaytn/servicechain-value-transfer-examples) for the other cases.

### Native Support for KIP-7 and KIP-17 (To Be Implemented) <a href="#native-support-for-kip-7-and-kip-17-to-be-implemented" id="native-support-for-kip-7-and-kip-17-to-be-implemented"></a>

Currently, the bridge contract provided by the Klaytn team supports only `requestERC20Transfer()` and `requestERC721Transfer()` for token transfer. The corresponding request functions for KIP-7 and KIP-17 will be supported soon. Before the implementation is done, as you can see above, you can transfer KIP-7 tokens using ERC-20 interfaces.

### Value Transfer for ERC-721, KIP-17, and KLAY <a href="#value-transfer-for-erc721-kip17-and-klay" id="value-transfer-for-erc721-kip17-and-klay"></a>

The workflow for ERC-721, KIP-17, and KLAY is the same as above. [`erc721`](https://github.com/klaytn/servicechain-value-transfer-examples/tree/main/erc721), [`kip17`](https://github.com/klaytn/servicechain-value-transfer-examples/tree/main/kip17), and [`klay`](https://github.com/klaytn/servicechain-value-transfer-examples/tree/main/klay) directories contain corresponding example source code.


# HA(High Availability) for ServiceChain

If only one bridge is used in the ServiceChain, that bridge can become a single point of failure. To solve this, we describe how you can build an HA system with two or more bridges. As shown in the figure below, configure the bridges to be connected in at least two pairs, so that even if there is a problem in one bridge connection, data anchoring and value transfer between chains can still work normally through the other bridge.

![](/files/i9yn7aX1DIMbH9LmuWP3)

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* The main bridge of the EN and the sub bridge of the SCN are connected. If it's not, please refer to [Baobab connection](/content/installation-guide/deployment/service-chain/getting-started/en-scn-connection) to establish the connection.
* This section describes how to add an extra bridge between Baobab and a ServiceChain. In the same way, you can also set up HA by adding another bridge.

### Step 1: Adding another Bridge between EN-SCN <a href="#step-1-adding-another-bridge-between-en-scn" id="step-1-adding-another-bridge-between-en-scn"></a>

In [Connecting to Baobab](/content/installation-guide/deployment/service-chain/getting-started/en-scn-connection), we assume that the EN and the SCN connected by a bridge as EN-01 and SCN-L2-01, respectively. In this section, we will add another bridge between EN-02 and SCN-L2-02. Since it follows the same procedure, we will briefly explain.

![](/files/0vuYBLC5hgxVagoLEtWu)

After building EN-02, set `SC_MAIN_BRIDGE` to 1 in `conf/kend.conf` and restart ken on EN-02.

```console
SC_MAIN_BRIDGE=1
```

Check the KNI information of EN-02 by the following command:

```console
EN-02$ ken attach --datadir ~/data
> mainbridge.nodeInfo.kni
"kni://eb8f21df10c6562...25bae@[::]:50505?discport=0"
```

Log in to SCN-L2-02, and create `main-bridges.json` with the KNI of EN-02. Please make sure that it should be in the JSON array format with a square bracket.

```console
SCN-L2-02$ echo '["kni://eb8f21df10c6562...25bae@192.168.0.5:50505?discport=0"]' > ~/data/main-bridges.json
```

On the shell of SCN-L2-02, edit `kscn-XXXXX-amd64/conf/kscnd.conf` as described below. To connect a bridge, set `SC_SUB_BRIDGE` to 1. `SC_PARENT_CHAIN_ID` is set to Baobob's `chainID` 1001. `SC_ANCHORING_PERIOD` is the parameter that decides the period to send an anchoring transaction to the parent chain. In this example, an anchor transaction is submitted to the parent chain (Baobab) for every 10 child blocks.

```
...
SC_SUB_BRIDGE=1
...
SC_PARENT_CHAIN_ID=1001
...
SC_ANCHORING_PERIOD=10
...
```

If you restart ken on EN-02, a bridge will be connected automatically between the EN-02 and the SCN-L2-02 and data anchoring will start from the point where the connection is made as shown in the figure below.

After adding the bridge between EN-02 and SCN-L2-02, you can now see the connection between the nodes are established as shown in below.

![](/files/z2jeGZqhpI1KiAYoiU1F)

### Step 2: Registering and Subscribing the Bridge Contract <a href="#step-2-registering-and-subscribing-the-bridge-contract" id="step-2-registering-and-subscribing-the-bridge-contract"></a>

As shown in the figure above, the bridge contract is registered only in EN-01 and SCN-L2-01.

Connect to the SCN-L2-02 console and run the APIs for bridge registration, bridge subscription, and token registration. The bridge and token contract were created while deploying the bridge contract with EN-01 and SCN-L2-01 in step 2 of [Cross-Chain Value Transfer](/content/installation-guide/deployment/service-chain/getting-started/value-transfer).

```
$ kscn attach --datadir ~/data
> subbridge.registerBridge("0xCHILD_BRIDGE_ADDR", "0xPARENT_BRIDGE_ADDR")
null
> subbridge.subscribeBridge("0xCHILD_BRIDGE_ADDR", "0xPARENT_BRIDGE_ADDR")
null
> subbridge.registerToken("0xCHILD_BRIDGE_ADDR", "0xPARENT_BRIDGE_ADDR", "0xCHILD_TOKEN_ADDR", "0XPARENT_TOKEN_ADDR")
null
```

![](/files/ZE98tIb9IvrZDFJeIgnr)

In the bridge contract, information about adding an extra bridge should be updated. Write the child operator and parent operator information of the added extra bridge in the `erc20/erc20-addOperator4HA.js` file of [service-chain-value-transfer-example](https://github.com/klaytn/servicechain-value-transfer-examples) and execute `node erc20-addOperator4HA.js`.

```
// register operator
await conf.child.newInstanceBridge.methods.registerOperator("0xCHILD_BRIDGE_ADDR").send({ from: conf.child.sender, gas: 100000000, value: 0 });
await conf.parent.newInstanceBridge.methods.registerOperator("0xPARENT_BRIDGE_ADDR").send({ from: conf.parent.sender, gas: 100000000, value: 0 });
```

When there are multiple bridges, value transfer can be provided more safely by setting a threshold. Value transfer can be enabled only when an operator above the threshold normally requests value transfer. For example, as in the current example, if there are two bridge pairs and the threshold is set to 2, value transfer can be provided only when both are normally requested. That is, even if one bridge is attacked and sends an abnormal request, it can be prevented. The default value of threshold is 1. In the `erc20/erc20-addOperator4HA.js` file of [service-chain-value-transfer-example](https://github.com/klaytn/servicechain-value-transfer-examples), uncomment the code below and set the threshold value and then run it to change the threshold for the bridge contract.

```
// // set threshold
// await conf.child.newInstanceBridge.methods.setOperatorThreshold(0, "your threshold number").send({ from: conf.child.sender, gas: 100000000, value: 0 });
// await conf.parent.newInstanceBridge.methods.setOperatorThreshold(0, "your threshold number").send({ from: conf.parent.sender, gas: 100000000, value: 0 });
```

When registration is completed, a bridge contract is registered in both EN-02 and SCN-L2-02 as shown in the figure below to configure HA.

![](/files/yCPvOZNk2ZG329r8YzC3)

When two or more bridge pairs are connected for HA, data anchoring transactions for the same block occur more than once, and value transfer transactions can also occur multiple times. That is, additional fees are required.


# Nested ServiceChain

This chapter explains how to build ServiceChain networks in a hierarchical structure by adding a new ServiceChain network to the ServiceChain network built in the previous chapter. The ServiceChain network to be added also consists of 4 SCNs in this example. The ServiceChain network constructed in the previous chapter is defined as L2, and the ServiceChain network to be newly constructed is defined as L3. We are going to connect a bridge between L2 and L3 to create a hierarchical structure. The overall structure of the ServiceChain network to be constructed in this chapter is shown in the figure below.

![](/files/EnhA3z7J0hrn5a4jvfEu)

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* Assume that you have progressed to the ServiceChain configuration and Baobab EN described in [Nested ServiceChain](/content/installation-guide/deployment/service-chain/getting-started/nested-sc). So we will briefly explain what was explained in the previous section.
* Assumptions and Limitations
  * One EN can bridge one-to-one to one of the SCNs of the ServiceChain L2. Similarly, one SCN in L2 of the ServiceChain can bridge one-to-one to one of the SCNs in L3.
  * An SCN node can have a main bridge and a sub bridge at the same time. However, the port numbers of the main bridge and the sub bridge must be set differently. (eg main-bridge: 50505, sub-bridge:50506)
  * Not all SCNs in L2 need to be bridged to EN, and likewise SCNs in L3 need not all be bridged to L2. However, for high availability, it is recommended that there are two or more main-bridge and sub-bridge pairs between chains. In this chapter, only one pair will be connected between L2 and L3, and the high availability between L2 and L3 is same to the HA between Baobab and L2.

### Step 1: Create and update Homi data for L3 <a href="#step-1-create-and-update-homi" id="step-1-create-and-update-homi"></a>

As when configuring ServiceChain L2, execute the `homi` command to create scripts and configuration files for building L3. You can run `homi` on any Linux/Mac PC. Baobab's `chainID` is `1001`, and L2's `chainID` was set to `1002` in the previous example, so for convenience, L3's `chainID` is set to `1003`. When operating a blockchain for an actual service, you must register a new `chainID` value at <https://chainlist.defillama.com/> to avoid the `chainID` conflict with other ServiceChains and EVM chains.

```console
$ ./homi setup --gen-type local --cn-num 4 --test-num 1 --servicechain --chainID 1003 --p2p-port 22323 -o homi-output
Created :  homi-output/keys/passwd1
Created :  homi-output/keys/passwd2
Created :  homi-output/keys/passwd3
Created :  homi-output/keys/passwd4
Created :  homi-output/scripts/genesis.json
Created :  homi-output/keys/nodekey1
Created :  homi-output/keys/validator1
Created :  homi-output/keys/nodekey2
Created :  homi-output/keys/validator2
Created :  homi-output/keys/nodekey3
Created :  homi-output/keys/validator3
Created :  homi-output/keys/nodekey4
Created :  homi-output/keys/validator4
Created :  homi-output/scripts/static-nodes.json
Created :  homi-output/keys_test/testkey1
Created :  homi-output/keys_test/keystore1/0xdC7218621513f71d609653d22C39d79d558d9CDC
Created :  homi-output/Klaytn.json
Created :  homi-output/Klaytn_txpool.json
```

![](/files/Nsg4yKUwGBTautju1TnT)

Update `IP address` and `port` information of ServiceChain L3 nodes in `homi-output/scripts/static-nodes.json`.

```json
[
     "kni://358235ccbf97a1f...787f7@192.168.0.21:22323?discport=0&type=cn",
     "kni://14ac4e3d53de5c7...6c91d@192.168.0.22:22323?discport=0&type=cn",
     "kni://5f36a456d93da09...8e216@192.168.0.23:22323?discport=0&type=cn",
     "kni://d62fd0928b9b6e5...6badf@192.168.0.24:22323?discport=0&type=cn"
]
```

Copy `homi-output` to all SCN nodes (SCN-L3-01, SCN-L3-02, SCN-L3-03, SCN-L3-04) of ServiceChain L3.

```console
$ scp -r path/to/homi-output user@192.168.0.21:~/ 
$ scp -r path/to/homi-output user@192.168.0.22:~/ 
$ scp -r path/to/homi-output user@192.168.0.23:~/ 
$ scp -r path/to/homi-output user@192.168.0.24:~/ 
```

Initialize all nodes.

```console
$ kscn --datadir ~/data init ~/homi-output/scripts/genesis.json
$ ls ~/data
keystore	klay		kscn
```

Connect to all SCNs (SCN-L3-01, SCN-L3-02, SCN-L3-03, and SCN-L3-04), copy `static-nodes.json` to the data folder `~/data`, and copy `nodekeys` one by one.

```console
$ cp   ~/homi-output/scripts/static-nodes.json   ~/data/
$ cp   ~/homi-output/keys/nodekey{1..4}   ~/data/klay/nodekey
```

### Step 2: SCN configuration in L3 <a href="#step-2-scn-configuration" id="step-2-scn-configuration"></a>

Edit `conf/kscnd.conf` on all SCNs in ServiceChain L3 as follows: The `PORT` uses 22323, the default port of the ServiceChain. `DATA_DIR` is `~/data`.

```
...
PORT=22323
...
DATA_DIR=~/data
...
```

Run the ServiceChain on all SCN nodes in L3 and check if it works properly.

```console
$ kscnd start
Starting kscnd: OK
$ kscn attach --datadir ~/data
> klay.blockNumber
10
```

### Step 3: Restart after setting L2 main bridge <a href="#step-3-restart-after-setting-l2-main-bridge" id="step-3-restart-after-setting-l2-main-bridge"></a>

Connect to the console of SCN-L2-03 node, (Note: this is not in L3 but in L2) that will act as the main bridge in the ServiceChain L2.

![](/files/ImdOTDnQi6yyhxT0Jwns)

Edit the kscn configuration file `conf/kscnd.conf` of SCN-L2-03 as follows.

```console
SC_MAIN_BRIDGE=1
```

Restart kscnd on SCN-L2-03.

```console
SCN-L2-03$ kscnd stop
SCN-L2-03$ kscnd start
```

### Step 4: Check KNI of Main Bridge Node <a href="#step-4-check-kni-of-main-bridge-node" id="step-4-check-kni-of-main-bridge-node"></a>

Check the KNI information of SCN-L2-03 node. This value will be used to create the `main-bridges.json` file of SCN-L2-03 node, which will be set up the subbridge in the ServiceChain L3.

![](/files/up1OXF7rRAEtlVAJ0Emc)

```console
SCN-L2-03$ kscn   attach   --datadir   ~/data
> mainbridge.nodeInfo.kni
"kni://87989a5a5dcc165...85b16b@[::]:50505?discport=0"
```

### Step 5: Configure L3 sub-bridge <a href="#step-5-configure-l3-sub-bridge" id="step-5-configure-l3-sub-bridge"></a>

Connect to SCN-L3-01 node that will have a subbridge of the ServiceChain L3 (Note: this is not L2). Create `main-bridges.json` under `~/data` folder. Replace \[::] after @ with the IP address of the node you checked in step 4.

```console
SCN-L3-01$ echo '["kni://87989a5a5dcc165...85b16b@192.168.0.13:50505?discport=0"]' > ~/data/main-bridges.json
```

Edit the configuration file `conf/kscnd.conf` of the SCN-L3-01 node with subbridge as follows. set `SC_SUB_BRIDGE`to 1 for activating the bridge connection, and `SC_PARENT_CHAIN_ID` is `1002`, `chainID` of L2, Set `SC_ANCHORING` to 1 to automatically anchor data upon restart. You can also access the SCN-L3-01 shell and turn on data anchoring with the `subbridge.anchoring(true)` command or turn it off with the `subbridge.anchoring(false)` command. `SC_ANCHORING_PERIOD` is a parameter that determines how often anchoring transactions are sent to the parent chain. Set the node to anchor every 10 blocks by specifying a value of 10. Default is 1.

```console
SC_SUB_BRIDGE=1
…
SC_PARENT_CHAIN_ID=1002
…
SC_ANCHORING=1
SC_ANCHORING_PERIOD=10
```

Restart kscnd on SCN-L3-01 after completing the setup.

```console
SCN-L3-01$ kscnd stop
Shutting down kscnd: Killed
SCN-L3-01$ kscnd start
Starting kscnd: OK
```

Check `subbridge.peers.length` to see if SCN-L3-01 is connected to SCN-L2-03, check `subbridge.latestAnchoredBlockNumber` to check the latest anchored block number to see if anchoring is in progress.

```console
SCN-L3-01$ kscn attach --datadir ~/data
> subbridge.peers.length
1
> subbridge.latestAnchoredBlockNumber
5010
```


# Value Transfer between Sibling ServiceChains

This section will explain how to enable value transfer between ServiceChain newtorks. The main features provided by ServiceChain, data anchoring and value transfer, can be used independently. That is, you can use only data anchoring or only value transfer, regardless of whether you use the other feature.

As shown in the figure below, if there are two ServiceChains (chainID 1002 and 1004) connected to Baobab, since each servicechain performs data anchoring with Baobab, data anchoring is not required between each other, only value transfer is required.

To transfer value when there is no bridge between two ServiceChains, first transfer value from the ServiceChain (chainID 1002) to baobab (chainID 1001), and then transfer value from baobab (chainID 1001) to the ServiceChain (chainID 1004) again. This is inefficient than providing value transfer directly from the ServiceChain (chainID 1002) to the ServiceChain (chainID 1004) at once. Therefore, by creating a bridge between ServiceChains directly, we can transfer value efficiently .

![](/files/ezHIfbgziTPM4khJZvcR)

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* We assume that you installed two ServiceChains, Each servicechain is connected to the baobab EN. Refer to [Connecting to Baobab](/content/installation-guide/deployment/service-chain/getting-started/en-scn-connection).
* We also assume that you have experienced value transfer through [Cross-Chain Value Transfer](/content/installation-guide/deployment/service-chain/getting-started/value-transfer).

Repeat [Connecting to Baobab](/content/installation-guide/deployment/service-chain/getting-started/en-scn-connection) as shown in the picture above to additionally install ServiceChain (chianID 1004).

A node can have only one main-bridge and one sub-bridge each. In this example, for convenience of explanation, we are going to connect a bridge to SCN-L2-03 and SCN-L2-07, which are nodes that do not have both main-bridge and sub-bridge yet.

![](/files/jRn05OXFrdH96jZIXIv0)

### Step 1: Check KNI of SCN-L2-03 Node <a href="#step-1-check-kni-of-scn-node" id="step-1-check-kni-of-scn-node"></a>

Take note of SCN-L2-03's KNI which is the information used to connect from an SCN node. This value will be used in the next step when generating `main-bridges.json`

```
SCN-L2-03$ kscn attach --datadir ~/data
> mainbridge.nodeInfo.kni
"kni://...39047242eb86278689...@[::]:50505?discport=0"
```

### Step 2: Create main-bridges.json <a href="#step-2-create-main-bridges-json" id="step-2-create-main-bridges-json"></a>

Log on to an SCN-L2-07 (note: chianID 1004) and create `main-bridges.json` on `~/data`. Replace `[::]` located after `@` letter with EN node's IP address.

```
$ echo '["kni://...39047242eb86278689...@192.168.0.3:50505?discport=0"]' > ~/data/main-bridges.json
```

### Step 3: Configure SCN then Restart <a href="#step-3-configure-scn-then-restart" id="step-3-configure-scn-then-restart"></a>

From the SCN-L2-07 node's shell, edit `kscn-XXXXX-amd64/conf/kscnd.conf`. Since each ServiceChain already anchored with the Baobab EN, data anchoring between sibling is not required. So we set `SC_ANCHORING` to 0.

```
...
SC_SUB_BRIDGE=1
...
SC_PARENT_CHAIN_ID=1002
...
SC_ANCHORING=0
...
```

Restart kscnd on SCN-L2-07 node

```
SCN-L2-07$ kscnd stop
Shutting down kscnd: Killed
SCN-L2-07$ kscnd start
Starting kscnd: OK
```

Check if the SCN-L2-07 is connected to the SCN-L2-03 by checking `subbridge.peers.length`

```
SCN-L2-07$ kscn attach --datadir ~/data
> subbridge.peers.length
1
```

In the case of value transfer, if the information corresponding to chainID 1002 is used as the mainbridge information and the information corresponding to chainID 1004 is set as a subbridge, value transfer is possible between siblings as in [Cross-Chain Value Transfer](/content/installation-guide/deployment/service-chain/getting-started/value-transfer).




---

[Next Page](/llms-full.txt/1)

