# Introduction

Introduction to Ontology

{% hint style="warning" %}
An upgrade of Ontology MainNet at the block height of **13920000** will introduce EVM compatibility and the token decimal upgrade to better support dApps on Ontology. Learn about more details [here](/guides-and-tutorials/evm-and-token-decimals-upgrade).
{% endhint %}

![](/files/-LvPYVF21MatT6d91YuQ)

**Ontology** is a next-gen network of public blockchains, and a distributed, trust-based collaboration platform with integrated support for ledger accounts and smart contracts.

Apart from providing support for the services and applications running on its public chains, Ontology also supports the public chains of the applications that have been developed on it's framework, and collaboration with various protocol groups.

On a more fundamental level, Ontology continues to provide a wide range of universal modules, such as the **Distributed Identity Framework (DID)**, the distributed **Distributed Data Exchange Framework (DDXF)**, and other such distributed trust collaboration packages and modules.

This **documentation center** serves as a guide for developers that are just getting started with `dApp` development with Ontology, apart from providing information on the different components of the Ontology framework.

It also serves as a location to explore and understand all the different resources available that can assist developers with their application development process.

{% hint style="info" %}
Any issues or inaccuracies related to documentation can be shared with us by following [**this**](https://forms.gle/STBynyuEPU1VXAiv9) link.
{% endhint %}


# Discover Ontology

Get acquainted with what we do and offer

## TestNet Tokens

**Ontology TestNet** has been made available for public use to facilitate developers in their `dApp` development process. It can be used to **deploy** and **test run** smart contracts before actually deploying them on the **MainNet**.

{% hint style="info" %}
The deployment and execution process consumes **gas** on the TestNet as well. **TestNet tokens** can be applied for by following this [**link**](https://developer.ont.io/applyOng).
{% endhint %}

## Ontology Trust Ecosystem

![](/files/-LvskNpRTuqSpq4w1urD)

### ONTO

**ONTO** serves as Ontology's primary **digital wallet application**. It currently supports **asset** and **identity management**. Users can expect **claim management** to be a part of **ONTO**'s functionality in future updates.

![](/files/-LvskNpTs7ed-nFRZ5ld)

Features in the current release-

* **Node Staking** - Stake **ONT** and earn **ONG**
* Access to **airdrop events** in **Candy Box**
* Support for assets from multiple platforms such as **ONT**, **NEO**, **ETH** and **Kakao**
* Access to variety of `dApps` in the **dApp** **store**
* Registering a new **ONT ID**

{% hint style="info" %}
To download **ONTO**, please follow this [**link**](https://onto.app/en/download/).
{% endhint %}

### OWallet

![](/files/-LvskNpXRjGwAugM3q0A)

**OWallet** is Ontology's digital wallet desktop client.

Features in the latest release-

* General **wallet management** and **shared wallet** support using **multi signature technology**
* **Account management** and **ledger support**
* Node **stake management**&#x20;
* **ONT ID** - **Identity management**

{% hint style="info" %}
To download **OWallet**, please follow this [**link**](https://github.com/ontio/OWallet/releases/).
{% endhint %}

### Explorer

![](/files/-M9agD6eo5SigalTg7GU)

The public **trust verifier system** from **Ontology** that facilitates monitoring **blockchain activity**.

The **Explorer** can fetch **transaction**, **entity**, **smart contract**, and **block** related data using identifiers such as a **transaction hash**, **ONT ID**, **contract hash**, **block height**, etc.

{% hint style="info" %}
To access the Explorer, please follow this [**link**](https://explorer.ont.io/).
{% endhint %}

## Deploy a Node

There are three different classifications of Ontology nodes:

### **Triones node | Ontology MainNet**

Triones nodes are bookkeeping nodes that participate in the network consensus, and must be voted in by user staking of `ONT`, after applying to be a consensus node. For more incentive and consensus related information, click [here](https://medium.com/ontologynetwork/triones-node-incentive-model-dbcb175f4728).

### **Synchronization node |** Ontology MainNet / Polaris TestNet

Synchronization nodes do not participate in network consensus, and only synchronize the blocks generated by the Triones (bookkeeping) nodes.

### **Single node | Ontology Privatenet / Polaris TestNet**

Ontology supports single node network deployment for development in a private testing environment.

{% hint style="info" %}
Follow [**this**](/ontology-node/node-deployment) link for a guide on how to deploy a node.
{% endhint %}

## Whitepapers

### Introductory White Paper

* [**English**](https://ont.io/wp/Ontology-Introductory-White-Paper-EN.pdf)
* [**Chinese**](https://ont.io/wp/Ontology-Introductory-White-Paper-ZH.pdf)
* [**Korean**](https://ont.io/wp/Ontology-Introductory-White-Paper-KR.pdf) translated by **@Sunghwan Kim**
* [**Dutch**](https://github.com/ontio/documentation/blob/master/nl-NL/Introductory%20White%20Paper%20-%20Dutch%20V1.pdf) translated by **@Mark Westerweel**
* [**Japanese**](https://github.com/ontio/documentation/blob/master/jp_JP/Ontology%20Introductory%20White%20Paper%20JP.pdf) translated by **@Miho Nakauchi**
* [**Spanish**](https://github.com/ontio/documentation/blob/master/es-ES/Introductory%20White%20Paper%20-%20Spanish.pdf) translated by **@Alejandro Garcia**
* [**Turkish**](https://github.com/ontio/documentation/blob/master/tr_TR/Introductory%20White%20Paper%20-%20Turkish.pdf) translated by **@Hakan**

### Technical White Paper

* [**English**](https://github.com/ontio/Documentation/blob/master/Ontology-technology-white-paper-EN.pdf)
* [**Chinese**](https://ont.io/wp/Ontology-technology-white-paper-ZH.pdf)
* [**Korean**](https://ont.io/wp/Ontology-technology-white-paper-KR.pdf) translated by **@Sunghwan Kim**
* [**Dutch**](https://github.com/ontio/documentation/blob/master/nl-NL/Technology%20White%20Paper%20-%20Dutch%20V1.pdf) translated by **@Mark Westerweel**
* [**Japanese**](https://github.com/ontio/documentation/blob/master/jp_JP/Ontology%20Technology%20White%20Paper%20JP.pdf) translated by **@Miho Nakauchi**

### Ecosystem White Paper

* [**English**](https://ont.io/wp/Ontology-Ecosystem-White-Paper-EN.pdf)
* [**Chinese**](https://ont.io/wp/Ontology-Ecosystem-White-Paper-ZH.pdf)
* [**Korean**](https://ont.io/wp/Ontology-Ecosystem-White-Paper-KR.pdf) translated by **@Sunghwan Kim**
* [**Dutch**](https://github.com/ontio/documentation/blob/master/nl-NL/Ecosystem%20White%20Paper%20-%20Dutch%20V1.pdf) translated by **@Mark Westerweel**
* [**Japanese**](https://github.com/ontio/documentation/blob/master/jp_JP/Ontology%20Ecosystem%20White%20Paper-JP.pdf) translated by **@Miho Nakauchi**

### Framework White Paper

* [**English**](https://ont.io/wp/Ontology-Framework-White-Paper-EN-2.0.0.pdf)
* [**Chinese**](https://ont.io/wp/Ontology-Framework-White-Paper-CH-2.0.0.pdf)

### Infrastructure White Paper

* [**English**](https://ont.io/wp/Ontology-Infrastructure-White-Paper-EN-2.0.0.pdf)
* [**Chinese**](https://ont.io/wp/Ontology-Infrastructure-White-Paper-CH-2.0.0.pdf)

### Trust Framework White Paper

* [**English**](https://ont.io/wp/Ontology-Trust-Framework-White-Paper-EN-2.0.0.pdf)
* [**Chinese**](https://ont.io/wp/Ontology-Trust-Framework-White-Paper-CH-2.0.0.pdf)

## Become a Trust Anchor

**Trust anchors** are entities that are a part of Ontology's **distributed identity network** and provide **credential verification** services for other users in the trust network. The role of a trust anchor can be played by anyone from **individuals** to **government institutes** and **organizations**.

## **Submit a dApp**

Ontology appreciates and supports **innovation**. If you have developed a `dApp` or are in the process of developing one and are looking to get it listed on the **community dApp store**, please follow this [**link**](https://oodapp.io/).

## Business Collaboration

Businesses that are looking into blockchain based solutions for their businesses and wish to collaborate with Ontology can get in touch with us [**here**](https://ont.io/contact/).

## Join us

Interested individuals can apply for positions at Ontology by following this [**link**](https://ont.io/join).


# Getting Started

A brief overview of dApp development process

With the `dApp` development process in mind, Ontology has made available a one stop solution in order to assist developers with the initial learning curve and help them get acquainted with `dApp` development.

![Ontology Ecosystem](/files/-Lx-QVsRDWCJlCjx9hGO)

## dApp Fundamentals

`dApp` development can be conveniently understood as a composition of two elements- Smart contract development, and `dAPI` integration.

![](/files/-LvPYVF79kK6pNfMDngY)

* When the `dApp` needs to synchronize and update its data from the chain, it can do so using any of Ontology's`SDKs`, or invoking the `Restful interface` or `RPC interface`. Feel free to check out the details regarding the aforementioned components.

{% hint style="info" %}
The `dApp` back end is not a necessary prerequisite. Certain `dApps` may not need a back end.
{% endhint %}

* The economic model of certain `dApps` requires tokens to implement key functionalities. If that is the case, the user may release tokens as and when needed. `OEP4` functionality in a smart contract, and smart contract sample code might be worth taking a look at. Please follow [this](https://github.com/ontio/OEPs/blob/master/OEPS/OEP-4.mediawiki) link for more details.
* Some special purpose `dApps` might need to store data on the chain. Consider taking a look at the following link for reference.

Generally speaking, the fundamental logic for most `dApps` completes within the scope of smart contracts. The various tools made available from Ontology's side help speed up development and deployment, or in some cases, migrate contracts from other chains onto Ontology. Ontology also provides the standard interface to interact with smart contracts, the `dAPIs`, thereby allowing the users to conveniently use `dApps` without compromising on security. There is no risk of losing the private key. The `dApp` developers have the freedom to solely focus on developing the core logic of the `dApp`.

Follow the link below to refer to the Ontology integration guides to start integrating Ontology into your dApps. There are also development guides available for reference that can be used to start developing applications and smart contracts.

{% content-ref url="/pages/-LwHH-Vbt5tdz4rSlbZY" %}
[Development Guides](/guides-and-tutorials/development-guides)
{% endcontent-ref %}

{% content-ref url="/pages/-LwHH-Vzcz7lJMlHiaOc" %}
[Integration Guides](/guides-and-tutorials/integration-guides)
{% endcontent-ref %}

## Smart Contract Fundamentals

Smart contracts are the fundamental units of **logic** as far their usage within the blockchain ecosystem is concerned. Smart contracts implement functionality by **releasing assets** on **single**, or **multiple chains** based on the business **logic** and **architecture**, when certain fixed and acknowledged **contractual clauses** are fulfilled, or fail to fulfill. Hence, smart contracts can be used to program **complex logic** and functionality without any constraints in terms of industry.

**Ontology** provides **SmartX**, and IDE that facilitates smart contract development using **Python**, **C#** and **JavaScript** (Coming soon). SmartX has an in-built **compiler** and can be used to deploy and test smart contracts on the Ontology **TestNet**, a locally deployed **privatenet**, and the **MainNet**. It also includes **templates** of varying complexity that can be used by developers and enthusiasts alike. Follow the link below for more details on smart contracts.

{% content-ref url="/pages/-LwSbeuwqOKHWuBzmP4E" %}
[Smart Contracts](/ontology-elements/smart-contracts)
{% endcontent-ref %}

## Deploying a Node Locally

Ontology node can be deployed on a local machines to test `dApp` and smart contract logic. The **punica suite** made available by Ontology serves as a **development framework** that includes all the necessary tools. Follow the link below for more details.

{% content-ref url="/pages/-LwHH-WNQowGfyEyTAfR" %}
[dApp Development Framework](/developer-tools/punica-suite)
{% endcontent-ref %}


# Glossary

Key terms and concepts related to Ontology

Here is a list of terminology and concepts that are frequently referred to throughout the documentation. This list can also be used a reference or starting point for users who are getting started with the **Ontology** framework.

Certain related terminology and concepts have been grouped together for ease of understanding and access.

{% hint style="warning" %}
All the term and concept definitions mentioned in this glossary are **limited** within the scope of **Ontology**.
{% endhint %}

## Blockchain

A **ledger-based** network of nodes that function based on **consensus** and **trust.** All the functionality and applications work based on the implementation of the aforementioned characteristics which have been brought about using **complex algorithms** and **cryptography**.

### Node

A node is an instance or the most basic element of a node-based **P2P** network. The same definition applies to blockchain based networks which are **P2P** in nature, generally speaking.

In the context of the Ontology framework, a node is a functioning deployment of the official Go-based implementation of the Ontology core.

### Block

A block is a **ledger unit** where **transaction records** are registered with the corresponding **transaction hashes** with all the data being **open** and **transparent** for all the nodes to be **accessed** and **synchronized** with. Blocks can be referred to using their **height** in the chain. A collection of time synchronized and linked blocks essentially forms the blockchain.

{% hint style="info" %}
Ontology blockchain offers fast blockchain generation rates with a new block being generated about every 6 seconds.
{% endhint %}

### Transaction

In the traditional sense, we understand transactions to be transmission or transfer of financial assets and goods. But in terms of blockchain, any transfer of data or message passing between two nodes of a network or the blockchain is considered a transaction. Each transaction has a transaction hash which can be used to find out details regarding the particular transaction.

## Tokens

**ONT** and **ONG** are Ontology chain's native tokens. &#x20;

### ONT&#x20;

**ONT** is a cryptocurrency token that has gained popularity in the digital currency market. It can be used for general exchange purpose within applications that support it. Feel free to explore the [**dApps**](/glossary#dapp-decentralized-application) in [**ONTO**](/discover#onto). It can be exchanged for other digital currencies, e.g. Bitcoin or Ethereum, or fiat, e.g. USD, over exchange platforms that accept **ONT**, such as [**Binance**](https://www.binance.com) and [**Huobi**](https://www.huobi.com/).

#### Characteristics of ONT:

1. Can be used as a governance token on the Ontology chain for staking.
2. Indivisible. i.e., the smallest unit of the token is limited to unity.

**Token decimal:**

Originally ONT was designed to have **0** decimal.  After the upgrade at the block height of **13920000,** it's updated to **9** decimals.

### ONG

**ONG** is a cryptocurrency much like **ONT**.

#### Characteristics of ONG:

1. **ONG** serves as the gas to perform operations on the Ontology blockchain. Each on-chain action, or a [**transaction**](/glossary#transaction) consumes a small amount of gas fee.
2. Divisible in nature. Smallest unit of ONG can be as small as **0.000000001** (precise to 9 decimal places)

**Token decimal:**

Originally ONG was designed to have **9** decimals. After the upgrade at the block height of **13920000,** it's updated to **18** decimals.

## Smart Contracts

Smart contracts are the fundamental units of logic as far their usage within the blockchain ecosystem is concerned. Smart contracts implement functionality by releasing assets on single, or multiple chains based on the business logic and architecture, when certain fixed and acknowledged contractual clauses are fulfilled, or fail to fulfill. Hence, smart contracts can be used to program complex logic and functionality without any constraints in terms of industry.

{% content-ref url="/pages/-LwHH-VgkPwtRNw6rc4n" %}
[Smart Contract Development](/guides-and-tutorials/development-guides/smart-contract-dev)
{% endcontent-ref %}

## NeoVM

The Neo virtual machine is the engine that processes and runs the **AVM byte code** generated upon compiling Ontology smart contracts. Currently NeoVM supports contracts written using **Python** and **C#**. Feel free to check out Ontology's online IDE [**SmartX**](https://smartx.ont.io) **(access using Google Chrome).**

## Web Assembly Framework - WASM

Just like **NeoVM**, the **Webassembly** framework has the capability of processing portable binary code. Applications can be developed using the Ontology framework and then compiled to optimized binary code which can then be processed by the Webassembly engine. The **WASM** framework currently supports **Rust** and **C++.**

{% content-ref url="/pages/-LwHH-VcK\_YN29pWUdqZ" %}
[WASM Contract](/guides-and-tutorials/development-guides/smart-contract-dev/wasm)
{% endcontent-ref %}

## Digital Wallet

A wallet that allows the user to store and utilize digital currency. Ontology currently has three digital wallets available for usage, [**Cyano**](https://chrome.google.com/webstore/detail/cyano-wallet/dkdedlpgdmmkkfjabffeganieamfklkm?hl=en), a **chrome plugin** wallet, [**ONTO**](https://onto.app/), which is available in the form of a **mobile application**, and [**OWallet**](https://github.com/ontio/OWallet/releases), which is a **desktop wallet**.

## dApp - Decentralized Application

A **decentralized application** implements **features** and the **back end mechanism** of a distributed system or network to achieve its business logic. **Ontology** provides the required **framework** and **SDKs** that facilitate `dApp` development. Follow the link below for a brief introduction to **dApps**.

## Bridge

Ontology [Bridge ](https://bridge.ont.io)supports the exchange between OEP-4 and ORC-20 tokens, and ONG transfer between Ontology addresses (a-) and Etheruem addresses (0x-). In the future, it will support NFT transfers.

Here's a detailed [tutorial](#blockchain).&#x20;

## Explorer

The [Explorer](https://explorer.ont.io/) is Ontology's **trust verifier**. **Block**, **transaction** and **contract** related information can be looked up conveniently using the corresponding identifiers such as the **transaction hash**, **block height**, **contract hash**, etc.

## OEP - Ontology Enhancement Proposals

**OEPs** define new standards for tokens and token protocols based on the Ontology framework and the native tokens **ONT** and **ONG**. Please follow the following link for details on the currently existing **OEP** token protocols.

{% content-ref url="/pages/-LwHH-VVKGoNynb7BAQr" %}
[Token Protocols](/ontology-elements/token-protocols)
{% endcontent-ref %}

## SDKs

An **SDK** is a collection of tools packaged together for easy access to developers. Ontology provides **SDKs** in all major languages to support `dApp` development and the developer community. Follow the link below to refer to the list of **SDKs** made available by **Ontology**.

{% content-ref url="/pages/-LwHH-WcLtHrtlsf2SEj" %}
[SDKs](/developer-tools/sdk)
{% endcontent-ref %}

## dAPI

A blanket term referring to the **APIs** provided by Ontology.

### Restful API

The Restful API is primarily useful for fetching on-chain data by sending individual requests to obtain individual responses. The **Restful API** uses `HTTP` requests and responses to communicate data.

### RPC API

The **Remote Procedure Call (RPC) API** has been implemented based on the `JSON-RPC` protocol. **RPC** uses `HTTP` requests and responses to communicate data.

### Websocket API

The **Websocket API** has been implemented based on the `websocket` protocol, which establishes a bi-directional link between the node and the chain that allows free flow of data.

{% content-ref url="/pages/-LwHH-VnNiKNrmo3qrRd" %}
[Using the dAPI](/guides-and-tutorials/development-guides/dapp-dev/using-dapi)
{% endcontent-ref %}

## Entity

In the context of a **distributed network** an entity could be an **individual**, **institutions** that verify trust based **claims**, **government bodies**, etc. with no limitations. Ontology's **ONT ID** and **DDXF** protocol involve entities that perform various functions to **verify identity** and **exchange resources** in a **credibility** and **trust** based network.

## ONT ID

A **digital identity** that is assigned to **entities** in the **Ontology** network in order to serve as a digital **identifier**.

{% content-ref url="/pages/-LwHH-VWs1EEoLXAyGVg" %}
[ONT ID](/decentralized-identity-and-data/ontid)
{% endcontent-ref %}

## DDXF

An abbreviation of **Distributed Data Exchange Framework** designed by Ontology that allows **tokenization** and exchange of **data** and **claims** via a **marketplace**. Click [**here**](https://github.com/hsutaiyu/DocumentationCentre-1.8/tree/45e5aa8ac6946dcc6764659a6683bcf1b34bd43a/ontology-elements/distributed-data-exchange-framework/README.md) for more details.

{% content-ref url="/pages/-LwHH-VYZ8MHVnXZA5J4" %}
[DDXF](/decentralized-identity-and-data/ddxf)
{% endcontent-ref %}

## Resource

In the context of **DDXF**, a resource is anything that is available on the **marketplace**. A resource can be **physical** in nature such as articles of value, or a **digital copy** of **creative production**, or even **processing power** or **storage** from a **cloud platform**. Activities of **exchange** and **transfer** can be carried out on these resources using the exchange system in place.

## Claim

A claim is a **verifiable credential** or **ownership related assertion** that holds value under specific circumstances in a **trust network** and can be used to represent **information** such as **personal data, digital signatures, attributes** and **ownership status** linked with physical objects, etc.

## Trust Network

A **decentralized** network that involves **entities** that use the **verifiable credentials** and a **trust mechanism** to carry out transactions that can involve **digital tokens** or other **tokenized assets**.

{% content-ref url="/pages/-LwHH-VXh7\_sK0xW\_7CI" %}
[Verifiable Credentials](/decentralized-identity-and-data/ontid/trust-mechanism)
{% endcontent-ref %}

## Nonce

An **arbitrary** number used in **cryptographic communication**. The number can only be used **once**.


# ONT ID

Ontology's decentralized identity framework

**Ontology’s** decentralized identity framework [**ONT ID**](https://ontid.ont.io/) is a decentralized identity framework based on the W3C recommendations for decentralized identifiers and verifiable credentials. It is designed to enable the identification of, and communication between different entities, say individuals, institutions, objects, assets, etc. in both decentralized, as well as centralized networks. It can be used to generate and assign digital, cryptography based identities to different entities such as individuals, institutions, objects, content, and so on.

{% hint style="info" %}
The **ONT ID** framework is not limited to the Ontology chain. The method has been implemented on **Ethereum** and **Binance Smart Chain** as well, extending all the same features to those networks.
{% endhint %}

**ONT ID** provides a self-sovereign system of data authorization and ownership confirmation, thereby granting true control to users. The entire process of ID generation, storage, update, and other critical operations are fully automated and decentralized in nature, thereby allowing the users operating within the ecosystem to have full control and ownership of any data that may be associated with them. Discrete IDs linked across various ecosystems can have multiple delegates and attributes. In the form of verifiable credentials, entities can make and verify claims in terms of data ownership, access rights, and validation. Since any entity that is part of the network can do this, this makes the ONT ID framework a strong contender to build an account mechanism with a high degree of disintermediation.

A few characteristics of **ONT ID**:

* **Decentralization**
* **Self-sovereignty and management**
* **Privacy protection**
* **Security**
* **Ease of use**

![Decentralized ONT ID Framework](/files/-LvskNjufFQvq2OVYjn-)

**Ontology** establishes a decentralized trust model and a distributed trust delivery system through **ONT ID** and a mechanism that uses **verifiable claims**. It uses the zero-knowledge proof protocol to assure the privacy protection of verifiable claims. Through **ONT ID**, Ontology will also incorporate various **authentication service agencies**, and establish **multi-source authentication** to achieve a more complete picture of the respective entity's identity.

{% hint style="info" %}
**Verifiable credentials** allow for the entities that are a part of the trust network to make claims related to their identity **within the scope** of the network, which can then be **verified** for their validity by other entities using a **decentralized trust mechanism**. More details on verifiable credentials and the trust mechanism are available in the next section.
{% endhint %}

In addition to building a trust network that relies on certain central entities, different entities can also build strong trust relationships amongst themselves. Such a **credibility based network** is generated through **mutual authentication** between entities. The higher the number of successful authentications, the higher the credibility of a particular entity. High credibility rating would make the entities more reliable and trustworthy, and authentication from a high credibility entity will equate to higher credibility for the said entity.

{% hint style="info" %}
ONT ID also comes with [**OScore**](https://www.ocredit.io/), a feature that takes on-chain data and behaviour, runs it through an algorithm to determine the reliability and generates credentials. Refer [**here**](/decentralized-identity-and-data/ontid/oscore) for more details.
{% endhint %}

## Salient Features

Some of the main features of the ONT ID framework are listed below.

#### Account Mechanism

An account mechanism that links to wallet addresses and is supported across the Ontology, Ethereum, and Binance Smart Chain ecosystem on the application layer.

#### Cross-chain Identity Aggregation

Linking to the respective contracts deployed on the Ethereum, Ontology and BSC chains to facilitate interoperability in the form of off-chain services such as an Oracle. Also, cross-chain communication between the ONT ID contracts deployed on Ontology and the target chain respectively.

#### Multi-asset Support

Support for assets from multiple chains (Bitcoin, Ethereum, Ontology, etc.)

#### Credit Score

A reputation score assigned to addresses based on transactional data such as asset ownership, transaction history with smart contracts, etc.

{% hint style="info" %}
ONT ID comes with **OScore**, another opt-in feature that users can enable to avail services from platforms that require proof of reliability, such as uncollateralized loans. More details on **OScore** [**here**](/decentralized-identity-and-data/ontid/oscore).
{% endhint %}

## Self-sovereign identity

In the context of **ONT ID,** the term `entity` refers to the following:

* **Individuals -** Individual users of `ONT ID`
* **Legal entities -** Institutions, organizations, enterprises, etc.
* **Objects -** Mobile phones, automobiles, **`IoT`** devices, etc.
* **Content -** Research, creative content, etc.

{% hint style="info" %}
It is important to note that the term **identity** strictly refers to an entity's identity within the Ontology trust network.
{% endhint %}

An **ONT ID** is basically an identifier within the scope of the system. All the entities that are part of the network shall have an **Ontology Identifier (ONT ID)** that identifies and manages it's identity.

{% hint style="success" %}
Users can register their ONT IDs using Ontology's **ONTO** wallet. The download links are available [**here**](https://onto.app/).
{% endhint %}

On the Ontology blockchain, an entity can correspond to multiple individual IDs, and there need not exist any kind of relationship between the said multiple IDs.

The **ONT Auth** and **Signing server** services have been deployed on the Ontology mainnet.

A signing server is a back end service that links **ONT ID** from end user to the account system inside an application. More information on signing servers is available [**here**](/developer-tools/signing-server).

## Workaround for Traditional Systems

It is normal for traditional businesses to have partially, or fully centralized systems. Thus, keeping such scenarios and use cases in mind, Ontology has developed a workaround for centralized systems to integrate and use **ONT ID**.

![Traditional System Workaround](/files/-LvskNjwXMSwK5Idqb1_)

The ID can be handed back to the user by changing the `owner` property of an **ONT ID** from the application to the end user. While conceptually, the **ONT ID** is delegated from the user to the application server host. The terms for this shall be prepared in advance, and the user would then authorize this 'delegation' by accepting the terms.

Technically speaking, the delegated **ONT ID** is able to perform the following tasks:

* Perform actions such as registration and login within the system on behalf of the user,

  and publishing results to the Ontology mainnet.
* Enable the users to take over full control and ownership of their **ONT ID** if they wish to do so.

{% content-ref url="/pages/-MBbu-KzeOtahMJvEgsC" %}
[Broken mention](broken://pages/-MBbu-KzeOtahMJvEgsC)
{% endcontent-ref %}


# Decentralized Identifiers

Decentralized identifiers (DIDs) are a new type of identifiers that enables verifiable, self-sovereign digital identity developed by the W3C Decentralized Identifier Working Group, the specifications for which can be found [**here**](https://www.w3.org/TR/did-core/).&#x20;

We have currently developed DID methods for the following chains.

| Network                                                                                                            | Method       |
| ------------------------------------------------------------------------------------------------------------------ | ------------ |
| [**Ontology**](/decentralized-identity-and-data/ontid/decentralized-identifiers/specification)                     | **did:ont**  |
| [**Ethereum**](/decentralized-identity-and-data/ontid/decentralized-identifiers/method-specification)              | **did:etho** |
| [**Binance Smart Chain**](/decentralized-identity-and-data/ontid/decentralized-identifiers/method-specification-1) | **did:bnb**  |


# Method Specification for Ontology

did:ont

## Abstract

ONT ID is Ontology's decentralized identity framework based on W3C Decentralized Identifiers (DIDs) specification using blockchain and cryptography technology, which can instantly identify and connect people, assets, things, and events. ONT ID offers the features of decentralization, self-management, privacy protection and ease of use. With ONT ID, the privacy and security of users' identity and data are fully protected and users can have complete control over their own identity and data.

The ONT ID specification conforms to [W3C DIDs specification](https://www.w3.org/TR/did-core/) and extends the definition and features on its basis.

## Conformance and Terminology

This specification assumes a fair degree of understanding of [W3C DIDs specification](https://www.w3.org/TR/did-core/).

The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHALL NOT**, **SHOULD**, **SHOULD NOT**, **RECOMMENDED**, **MAY**, and **OPTIONAL** in this document are to be interpreted as described in [IETF RFC 2119](https://www.ietf.org/rfc/rfc2119).

### ONT ID

Used to denote Ontology's blockchain technology and cryptography based decentralized identity framework. Also denotes the decentralized identifier allocated to entities that part of the decentralized Ontology network.

### SHA256

A part of the SHA-2 cryptographic hash family designed by the United States National Security Agency. First published in 2001.

### Base58

A popular encoding scheme commonly used in blockchain technology. Maintains readability while allowing for data compression and encoded verification.

### ABNF

An abbreviation for augmented Backus–Naur form. An ABNF specification is a set of derivation rules.

## ONT ID Format

### ONT ID Syntax

ONT ID is a URI conforming to [IETF RFC 3986](https://www.ietf.org/rfc/rfc3986) and **SHOULD** be generated by each entity itself.

ONT ID is generated in conformity with [W3C DIDs specification](https://www.w3.org/TR/did-core/)。

ONT ID is generated as described in ABNF as follows:

```
ontid        = "did:ont:" ontid-string
ontid-string = 1* idchar
idchar       = 1-9 / A-H / J-N / P-Z / a-k / m
```

"did:ont:" denotes that ONT ID is the decentralized identifier conforming to [W3C DIDs specification](https://www.w3.org/TR/did-core/) that is registered on the Ontology blockchain; `idchar` includes all the characters of the Base58 encoded character set.

`ontid-string` **MUST** be generated using the following method:

1. Generate a 20-byte random number.
2. Append 1-byte tag bits. Append 1-byte tag bits to the generated random number, i.e. data = VER || h;
3. Calculate 4-byte parity bits. Calculate the SHA256 hash of the data twice and take the first 4 bytes as parity bits, i.e. checksum = SHA256(SHA256(data))\[0:4];
4. Encode. Encode the above result to a Base58 encoded value, i.e. ontid-string = Base58(data || checksum).

In the above stated process, || represents the connector that connects the two adjoining byte strings. The recommended value of `VER` is 23.

Below is an example of an ONT ID:

```
did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72
```

### ONT ID URL Syntax

The ONT ID URL syntax follows the DID URL rules defined in [W3C DIDs specification](https://www.w3.org/TR/did-core/).

The ONT ID URL syntax is as follows.

```
ontid-url = "did:ont:"ontid-specific-id
          [ ";" param ] [ "/" path ]
          [ "?" query ] [ "#" fragment ]
```

For more information, see the rules about [param](https://w3c.github.io/did-core/#method-specific-did-url-parameters)，[path](https://w3c.github.io/did-core/#path)，[query](https://w3c.github.io/did-core/#query) and [fragment](https://w3c.github.io/did-core/#fragment) as defined in [W3C DIDs specification](https://www.w3.org/TR/did-core/).

## ONT ID Registration and Deactivation

ONT ID **MUST** be registered on the Ontology blockchain to be activated, and the same ONT ID **MUST NOT** be registered more than once.

Only the owner or delegate of the ONT ID can deactivate it.

When an ONT ID is deactivated, all the related data, including private keys, delegates, properties, and recovery person, will be deleted and only the identifier of the ONT ID will remain on the Ontology blockchain.

Deactivated ONT ID can no longer be used and cannot be reactivated for use.

## ONT ID Document

Each ONT ID will have a corresponding ONT ID Document.

ONT ID Document is a method of serializing ONT ID information expressed using [JSON-LD](https://www.w3.org/TR/json-ld/) as defined in [DID Documents](https://www.w3.org/TR/did-core/#did-documents) of the W3C DIDs specification.

Below is the structure of the ONT ID Document:

```javascript
{
  "@context": ["https://www.w3.org/ns/did/v1", "https://ontid.ont.io/did/v2"],
  "id": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72",
  "publicKey": [{...}],
  "authentication": [{...}],
  "controller": [{...}],
  "recovery": [{...}],
  "service": [{...}],
  "attribute": [{...}],
  "created": [{...}],
  "updated": [{...}],
  "proof": [{...}]
}
```

### Context

ONT ID Documents **MUST** include a `@context` property.

The value of the @context property **MUST** be one or more URIs, where the value of the first URI **MUST** be <https://www.w3.org/ns/did/v1> and the value of the second URI **MUST** be [https://ontid.ont.io/did/v2](https://ontid.ont.io/did/v1). For more information, see [W3C DIDs specification](https://w3c.github.io/did-core/#production-0).

Below is an example:

```javascript
{
  "@context": ["https://www.w3.org/ns/did/v1","https://ontid.ont.io/did/v2"]
}
```

In practice, the terms in the context provided by W3C and Ontology may not be able to meet users' demand. In this case, users need to define the context themselves and can use [embedded context](https://www.w3.org/TR/json-ld/#dfn-embedded-context) for extensions.

For example, users need to append a property to an ONT ID, create the corresponding context for the type value of the property and publish the context to an URI accessible to all users. This is represented in the ONT ID Document as follows:

```javascript
{
  "attribute": [
    {
      "@context": {
        "some-type": "uri-of-the-context",
      },
      "id": "did:ont:some-ont-id#some-attribute",
      "type": "some-type",
      "value": "some-value"
    },
  ]
}
```

### Identifiers

ONT ID Documents **MUST** include an `id` property to specify the ONT ID identifier linked to the Document.

The value of id **MUST** be a valid ONT ID.

```javascript
{
  "id": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72"
}
```

### Public Keys

An ONT ID Document **MUST** include a `publicKey` property to specify a set of public keys linked to that ONT ID.

Public and private key pairs can be used for the self-management, authorization, and verification of ONT ID. An ONT ID can be linked to multiple public and private key pairs and one pair of public and private keys can also be used to manage multiple ONT IDs.

When an ONT ID is registered on the Ontology blockchain, it **SHOULD** be bound to the public key of the ONT ID owner. The owner should keep the matching private key safely.

Every public key object linked to the `publicKey` property **SHOULD** include the fields `id`, `type`, `controller` and `encoding`.

Each linked public key has its own identifier specified using the field `id`. Each bound public key is numbered starting from 1 according to the linking order. The format of "id" is

```
did:ont:some-ont-id#keys-{index}
```

`{index}` is the serial number of the public key.

Bound public keys can be revoked. Revoked public keys cannot be reactivated, but still possess the original serial numbers.

The value of the `type` field represents the corresponding cryptographic algorithm of the public key. Ontology supports an array of international standard cryptographic algorithms, such as **ECDSA**, **EdDSA** and **SM2** signature.

The value of the `controller` field, which identifies the controller of the corresponding private key, **MUST** be a valid ONT ID, denoting that the public key is controlled by this ONT ID.

The `encoding` key is the corresponding encoding format of the public key and the value is the result value of the public key using that encoding format. The encoding formats that Ontology supports include `publicKeyPem`, `publicKeyHex` and `publicKeybase58`.

Below is a specific example of the `PublicKey` property:

```javascript
{
  "publicKey": [
    {
      "id": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72#keys-1",
      "type": "EcdsaSecp256r1VerificationKey2019",
      "controller": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72",
      "publicKeyHex": "02a545599850544b4c0a222d594be5d59cf298f5a3fd90bff1c8caa095205901f2"
    }
  ]
}
```

### Authentication

ONT ID Documents use an **OPTIONAL** `authentication` property to specify verification methods.

ONT ID allows users to add the authentication property to denote that the holder of that ONT ID has authorized a set of verification methods for identification.

This part is derived from [W3C DIDs specification](https://www.w3.org/TR/did-core/#services).

Below is an example:

```javascript
{
  ...
  "authentication": [
    "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72#keys-1",
    {
      "id": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72#keys-2",
      "type": "EEcdsaSecp256r1VerificationKey2019",
      "controller": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72",
      "publicKeyBaseHex": "03a835599850544b4c0a222d594be5d59cf298f5a3fd90bff1c8caa064523745f3"
    }
  ],
}
```

### Delegation

In an ONT ID Document, an **OPTIONAL** `controller` property is used to designate a delegate.

An ONT ID can be delegated to and controlled by other ONT IDs. A designated delegate **MUST** be specified when registering the ONT ID on the Ontology blockchain.

The ONT ID of the delegate has the authorization of registration and deactivation of the delegated ONT ID, and can modify properties `publicKey` and `authentication` of the delegated ONT ID.

It is worth noting that an ONT ID Document can assign `controller` without designating `authentication`.

The ONT ID of the delegate **MUST** be self-managed.

The delegate can be an ONT ID or a management group consisted of multiple ONT IDs. The management group can set complex threshold control logic to meet different security requirements. For example, set a management group of n ONT IDs and specify that the group can only perform an operation with the signature of at least m(<=n) ONT IDs. The setting is expressed as follows:

```javascript
{
  "threshold": "m",
  "members": ["ID1", "ID2", ... , "IDn"]
}
```

Then, define the control logic of the recursive combination, meaning that group members can either be ONT ID, or a nested management group, as shown below:

```javascript
{
  "threshold": "m1",
  "members": [
    "ID1",
    {
      "threshold": "m2",
      "members": ["ID2", ...]
    },
    ...
  ]
}
```

Below is a specific example representing that either `did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72`, or `did:ont:AXjJnU1TJViks4KUGQruiXwkKznwVpz7Z9` and `did:ont:AKwf6DvKFSBxhsmhjGCvJgaxHvCEQmpZZv` together can act as a delegate.

```javascript
"controller:" [
  {
    "threshold": 1,
    "members": [
      "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72",
      {
        "threshold": 2,
        "members": ["did:ont:AXjJnU1TJViks4KUGQruiXwkKznwVpz7Z9", "did:ont:AKwf6DvKFSBxhsmhjGCvJgaxHvCEQmpZZv"]
      },
      ...
    ]
  }
]，
```

When performing operations on the delegated ONT ID, the ONT ID of the delegate(s) need to provide valid digital signatures conforming to the control logic.

The delegate can link public keys for the delegated ONT ID by setting `publicKey` property, and can also set `authentication` property, thus turning it into self-management mode. A self-managed ONT ID cannot be switched to delegated mode.

### Recovery Mechanism

ONT ID Documents use an **OPTIONAL** `recovery` property to designate the recovery party.

In the event that the owner of the ONT ID lost the private key, the recovery person can help the owner to reset the private key. The recovery person can add and delete public keys from `authentication` of that ONT ID and update the settings for the recovery person.

Only a self-managed ONT ID can designate other ONT IDs as the recovery party.

The recovery person can use the method of group management, the rules of which are the same as the management group of delegate. The recovery person needs to provide valid digital signatures in conformity with the control logic to perform any operation.

Below is a specific example, representing that either one of `ont:AXjJnU1TJViks4KUGQruiXwkKznwVpz7Z9` and `did:ont:AKwf6DvKFSBxhsmhjGCvJgaxHvCEQmpZZv` can perform the recovery operation.

```javascript
"recovery": [
  {
    "threshold": 1,
    "members": ["did:ont:AXjJnU1TJViks4KUGQruiXwkKznwVpz7Z9", "did:ont:AKwf6DvKFSBxhsmhjGCvJgaxHvCEQmpZZv"]
  }
]，
```

### Service Information

ONT ID Documents use an **optional** `service` to specify the service property.

ONT ID allows entities to add services to specify the information of a service related to that ONT ID, including types of service and service endpoints.

This part is derived from [W3C DIDs specification](https://www.w3.org/TR/did-core/#services).

Below is a specific example:

```javascript
{
  ...
  "service": [
    {
      "id": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72#some-service",
      "type": "SomeServiceType",
      "serviceEndpint": "Some URL"
    }
  ]
}
```

### Additional Properties

ONT ID Documents include an **OPTIONAL** `attribute` to link a set of ONT ID-related properties.

The owner or delegate of the ONT ID can add, modify or delete additional properties.

Each property **MUST** include the fields of `key`, `value`, and `type`.

* `key` as the identifier of the property,
* `type` denotes the type of the property,
* `value` is the content of the property.

`attribute` can include 100 properties at most.

There is a limit on the length of the property's field. The maximum lengths of the `key`, `value`, and `type` fields are 80 bytes, 64 bytes, and 512K bytes respectively.

For example, `did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72` contains a property:

```
key: "some-attribute"
type: "some-type"
value: "some-value"
```

The property is then expressed in the ONT ID Document as follows:

```javascript
{
  "id": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72",
  "attribute" : [
    {
      "key": "some-attribute",
      "type": "some-type",
      "value": "some-value"
    },
  ]
}
```

The types and the specific content of the additional properties are not covered in this specification and should be defined by the application layer.

Below is a specific example:

```javascript
{
  "attribute": [
    {
      "key": "age",
      "type": "number",
      "value": 18
    },
  ]
}
```

### Created

ONT ID Documents **SHOULD** include a `created` property to specify the time of creation.

This part is derived from [W3C DIDs specification](https://www.w3.org/TR/did-core/#services).

Below is a specific example:

```javascript
{
  "created": "2018-06-30T12:00:00Z"
}
```

### Updated

ONT ID Documents **SHOULD** include an `updated` property to specify a timestamp of the most recent change.

This part is derived from [W3C DIDs specification](https://www.w3.org/TR/did-core/#services).

Below is a specific example:

```javascript
{
  "updated": "2019-06-30T12:00:00Z"
}
```

### Proof of Integrity

ONT ID Documents **MAY** include a `proof` property to prove the integrity of that ONT ID Document.

This part is derived from [W3C DIDs specification](https://www.w3.org/TR/did-core/#services).

Below is a specific example:

```javascript
{
  "proof": {
    "type": "LinkedDataSignature2015",
    "created": "2020-02-02T02:02:02Z",
    "creator": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72#keys-1",
    "signatureValue": "QNB13Y7Q9...1tzjn4w=="
  }
}
```

As of now, the `proof` property has not been fully implemented yet.

## Appendix

Below is a simple example of an ONT ID Document:

```javascript
{
  "@context": ["https://www.w3.org/ns/did/v1", "https://ontid.ont.io/did/v2"],
  "id": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72",
  "publicKey": [
    {
      "id": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72#keys-1",
      "type": "EcdsaSecp256r1VerificationKey2019",
      "controller": "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72",
      "publicKeyHex": "02a545599850544b4c0a222d594be5d59cf298f5a3fd90bff1c8caa095205901f2"
    }
  ],
    "authentication": [
    "did:ont:AderzAExYf7yiuHicVLKmooY51i2Cdzg72#keys-1"
  ]
}
```

## References

**\[W3C-DID]**\
Decentralized Identifiers (DIDs) v1.0. W3C. Mar 2020. Working Draft. URL: <https://www.w3.org/TR/did-core/>

**\[RFC2119]**\
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: <https://tools.ietf.org/html/rfc2119>

**\[RFC3986]**\
Uniform Resource Identifier (URI): Generic Syntax. T. Berners-Lee; R. Fielding; L. Masinter. IETF. JANUARY 2005. Standards Track. URL: <https://tools.ietf.org/html/rfc3986>

**\[BASE58]**\
The Base58 Encoding Scheme. Manu Sporny. IETF. December 2019. Internet-Draft. URL: <https://tools.ietf.org/html/draft-msporny-base58>

## ONT ID Contract API

Please follow the link below for the contract API reference.

{% content-ref url="/pages/-M8n8zm\_vUsaCbzbhLxX" %}
[ONT ID Contract API](/developer-tools/api/ont-id-contract-api)
{% endcontent-ref %}


# Method Specification for Ethereum

did:etho

## Summary

Decentralized identifiers (DIDs) are a new type of identifiers that enables verifiable, self-sovereign digital identity. This ETHO DID method specification describes a new DID method, that is, ETHO DID and defines how Ethereum blockchain stores ETHO DIDs and their corresponding DID documents, and how to do CRUD operations on ETHO DID documents.

This specification conforms to the requirements specified in the [DIDs specification](https://www.w3.org/TR/did-core/) currently published by the W3C Credentials Community Group.

{% hint style="info" %}
The full **DID ETHO** specification can be found [**here**](https://github.com/ontology-tech/DID-solidity/blob/etho-did/doc/en/DID-spec-ethereum.md).
{% endhint %}

## ETHO DID Method Name

The name-string that shall identify this DID method is: `etho`.

A DID that uses this method **MUST** begin with the following prefix: `did:etho`. Per this DID specification, this string **MUST** be in lowercase.

The remainder of the DID, after the prefix, is its namespace-specific identifier specified below.

#### Namespace Specific Identifier (NSI)

The namespace specific identifier is defined by the following ABNF:

```
etho-did   = "did:etho:" etho-specific-idstring
etho-specific-idstring = 40*40HEXDIG
```

#### Example

A valid ETHO DID might be:

```
did:etho:1f4B9d871fed2dEcb2670A80237F7253DB5766De
```

## CRUD Operations

The following section outlines the DID operations for the `did:etho` method.

ETHO DIDs reside on the Ethereum blockchain, and are managed via the ETHO DID management smart contract.

For the sake of convenience, we refer to the ETHO DID management smart contract as 'the registry'.

### Create (Register)

The ETHO DID creation is implicit and it does not require any interaction with the registry.

A subject who has an Ethereum address need not invoke any method and will automatically own an ETHO DID that concatenating "did:etho:" and the Ethereum address without a `0x` prefix.

For instance, Alice, who has an Ethereum address `0x1f4B9d871fed2dEcb2670A80237F7253DB5766De`, will automatically become the subject of `did:etho:1f4B9d871fed2dEcb2670A80237F7253DB5766De`.

### Read (Resolve)

ETHO DID's associated DID document can be looked up by invoking the `getDocument` method of the registry.

To ensure the smart contract invocation result is trustworthy, the client could query a certain number of nodes and then compare the return values or deploy its own node.

The interface method for resolving an ETHO DID document is defined as follows:

```
get_document()
```

Besides this full-fledged resolver, the ETHO blockchain provides other simple resolvers, such as fetching the `authentication` property.

#### **ETHO DID Document Example**

```
{
  "@context": ["https://www.w3.org/ns/did/v1"],
  "id": "did:etho:1f4B9d871fed2dEcb2670A80237F7253DB5766De",
  "publicKey": [
	{
	  "id": "did:etho:1f4B9d871fed2dEcb2670A80237F7253DB5766De#keys-1",
	  "type": "EcdsaSecp256k1RecoveryMethod2020",
	  "controller": "did:etho:1f4B9d871fed2dEcb2670A80237F7253DB5766De",
	  "ethereumAddress": "0x1f4B9d871fed2dEcb2670A80237F7253DB5766De"
	}
  ],
  "authentication": [
	"did:etho:1f4B9d871fed2dEcb2670A80237F7253DB5766De#keys-1"
  ]
}
```

### Update (Replace)

To update an ETHO DID document, the corresponding ETHO DID subject just need to invoke relevant functions.

For instance, the ETHO DID subject can invoke the `addController` method to add a delegate which has the authorization to insert a new verification method into the `authentication` property of the delegated ETHO DID.

The interface method for adding a delegate ETHO DID is defined as follows:

```
add_controller(delegate: String)
```

The `delegate` parameter specifies the to-be-added controller.

Similarly, the interface method for removing a delegate ETHO DID is defined as follows:

```
remove_controller(delegate: String)
```

The `delegate` parameter specifies the to-be-removed controller.

Here we do not provide the full list of supported update methods and will provide specific documentation which lists all of the related APIs.

### Delete (Revoke)

To delete (or deactivate) an ETHO DID, it suffices to remove all the verification methods from its associated DID document and set a flag in the registry to indicate the DID is deactivated. In this case, there is no authentication method that can be used to authenticate the holder's identity.

The interface method for deactivating an ETHO DID document is defined as follows:

```
deactivate_did(did: String)
```

The `did` parameter specifies the to-be-deactivated ETHO DID.

More importantly, the deletion of an ETHO DID implies this DID cannot be registered or reactivated again.

## Security and Privacy Considerations

There are several securities and privacy considerations that implementers would want to take into consideration when implementing this specification.

The current ETHO DID implementation does not allow an Ethereum address to have multiple ETHO DIDs, and if the ETHO DID is deactivated, the corresponding Ethereum address cannot access the deactivated ETHO DID. Hence, it loses all capability to perform operations on that ETHO DID.

Since the delegates specified in the `controller` property can change the value of `authentication`, they have the same privileges as the DID subject.

ETHO DID documents should be limited to verification methods and service endpoints, and should not store any personal information.

## Reference Implementations

The reference implementation is available here: <https://github.com/ontology-tech/DID-solidity/tree/etho-did>

## References

\[1]. Ethereum github, <https://github.com/ethereum>

\[2]. W3C Decentralized Identifiers (DIDs) v1.0, <https://w3c.github.io/did-core/>


# Method Specification for BSC

did:bnb

## Summary

Decentralized identifiers (DIDs) are a new type of identifiers that enables verifiable, self-sovereign digital identity. This Binance DID method specification describes a new DID method, that is, Binance DID and defines how Binance Smart Chain stores Binance DIDs and their corresponding DID documents, and how to do CRUD operations on Binance DID documents.

This specification conforms to the requirements specified in the [DIDs specification](https://www.w3.org/TR/did-core/) currently published by the W3C Credentials Community Group.

{% hint style="info" %}
The full Binance DID specification can be found [**here**](https://github.com/ontology-tech/DID-solidity/blob/binance-did/doc/en/DID-spec-binance.md).
{% endhint %}

## Binance DID Method Name

The namestring that shall identify this DID method is: `bnb`.

A DID that uses this method **MUST** begin with the following prefix: `did:bnb`. Per this DID specification, this string **MUST** be in lowercase.

The remainder of the DID, after the prefix, is its namespace-specific identifier specified below.

#### Namespace Specific Identifier (NSI)

The namespace specific identifier is defined by the following ABNF:

```
bnb-did   = "did:bnb:" bnb-specific-idstring
bnb-specific-idstring = 40*40HEXDIG
```

#### Example

A valid Binance DID might be:

```
did:bnb:1f4B9d871fed2dEcb2670A80237F7253DB5766De
```

## CRUD Operations

The following section outlines the DID operations for the `did:bnb` method.

Binance DIDs reside on the Binance blockchain, and are managed via the Binance DID management smart contract.

For the sake of convenience, we refer to the Binance DID management smart contract as 'the registry'.

### Create (Register)

The Binance DID creation is implicit and it does not reqiure any interaction with the registry.

A subject who has a Binance address need not invoke any method and will automatically own a Binance DID that concatenating "did:bnb:" and the Binance address without a `0x` prefix.

For instance, Alice, who has a Binance address `0x1f4B9d871fed2dEcb2670A80237F7253DB5766De`, will automatically become the subject of `did:bnb:1f4B9d871fed2dEcb2670A80237F7253DB5766De`.

### Read (Resolve)

Binance DID's associated DID document can be looked up by invoking the `getDocument` method of the registry.

To ensure the smart contract invocation result is trustworthy, the client could query a certain number of nodes and then compare the return values or deploy its own node.

The interface method for resolving a Binance DID document is defined as follows:

```
get_document()
```

Besides this full-fledged resolver, the Binance Smart Chain provides other simple resolvers, such as fetching the `authentication` property.

**Binance DID Document Example**

```
{
  "@context": ["https://www.w3.org/ns/did/v1"],
  "id": "did:bnb:1f4B9d871fed2dEcb2670A80237F7253DB5766De",
  "publicKey": [
	{
	  "id": "did:bnb:1f4B9d871fed2dEcb2670A80237F7253DB5766De#keys-1",
	  "type": "EcdsaSecp256k1VerificationKey2019",
	  "controller": "did:bnb:1f4B9d871fed2dEcb2670A80237F7253DB5766De",
	  "publicKeyHex": "0xfbf38de9fb40edcdab412094d24fa39a314f3d3f52f5860e2509c32522eda30161fe70dfc9f90434d64bd976ede4f112d4f2d8e34d28fe48281663219d2ddac6"
	}
  ],
  "authentication": [
	"did:bnb:1f4B9d871fed2dEcb2670A80237F7253DB5766De#keys-1"
  ]
}
```

### Update (Replace)

To update a Binance DID document, the corresponding Binance DID subject just need to invoke relevant functions.

For instance, the Binance DID subject can invoke the `addController` method to add a delegate which has the authorization to insert a new verification method into the `authentication` property of the delegated Binance DID.

The interface method for adding a delegate Binance DID is defined as follows:

```
add_controller(delegate: String)
```

The `delegate` parameter specifies the to-be-added controller.

Similarly, the interface method for removing a delegate Binance DID is defined as follows:

```
remove_controller(delegate: String)
```

The `delegate` parameter specifies the to-be-removed controller.

Here we do not provide the full list of supported update methods and will provide specific documentation which lists all of the related APIs.

### Delete (Revoke)

To delete (or deactivate) a Binance DID, it suffices to remove all the verification methods from its associated DID document and set a flag in the registry to indicate the DID is deactivated. In this case, there is no authentication method that can be used to authenticate the holder's identity.

The interface method for deactivating a Binance DID document is defined as follows:

```
deactivate_did(did: String)
```

The `did` parameter specifies the to-be-deactivated Binance DID.

More importantly, the deletion of a Binance DID implies this DID cannot be registered or reactivated again.

## Security and Privacy Considerations

There are several securities and privacy considerations that implementers would want to take into consideration when implementing this specification.

The current Binance DID implementation does not allow a Binance address to have multiple Binance DIDs, and if the Binance DID is deactivated, the corresponding Binance address cannot access the deactivated Binance DID. Hence, it loses all capability to perform operations on that Binance DID.

Since the delegates specified in the `controller` property can change the value of `authentication`, they have the same privileges as the DID subject.

Binance DID documents should be limited to verification methods and service endpoints, and should not store any personal information.

## Reference Implementations

The reference implementation is available here: <https://github.com/ontology-tech/DID-solidity/tree/binance-did>

## References

\[1]. Binance Smart Chain, <https://www.binance.org/en/smartChain>

\[2]. W3C Decentralized Identifiers (DIDs) v1.0, <https://w3c.github.io/did-core/>


# Verifiable Credentials

Outline of the trust model

The foundation of Ontology's trust mechanism is based on a **verifiable credential system**.

Entities issue credentials and sell them to their customers, and this gives rise to a verification scenario. The closed loop of issuing requests, creation, and consumption of credentials is what makes up the trust mechanism. All entities can make and verify claims.

![Credential Workflow](/files/-LvskNrkwyRj08alaH6S)

Here are the parties that are involved in the process.

* **Credential owner -** has an `ONT ID`. This entity acquires a verifiable credential issued by another entity that is referred to as the `credential issuer`. This entity is able to manipulate credentials, with [**anonymous credential**](https://github.com/ont-project/documentation/blob/master/prod-doc/en/ontid/framework/credential-store/anonymous-credential.md) technology, and provide the credentials to the `credential consumer`. Thus, they play the role of a **trust seller.**
* **Credential issuer -**  has an `ONT ID`. This entity issues credentials to endorse a target entity for certain qualifications or credentials. The category of **credential Issuer** includes **trust anchors,** i.e. the partners or **entities** that provide **authentication services** in the Ontology ecosystem. Trust anchors could be **government agencies**, **universities**, **banks**, third-party **authentication services**, **bio-metric technology companies**, etc. Credential issuers provide multi-dimensional authentication for entities that are part of the trust network. The authentication process and result are recorded on the Ontology blockchain with data privacy protection. Credential issuers provide a **standardized and credible** authentication method for **credential consumers to verify** the credentials. Credential issuers **play the role of a** trust endorser.
* **Credential consumers -**  accept the user's verifiable credentials and initiate the credential verification process for the respective credentials. This includes many different scenarios, e.g., the employers who need to verify the interviewer's identity information/degree/industry skills. They the play the role of **trust buyer.**

## Verifiable Credential Protocol

![Credential Verification Process](/files/-MFE7OmE2UZGvCjacCdf)

It is clear from the workflow illustrated above that the process involves three major actions:

1. Credential **request**
2. Credential **issue**
3. Credential **verification**

The **issuing** process involves two parties, the credential issuer and the entity that owns the **ONT ID.**

A **verifiable credential** includes the contents of the credential (that would vary depending upon the system), the digital signatures, and blockchain attestation records. Some of the records are:

* **Credential ID:** Unique identifier for credentials
* **Credential content:** Specific credentials or information, for instance a degree certificate
* **Credential metadata-**
  * **Created time:** Timestamp for when the credential was created
  * **Issuer:** **ONT ID** of the issuer
  * **Recipient:** **ONT ID** of the recipient party
  * **Expiration time:** **UNIX** timestamp for the credential automatically expires
  * **Revocation mechanism:** Use the **revocation list** or record the revocation information directly in the **attestation contract**
* **Blockchain proof**
* **Signature-**
  * Public key of the **issuer**
  * Signature **value**

{% hint style="info" %}
A verifiable credential template for an employee's salary certificate is available [**here**](https://github.com/ontio/ontology-DID/blob/master/claimtemplate/en/employment_certification_claimtemplate.md).
{% endhint %}

{% hint style="warning" %}
For centralized **ONT ID** systems, the first step in the workflow might differ in terms of the request that is sent to the credential issuer, since the owners will have **delegated** another body with access to their **ONT ID** and credentials. The request may not necessarily be sent by the owner themselves. The delegated body may also initiate and authorize credentials.
{% endhint %}

### Issuance process

The issuance process involves four main steps:

1. The **ONT ID** owner initiates the process by sending a request to the credential issuer.&#x20;
2. The **credential issuer** generates a verifiable credential and transmits it to the **recipient** using a secure method. The credential is **encrypted** using the recipient's **public key**.
3. The **owner** (or the delegate) signs the credential and sends it back to the **credential issuer**.
4. The **credential issuer** finally completes the signing process and sets the status of the credential to **attested***.* Next, the credential is transmitted to both the **Ontology** **blockchain** and the **owner** (or the delegate).

This whole process basically covers **Steps 1\~3** in the **credential workflow** illustrated above.

### Credential verification

There are **three** major actions involved in verifying a credential and they correspond to the **steps 4 \~ 5** in the workflow illustrated above.

* **Verifying** whether the credential is in the blockchain
* Verifying the **signature** and whether it has **expired**
* Checking whether the credential has been **revoked**

#### Blockchain record verification

It is necessary to verify whether the record of the verifiable credential is present on the blockchain. In case the node is not fully synchronized with the Ontology blockchain, merkle proof can be used to verify the verifiable credential transaction.

**Merkle proof** consists of an array, and each element contains two data items, **direction** and **hash**.

* **Direction:** Represents branch of the merkle tree the particular array element is in. There are two possible values.
* **Hash:** Represents hash value of the element data.

The algorithm using which the merkle proof is verified is as follows:

1. Check if **transaction** is included in **block** indexed by `proof.BlockHeight`. If not, return `false`.
2. Execute `p <- GetBlockHash(proof.BlockHeight)`.
3. For each **element** in `proof.Nodes`, update `p` as
   * **if** `e.Direction == "Left"`, `p <- H(e.TargetHash, p)`;
   * **else**, `p <- H(p, e.TargetHash)`.
4. Return `true` if `p` equals to the `proof.MerkleRoot`. Otherwise, return `false`.

   In addition, it is also necessary to verify the status of the credential attestation. This can be carried out by calling the inquiry interface `GetStatus()` of the attestation contract with the address `proof.ContractAddr`. If the status is `not attested`, an error would be returned.

#### Signature verification and Expiration time

When verifying the signature, the **public key ID** needs to be used to fetch the public key **value** and its current **status**. The verification algorithm is then called to carry out the verification process.

The format of the pubic key ID is `<ONTID>#keys-<number>`

The public key ID is used to call the ONT ID smart contract method that queries the status of the public key. `GetPublicKeyStatus(byte[] ontId, byte[] pkId)`

The response contains the following:

* **publicKey**: Public key value (hex)
* **status**: Two possible values: `InUse`, `Revoked`

Three possible results of signature verification:

* Signature is **invalid**
* Signature is **valid**
* Signature is **valid** and the public key is `revoked`

Next, the expiration time can be verified by checking whether the **timeout** period has expired.

#### Revoking verification

Currently there are two revocation modes available- **revocation list** and **revocation inquiry** interface.

Here's an example of the revocation list credential **request**. It contains the `URL` of the list.

```yaml
"clm-rev": {
    "type": "RevocationList",
    "url": "https://example.com/rev/1234"
}
```

Using the revocation inquiry interface as an example, if the revocation information is placed in the **attestation contract**, when calling the inquiry interface `GetStatus` of attest contract, revocation verification will return `success` if and only if the returned status field is `attested`. It will return `fail` if the status field is `attest has been revoked`.

```javascript
"clm-rev": {
       "type": "AttestContract",
       "addr": "8055b362904715fd84536e754868f4c8d27ca3f6"
}
```

The revocation list mainly includes the **unique identifier** and the **revocation time** of the revoked verifiable credential.

## Format of a verifiable credential

We will use an extension of the [JSON Web Token](https://tools.ietf.org/html/rfc7519) format to build the structure of the **credential** which is transferred between the **issuer** and the **recipient**.

The fundamental structure of the token consists of three parts:

* **Header**
* **Payload**
* **Signature**

{% hint style="info" %}
The standard **JWT** attributes are used to a great extent while in certain special cases **custom** attributes are defined.
{% endhint %}

The standard **JWT** format is augmented by appending the blockchain proof at the end, a typical verifiable credential has the following layout: `header.payload.signature.blockchain_proof`

{% hint style="info" %}
The `blockchain_proof` is not required in some cases, and is thus optional.
{% endhint %}

#### Header

The `header` defines the format, the signature scheme, and the ID of the public key used to verify the signature on the credential.

```yaml
{
    "alg": "ES256",
    "typ": "JWT-X",
    "kid": "did:ont:TRAtosUZHNSiLhzBdHacyxMX4Bg3cjWy3r#keys-1"
}
```

| Attribute | Description                                                                                                                                                                                  |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **alg**   | Specifies the signature scheme to use. A list of supported values can be found [here](https://github.com/ontio/ontology-DID/blob/master/docs/en/claim_spec.md##_Supported_signature_schemes) |
| **typ**   | <p>"JWT": blockchain proof is not contained in the credential</p><p>"JWT-X" : blockchain proof is a part of the credential</p>                                                               |

The credential ID, credential content and the metadata are packaged into a `JSON` object which then acts as the payload. It will use some of the registered credential names specified in the `JWT` specification, such as `jti`, `iss`, `sub`, `iat`, `exp`.

```yaml
{
    "ver": "0.7.0",
    "iss": "did:ont:TRAtosUZHNSiLhzBdHacyxMX4Bg3cjWy3r",
    "sub": "did:ont:SI59Js0zpNSiPOzBdB5cyxu80BO3cjGT70",
    "iat": 1525465044,
    "exp": 1530735444,
    "jti": "4d9546fdf2eb94a364208fa65a9996b03ba0ca4ab2f56d106dac92e891b6f7fc",
    "@context": "https://example.com/template/v1",
    "clm": {
        "Name": "Bob Dylan",
        "Age": "22"
    },
    "clm-rev": { 
        "typ": "AttestContract",
        "addr": "8055b362904715fd84536e754868f4c8d27ca3f6"
    }
}
```

| Attribute    | Description                                                                                                    |
| ------------ | -------------------------------------------------------------------------------------------------------------- |
| **ver**      | Specifies the version of the credential specification being followed                                           |
| **iss**      | ONT ID of the issuer                                                                                           |
| **sub**      | ONT ID of the recipient                                                                                        |
| **iat**      | UNIX timestamp when the credential was created                                                                 |
| **exp**      | UNIX timestamp of when the credential expires automatically                                                    |
| **jti**      | Unique identifier of the verifiable credential                                                                 |
| **@context** | URI of the credential content definition document that defines each field and the respective values explicitly |
| **clm**      | Object that contains the credential content                                                                    |
| **clm-rev**  | Object that defines the revocation mechanism the credential uses                                               |

{% hint style="info" %}
A list of the supported revocation mechanisms has been listed [**here**](https://github.com/ontio/ontology-DID/blob/master/docs/en/claim_spec.md#C-Revocation).
{% endhint %}

Next, to issue a credential, a JSON object needs to be constructed that would contain the credential ID, the content, and the metadata. The JSON object can then be **serialized** using the standard serialization method. One of the issuer's private keys is then used to **sign** the binary data of the payload and the header.

After serialization, the **payload** would look something like-

```yaml
{
   "ver": "0.7.0",
   "iss": "did:ont:TRAtosUZHNSiLhzBdHacyxMX4Bg3cjWy3r",
   "sub": "did:ont:SI59Js0zpNSiPOzBdB5cyxu80BO3cjGT70",
   "iat": 1525465044,
   "exp": 1530735444,
   "jti": "4d9546fdf2eb94a364208fa65a9996b03ba0ca4ab2f56d106dac92e891b6f7fc",
   "@context": "https://example.com/template/v1",
   "clm": {
      "Name": "Bob Dylan",
      "Age": "22"
   },
   "clm-rev": {
      "Type": "Contract",
      "Addr": "8055b362904715fd84536e754868f4c8d27ca3f6"
   }
}
```

#### Signature

After the header and payload of the request are constructed the signature is computed according to the **JWS standard**. Full description of the standard can be found in the [RF 7515 Section 5.1](https://tools.ietf.org/html/rfc7515#section-5.1) of the IETF documentation.

The process is as follows:

1. Calculate the signing input as serialization of the header and payload according to **JWS** specification.

```
sig := sign(Base64URL(header) || . || Base64URL(payload))
```

1. Compute the **JWS** signature using the specified method for the particular **signature scheme** being used for the signing input.
2. Encode the signature.

```
signature := Base64URL(sig)
```

#### Blockchain Proof

The general format of a proof object is as follows:

```yaml
{
    "Type": "MerkleProof",
    "TxnHash": "c89e76ee58ae6ad99cfab829d3bf5bd7e5b9af3e5b38713c9d76ef2dcba2c8e0",
    "ContractAddr": "8055b362904715fd84536e754868f4c8d27ca3f6",
    "BlockHeight": 10,
    "MerkleRoot": "bfc2ac895685fbb01e22c61462f15f2a6e3544835731a43ae0cba82255a9f904",
    "Nodes": [{
        "Direction": "Right",
        "TargetHash": "2fa49b6440104c2de900699d31506845d244cc0c8c36a2fffb019ee7c0c6e2f6"
    }, {
        "Direction": "Left",
        "TargetHash": "fc4990f9758a310e054d166da842dab1ecd15ad9f8f0122ec71946f20ae964a4"
    }]
}
```

| Attribute        | Description                                                                        |
| ---------------- | ---------------------------------------------------------------------------------- |
| **Type**         | Fixed value 'Merkleproof'                                                          |
| **TxnHash**      | Hash of the transaction that attests the credential ID in the attestation contract |
| **ContractAddr** | Address of the attestation contract                                                |
| **BlockHeight**  | Height of the block that contains the attestation contract                         |
| **MerkleRoot**   | Root of the merkle tree when the tree size equals the **BlockHeight**              |
| **Nodes**        | Inclusion proof of block in the merkle tree                                        |

The **MerkleProof** is encoded in the following manner:

```
BASE64URL(MerkleProof)
```

Hence, a complete **verifiable credential** is created. The final structure is as follows:

```
BASE64URL(Header) || '.' || BASE64URL(Payload) || '.' || BASE64URL(Signature)  '.' || BASE64URL(MerkleProof)
```

### Attestation Contract

The **attestation contract** of a verifiable credential provides **attestation service** and **record availability** information, that is, whether or not it has been revoked.

The available methods are described below:

* **Commit Attestation**

```
bool Commit(byte[] claimId, byte[] committerOntId, byte[] ownerOntId);
```

In the attestation contract, `claimID` serves as the unique identifier for a credential. It is the first parameter; The `committerOntId` is the **ONT ID** of the **attester**. The `ownerOntId` is the **ONT ID** of the owner.

This method will return `true` if and only if the credential is **not attested**, and the method has been called by the **committer**; Otherwise, it will return `false`.

After the attestation is done, the status of the credential will be updated to **attested.**

* **Revoke credential**

```
bool Revoke(byte[] claimId, byte[] revokerOntId);
```

This method will return `true` if and only if the credential is **attested**, and the `revokerOntId` is the same as the **attester's** `ONT ID`; Otherwise, it will return `false`.

* **Attestation Inquiry method**

```
byte[] GetStatus(byte[] claimId);
```

This method returns the status of the credential. The response contains **two parts** of information:

* Status: `Not attested` , `Attested`, `Attest has been revoked`;
* **ONT ID** of the **attester**.

## Signature schemes

Currently supported signature schemes are:

| Scheme      | Encryption Technology |
| ----------- | --------------------- |
| **ES224**   | ECDSA with SHA224     |
| **ES256**   | ECDSA with SHA256     |
| **ES384**   | ECDSA with SHA384     |
| **ES512**   | ECDSA with SHA512     |
| **ES3-224** | ECDSA with SHA3 224   |
| **ES3-256** | ECDSA with SHA3 256   |
| **ES3-384** | ECDSA with SHA3 384   |
| **ES3-512** | ECDSA with SHA3 512   |
| **ER160**   | ECDSA with RIPEMD160  |
| **SM**      | SM2 with SM3          |
| **EDS512**  | EDDSA with SHA256     |


# Anonymous Credentials

A zero knowledge proof signature algorithm

The anonymous credential scheme is a part of the Ontology Crypto library that provides several cryptography related utilities for the Ontology network. The main features provided by the crypto library basically revolve around digital signature. It provides general APIs for processing digital signatures and keys.&#x20;

## Abstract

There are **three** parties involved in an anonymous credential scheme, namely the **issuer**, the **user** (prover), and the **verifier**.

The issuer provides a certificate to the user. This certificate contains a list of the user's attributes and the issuer's signature (using BBS+signature). This protocol is formally called **credential issuance protocol.** The user who is in possession of the credentials can selectively disclose some parts to a verifier. This protocol is formally called **credential presentation protocol**.

## Background

### BBS + Signature

**Setup:** Groups $$G\_1, G\_2$$ and $$G\_t\ .$$ Pairing function $$e: G\_1\*G\_2 \rightarrow G\_t \ ,$$ where $$G\_1$$ and $$G\_2$$ are both of order $$p$$.\
Common parameters:&#x20;

* $$g\_1$$ is the generator of $$G\_1$$&#x20;
* $$g\_2$$ is the generator of $$G\_2$$&#x20;
* $$H\_{rand} \ , h\_1, ... \ , h\_L$$ are elements from $$G\_1$$&#x20;

**KeyGen:** A sample $$x$$ from uniform distribution on $$Z\_p$$, output $$s\_k = x \ ,\ p\_k = {g\_2}^x$$&#x20;

**Sign**$$(s\_k, m\_1, ... \ , m\_L)$$**:** Two random numbers $$E$$ and $$s$$are selected from $$Z\_p$$.  First$$B = g\_1 \* {H\_{Rand}}^s \* ({h\_1}^{m\_1} \* ... \* {h\_L}^{m\_L})$$ is calculated, and then  $$A = B^{1/(E+x)}$$ is computed. The signature is $$(A, B, E, s)$$&#x20;

**Verify** $$(p\_k, m\_1, ...\ ,m\_L, sig)$$**:** Decode $$sig$$ as $$(A, B, E, s)$$ , and check if  $$e(A, {g\_2}^E \* p\_k) == e(B, g\_2)$$ and whether $$B == g\_1 \* {H\_{Rand}}^s \* ({h\_1}^{m\_1} \* ... \* {h\_L}^{m\_L})$$&#x20;

### &#x20;Non-Interactive Proof of Knowledge (PoK) protocol

In this subsection, we will look at an example of the non-interactive proof of knowledge protocol which proves that the public key is generated as specified in the BBS + signature scheme. That is, $$\pi = PoK { x : w = {g\_2}^x \ && \ \_g\_2 = \_{g\_1}^x}$$. This means the prover proves the knowledge of $$x$$ such that $${g\_2}^x = w$$ and $$\_g\_2 = \_{g\_1}^x$$. It is assumed that $$w, g\_2, \_g\_1, \_g\_2$$ are all public.

The protocol that we provide is a standard sigma protocol. It involves three steps, which are commit, challenge, and response. Sigma protocol is an interactive protocol and can be modified to be a non-interactive zero knowledge proof by using the well-known [**Fiat-Shamir heuristic**](https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic). The proof $$\pi = { C, S}.$$&#x20;

#### 1. Commitment (Prover)

```go
r = rand(Zp)

t1 = g2^r

t2 = _g1^r
```

#### 2. Proof (Prover)

```go
P = t1 || t2 || g2 || _g1 || w || _g2    //join them together in binary format

C = hash_to_int(P)                       //C is challenge

S = (r + C * x) mod p                    //response to verifier
```

#### 3. Verify (Verifier)

```go
_t1 = g2^S * w^(-c)

_t2 = _g1^S * _g2^(-c)

_P = _t1 || _t2 || g2 || _g1 || w || _g2

_C = hash_to_int(_P)

// use C to compare with _C, which was calculated just now
if C == _C {
    return true
} else {
    return false
} 
```

## Setup of the Issuer's key pair

Given an array of the attribute names `AttributeNames`, the issuer's key pair is generated in the following manner:

1. Select a random element $$x$$ from $$Z\_p$$, and compute $$w = {g\_2}^x$$
2. Select a random element $$\_g\_1$$from $$G\_1$$, and compute $$\_g\_2 = \_{g\_1}^x$$
3. Generate non-interactive proof of knowledge  $$\pi = PoK{ x: w = {g\_2}^x  \ && \ {\_g\_1}^x  } = (C, S)$$\
   Here,&#x20;

* `r` **:** A random element $$r$$ from $$Z\_p$$&#x20;
* `t1` **:** Computed as $$t\_1 = {g\_2}^r$$&#x20;
* `t2` **:** Computed as $$t\_2 = \_{g\_1}^r$$&#x20;
* `C` **:**  $$C = H(t\_1 || t\_2 || g\_2 || \_g\_1||w||\_g\_2)$$&#x20;
* `s` **:** $$S = (r + C \*x) \bmod p$$&#x20;

4\. Select an array of elements from $$G\_1$$ from `AttributeNames`. Next, calculate `HAttrs[i] = random(G1)` for each attribute in `AttributeNames`

5\. Select two random elements `HRand` And `HSk` from $$G\_1$$ \
6\. The issuer's public key is set to  `ipk = (w, _g1, _g2, π, HAttrs, AttributeNames, HRand, HSk)`, and the private key is set to `isk = x`\
7\. Return `isk` and `ipk`

The following are the reference data structures for the issuer's key pair:

```go
type IssuerSecretKey struct {
    x BigNum
}
```

```go
type IssuerPublicKey struct {
    AttributeNames []string
    HAttrs         []G1Point // one G1-element for one attribute
    HRand          G1Point   // a random G1 point 
    HSk            G1Point   // a random G1 point to encode user's secret key 

    w              G2Point   // element from G2  
    _g1            G1Point   // point of G1
    _g2            G1Point   // point of G1

    //PoK{x: w = g2^x && _g2 = _g1^x}
    C              BigNum    // challenge
    S              BigNum    // response
}
```

## Issuance Protocol

Issuance protocol is an interactive protocol that consists of the following steps:

1. The issuer sends a random [**nonce**](/glossary#nonce) to the user
2. The user creates a **credential request** using the public key, the secret, and the nonce. This request consists of a commitment to the user secret (can be seen as a public key), and a zero-knowledge proof of the knowledge of the user secret key. The user **sends** this credential request to the issuer
3. The **issuer verifies** the credential request by verifying the zero-knowledge proof \
   If the request is **valid**, the issuer issues a credential to the user by **signing** the **commitment** to the secret key along with the attribute values and then **sends** the credential back to the user
4. The **user verifies** the issuer's **signature** and **stores** the **credential** that consists of the signature value, a randomness used to create the signature, the user secret, and the attribute values

The following diagram represents the interaction between the user and the issuer:

![](/files/-LwvEMQ37aHmlV1xWV0j)

* The credential request CredRequest contains a commitment $$N\_{ym}$$ to user's secret key which is of the form $${H\_{Sk}}^{sk}$$ and a `zk-PoK` of the $$N\_{ym}$$&#x20;
* Credential contains the `BBS+signature` on the attributes and the `Nym`

### Generating credential request

The user generates the credential request using the attribute values and the nonce as input. The process is as follows:

1. Select a random element **sk** from $$Z\_p$$ as the user's master secret key
2. Calculate $$N\_{ym} = {H\_{Sk}}^{sk}$$ , which represents the commitment to the user's master secret
3. Generate the zero knowledge proof $$\pi = PoK { sk : N\_{ym} = {H\_{Sk}}^{sk} } = (C, S)$$ in the following manner-

* Select a random element $$sk$$ from $$Z\_p$$ which acts as the user's master secret
* Calculate $$t\_1 = {H\_{Sk}}^r$$&#x20;
* Compute the challenge $$C = H(t\_1 || H\_{Sk}||N\_{ym}||nonce)$$&#x20;
* Compute the response $$S = (r+C\*sk) \bmod p$$&#x20;

The data structure of the credential request is of the following manner:

```go
type CredRequest struct {
   Nym             G1Point  //commitment to user's master secret
   IssuerNonce     BigNum   //nonce 
   Attrs           []BigNum //user's attributes

   //PoK that Nym is constructed as in the issuance protocol
   // i.e. PoK{(sk): HSk^sk = Nym }
   C               BigNum   //challenge in Sigma-protocol
   S               BigNum   //response in Sigma-protocol
}
```

### Issuing Credential

After receiving the credential request from the user, the issuer verifies $$\pi = (C, S)$$ and generates credentials for the user. The credential is generated using the issuer's private key $$i\_{sk}$$ as follows:

1. Select two random elements $$e, s$$ from $$Z\_p$$&#x20;
2. Calculate  `B = g1 · HRand^s · Nym · MulAll(HAttrs[i]^(Attrs[i]))`
3. Compute  `A = B^(1/(e+x))`
4. Return the credential $$(A, B, e, s, Attrs)$$&#x20;

The data structure of a credential looks something like:

```go
type Credential struct {
   A               G1Point
   B               G1Point
   e               BigNum
   s               BigNum
   Attrs           []BigNum
}
```

## Presentation Protocol

In the presentation protocol, the prover tries to convince the verifier that they are aware of some secret input, such that some hypothetical predicate is true. A typical example of a predicate is that the prover is in possession of an anonymous credential, and they can selectively disclose certain attributes while hiding the other attributes.

The information that is available to the user is:

* User's secret key $$sk$$ and its commitment $$N\_{ym}$$&#x20;
* Attribute values $$attrs = (a\_1, ...\  , a\_L)$$&#x20;
* BBS +signature `(A, B, e, s)`
* Extra input&#x20;
  * (D, I) **:** Attribute predicate, describes what attributes will be disclosed. If `D[j] == 1`, `I[j] = attrs[j] = aj`, else `I[j] = null`

### Proving Algorithm

The selective disclosure proof can be generated in the following manner:

1. Randomize A **:** Select a random element $$r\_1$$ from $${Z\_p}^\*$$, and compute $$A' = A^{r\_1}$$&#x20;
2. Calculate $$\_A = A'^{(−e)} \ · B^{r\_1},\ r\_3 = 1/r\_1$$&#x20;
3. Select an element $$r\_2$$ from $$Z\_p$$&#x20;
4. Calculate $$B' = B^{r\_1} · {H\_{Rand}}^{-r\_2}$$ , $$s' = s - r\_2 · r\_3$$&#x20;
5. Generate zero knowledge proof $$\pi = PoK{ (s\_k, {a\_i}\_{hidden}, e, r\_2, r\_3, s') }$$ such that-

* &#x20;`_A/B' = A'^(-e) · HRand^r2`
* `g1 · MulAll(hi^ai_reveal) = (B')^r3 · HRand^(-s') · HSk^(-sk) ·MulAll(hi^(-ai_hidden))`, where `hi` stands for `HAttrs[i]`

&#x20;        The proof can be generated as follows:

```yaml
r_ai : for i belongs to _D(attributes not disclosed), means D[i]==0
r_e : random from Zp
r_r2 : random from Zp
r_r3 : random from Zp
r_s' : random from Zp
r_sk : random from Zp
E : E = HSk^r_sk
t1 : t1 = A'^r_e · HRand^r_r2
t2 : t2 = (B')^r_r3 · HRand^r_s' · E^(-1) · MulAll(hi^r_ai)
c' : c' = H(A', _A, B', nym, t1, t2, g1, HRand, h1, ... , hL, w)
nonce : nonce, with τ bit length, randomly generated again
c : c = H(nonce, c', (D, I))
s_sk : s_sk = r_sk + c · sk
s_ai : s_ai = r_ai - c · ai, for i belongs to _D(attributes not disclosed)
s_e : s_e = r_e - c · e
s_r2 : s_r2 = r_r2 + c · r2
s_r3 : s_r3 = r_r3 + c · r3
s_s' : s_s' = r_s' - c · s'
π : {c, s_sk, {s_ai}, s_e, s_r2, s_r3, s_s', nonce}, i belong to _D
```

The output is $$(A', \_A, d, n\_{ym}, \pi)$$ where $$\pi = {c, s\_{sk}, s\_{ai}, s\_e, s\_{r\_2}, s\_{r\_3}, {s\_s}', nonce}$$&#x20;

Here is the reference data structure for the zero knowledge proof:

```go
type Proof struct {
    APrime             G1Point  // randomized credential signature values
    ABar               G1Point  // randomized credential signature values
    BPrime             G1Point  // randomized credential signature values

    /* challenge in sigma-protocol */
    ProofC             BigNum
    /* response in sigma-protocol */
    ProofSSk           BigNum
    ProofSE            BigNum
    ProofSR2           BigNum
    ProofSR3           BigNum
    ProofSSPrime       BigNum
    ProofSAttrs        []BigNum

    Nonce              BigNum   // nonce used to avoid replay attack
    Nym                G1Point  
}
```

### Verification

The verifier has the following input information available:

* &#x20;$$(A', \_A, B', n\_{ym}, \pi)$$ : from the signer
* &#x20;$${c, s\_{sk}, {s\_{a\_i}}, s\_e, s\_{r\_2}, s\_{r\_3}, {s\_s}', nonce}$$ : obtained by parsing $$\pi$$&#x20;

The verification algorithm proceeds as in the following manner:

1. Check if `A' != 1` in G1; if false, return `false`.
2. Check if `e(A', w) == e(_A, g2)`; if false, return `false`. This is $$z\_k-PoK$$ for **A**.
3. Parse $$\pi$$ : `{c, s_sk, {s_ai}, s_e, s_r2, s_r3, s_s', nonce} <- π`; if failed, return `false`.
4. &#x20;\~ $$t\_1$$ : `~t1 = A'^s_e · HRand^s_r2 · (_A/B')^(-c)` . This is $$z\_k-PoK$$ for **e**, **r2***.*
5. &#x20;\~ $$t\_2$$ : `(B')^s_r3 · HRand^s_s' · HSk^(-s_sk) · MulAll(hi^(-s_ai)) · (g1·MulAll(hi^ai))^(-c)`

   * the `i` above, first `MulAll( )` belongs to `_D`, where `D[i]==0(false)`
   * the `i` above, second `MulAll( )` belongs to `D`, where `D[i]==1(true)`

   This is $$Z\_k - PoK$$ for **r3**, **s'**, **gsk**, **ai** of \_D.
6. &#x20;$$c'$$ : `c' = H(nonce, H(A', _A, B', nym, ~t1, ~t2, g1, HRand, h1, ... , hL, w), (D, I))`
7. Check if `c == c'` : if false, return `false`. Otherwise return `true`.


# ONT Login

ONT Login is a decentralized universal authentication login component that helps developers shield the details of authentication implementation, and can quickly bring a Web 3.0 secure login experience to enterprises and services.&#x20;

Currently users need to log into your service via ONT ID. In future it will be possible to log in with wallet addresses directly.

## Characteristics

* **Trustless:** Authenticate user data securely with decentralized identities.
* **Self-Sovereign**: Users store identity information locally and authorize services to access when needed.&#x20;
* **Passwordless:** Users do not need to set up and memorize complex passwords.
* **End-user Convenient**: One-time personal information validation can be used in multiple services anytime.
* **Multi-Language**: Provide front-end JavaScript SDK, and back-end Golang/Java SDK for quick integration.
* **High Compatibility:** Support traditional Internet services and different blockchain systems including public chains and alliance chains. Support DID protocols on multiple chains and various signature schemes.
* **Secure Process:** challenge-response authentication mode and digital signature technology ensure the security of the authentication process.

## Increase User Engagement

The username and password authentication mechanism requires users to spend considerable efforts to maintain passwords to avoid vulnerabilities. Authentication is usually the first step that a digital property designs for a user engagement journey. Active users also need to log in once in a while when they interact with your product. Hence, authentication plays a crucial part in user engagement.

ONT Login provides a smoother user login experience. Users can verify their email, phone number, etc. once in the decentralized identity wallet to obtain relevant credentials. When logging into a service, users can directly show the credentials, eliminating the cumbersome steps of multiple verification.

## Enhance User Data Security

Many people today have multiple digital identities for various scenarios, and tend to use the same password for different services. If one service is compromised, then accesses to other services are also at risk. At the same time, many services require users to bind personal information such as phone number and social accounts. Users do not know if the information is kept safe.&#x20;

ONT Login adopts the challenge-response authentication method based on decentralized identity and digital signature technology. The authentication mechanism also helps avoid the risk of server collision with the database, and improve user information security. Furthermore, only users have direct access to their personal data, which largely decreases the chance of data breach.&#x20;

## Decrease Data Management Effort

With ONT Login you are free from the annoyance of handling sensitive user personal information,  usernames and passwords, hence save the effort of dealing with related regulations.&#x20;


# Scenarios

Systems ranging from traditional networks to decentralized ecosystems including public chains and alliance chains can be empowered by ONT Login to achieve passwordless authentication.&#x20;

Businesses with below scenarios can especially benefit from the convenience and security:&#x20;

* Services targeting privacy-sensitive users
* Services targeting web 3.0 users
* Systems tired of password management
* Services with KYC requirements


# Protocol Specification

![](/files/-MieMTE7k3zqkjThcblU)

The following parties are involved in the authentication process:

* **Server**: The service relying party that provides services to the user.&#x20;
* **Client**: A website or app with which the user sends authentication request to the server.&#x20;
* **Decentralized Identity Management Wallet ("Wallet")**:  A tool for the user to manage their decentralized identities and verifiable credentials.&#x20;

{% hint style="info" %}
ONT Login requires end users to have an ONT ID.  Please refer to this [doc ](https://docs.ont.io/decentralized-identity-and-data/ontid)on how to generate ONT IDs for your users.
{% endhint %}

The whole process can be divided in the following 5 steps. We will go through each step in detail in later sections.

1. [Authentication Request](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#authentication-request): The user starts the login process. The client sends the authentication request to the server.
2. [Authentication Challenge](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#authentication-challenge): Received the request, the server generates and sends a challenge to the client, which can specify the required VC if needed.
3. [Signature (and Authorization)](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#signature-and-authorization): The client receives the challenge, then requests signature and VP from the wallet with the challenge.
4. [Authentication Response](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#authentication-response): The client receives the signature and VP from the wallet, and send the response message to the server.
5. [Verification](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#verification): The server verifies if the response is correct. If yes, the server parses the VP to obtain the information authorized by the user.&#x20;

## Authentication Request

The client sends the authentication request to the server as the example below:

```javascript
{
 "ver": "1.0",
 "type": "ClientHello",
 "action": "1",
 "ClientChanllege": {},
}
```

| Property          | Type              | Description                                                                                                              |
| ----------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `ver`             | `1.0`             | Protocol version, current version is 1.0.                                                                                |
| `type`            | `ClinetHello`     | Message type, the type of an authentication request is `ClinetHello`.                                                    |
| `action`          | `integer`         | "0" = authentication; "1" = authentication and authorization. You  can define other actions based on the business logic. |
| `ClientChanllege` | `ClientChanllege` | Optional, challenge sent from the the client, required for mutual authentication.                                        |

## Authentication Challenge

Upon receiving the request from the client, the server generates and a nonce and stores it.&#x20;

The server returns the following message to the client:&#x20;

````javascript
{
"ver": "1.0",
 "type": "ServerHello",
 "nonce": "128-uuid",
 "server": {
   "name": "",
   "icon": "",
   "url": "",
   "did": "",
   "verificationMethod": "",
 },
 "chain": ["ONT","BSC"],
 "alg": ["ES256","Ed25519"],
 "VCFilters": [
   {"type": "DegreeCredential", "trustRoot":["did:ont:bob",""], "required": true},
   {"type": "IdentityCredential", "trustRoot":["did:ont:bob",""], "express":["",""], "required": false},
 ],
 "serverProof":{},
}
```
````

| Property      | Type                                                                                                                             | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ver`         | `1.0`                                                                                                                            | Protocol version, current version is 1.0.                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `type`        | `ServerHello`                                                                                                                    | Message type, the type of an authentication challenge is `ServerHello`.                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `nonce`       | `string`                                                                                                                         | A one-time random number or 128-digit UUID generated by the server used as a challenge. It's necessary to ensure it's randomly and recently generated.                                                                                                                                                                                                                                                                                                                                             |
| `server`      | [`server`](https://github.com/ontology-tech/ontlogin-js-sdk/blob/98947f653c830f4871774238d613570aff014ddc/src/type.ts#L41)       | <p>A message from the server including strings:</p><p>- name: string, name of the server, required.</p><p>- icon: string, image URL of the server's icon or the serialized icon, optional.</p><p>- <code>url</code>: string, server URL, required.</p><p>- <code>did</code>: string, server DID, required for mutual authentication.</p><p>- <code>verificationMethod</code>: string, serial number of the verification method in the server DID Document, required for mutual authentication.</p> |
| `VCFilters`   | [`VCFilter`](https://github.com/ontology-tech/ontlogin-js-sdk/blob/98947f653c830f4871774238d613570aff014ddc/src/type.ts#L29)`[]` | <p>Types of VC required from the server, including at least 3 fields below: </p><p>- <code>type</code>: string, type of VC </p><p>- <code>trustRoot</code>: VC issuer</p><p>- <code>required</code>: boolean, if the VC is required</p><p>The <code>express</code> string is used to specify requirements in a zero knowledge proof, e.g. age 18 and above.</p>                                                                                                                                    |
| `chain`       | `string[]`                                                                                                                       | Denoting chains supported by the server with native token symbols, e.g. “ONT” represents Ontology chain.                                                                                                                                                                                                                                                                                                                                                                                           |
| `alg`         | `string[]`                                                                                                                       | Signature schemes supported by the server.                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `serverProof` | `object`                                                                                                                         | Optional, server's response to the challenge sent from the client for mutual authentication.                                                                                                                                                                                                                                                                                                                                                                                                       |

## **Signature (and Authorization)**

When the client receives the authentication challenge , a message is generated accordingly for the wallet to sign. The wallet signs the message containing the challenge, and generates the VP for VC required by the server.

An example of message to be signed:

```javascript
{
  "type": "ClientResponse",
  "server": {
    "name":,
    "url":, 
    "did":
  },
  "nonce": "128-uuid",
  "did": "did:ont:alice",
  "created":1630425600,
}
```

| Property  | Type             | Description                                                                                                                                                                                     |
| --------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`    | `ClientResponse` | Message type, the type of a message to be signed is `ClientResponse`.                                                                                                                           |
| `server`  | `object`         | <p>Server details including 3 strings: </p><p>- <code>name</code>:  string, server name</p><p>- <code>url</code>: string, server URL</p><p>- <code>did</code>: string, server DID, optional</p> |
| `nonce`   | `string`         | The nonce included in the challenge.                                                                                                                                                            |
| `did`     | `string`         | User DID.                                                                                                                                                                                       |
| `created` | `number`         | UNIX timestamp in seconds of signature creation time.                                                                                                                                           |

## Authentication Response&#x20;

After the signature and VP are received, the client sends the response to the challenge to the server.

```javascript
{
 "ver": "1.0",
 "type": "ClientResponse",
 "nonce": "uuid-128",
 "did": "did:ont:alice",
 "proof": {
   "type":"Ed25519",
   "verificationMethod": "did:ont:alice#key-1",
   "created":"2010-01-0119:23:24Z",
   "value":"xx",
 },
 "VPs": ["",""],
}
```

| Property | Type                                                                                                                      | Description                                                                                                                                                                                                                                                                                                                                                       |
| -------- | ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ver`    | `1.0`                                                                                                                     | Protocol version, current version is 1.0.                                                                                                                                                                                                                                                                                                                         |
| `type`   | `ClientResponse`                                                                                                          | Message type, the type of the challenge response is `ClientResponse`.                                                                                                                                                                                                                                                                                             |
| `nonce`  | `string`                                                                                                                  | Nonce included in the challenge.                                                                                                                                                                                                                                                                                                                                  |
| `did`    | `string`                                                                                                                  | User DID.                                                                                                                                                                                                                                                                                                                                                         |
| `proof`  | [`proof`](https://github.com/ontology-tech/ontlogin-js-sdk/blob/98947f653c830f4871774238d613570aff014ddc/src/type.ts#L58) | <p>Signed challenge including the following 4 fields: </p><p>- <code>type</code>: signature scheme used for the signature</p><p>- <code>verificationMethod</code>: serial number of the verification method in the user DID Document</p><p>- <code>created</code>: UNIX timestamp in seconds of signature creation time</p><p>- <code>value</code>: signature</p> |
| `VPs`    | `string[]`                                                                                                                | Encoded VC.                                                                                                                                                                                                                                                                                                                                                       |

## Verification

The server verifies data contained in the challenge response:

1. Verify the validity of parameters&#x20;
2. Verify if the nonce is the same as the one generated by the server
3. verify the signature
4. Verify the validity of VP and VC
5. Check if the provided VC meets the requirement &#x20;


# Front-end JavaScript SDK

ONT Login Front-end JavaScript SDK provides functionalities that allow the client of your app to initiate authentication, and then interact with the server to complete the process.


# Integration and Usage

## Example apps

* [vue](https://github.com/ontology-tech/ontlogin-sdk-js/tree/main/example/vue-demo)
* [pure HTML](https://github.com/ontology-tech/ontlogin-sdk-js/tree/main/example/html-demo)

## Install and import package

&#x20;via NPM [package](https://npmjs.com/package/ontlogin)

```javascript
npm i ontlogin
```

```javascript
import {createAuthRequest} from "ontlogin";
```

via [js bundle](https://github.com/ontology-tech/ontlogin-sdk-js/blob/main/dist/ontlogin.min.js)

```javascript
<script src="ontlogin.min.js"></script>
<script>
    ontlogin.createAuthRequest();
</script>
```

via [es module js bundle](https://github.com/ontology-tech/ontlogin-sdk-js/blob/main/dist/ontlogin.es.js)

```javascript
import {createAuthRequest} from "ontlogin.es.js";
```

## Generate `authRequest` and challenge

```javascript
import { createAuthRequest } from "ontlogin";

const authRequest = createAuthRequest();
const challenge = await fetch("server-url", { body: authRequest });
```

## Get QR code from ontlogin QR server.

```javascript
import { requestQR } from "ontlogin";

const { text, id } = await requestQR(challenge);
```

## Show QR code UI and query scan result from ontlogin QR server

```javascript
import { queryQRResult, cancelQueryQRResult, ErrorEnum } from "ontlogin";

try {
  const challengeResponse = await queryQRResult(id);
} catch (e) {
  if (e.message === ErrorEnum.UserCanceled) {
    // handle cancel
  } else {
    // handle error
  }
}

cancelQueryQRResult(); // Cancel fetching result if you need.
```

## Submit challenge response to your server

```javascript
fetch("server-url", { body: challengeResponse });
```


# API Reference

## Index

* [createAuthRequest](/decentralized-identity-and-data/ontid/ont-login/front-end-javascript-sdk/api-reference#createauthrequest)
* [createSignData](/decentralized-identity-and-data/ontid/ont-login/front-end-javascript-sdk/api-reference#createsigndata)
* [requestQR](/decentralized-identity-and-data/ontid/ont-login/front-end-javascript-sdk/api-reference#requestqr)
* [queryQRResult](/decentralized-identity-and-data/ontid/ont-login/front-end-javascript-sdk/api-reference#queryqrresult)[  ](/decentralized-identity-and-data/ontid/ont-login/front-end-javascript-sdk/api-reference#cancelqueryqrresult)
* [cancelQueryQRResult](/decentralized-identity-and-data/ontid/ont-login/front-end-javascript-sdk/api-reference#cancelqueryqrresult)

## createAuthRequest

Creates`AuthRequest` to get the authentication challenge message.

#### Parameters&#x20;

| Parameter | Type   | Description                      |
| --------- | ------ | -------------------------------- |
| `action`  | `enum` | IdAuth: = 0 IdAuthAndVcAuth: = 1 |

#### **Returns**

[`AuthRequest`](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#authentication-request)

## createSignData

Creates a message for the user to sign with the wallet.

{% hint style="info" %}
Convert the message to a JSON string before signing.
{% endhint %}

#### Parameters&#x20;

| Parameter       | Type            | Description                                                                                                           |
| --------------- | --------------- | --------------------------------------------------------------------------------------------------------------------- |
| `AuthChallenge` | `AuthChallenge` | See details [here](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#authentication-challenge). |
| `account`       | `string`        | DID of the signer (user).                                                                                             |

#### Returns&#x20;

[`SignData`](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#signature-and-authorization)

## requestQR

Gets the challenge in the form of a QR code with `AuthChallenge`.

#### **Parameters**

[`AuthChallenge`](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#authentication-challenge)

#### **Returns**

`Promise<QrResult>` **,** including the following properties:

| Property | Type     | Description                      |
| -------- | -------- | -------------------------------- |
| `id`     | `string` | QR code ID.                      |
| `text`   | `string` | Text for generating the QR code. |

## `queryQRResult`

Fetches the result of a user scanning the QR code.&#x20;

The query loops until a result or an error is returned. To stop the query, call [`cancelQueryQRResult`](/decentralized-identity-and-data/ontid/ont-login/front-end-javascript-sdk/api-reference#cancelqueryqrresult).

#### **Parameters**

| Property   | Type     | Description                                                       | Required |
| ---------- | -------- | ----------------------------------------------------------------- | -------- |
| `id`       | `string` | QR code ID.                                                       | Yes      |
| `duration` | `number` | Time interval between two queries, in milliseconds. Default: 1000 | No       |

#### **Returns**

[`Promise<ChallengeResponse>`](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#authentication-response)

## cancelQueryQRResult

Stops querying the result of a QR code scan.

#### **Parameters**

None

#### **Returns**

`void`

## Errors

| Member              | Value                      |
| ------------------- | -------------------------- |
| `VersionNotSupport` | `ERR_WRONG_VERSION`        |
| `TypeNotSupport`    | `ERR_TYPE_NOT_SUPPORTED`   |
| `ActionNotSupport`  | `ERR_ACTION_NOT_SUPPORTED` |
| `UserCanceled`      | `USER_CANCELED`            |
| `UnknownError`      | `ERR_UNDEFINED`            |


# Front-end UI SDK

The front-end UI SDK allows you to build a login UI in no time.&#x20;


# Integration and Usage

ONT Login web component UI SDK for JavaScript

{% hint style="warning" %}
Before getting started, please make sure to:

* implement the API as specified&#x20;
* check web component compatibility [here](https://caniuse.com/?search=Custom%20Elements)​
  {% endhint %}

{% hint style="info" %}
​Please check out the [front-end JavaScript SDK](/decentralized-identity-and-data/ontid/ont-login/front-end-javascript-sdk) is you want to build a custom UI.
{% endhint %}

## Example Apps <a href="#example-apps" id="example-apps"></a>

* ​[vue](https://github.com/ontology-tech/ontlogin-sdk-ui/tree/main/examples/vue)​
* ​[pure HTML](https://github.com/ontology-tech/ontlogin-sdk-ui/tree/main/examples/html)​

## Integration and Usage <a href="#integration-and-usage" id="integration-and-usage"></a>

via NPM [package](https://npmjs.com/package/ontlogin-ui)​

```
npm i ontlogin-ui
```

```
import "ontlogin-ui";
```

```javascript
<ont-login
  url_of_get_challenge="server/requestChallenge"
  url_of_submit_response="server/submitChallenge"
/>
```

via [js bundle](https://github.com/ontology-tech/ontlogin-sdk-ui/blob/main/dist/ontloginui.min.js)​

```javascript
<ont-login
  id="ontlogin"
  url_of_get_challenge="server/requestChallenge"
  url_of_submit_response="server/submitChallenge"
/>
<script src="ontloginui.min.js"></script>
<script>
  // add event listener to custom event
  const target = document.querySelector("#ontlogin");
  target.addEventListener("success", (e) => {
    console.log(e.detail);
  });
  target.addEventListener("error", (e) => {
    console.log(e.detail);
  });
  target.addEventListener("cancel", (e) => {
    console.log(e.detail);
  });
</script>
```


# API Reference

## Parameters

| Name                     | Type     | Description                                                                                                                                                                                    |
| ------------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url_of_get_challenge`   | `string` | URL of server API to get challenge, see details below                                                                                                                                          |
| `url_of_submit_response` | `string` | URL of server API to submit response, see details below                                                                                                                                        |
| `show_vc_list`           | `string` | 'true'\|'false'. Show a list of VC in the dialog if exists                                                                                                                                     |
| `test`                   | `string` | 'true' \| 'false'. Add a button to mock the successful scan result (test only)                                                                                                                 |
| `action`                 | `string` | '0' \| '1'. "0" = authentication; "1" = authentication and authorization. More details [here](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#authentication-request). |

### url\_of\_get\_challenge

Gets challenge with `AuthRequest`.

#### Request&#x20;

| Content Type       | Format                                                                                                        | Example                                         |
| ------------------ | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `application/json` | [AuthRequest](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#authentication-request) | `{"ver":"1.0","type":"ClientHello","action":0}` |

#### Response

| Content Type       | Format                                                                                                             | Example                                                                                                                                                                                                                                                                                                                      |
| ------------------ | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `application/json` | [AuthChallenge ](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#authentication-challenge) | `{"ver":"1.0","type":"ServerHello","nonce":"8125419d-0ba4-11ec-a4f0-441ca8e37c61","server":{"name":"testServcer","icon":"http://somepic.jpg","url":"https://ont.io","did":"did:ont:sampletest"},"chain":["ONT"],"alg":["ES256"],"VCFilters":[{"type":"EmailCredential","trust_roots":["did:ont:testdid"],"required":true}]}` |

### `url_of_submit_response`

Submits `AuthResponse` to the server

#### Request&#x20;

| Content Type       | Format                                                                                                           | Example                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------------ | ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `application/json` | [AuthResponse ](/decentralized-identity-and-data/ontid/ont-login/protocol-specification#authentication-response) | `{"ver":"1.0","type":"ClientResponse","nonce":"221b111a-0ba5-11ec-a4f0-441ca8e37c61","did":"did:ont:AR9NDnK3iMSZodbENnt7eX5TJ2s27fnHra","proof":{"type":"Ed25519","verificationMethod":"did:ont:AR9NDnK3iMSZodbENnt7eX5TJ2s27fnHra#key-1","created":1630556445,"value":"01c3841e922884df9288dde3c1fecbb575482c834560781454c44192b54140d3a7413d116fe81b76e3e74f88e2eb1351c120854d47189241545f66d7702cab8523"},"VPs":[]}` |

#### Response

JSON messages.

## Events

| Name      | Type          | Description                                                                             |
| --------- | ------------- | --------------------------------------------------------------------------------------- |
| `success` | `CustomEvent` | Callback submitted successfully, with response to`url_of_submit_response` in `e.detail` |
| `error`   | `CustomEvent` | Error callback.                                                                         |
| `cancel`  | `CustomEvent` | Callback cancelled by user.                                                             |


# Back-end Go SDK

The back-end Go SDK assists the server to collect and process data required for authentication.


# Integration and Usage

{% hint style="info" %}
In this example we use [go-chi](https://github.com/go-chi/chi) to build the RESTful service. You can view the full code [here](https://github.com/ontology-tech/ontlogin-sample-go), and find the SDK [here](https://github.com/ontology-tech/ontlogin-sdk-go).
{% endhint %}

## Initialization <a href="#initialization" id="initialization"></a>

Add the following in the `go.mod` file.

```go
require (	...	github.com/ontology-tech/ontlogin-sdk-go latest)
```

## Add API Methods <a href="#add-api-methods" id="add-api-methods"></a>

Import the methods in the `main.go` file.

* `requestChallenge`: Returns the challenge from the server
* `submitChallenge` : Passes the signed challenge and VP (if requested by the server)

```go
package main​
import (	
        "log"
        "net/http"​
        "github.com/go-chi/chi/v5"	
        "github.com/go-chi/chi/v5/middleware"	
        "github.com/go-chi/cors"​	
        "ontlogin-sample/auth"	
        "ontlogin-sample/service"
)
```

&#x20;Initialize the service, perform cross-origin resource sharing checks and define API methods.

```go
func main() {
	r := chi.NewRouter()	
	service.InitService() // Service Initialization	
	r.Use(cors.Handler(cors.Options{		
		// AllowedOrigins:   []string{"https://foo.com"}, // Use this to allow specific origin hosts		
		AllowedOrigins: []string{"*"},		
		// AllowOriginFunc:  func(r *http.Request, origin string) bool { return true },		
		AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},		
		// AllowedHeaders:   []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},		
		AllowedHeaders:   []string{"Authorization", "Content-Length", "X-CSRF-Token", "Token", "session", "X_Requested_With", "Accept", "Origin", "Host", "Connection", "Accept-Encoding", "Accept-Language", "DNT", "X-CustomHeader", "Keep-Alive", "User-Agent", "X-Requested-With", "If-Modified-Since", "Cache-Control", "Content-Type", "Pragma"},		
		ExposedHeaders:   []string{"Content-Length", "token", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Cache-Control", "Content-Language", "Content-Type", "Expires", "Last-Modified", "Pragma", "FooBar"},		
		AllowCredentials: false,		
		MaxAge:           172800, // Maximum value not ignored by any of major browsers		
		//Debug:true,	
	}))	
	r.Use(middleware.Logger)	
	r.Use(auth.Middleware()) // Detect app login permission​	
	
	r.Post("/requestChallenge", service.RequestChallenge) // Challenge request	
	r.Post("/submitChallenge",service.Login) // Challenge submission	
	r.Get("/afterLogin",service.AfterLogin)  // Other business logic	
	log.Fatal(http.ListenAndServe(":3000", r))
}
```

## Import and Use `service.go` <a href="#import-and-use-service-go" id="import-and-use-service-go"></a>

Handle API requests using `service.go`

```go
package service​
import (
	"encoding/json"	
	"fmt"	
	"github.com/ontology-tech/ontlogin-sdk-go/did"	
	"github.com/ontology-tech/ontlogin-sdk-go/did/ont"	
	"github.com/ontology-tech/ontlogin-sdk-go/modules"	
	ontloginsdk "github.com/ontology-tech/ontlogin-sdk-go/sdk"	
	"net/http"​	
	
	"github.com/google/uuid"​	
	
	"ontlogin-sample/auth"	
	"ontlogin-sample/jwt"
)​

var loginsdk *ontloginsdk.OntLoginSdk
var mapstore map[string]string


​func InitService() {	
	mapstore = make(map[string]string) // To store UUID. In real projects, UUID can be stored in the database, redis or cache                                     	
	
	vcfilters := make(map[string][]*modules.VCFilter)		// Configure `VCFilter` according to `actionType`	
	vcfilters[modules.ACTION_REGISTER] = []*modules.VCFilter{		
		{Type: "EmailCredential", Required: true, TrustRoots: []string{"did:ont:ssssss"}}, // Issuer DID	
	}	// Server configuration information needed by the SDK, which can be obtained from config files	
	conf := &ontloginsdk.SDKConfig{		
		Chain: []string{"ont"}, // Supported chains, e.g. eth, ont, bsc, respective Processors needed		
		Alg:   []string{"ES256"}, // Supported signature schemes		
		ServerInfo: &modules.ServerInfo{			
			Name:               "testServcer",			
			Icon:               "http://somepic.jpg",			
			Url:                "https://ont.io",			
			Did:                "did:ont:sampletest",			
			VerificationMethod: "",		
		},		
		VCFilters: vcfilters,   // VC required by the server	
	}​	
	
	Processors := make(map[string]did.DidProcessor)  // Initialize the Processor of the respective chain
	// Parameter specification using Ontology as an example
	// 1. doubleDirection bool: if mutual authentication is required
	// 2. Ontology node rpc server address
	// 3. DID contract address, can be null when 1 takes `false`
	// 4. Ontology wallet address, can be null when 1 takes `false`
	// 5. Wallet password, can be null when 1 takes `false`		
	
	ontProcessor, err := ont.NewOntProcessor(false, "http://polaris2.ont.io:20336", "52df370680de17bc5d4262c446f102a0ee0d6312", "./wallet.dat", "123456")	
	if err != nil {
		panic(err)	
	}	
	Processors["ont"] = ontProcessor
	// Except config, Processor and SDK, the following functions need to be passed
	// 1. func()string: generates UUID
	// 2. func(string)error: checks if the nonce (UUID) exists in the database/redis/cache		
	loginsdk, err = ontloginsdk.NewOntLoginSdk(conf, Processors, GenUUID, CheckNonce)	
	if err != nil {		
		panic(err)	
	}
}

​func RequestChallenge(writer http.ResponseWriter, request *http.Request){  
	// Handle the request from the client	
	cr := &modules.ClientHello{}	
	writer.Header().Set("Content-Type", "application/json")	
	err := json.NewDecoder(request.Body).Decode(&cr)	
	if err != nil {		
		fmt.Printf("err:%s\n",err.Error())		
		writer.Write([]byte(err.Error()))		
		return	
	}  
	// Invoke the SDK to generate the challenge	
	serverHello,err := loginsdk.GenerateChallenge(cr)	
	if err!= nil{		
		fmt.Printf("err:%s\n",err.Error())		
		writer.Write([]byte(err.Error()))		
		return	
	}	  
	// Return the challenge	
	bts,_:=json.Marshal(serverHello)​	
	writer.Write(bts)
​}​

func Login(writer http.ResponseWriter, request *http.Request){
	lr := &modules.ClientResponse{}	
	writer.Header().Set("Content-Type", "application/json")​	
	
	err := json.NewDecoder(request.Body).Decode(&lr)​	
	
	if err != nil {
		fmt.Printf("err:%s\n",err.Error())		
		writer.Write([]byte(err.Error()))		
		return	
	}​	
	
	err = loginsdk.ValidateClientResponse(lr)	
	if err != nil {		
		fmt.Printf("err:%s\n",err.Error())		
		writer.Write([]byte(err.Error()))		
		return	
	}​
	// The challenge response from the client has passed validation
	// Now you can proceed according to your business logic
	// In this example, JWT is used for authentication​​	
	s ,err:= jwt.GenerateToken(lr.Did)​	
	writer.Write([]byte(s))
​}

​func AfterLogin(writer http.ResponseWriter, request *http.Request) {
	if err := auth.CheckLogin(request.Context()); err != nil {		
		fmt.Printf("err:%s\n", err.Error())		
		writer.Write([]byte("please login first"))		
		return	
	}	
	writer.Write([]byte("normal business process"))
}

​​func GenUUID()string{	
	uuid,err := uuid.NewUUID()	
	if err != nil{		
		fmt.Printf("uuid failed:%s\n",err.Error())		
		
		return ""	
	}	
	mapstore[uuid.String()] = "ok"	
	return uuid.String()
}​

func CheckNonce(nonce string)error{	
	if _,ok:=mapstore[nonce]
	;!ok{		
		return fmt.Errorf("no nonce found")	
	}	
	return nil
}
```

## Handle VP <a href="#handle-vp" id="handle-vp"></a>

Use the following to extract VC from VP in form of JSON text.

```go
 GetCredentialJson(chain, presentation string) ([]string, error)
```

Since the form of VC varies according to the server's request, only JSON is supported here. The server can parse the VC into the per-defined form.


# API Reference

## Index

* [NewOntLoginSdk](/decentralized-identity-and-data/ontid/ont-login/back-end-go-sdk/api-reference#newontloginsdk)
* [GenerateChallenge](/decentralized-identity-and-data/ontid/ont-login/back-end-go-sdk/api-reference#generatechallenge)
* [ValidateClientResponse](/decentralized-identity-and-data/ontid/ont-login/back-end-go-sdk/api-reference#validateclientresponse)
* [GetCredentialJson](/decentralized-identity-and-data/ontid/ont-login/back-end-go-sdk/api-reference#getcredentialjson)

## `NewOntLoginSdk`

Creates an OntLoginSdk instance.

#### Parameters

**`conf *SDKConfig`**

SDK configuration

```go
type SDKConfig struct {
	Chain      []string                       // Supported chain, e.g."ONT","ETH","BSC"
	Alg        []string                       // Signature scheme such as "ES256","Ed25519"
	ServerInfo *modules.ServerInfo            // Server configuration info, see details below
	VCFilters  map[int][]*modules.VCFilter    // VCFilter info for authentication/authorization, see details below
```

```go
type ServerInfo struct {
	Name               string `json:"name"`                             // Server name
	Icon               string `json:"icon,omitempty"`                   // Icon, optional
	Url                string `json:"url"`                              // Server URL 
	Did                string `json:"did,omitempty"`                    // Server DID, optional
	VerificationMethod string `json:"verificationMethod,omitempty"`     // Verification method, optional
}
```

```go
type VCFilter struct {
	Type       string   `json:"type"`                  // Type of VC, e.g. "DegreeCredential"
	Express    []string `json:"express,omitempty"`     // List of expressions for zero-knowledge proof
	TrustRoots []string `json:"trust_roots"`           // List of trusted VC issuer DIDs
	Required   bool     `json:"required"`              // If it's required  
```

`processors map[string]did.DidProcessor`

DID processor map

`nonceFunc func(int) string`

Function to generate nonce

`getActionByNonce func(string) (int,error)`

Gets action by nonce

#### Returns

| Field          | Description              |
| -------------- | ------------------------ |
| `*OntLoginSdk` | Instantiation successful |
| `error`        | Instantiation failed     |

## GenerateChallenge

Generates the challenge.

#### Parameters

```go
type ClientHello struct {
	Ver             string           `json:"ver"`                       // Version number 
	Type            string           `json:"type"`                      // "ClientHello" for this message
	Action          int              `json:"action"`                    // 0: Authentication, 1: Authorization
	ClientChallenge *ClientChallenge `json:"ClientChallenge,omitempty"` // Challenge sent from the client for mutual authentication, optional
}
```

#### Returns

`*modules.ServerHello`

```go
type ServerHello struct {
	Ver         string       `json:"ver"`                     // Version number 
	Type        string       `json:"type"`						 // "ServerHello" for this message
	Nonce       string       `json:"nonce"`                   // String of nonce
	Server      *ServerInfo  `json:"server"`                  // Server info 
	Chain       []string     `json:"chain"`                   // List of supported chains
	Alg         []string     `json:"alg"`                     // List of supported signature schemes
	VCFilters   []*VCFilter  `json:"VCFilters,omitempty"`     // List of VCFilters, optional 
	ServerProof *ServerProof `json:"ServerProof,omitempty"`   // Challenge response sent from the server for mutual authentication, optional
	Extension   *Extension   `json:"extension,omitempty"`     // Extension, optional
}
```

## ValidateClientResponse

Validates the response from the client.&#x20;

#### Parameters

```go
type ClientResponse struct {
	Ver   string   `json:"ver"`					// Version number 
	Type  string   `json:"type"`				// "ClientResponse" for this message
	Did   string   `json:"did"`					// User DID
	Nonce string   `json:"nonce"`             // String of nonce generated by the server
	Proof *Proof   `json:"proof"`             // Signature info sent from the client, see details below
	VPs   []string `json:"VPs,omitempty"`     // List of verifiable presentations, optional
}
```

```go
type Proof struct {
	Type               string `json:"type"`               // Signature scheme
	VerificationMethod string `json:"verificationMethod"` // DID & key index,e.g."did:ont:alice#key-1"
	Created            uint64 `json:"created"`            // Unix timestamp
	Value              string `json:"value"`              // HEX string of signature
}
```

#### Returns

| Field   | Description           |
| ------- | --------------------- |
| `null`  | Validation successful |
| `error` | Validation failed     |

Validation Process:

1. Verify the validity of parameters&#x20;
2. Verify if the nonce is the same as the one generated by the server
3. verify the signature
4. Verify the validity of VP and VC
5. Check if the provided VC meets the requirement &#x20;

## GetCredentialJson

Gets JSON string of VC from VP.

#### Parameters

| Parameter      | Description |
| -------------- | ----------- |
| `chain`        | Chain name  |
| `presentation` | VP string   |

#### Returns

| Field      | Description           |
| ---------- | --------------------- |
| `[]string` | JSON string of VC     |
| `error`    | Fail to get VC string |


# Back-end Java SDK

The back-end Java SDK assists the server to collect and process data required for authentication.


# Integration and Usage

{% hint style="info" %}
In this example we use SpringBoot to build the RESTful service. You can view the full code [here](https://github.com/ontology-tech/ontlogin-demo/tree/main/backend/java), and find the SDK [here](https://github.com/ontology-tech/ontlogin-sdk-java).&#x20;
{% endhint %}

## Initialization

Include the SDK dependencies to the local Maven repository:

```java
mvn install:install-file -DgroupId=com.github.ontio -DartifactId=ontlogin-sdk-java -Dversion=1.0.0 -Dpackaging=jar -Dfile=ontlogin-sdk-java-1.0.0.jar
```

Add dependencies in the `pom.xml` file:

```java
        <dependency>
            <groupId>com.github.ontio</groupId>
            <artifactId>ontlogin-sdk-java</artifactId>
            <version>1.0.0</version>
        </dependency>
```

## Add API Methods <a href="#add-api-methods" id="add-api-methods"></a>

Add the methods in the Controller:

* `requestChallenge`: Returns the challenge from the server
* `submitChallenge` : Passes the signed challenge and VP (if requested by the server)&#x20;

```java
    // Challenge request
    @PostMapping("/challenge")
    public Result generateChallenge(@RequestBody ClientHello clientHello) throws Exception {
        String action = "generateChallenge";
        ServerHello result = loginService.generateChallenge(action, clientHello);
        return new Result(action, ErrorInfo.SUCCESS.code(), ErrorInfo.SUCCESS.descEN(), result);
    }

    // Challenge submission
    @PostMapping("/validate")
    public Result validateClientResponse(@RequestBody ClientResponse clientResponse) throws Exception {
        String action = "validateClientResponse";
        String token = loginService.validateClientResponse(action, clientResponse);
        return new Result(action, ErrorInfo.SUCCESS.code(), ErrorInfo.SUCCESS.descEN(), token);
    }

    // Other business logic
    @PostMapping("/check-jwt")
        public Result checkJwt(@RequestBody JSONObject req) {
            String action = "checkJwt";
            String token = req.getString("token");
            loginService.checkJwt(action, token);
            return new Result(action, ErrorInfo.SUCCESS.code(), ErrorInfo.SUCCESS.descEN(), ErrorInfo.SUCCESS.descEN());
        }
```

## Use `loginService`

```java
   @Autowired
    private JWTUtils jwtUtils;
    @Autowired
    private SDKUtil sdkUtil;

    @Override
    public ServerHello generateChallenge(String action, ClientHello clientHello) throws Exception {
        // Invoke the SDK to generate the challenge
        return sdkUtil.generateChallenge(clientHello);
    }

    @Override
    public String validateClientResponse(String action, ClientResponse clientResponse) throws Exception {
        sdkUtil.validateClientResponse(clientResponse);
        // Challenge verification successful
        // Now you can proceed according to your business logic
        // In this example, JWT is used for authentication 
        String token = jwtUtils.signAccess("", "test user");
        return token;

    }

    @Override
    public void checkJwt(String action, String token) {
        jwtUtils.verifyAccessToken(token);
    }
```

## Import `SDKUtil` and Initialize `ontlogin Sdk`

```java
    private OntLoginSdk sdk;
    // To store UUID. In real projects, UUID can be stored in the database, redis or cache
    private Map<String, Integer> nonceMap = new HashMap<>();

    private OntLoginSdk getOntLoginSdk() throws Exception {
        if (sdk == null) {
            synchronized (OntLoginSdk.class) {
                if (sdk == null) {
                    ServerInfo serverInfo = new ServerInfo();
                    serverInfo.setName("testServcer");
                    serverInfo.setIcon("http://somepic.jpg");
                    serverInfo.setUrl("https://ont.io");
                    // Server DID 
                    serverInfo.setDid("did:ont:sampletest");
                    serverInfo.setVerificationMethod("");
                    
                    Map<Integer, VCFilter[]> vcFilters = new HashMap<>();
                    // Configure `VCFilter` according to `actionType`
                    VCFilter vcFilter = new VCFilter();
                    // VC type
                    vcFilter.setType("EmailCredential");
                    // If it's required
                    vcFilter.setRequired(true);
                    // Issuer DID
                    vcFilter.setTrustRoots(new String[]{"did:ont:testdid"});
                    VCFilter[] vcFiltersArray = {vcFilter};
                    vcFilters.put(Const.ACTION_AUTHORIZATION, vcFiltersArray);
                            
                    SDKConfig sdkConfig = new SDKConfig();
                    // Supported chains, e.g. eth, ont, bsc, respective Processors needed
                    sdkConfig.setChain(new String[]{"ont"});
                    // Supported signature scheme
                    sdkConfig.setAlg(new String[]{"ES256"});
                    // Server info
                    sdkConfig.setServerInfo(serverInfo);
                    // VC required by the server
                    sdkConfig.setVcFilters(vcFilters);
                    
                    // Initialize the Processor of the respective chain
                    // Parameter specification using Ontology as an example
                    // 1. doubleDirection bool: if mutual authentication is required
                    // 2. Ontology node rpc server address
                    // 3. DID contract address, can be null when 1 takes `false`
                    // 4. Ontology wallet address, can be null when 1 takes `false`
                    // 5. Wallet password, can be null when 1 takes `false`
                    OntProcessor ontProcessor = new OntProcessor(false, "http://polaris2.ont.io:20334",
                            "52df370680de17bc5d4262c446f102a0ee0d6312", "./wallet.json", "12345678");
                    Map<String, DidProcessor> resolvers = new HashMap<>();
                    resolvers.put("ont", ontProcessor);

                    // Except config, Processor and SDK, the following functions need to be passed
                    // 1. public String genRandomNonceFunc(Integer action): generates UUID by action
                    // 2. public Integer getActionByNonce(String nonce): checks if the nonce (UUID) exists in the database/redis/cache and returns action
                    sdk = new OntLoginSdk(sdkConfig, resolvers) {
                        @Override
                        public String genRandomNonceFunc(Integer action) {
                            String nonce = UUID.randomUUID().toString().replace("-", "");
                            nonceMap.put(nonce, action);
                            return nonce;
                        }

                        @Override
                        public Integer getActionByNonce(String nonce) {
                            Integer action = nonceMap.get(nonce);
                            if (action == null) {
                                throw new OntLoginException("checkNonce", ErrorInfo.NONCE_NOT_EXISTS.descEN(), ErrorInfo.NONCE_NOT_EXISTS.code());
                            }
                            nonceMap.remove(nonce);
                            return action;
                        }
                    };
                }
            }
        }
        return sdk;
    }

    public ServerHello generateChallenge(ClientHello clientHello) throws Exception {
        OntLoginSdk ontLoginSdk = getOntLoginSdk();
        ServerHello serverHello = ontLoginSdk.generateChallenge(clientHello);
        return serverHello;
    }

    public void validateClientResponse(ClientResponse clientResponse) throws Exception {
        OntLoginSdk ontLoginSdk = getOntLoginSdk();
        ontLoginSdk.validateClientResponse(clientResponse);
    }
```

## Handle VP

Use the following to extract VC from VP in form of JSON text.

```java
public String[] getCredentialJsons(String presentation)
```

Since the form of VC varies according to the server's request, only JSON is supported here. The server can parse the VC into the per-defined form.


# API Reference

## Index

* [NewOntLoginSdk](/decentralized-identity-and-data/ontid/ont-login/back-end-java-sdk/api-reference#newontloginsdk)
* [GenerateChallenge](/decentralized-identity-and-data/ontid/ont-login/back-end-java-sdk/api-reference#getcredentialjson)
* [ValidateClientResponse](/decentralized-identity-and-data/ontid/ont-login/back-end-java-sdk/api-reference#validateclientresponse)
* [GetCredentialJson](/decentralized-identity-and-data/ontid/ont-login/back-end-java-sdk/api-reference#getcredentialjson)

## NewOntLoginSdk

Creates an OntLoginSdk instance.

#### Parameters

**`SDKConfig`**

SDK configuration

```java
public class SDKConfig {
	String[] chain;                        // Supported chain, e.g."ONT","ETH","BSC"
    String[] alg;                        // Signature scheme such as "ES256","Ed25519"
    ServerInfo serverInfo;               // Server configuration info, see details below
    Map<Integer, VCFilter[]> vcFilters;  // VCFilter info for authentication/authorization, see details below
}
```

```java
public class ServerInfo {
	String name;                    // Server name
	String icon;                    // Icon, optional
	String url;                     // Server URL 
	String did;                     // Server DID, optional
	String verificationMethod;      // Verification method, optional
}
```

```java
public class VCFilter {
	String type;                    // Type of VC, e.g. "DegreeCredential"
	String[] express;               // List of expressions for zero-knowledge proof
	String[] trustRoots             // List of trusted VC issuer DIDs
	boolean required;               // If it's required  
}
```

`Map<string,DidProcessor>`

DID processor map

`@Override`&#x20;

`public String genRandomNonceFunc(Integer action)`

Function to generate nonce

`@Override`&#x20;

`public Integer getActionByNonce(String nonce)`

Gets action by nonce

#### Returns

&#x20;`OntLoginSdk`

## GenerateChallenge

Generates the challenge.

#### Parameters

```java
public class ClientHello {
	String ver;                         // Version number 
	String type;                        // "ClientHello" for this message
	int action;                         // 0: Authentication, 1: Authorization
	ClientChallenge clientChallenge;    // Challenge sent from the client for mutual authentication, optional
}
```

#### Returns

`ServerHello`

```java
public class ServerHello {
	String ver;                 // Version number 
	String type;		        // "ServerHello" for this message
	String nonce;              // String of nonce
	ServerInfo server;         // Server info 
	String[] chain;            // List of supported chains
	String[] alg;              // List of supported signature schemes
	VCFilter[] VCFilters;      // List of VCFilters, optional  
	ServerProof serverProo     // Challenge response sent from the server for mutual authentication, optional
	Extension extension;       // Extension, optional
}
```

## ValidateClientResponse

Validates the response from the client.&#x20;

#### Parameters

```java
public class ClientResponse {
	String ver;	        // Version number 
	String type;        // "ClientResponse" for this message
	String did;         // User DID
	String nonce;       // String of nonce generated by the server
	Proof proof;        // Signature info sent from the client, see details below
	String[] VPs;       // List of verifiable presentations, optional
}
```

```java
public class Proof {
	String type;            // Signature scheme
	String verificatio      // DID & key index,e.g."did:ont:alice#key-1"
	int created;            // Unix timestamp
	String value;           // HEX string of signature
}
```

#### Returns

| Field  | Description           |
| ------ | --------------------- |
| `null` | Validation successful |

Validation Process:

1. Verify the validity of parameters&#x20;
2. Verify if the nonce is the same as the one generated by the server
3. verify the signature
4. Verify the validity of VP and VC
5. Check if the provided VC meets the requirement &#x20;

## GetCredentialJson

Gets JSON string of VC from VP.

#### Parameters

| Parameter      | Description |
| -------------- | ----------- |
| `chain`        | Chain name  |
| `presentation` | VP string   |

#### Returns

| Field      | Description       |
| ---------- | ----------------- |
| `[]string` | JSON string of VC |


# ONT TAG

ONT TAG is an open and decentralized authentication platform based on ONT ID and the Ontology trust ecosystem. It provides KYC services for people, finances, things, and affairs. The Ontology trust ecosystem has gathered trust anchors that provide global identity authentication services, including IdentityMind, CFCA, Shufti Pro, etc., as well as email, mobile, and social media authentication methods.

![](/files/-MieujfHGE5AVG3xtDO4)

## What can ONT TAG do for you?

If you have your own app or platform, ONT TAG can help your users complete authentication. You can integrate ONT TAG into your platform or product for KYC, identity authentication services, login, and so on, depending on your business requirements.

ONT TAG has the following advantages:

* The Ontology trust ecosystem is already connected to global certification services, covering users in 218 countries and regions;
* Provides low cost, one-time authentication, which can be used multiple times, and reduces the cost of multiple authentications;
* The protocol uses end-to-end encryption specifications to protect user data throughout;
* All authentication actions and results are attested to the Ontology blockchain;
* The specification supports cryptographic algorithms such as zero-knowledge proof, and users can selectively present their own identity information to maximize user privacy.

## Data Privacy

No user data is stored on TAG servers in any form. All the credentials are to be stored and maintained by the user. In case the user loses access to their credential, we cannot recover it for them and they would need to go through the process of getting a new one.


# Workflow

## Overview

ONT TAG takes user data from your platform, authenticates it with a third party verifying institution such as Shufti Pro or Identity Mind, and issues credentials for the user that are valid for a certain period of time.

A credential contains all the verified data passed with the authentication request. Ideally, the user would store their credential and authorize access to credential data as necessary.

This data can be used to perform background checks and assess any associated risks.

The overall KYC verification degree can be customized to your app logic and business needs.

## Process Flow

The ONT ID framework can be used to assign DIDs to entities in networks. Once an identifier has been assigned, a process that takes place off-chain, the entity can start making specific claims. Validation and verification of these claims will be a part of most operations associated with this particular entity.

The set of claims are first validated by a reliable institution (a trust anchor), and then packaged into a credential (JWT). This credential is to be stored for later use while it’s still valid. Generally speaking, the credential is sent to the user and they are prompted to store and maintain it.

Upon being validated, a record of this action will be registered on the Ontology chain. This record contains details such as when it will expire and a hash which is used to verify if the credential data has been tampered with.&#x20;

![](/files/-MievC-lyYZhLDsRzwvr)

The following sequence diagram illustrates the flow of data between different parties.

* **End user:** The user makes the claim (by providing personal details). May be termed as the credential owner.
* **Credential consumer:** The system or the institution that will process (or consume) the credentials presented by the end user.
* **Trust Anchor Gateway:** Intermediary service used to avail trust anchor services, register credential consumers and obtain credentials.
* **Trust Anchor:** The system that validates the KYC/AML information submitted by users. Consists of a third-party verifying institution, e.g., Identity Mind, Shufti Pro, etc. Issues credentials after successful verification.
* **Ontology Mainnet:** The Ontology blockchain.

## Integrating and Using the SDK

The steps have been laid out below and described individually in the later section.&#x20;

1. Register as a credential consumer to obtain the SDK configuration file
2. Verify the KYC details submitted by the user by calling the SDK to send authentication requests
3. Use a wallet to get the user to authorize access to their credential data after they have stored it

### Registration

1.Download and install the Ontology Authenticator or ONTO wallet application on your mobile device, and then create or import an ONT ID wallet account. This ONT ID will be later used as the credentials consumer ID

**Note:** You can get in touch with the Ontology team to connect a wallet that pays the gas fee on your behalf for on-chain operations.

2.Share this wallet address with Ontology to obtain the SDK configuration file that contains information necessary to invoke the gateway service, including the API key.

### KYC Operations

The KYC information verification process is followed by issuing a credential. This credential can serve as the proof of identity for the user till it expires. The process is mentioned below.

**Note:** ONT IDs do not need to be generated separately. The existing public key of the wallet address is prefixed with the method name, for instance ***did:bnb:1f4B9...766De***. Refer to the method specifications for [Ethereum](https://docs.ont.io/decentralized-identity-and-data/ontid/etho-id/method-specification), [Binanace Smart Chain](https://docs.ont.io/decentralized-identity-and-data/ontid/binance-id/method-specification), and [Ontology](https://docs.ont.io/decentralized-identity-and-data/ontid/ont-id/specification) for more details on how this works.

1. First, take the user’s wallet address to form an ONT ID.
2. The next step is to verify the KYC data collected from the user. Based on the result, the trust anchor server will issue a verifiable credential.
3. Upon authorization from the user, different applications and platforms can process credential data in different ways.

**Note:** Some trust anchors may not support continued re-use of credentials.

### Data Verification

The user KYC data verification logic is as defined below:

1. The user enters their KYC information and submits it for verification. As per the KYC needs of the usage scenario, you can get in touch with our team to enable facial biometric and other modes of verification etc.
2. You send this data with an authentication request via the gateway using the TS SDK.
3. The trust anchor verifies this data and returns a result. If the KYC data is valid, it issues a credential, records its status on-chain, and sends it back to the gateway.
4. You can now use the TS SDK to fetch this credential and prompt the user to store it on their device.
5. You send a request to the user to authorize access to their credential data.
6. Next, you can use the Ontology SDK to process the credential data as and when shared by the user. The credential status can be verified on-chain as per app logic.

## Wallet Support

The credentials issued by the trust anchor verification server can be linked to ONT ID on multiple chains with different wallets. This is achieved by using the user’s wallet address (public key).

For this logic to work, the system should be compatible with the decentralized approach of identity and credential handling, which is to say that the wallet and the credential data can be under the user’s control, and it should be possible for the client to store credentials on their device. The data request process looks something like:

1. The user stores the encrypted credential
2. Once the user signs and authorizes the action using their private key, this action is recorded on-chain.
3. This credential data can now be accessed and processed.

You can use the Java SDK to process credentials and make on-chain verification. This can be implemented with any third party wallet client that supports signing.

Ontology's Chrome extension wallet Cyano, and mobile data wallet **ONTO** support credential management out of the box.


# API Reference

{% hint style="info" %}
Please find the SDK [here](https://github.com/ontology-tech/onttag-sdk-js).
{% endhint %}

## Installation

You can start with importing the `@ont-dev/ont-tag` package by running npm command below.

You can now use the following `import` statement to bring in all the modules from the `@ont-dev/ont-tag` package.

```javascript
import VC from "@ont-dev/ont-tag";
```

The following `require` statement can also be used to load the modules.

```javascript
var VC = require("@ont-dev/ont-tag");
```

To use the methods in a browser, you must use the compiled version of the library. The `browser.js` file is located in the `lib` directory. You can include it in your project using a `script` tag as follows.

```javascript
<script src="./lib/browser.js"></script>
```

Everything will now be available under the `VC` variable. For instance, to fetch the list of available regions, you can invoke:

```javascript
var areaList = VC.utils.areaList;
```

## Usage

### Method list

| Method name                                                                                                                                                               | Description                                                                      |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| [sendUserInfo](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#sending-an-authentication-request)          | Sends authentication request to the trust anchor service with user's KYC details |
| [getSocialAuthLink](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#fetch-third-party-authentication-link) | Fetch URL to initiate social media platform authentication                       |
| [getVcList](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#fetching-credentials)                          | Fetches any issued credentials for previously sent authentication requests       |
| [utils.areaList](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#utility-methods)                          | Returns a list of countries and regions with their respective aliases            |
| [utils.authType](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#authtype)                                 | Returns a list of valid authentication types                                     |
| [utils.chainType](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#chaintype)                               | Returns the list of supported chains                                             |
| [utils.generateId](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#generateid)                             | Generates a valid ONT ID using a wallet addresses                                |
| [utils.serializeSignMessage](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#serializesignmessage)         | Serializes the passed object data to generate a `base64` string                  |
| [utils.createPresentation](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#createpresentation)             | Generates a presentation for the passed credential data payload                  |
| [utils.deserialize](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#deserialize)                           | Deserializes the passed `base64` string to an object                             |

### Sending an Authentication Request

This method is used to send authentication requests for a user's KYC data. It takes two parameters. The first one is an object literal with the KYC info. as defined below, and the second one is your API key.

```javascript
params // parameters to be passed
{
  appId: string,    // Application ID, assigned by Ontology
  region: string,  // Nationality (area alias)
  docId: string,    // Document ID no.
  authType: string,  // Document or authentication type
  frontDoc: string, // Front page image of the selected document (encoded)
  backDoc: string,  // Last page image of the selected document (encoded)
  name: string,     // Legal name as in document
  ownerDid: string  // DID of the user, generated using the generateId utility method
}
```

> **Note:** Both the `frontDoc` and `backDoc` images need to be passed as `base64` encoded strings.

The `region` field takes the respective alias for each region. Use the [`areaList`](broken://pages/-MieUnVe6Pds40bRP_eE#arealist) utility method to obtain the list of countries and their aliases.

The `ownerDid` field takes an ONT ID. You can generate one using the [`generateId`](broken://pages/-MieUnVe6Pds40bRP_eE#generateid) utility method.

The `authType` field specifies the type of document sent for authentication. Use the [`authType`](broken://pages/-MieUnVe6Pds40bRP_eE#authtype) utility method to fetch the list of valid documents.

Call the method with the user info and your API key to send an authentication request.

```javascript
await VC.sendUserInfo({ ...params }, apiKey);
```

It returns `true` for a successful request and an error message if an exception occurs.

| Error Message            | Description                       |
| ------------------------ | --------------------------------- |
| SUCCESS                  | Authentication successful         |
| APP\_NOT\_FOUND          | Passed `appId` not found          |
| REQUEST\_LIMIT\_EXCEEDED | Request limit for a user exceeded |
| SIG\_VERIFY\_FAILED      | Invalid API signature             |
| INTERNAL\_ERROR          | Internal error occurred           |

> **Note:** Each application (identified with the combination of their appid and API key) is limited to sending 10 requests for a user's particular document/authentication method (identified with a user's DID context). Also, in case of an internal error, please get in touch with the Ontology team.

### Fetch Third Party Authentication Link

Invoking this method returns a URL that can be used to prompt user authentication for a social media platform.

```javascript
getSocialAuthLink(ownerDid, authType, apiKey, appId);
```

It takes four parameters.

* `ownerDid`: User's DID
* `authType`: The authentication method (social media platform). [See here](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#authtype)
* `apiKey`: Your API key
* `appId`: Your app ID

The method returns a URL that triggers OAuth authentication for a particular platform.

Once successfully authorized, a credential will be issued that can be used to prove the relationship between a social media account and a DID.

### Fetching Credentials

You can use this method to fetch the issued credentials for a user after having sent a data authentication request.

This method takes two parameters, the DID of the user (or owner in the context of a credential), and the ID document type.

```javascript
const result = await VC.getVcList(ownerDid, authType);
```

If the authentication was successful, the `encryptOriginData` field will contain serialized credential data.

```javascript
{
  authId: '0348xxxx-xxxx-4317-xxxx-8d6f6166a65b',
  appId: 'tesxxxx01',
  credentialContext: 'credential:sfp_passport_authentication',
  description: 'My Shuftipro Passport Authentication',
  txHash: '9494568336a4c2xxxxxxxxxxxxxxxxbaa066e1585fe47',
  status: 1,
  encryptOriginData: 'xxxxxxx', // credential information
  requestTime: 1622156645 // unix timestamp (in seconds)
}
```

| Status | Description               |
| ------ | ------------------------- |
| 1      | Authentication successful |
| 2      | Authentication failed     |
| 0      | Verification in progress  |

> **Note:** The user needs to sign this data to authorize access and prove their relationship with the credential data. After fetching the credential data, you can proceed with generating a presentation with the signed credential data as its payload. The resultant token can then be used for signature verification and access control.

### Utility Methods

`utils` class contains multiple methods that can be used to perform specific tasks. Each method is described below.

#### **`areaList`**

Invoking this method returns an array of all the supported countries and regions with their respective aliases.

The response is structured as follows.

```javascript
[
  { name: 'Afghanistan', alias: 'AF' },
  { name: 'Aland Islands', alias: 'AX' },
  ...
]
```

#### **`authType`**

This method returns the list of supported documents and authentication types as an object.

The response is of the following form.

```javascript
{
  Passport: 'passport',
  IdCard: 'id_card',
  DrivingLicense: 'driving_license',
  Twitter: 'twitter',
  Github: 'github',
  Linkedin: 'linkedin',
  Line: 'line',
  Amazon: 'amazon',
  Kakao: 'kakao'
}
```

#### **`chainType`**

This method returns an object containing valid chain type names.

The response is as follows.

```javascript
{
  ETH: 'etho',
  BSC: 'bnb'
}
```

#### **`generateId`**

Invoking this method with a wallet address prefixes it with the appropriate DID method based on the passed `chainType` and returns a valid ONT ID as a string. For e.g., `did:etho:0xdc6...974a9`.

```javascript
const ownerDid = VC.utils.generateId("0xdc6...974a9", chainType);
```

#### **`serializeSignMessage`**

This method returns a serialized `base64` JWT string. It takes the following parameters:

1. `jwtStr` - The credential JWT string
2. `audienceId` - DID of the credential consumer
3. `ownerDid` - DID of the Credential owner
4. `effectiveTime` - Validity period of the presentation (in seconds). For e.g., 1 day = 86400

The parameters are of the following form.

```javascript
{
  jwtStr: string,
  audienceId: string,
  ownerDid: string,
  effectiveTime: number   // Presentation Effective time, eg 1 day = 86400
}
```

```javascript
const JWT = VC.utils.serializeSignMessage(params);
```

#### **`createPresentation`**

Invoke this method to generate a presentation with credential data signed by the user. It returns the presentation as a JWT string.

It takes an object parameter containing:

1. `signMessage` - Serialized JWT string (using [`serializeSignMessage`](broken://pages/-MieUnVe6Pds40bRP_eE#serializesignmessage))
2. `signature` - Serialized JWT string that has been signed by the user

The parameter object is of the following form.

```javascript
{
  signMessage: string,
  signature: string
}
```

```
const JWT = VC.utils.createPresentation(params);
```

Presentation data can be obtained by deserializing this token. You can perform signature verification and message decryption using the Java SDK. Follow this [link](https://github.com/ontology-tech/onttag-sdk-js/blob/master) for reference.

#### **`deserialize`**

You can obtain the user's verified KYC data by deserializing the `encryptOriginData` string in the credential object received [here](/decentralized-identity-and-data/ontid/ont-tag/verification-via-did-verifiable-credentials-service-integration#fetching-credentials).

This method takes the serialized JWT string as parameter and returns an object containing credential data.

```javascript
const result = VC.utils.deserialize(string);
```

The response object is of the following form.

```javascript
{
  '@context': [
    'https://www.w3.org/20xxxxxxxxxxxx',
    'https://ontid.ont.i20xxxxxxxxxxxx',
    'credential:sfp_passport_authentication'
  ],
  id: 'urn:uuid:861cbae4-xxxx-4844-xxxx-8c8xxxx7052',
  type: [ 'VerifiableCredential' ],
  issuer: 'did:ont:APc8FBxxxxxxxxxxxxxxSUFX2HAnBuBna',
  issuanceDate: '2021-05-28T07:04:23.000Z',
  expirationDate: '2022-05-28T07:04:23.000Z',
  credentialStatus: {
    id: '4f7f159ac4xxxxxxxxxxx5f61b7d0cc6',
    type: 'AttestContract'
  },
  credentialSubject: {
    Name: 'xxxxxxxx',
    BirthDay: 'xxxx-03-09',
    ExpirationDate: 'xxxx-03-12',
    IDDocNumber: 'xx26xxxx86',
    IssuerName: 'Shxxxxro',
    user_did: 'did:ont:5cxxxxxxxx701CbBExxxxx29b'
  },
  proof: {
    type: 'JWT',
    verificationMethod: 'did:ont:APcxxxxxxxxq2BSUFX2xxxxxna#keys-1',
    created: '2021-05-28T07:04:23Z',
    proofPurpose: 'assertionMethod',
    jws: 'ARyjxxxxxxxxxxxxxxxxxxGDisGMJdFE/4erXIazh3n8ipPotTFA+Z4hS09GlhVaio=\\'
  }
}
```


# Mercury

Mercury is a trustless, peer to peer decentralized communication protocol that makes entities be able to securely transmit messages, verifiable credentials, and verifiable presentations with each other.

Using Mercury, each entity has a decentralized identity and is identified using decentralized identifiers. Mercury is decentralized identifier agnostic, that is, supports various decentralized identifier methods defined in the W3C DID method registries. Now it supports ONT ID which is developed by the Ontology team, in the future, it will support more decentralized identifiers, it will even support ENS and other decentralized domain naming systems. Mercury employs cryptographic encryption and signature schemes to protect communication in a secure and privacy preserving manner.

Mercury defines several decentralized identifiers based sub-protocols for building communication connection, transmitting messages, verifiable credentials, and verifiable presentations between entities. The sub-protocol family defined by Mercury includes connection protocol, general (encrypted) message exchange protocol as well as verifiable credential and presentation transmission protocol.

## Basic Architecture

In Mercury, entities talk to each other through agents. There are three kinds of agents in this system:

### User Agent

A user agent is under the control of some end entity, and it can be built as or embedded into mobile apps or other rich clients. It is worth noting that user agents have a most important feature that they cannot be online for 24/7.

Entities can keep the corresponding secret keys and store their verifiable credentials in their local storage and then use user agents to initiate communication or transmit messages securely.

### Cloud Agent

In some business cases where user agents cannot be online continuously, messages and credentials need to be relayed, forwarded and stored temporarily. The cloud agents play an important role in routing the messages. The cloud agent itself has a public decentralized identity and an attribute of service endpoint, so its corresponding secret key needs to be properly kept.

### Service Agent

The service agent itself is also a cloud agent, and it also provides services such as the issuance of some verifiable credentials (such as diplomas from third-party institutions). The service agent should also have a public and certified DID , so it also needs to keep the secret key properly.

## Sub-Protocols

### Connection Protocol

The entities who want to talk with others should establish connections with the communication partners. In Mercury, entities could establish connections using connection protocol.

### General Message Exchange Protocol

After establishing a connection between two entities, they can send messages to each other. Messages which are sent to communication partners could be encrypted and signed using some cryptographic schemes for the privacy preservation purpose.

### Verifiable Credential and Presentation Transmission Protocol

In a verifiable credentials system, there are three roles: the holder, the issuer, and the verifiers. The issuer can issue a verifiable credential to the holder at the holder's request, the holder could generate verifiable presentations from their credentials for some proof purposes. The verifiers obtaining the verifiable presentation can verify the presentations cryptographically.&#x20;

The verifiable credential and presentation transmission protocol defines the methods how the three above roles interact with each other.

For more details, please visit Mercury's [GitHub page](https://github.com/ont-id/mercury).&#x20;


# OScore

Cross-chain reputation and credit evaluation protocol

## Overview

[**OScore**](https://www.ocredit.io/) is a protocol that takes transactional data and assigns a score with the ability to objectively assess the reputation of an account based on specific criteria to the associated ONT ID (or any other DID based implementation) account and addresses based on on-chain behaviour such as:

1. Asset exchange volume
2. Smart contract association
3. Historical holdings
4. Existing credit history

&#x20;The data points that the OScore algorithm takes can be modified and customized depending on the application, platform, or ecosystem. So each application can have a different algorithm to calculate the customized score for addresses and IDs in their ecosystem.

## Characteristics

#### **Consolidation/Aggregation**

Assets and on-chain activity from multiple chains can be linked under discrete IDs

#### Flexibility

Light, API-based plugin for quick integration, SDKs for native integration

#### Security and Privacy

Selective and minimal disclosure of data and attributes

## Usecases

A few examples of how users enabling OScore will benefit both the users and the platforms that integrate ONT ID would be:

#### Credit Score

* Users can redeem credit benefits on DeFi platforms and other credit based services. Here the user can voluntarily produce a reliability quotient in the form of credentials. The platform can determine and confirm the same as the data that is processed by the algorithm is open and public, making the mechanism entirely trustless.

#### Anti-sybil System

* Platforms can integrate a lightweight OScore web plugin (or API) and incentivize users to go through a verification process that consists of different levels of due diligence that a user needs to complete in order to unlock or access specific features and participate in certain campaigns. E.g., ICOs and air drops. Here the privacy of the user is protected as only the necessary information is shared with the platform, and the platform can maximize their reach using compliance.

{% content-ref url="/pages/-MDZdRUCa-PWY0HK\_n8b" %}
[OScore Open API](/developer-tools/api/oscore-open-api)
{% endcontent-ref %}


# DDXF

A brief introduction to Ontology's Distributed Data Exchange Framework

## Introduction

The increasing dependence of businesses, organizations and institutes on internet systems has significantly increased the pressure on existing infrastructures to meet the needs of end users.

As a consequence, there is increasing demand for connected **IoT** or internet systems.

Traditional resource management, including information databases and analytics architectures and infrastructures, remain essential. With the growing data management demands, there are specific needs in terms of sheer capacity and capability to be able to handle diverse and complex data streams from different sources. This data needs to be processed and managed properly to maximize its value in a secure manner, while complementing it with other information sources.

**Ontology's Distributed Data Exchange Framework (DDXF)** defines an infrastructure framework and guidelines to support comprehensive **data processing** and **management**, while incorporating reasonable measures to achieve a **layered**, **data-centric** paradigm. As a result of extensive research on the characteristics of effective data processing and management systems, **DDXF** is focusing on the **data interoperability**, **classification**, **format** and **security issues** that affect various stakeholders.

![DDXF Framework](/files/-LvskNkg09Xg3pGSSol4)

It provides a series of **methods** and **interfaces** to meet the requirements of **trust** and **data interoperability** across **multiple systems**, which serves multiple business requirements and scenarios, especially the **data exchange** scenarios.


# Components and Interfaces

Different components and modules of DDXF

## Components and interfaces

The **DDXF** framework can facilitate performing the following:

* Integrating **multi-system off-chain resources**
* **Tokenize data authority and privileges** and perform **cross-chain resource and token transactions**
* Implementing and realizing **resource** and **data exchange** in the form of **token passing** and changes in **data characteristics**
* **Data processing** and **transaction authentication** rights are supported for **offline resources** and any **off-chain** arbitration, ensuring **shared incentives**.

![DDXF Components](/files/-LvskNl295kh5R4niMqq)

There are three different function modules that the framework offers. Let us take a closer look at each one.

### Self-governed resource and data administration - DToken model

The self-sovereign data management is to decouple **data ownership** and **data accessibility** (or other data processing) **privileges**, thereby allowing for data management on a different level from the data owner(s).

**DDXF** provides a platform that allows for self-sovereign **data administration** using a combination of services such as:

* **Data storage** provides the ability to store data with security features and data privacy at a relatively lower cost.
* **ONT ID** helps identifying different parties such the data itself, the data owner, and the data handler.
* **DToken** allows for **data privilege management**, ensuring that the **data processing** and **storage** is carried out on the Ontology blockchain infrastructure.
* **Ontology blockchain** provides features such as **traceability** and **trust endorsement**.

The **DToken** model defines the following features:

* **Resource modeling and mapping -** Provides **static modeling** and **mapping** functions where the off-chain resources from Internet or `IoT` systems can be stored online in a form of a data model and the online data will be mapped onto with on-chain identifiers.
* **DToken generation -** provides a static identifier mapping capability, where data privileges can be **tokenized** in the form of `DTokens`. The usage of `DTokens` will be controlled from and logged on-chain.

The **DToken model** also provides interfaces to define **entities**, **resources** and **operations** in **DDXF**.

### Decentralized data processing and resource exchange

Decentralized data processing and administration module provides a run time mechanism to **control** the **business actions** of **resource exchange**, **data transfer**, and **data processing**.

The two main features of this module are:

* **Resource Exchange:** Provides the mechanism for token based resource transfer and exchange.
* **Token Usability:** Provides the mechanism to manage token usage, especially DToken usage to access data.

Decentralized data processing and administration module also provides **interfaces** to **process** and **manage data** in **DDXF**.

### Trust Audit

The **DDXF marketplace** provides the ability to carry out **cross system resource exchange**.

As a result of different business models, data can be owned by smart devices, end users, or systems. Data processing changes the form the data. **DDXF** enables **data processing**, **transfer**, and **exchange** with control over **ownership** and **accessibility** of **data instances**. The off-chain resources and the transactions carried out by the end users serves to provide **trust endorsement** for **DDXF**.

The two main features of this module are:

* **Resource audit:** Provides a mechanism to ensure the **ownership** and **accessibility** of off-chain resources, including the **resource quality** and **transaction behavior**.
* **Reputation score:** Based on the usage, transactions can provide trust endorsement for **DDXF**

**Trust audit module** also provides interfaces to implement the **trust endorsement** function for **transactions**, **data credentials**, and the **end users** in **DDXF**.


# GREP

Generic Resource Exchange Protocol Specifications

## Abstract

The Generic Resources Exchange Protocol (GREP) is a set of decentralized resources exchange protocols built on the Ontology main chain infrastructure. By using the GREP, users can quickly establish on-chain attestation and transfer platforms for data and other resources. Thanks to Ontology's comprehensive trust ecosystem infrastructure, including the decentralized identifier ONT ID, the decentralized multi-source authentication system Trust Anchor, the trusted off-chain data connector Oracle, and the decentralized electronic contract and signature system ONT Sign, the GREP can provide a solid foundation of trust for decentralized resources exchange.

![GREP Ilustration](https://github.com/ont-bizsuite/documentation/raw/master/prod-doc/en/ddxf/res/overall.png)

## Resource Tokenization and Assetization

Through the GREP, anyone can quickly and easily establish a diverse on-chain resource attestation and transfer platform. Under the protocol, resources can be digital resources, such as data, CPU computing power, GPU computing power, storage, on-chain Oracle and trusted computing platforms, etc.; they also include some physical resources, such as property, antique calligraphy and paintings. The platform can be a general-purpose platform where multiple resources can be circulated; it can also be a general-purpose exchange platform for the fine-grained circulation of specific resources.

Resource circulation can be in the form of exchanging resource for ONG, OEP-4 tokens, etc., or it can be in the form of resource exchange. Possible forms of resource transfer include, but are not limited to:

* Data resource circulation, such as exchanging medical big data (analysis results) for ONG;
* Circulation of computing power resources, such as exchanging trusted computing power for PAX;
* Circulation of physical resources, such as split auctions of ownership of famous paintings.

The circulation of resources is essentially the tokenisation and transfer of the rights to use the resources. For a resource, it can be its ownership or the right to use that is circulated. Resources with off-chain entities need to be delivered off the chain, and the method of off-chain delivery will be determined by the nature of the resource and other factors.

In the GREP, the Ontology public chain provides an important decentralized foundation of trust.  Each user, including the resource provider, resource consumer, resource verifier and off-chain judge, needs to generate a corresponding **ONT ID** for themselves, and register and/or complete related **KYC authentication** according to the needs of the marketplace. Resources need to be registered on the chain during the transaction. When registering, the unique code of the resource is usually extracted to create a digital fingerprint, and the corresponding **ONT ID** is generated for the resource.

## Token-based Exchange Mechanism

The process of data and resource exchange can be viewed as exchange and transfer of tokens. The process is executed using smart contracts.

### Roles

GREP defines the following roles that implement the token exchange process:

* **Resource Provider (RP):** An entity that can provide and transfer resources-related rights and make them accessible to the market in exchange for some rewards (for example, ONG or some other resources) through a certain pricing system. The resource provider may or may not be the owner of the resource. For example, it can be a resource aggregator. There are many types of such entities, such as data owners, computing power owners, data collection platforms, and data custodians with certain permissions.
* **Resource Consumer (RC):** The counter-party of a resource provider and an entity that is in need of a certain type of resource. The resource consumer pays the resource provider a fee (for example, ONG) in exchange for the (partial) ownership or the right to use the resource.
* **Resource Authenticator (RA):** A third party with certain credentials that has its own resource quality authentication system, according to which it can provide resources or resource providers with a certain way of authentication to enhance the credibility of resources or resource providers. An authentication fee may be charged based on different models. Compared to their non-authenticated counterparts, authenticated resources have more potential buyers and are likely to command a higher fee.
* **Off-chain Judge (OJ):** An off-chain dispute arbiter recognized by both the resource provider and resource consumer of a transaction. Off-chain disputes (for example, the resource consumer did not receive the resources) will be arbitrated by the OJ.
* **Marketplace (MP):** It is the link between the resource provider and resource consumer. It stores the meta-information of resources, provides flexible display and fast search for resources while charging a transaction fee. Each marketplace can provide scalable and flexible services according to the characteristics of its own transactions, such as providing meta-information templates, electronic contract templates for resolving off-chain disputes, etc., for both parties to the transaction. An **MP** generally has a resource transaction pricing system. In addition, the **MP** generally also has a resource transaction information disclosure system, which can disclose transaction information to the public or regulatory authorities.

### Token Transaction Process

Privacy is the top priority in the GREP design process. The GREP is committed to protecting the privacy of personal information and trading information of both parties in the transaction. In addition, another focus of the GREP is that resources (especially digital resources, etc.) themselves and resource metadata will not be uploaded onto the chain.

GREP provides a method to fix the price of a resource. There are different ways to set the price, such as auction pricing, bidding, etc. Two common methods are as follows:

1. **Fixed Pricing:** The RP sets the price when issuing the resource the first time and if interested the consumer must carry out the transaction at this fixed pricing.

```javascript
{
  pricing: fixed // Pricing method
  price: 10.23 // Price
  currency: ONG // Price unit, e.g. ONT, ONG, etc.
} 
```

2\. **Negotiatory Pricing:** The RP does not define a price when issuing the resource. The price is set by  negotiation between the provider and the consumer. The price is then set and updated in the transaction contract.

```javascript
{
  pricing: negotiatory // Pricing method set to negotiatory
}
```

&#x20;The user selects the **MP** where the transaction is to take place according to his own needs. Resources that can be delivered multiple times can be traded in different ways on different **MP**s. For example, the right to use a piece of data can be traded in multiple **MP**s. It is assumed that users, including the **RP**, the **RC**, and the **OJ**, have already completed KYC according to the requirements of the **MP**. The entire resource circulation process involves resource preparation, resource release, resource transaction, profit distribution and post-transaction review.

The complete process is described in the use case section. Resource and data exchange is carried out via GREP by implementing a reputation system that is based on transaction ratings. This is a step towards developing a reliable, trust based ecosystem.

#### Resource Preparation:

1. Registration of the resource on the chain. The **RP** creates an ONT ID on the chain for the resource to be published and generates a corresponding ONT ID Document as a mapping of the resource on the chain;
2. Resource authentication \* (optional) \*. The **RP** obtains authentication of the resources that are to be released from the **RA**;
3. Resource pricing. Specific transaction rights and pricing methods are determined based on the pricing system provided by the **MP**;
4. Generation of resource meta-information. Generate the resource meta-information based on the resource meta-information template provided by the **MP**.

#### Resource Release:

1. Resource submission. The **RP** submits the resource's ONT ID, meta-information, rights to be traded, and pricing method to the **MP**;
2. Resource information processing. The **MP** obtains the information corresponding to the resource from the chain and its own database;
3. Resource display. The **MP** displays the resources so that the **RC** can quickly retrieve the required resources based on the resource meta-information.

#### Resource Transaction:

1. Resource retrieval. The **RC** quickly retrieves the required resources stored by the **MP** according to the resource meta-information and selects the resources that it wants to trade;
2. Signing of the electronic contract for resource transaction \* (optional) \*. The **RP** and the **RC** use the **MP**'s electronic contract template to create an electronic contract between the two parties, appoint the **OJ**, sign the contract via ONT Sign, and record it in the transaction smart contract.

According to the **MP** or contract requirements, the **RP** and the **RC** may need to stake a certain amount of ONG into the transaction smart contract respectively for dispute settlement and post-transaction profit distribution;

1. Tokenization and on-chain transfer of resource rights. The **RP** generates DToken according to the electronic contract, and authorises a certain right of the resource, such as (partial) ownership or the right to use, to the **RC**;
2. Off-chain transaction and dispute arbitration. When the transaction enters the lock-in period, the **RP** uses the DToken in exchange for the right to deliver the resources; if a dispute arises during the lock-in period, the two parties need to submit on-chain or off-chain proofs. The off-chain proofs will be judged by the **OJ** or Ontology Oracle.

#### Profit Distribution

Profit distribution of the transaction. After the lock-in period ends, the profit will be distributed according to the transaction results. The **OJ**'s or Ontology Oracle's arbitration on the dispute may trigger profit distribution in advance.

#### Post-Transaction Review

Post-transaction review. In a reputation system, the **RP** and the **RC** review each other, and the review can be about the resources or users. The ratings obtained by users or resources will affect their rankings on the marketplace and the success rate of transactions.

## DToken

When executing a transaction, the **RP** generates a DToken for the resource (implemented in the form of a smart contract), which includes a reference to the resource's ONT ID, the ONT ID of the DToken holder, and the validity period. DToken can be a homogeneous token, for example, the split of a crowdfunded property. It can also be a non-homogeneous token, such as one-to-one data delivery.

A possible DToken structure is as follows:

```go
type DToken struct {
  Name // The name of the DToken
  Symbol // The symbol of the DToken
  Amount // The amount of the DToken
  ResourceID // The ONT ID of the resource corresponding to the resource 
  RealContractDigest // The record of the e-contract signed by both parties via ONT Sign
  Expires // Validity period of resource rights
  Exchange // The number of times the DToken can be transferred. The DToken cannot be transferred if the number is set to 0
  Status // The status of the DToken, indicating whether it can  be used. The counter method can also be used
}
```

The status of the DToken is initially set to "Unused" (even if the remaining number of transfers is 0). When the holder wants to obtain the right to use off-chain resources from the **RP**, the DToken status needs to be set to "used" first. The DToken in this status can no longer be transferred. When a resource can be "used" multiple times, the status can be set to a number, and the initial value is the number of times the DToken can be used. When the holder wants to obtain the right to use off-chain resources from the **RP**, the number of the DToken status decreases by 1. The value cannot be less than zero. DToken under a certain value can only be used once.

After the **RP** receives a request to use off-chain resources, in order to prevent malicious behaviour, the **RP** will verify whether the **RC** is the current holder of the DToken, and check whether the status of the DToken is available, etc., before transferring the right to use the resources. For example, when a DToken represents the right to use certain data, the DToken and **RC** signature can be used to generate a JWT to access the data corresponding to the DToken.

## Resource verification and audit

Off-chain behaviour, such as the attestation of ownership and legitimacy of resources, involve the identification of behaviors and the determination of rights in the real world. This identification method needs to be agreed by both parties, and if necessary, by a decentralized electronic contract and the signature system ONT Sign. Moreover, in the event of breach, how the off-chain liabilities are handled needs to be specified.

&#x20;Since there may be off-chain disputes, for example, the resource provider has not delivered resources off the chain, the two parties to the transaction usually sign an electronic contract via **ONT Sign** to clarify how to settle off-chain disputes. The off-chain judge, which is jointly designated by both parties when signing a contract, is a more reliable and efficient way to resolve off-chain disputes. The off-chain judge or its delegate (for example, the marketplace) puts the result of the dispute arbitration onto the chain. The off-chain judge does not handle on-chain disputes, which are resolved directly through on-chain proofs. In addition, some off-chain proofs can be uploaded onto the chain through **Ontology Oracle**, and a direct ruling can be made on the chain.

## Extension

GREP is an open public protocol. As the technology becomes more advanced and the ecosystem evolves, GREP's features will also grow simultaneously to keep up with the growing needs.

GREP supports the pricing of resources and provides resource transactions based on pricing. In the actual transaction process, Token payment is supported. Since the current token assets of the blockchain are located on multiple chains, GREP supports cross-chain asset transactions.


# Overall Scheme

Possible DDXF scenarios

DDXF facilitates data resource exchange while ensuring data privacy protection and traceability. Its characteristics are as follows:

* Data interoperability
* Across off chain systems
* On-chain features and techniques

## Resource Exchange Process

The process that takes place on the marketplace through which resources are exchanged between the provider and the consumer as follows:

#### 1. Resource Preparation

* Resource digitization (secure storage)
* Data resource attribute extraction

#### 2. Resource Issue (Marketplace)

* Resource verification
* Resource exchange metadata assignment
* Transaction contract confirmation
* Contract safety bond payment

#### 3. Transaction

* Requirements confirmation, resource processing workflow
* Resource integration, transaction generation
  * User delegation and data characteristic mapping
  * Contract order generation
* Transaction execution
  * Smart contract driven data processing and resource exchange
* Instant dispute settlement and arbitration

## Resource Preparation

The provider generates an ONT ID and a DDO on the blockchain for the resource that is to be published. This serves as an on-chain mapping entity for the resource.

The **RP** can invite a **RA** with certain credentials to authenticate the resources before release, so as to improve the credibility of the resources on the market. Generally speaking, highly trusted resources will have more potential buyers and may command higher fees, and will be more easily retrieved in the marketplace. Resource authentication can be done by the **RA** by issuing verifiable credentials to related resources, or by uploading the physical certificate of the resources onto the chain via **ONT Sourcing**.

The **MP** will provide some corresponding meta-information templates for specific resources, so that the **RP** can easily extract meta-information when publishing data. For example, a medical data marketplace will provide medical data metadata templates. When the **RP** prepares to conduct data transactions in an **MP**, it generates the corresponding meta-information for the resources to be released according to the **MP**'s meta-information template for the retrieval and selection of the **RC**. When making the format of the meta-information template, the **MP** should meet certain specifications and provide necessary information accordingly.

The **MP** determines the pricing system based on the characteristics of the resources. The **RP** determines and submits its pricing method in a way approved by the **MP**. Common pricing methods include fixed pricing, dynamic pricing, and auctions. Once again, it should be emphasized that resource transactions are essentially the transfer of resource-related rights.

### 1. Data Value Confirmation

After the **RP** provides the resources, the resource authentication API provided by the marketplace or the platform-defined data is stored in the **RA**. The **RA** can use trust anchor to perform resource authentication for the relevant data, or directly store the entity certificate through ONT Sourcing certification. After the resource authentication is successful, the **RP** can proceed with data tokenization.

Please refer to the link below for details on resource auditing.

{% content-ref url="/pages/-MAZWTLqHg0Pbwn1ZAC0" %}
[Resource Auditor](/decentralized-identity-and-data/ddxf/solutions/resource-auditor)
{% endcontent-ref %}

### 2. Data Tokenization

After the **RP** applies for the value confirmation or verification of the resource, the marketplace can be used to tokenize the resource (the tokenization). The data transfer carried out by the marketplace denotes the circulation of the tokens.

Please refer to the Resource Publication section below for more details on how the tokens are generated.

### 3. Data Privileges

Based on the **DToken** contract, when tokenizing data, you need to pass the **RPs** account, the `dataid` of the resource, the ONTID of the controller, etc., to bind people, property, events, and things. The incoming controller has control of the data privileges, the essence of resource transactions is the conversion of Token permissions. After **RC** purchases a Token, you can use it to view the specific details of the data.

{% content-ref url="/pages/-MA\_jJgN0AZK3DPR0Kna" %}
[DToken Contract API](/developer-tools/api/dtoken-contract-api)
{% endcontent-ref %}

### 4. Data Evaluation

After the resource passes the **RA** certification, the resource is tokenized. After ensuring that the resource meets the standards of the third-party certification authority, the frequency of the data circulation can be judged to further evaluate its value. You can refer to the openbase credibility system to formulate a series of value systems for tokens by offering incentives for upholding contracts.

## Resource Publishing

The **RP** publishes resources to an **MP** and waits for the **RC** to purchase. The published content includes the resource's ONT ID, associated ONT ID Document information, meta-information, rights to be transferred, pricing strategy, and authentication information (if the resource has any) of the resource from one or more third-party authentication centers. The **MP** stores the resource metadata and other information into a local database and optimizes information retrieval. The **MP** will also display related historical transaction information, authentication information, and other information from the chain.

The reviews of users and resources in previous transactions will be converted into equivalent scores under a certain distributed reputation system. The scores will affect the rankings of users or resources on the marketplace and the success rate of transactions.

There could be several different **MP**s, such as the medical data marketplace and antique auction marketplace. Each marketplace accepts and exhibits different types of resources based on its own market characteristics, and the same resource can also be published on different marketplaces.

### Data Token Transactions

#### **E-Shop Mode**

The initial holder of the DToken is the **RP**, and the DToken can then be transferred (via transactions) to others. The **RP** can set a limit on the number of transfers allowed for the DToken. The number of transfers decreases with each transfer. If the number of transfers is 0, it means that the DToken can no longer be transferred.

Certain basic data fields and information needs to be provided in order to carry out token generation before publishing a resource, such as the token volume, resource ownership period time limit, marketplace SDK methods available to invoke the DToken contract and the marketplace purchasing contract.

#### Data Mode

When uploading resources, the **RP** needs to upload the token generation parameters together, and then when the **RC** performs the purchase operation, the DToken contract and **MP** purchase contract are invoked through the SDK methods provided by the marketplace.

The marketplace provides an SDK for querying the on-chain data chain. The platform needs to be integrated into its own project so as to allow users to view the description of the data. The platform can customize the exchange method, such as online or offline transaction tokens.

{% hint style="info" %}

#### Off-chain Conflict Resolution and Arbitration

After the **RC** executes the purchase operation, it can have all the rights of the token. When the **RC** applies for arbitration, the **MP** arbitration contract will pledge the token. When the **OJ** determines that the **RP** has not provided the resources and sends this result to the transaction  smart contract, it handles the resolution process accordingly.
{% endhint %}

## Resource Transaction

After the resource retrieval phase, that is, after the **RC** quickly retrieves the required resources based on the resource meta-information at the **MP**, the **RC** will conduct transactions with the **RP**, the owner of the required resources. The resource transaction process roughly includes the following steps:

1. **Place an order:** The **RC** quickly retrieves the required resources according to the resource meta-information at the **MP**. The two transacting parties sign an electronic contract for resource transaction via ONT Sign, set the subject matter of the transaction (such as the right to use the resources), transaction details, and staking information of both parties (optional), transaction lock-in period (optional), dispute resolution logic, profit distribution logic, etc., and then create the smart contract. In order to prevent malicious behaviours, the **RP** and the **RC** each need to stake a certain amount (it may be 0) of tokens according to the electronic contract;
2. **On-chain transactions:** The **RP** generates the DToken on the blockchain for the transaction of resource rights, and transfer the DToken to the **RC**. The **RP** can also authorise the **MP** to generate the DToken. The **RC** can trade the DToken per the contract:
3. When the transaction of DToken does not involve the delivery of off-chain resources, it can be in the form of atomic transactions without setting a transaction lock-in period;
4. When the transaction is in the form of resource exchange, the **RC** will also generate DToken for the resource that is to be traded. Of course, the DToken can also be generated by an authorised **MP**. DTokens can also be traded in the form of atomic transactions, and can set a transaction lock-in period based on whether off-chain delivery is required;
5. When the transaction is in the form of exchanging resources for tokens (such as ONG), the token holder stakes a required amount of tokens into the transaction contract and sets a transaction lock-in period based on whether off-chain delivery is required;
6. &#x20;**Off-chain resource delivery:** After the on-chain transaction is completed, the transaction lock-in period is triggered. During the lock-in period, the **RC** uses the DToken to receive the resources from the **RP**, that is, the rights to use the resources change hand. When a dispute arises, proofs need to be submitted to resolve the dispute. There are on-chain and off-chain proofs. The proofs can come from the Ontology blockchain, Ontology Oracle, and the **OJ** specified in the contract.

![Resource Transaction Process](/files/-MAtkg3YOVEv4WHLzL7j)

### Electronic Contract

After going through the resource discovery stage, the **RC** quickly retrieves the required resources based on the resource metadata at the **MP**, and both parties can sign the relevant resource transaction electronic contract via ONT Sign. If the resource transaction process does not involve **OJ**, i.e. **OJ** is not required for off-chain judgment, it is not necessary to sign an electronic contract.

According to the characteristics of its tradable resources, MP can set up electronic contract templates to guide its users to quickly sign electronic contracts. Generally speaking, electronic contracts mainly include the following:

* **Transaction subject matter.** The subject matter of the transaction is a certain right of a certain resource.
* **Trading party.** Mainly specifies the **RP** and **RC** of the transaction.&#x20;
* **Trading rules.** Mainly stipulates the delivery period, delivery stage, delivery method, etc.
* **Transaction lockout period and dispute handling logic.** When it comes to delivery and disposal of off-chain resources, it is recommended to set a transaction locking period and set dispute handling logic. During the transaction lock period, both parties to the transaction can deliver off-chain resource rights. When a dispute occurs in an off-chain transaction, the dispute is resolved in accordance with the dispute handling logic, and the result of the dispute is recorded on the chain. Generally, the chain of dispute resolution results is carried out by OJ. In addition, [**Ontology Oracle**](/ontology-elements/oracle) system can also be used for off-chain dispute resolution.
* **Both parties pledge information.** It is agreed whether the two parties of the transaction need to pledge a certain amount of tokens. In general, **RC** will be required to pledge tokens that are at least equivalent to the price required to obtain the subject of the transaction to make the transaction smooth. Sometimes, **RP** may also be required to put in a certain amount of tokens as security deposit to prevent them from doing malice.
* **Profit distribution:** It mainly stipulates how to divide the profit after the transaction is completed. The suspension or cancellation of the transaction is also considered a way of completion. Split run is mainly carried out between the parties to the transaction, **MP** and **OJ**.

### Transaction Contract

During the transaction lock-in period, the **RC** uses the DToken to receive the resources from the **RP**, that is, the rights to use the resources change hand. During the lock-in period, disputes may arise due to problems occurred during the transfer of resources-related rights.

Under normal circumstances, since the automatic profit distribution logic usually transfers the transaction fees of the **RC** to the **RP** after the transaction lock-in period ends, the settlement of transaction disputes is generally initiated by the **RC**. The initiator of the transaction dispute arbitration needs to stake a transaction dispute application fee, which can be paid in the form of a deposit when the transaction is established. The losing side of the dispute arbitration will pay the costs incurred and possible fines. When the transaction dispute arbitration rules that the initiator loses, the transaction dispute application fee will be used to pay the arbitration fees; if the other party loses, then its stake is usually used to pay the arbitration fees.

For one transaction, due to the existence of the contract and the **OJ** jointly designated by the two parties, the result of the first dispute arbitration shall prevail.

When a dispute arises, proofs need to be submitted to resolve the dispute. The tamper-proof, open and transparent blockchain, as well as the automatically executed contracts, help improve the transparency of the data transaction process, can record the process of disagreement, and facilitate the transacting parties (the **RP** and the **RC**) to submit the necessary proofs. In order to increase the transaction processing speed and the degree of automation, the conditions for the success or failure of the transaction need to be defined. For example:

* Whether the **RP**'s resources are accessible during the transaction lock-in period. If the **RP** cannot provide this proof, the transaction will fail;
* If the **RP** submitted the **RC**'s record of resource delivery, the transaction will be successful.

Each condition corresponds to a validation logic. When a dispute arises, proofs need to be submitted to resolve the dispute. There are on-chain proof and off-chain proof.

* The verification of on-chain proofs is done directly by the blockchain nodes. Common on-chain proofs include digital signatures, preimages on Hash functions, zero-knowledge proof, Merkle Proof, and so on. The off-chain information imported into the chain through Ontology Oracle can also be considered as on-chain proof and is processed by relevant processing logic;
* When there is a dispute that cannot be settled on the chain, then an **OJ** is required to complete the verification of the off-chain proof. The **OJ** completes the confirmation and arbitration of the off-chain transaction according to the electronic contract signed by the two parties via ONT Sign and sends the arbitration result to the smart contract of the transaction. The arbitration result is part of the dispute settlement.

The proof of dispute liability determination, whether it is on-chain or off-chain proof, will affect the outcome of dispute liability determination, which in turn will affect the profit distribution of transactions. The determination of the liability for the dispute may trigger profit distribution in advance.

## Resource Incentive Sharing

&#x20;After the transaction lock-in period, that is, after the off-chain resource transfer period ends, the transaction will enter the profit distribution phase. Profit distribution is mainly between the two transacting parties, the **MP**, and the **OJ**. Profit distribution is a relatively broad concept, including returning the staked token to both parties and distributing transaction fees to the **MP**. Either party of the data transaction can trigger profit distribution, which will automatically distribute the profit based on the preset logic.

* If there is no dispute, profit distribution will be triggered automatically when the lock-in period ends.
* If an arbitration occurs, then the profit distribution operation will be triggered automatically according to the arbitration result when the lock-in period ends.

Transaction success, termination, or penalty for malicious behaviour are all a form of profit distribution.

The conditions for the success or failure of a transaction formally define the possible status of the transaction and the corresponding judgments to execute the appropriate profit distribution strategy accordingly. For example, the profit distribution strategy defines that when the **RP** cheats, the staked token of the **RP** will be confiscated when a dispute occurs. Then if the **OJ** rules that the **RP** did not provide resources and puts the result into the transaction smart contract, the contract will be executed accordingly.

### Profit Distribution Policy

**In case of no disputes**, the incentive is shared as per policy.

* The marketplace platform uses the contract to set transaction fee rate, deposit rate, and the arbitration fee rate.
* **RP** receives the resource deposit amount
* **RC** receives the resource tokens
* The marketplace platform receives the transaction fee

**In case of a dispute**, the incentive is distributed based on the dispute resolution result.

* The marketplace platform can use the contract to set transaction fee rate, deposit rate, and the arbitration fee rate. Before publishing a resource, the RP needs to pay a resource deposit, and the RC needs to pay transaction fees to the marketplace platform.
* If a party initiates arbitration, the arbitration fee shall be paid by the concerned party, and the fee shall be pledged into the **MP** arbitration contract through the API.
* If the initiator is judged to be unsuccessful by **OJ**, the final arbitration fee will be owned by **OJ**. The commodity fees paid by **RC** in advance will be distributed to both parties by **OJ** through the **MP** arbitration contract interface. The **MP** platform will finally get the transaction fee when **RC** carries out the purchase.

{% hint style="info" %}
The various fees with respect to the marketplace are calculated as follows:

*Resource Deposit* **=** *Resource Price* **\*** *Deposit Rate*

*Platform Transaction Fees* **=** *Resource Price* **\*** *Platform transaction fee rate*

*Arbitration Fees* **=** *Resource Price* **\*** *Arbitration fee rate*

The **OJ** needs to be hired and provided by the **RC.** Generally speaking, an arbitration is triggered by the **RC** in most cases.
{% endhint %}

{% content-ref url="/pages/-MAuVpVhHUl10SrBJFwW" %}
[Offline Judge](/decentralized-identity-and-data/ddxf/solutions/offline-judge)
{% endcontent-ref %}

## Post-Transaction Review

After the transaction is completed, the **RP** and the **RC** review each other. The review can be about the resources or users. The **MP** can provide a review system and the post-transaction reviews are stored in the **MP**'s local database. When the on-chain review system is well-established, the **MP** can use a combination of the on-chain review system and local review system to present a more accurate rating.

Please proceed to the next section for more details regarding the currently available solutions.


# Solutions


# Marketplace

Data resource exchange platform

{% hint style="info" %}
This model allows one to register a marketplace and then register off-chain resources or data to the platform to allow exchange between the provider and the consumer. The exchange process of the All the roles and components described below have been defined in, and are derived from the [**Generic Resource Exchange Protocol (GREP)**](/decentralized-identity-and-data/ddxf/grep). Please refer to the protocol specifications for more details.
{% endhint %}

## Marketplace Resources

The marketplace basically facilitates resource exchange on an open platform.

The process one would follow to enable the marketplace to be able to publish resources can briefly be outlined in the following manner:

#### 1. Domain registration

The domain that helps identify the marketplace needs to be registered on the blockchain and in the Ontology system. It involves these steps:

* **ONT ID registration:** Identifies the marketplace and the owner
* **Payer registration:** Account that pays the operation costs
* **ONS registration:** Registering the domain name on the Ontology name server

#### 2. Marketplace setup

You may choose to use the [**Ontology generic marketplace server**](/decentralized-identity-and-data/ddxf/solutions/marketplace/saas-tenant) for your solution, or [**deploy your own**](/decentralized-identity-and-data/ddxf/solutions/marketplace/deployment). The next step would be configure the marketplace you deployed.

#### 3. SDK invocation

Link to the [**data storage provider**](/decentralized-identity-and-data/ddxf/solutions/data-storage) by invoking the marketplace SDK in your application. The ONT ID for your application also needs to be enabled at this point.

#### 4. Resource auditors

Choose the [**resource auditors**](/decentralized-identity-and-data/ddxf/solutions/resource-auditor) and [**offline judgers**](/decentralized-identity-and-data/ddxf/solutions/offline-judge) for your marketplace platform.

## Marketplace Runtime

The process to enable the marketplace for your end users is as follows:

### 1. Calling resource data mapping and upload&#x20;

The RP needs to set up a storage service for the data resources that are to be published on the marketplace. Once the storage service is in place, the marketplace API or SDK methods can be used to generate `DataId` for the respective data items and then link them to the marketplace platform using this ID.

### 2. Fetching a claim from the resource auditor

The RP needs to fetch a verifiable [**claim**](/glossary#claim) from their resource auditor.

### 3. Generating a data identifier

Use the marketplace API or SDK method to fetch the QR code to authenticate the `DataId` for the respective data items using [**ONT Auth**](/discover#ontology-authenticator).

The SDK method or the API can be used to confirm if the authentication was successful. If the authentication is successful, the platform automatically links the `DataId` and the respective data resources.

### 4. Choose a marketplace model&#x20;

There are two marketplace models available currently.

#### Pay-as-you-go

**pay-as-you-go** model is as such:

1. The **RP** needs to link the `DataId` with the resources after pre-uploading the data
2. &#x20;**RP** uploads the data and passes the necessary parameters to generate the token
3. The **RC** makes a purchase on the marketplace, the token is generated, and the ownership is transferred to the **RC**
4. RC can use the token to gain access to the data resource and the meta data
5. Once the purchase is deemed successful, the transaction costs are allocated to the marketplace as per the fixed policy

#### Pre-order&#x20;

This model involves generating DTokens to carry out transfer of off-chain data on the data storage provider.  The exchange process of the **pre-order** model is as such:

1. The **RP** needs to generate and link the `DataId` with the resources after pre-uploading the data
2. After the `DataId` is generated, the parameters to generate the DToken need to be passed, such as the amount of tokens to be generated, etc.
3. The `DataId` and DToken are linked and the data is uploaded to the platform
4. The **RC** can make a purchase by choosing to either buy all the tokens, or a certain amount with respect to a particular resource
5. **RC** uses the token to access the resource meta data
6. Once the purchase is deemed successful, the transaction costs are allocated to the marketplace as per the fixed policy

Publishing a resource on the marketplace platform consists of the following steps:

1. Data quality verification
2. Publishing the meta data
3. Publishing the price
4. Lock the safety deposit to the marketplace smart contract
5. Define a offline judger candidate list for the transaction contract
6. Publish the resource on the platform

### 5. DToken exchange

In the case of an [**E-shop**](/decentralized-identity-and-data/ddxf/use-cases/e-shops), carrying out a transaction with would involve token generation using the passed parameters which would determine the total volume of the tokens, the contract is then invoked and the action can be authenticated using [**ONT Auth**](/discover#ontology-authenticator).

**Sample Parameters:**

```javascript
{
  dataId: "did:ont:aaaaaaa", // Data ontid
  ontid: ontid, // RP ontid
  pubKey: 1,
  contractVo: {
    argsList: [{
      name: "account",
      value: "Address:aaaaaaa" // wallet address
    }, {
      name: "dataId",
      value: "String:" + dataId // data ontid
    }, {
      name: "ontid",
      value: "String:" + ontid	// RP ontid
    }, {
      name: "index",
      value: 1
    }, {
      name: "symbol",
      value: "String:aaa"
    }, {
      name: "name",
      value: "String:aaa"
    }, {
      name: "amount",  // Token amount to be generated
      value: 12
    }, {
      name: 'transferCount',
      value: 12
    }, {
      name: 'accessCount',
      value: 12
    }, {
      name: 'expireTime',
      value: 16121212		// Token expiration time
    }],
    contractHash: "06633f64506fbf7fd4b65b422224905d362d1f55",	// contract hash
    method: "createTokenWithController",	// contract method
  }
}
```

The API can be used to verify the authentication result. The QR code parameters can be fetched using the SDK method or the [**storage API**](/developer-tools/api/ddxf/storage-api)**.** After the `DataId` and the tokens are linked the data can finally be uploaded to the platform.

Once the RC makes a purchase, the transaction will be carried out with the token amount selected. In data mode, the defined amount of tokens will be generated and the ownership will be transferred to the RC.

### 6. Incentive sharing

Incentives and profit are shared based on the respective fixed policies. Please refer to the [**resource incentive sharing**](/decentralized-identity-and-data/ddxf/overall-scheme#resource-incentive-sharing) section in the over all scheme for details.

### 7. Transaction evaluation and rating

After the transaction is completed, the **RP** and the **RC** review each other. The review can be about the resources or users. The **MP** can provide a review system and the post-transaction reviews are stored in the **MP**'s local database. When the on-chain review system is well-established, the **MP** can use a combination of the on-chain review system and local review system to present a more accurate rating.

## Hosting a Resource Exchange Platform

#### Step 1: Deployment

Refer to the link below for details on marketplace deployment process.

{% content-ref url="/pages/-MAUKfEZW6-WbiMkQR-A" %}
[Deployment](/decentralized-identity-and-data/ddxf/solutions/marketplace/deployment)
{% endcontent-ref %}

#### Step 2: Smart Contract API Integration

For API and SDK reference please follow the links below.

{% content-ref url="/pages/-MAzFFxo2QC2Ndq6lgwU" %}
[Marketplace Contract API](/developer-tools/api/ddxf/marketplace-api)
{% endcontent-ref %}

{% content-ref url="/pages/-MAzFL0T1GUyoUwOOyIg" %}
[Storage API](/developer-tools/api/ddxf/storage-api)
{% endcontent-ref %}

#### Step 3: Marketplace SDK Invocation

Please follow [**this**](https://github.com/ont-bizsuite/marketplace-addon) link to access the Java SDK repository.

#### Step 4: Proceed with the flow specific to your scenario


# Deployment

Deploying a custom marketplace

Deploying a marketplace involves the following steps:

* Deploying a smart contract
* Deploying a docker image
* Smart contract and server configuration
* Execution

More details to be updated soon!

For more technical details and solutions specific to your case, please get in touch with us at [**Ontology**](https://ont.io/contact/).


# Scenarios

Marketplace solution potential rundown

**DDXF** mainly aims to provide solutions that deliver data interoperability across off-chain systems, with on-chain techniques to provide data privacy protection, data traceability for data processing and management.

Potential scenarios for the marketplace based solution are as listed below.

##


# SaaS Tenant

Use Ontology's generic marketplace server

More details to be updated soon!

For more technical details and solutions specific to your case, please get in touch with us at [**Ontology**](https://ont.io/contact/).


# Java SDK

Marketplace SDK reference

More details to be updated soon!

For more technical details and solutions specific to your case, please get in touch with us at [**Ontology**](https://ont.io/contact/).


# Data Storage

Data Storage service using Ontology's DDXF

Data is a form of resource, be it simulated data or any other type of discrete data.

Data is also diverse in the sense that static data can be stores once and used perpetually, since it does not change, while dynamic data updates constantly and the records must be updated in real time in order to maintain it's integrity.

Considering data privacy, certain data can be made available to the consumers in the form of copies or duplicates. Some data can also be made available such that the data provider is not exposed, while the data can only be processed using an algorithm (provided by the data consumer) and the final result is shared with them.

{% hint style="info" %}
All the roles and components described below have been defined in, and are derived from the [**Generic Resource Exchange Protocol (GREP)**](/decentralized-identity-and-data/ddxf/grep). Please refer to the protocol specifications for more details.
{% endhint %}

## Data Storage and Processing

Generally speaking, the **RP** (resource provider) needs to arrange the storage and access services for the data that is to be made available for purchase.

There are several different storage options. The **RP** may choose to setup and use their own storage service or they may use storage services such as cloud storage, or use decentralized storage platforms like **ONTFS**. If data is stored on a hosted platform, data security and integrity can be ensured using cryptography and other techniques, as necessary.

When an **RC** wishes to access the data, they need to send a request token to the data storage service. The request token can be a JWT token generated by the **RC** by signing a DToken.

Before granting access, the data service needs to check the validity of the DToken by querying the blockchain explorer, fetch the DToken's owner details (public key linked to the ONT ID), and verify the validity of the JWT token.

Once the verification is successful, both parties use the ONT ID to set up a secure data transfer channel, and transmit the data.

There are two methods for data access:

**1.Fetching the data directly.** This can be viewed as a transfer of ownership with respect to a copy of the data. Other permissions such as the authority to transfer, etc. can be fixed on the basis of transaction terms. The data can be decrypted and processed as necessary.

* **RC** fetches the data from the storage service via the secure channel. For instance, real time data streaming is carried out via the secure channel to transfer data to the **RC**;
* If the data is encrypted (stored encrypted on the hosting platform), the **RC** needs to send a request to the **RP** in order to obtain the decryption key. **RP** first needs to confirm the identity of the party sending the request, and then send the decryption key to the **RC**. Other cryptographic techniques can be used to enhance data security when transferring data. For example, proxy re-encryption can be used to transfer the encrypted data in order to reduce the number of times data is encrypted and decrypted<br>

**2. Request to analyze results.** This can be viewed as a permission to access the data. If the **RP** does not wish to share the original, raw data with a consumer, they may use this method. The **RC** first provides the algorithm that needs to be run on the data. The algorithm is then executed with the data, and finally the result is shared with the **RC** via a secure channel. The data processing environment to execute the algorithm can be provided by the **RP**, or a third party platform may also be used.

To ensure the privacy and security of the data during the execution process, the **RP** can first ensure the environment is suitable for the same before proceeding with the real data and the algorithm.

If the **RC** isn't willing to share the algorithm with the **RP**, they may choose to carry out the data processing in a reliable third party environment. The third party carries out the execution, and then shares the result with **RC** and **RP** as per the contract terms.

## Data Privileges and Management

The `DToken` protocol is used to generate tokens that signify data access and ownership privileges. This tokenization is carried out by the using the underlying blockchain technology of Ontology.

The data access permission token attributes of  in `DToken` adheres to the system token privilege management specifications. The token attributes use the resource exchange and data processing and interaction processes that are part of the marketplace and assures blockchain technology's high security, tamper-proof, and traceable system characteristics.

## Self-sovereign Data Usage

Data can be cleared, modelled, and analyzed to create new data. This new data also has an ONT ID. To enhance self-sovereign features for the data, the ONT ID document can be extended in the following manner:

```go
type DataDDO struct{
  Name // Data name
  Fingerprint // Unique digital fingerprint of the data, required to generate an ONT ID for the data
  Description // Brief description
  Protocol    // Storage and access protocol, for e.g. HTTPS, IPFS, etc.
  Location    // Access path or address
  SourceData  // Original data list, ONT ID of original data
  Transformer // ONT ID of the party that processed the data
}
```

One method of extension could be where the above described structure can be included in the ONT ID `attribute`.

Based on the differences in data structure, the way a digital fingerprint is drawn also varies. Static data uses the hash value. Big data can be divided into groups and generate a merkle tree, then use the merkle root as the fingerprint. Dynamic data can use the unique identifier of the data source.

When details regarding the available data is published, the metadata should be provided. The metadata is open for the consumers to explore and make a choice. The metadata should follow a standard. The recommended standard can be found at [schema.org](http://schema.org/).

### Data Description Template

A unique identifier should be allocated for the data that is transmitted to the chain, which is the data ONT ID generated by the provider. The publisher also submits other details regarding the data. The publisher can be an individual or a group, determined based on the ONT ID structure. Besides, there is more data that can be included in the metadata structure, such as the version no., license no., etc.

The metadata template can be modified as necessary based on the market being targeted. The **RP** fills in the necessary metadata details to generate the metadata when publishing the data. The following is a sample metadata template that illustrates a valid structure:

```go
{
    @context: ["https://ddxf.ont.io/schema/v2","http://schema.org"],
    @type: Dataset,
    identifier: did:ont:xxxx....,
    name: sample data,
    description: "Just a sample for structured data",
    keywords: "sample, structured",
    publisher: {
      @type: Person,
      identifier: did:ont:yyyy....,
      name: My Name,
      ...
    },
    datePublished: 2019-01-01T00:00:00Z
    owner: {...},
    version: 1,
    expires: 2020-02-01T00:00:00Z,
    license: "http://example.license.com/v1"
    ...
  }
```

There are some necessary fields in the above template that must be included in the structure:

* **@context:** Specifies the context table of the schema. The first value must be `https://ddxf.ont.io/schema/v2`. The second value in the above sample is `http://schema.org`, which imports the schema.org methods;
* **@type:** Specifies the data type of the respective data, must be one of the types that are defined in the previously defined context;
* **identifier:** Unique identifier of the data resource, a valid ONT ID;
* **name:** Data resource name;
* **description:** Brief description of the contents of the data resource;
* **keywords:** Keyword that makes the data resource searchable. Multiple key words can be specified by separating them using commas.
* **publisher:** The data provider, target can be **person** or **organization**. The `identifier` field specifies their ONT ID, and there are other optional fields such as name, email, etc. that may be specified.

There are other optional fields that are part of the structure:

* **owner:** The data owner, the target may be `Person` or `Organization`;
* **version:** Data version no., maybe a number or a character string.
* **expires:** Data expiry date;
* **license:** License agreement for data usage;

### Data Processing and Transactions

ONT ID and DDO help maintain a complete record of data processing and proof of consistency.

![Data Processing](/files/-MAPcWut5y_6ABliQf-H)

In a data transaction scenario, it must be ensured that a situation where **RP**'s data server cannot be accessed does not occur. If **RC** can't access the data, the deposit tokens are refunded to their address. We can use digital signatures to determine whether the **RC** was able to access the data server by making sure that the **RC** provides a valid signature when they access the data server. (This signature can be verified using the **RC**'s ONT ID)

Generally speaking, a few commonly used forms of proof are:

* **Digital Signature:** The infallibility of digital signatures can be used to help the **RP** establish that they did provide data access.
* **Original Image of the Hash Function:** Can be used to record any abnormalities or changes that may occur with respect to the data during transmission, such error logs, illustrations of the error process, etc.

## Data Storage Service

Please use the links below to navigate to the relevant section.

{% content-ref url="/pages/-MAPicTh0ZBtSvG04TJ3" %}
[Deployment](/decentralized-identity-and-data/ddxf/solutions/data-storage/deployment)
{% endcontent-ref %}

{% content-ref url="/pages/-MAzFL0T1GUyoUwOOyIg" %}
[Storage API](/developer-tools/api/ddxf/storage-api)
{% endcontent-ref %}

{% content-ref url="/pages/-MAPija0l2nMQLgdyR8B" %}
[Java SDK](/decentralized-identity-and-data/ddxf/solutions/data-storage/java-sdk)
{% endcontent-ref %}


# Deployment

Deploying the storage service

To be updated soon!


# Java SDK

Storage SDK documentation

To be updated soon!


# Resource Auditor

DDXF resource auditor solution for resource providers

The resource provider that wishes to avail this service can select the auditor to verify the data before generating the `dataid`. The auditor can use the marketplace API to access the data that is to be verified.

The auditor can also choose to perform claim verification via trust anchors. Once the verification is complete, the party can proceed with other operations.

#### Marketplace API

Marketplace API can be used to fetch details regarding the data using the `orderId`. The auditor fixes the data verification result parameter.

```yaml
 {
    orderId: 'orderId',
    isCer: true,
  }
```

#### Trust Anchor Data Verification

For details, please refer to the claim issue section.

Once the verification process is completed, the marketplace automatically synchronizes the verification details.


# Offline Judge

An arbitrator to help resolve disputes off-chain

An arbitration consists of the following:

* Arbitrator
* Arbitration scheme
* Execution result/outcome
* Arbitration contract

The resource arbitrator proposes the arbitration of data. The arbitrator queries the required arbitration data according to the API provided by the Marketplace, and publishes the execution results as per the arbitration scheme in the signed arbitration contract.

### Arbitration Process

The order data necessary for arbitration is fetched through the API provided by the marketplace, the arbitrator determines the success and failure of the arbitration according to the arbitration contract, and performs the contract on-chain operation. The required parameters are passed through the API provided by marketplace and return the QR code string.

![Sample QR Code](/files/-MAui9umwEK0szPtBUSC)

After the arbitration is completed, the funds will be automatically sent to the wallets of both parties (demand and provider) according to the results. The two parties can also query the order status (including the arbitration result) using the marketplace AP&#x49;**.**


# Use Cases

Current use cases for the DDXF framework


# E-Shops

Data marketplaces for exchange between data providers and potential consumers

To be updated soon!


# Smart Contracts

Units of logic and functionality

![](/files/-LwSe4KvYfSuN-uwqUOF)

## Abstract

Smart contracts are by no means a new concept, and certainly not directly linked to blockchain, traditionally speaking. The term was coined in the 1990's long before blockchain was conceived of.

However, because of the way smart contracts have been used to implement general computational logic and mechanism on different blockchains, especially **Ethereum**, any computer program that implements a certain logic can be regarded as a smart contract in the context of blockchains and distributed ledgers.

For more information on how to develop smart contracts using Ontology, please follow [this](/guides-and-tutorials/development-guides/smart-contract-dev) link.

## Functionality

Smart contract, or simply digital contract was conceived in their original form to mimic real world contracts, but with the inception of distributed ledgers and blockchain coming into picture, it is safe to say that smart contracts can be used to execute various form of complex logic and functionality in different industries, almost certainly going beyond finance.

A few ways in which smart contracts can be used in tandem with either completely, or partially decentralized blockchain technology:

* Intellectual Property (IP) protection
* Supply chain management
* Research and development
* Legal Industry
* Government sectors

Smart contracts carry out functions by releasing assets on single, or multiple chains based on the business logic and architecture, when certain pre-determined contractual clauses are fulfilled or fail to fulfill. The important thing to note here would be that these clauses and all the steps of this process are publicly visible. This brings a whole new level of transparency to systems that are notoriously untraceable and hence face issues in terms of communication, co-ordination, responsibility and role management, etc. As the competition grows and blockchain technology develops further, smart contracts will play bigger and more important roles.

**Ontology Smart Contracts** support dynamic features including **high scalability**, **high performance**, **multilingual contracts**, **cross-chain**, cross-virtual-machines, etc., all integrated into one system. The programming languages supported currently include **Python, C#, and Rust.** While **Java, C++, Go,** and **JavaScript** will be supported in the future.

Ontology also supports EVM contracts written in **Solidity.**

## Security measures

Smart contracts have a lot of strong points such as **transparency**, **precision**, **cost-effectiveness** and **practicality**.

Smart contract can be used as safeguards, to ensure that certain assets are released only when the fixed contractual clauses are satisfied. But there is a security vulnerability that arises due to the transparency of smart contracts. Not only are the clauses on public display, so are any issues and vulnerabilities.

Considering the fact that smart contracts cannot be altered after being deployed, it is important to look into the smart contract logic and perform rigorous testing by subjecting them to practical scenarios so as to avoid any mishaps such as the popular **2016 DAO attack**. There are several smart contract auditing services that have come up since the attack. But here are other tips that one can follow to write **good** smart contracts:

* Follow general programming best practices to avoid any limitations brought about by the programming language being used.
* Write blockchain specific code with the level of decentralization in mind instead of writing general logic.
* Testing, testing, and more meticulous testing. Ensure that the contract works as intended under various different calculated circumstances.
* Limit functionality to only the essentials. This might seems a little counter-intuitive, but more functionality generally equates to more loopholes that can be exploited, generally speaking.

{% content-ref url="/pages/-LwHH-VgkPwtRNw6rc4n" %}
[Smart Contract Development](/guides-and-tutorials/development-guides/smart-contract-dev)
{% endcontent-ref %}


# Types of smart contracts

Different types of Ontology smart contracts

There are three types of smart contracts with different execution engines that are invoked via a dispatch center:

1. **Native contracts:** Ontology's ONT and ONG contracts that govern all the OEP token protocols and their corresponding functioning.
2. **NeoVM contracts:** Smart contracts that are compiled to **AVM** bytecode, which is then run on the **NeoVM** engine. Currently supported in **Python** and **C#**.
3. **WebAssembly (WASM) VM contracts:** Smart contracts that are compiled to a portable binary code format that can be read and executed by the WebAssembly engine. Currently supported in **Rust** and **C++.**

Let us take a closer look at the flow of control for a smart contract execution cycle.

![](/files/-LwScRKDr2SKk4EI-ZiU)

#### Smart contract invocation mechanism

Once a smart contract has been compiled to **AVM bytecode** and the stack `opcode` is obtained, the contract is transmitted to the chain along with some relevant information regarding the contract. This is involves a transaction that consumes a certain amount of gas, and this is the state where a contract is considered to be deployed on the chain.

Next, when a smart contract is **invoked**, the **layer dispatch** center determines the nature of the contract. The three types of contracts all run on **different engines** and so the flow of control is transferred to the respective contract layer.

For every subsequent invocation from app calls the same procedure is followed.

## EVM Contracts

Solidity smart contracts that run in an **Ethereum Virtual Machine (EVM)** environment in the Ethereum  network can be also deployed on Ontology. All the same development and testing tools, such as the MetaMask wallet, the web3.js library, Truffle and Hardhat development frameworks, etc. can be used for writing, testing, deploying, and running EVM contracts on the Ontology testnet and mainnet.

Solidity contracts are compiled to bytecode and executed in the form of EVM opcodes.

You are now familiar with what smart contracts are, what they can be used to achieve, and how they are executed on the **Ontology** platform. Follow the link below to refer to our smart contract development guides.

{% content-ref url="/pages/-LwHH-VgkPwtRNw6rc4n" %}
[Smart Contract Development](/guides-and-tutorials/development-guides/smart-contract-dev)
{% endcontent-ref %}


# Token Protocols

Ontology's OEP token protocols

The **ONT Enhancement Proposals** (OEP) lay out the **standard** for tokens on the Ontology platform, including **core protocol specifications**, **client APIs** and **smart** **contract standards.**

You can refer to `OEP-1` to get the general idea and then clone the `OEP` [**repository**](https://github.com/ontio/OEPs) and add your own `OEP` protocol to it. You can refer to the [**pull requests**](https://github.com/ontio/OEPs/pulls) here.

Here is a list of the token protocols currently available for reference and usage:

| Sr. No. | Title                                                 | Author                                                | Type     | Status   | Ref.                                                                                                                                                                                      |
| ------- | ----------------------------------------------------- | ----------------------------------------------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1       | OEP Purpose and Guidelines                            | Ontology Team                                         | Meta     | Active   | [OEP-1 Token Standard](https://github.com/ontio/OEPs/blob/master/OEPS/OEP-1.mediawiki)                                                                                                    |
| 2       | Ontology ID Standard                                  |                                                       | Standard | Stub     | [Authentication process](https://github.com/ontio/OEPs/blob/master/meta-backup/Auth-process.mediawiki), [Website Interaction Standard pull request](https://github.com/ontio/OEPs/pull/9) |
| 3       | Ontology SDK Extension                                | Ontology Team & Community                             | Meta     | Stub     | [CSharp-SDK](https://github.com/ontio/OEPs/blob/master/meta-backup/CSharp-SDK.mediawiki)                                                                                                  |
| 4       | Token Standard                                        | luodanwg, tanyuan, zhoupw                             | Standard | Accepted | [OEP-4 Token Standard](https://github.com/ontio/OEPs/blob/master/OEPS/OEP-4.mediawiki)                                                                                                    |
| 5       | Non-Fungible Token Standard                           | tanyuan, zhoupw, tonyclarking, blckchan, Wyatt Mufson | Standard | Accepted | [OEP-5 Token Standard](https://github.com/ontio/OEPs/blob/master/OEPS/OEP-5.mediawiki)                                                                                                    |
| 6       | dApp extension                                        | Community                                             | Meta     | Draft    | [Pull Request](https://github.com/ontio/OEPs/pull/8)                                                                                                                                      |
| 7       | URI Schema                                            | zhoupw                                                | Standard | Draft    | [Pull Request](https://github.com/ontio/OEPs/pull/19)                                                                                                                                     |
| 8       | Crypto Item Standard                                  | tanyuan, zhoupw, tonyclarking, blckchan               | Standard | Accepted | [OEP-8 Token Standard](https://github.com/ontio/OEPs/blob/master/OEPS/OEP-8.mediawiki)                                                                                                    |
| 9       | Ontology X-shard Asset Contract                       | qiluge                                                | Standard | Draft    | [Pull Request](https://github.com/ontio/OEPs/pull/50)                                                                                                                                     |
| 10      | Cross-contract Call Attack Prevention Standard        | Wyatt Mufson                                          | Standard | Accepted | [OEP-10 Standard](https://github.com/ontio/OEPs/blob/master/OEPS/OEP-10.mediawiki)                                                                                                        |
| 11      | Ontology Wallet Standard                              | Wyatt Mufson                                          | Standard | Draft    | [OEP-15 Wallet Standard](https://github.com/ontio/OEPs/pull/56)                                                                                                                           |
| 12      | Security Token Offering (STO) Standard                |                                                       | Standard | Stub     | [Regulation D 506(c)](https://www.sec.gov/smallbusiness/exemptofferings/rule506c),  [Issue reference](https://github.com/ontio/OEPs/issues/23)                                            |
| 13      | Time-limited Token Standard                           |                                                       | Standard | Stub     | [Issue reference](https://github.com/ontio/OEPs/issues/24)                                                                                                                                |
| 14      | Ontology Oracle Standard                              |                                                       | Standard | Draft    | [Pull Request](https://github.com/ontio/OEPs/pull/35)                                                                                                                                     |
| 15      | Standard process of transaction fee rebate adjustment |                                                       | Meta     | Accepted | [OEP-39 Proposal](https://github.com/ontio/OEPs/blob/master/OEPS/OEP-39.mediawiki)                                                                                                        |
| 16      | Data Token Standard                                   |                                                       | Standard | Draft    | Data Tokenization Standard, etc.                                                                                                                                                          |
| 17      | Token Exchange Standard                               |                                                       | Standard | Stub     | Data-Token Exchange Standard, etc.                                                                                                                                                        |
| 18      | Ontology Data Encryption extension                    |                                                       | Meta     | Stub     | Zero-knowledge proof, Homomorphic Encryption, etc.                                                                                                                                        |
| 19      | Ontology Ecosystem Governance Meta                    | Ontology Team                                         | Meta     | Stub     | Ontology Governance Standard                                                                                                                                                              |
| 20      | Ontology Tokenomics Meta                              | Ontology Team                                         | Meta     | Stub     | Ontology Gas Standard                                                                                                                                                                     |


# Consensus Mechanism

Ontology's consensus network and mechanism

**Verifiable Byzantine Fault Tolerance (VBFT)** is the **core consensus algorithm** of the **Ontology Consensus Engine (**`OCE`**)**. It is a hybrid algorithm that combines **Proof of Stake (**`PoS`**)**, **Verifiable Random Function** **(**`VRF`**)**, and the **Byzantine Fault Tolerance** algorithm **(**`BFT`**)**.

**VBFT** supports up-scaling of the consensus group. The **randomness** and **fairness** within the consensus group is safeguarded by the `VRF`, while also ensuring that a final consensus is swiftly reached.

The consensus network is fundamentally composed of two parts-

#### Consensus Network

The consensus network is made up of all the **consensus nodes** that carry out the **consensus process** with respect to the **events** that take place within the **Ontology** network. This includes **block generation**, maintaining **ledger consistency**, and sending the blocks that pass the consensus process to the **synchronization node** network.

#### Consensus Candidate Network

Candidate nodes do not participate in the consensus process, but stay synchronized to the consensus node status and **update** the new **block information real time** in the ledger they maintain.

The candidate nodes constantly monitor the consensus nodes and their status. They verify the consensus blocks and support Ontology network administration.

![Candidate Node Pool](/files/-Lym8TTiuJqKUWilqpqE)

The consensus network scale is administered using **consensus smart contracts**. Every node in the consensus network has its corresponding `stake` set by the **node administrator**.

## Building a Consensus Network

The consensus network is built using the **consensus management smart contracts**. Consensus management contracts are **permanently deployed** and **running** on the Ontology network and periodically update the **consensus node list** and`VBFT` algorithm **configuration parameters**.

The `PoS` table is an important `VBFT` parameter. When `VBFT` is run, all the nodes **randomly** choose the nodes that will participate and carry out a **round** of **consensus process**.

## Algorithm Overview

The **VBFT** algorithm could be considered as an improvement on the traditional **Byzantine Fault Tolerance (BFT)** algorithm in terms of its **randomness** being **verifiable.**

A set of alternate **block proposal nodes** is selected sequentially on the basis of `VRF` for a round of **consensus**. The node sets are segregated in two, **block verification node set** and **block confirmation node set**, and then the **consensus** process is carried out based on this selection.

Owing to the **randomness** factor added by `VRF`, the **proposal node**, **verification node**, and **confirmation node** sets are **different** for each round of block consensus. This is very difficult to predict, and that makes this algorithm resistant to malicious attacks.

The algorithm can be summarized as follows:

1. Alternate **proposal nodes** are selected from the consensus network based on `VRF`. A **block** is **proposed** by **each** proposal node.
2. **Verification nodes** are chosen from the consensus network based on `VRF`. Each verification node **collects** the **proposed blocks** from the consensus network, carries out **verification**, and **votes** for the proposed block with the **highest priority**.
3. **Confirmation nodes** are selected from the consensus network based on `VRF`. These nodes carry out **statistical verification** for the **voting** carried out by the **verification nodes** and **confirm** the **final consensus result**.
4. All the nodes in the consensus then **acknowledge** the result obtained by the confirmation nodes. This marks the **end** of one **round** of consensus, and post confirmation a new round of consensus begins.

### Verifiable Random Function

As part of the current `VBFT` algorithm, the `VRF` value of **each block** is determined by the **previous consensus blocks**. The algorithm actually **fetches transaction information** from the **previous block** and calculates the `1024` place **hash value**, and then uses it as the `VRF` value for the **next block.**

### **Node Selection**

The `VBFT` algorithm uses the **`VRF` value** from the **previous round** of consensus as **index** to determine the nodes from the **`PoS` table** that will participate the **next round** of consensus. The `PoS` table generation takes every node owner's **`PoS` information** and the consensus network's **governance policy** into account. Even though the random `VRF` values can be considered to be **uniformly distributed**, the algorithm's random node selection process is still subject to **Ontology's** consensus network **administration policies**.

Since the `VRF` value generated by every block is **verifiable**, provided that a block is not split, all the nodes will be **consistent** for a block at a certain **height.**

The `VRF` in the algorithm selects nodes sequentially from the `PoS` table. For this reason, each `VRF` value maintains an **alternate proposal node sequence**, and this random node sequence is also **consistent** with the **consensus process**.

### Fork Selection

Ontology by the virtue of being a public chain that operates on a public network inevitably needs to face issues such as **malicious attacks** and **faults** that any public network would face. Although the `VBFT` consensus algorithm uses the consensus nodes **randomly**, and this **increases** the level of **difficulty** to execute an **attack**, the **risk** of a fork still exists when **network isolation** occurs.

As discussed above, every block's `VRF` can determine a **node sequence**. When `VBFT` carries out **fork choice**, it assigns the **level of priority** for each node based on this **node sequence**. Next, each fork priority is **weighted** based on the sequence of these **assigned priorities**, and then each node makes the suitable **fork choice** based on the **weighted fork priority** levels.

Since each block is selected based on the priority sequence determined by `VRF`, we can say that it is very **difficult**, or even **impossible** for **malicious forks** to maintain a high level of priority for themselves, and thus such forks swiftly **die out**. This is how `VBFT` is able to ensure **quick conclusion rate** in terms of **final states.**

### **Automatic Configuration**

To maintain the **quality** of the consensus network, **Ontology** consensus management contract automatically **updates** the **node list**. In the event of a **network discrepancy**, the consensus management contract supports the **voting** that place on the basis of `stake` and **explicitly updates** the node list of the consensus network.

After a new node gains more `stake` and it is confirmed that the **node performance** meets the **requirements** of the **consensus network**, it is added to the consensus network when the node list is **updated**.

The **updation time** of the consensus network is marked with **block** as the unit. Every time the consensus network completes consensus on a certain, **fixed number** of blocks, the next block's **proposal node** must **construct** a management contract **execution event** and **package** it into the next proposed block as the **first event**. The corresponding **validation** and **confirmation** nodes also verify the **validity** of this **proposed block**.

After the block that contains the consensus management **contract execution event** is reached consensus upon, every **node** in the network **executes** the consensus **management contract** and updates the **node list**. By the end of this process, the consensus node list would be updated throughout the **consensus network**.

| Consensus Mechanism | Application Scenarios           | Efficiency | Consensus Confirmation Rate | Consensus Confirmation Sample Time                      | Node Count | Anti-malicious Node Count                                 | Resource Consumption Rate | Security Control |
| ------------------- | ------------------------------- | ---------- | --------------------------- | ------------------------------------------------------- | ---------- | --------------------------------------------------------- | ------------------------- | ---------------- |
| POW                 | Public Blockchain               | < 20 tps   | Slow                        | <p>Bitcoin: 60 minutes</p><p><br>Ethereum: 1 minute</p> | -          | 50%                                                       | High                      | Low              |
| DPOS                | Public Blockchain               | > 500 tps  | Medium                      | Bitstocks: 10 seconds                                   | < 30       | Not known                                                 | Low                       | High             |
| PBFT                | Alliance/Proprietory Blockchain | > 1000 tps | Fast                        | <p>FISCO-BCOS：1 second</p><p><br>Fabric：1 second</p>    | < 30       | No more than 1/3 consensus nodes                          | Low                       | High             |
| VBFT                | Public/Proprietory Blokchcain   | > 3000 tps | Medium                      | Ontology Testnet：5-10 Seconds                           | < 1000     | Configurable BFT number，Not more than 1/3 consensus nodes | Low                       | High             |
| Paxos/RAFT          | Alliance/Proprietory Blockchain | > 5000 tps | Fast                        | FISCO-BCOS：1 Second                                     | < 30       | None                                                      | Low                       | High             |


# Ontology Oracle

Oracle network and mechanism

More and more **dApps** now depend on outside world triggers. Here's a hypothetical scenario: A flight is scheduled to arrive at 10:00 AM. An **insurance smart contract** has been set in place which will be triggered if the flight is **delayed**, and all the beneficiaries of the insurance policy should receive 100 tokens as **compensation**.

A scenario such as this one involves many **variables**, and a **dApp** that implements a smart contract such as this will require a lot of outside world **data** such as flight information, insurance policy related data, relevant account information to actually carry out the transaction, etc.

**dApps** are becoming richer and are trying to encapsulate as much functionality as possible. As a result, more and more real world data needs to be processed, such as logistic information, stock prices, weather data, sports statistics and scores, etc.

Ontology Oracle is designed to deal with this issue of smart contracts not being able to interact with the outside world. It essentially plays the role of data transporter, making it possible for smart contracts to fetch outside world data.&#x20;

## Ontology Oracle Framework

![Oracle infrastructure](/files/-LwX2ZrujLyGpclx_ktP)

With reference to the illustration above, the infrastructure consists of two major parts-

1. **On-chain**
2. **Off-chain**

### Off-chain (Oracle Operator and Data Source)

The **Oracle node** and the **data source** are two parts of the Oracle network that exist off-chain. The nodes are linked to the **Ontology network** and listen for **requests** from the Oracle contracts. All nodes process the data requests **independently**. These nodes will support more blockchain networks in the future.

The operation carried out by the nodes consists of two important tasks:

* **Data crawling**
* **Data analysis**

The node fetches **data** from the **data sources** via external **APIs** and after processing and analyzing the **response** writes the **data** into the Oracle **contract** after **serializing** it into the format specified by the user.

### On-chain (Oracle Contract)

The Oracle contract primarily collects and stores the data sent by the node, making it available for other smart contracts to invoke and access.

### Oracle data and workflow

![Oracle network data flow](/files/-LwXfQjXPr9Vke7mlKeT)

The data flow within the Oracle network, as illustrated above, can be described as follows:

1. The **client** issues **data requirements** using an **Oracle data request** to the Oracle contract
2. **Oracle contract** updates the received information in a **ledger** that functions like a **database**
3. An **Oracle node** picks up on this **request** and **fetches** this data using the **RPC** interface
4. The **node** fetches data from external data sources using **HTTP API**
5. The **node serializes** the received **data** based on the **client request** obtained earlier and **invokes** the **Oracle contract** to **transmit** the data
6. Other smart contracts on **client** side can then **invoke** this **Oracle contract** to **access** this data


# Oracle Process Flow

Let us take a look at an example and some sample code with respect to Oracle contract

## Creating Oracle request

An **Oracle contract** can be deployed on the Ontology **network** to send Oracle **requests** and fetch **data** from outside world and make it **accessible** to other **smart contracts**.

{% hint style="info" %}
In the future, **all** the deployed Oracle contracts will be **listed** on the **Oracle market**
{% endhint %}

The sample **Oracle contract** that we will be looking at here fetches sports statistics, i.e., match details.

Let's say the address of an example Oracle contract is as follows:

#### Test net - e0d635c7eb2c5eaa7d2207756a4c03a89790934a

#### Main net - a6ee997b142b002d49670ab73803403b09a23fa0

The structure of the Oracle **request** is of the form:

### httpGet

```yaml
operation = "CreateOracleRequest"
request = """{
		"scheduler": {
			"type": "runAfter",
			"params": "2018-06-15 08:37:18"
		},
		"tasks": [
			{
			  "type": "httpGet",
			  "params": {
				"url": "https://bitstamp.net/api/ticker/"
			  }
			},
			{
				"type": "jsonParse",
				"params":
				{
					"data":
					[
						{
							"type": "String",
							"path": ["timestamp"]
						},
						{
							"type": "String",
							"path": ["last"]
						},
						{
							"type": "Float",
							"decimal": 100,
							"path": ["open"]
						}
					 ]
				}
			}
		]
	}"""
args = [request, address]
```

The **response** is as follows:

```yaml
{
	"high": "5610.00000000",
	"last": "5518.70",
	"timestamp": "1542359479",
	"bid": "5518.12",
	"vwap": "5436.78",
	"volume": "16423.18407040",
	"low": "5199.80000000",
	"ask": "5518.69",
	"open": 5571.12
}
```

**Parameters:** `url`, **URL** of the **GET** request

### JsonParse

**JsonParse** will parse the `http` response with the parameter path list as **key**. The result will then be serialized to form a data structure, as defined by the user, and then finally written in the Oracle contract.\
Here is a list of the parameters:

| Parameter | Description                                                                                                                                |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| data      | Data structure defined by the user                                                                                                         |
| type      | Data type, support int, float(\* decimal as int), string, array, map, struct                                                               |
| sub\_type | Sub-type of the array, map and struct                                                                                                      |
| decimal   | decimal places of floating point value                                                                                                     |
| path      | Iterator list of **JSON** parse key, if data is `json`, write **key** in list, if data is **array**, write **index** as **string** in list |

Here's a complex **JsonParse** example:

```yaml
var request = """{
		"scheduler": {
			"type": "runAfter",
			"params": "2018-06-15 08:37:18"
		},
		"tasks": [
			{
			  "type": "httpGet",
			  "params": {
				"url": "http://data.nba.net/prod/v2/20181129/scoreboard.json"
			  }
			},
			{
				"type": "jsonParse",
				"params":
				{
					"data":
					[
						{
							"type": "Array",
							"path": ["games"],
							"sub_type":
							[
								{
									"type": "Struct",
									"sub_type":
									[
										{
											"type": "String",
											"path": ["gameId"]
										},
										{
											"type": "String",
											"path": ["vTeam", "teamId"]
										},
										{
											"type": "String",
											"path": ["vTeam", "score"]
										},
										{
											"type": "String",
											"path": ["hTeam", "teamId"]
										},
										{
											"type": "String",
											"path": ["hTeam", "score"]
										}
									]
								}
							]
						}
					]
				}
			}
		]
	}"""
```

A part of the raw `HTTP` response is:

```yaml
{
	"numGames": 3,
	"games": [{
			"gameId": "0021800316",
			"vTeam": {
				"teamId": "1610612744",
				"score": "128"
			},
			"hTeam": {
				"teamId": "1610612761",
				"score": "131"
			}
		},
		{
			"gameId": "0021800317",
			"vTeam": {
				"teamId": "2610612744",
				"score": "96"
			},
			"hTeam": {
				"teamId": "2610612761",
				"score": "131"
			}
		},
		{
			"gameId": "0021800318",
			"vTeam": {
				"teamId": "3610612744",
				"score": "128"
			},
			"hTeam": {
				"teamId": "3610612761",
				"score": "131"
			}
		}
	]
}
```

Here, the raw `HTTP` response is parsed and then a structure is created based on the data structure, which is then serialized.

An **application** smart **contract** calls the **Oracle contract** to fetch the result and then **deserializes** it as follows:

```yaml
[
    [
        ["0021800316", "1610612744", "128", "1610612761", "131"],
        ["0021800317", "2610612744", "128", "2610612761", "131"],
        ["0021800318", "3610612744", "128", "3610612761", "131"]
    ]
]
```

### Scheduler

This option is used to fix the time when a contract or task will be executed. It's format is as follows:

```yaml
{
    "type": "",
    "params": "",
}
```

Currently it only supports one execution method, **runAfter.**&#x20;

**runAfter** is used to specify a time when the task is to be run. For example, this can be used to send scores to the user after a game has ended. If the `type` field is left **empty**, the task will be run **immediately**. While the `params` field is used to specify the time in this format: **`YYYY-MM-DD HH:MM:SS`**\
Example - **"2018-06-15 08:37:18"**

### **httpPost**

The request format is as follows:

```yaml
operation = "CreateOracleRequest"
request = """{
        "scheduler": {
            "type": "runAfter",
            "params": "2018-06-15 08:37:18"
        },
        "tasks":[
            {
              "type": "httpPost",
              "params": {
                "url": "https://api.random.org/json-rpc/1/invoke",
                "contentType": "application/json-rpc",
                "body": "{\\"jsonrpc\\": \\"2.0\\",\\"method\\": \\"generateSignedIntegers\\",\\"params\\": {\\"apiKey\\": \\"c7511065-c88d-4f28-af4f-293c91ad20d9\\",\\"n\\": 6,\\"min\\": 1,\\"max\\": 10,\\"replacement\\": false,\\"base\\": 10},\\"id\\": 1}"
              }
            },
            {
                "type": "jsonParse",
                "params":
                {
                    "data":
                    [
                        {
                            "type": "Array",
                            "path": ["result", "random", "data"],
                            "sub_type":
                                [
                                    {
                                        "type": "Int"
                                    }
                                ]
                        }
                    ]
                }
            }
        ]
    }"""
args = [request, address]
```

The raw `HTTP` response is:

```yaml
{
    "jsonrpc": "2.0",
    "result": {
        "random": {
            "method": "generateSignedIntegers",
            "hashedApiKey": "oT3AdLMVZKajz0pgW/8Z+t5sGZkqQSOnAi1aB8Li0tXgWf8LolrgdQ1wn9sKx1ehxhUZmhwUIpAtM8QeRbn51Q==",
            "n": 6,
            "min": 1,
            "max": 6,
            "replacement": true,
            "base": 10,
            "data": [
                2,
                4,
                4,
                1,
                5,
                3
            ],
            "completionTime": "2013-09-30 14:58:03Z",
            "serialNumber": 69260
        },
        "signature": "BxHxajeRg7Q+XGjBdFS1c7wkZbJgJlverfZ5TVDyzCKqo2K5A4pD+54EMqmysRYwkL3w2NS2DFLVrsyO1o96bW9BGp5zjjrEegz9mB+04iOTaRwmdQnLJAj/m3WRptA+qzodPCTaqud8YWBifqWCM34q98XwjX+nlahyHVHT9vf5KO0YVkD/yRI1WN5M/qX21chVvSxhWdmIrdCkrovGnysFq8SzCRNhpYx+/1P+YT2IKsH8jth9z82IAz1ANVh918H/UdpuD1dR7TD6nk3ntRgGrIiu2qqVzFi8A7/6viVgRqtffE4KVZY6O9mUJ+sGkF5Ohayms7LHSFy1VC8wMbMgwod+A8nr5yzjAC4SCUkT1bKAyWNF3SdVcLtvWdcf97Ew6RjohzCW4Vs3jUlh6jF/pj3b3++U3lBHCh43IIonw8MQ7afwpqP12yvyDym1isNjhMKYjmzWRerSvnsMyQIH8xFW7IHt2g/0qnzJgABFmUNBRKJPCD9CMgjh60sSwW7EyrGMy7/qisfE0IU74P/F7KCty/g1jIlXX5/O1lQjwY34wnoP0NXL08QteukRZZUfJQnscx1NGE+HX1c9bMBI8LC0ZFYFk+uY6ib/0rCV5OcLLE9PihCdC8WoI1x3bobr8tbtfgnXMTjogxwVXiiSN1TMnTIWlJ+KM5eSWrw=",
        "bitsUsed": 16,
        "bitsLeft": 932400,
        "requestsLeft": 199991,
        "advisoryDelay": 1000
    },
    "id": 1
}
```

An application contract **deserializes** the result as follows:

```yaml
[
    [
        2,
        4,
        4,
        1,
        5,
        3
    ]
]
```

The `HTTP` post example above fetches a random number from **random.org.** This Ontology Oracle packages a more convenient method **`randomOrg`** to get a **signed random number**.

The request is as follows:

```yaml
operation = "CreateOracleRequest"
request = """{
        "scheduler": {
            "type": "runAfter",
            "params": "2018-06-15 08:37:18"
        },
        "tasks": [
            {
              "type": "randomOrg",
              "params": {
                "method": "GenerateSignedIntegers",
                "n": 10,
                "min": 1,
                "max": 10,
                "replacement": false
              }
            },
            {
                "type": "jsonParse",
                "params":
                {
                    "data":
                    [
                        {
                            "type": "Array",
                            "path": ["data"],
                            "sub_type":
                                [
                                    {
                                        "type": "Int"
                                    }
                                ]
                        },
                        {
                            "type": "String",
                            "path": ["signature"]
                        }
                    ]
                }
            }
        ]
    }"""
args = [request, address]
```

Here is the list of parameters:

| Parameter   | Description                                                                         |
| ----------- | ----------------------------------------------------------------------------------- |
| n           | Number of random numbers                                                            |
| min         | Lower limit for random numbers                                                      |
| max         | Upper limit for random numbers                                                      |
| replacement | **`true`**: random number can occur multiple times, **`false`**: numbers are unique |

The response is:

```go
type SignedIntegerData struct {
	Raw          json.RawMessage `json:"raw"`
	HashedApiKey string          `json:"hashedApiKey"`
	SerialNumber int             `json:"serialNumber"`
	Data         []int           `json:"data"`
	Signature    string          `json:"signature"`
}
```

**Unsigned random numbers** can also be generated as follows:

```yaml
operation = "{
        "scheduler": {
            "type": "runAfter",
            "params": "2018-06-15 08:37:18"
        },
        "tasks": [
            {
              "type": "randomOrg",
              "params": {
                "method": "GenerateIntegers",
                "n": 10,
                "min": 1,
                "max": 10,
                "replacement": false
              }
            },
            {
                "type": "jsonParse",
                "params":
                {
                    "data":
                    [
                        {
                            "type": "Array",
                            "path": ["data"],
                            "sub_type":
                                [
                                    {
                                        "type": "Int"
                                    }
                                ]
                        },
                        {
                            "type": "String",
                            "path": ["completionTime"]
                        }
                    ]
                }
            }
        ]
    }"""
args = [request, address]
```

| Parameter   | Description                                                                         |
| ----------- | ----------------------------------------------------------------------------------- |
| n           | Number of random numbers                                                            |
| min         | Lower limit for random numbers                                                      |
| max         | Upper limit for random numbers                                                      |
| replacement | **`true`**: random number can occur multiple times, **`false`**: numbers are unique |

The response is as follows:

```go
type IntegerData struct {
	Data           []interface{} `json:"data"`
	CompletionTime string        `json:"completionTime"`
}
```

## Result of Oracle request

The transaction hash `txhash` can be used to fetch the **result** of the on-chain Oracle **request**. The request format is:

```yaml
operation = "GetOracleOutcome"
args = txhash
```

## Sample Code

Please follow [**this**](https://github.com/ontio/ontology-oracle/blob/master/smartcontract/oracle.py) link to refer to **Oracle contract** template.

Please follow [**this**](https://github.com/ontio/ontology-oracle/blob/master/smartcontract/app.py) link to refer to an **application contract** that uses **Oracle**.


# Development Guides

Basic tutorials for developing with Ontology

The following guides have been built with the sole purpose of giving developers, and explorers alike, a foundational understanding of how the different tools and elements of the Ontology framework connect, and work with each other using practical examples and sample code.

The guides assume a certain level of understanding of the distributed development environment, apart from the basic knowledge of certain tools such as `Git` and Shell script.

At the end of each guide, you will have at least an entry level understanding of the respective component or process that the guide targets. We hope this will suffice to break the ice and significantly increase your development efficiency in terms of employing and implementing the Ontology framework and developing distributed applications.

{% hint style="info" %}
The developers looking to integrate **ONT ID** or those who intend to use the **ONT ID protocol** in their applications, we recommend taking a look at the new [**ONT 2.0 specification**](/decentralized-identity-and-data/ontid/decentralized-identifiers/specification)**.**

**ONT ID** management **contract API reference** is available [**here**](/developer-tools/api/ont-id-contract-api)**.**
{% endhint %}


# dApp Development


# Using the dAPI

Smart Contract and dApp development using Ontology's dAPI

The `dAPI` has been created to specifically facilitate `dApp` development. It supports browser (currently limited to Google Chrome) and mobile based `dApp` development (implemented using `Cyano` wallet that employs `dAPI` interface).

The mobile version of `dAPI` provides a limited number of the more significant interfaces only. The interfaces that query block transactions, or other interfaces that perform similar functions can directly invoke the `explorer` API interface. The `dAPI` interface set of the `chrome` plug-in is overall more comprehensive.

{% hint style="warning" %}
The code written in the two different environments is not mutually interchangeable currently. For compatibility related information, please refer: [dapi-universal](https://github.com/ontio-cyano/dapi-universal)
{% endhint %}

This guides aims at providing a surface level introduction for some of the more commonly used interfaces- login, signature data, contract query, and contract invocation.

{% hint style="info" %}
Note: The data returned by the `dAPI` interface is referred to as "Promise"
{% endhint %}

## Configuration Process

![dAPI Installation Flowchart](/files/-LvPYWZST2T6ajbyoZSm)

### 1. Installing dAPI

The first step is to install and set-up Ontology's `dAPI` package.

{% hint style="info" %}
Ensure that Node.js is configured properly on your system. The installation process uses `npm` commands.
{% endhint %}

#### Chrome version-

```bash
npm install ontology-dapi
```

#### Mobile version-

```bash
npm install cyanobridge
```

### 2. Initialization

A contract must be initialized before it is invoked.

#### Chrome version

```javascript
import {client} from 'ontology-dapi'
client.registerClient({})
```

#### Mobile version

```javascript
import {client} from 'cyanobridge'
client.registerClient();
```

### 3. Login

There are two ways to implement the login mechanism in a `dApp`:

* Use the `dAPI` to directly fetch the user's account address or `ONT ID`. If the information can be retrieved successfully, it indicates the logged in state with respect to the `dApp`.
* The dApp back end generates a string and sends it to the front end, and the front end invokes the dAPI requesting it to assign a signature to it, and then returning it to the back end. If the back end can successfully verify this signature, the user can be considered to have logged in successfully. Next, the back end can issue `access tokens` to the user. This depends on the business logic of the `dApp`.

{% hint style="info" %}
For more information on the method to implement back end signature verification, consider referring-

* [Java SDK signature verification](https://github.com/ontio/ontology-java-sdk/blob/master/docs/en/interface.md#verify-signature)
* [TypeScript SDK signature verification](https://github.com/ontio/ontology-ts-sdk/blob/master/test/ecdsa.crypto.test.ts)
  {% endhint %}

## **Fetching Account Information or Identity**

While fetching the account or identity information, the users working with the mobile version `API` may choose not to submit the `dApp` information and leave the fields empty.

#### Mobile version

```javascript
import { client } from 'cyanobridge'

const params = {
    dappName: 'My dapp',
    dappIcon: '' // a URL that points to the dApp icon resource
}

try {
    const res = await client.api.asset.getAccount(params);
    const res = await client.api.identity.getIdentity(params);
    console.log(res)
} catch(err) {
    console.log(err)
}
```

#### Chrome version

```javascript
account = await client.api.asset.getAccount()
res = await client.api.identity.getIdentity();
```

### 4. Data Signature

Here's some sample code to exemplify how the the signature mechanism can be carried out by the back end.

#### Mobile version

```javascript
const params = {
    type: 'account',// account or identity that will sign the message
    dappName: 'My dapp', // dapp's name
    dappIcon: 'http://mydapp.com/icon.png', // the URL that points to the dapp's icon resource
    message: 'test message', // message sent from dapp that will be signed by native client
    expired: new Date('2019-01-01').getTime(), // expiry date of login
    callback: '' // callback url of dapp
}
let res;
try {
    res = await client.api.message.login(params);
    console.log(res)
}catch(err) {
    console.log(err)
}
```

#### Chrome version

```javascript
const result = await client.api.message.signMessage({message});
```

### 5. Contract invocation

Contract invocations are mainly of two types: *execution* and *pre-execution*.

Pre-execution invocations normally involve using the contract's query interfaces, while the execution invocations directly use the contract itself. Pre-execution calls generally do not trigger the consensus mechanism. For example, in a game of rolling dice, a pre-execution invocation can query the result of a dice roll, and by the means of an execution invocation the specific method of a dice roll can be fetched.

***Execution invocation sample code-***

#### Mobile version

```javascript
const scriptHash = 'cd948340ffcf11d4f5494140c93885583110f3e9';
const operation = 'test'
const args = [
    {
        type: 'String',
        value: 'helloworld'
    }
]
const gasPrice = 500;
const gasLimit = 20000;
const payer = 'AecaeSEBkt5GcBCxwz1F41TvdjX3dnKBkJ'
const config = {
    "login": true,
    "message": "invoke smart contract test",
    "qrcodeUrl": "" ,
    "callback": ""
}
const params = {
          scriptHash,
          operation,
          args,
          gasPrice,
          gasLimit,
          payer,
          config
        }
try {
   const res = await client.api.smartContract.invoke(params);
   } catch(err) {
    console.log(err)
}
```

#### Chrome version

```javascript
const scriptHash = '16edbe366d1337eb510c2ff61099424c94aeef02';
const gasLimit = 30000;
const gasPrice = 500;
const operation = 'test'

const args = [
   {
    name: "msg",
    type: "String",
    value: "hello world"
   }
]
 params = {
            scriptHash,
            operation,
            args,
            gasPrice,
            gasLimit
}
await client.api.smartContract.invoke(params)
```

## dAPI demonstration

The concepts explained above help create a foundation level understanding of how Ontology's `dAPI` works and a few ways in which it can used in a `dApp`.

The following demonstration will illustrate how the `dAPI` would function when integrated with a `dApp`, both the browser and mobile versions.

Here's a link to the sample mobile `dApp` <http://101.132.193.149:5000/>; the original code can be found [here](https://github.com/ontio-cyano/mobile-dapp-demo).

A browser based sample `dApp` is demonstrated below. The developers working with the Chrome plugin version may refer to the original code [here](https://github.com/OntologyCommunityDevelopers/ontology-dapi-demo).

First, the git repository needs to be cloned to the system and installed. The process can be carried out as follows.

```bash
$ git clone https://github.com/ontio-community/ontology-dapi-demo.git

$ npm install

$ npm run start
```

![Message displayed in the shell command window](/files/-LvPYWZbooj96ZMtqV8K)

Upon successfully installing and running the application, it can be accessed using the address - <http://localhost:3000>.

{% hint style="success" %}
Please ensure that the `Cyano` wallet Chrome extension is activated and running when the above page is opened.
{% endhint %}

![](/files/-LvPYWZdtO7t1x7niHXe)

Once the page opens, you can click on **Provider**, and then **GetProvider** on the next page to check whether or not the application is functioning properly. A prompt should display the version of `Cyano` you have installed.

![](/files/-LvPYWZfR8q-3FXKMu7I)

At this point, the app has successfully established a connection and can interact with the chain by invoking the API. For instance, return to the main page and click on **Network** -> **GetBlock**. The app will return block related information, as such -

![](/files/-LvPYWZhW-8seAuozVf3)

To demonstrate the functionality of the application we can carry out an account transfer. To do so, click on **Asset** -> **Make Transfer**. A default address will by default appear in the address field.

{% hint style="info" %}
The transaction takes place on the `test-net`. Please ensure that your wallet is connected to the test net so as to carry out the authorization protocol and then later on see the changes reflect in your wallet.
{% endhint %}

The `Cyano` wallet's confirmation window will automatically pop up. Confirm the transaction, and then once the transaction completes, it can be confirmed using Ontology's `Explorer` by using your public address or the transaction hash the Chrome prompt will display.

![](/files/-LvPYWZlun7lcxShXjfH)

![](/files/-LvPYWZnZX4gIdEDqzeM)

At this point, the changes will be reflected in your wallet. The amount that you selected, along with 0.01 ONG (gas price) will be deducted from your wallet. Other transaction related details can be found in the `explorer`. The explorer can be accessed from [here](https://explorer.ont.io).

![](/files/-LvPYWZpEqEfN-6mGMfe)

![](/files/-LvPYWZrorVFZlAh2xQi)


# Data Synchronization

Synchronizing your local database with the data on the chain

Every time a `dApp` needs to fetch the data stored on the chain (i.e., transaction records, etc.), it can do so by querying the public [**Explorer API**](https://explorer.ont.io)**.** But this would only be feasible for the `dApps` that have a low query rate, or execute queries at a lower frequency.

`dApps` with higher query requirements both in terms of number and frequency cannot work at optimum efficiency when using the Explorer interface. Therefore, to target this specific issue, Ontology introduced a new method which allows the application's local database to synchronize its data with the chain.

{% hint style="warning" %}
Synchronizing the local database with the chain is an option, and not a requirement for `dApp` development. Developers are advised to analyze the specific requirements for their respective applications to make this judgement.
{% endhint %}

## Connecting to Ontology's Nodes

Connecting to Ontology's nodes is the first step of data synchronization process. This can be performed in two different ways-

### 1. Connecting to Ontology's Consensus nodes

Generally speaking, personally deploying and running a node is a very tedious task for developers. And that is why Ontology made `Polaris` test net and main net nodes available for developers to employ. It supports `RPC`, `Restful`, and `WebSocket` invocation, and use default ports.

The Polaris test net nodes are-

* <http://polaris1.ont.io>
* <http://polaris2.ont.io>
* <http://polaris3.ont.io>
* [http://polaris4.ont.io](http://polaris1.ont.io)
* <http://polaris5.ont.io>

and the main net nodes are-

* <http://dappnode1.ont.io>
* <http://dappnode2.ont.io>
* <http://dappnode3.ont.io>
* <http://dappnode4.ont.io>

{% hint style="success" %}
**10334** port of the first nodes of the Polaris test net net and the main net support **HTTPS**
{% endhint %}

### 2. Running your own node

Depending on the architecture of the `dApp` the developer may choose to personally run a synchronization node. For more details and a quick walkthrough, refer to -

## Running the Synchronization Sequence

What synchronization basically does is all the data that is stored on the chain, say all the block, transaction and contract event related data, is imported to a local database that the `dApp` has direct access to, thereby increasing the efficiency with which the app can query it.

Ontology's Explorer is a model synchronization program. The user may selectively synchronize the data that serves their purpose. For e.g., data related to the events pertaining to a smart contract that you deployed.

### 1. Synchronizing with all the blocks on the chain

There are `dApps` that needs to synchronize the information from all the blocks on the chain, a typical case of which would be Ontology's `Explorer`. Developers developing `dApps` with needs analogous to those of Explorer may find [this](https://github.com/ontio/ontology-explorer/tree/master/back-end-projects/OntSynHandler) helpful.

On the basis of the height of the given block, the **`getblk_by_height`** interface returns the following `JSON` response.

```javascript
http://polaris1.ont.io:20334/api/v1/block/details/height/909220

{
    "Action": "getblockbyheight",
    "Desc": "SUCCESS",
    "Error": 0,
    "Result": {
        "Hash": "02f723a83eae05238481bc8b7d315cbbcd4326ccb53df6e1de35b19c496868ee",
        "Size": 1392,
        "Header": {
            "Version": 0,
            "PrevBlockHash": "b0243bd78e7368c8bed33a9e66b4a8c0a2f98fbcf18457a018f027b69ab1f7fc",
            "TransactionsRoot": "7f89aaf1ca48a8cff46493f1ca75f91fabe1ec14b8acd3ffd32acd722d398b4e",
            "BlockRoot": "e6440680fc91be58c5d41298c992cb6cd04c365a00bf6dce216ce085ce0e75cd",
            "Timestamp": 1551427384,
            "Height": 909220,
            "ConsensusData": 12174009838538082583,
            "ConsensusPayload": "7b226c6561646572223a312c227672665f76616c7565223a224249526839547a4f4e526e71766444566b565a6753624e6e533871336465344b4b59786a52686174713864394b6d3974316f7279654f426b727170502f4b6f4474674135647061492f313649536c4b643556784e4d444d3d222c227672665f70726f6f66223a222f6e7a554a54766f7959676d594a544570574938326958454b497a6c7247707870753067767239784a6231784c646c344442435831796d7372703941796f495256372f35626f2f4c572b2b36336937665553747378513d3d222c226c6173745f636f6e6669675f626c6f636b5f6e756d223a3930383432342c226e65775f636861696e5f636f6e666967223a6e756c6c7d",
            "NextBookkeeper": "AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM",
            "Bookkeepers": ["037c9e6c6a446b6b296f89b722cbf686b81e0a122444ef05f0f87096777663284b", "03aa4d52b200fd91ca12deff46505c4608a0f66d28d9ae68a342c8a8c1266de0f9", "0205bc592aa9121428c4144fcd669ece1fa73fee440616c75624967f83fb881050", "030a34dcb075d144df1f65757b85acaf053395bb47b019970607d2d1cdd222525c", "020cc76feb375d6ea8ec9ff653bab18b6bbc815610cecc76e702b43d356f885835", "03dff4c63267ae5e23da44ace1bc47d0da1eb8d36fd71181dcccf0e872cb7b31fa"],
            "SigData": ["ded9f22792bfc4aa1e471fe05cfc68af2cd5204fd1664f3151648910f51cc531f8dc9c301ee450538e84ffa8a77b5c8141e37caab4917eb7b8c6eb11e8e1b387", "ac5b1710b50d1d35b7948d2e19a22e5f7eecbe210f09551275ca273d09ea15e1aa5198d052ef913cf51b3855955f0f89caf174ca4ffac4451d27b29dc64626e7", "121d213cf49f7c7a706e9098d2ed9ae53ead4fe41774fdccd7186fd47fffa13f60dea875794fe9bbcf5fd729a1294cc835b34ef42ae8544425b15bedca0d8e93", "8053c1fbf81f3d3c01925ad3160dec9c4751203da9a31c22448de4aa18c38d07f99e0cbb7066bb83de6e7d46720184e541bcad8e9fdd2ec18cd8cbd83f0c335c", "ffc94ae16e0ff54a922f970b3226b5e2267a1b783ff990799f536dd3f0713782c9e43d372fcd3b4596f922a222db4e3bf3fe2b84e62c3ef580ff02d46491a61a", "cf52208439275256dfe3f97af4fab5a1b6c69661d5b885f6623337a4dfc729cb6b425fe8e009fccb115e7b4626f4176806ffd323a96d4aa0866a0459cf02917a"],
            "Hash": "02f723a83eae05238481bc8b7d315cbbcd4326ccb53df6e1de35b19c496868ee"
        },
        "Transactions": [{
            "Version": 0,
            "Nonce": 1551427383,
            "GasPrice": 500,
            "GasLimit": 20000000,
            "Payer": "Af1n2cZHhMZumNqKgw9sfCNoTWu9de4NDn",
            "TxType": 209,
            "Payload": {
                "Code": "016414aa57ed4be4a318fb4b88b6a25d662f7e073743aa14feec06b79ed299ea06fcb94abac41aaf3ead765853c15a14feec06b79ed299ea06fcb94abac41aaf3ead76581446b1a18af6b7c9f8a4602f9f73eeb3030f0c29b753c152c151c10e7472616e736665725f6d756c746967bed9a5a68557381d0598cfcbfb16c03334a791ca"
            },
            "Attributes": [],
            "Sigs": [{
                "PubKeys": ["02e8e84be09b87985e7f9dfa74298f6bb7f70f85515afca7e041fe964334e4b6c1"],
                "M": 1,
                "SigData": ["dd0edcbb49e77bfec7fb5dbaaeafcb309dcd2b3db940dc27a33f5738872bd25684fcbd1da140d7ec483fa2eedb9e0c520619076e45e5f43383eeef55ca36d759"]
            }, {
                "PubKeys": ["03d0fdb54acba3f81db3a6e16fa02e7ea3678bd205eb4ed2f1cfa8ab5e5d45633e"],
                "M": 1,
                "SigData": ["df6c95816a56eab350800be3ccc3a9a7794b565a47b49f53b6351a19c5e1dd8d980d32a04a97f8e933a11683b7e1fcc50fd8f91695ab0189468a7c0a5a518156"]
            }],
            "Hash": "7f89aaf1ca48a8cff46493f1ca75f91fabe1ec14b8acd3ffd32acd722d398b4e",
            "Height": 0
        }]
    },
    "Version": "1.0.0"
}
```

### 2. Synchronize specific contract related Events

Most `dApps` only need to synchronize the `events` that are generated by their own contracts. This suffices for any functionalities that `dApp` may be implementing, and so there is no need to fetch and store all the data stored in all the different blocks.

The code to synchronize the data will always be application specific, because it would also have to adhere to the logic of the application. But here's an example of how a contract specific synchronization method would look like:

The code for the data synchronization is application specific, because it needs to adhere to the logic of the application.

* The developer defines the argument set for `Notify`

```python
Notify(["param1", "param2", "param3"])
```

* When querying a smart contract event using the block height, the reply that the `getSmartCodeEvent` interface sends would look like:

```javascript
http://polaris1.ont.io:20334/api/v1/smartcode/event/transactions/909220

{
    "Action": "getsmartcodeeventbyheight",
    "Desc": "SUCCESS",
    "Error": 0,
    "Result": [{
        "TxHash": "7f89aaf1ca48a8cff46493f1ca75f91fabe1ec14b8acd3ffd32acd722d398b4e",
        "State": 1,
        "GasConsumed": 10000000,
        "Notify": [{
            "ContractAddress": "ca91a73433c016fbcbcf98051d385785a6a5d9be",
            "States": ["7472616e736665725f6d756c7469", [
                ["46b1a18af6b7c9f8a4602f9f73eeb3030f0c29b7", "feec06b79ed299ea06fcb94abac41aaf3ead7658", "0a"],
                ["feec06b79ed299ea06fcb94abac41aaf3ead7658", "aa57ed4be4a318fb4b88b6a25d662f7e073743aa", "64"]
            ]]
        }, {
            "ContractAddress": "0200000000000000000000000000000000000000",
            "States": ["transfer", "Af1n2cZHhMZumNqKgw9sfCNoTWu9de4NDn", "AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK", 10000000]
        }]
    }],
    "Version": "1.0.0"
}
```

* The composition of the `ExecuteNotify` data structure is

```go
type ExecuteNotify struct {
    TxHash      common.Uint256   //Transcation hash
    State       byte             //1 signifies that the transaction was successful, 0 signifies failure
    GasConsumed uint64
    Notify      []*NotifyEventInfo
}
```

* The composition of `NotifyEventInfo` data structure is

```go
type NotifyEventInfo struct {
    ContractAddress common.Address  //Address of the smart contract
    States          interface{}     //The message to be notified
}
```

* The method that listens for special or specific contract events could look something like:

```java
public void run() {

    try{

        while (true) {
            //Fetch the current block height
            int remoteBlockHieght = getRemoteBlockHeight();
            logger.info("######remote blockheight:{}", remoteBlockHieght);
            //Find out the height of synchronized blocks in the database
            int dbBlockHeight = blkHeightMapper.selectDBHeight();
            logger.info("######db blockheight:{}", dbBlockHeight);
            dbBlockHeight = dbBlockHeight +1;
            //If the synchronized block height exceeds, or is equal to that of
            //the newest block added, wait for the next block to be created, then sync
            if (dbBlockHeight >= remoteBlockHieght) {
                //TODO
            }
            //For each block, determine all the corresponding events, an event is a JSONArray object
            //The data type of every element is ExecuteNotify
            Object event = sdk.getConnect().getSmartCodeEvent(dbBlockHeight);
            if (event != null) {
              for(Object obj : (JSONArray)event){
                  //Filter successful transactions
                  if (obj.get("State") ==1) {
                    for(Object notify: obj.get("Notify")) {
                        //Filter the events that we were listening for
                        if(notify.getString("ContractAddress") == contractAddress) {
                             //TODO
                        }
                    }
                  }
              }
            }
            //Update the block height in the database
            blkHeightMapper.update(dbBlockHeight);

        }
    }catch (Exception e) {
        logger.error("Exception occured，Synchronization thread can't work, error ...", e);
    }

}
```


# Smart Contract Development

Developing smart contracts with Ontology


# EVM Contract

Solidity smart contract development and deployment on Ontology


# Development Environment and Tools

Necessary tools to start writing EVM contracts

{% hint style="info" %}
Before getting started, you can apply for testnet **ONG** tokens that will be used for invoking any contracts you deploy over at the [**faucet here**](https://developer.ont.io/).
{% endhint %}

{% hint style="warning" %}
The value of gas price for a transaction must be in multiples of 10^9. The minimum value is 2500\*10^9.
{% endhint %}

## Development Environment and Tools

EVM smart contracts are written using [Solidity](https://docs.soliditylang.org/en/v0.8.6/). You can reuse existing Ethereum contract frameworks to develop and deploy EVM contracts.

### Remix

[Remix IDE](https://remix.ethereum.org/#optimize=false\&runs=200\&evmVersion=null\&version=soljson-v0.8.1+commit.df193b15.js) is an open source development environment for EVM contracts. Remix IDE documentation is [here](https://remix-ide.readthedocs.io/en/latest/).

We will now go through an example of a Hello World contract development using Remix.

#### **Initialize Remix**

First, locate and activate "Solidity Compiler" and "Deploy and Run Transactions" in PLUGIN MANAGER.

[![image-20210526142630046](https://github.com/ontio/ontology/raw/master/docs/specifications/evm_refernce/tutorial/image-20210526142630046.png)](https://github.com/ontio/ontology/blob/master/docs/specifications/evm_refernce/tutorial/image-20210526142630046.png)

Then, select Solidity environment. Create a new file and name it HelloWorld.sol. Then copy the code of [Hello World contract](https://github.com/ontio/ontology/blob/master/docs/specifications/evm_refernce/contract-demo/helloworlddemo/helloworld.sol) and paste it in the file just created.

[![image-20210526143301031](https://github.com/ontio/ontology/raw/master/docs/specifications/evm_refernce/tutorial/image-20210526143301031.png)](https://github.com/ontio/ontology/blob/master/docs/specifications/evm_refernce/tutorial/image-20210526143301031.png)

#### **Compile Contract**

Click on the Solidity Compiler button, select compiler version to 0.5.10 and start compiling HelloWorld.sol

#### **Deploy Contract**

The contract is ready to deploy on Ontology after compiling. Here we deploy it on Ontology TestNet.

{% hint style="info" %}
**Note**: MetaMask must be configured for Ontology before you deploy the contract.
{% endhint %}

Select "Custom RPC" in MetaMask networks settings. Fill in and save the info below.

* **Network name:** Ontology TestNet
* **Node URL:** `https://polaris1.ont.io:10339` or `https://polaris2.ont.io:10339` or `https://polaris3.ont.io:10339` or `https://polaris4.ont.io:10339`
* **Chain ID:** 5851
* **Blockchain Explorer URL:** "<https://explorer.ont.io/testnet>"

[![RemixIDE\_Step1](https://github.com/ontio/ontology/raw/master/docs/specifications/evm_refernce/tutorial/metamask_networks.png)](https://github.com/ontio/ontology/blob/master/docs/specifications/evm_refernce/tutorial/metamask_networks.png)

Finally, select "Injected Web3" in Remix. Click "Deploy" to finish.

[![deploy contract](https://github.com/ontio/ontology/raw/master/docs/specifications/evm_refernce/tutorial/remix_deploy.jpg)](https://github.com/ontio/ontology/blob/master/docs/specifications/evm_refernce/tutorial/remix_deploy.jpg)

#### **Invoke Contract**

Now you can call the method in this contract. The string `hello` is saved in the contract when you deploy it, you can call the method `message` to query this string:

[![invoke contract](https://github.com/ontio/ontology/raw/master/docs/specifications/evm_refernce/tutorial/remix_invoke.jpg)](https://github.com/ontio/ontology/blob/master/docs/specifications/evm_refernce/tutorial/remix_invoke.jpg)

### Truffle

Truffle offers tools and frameworks for EVM contract development, testing and management. You can find more details [here](https://www.trufflesuite.com/docs/truffle/quickstart).

Now we will demonstrate how to use Truffle with this [test code](https://github.com/ontio/ontology/blob/master/docs/specifications/evm_refernce/contract-demo/truffledemo).

#### **Install Truffle**

First, initialize and install dependencies.

* [Node.js v8+ LTS and npm](https://nodejs.org/en/) (comes with Node)
* [Git](https://git-scm.com/)

Then run this command to install Truffle.

```
npm install -g truffle
```

#### **Configure truffle-config**

* Create a new `.secret` to store the mnemonic phrase or private key (which can be found in MetaMask).
* Edit the code of truffle-config as below.

```javascript
const HDWalletProvider = require('@truffle/hdwallet-provider');
const fs = require('fs');
const mnemonic = fs.readFileSync(".secret").toString().trim();
module.exports = {
  networks: {
    ontology: {
     provider: () => new HDWalletProvider(mnemonic, `http://polaris2.ont.io:20339`),
     network_id: 5851,
     port: 20339,            // Standard Ethereum port (default: none)
     timeoutBlocks: 200,
     gas:800000,
     skipDryRun: true
    }
  },
  compilers: {
    solc: {
      version: "0.5.16",    // Fetch exact version from solc-bin (default: truffle's version)
      docker: false,        // Use "0.5.1" you've installed locally with docker (default: false)
      settings: {          // See the solidity docs for advice about optimization and evmVersion
       optimizer: {
         enabled: true,
         runs: 200
       },
       evmVersion: "byzantium"
      }
    }
  }
};
```

#### **Deploy Contract**

Run this command to deploy the contract on the Ontology network.

```
truffle migrate --network ontology
```

If successful, you will see the result below.

{% hint style="warning" %}
**Note:** Avoid using ETH units (e.g. wei, gwei, ether, etc.) when writing test scripts.
{% endhint %}

```
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.

Starting migrations...
======================
> Network name:    'ontology'
> Network id:      12345
> Block gas limit: 0 (0x0)
1_initial_migration.js
======================

   Replacing 'Migrations'
   ----------------------
   > transaction hash:    0x9019551f3d60611e1bc6b323f3cf3020d15c8aeb06833d14ff864e24622884aa
   > Blocks: 0            Seconds: 4
   > contract address:    0x53e137A51CfD1E1b088E0d921eB5dBCF9cFa955E
   > block number:        6264
   > block timestamp:     1624876467
   > account:             0x4e7946D1Ee8f8703E24C6F3fBf032AD4459c4648
   > balance:             0.00001
   > gas used:            172969 (0x2a3a9)
   > gas price:           0 gwei
   > value sent:          0 ETH
   > total cost:          0 ETH


   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:                   0 ETH


2_deploy_migration.js
=====================

   Replacing 'HelloWorld'
   ----------------------
   > transaction hash:    0xf8289b96f2496a8c940ca38d736a554a90f64d927b689921781619499906721b
   > Blocks: 0            Seconds: 4
   > contract address:    0xfbff9bd546B0e0D4b40f6f758847b70050d01b37
   > block number:        6266
   > block timestamp:     1624876479
   > account:             0x4e7946D1Ee8f8703E24C6F3fBf032AD4459c4648
   > balance:             0.00001
   > gas used:            243703 (0x3b7f7)
   > gas price:           0 gwei
   > value sent:          0 ETH
   > total cost:          0 ETH

hello contract address: 0xfbff9bd546B0e0D4b40f6f758847b70050d01b37

   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:                   0 ETH


Summary
=======
> Total deployments:   2
> Final cost:          0 ETH
```

### Hardhat

Hardhat is an Ethereum development environment. We will use this [test code](https://github.com/ontio/ontology/blob/master/docs/specifications/evm_refernce/contract-demo/hardhatdemo) as an example and demonstrate how to use Hardhat.

#### **Install Hardhat**

Please refer to [Hardhat doc](https://hardhat.org/getting-started/) for details on this step.

#### **Configure hardhat-config**

* Create a new `.secret` file to save your private key.
* Update the code of hardhat.config.js as shown below:

```javascript
require("@nomiclabs/hardhat-waffle");
const fs = require('fs');
const privateKey = fs.readFileSync(".secret").toString().trim();
module.exports = {
    defaultNetwork: "ontology_testnet",
        ontology_testnet: {
            url: "http://polaris2.ont.io:20339",
            chainId: 5851,
            gasPrice:2500000000000,
            gas:2000000,
            timeout:10000000,
            accounts: [privateKey]
        }
    },
    solidity: {
        version: "0.8.0",
        settings: {
            optimizer: {
                enabled: true,
                runs: 200
            }
        }
    },
};
```

**Deploy Contract**

Run this command in root of the project directory to deploy the contract on Ontology Chain:

```
$ npx hardhat run scripts/sample-script.js --network ontology_testnet
```

The result looks like this:

```
sss@sss hardhatdemo % npx hardhat run scripts/sample-script.js --network ontology_testnet
RedPacket deployed to: 0xB105388ac7F019557132eD6eA90fB4BAaFde6E81
```

## Network Info

### Network Types

**MainNet**

| Item           | Description                                                                                                                                                                                                                                                                                                                                                                                                       |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| NetworkName    | Ontology MainNet                                                                                                                                                                                                                                                                                                                                                                                                  |
| chainId        | 58                                                                                                                                                                                                                                                                                                                                                                                                                |
| Gas Token      | ONG Token                                                                                                                                                                                                                                                                                                                                                                                                         |
| RPC            | <p><code><https://dappnode1.ont.io:10339></code>,</p><p><code><https://dappnode2.ont.io:10339></code>,</p><p><code><https://dappnode3.ont.io:10339></code>,</p><p><code><https://dappnode4.ont.io:10339></code>,</p><p><code><http://dappnode1.ont.io:20339></code>, <code><http://dappnode2.ont.io:20339></code>, <code><http://dappnode3.ont.io:20339></code>, <code><http://dappnode4.ont.io:20339></code></p> |
| Block Explorer | <https://explorer.ont.io/>                                                                                                                                                                                                                                                                                                                                                                                        |

**TestNet**

| Item           | Description                                                                                                                                                                                                |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| NetworkName    | Ontology TestNet                                                                                                                                                                                           |
| chainId        | 5851                                                                                                                                                                                                       |
| Gas Token      | ONG Token                                                                                                                                                                                                  |
| RPC            | <p><code><https://polaris1.ont.io:10339></code> , <code><https://polaris2.ont.io:10339></code>,</p><p><code><https://polaris3.ont.io:10339></code>,</p><p><code><https://polaris4.ont.io:10339></code></p> |
| Block Explorer | <https://explorer.ont.io/testnet>                                                                                                                                                                          |

{% hint style="info" %}
Ontology EVM contracts consume ONG as gas fee for execution. You can apply for TestNet ONG [here](https://developer.ont.io/).
{% endhint %}

### EVM Assets on Ontology

| Name | Address                                     |
| ---- | ------------------------------------------- |
| ONG  | 0x00000000000000000000000000000000000000000 |

### OEP-4 Assets

Please refer to this [link](https://explorer.ont.io/tokens/oep4/10/1#).


# Wallet Setup

Set up a wallet for contract deployment and execution

## Key Management with MetaMask

Developers can manage Ethereum wallet private keys using the MetaMask browser add-on.

MetaMask is a non-custodial wallet. The user's private key is encoded with the mnemonic phrase and stored in user's local browser. Once lost, the user can no longer control the savings or restore access to the wallet. MetaMask communicates with Ethereum Ledger via Infura. Please refer to the [MetaMask website](https://metamask.io/) for more details.

### Initialize Web3

First, install the following in your dApp:

```bash
npm install --save web3
```

Create a new file, name it web3.js and insert the following code in it:

```javascript
import Web3 from 'web3';

const getWeb3 = () => new Promise((resolve) => {
 window.addEventListener('load', () => {
     let currentWeb3;

     if (window.ethereum) {
         currentWeb3 = new Web3(window.ethereum);
         try {
             // Request account access if needed
             window.ethereum.enable();
             // Accounts now exposed
             resolve(currentWeb3);
         } catch (error) {
             // User denied account access...
             alert('Please allow access for the app to work');
         }
     } else if (window.web3) {
         window.web3 = new Web3(web3.currentProvider);
         // Accounts always exposed
         resolve(currentWeb3);
     } else {
         console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');
     }
 });
});

export default getWeb3;
```

To put it simply, you can inject the global object `ethereum` if you have added MetaMask to Chrome.

Next, import the code as below:

```javascript
import getWeb3 from '/path/to/web3';
```

Call the function:

```javascript
  getWeb3()
 .then((result) => {
     this.web3 = result;// we instantiate our contract next
 });
```

### Set up Account

We need an account from the web3 instance we created above to send transactions.

```javascript
  this.web3.eth.getAccounts()
 .then((accounts) => {
     this.account = accounts[0];
 })
```

The `getAccounts()` function returns all the user’s Metamask accounts, while`accounts[0]` is the one currently selected by the user.

### Initialize Contract

Initialize your contract after completing above steps.

### Call Functions

Now you can call any function by directly interacting with the instantiated contract. Please note that:

Functions that do not alter the state of the contract are `call()` functions. Below is an example of calling a `call()` function:

```javascript
  this.myContractInstance.methods.myMethod(myParams)
    .call()
    .then(
        // do stuff with returned values
    )
```

Functions that alter the state of the contract are `send()` functions. Below is an example of calling a `send()` function:

```javascript
this.myContractInstance.methods.myMethod(myParams)
.send({
from: this.account,gasPrice: 0
}).then (
(receipt) => {
  // returns a transaction receipt}
);
```

## Move Assets from Ethereum to Ontology

Ontology supports developers to conduct cross-chain asset transfer using [PolyBridge](https://bridge.poly.network/).


# Contract Development

Write and deploy EVM contracts

{% hint style="info" %}
Before getting started, you can apply for TestNet **ONG** tokens that will be used for invoking any contracts you deploy over at the [**faucet here**](https://developer.ont.io/).
{% endhint %}

Now we will demonstrate the full process of contract development, deployment and testing using Hardhat.

## Set up Environment

* Install [nodejs](https://nodejs.org/en/)
* Install [Hardhat](https://hardhat.org/getting-started/)

## Contract Design

### **Contract Logic**

The contract we use as an example here is for sending red packets, which is used when users send crypto assets as gifts. The core functions are:

* Send red packets
* Receive red packets

Before sending red packets, the user need to determine the amount of tokens to be sent and the number of red packets. For instance, 100 tokens will be sent in 10 red packets (to 10 different wallets). For ease of understanding, each red packet contains the same amount, i.e., each contains 10 tokens.

Consequently, we define the data structure:

```javascript
EIP20Interface public token; // support token address
uint public nextPacketId; // the next redpacket ID

// packetId -> Packet, store all the redpacket
mapping(uint => Packet) public packets;

//packetId -> address -> bool,  store receive redpacket record
mapping(uint => mapping(address => bool)) public receiveRecords;

struct Packet {
    uint[] assetAmounts;// Number of tokens per copy
    uint receivedIndex; // Number of red packets received
}
```

### **Define Contract Events**

When executing the contract, we can trace the process by adding events.

Here we design two events:

1. When the user send a red packet, the contract generates an ID for the red packets, which will be sent through this event notification:

```javascript
event SendRedPacket(uint packetId, uint amount); 
```

2\. When a user receives a red packet, this event notification is sent to record the ID and token amount of the received red packet:

```javascript
event ReceiveRedPacket(uint packetId, uint amount);
```

### **Define Functions**

**`sendRedPacket`**

Sends red packets. Any system is able to call the function and send certain amount of tokens to the contract address. Other addresses can receive red packets from this contract address.

{% hint style="info" %}
**Note:** Before invoking this function, the contract has to be authorized to transfer tokens from users' addresses. To do so, call the `approve` method of the token first.
{% endhint %}

```javascript
function sendRedPacket(uint amount, uint packetNum) public payable returns (uint) {
    require(amount >= packetNum, "amount >= packetNum");
    require(packetNum > 0 && packetNum < 100, "packetNum>0 && packetNum < 100");
    uint before = token.universalBalanceOf(address(this));
    token.universalTransferFrom(address(msg.sender), address(this), amount);
    uint afterValue = token.universalBalanceOf(address(this));
    uint delta = afterValue - before;
    uint id = nextPacketId;
    uint[] memory assetAmounts = new uint[](packetNum);
    for (uint i = 0; i < packetNum; i++) {
        assetAmounts[i] = delta / packetNum;
    }
    packets[id] = Packet({assetAmounts : assetAmounts, receivedIndex : 0});
    nextPacketId = id + 1;
    emit SendRedPacket(id, amount);
    return id;
}
```

**`receivePacket`**

Receives red packets. Any address can call this function by red packet ID to receive a red packet, meaning that you need to specify which one to receive.

```javascript
function receivePacket(uint packetId) public payable returns (bool) {
    require(packetId < nextPacketId, "not the redpacket");
    Packet memory p = packets[packetId];
    if (p.assetAmounts.length < 1) {
        return false;
    }
    require(p.receivedIndex < p.assetAmounts.length - 1, "It's over");
    require(receiveRecords[packetId][address(msg.sender)] == false, "has received");
    p.receivedIndex = p.receivedIndex + 1;
    bool res = token.universalTransfer(msg.sender, p.assetAmounts[p.receivedIndex]);
    require(res, "token transfer failed");
    packets[packetId] = p;
    receiveRecords[packetId][address(msg.sender)] == true;
    emit ReceiveRedPacket(packetId, p.assetAmounts[p.receivedIndex]);
    return true;
}
```

View the full code [here](https://github.com/ontio/ontology/blob/master/docs/specifications/evm_refernce/contract-demo/hardhatdemo/contracts/Redpacket.sol).

## Compile and Test Contract using Hardhat

### **Create a Hardhat Project**

```bash
mkdir hardhatdemo
cd hardhatdemo
npm init
npm install --save-dev hardhat
npx hardhat
```

### **Configure hardhat.config**

Include TestNet node information:

```javascript
module.exports = {
    defaultNetwork: "ontology_testnet",
    networks: {
        hardhat: {},
        ontology_testnet: {
            url: "http://polaris2.ont.io:20339",
            chainId: 5851,
            gasPrice:2500000000000,
            gas:2000000,
            timeout:10000000,
            accounts: ["your private key1","your private key2"]
        }
    },
    solidity: {
        version: "0.8.0",
        settings: {
            optimizer: {
                enabled: true,
                runs: 200
            }
        }
    },
};
```

`accounts` field takes the array of selected private key. There should be enough ONG balance in the corresponding address to pay for transactions. You can apply for TestNet ONG [here](https://developer.ont.io/).

### **File Preparation**

Add the contract file in the `contracts` folder. To support ERC-20 token transfer, we also need `EIP20Interface.sol`, `UniversalERC20.sol`, and `TokenDemo.sol` which you can download from [here](https://github.com/ontio/ontology/blob/master/docs/specifications/evm_refernce/contract-demo/hardhatdemo/contracts).

### **Include Code in the test Folder**

```javascript
describe("RedPacket", function () {
    let tokenDemo, redPacket, owner, acct1, assetAmount, packetAmount;
    beforeEach(async function () {
        const TokenDemo = await ethers.getContractFactory("TokenDemo");
        tokenDemo = await TokenDemo.deploy(10000000, "L Token", 18, "LT");
        await tokenDemo.deployed();
        const RedPacket = await ethers.getContractFactory("RedPacket");
        redPacket = await RedPacket.deploy(tokenDemo.address);
        await redPacket.deployed();
        [owner, acct1] = await ethers.getSigners();
        assetAmount = 1000;
        packetAmount = 10;
    });
    it("token", async function () {
        expect(await redPacket.token()).to.equal(tokenDemo.address);
    });
    it("sendRedPacket", async function () {
        const approveTx = await tokenDemo.approve(redPacket.address, assetAmount);
        await approveTx.wait();

        const sendRedPacketTx = await redPacket.sendRedPacket(assetAmount, packetAmount);
        await sendRedPacketTx.wait();
        let balance = await tokenDemo.balanceOf(redPacket.address);
        expect(balance.toString()).to.equal(assetAmount.toString());

        res = await redPacket.nextPacketId();
        expect(res.toString()).to.equal("1");

        await redPacket.connect(acct1).receivePacket(0);
        balance = await tokenDemo.balanceOf(acct1.address);
        expect(balance.toString()).to.equal((assetAmount / packetAmount).toString());
    });
});
```

### **Compile Contract**

Run this command in the root directory to compile the contract.

```bash
$ npx hardhat compile
Compiling 5 files with 0.8.0
Compilation finished successfully
```

Then the following folders are generated.

```bash
.
├── artifacts
├── cache
├── contracts
├── hardhat.config.js
├── node_modules
├── package-lock.json
├── package.json
├── scripts
└── test
```

### **Test Contract**

```bash
npx hardhat test
```

You will get the following result:

```bash
sss@sss hardhatdemo % npx hardhat test
  RedPacket
    ✓ token
    ✓ sendRedPacket (16159ms)


  2 passing (41s)
```

{% hint style="info" %}
You can refer to the **Ethereum Web3 API** by following the link below.
{% endhint %}

{% content-ref url="/pages/-MiKeP3mdf5O969ZxyCs" %}
[Web3 API](/developer-tools/api/eth-web3-api)
{% endcontent-ref %}


# How to Deploy a Smart Contract with GetBlock

Dive straight into our freshly brewed guide from the devs' desk. Your dream of deploying a smart contract on Ontology is about to become a reality with these easy, step-by-step instructions.

## 1. Get Ready

Set up a Development Environment:

* [Solidity programming language](https://soliditylang.org/).
* Development tools like \[[Truffle](https://trufflesuite.com/)] or \[[Remix IDE](https://remix.ethereum.org/#lang=en\&optimize=false\&runs=200\&evmVersion=null\&version=soljson-v0.8.18+commit.87f61d96.js)].
* [Node.js](https://nodejs.org/en) on your computer.
* [Web3.js](https://web3js.readthedocs.io/en/v1.10.0/) library.
* The Ontology RPC URL endpoint by [GetBlock](https://getblock.io/).

## 2. Create Your Smart Contract (Example)

```
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;

contract FunctionalityContract {
    string message;
    function setMessage(string memory newMessage) public {
        message = newMessage;
    }
    function getMessage() public view returns (string memory) {
        return message;
    }
}
```

Save this as *Test.sol* or a name of your choice with *.sol* extension.

## 3. Compile Your Smart Contract

`truffle compile Test.sol`

You'll receive an output similar to:

```
Compiling your contracts...

> Compiling ./Test.sol
> Artifacts written to /Users/hannask/explorer/ontologi/build/contracts
> Compiled successfully using:
— solc: 0.8.19+commit.7dd6d4e4.Emscripten.clang
```

This generates two crucial files: the bytecode (`.bin`) and ABI (`.abi`). The bytecode is the version ready for the Ontology blockchain, while the ABI describes how you can interact with the contract.

## 4. Connect to Ontology's RPC Node with Web3.js

You can achieve this connection by using the following script. Remember to replace `<Ontology RPC URL>` with the URL you got from GetBlock.

In order to get one, register on [*GetBlock.io*](https://getblock.io/), choose Ontology in the protocols, testnet as a network and create your endpoint, then copy it to use for your purposes. If you want to deploy contract on mainnet, then choose mainnet as a network.

<figure><img src="/files/10tR17mnX1nB7K8OLSfh" alt=""><figcaption></figcaption></figure>

```
const Web3 = require('web3');
const web3 = new Web3('https://ont.getblock.io/<API-KEY>/testnet/web3/');
```

## 5. Deploy Your Smart Contract with Web3.js

The following script assists in deploying the smart contract:

```
const fs = require('fs');

// Read ABI and bytecode files
const abi = JSON.parse(fs.readFileSync('<path-to-abi-file>', 'utf8'));
const bytecode = fs.readFileSync('<path-to-bytecode-file>', 'utf8');

// Create a new Contract object using ABI
const myContract = new web3.eth.Contract(abi);

// Create a transaction object using the bytecode
const deployTransaction = myContract.deploy({
    data: '0x' + bytecode,
    arguments: [arg1, arg2, ...]
});

// Send the transaction to Ontology
deployTransaction.send({
    from: '<sender-address>',
    gas: <gas-limit>,
    gasPrice: <gas-price>
})
.on('receipt', (receipt) => {
    console.log('Contract deployed at address:', receipt.contractAddress);
});
```

Don't forget to fill in the placeholders (`<path-to-abi-file>`, `<path-to-bytecode-file>`, `<sender-address>`, `<gas-limit>`, and `<gas-price>`) with the corresponding details.

## 6. Test Your Smart Contract

Once your smart contract is deployed, it's crucial to test its functionality to ensure it behaves as expected.

```
// Set a message
myContract.methods.setMessage("Hello, Ontology!").send({ from: '<sender-address>' }).then(receipt => {
    console.log('Transaction receipt:', receipt);
});

// Get the message
myContract.methods.getMessage().call().then(result => {
    console.log('Stored message is:', result);
});
```

This test involves setting a new message in the contract and retrieving it. You should see "Hello, Ontology!" printed in your console.

## 7. Celebrate Your Success! 🎉

You've now written, deployed, and tested a smart contract on the Ontology network using the GetBlock RPC node provider. Cheers to your contribution to the decentralized world!

<br>


# NeoVM Contract

Native Ontology contract development and deployment


# Development tools and environment

Tools required to start developing contracts

Before we start with the actual development process, we need to ensure that we have the required tools at hand.

The following are the essentials that will be at the core of the development process of smart contracts using Ontology:

* **SmartX** **-** Ontology's online smart contract IDE and debugger
* **Cyano wallet** **-** Google Chrome extension
* **Explorer** **-** Web based public tool used to track blockchain activity and transactions in general

Setting up the development environment can be a complicated and time-consuming process. That is the reason why we have tried to make this step as swift and convenient as possible. The tools are web based and are practically ready to use right away.

Firstly, for the sake of simplicity and convenience, we will be testing the contracts we develop on the test net, thereby eliminating the need of a private chain. A private blockchain network architecture can be set up just as easily on your local environment using Ontology's **Punica suite**, a set of development tools that allows for smart contract deployment and testing on the private net. Follow [**this**](/guides-and-tutorials/development-guides/smart-contract-dev/neovm-contract/deploy-test) link for more details.

The first tool that we need is a web browser. We recommend using [**Google Chrome**](https://www.google.com/chrome) for the entire process as Cyano wallet is a Chrome plugin.

Next, we need to install the **Cyano wallet plugin** in the browser. You can search "Cyano Wallet" in the Chrome store, or follow [**this**](https://chrome.google.com/webstore/detail/cyano-wallet/dkdedlpgdmmkkfjabffeganieamfklkm) link.

![](/files/-LvPYVIoFSozO4UHni0d)

Once the installation completes and you launch the wallet for the first time, you will be prompted to login.

In case you already have a Cyano account, you can choose to login using your private key and mnemonics phrase.

If not, register a fresh account and proceed. Ensure that you save the private key and the mnemonics phrase in a secure location.

Once logged in, export the wallet to an external **.dat** file. This can be done by accessing settings by clicking on the cog in the top right corner. Ensure that it is stored securely. We will use this file later to work with SmartX.

![](/files/-LvPYVIqdbpWSVTKiftx)

Ensure that you change the network setting to **TEST-NET**, since we will be deploying and testing our logic on the test net.

{% hint style="warning" %}
Note: Deploying and testing smart contracts on the test net can be carried out without a MainNet **ONT/ONG** balance. But, to pay the gas cast of deploying a contract on the TestNet, you will still need a nominal TestNet **ONG** balance. The gas cost is calculated by taking the product of gas price and gas limit (gas price \* gas limit). Test tokens can be applied for by following [**this**](https://developer.ont.io/applyONG) link.
{% endhint %}

![](/files/-LvPYVIszYOd_zG1RvkS)

![SmartX main page](/files/-LvPYVIuNH2DsmwYrpOI)

The IDE that we will be using is Ontology's **SmartX**, a browser-based development environment that supports Python, C#, and JavaScript(coming soon). We are going to take an in-depth look at the development process using Python, as far as this tutorial is concerned.

**NeoVM** serves as the execution engine for the programs written using Python in SmartX. The SmartX core integrates all of Ontology's APIs, and so all the different functions which allow us to perform blockchain related tasks can be used directly by importing the relevant API, which we will be discussing later.

![Ontology Explorer main page](/files/-LvPYVIwKkyENo4YdsxI)

**Explorer** is an online web based tool that can be used to track transaction and event related blockchain activity. It can be used to monitor both the TestNet and the MainNet using transaction hashes, ONT IDs, contract addresses, and even block height. It can be accessed by following [**this**](https://explorer.ont.io/) link.


# Launching the IDE

A guide for first time SmartX users

![](/files/-LvPYVIuNH2DsmwYrpOI)

Here, you can use the **.dat** exported earlier to login to SmartX. Alternatively, you can also use directly launch the wallet and authenticate from there, or even use your Github account to login.

![](/files/-LvPYVETa9H3n0Mn_jaD)

Once logged in you will be prompted to select a project. Create a new one if there are no existing projects.

![](/files/-LvPYVFcK4rY7ZUtyU0v)

Upon selecting the new project option, you can choose a programming language to work with. In this tutorial, since our focus is on developing smart contracts with **NeoVM**, we will be illustrating examples and sample code using **Python**.

![](/files/-LvPYVEXIPsiQUAsE8TH)

A list populated with a set of examples and templates of smart contracts will be displayed once you proceed to the next menu. You can choose any example and go through the sample code or use it as a base to give structure to your own smart contract logic. For this tutorial we will be looking at the **OEP-4** illustration.


# Writing and editing program logic

Start writing code for smart contracts

![](/files/-LvPYVIcfn7EKGAWtylj)

Once **SmartX** is up and running, this what the main window looks like.

Since we have selected the **OEP-4** template, the code is already present in the editor area. You may choose to edit this code as you please based on the logic that you're trying to implement. But for the sake of simplicity and staying within the scope of this tutorial we will use the code as it is to ensure uniformity.

It is worth taking some time to take a look at the code and the overall structure of the program that we'll be working with.

![](/files/-LvPYVIe86Or8PpmPbxb)

The variables declared in this section of the code define the protocol itself and the specifics that will govern its functionality.

Variables such as `NAME` and `SYMBOL` serve as identifiers for the token.

`FACTOR` is the base 10 value that dictates the precision of amounts that can be transferred. For example, if the value is set to 100, transfer amounts with values up to two levels of precision are supported by the system. `DECIMALS` stores the multiplier value for access convenience.

`OWNER` stores the **Base58** address of the entity or account that holds the authority over the totality of tokens and can choose to distribute them as and when needed.

`TOTAL_AMOUNT` stores the total number of tokens that exist. Always a fixed number.

`BALANCE_PREFIX` is an access modifier that is used with account addresses for authentication purposes. `APPROVE_PREFIX` serves the same purpose, but for the approve operation wherein the owner can authenticate another account to use tokens.

`SUPPLY_KEY` correlates directly to the total amount of tokens and is used for any operations that may be carried with the total tokens figure, since the value isn't directly accessible.

![](/files/-LvPYVIgUIWgos-SHO_i)

This line immediately stands out in the upper section of the code.

`GetContext()` is a function that acts as the bridge between the smart contract and the blockchain. It is used when fetching and transmitting data from and to the chain by calling the `GET` and `PUT` functions which are a part of the **Storage API**.

We will go through the relevant APIs as we come across the respective functions, and the full set of available APIs in a later section of the tutorial.

![](/files/-LvPYVIiqZ61iZznZy3l)

Since we're working with the online SmartX IDE, all the APIs and functions are available for use and can be accessed directly by importing at the start of the program. Here, the functions that we import are `GetContext()`, `Get()`, `Put()`, and `Delete()` from the **Storage API**, `Notify()`, `CheckWitness()` and `Base58ToAddress()` from the **Runtime API** and the built-in function `concat()`.

{% hint style="info" %}
In later versions, built-in functions don't need to be imported and can be called directly.
{% endhint %}

Let us take a look at the `main()` function.

![](/files/-LvPYVIkXckDaetHHEP8)

The Main() function takes two arguments, `operation` and `args`. The *operation* argument is based on the operation to be performed and dictates the function to the executed. The `args` argument helps passing the important information that a function needs to carry out further execution, for example account addresses or input data.

Here, clearly there are 11 different functions that can be called depending upon the argument that is passed in Main(). SmartX passes these arguments using the "Options" pane on the bottom right.

* **init()** **:** The init() function serves as the starting point of the program logic. It initializes the definition variables declared at the top based on the values provided. Thus, this is the first function that needs to be executed post deployment.
* **name() :** This function returns the name assigned to the token, "My Token" in this case.
* **symbol() :** This function returns the symbol assigned to the token, "MYT" in this case.
* **decimals() :** Returns the number of decimal places that designate the precision of valid token values, 8 in this case.
* **totalSupply() :** Returns the total number of tokens assigned while initializing. Denotes the fixed number of tokens allocated for circulation. (Uses `SUPPLY_KEY` to fetch the value from the chain, stored earlier during initialization)
* **balanceOf(acct) :** Fetches the corresponding token balance of the account that identifies with the Base58 address passed as argument to the function.
* **transfer(from\_acc, to\_acc, amount) :** Transfers the equivalent token value passed as the amount argument to the `to_acc` address from the `from_acc` address.
* **transferMulti(args) :** The parameter here is an array that contains the same information, i.e., the sender's address, receiver's address, and the amount to be sent, in that sequence at the respective indices. It can be iterated for multiples transactions by passing the respective account addresses and the corresponding amount.
* **transferFrom(spender, from\_acc, to\_acc, amount) :** The spender here takes a certain amount of tokens from the `from_acc` address, and transfers them to the `to_acc` address.
* **approve(owner, spender, amount) :** The owner authorizes the spender to use a certain amount of tokens from their own account. Both the owner and spender arguments here are Base58 addresses and the amount specifies the amount that the spender is authorized to spend.
* **allowance(owner, spender) :** This function can be used to the amount that the owner account has authorized spender to use. Both arguments in this case are **Base58** addresses.

The functions above can be classified into two different types- access functions and utilities. Let us consider the flow of control as these functions are called.

**Access functions** are primarily used to fetch data post contract deployment. Functions such as `name()`, `symbol()`, `totalSupply()` and `balanceOf(acc)` allow us to achieve this by using `get()` function from the **Storage API** which fetches relevant data from the chain. Let us look at how it is implemented in program logic.

**name() function definition**

![](/files/-LvPYVImX3x8yOVttqQV)

This is how a simple access function can be defined. The `name()` function takes no arguments. Even though functions such as `name()`, `symbol()` and `decimals()` do not explicitly call the `get()` function, after the contract is deployed, all the data is fetched from the chain.

**balanceOf(acc) function definition**

![](/files/-LvPYVIogzOsWw2iEcI1)

The `balanceOf()` function takes one argument, a `Base58` address which denotes an account. There is a validity check in place that verifies the length of the address and raises an exception if the address is invalid. If the address is valid the `get()` function is called with two arguments, the account address prefixed with `BALANCE_PREFIX`, and the context.

The context allows for data reference on the chain to fetch the account balance value, while the prefixed account address ensures authenticated access. Next, `get()` returns this data to `Main()` where it is output to the log window using the `notify()` function. The `totalSupply()` function works in a similar fashion.

{% hint style="info" %}
The balance and approve prefixes are hexadecimal values in `ASCII` format and can be modified to support your own program logic.
{% endhint %}

Let us look at the utilities in the sample code.

Utilities are methods that have richer functionality and help modifying the on-chain data, which is the basis for transactions and tasks that may be carried out. The **OEP-4** token logic that the code template is using illustrates various use cases and scenarios in the form of functionality. This is to exhibit just how versatile smart contracts are in nature and the different kinds of business logic that they can be used to generate.

**transfer(from\_acc, to\_acc, amount)**

![](/files/-LvPYVIqQ_z1mdb1t3Sq)

The `transfer()` function implements the most fundamental transaction feature, transferring tokens from one account to another. It takes three arguments, the sender's address, the receiver's address, and the amount to be transferred.

The function carries out verification by a simple length check, but a more complex logic can be developed based on individual needs.

Next, the `BALANCE_PREFIX` is concatenated to the sender's account address, and balance is retrieved by making a `get()` call using this address. A quick comparison is made in the next step where the sender account's balance is compared with the amount to be transferred. All three scenarios have been defined clearly.

If the balance is less than the transfer amount, the transaction fails, and the control returns to `Main()` directly.

If the amount equates to the balance amount exactly, the balance of sender account is set to 0 by calling the `delete()` method using the sender's prefixed address. This is practically equivalent to using the `put()` method to manually assign the value 0 to sender's account but using `put()` method in this case might give rise to security vulnerabilities.

If the balance is higher than the transfer amount, the amount is deducted from the balance by making a `put()` call and updating the sender accounts balance with the deducted value.

Next, the receiver's address is prefixed with the `BALANCE_PREFIX`, and the prefixed address is used to add the transfer amount to the receiver's account.

Finally, this transaction event is sent to the chain using the `RegisterAction()` method for recording in a ledger.

The `transfer()` function implements the most fundamental transaction feature, transferring tokens from one account to another. It takes three arguments, the sender's address, the receiver's address, and the amount to be transferred.

The function carries out verification by a simple length check, but a more complex logic can be developed based on individual needs.

Next, the `BALANCE_PREFIX` is concatenated to the sender's account address, and balance is retrieved by making a `get()` call using this address. A quick comparison is made in the next step where the sender account's balance is compared with the amount to be transferred. All three scenarios have been defined clearly.

If the balance is less than the transfer amount, the transaction fails, and the control returns to `Main()` directly.

If the amount equates to the balance amount exactly, the balance of sender account is set to **0** by calling the `delete()` method using the sender's prefixed address. This is practically equivalent to using the `put()` method to manually assign the value 0 to sender's account but using `put()` method in this case might give rise to security vulnerabilities.

If the balance is higher than the transfer amount, the amount is deducted from the balance by making a `put()` call and updating the sender accounts balance with the deducted value.

Next, the receiver's address is prefixed with the `BALANCE_PREFIX`, and the prefixed address is used to add the transfer amount to the receiver's account.

Finally, this transaction event is sent to the chain using the `RegisterAction()` method for recording in a ledger.

**TransferEvent** is the alias that `RegisterAction()` uses here. `RegisterAction()` is a method of the **Action API** and it takes four arguments that are transferred to the chain in order to record transaction details. The transaction hash and certain other details are output in the logs section.

The **transferMulti()** is works in a similar manner. The logic remains the same, since basically all that `transferMulti()` does is call `transfer()`, but it allows for multiple transfers to take place simultaneously. It takes one argument which is a nested array. is the alias that `RegisterAction()` uses here. `RegisterAction()` is a method of the **Action API** and it takes four arguments that are transferred to the chain in order to record transaction details. The transaction hash and certain other details are output in the logs section.

The **transferMulti()** is works in a similar manner. The logic remains the same, since basically all that `transferMulti()` does is call `transfer()`, but it allows for multiple transfers to take place simultaneously. It takes one argument which is a nested array.

![](/files/-LvPYVIsOh7kHt2dvZbS)

The sub-array elements are processed in sets of three such that the first and second elements still represent the sender's and receiver's addresses, and the third element represents the transfer amount. The sub arrays are iterated till there are no more elements left in the `args[]` array.

Exception is thrown in case the sub-array does not contain exactly three elements, or the previous transaction fails for some reason, and the control comes out of the loop and goes back to `Main()`

**approve(owner, spender, amount)**

![](/files/-LvPYVIuoA7avBSypIpR)

The approve function implements another complex logic wherein an account, namely the `spender` is given the permission to utilize a certain amount in tokens from another account, namely the `owner`.

The function first carries out address validation in terms of length, and user authentication for the `owner` who is about to perform the approval.

Next, the amount selected for approval is compared to the available balance in the `owner` account.

If the account does not have enough balance the process is terminated, and the control returns to `Main()`.

If the account has enough balance, a key is generated by concatenating the `owner` address prefixed with `APPROVAL_PREFIX` and the `spender` address. It is then added to the ledger using the `put()` method by passing the context, the above generated key, and the approval amount.

The transaction event is then recorded using the `ApprovalEvent()` method, and the result containing the transaction hash returned by the **NeoVM** engine is displayed in the logs section.

## **transferFrom(spender, from\_acc, to\_acc, amount)**

![](/files/-LvPYVIwPOdCUIAbbwZS)

The `transferFrom()` function implements a more complex logic and carries out a task that may prove to be useful for certain applications.

This function allows a third party, namely the spender, to utilize a certain amount in tokens that are provided from an account that does not designate to their own credentials, basically implementing the same logic as that of the `approve()` function. It takes four arguments, which are three **Byte58** addresses and one transfer amount.

First, the function carries out the conventional address validation. Then it verifies whether the spender has the authorization to carry out this transaction using the `CheckWitness()` function which is a part of the **Runtime API**.

Next, the balance of the `from` account is fetched and cross-checked with the transaction amount to ensure the account has enough balance. The process to fetch the balance remains the same.

The spender's address is then prefixed with the `APPROVE_PREFIX` and the approved amount from is fetched using the prefixed address.

The transaction comes next. If the transaction amount is higher than the approved amount the transaction is aborted, and control returns to `Main()`.

If the amount is exactly equal to the approved amount, the transaction amount is deducted from the `from` accounts balance.

If the approved amount exceeds the transaction amount, the difference is calculated and stored in the ledger for future reference, and the transaction amount is deducted from the `from` account.

The transaction amount is then transferred to the `to` account using the `put()` function. The event is then recorded and the result with the transaction hash is displayed in the logs section of the **IDE**.

Another function that implements a similar logic has be defined as **allowance(owner, spender)** which facilitates querying the amount of allowance that has been allocated to the `spender` account from the `owner` account.

![](/files/-LvPYVIyTVwH7skr6lFq)

Practically speaking, this function cam be classified as an access function too in the sense that it returns the allowance value. But it also performs a `get()` query to fetch this result from the chain.

A key generated by concatenating the prefixed owner address and the spender address is passed to the `get()` method along with the context to fetch the required allowance value, which is then returned to `Main()`. The value can then be displayed or used to perform other tasks.


# Deploying and testing on private net

Testing contracts on private net

This brief tutorial will help you with private chain smart contract set-up, testing, and finally deployment on the MainNet.

There are certain tools that will be key to the process that follows-

* **SmartX** **-** Ontology's online Smart contract IDE and debugger.
* **Solo-chain** **-** A pre-built private chain.
* **Cyano wallet -** Ontology's Google Chrome plug-in.

## How to invoke a smart contract in SmartX

![](/files/-LvPYVFPX8QVtyYT3ONT)

### 1. Download and install solo-chain

Solo-chain is a pre-built private chain. It encapsulates many different network communication and monitoring tools.

Set up solo-chain and verify whether it operates as configured. You can do this by checking the blocks that are currently being generated and the transactions that are taking place.

{% hint style="warning" %}
Please note down the IP address that is displayed in the control panel for future reference.
{% endhint %}

![](/files/-LvPYVFR6prC1zQM_mMD)

### 2. Install Cyano Wallet plugin in Google Chrome

**Cyano** wallet is a chrome integrated development program which allows developers to deploy and test smart contracts on the TestNet and MainNet.

Install Cyano wallet and then in the main window click on the ![](/files/-LvPYVFTAMoua6gJt7qY) icon in the top right corner.

![](/files/-LvPYVFVuPnzupuG_Gnz)

Change the "Net" option to **PRIVATE-NET**, and paste the IP address copied from solo-chain (Under normal circumstances the address of the private node is `127.0.0.1`). Save the settings by scrolling down and clicking the save button at the bottom.

Once Cyano successfully connects to the private net, the ![](/files/-LvPYVFXA-eg4kmBw5yD) icon at the bottom right corner of the wallet window will change to![](/files/-LvPYVFZu0an84xzekro) icon indicating that the connection has been successfully established.

{% hint style="info" %}
For users with slower network speeds, the connection phase might take a few seconds.
{% endhint %}

Next, the private key is imported to the Cyano wallet from the solo-chain.

At the end, transactions can be initiated and the transaction fees can be drawn in `ONG`. The transaction fees here refer to the costs incurred during the testing and deployment phases of the smart contract respectively.

### 3. Accessing SmartX IDE

We will use SmartX to develop, compile, and test smart contracts. Useful information regarding Smart contract development can be found [**here**](https://smartx.ont.io/).

You can login to SmartX using your Cyano wallet **.dat** file if you're already registered, or you can login using Github.

![](/files/-LvPYVFaizXSAmj_Pg0G)

Once logged in, you can create a new project. After selecting the new project option, you will be prompted to select a programming language.

![](/files/-LvPYVFcK4rY7ZUtyU0v)

Select the programming language of your choice. Next, a list of templates will appear. Select the template that is the most appropriate, or you can choose to choose the "Blank" option in case you want to start with a blank file. Give your file a name and proceed.

For simplicity, here we demonstrate the "Domain" template written in Python.

![](/files/-LvPYVFew_nAh7fdsc5O)

The next window that pops up is the main IDE that encapsulates editing, compilation, and testing of smart contracts into one convenient package.

### 4. Compiling and Deploying Smart contracts

![](/files/-LvPYVFgDyBcQ9ie5Eji)

Once you complete the editing process of your code, it can be compiled using the compile function that is accessible from the right hand side pane under the compile section. If the code is successfully compiled, a lot of useful information such as the **AVM** bytecode and the **ABI** details will be displayed on the bottom.

Next, you may proceed to deploy the contract.

{% hint style="warning" %}
Please note that deploying, running and testing contracts incurs gas cost and uses 0.01 units of ONG, and thus requires a certain amount of ONG balance to be present in your wallet. In case you don't have any, test tokens are available free of cost and can be applied for [**here**](https://developer.ont.io/applyOng).
{% endhint %}

![](/files/-LvPYVFitHn5Hdgwo2Er)

Fill in the details and deploy the contract.

![](/files/-LvPYVFkXt_R4GJs30jg)

![](/files/-LvPYVFmuPm3UoDBcgyN)

Using solo-chain, it can be confirmed whether or not the smart contract was successfully deployed. If the contract is deployed successfully you may then run it.

Under the run tab, the contract hash and a drop down list populated with the available functions can be accessed. The respective arguments in their corresponding data types can be passed through this pane.

![](/files/-LvPYVFo0MAW2qtSFERe)

The three operations over here can be used to perform the following functions-

* **Debug Run:**  can be used to verify whether the code works as intended within the local environment.&#x20;
* **Pre-Run:**  can be used to invoke the query method, get the gas limit of the contract.
* **Run:**  the engine calls the smart contract and brings up the wallet, wherein the gas price can be set. Once confirmed,  the transaction is authorized and the transaction fee is charged in ONG.

![](/files/-LvPYVFqmW84hezuPQYt)

Every time the system returns a value or response, it will be displayed in the logs section. The return values are limited to hashes and hexadecimal values. There is a separate "Tool" section in the top right hand pane which facilitates conversion between different units and data types along with providing other useful functions.

![](/files/-LvPYVFsCpv9mzAqL96f)

The "Test" tab allows for multiple functions to be executed simultaneously. This allows for testing to mimic how the smart contract would actually function in real time when integrated into a dApp.

![](/files/-LvPYVFu8r_Klmh_RqEN)

The "restful" tab refers to the restful API that Ontology employs as the link that allows for communication with nodes. Here we use it to fetch chain and transaction related information.

![](/files/-LvPYVFwPq7IE_vWg0mG)

![](/files/-LvPYVFyX5ucmnrBOhcM)

The collapsed `result` tab in the pop-up window includes detailed information with respect to the query. The tab can be expanded to reveal the information.

![](/files/-LvPYVG-b7IIhfxbYW7g)

### 5. Migrating to MainNet

Once the testing phase completes, we can move on to deploying the smart contract on the MainNet.

First, bring up the Cyano wallet and access settings by clicking on the cog ![](/files/-LvPYVG1mHzgSJbT_r5s) in the top right hand corner.

![](/files/-LvPYVG3t-laEaGs3u43)

Save the settings and your wallet will connect to the MainNet.

{% hint style="success" %}
At this point, do ensure that your wallet has enough gas to further deploy contracts.
{% endhint %}

Next, you may return to SmartX and continue with the development process. The procedure to test and deploy the contracts does not change. Before you proceed, do confirm that the wallet's connection to the MainNet is still intact.


# WASM Contract

WASM smart contract development using the Ontology platform

![](/files/-LvPYWInQKWUwZXNJCdD)

Ontology's WebAssembly based (WASM) contracts support development in Rust and C++. In this tutorial, we will focus on smart contract development using Rust.

This simple walkthrough aims at allowing developers who are just getting started with building WASM contracts. The guide will help you with installing the development environment and then slowly move towards the development process.

The tutorial does follow a sequence, but feel free to navigate through the different sections based on your requirements.

{% content-ref url="/pages/-LwHH-Vd\_cW4P8CY4zGA" %}
[Development Environment](/guides-and-tutorials/development-guides/smart-contract-dev/wasm/dev-environment)
{% endcontent-ref %}

{% content-ref url="/pages/-LwHH-VechxHIJ1Tj1ja" %}
[Project Initiation - Hello World](/guides-and-tutorials/development-guides/smart-contract-dev/wasm/hello-world)
{% endcontent-ref %}

{% content-ref url="/pages/-LwHH-VfVyJ\_ktmt85yj" %}
[Creating your own project](/guides-and-tutorials/development-guides/smart-contract-dev/wasm/create-new-project)
{% endcontent-ref %}


# Development Environment

Setting up the required tools on the local machine

![](/files/-LvPYWzAAGreDq_eL0E0)

To make the development process as smooth and as efficient as possible, we recommend confirming that all the tools mentioned below are installed and configured properly on your local machine.

* **Rust** development environment
* An **Integrated Development Environment** (IDE) software
* Ontology's **WASM** contract testing **private node**&#x20;

Let us look at the installation process for the above mentioned tools one by one.

{% hint style="warning" %}
For this tutorial, we will be setting up a private test node for testing our `WASM` contract. This will allows us to add `debug` information to the contract and monitor the contract's run-time information in the logs section. In case you feel that node setup is complicated, you can always use the testnet to deploy and invoke contracts, something that we are working on at Ontology and hope to make available very soon.
{% endhint %}

## Rust Development Environment

**Non-windows** platforms can use the following shell command to install **rustup**.

```bash
curl https://sh.rustup.rs -sSf | sh
```

For **windows** users, please follow [**this**](https://www.rust-lang.org/tools/install) link to directly download rustup from the official website. Install and add the respective PATH environment variables by following the directions provided.

Install the Rust compiler using this shell command.

```bash
rustup install nightly
```

Set the default compiler version to nightly by-

```bash
rustup default nightly
```

Install the `wasm32` compiler target-

```bash
rustup target add wasm32-unknown-unknown
```

Later when we write our Rust code, we will be compiling it and converting it to bytecode using the `cargo` tool. But, the file that `cargo` generates is relatively large in size. Therefore, to compress the bytecode file, as well as to check and optimize it for deploying on the blockchain, we will be using the **ontio-wasm-build** tool.

`ontio-wasm-build` can be installed using the following shell command-

```bash
cargo install --git=https://github.com/ontio/ontio-wasm-build
```

For more details on ontio-wasm-build, please refer to [**this**](https://github.com/ontio/ontio-wasm-build) link.

## Integrated Development Environment (IDE) Software

Since we will be using rust, there are certain IDEs that work well. The following IDEs can be used-

* **IntelliJ IDEA** - <https://www.jetbrains.com/idea/download>
* **IntelliJ CLion** - <https://www.jetbrains.com/clion/download/>
* **Vim Editor** - <https://www.vim.org/download.php>

## Local Test Node Set-up

A private node can be set up on the local machine and run using Ontology's CLI.

In order to realize this, we must first download and configure the implementation of Ontology's core software.

{% hint style="info" %}
Information and direction on how to build Ontology from the source code can be found by following [**this**](https://github.com/ontio/ontology#build-from-source-code) link.
{% endhint %}

The executable for the latest release different operating systems can be downloaded from [**this**](https://github.com/ontio/ontology/releases/) link.

After download and installing Ontology, we don't have to build it from the source code and can directly proceed with the development process.

{% hint style="warning" %}
When running the pre-built executable file, please set the log level to **DEBUG** mode. Debug information is more conveniently accessible in this mode.
{% endhint %}


# Project Initiation - Hello World

An illustration to write the contract logic using rust

To execute Rust code on the Ontology blockchain, there's a process that needs to be followed. The steps are carried out in the following way:

1. WASM bytecode is generated by compiling the code.
2. The bytecode is deployed on to the chain.
3. Functions from the contract are invoked.

We will approach the development process from two different angles. In this section, we will first look at a template designed with the specific goal of getting you acquainted with the fundamentals of writing a WASM smart contract and working with a template. And then in the later sections, we will proceed to demonstrating how to start writing code from scratch.

To facilitate developers looking to work on Ontology WASM smart contracts we have made available a Rust template that developers can clone and start editing to speed things up. The code can be cloned from Github using the following command-

```bash
git clone https://github.com/ontio/rust-wasm-contract-template.git
```

## Project file hierarchy and specifics

The file hierarchy of the project is mapped below.

```rust
.
├── .cargo
│   └── config
├── Cargo.toml
├── build.sh
└── src
    └── lib.rs
```

The **config** file in `.cargo` directory contains the configuration settings which will be used when compiling the contract. The contents of the file-

```bash
[target.wasm32-unknown-unknown]
rustflags = [
    "-C", "link-args=-z stack-size=32768"
]
```

`[target.wasm32-unknown-unknown]` is the compile target. The target will directly be compiled to WASM using the low-level virtual machine (LLVM) back end. The resultant bytecode can be executed on Linux, Mac, and Windows system platforms. `rustflags` is used to configure the link arguments and the default stack size to 32768 bytes, 32KB that is. This indicates the highest stack value that the contract is allowed to use.

`cargo.toml` file contains a few configuration settings and other details regarding the contract. The content is as follows-

```yaml
[package]
name = "rust-wasm-contract-template"
version = "0.1.0"
authors = ["laizy <aochyi@126.com>"]
edition = "2018"

#See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["cdylib"] #Compile as a dynamic link library

[dependencies]
ontio-std = {git = "https://github.com/ontio/ontology-wasm-cdt-rust"}

[features]
mock = ["ontio-std/mock"]
```

In the `[lib]` configuration module, `crate-type = ["cdylib"]` specifies the compilation `DLL` that can be invoked using other languages.

`path = "src/lib.rs"` sets the library file path.

`[dependencies]` section is used to specify the project dependency details. Here, we import the `ontio-std` library.

`[features]` is used to toggle newly introduced features that are unstable. These features can be used with the nightly version compiler only.

The `build.sh` file encapsulates functions that will be used to compile and optimize our contract. Executing this shell script will move the optimized bytecode to the output directory.

The src/lib.rs rust file is used to write the contract logic. The template contains the following code:

```rust
#![no_std]
use ontio_std::runtime;

#[no_mangle]
fn invoke() {
    runtime::ret(b"hello");
}
```

`#![no_std]` annotation is used to indicate that the core library is to be used instead of the standard library, referred to as **crate** in rust. This will allow us to use Ontology's APIs.

`#![no_mangle]` annotation indicates that when the code is compiled to `WASM` bytecode, the compiler will not obscure the invoke method. The runtime module encapsulates the API that allows the contract to communicate with the blockchain. The `runtime::ret()` method is used to return the result of contract invocation. Here, we are trying to implement a simple contract that returns "hello" when invoked.

## Compiling the contract

The code can be compiled and the optimized bytecode can be fetched by running the `build.sh` shell script.

```bash
./build.sh
```

{% hint style="warning" %}
If the console returns a "Permission denied" message, use `sudo` on linux systems or run the command line as administrator on windows platforms and run the script again.
{% endhint %}

After the script successfully executes, it will create the output directory in the following way-

```bash
├── output
│   ├── rust_wasm_contract_template.wasm
│   └── rust_wasm_contract_template.wasm.str
```

Two files are generated here. The WASM file is the bytecode generated by compiling the smart contract that we compiled, and the **str** file contains the hex encoding for the bytecode.

## Deploying the contract

Once the code is compiled, it needs to be deployed on to the chain to be executed. The bytecode that we generated can be deployed on both the test net and the private net for testing. For now, let us look at how to deploy the contract on the private net.

First, we need to create a wallet account and run our private node. We use the following shell command to create an account-

```bash
./ontology account add
```

After executing the above command, follow the instructions and set up and account with the default configuration. Then, use the following command in a new command line window to start a private node.

```
./ontology --testmode --loglevel 1
```

The `--loglevel 1` parameter is used to set the log level to `debug`. In case there is any debug information returned while testing the node, it will be displayed in the log files generated in the Log directory.

In a new window, access the Ontology master directory and execute the following command to deploy the contract. Enter the password for the account when prompted.

The parameters consist of the target path and some other information regarding the contract which is optional to fill in. The `gaslimit` is set at the end.

{% hint style="warning" %}
Note: The gas limit is precise to 9 decimal places. Thus, 10^9 units of gas would be equivalent to 1 ONG token with the minimum valid value being 0.000000001. The gas cost, which basically means the cost to carry out a transaction on the chain, is calculated by taking the product of the gas price and the gas limit.
{% endhint %}

```bash
./ontology contract deploy --vmtype 3 --code ./rust_wasm_contract_template.wasm.str --name helloworld --author "author" --email "email" --desc "desc" --gaslimit 22200000
```

The result will be as follows-

```bash
Password:
Deploy contract:
  Contract Address:0be3df2e320f86f55709806425dc1f0b91966634
  TxHash:bd83f796bfd79bbb2546978ebd02d5ff3a54c2a4a6550d484689f627513f5770

Tip:
  Using './ontology info status bd83f796bfd79bbb2546978ebd02d5ff3a54c2a4a6550d484689f627513f5770' to query transaction status.
```

{% hint style="warning" %}
If the system returns the error that the gaslimit is not enough, please change the gaslimit and enter a bigger value.
{% endhint %}

## Test invocation

Next, we use the following command to invoke our smart contract. Here we use the contract address that was returned by the system earlier when we deployed the contract.

There are no parameters to be passed for this function, and the execution mode is `--prepare` which indicates that the contract will be pre-executed, thereby allowing us to see the value that will be returned by the `invoke` function.

```bash
./ontology contract invoke --address 0be3df2e320f86f55709806425dc1f0b91966634 --vmtype 3 --params '' --version 0 --prepare
```

The result is as follows-

```bash
Invoke:346696910b1fdc2564800957f5860f322edfe30b Params:null
Contract invoke successfully
Gas limit:20000
Return:68656c6c6f (raw value)
```

We expected a "Hello" to show up, but the value returned by the system is **68656c6c6f.** Why?

The reason is simple. All the data values returned by the system will be hex encoded. A simple hexadecimal to string conversion will show that **68656c6c6f** is in fact "Hello".

You have successfully executed your first Ontology WASM contract.

## Templates for reference

Please follow the following link to find the various templates made available by Ontology. The templates serve as examples that illustrate how token exchange and transaction protocols can be realized using rust.

### [Example Repo](https://github.com/ontio/ontology-wasm-cdt-rust/tree/master/examples)


# Creating your own project

Writing your smart contract from scratch

Using templates is convenient but it might limit certain dimensions of the development process.

So, let us write a contract from scratch and test it. This will be more helpful for developers who are familiar with smart contract development but are just getting started with Ontology WASM smart contracts.

## Create a New Smart Contract

We create a new library, so to speak, to start implementing a new smart contract. Navigate to the appropriate directory and execute the following code-

```bash
cargo new --lib helloworld
```

If successfully executed, the file hierarchy of the new library would look like so-

```bash
.
├── Cargo.toml
└── src
    └── lib.rs
```

As you may have noticed, a rust based WASM contract consists of two components, one being the `Cargo.toml` file and the other being the `src/lib.rs` rust file that is used to write and implement contract logic.

## Generate the ontio-std API File

Before generating the API file, we need to edit the `Cargo.toml` file to add certain dependencies and libraries that will be used later.

First, under the `[dependencies]` configuration, include the Ontology WASM contract toolkit. Also, since we will compiling the contract in a form that is different from the standard, we need to add `[lib]` configuration settings.

The `[features]` configuration is used to toggle certain unstable features. Please note that these features can only be compiled using the nightly compiler.

A complete `Cargo.toml` would look something like-

```yaml
[package]
name = "helloworld"
version = "0.1.0"
authors = ["Lucas <sishsh@163.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib"]
path = "src/lib.rs"
[dependencies]
ontio-std = {git="https://github.com/ontio/ontology-wasm-cdt-rust.git"}

[features]
mock = ["ontio-std/mock"]
```

We still do not know the APIs that we can use from the toolkit that we just included in the project dependencies.

The following command can be used to generate the API documentation for this library.

```bash
cargo doc
```

After successful execution of the above command the project structure would be as follows-

```bash
.
├── Cargo.lock
├── Cargo.toml
├── src
│   └── lib.rs
└── target
    ├── debug
    └── doc
```

The API documentation can be found in the doc directory. The settings.html file can be opened using a web browser. The reference for **ontio-std** library looks like-

![](https://github.com/hsutaiyu/DocumentationCentre_Backup/tree/7c051cc169c49d5eaf720a4a6930bf92edca4491/test/untitled-1-1/webassembly-distributed-application-development/.gitbook/assets/wasm-doc-ontiostd.jpg)

{% hint style="warning" %}
Libraries are referred to as **crates** in the context of Rust.
{% endhint %}

## Writing Contract Logic

The `src/lib.rs` file that was generated when we created a new library has the following contents by default-

```rust
#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
```

There is some test code included. You can test this code by executing the `cargo test` command under the `root` directory.

We can now proceed with writing our logic by editing this file.

First, we import the `ontio-std` library added in the `Cargo.toml` dependencies. We use the `#![no_std]` annotation so as to prevent rust from using the standard library.

```rust
#![no_std]
extern crate ontio_std as ostd;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
```

Then we add an invoke function that acts as the main() for all intents and purposes. We also import the APIs that will allow us to carry out parameter I/O.

```rust
#![no_std]
extern crate ontio_std as ostd;
use ostd::abi::{Sink, Source};
use ostd::prelude::*;
use ostd::runtime;

fn say_hello(msg: &str) -> String {
    return msg.to_string();
}

#[no_mangle]
fn invoke() {
    let input = runtime::input();
    let mut source = Source::new(&input);
    let action: &[u8] = source.read().unwrap();
    let mut sink = Sink::new(12);
    match action {
        b"hello" => {
        let msg = source.read().unwrap();
        sink.write(say_hello(msg));
        },
        _ => panic!("unsupported action!"),
    }
    runtime::ret(sink.bytes())
}

#[test]
fn test_hello() {

    let res = say_hello("hello world");
    assert_eq!(res, "hello world".to_string());
}
```

Here, `Sink` and `Source` objects have been imported. `Source` allows us to fetch the parameters and data that is passed when the contract is invoked externally. `Sink` is used to serialize data of different formats to the bytearray format.

The `prelude` module of ontio-std provides a few commonly used data types `Address`, `U128`, `String`, etc., apart from other useful functions.

The runtime API contains functions that are used to interact with the blockchain and the application end. For example, the `runtime::ret()` method is used to return the result of contract execution.

The `#[no_mangle]` annotation instructs the compiler not to obscure the main function while compiling it to ensure that Ontology's build tools can work with the bytecode that is generated post-compilation.

With this, the basic methods that allow us to interact with the contract are in place. The contract can now be compiled.

## Compiling the Contract

The code needs to be compiled and converted to `WASM` `bytecode` to be deployed on the chain. The following command can be used to compile a contract.

```bash
RUSTFLAGS="-C link-arg=-zstack-size=32768" cargo build --release --target wasm32-unknown-unknown
```

The `RUSTFLAGS="-C link-arg=-zstack-size=32768"` directive is used to set the maximum allowed stack size to 32KB. The default size of the `rustc` compiler stack is 1MB, which is very wasteful as far as smart contracts are concerned. `wasm32-unknown-unknown` indicates that the target bytecode be generated using the LLVM back end compiler. It generates better and more sophisticated code than the **emscripten** compiler.

Once the above code is successfully executed the target directory will look like-

```bash
.
├── release
│   ├── build
│   ├── deps
│   ├── examples
│   └── incremental
└── wasm32-unknown-unknown
    └── release
```

For our example, the file generated can be found in the `wasm32-unknown-unknown/release` folder under the `target` directory with the file name `helloworld.wasm`

The bytecode file generated post compilation tends to be large in size, and thus if deployed on to the chain in it's current form, a large amount of space would be required to store it, implying higher costs. To optimize storage, we use the **ontio-wasm-build** tool to optimize the bytecode and compress it.

{% hint style="warning" %}
More details for those curious about ontio-wasm-build can be found by following [this](https://github.com/ontio/ontio-wasm-build) link.
{% endhint %}

The tools can be used by executing the following command with the WASM bytecode file-

```bash
ontio-wasm-build helloworld.wasm helloworld_optimized.wasm
```

The file with the optimized bytecode goes by the name of **helloworld\_optimized**. Another file with a **.str** extension will also be generated. While deploying the contract we will be using this string file that contains hex code obtained by converting the bytecode, since we are carrying out this entire process using the CLI (Command Line Interface).

## Deploying and Invoking the Contract

To able to perform any transaction related operations we will first need to deploy our private test node, and a private test node requires a wallet file to work with. Here we make a new account and generate a `.dat` wallet file. Navigate to the Ontology root directory and execute the following command.

```bash
./ontology account add
```

Next, open a new terminal window and run the following command to start the private node.

```
./ontology --testmode --loglevel 1
```

`--testmode` selects the test mode to start the node, and `--loglevel 1` selects the debug mode so that the debug information gets recorded in the logs section for us to refer to, as and when needed.

We need to ensure that this particular window stays up and running in the background since this is what serves as our private node, practically speaking.

Then, return to the original window and execute the following command to deploy the contract.

```bash
./ontology contract deploy --vmtype 3 --code ./helloworld.wasm.str --name helloworld --author "author" --email "email" --desc "desc" --gaslimit 22200000
```

Let us go through the series of options used here one by one.

|   Option   |  Value  | Description                                                          |
| :--------: | :-----: | -------------------------------------------------------------------- |
|  --vmtype  |    3    | The VM type to be used to run the contract                           |
|   --code   |   Path  | Path of the file containing the bytecode                             |
|   --name   |  String | Name of the smart contract                                           |
|  --author  |  String | Name of the author of the smart contract                             |
|   --email  |  String | Email address of the contract author                                 |
|   --desc   |  String | Brief description of the contract                                    |
| --gaslimit | Integer | Gas limit to calculate the Gas cost for deploying the smart contract |

After the deploy command, `--vmtype 3` indicates that the contract is a WASM contract. We specify this since apart from WASM contracts, Ontology also supports NeoVM smart contract development in Python and C#. Interested developers feel free to check out the the relevant details.

Finally, if the contract was deployed successfully, we can proceed to invoke the contract using the contract details.

The `invoke()` function serves as the entry point for a smart contract. Any other functions that we may define in the scope of the contract can be called by passing parameters to the `invoke()` function and then calling the respective function from within `invoke()`. The functions that are defined under the `#[test]` annotation can be run locally from the IDE to test logic.

When we invoke the invoke() function here, it will return a "hello world" if the contract is invoked successfully, since the function we're calling is hello, and we have passed the string "hello world" as parameters. We just need to ensure that we use the `--prepare` option when invoking the contract. This means that we are pre-executing it, the reason for which being the result returned by the contract will not be displayed if we invoke and run the contract directly.

{% hint style="warning" %}
More details on contract invocation and CLI operation in general can be found [here](https://github.com/ontio/ontology/blob/master/docs/specifications/cli_user_guide.md).
{% endhint %}

The command is as follows-

```
./ontology contract invoke --address 913ea5298565123847ffe61ec93986a52e824a1b --vmtype 3 --params 'string:hello,string:hello world' --version 0 --prepare
```

If the executed successfully, **68656c6c6f20776f726c64** along with the transaction hash will be returned in the command line. The value is in fact "hello world" in hexadecimal.

You now have the fundamental understanding of Ontology's WASM contracts such that you can develop your own smart contracts and implement complex logic.

## Code for Reference

For examples and sample code that implement more complex logic, please follow the link below.

[**Example Repo**](https://github.com/ontio/ontology-wasm-cdt-rust/tree/master/examples)


# Development using SmartX

Developing and Deploying WASM Contracts using SmartX IDE

**SmartX** supports WASM contract deployment and invocation. Head over to **smartx.ont.io** (supported on Chrome browsers only) and try it out!

### 1. Selecting and Uploading a WASM file

First, we login to SmartX, and then once in the system we can see the "Project List". Here, we select the "Open WASM File" option.

![](/files/-M0uSSfdYoJBUM0eb0MX)

Here we enter the name of the WASM contract and upload the WASM bytecode file. This creates a new WASM contact project which we can return to later as well.

![](/files/-M0uSX37PR0b7iSIjpsO)

### 2. Opening a WASM Project

![](/files/-M0uSaanCTWSpeCmMGwD)

We can click on the newly created WASM project. As soon as we enter the project we can see the bytecode in the editor. We can make changes to this bytecode if necessary.

### 3. Deploying a WASM Contract

![](/files/-M0uSd3Jkezcf-WR_Z2x)

Next, we can proceed to deploy this WASM contract. The process is the same as deploying a NeoVM contract.

We fill out the necessary details in the top right "Information" pane, and then click on the "Deploy" button. SmartX then calls the Cyano Wallet plugin in the Chrome browser (assuming the latest version is already installed). The user is prompted to enter the password. If the wallet has sufficient **ONG** balance, the WASM contract will be deployed to the Ontology network.

### 4. Executing a WASM Contract

After deploying the contract successfully, we can open the "Run" pane. This is where we can choose the method that we want to call. After entering the necessary parameter values and types the contract can be prerun. The result of the execution will be displayed in the "Logs" pane at the bottom.

Here we conclude this simple guide on how to deploy and execute WASM smart contract in SmartX.


# Runtime API

WASM Contract Runtime API Specifications

The **runtime** module of the `ontology-wasm-cdt-rust` Ontology WASM contract development toolkit includes APIs that enable communication between the contract and Ontology blockchain. The API methods can be used to fetch on-chain data and store the contract data on the chain. The API methods have been listed below:

|                API Methods               | Response Value | Description                                                                                           |
| :--------------------------------------: | :------------: | ----------------------------------------------------------------------------------------------------- |
|                 timestamp                |       u64      | Fetch current timestamp                                                                               |
|               block\_height              |       u32      | Fetch current block height                                                                            |
|                  address                 |     Address    | Fetch address of the contract that is run                                                             |
|                  caller                  |     Address    | Fetch the address of the party invoking the contract, mainly used in certain cross contract scenarios |
|              entry\_address              |     Address    | Fetch the entry address                                                                               |
|            current\_blockhash            |      H256      | Fetch current block's hash                                                                            |
|              current\_txhash             |      H256      | Fetch current transaction's hash                                                                      |
|      sha256(data: impl AsRef<\[u8]>)     |      H256      | Calculate the SHA256 encryption of the input parameter                                                |
|      check\_witness(addr: \&Address)     |      bool      | Check whether the specified address's signature exists                                                |
|                   input                  |       Vec      | Fetch the parameters passed when the contract was invoked                                             |
|             ret(data: &\[u8])            |        !       | Returns the result of contract execution                                                              |
|           notify(data: &\[u8])           |        !       | Save the contract's `notify` content on the blockchain                                                |
|             panic(msg: \&str)            |        !       | Contract's `panic` message                                                                            |
| storage\_write(key: &\[u8], val: &\[u8]) |                | Transmits data to the blockchain                                                                      |
|        storage\_read(key: &\[u8])        |  Option\<Vec>  | Fetch on-chain data                                                                                   |
|       storage\_delete(key: &\[u8])       |                | Deleting on-chain data                                                                                |

Next, we will describe the available API methods in detail. Developers are advised to first clone our smart contract template from **Github** and then add the contract logic in `lib.rs` file.

### API Method Usage Specifications

Developers can use the following command to import the `runtime` module into the contract.

```rust
use ontio_std::runtime;
```

All the API methods can be called using the runtime module. The available methods are:

### timestamp()

The `timestamp()` method can be used to fetch the current timestamp. The value returns the UNIX timestamp in seconds. Example:

```rust
let t = runtime::timestamp();
```

### block\_height()

The `block_height` method can be used to fetch the current height of the blockchain. Example:

```rust
let t = runtime::block_height();
```

### address()

The `address()` method can be used to fetch a contract's address. Example:

```rust
let t = runtime::address();
```

### caller()

The `caller()` method can be used to fetch the address of the party calling the contract. This finds application in cross-contract scenarios, for example if a contract A calls another contract B, contract B can use this method to find out the address of contract A. Example:

```rust
let t = runtime::caller();
```

### entry\_address()

The `entry_address()` can be used to fetch the entry address of a contract. A sample application could be where a contract A calls a contract C through contract B, and the contract C uses this method to fetch the address of contract A. Example:

```rust
let t = runtime::entry_address();
```

### current\_blockhash()

The `current_blockhash()` method can be used to fetch the hash of the current block. Example:

```rust
let t = runtime::current_blockhash();
```

### current\_txhash()

The `current_txhash()` method can be used to fetch the hash of the current transaction. Example:

```rust
let t = runtime::current_txhash();
```

### sha256()

This `sha256()` method can be used to fetch the **SHA256** encryption of the input parameter. Example:

```rust
let h = runtime::sha256("test");
```

### check\_witness()

The `check_witness(from)` verifies whether the signature of the passed address exists.

* The method checks whether the party invoking the method contains the signature of `from`. If true (and signature verification is successful), the method returns `true`.
* The method checks whether the invoking party is a contract. If it is, and the method is invoked from this contract, it returns `true`. It also checks if the `from` is the returned value from `caller()`. Here, the `caller()` method returns the contract hash of the contract that invokes the method.

```rust
assert!(runtime::check_witness(from));
```

### notify()

The `notify` method can be used to pass contract event information to the network along with transmitting it to the blockchain. Example:

```rust
runtime::notify("notify".as_bytes())
```

An event function can be defined when sending a message from the contract using the `#[event]` annotation. The toolkit provided includes the necessary macros which can be imported using `use ostd::macros::event;`. Example:

```rust
use ostd::macros::event;
mod notify {
    use super::*;
    #[event]
    pub fn transfer(from: &Address, to: &Address, amount: U128) {}
}
fn transfer(from: &Address, to: &Address, amount: U128) -> bool {
    ...
    notify::transfer(from, to, amount);
}
```

### panic()

The `panic` method stops a transaction when a critical error occurs and then rolls back the current transaction. This method can prove to be very useful in a cross-contract scenario.

For example, before **contract A's** method calls **contract B's** method, it transmits and stores certain data to the blockchain, but before **contract B's** method can be executed a critical error occurs. At this point, the action performed by **contract A** and the data stored on the chain need to be rolled back. This is carried out by using the `panic` function in **contract B's** method. Example:

```rust
runtime::panic("test");
```

### storage\_write()

This method is used to transmit and store data on the blockchain in the form of key-value pairs. The key and value are both of the **bytearray** data type. Example:

```bash
runtime::storage_write("key".as_bytes(), "value".as_bytes())
```

### storage\_read()

The method is used to fetch data from the blockchain using the key. The response is also of the **bytearray** data type . Example:

```bash
runtime::storage_read("key".as_bytes())
```

### &#x20;storage\_delete()

This method is used to delete the on-chain data using the key. Example:

```bash
runtime::storage_delete("key".as_bytes())
```


# Contract Fundamentals

Data Serialization and Deserialization of Data in Ontology WASM Contract

Some common aspects of smart contract development process are:&#x20;

1. Parameter processing upon contract invocation&#x20;
2. Storing the user-defined data structures on the blockchain
3. Fetching and reading the on-chain data and processing and resolving them to original data types
4. Transferring the parameters to the target contract when carrying out cross-contract invocation

Most of these aspects involve serialization and deserialization of data. Here we talk about data serialization and deserialization in Ontology **WASM** contracts.

{% hint style="success" %}
A template contract has been made available [**here**](https://github.com/ontio/rust-wasm-contract-template) on Github for the developers to make **WASM** contract development in Rust convenient. The template provides a script to compile the contract and a basic structure to start working with.&#x20;
{% endhint %}

### Encoder and Decoder Interfaces

The Encoder and Decoder interfaces define serialization and deserialization methods respectively for different data types. For the specific implementation logic, please refer to the `sink.rs` file. The `ontology-wasm-cdt-rust` library supports most commonly used data types, for e.g. **\&str**, **u8**, **u16**, **u32**, **u64**, **u128**, **bool**, **H256**, **Address**, **Vec**, **String**, and **tuple**. Sample code for serialization and deserialization of different data types:

```rust
let mut sink = Sink::new(16);
sink.write(1u128);
sink.write(true);
let addr = Address::repeat_byte(1);
sink.write(addr);
sink.write("test");
let vec_data = vec!["hello","world"];
sink.write(&vec_data);
let tuple_data = (1u8, "hello");
sink.write(tuple_data);
let mut source = Source::new(sink.bytes());
let res1:u128 = source.read().unwrap_or_default();
let res2:bool = source.read().unwrap_or_default();
let res3:Address = source.read().unwrap_or_default();
let res4:&str = source.read().unwrap_or_default();
let res5:Vec<&str> = source.read().unwrap_or_default();
let res6:(u8, &str) = source.read().unwrap_or_default();
assert_eq!(res1, 1u128);
assert_eq!(res2, true);
assert_eq!(res3, addr);
assert_eq!(res4, "test");
assert_eq!(res5, vec_data);
assert_eq!(res6, tuple_data);
```

All the parameters passed to the `sink.write()` method support all the data types that implement the Encoder interface. Their data types need to be declared when serializing, for example `1u128`. The `source.read()` method can fetch and read all the data types that implement the Decoder interface. The target data type needs to be specified when deserializing as follows:

```rust
let res1:u8 = source.read().unwrap_or_default();
```

The data type needs to be specified after `res1`. Here, the data type is `u8`.

```rust
let res1 = source.read_byte().unwrap_or_default();
```

Since reading is carried out using the the `read_byte` method it is not necessary to specify the data type.

### Processing Contract Invocation Parameters

The contract fetches the invocation parameters using the `runtime::input()` method. But, this method can only fetch parameters of the `bytearray` type. This parameter can be deserialized to the corresponding method name and method parameters. Sample code for serialization and deserialization:

```rust
let input = runtime::input();
let mut source = Source::new(&input);
let method_name: &str = source.read().unwrap();
let mut sink = Sink::new();
match method_name {
    "transfer" => {
        let (from, to, amount) = source.read().unwrap();
        sink.write(ont::transfer(from, to, amount));
    }
    _ => panic!("unsupported action!"),
}
```

Rust supports type derivation. For most cases, type declaration is not necessary. For example, `ont::transfer()` method declares the data type for `from`, `to`, and `amount` variables, and so data type declaration is not required for these variables.

Deserialization for the `Vec<&str>` data type can be carried out in the following way:

```rust
let param:Vec<&str> = source.read().unwrap();
```

Deserialization for the `Vec<(&str, U128, Address)>` data type can be carried out in the following way:

### ONT and ONG Transfers

The WASM contract development tools already encapsulate methods that can used to invoke **ONT** and **ONG** native contracts. The `contract` module contains these methods, and can be invoked in the following fashion:

```rust
#![no_std]
use ostd::contract::ont;
fn ont_transfer(&self, from: &Address, to: &Address, amount: U128) -> bool {
    ont::transfer(&from, &to, amount)
}
fn ong_transfer(&self, from: &Address, to: &Address, amount: U128) -> bool {
    ong::transfer(&from, &to, amount)
}
#[no_mangle]
pub fn invoke() {
    let input = runtime::input();
    let mut source = Source::new(&input);
    let action = source.read().unwrap();
    let mut sink = Sink::new(12);
    match action {
        "ont_transfer" => {
            let (from, to, amount) = source.read().unwrap();
            sink.write(ont_transfer(from, to, amount));
          },
          "ong_transfer" => {
              let (from, to, amount) = source.read().unwrap();
              sink.write(ong_transfer(from, to, amount));
            },
        _ => panic!("unsupported action!"),
    }

    runtime::ret(sink.bytes())
}
```

```rust
let param:Vec<(&str,U128,Address)>= source.read().unwrap();
```

### Serializing the User-defined Data Structures

While developing smart contracts we often need to serialize and deserialize data of type `struct`. To achieve this function, `#[derive(Encoder, Decoder)]` can be conveniently added above the struct declaration statement. Refer to the code:

```rust
#[derive(Encoder, Decoder)]
struct ReceiveRecord {
    account: Address,
    amount: u64,
}

#[derive(Encoder, Decoder)]
struct EnvlopeStruct {
    token_addr: Address,
    total_amount: u64,
    total_package_count: u64,
    remain_amount: u64,
    remain_package_count: u64,
    records: Vec<ReceiveRecord>,
}
```

{% hint style="info" %}
When using this feature to carry out serialization and deserialization, it is important to ensure that all the fields of `struct` implement the `Encoder` and `Decoder` interface.
{% endhint %}

```rust
let addr = Address::repeat_byte(1);
let rr = ReceiveRecord{
    account: addr,
    amount: 1u64,
};
let es = EnvlopeStruct{
    token_addr: addr,
    total_amount: 1u64,
    total_package_count: 1u64,
    remain_amount: 1u64,
    remain_package_count: 1u64,
    records: vec![rr],
};
let mut sink = Sink::new(16);
sink.write(&es);

let mut source = Source::new(sink.bytes());
let es2:EnvlopeStruct = source.read().unwrap();

assert_eq!(&es.token_addr,&es2.token_addr);
assert_eq!(&es.total_amount,&es2.total_amount);
assert_eq!(&es.total_package_count,&es2.total_package_count);
assert_eq!(&es.remain_amount,&es2.remain_amount);
assert_eq!(&es.remain_package_count,&es2.remain_package_count);
```

### Fetching On-chain Data of Specific Data Types

The different types of data that are handled in a contract can be stored on the blockchain. But these different data types first need to be converted to `bytearray` type using serialization. Similarly, the data that is fetched from the blockchain is in the `bytearray` form and needs to be deserialized to obtain results in specific data types. The `database` module provides several simple API methods that are available for the developer to use.

```rust
put<K: AsRef<[u8]>, T: Encoder>(key: K, val: T)
```

The `T` data type is saved based on the `key`, and the type `T` is to implement the **Encoder** interface.

#### Sample code

```rust
let es = EnvlopeStruct{
    token_addr: addr,
    total_amount: 1u64,
    total_package_count: 1u64,
    remain_amount: 1u64,
    remain_package_count: 1u64,
    records: vec![rr],
};
database::put("key", es);
```

From the above example it is clear that when using the `database::put` method, first we serialize the `es` parameter, and then save the result on the blockchain.

```rust
fn get<K: AsRef<[u8]>, T>(key: K) -> Option<T> where for<'a> T: Decoder<'a> + 'static,
```

Here we fetch data of type `T` using the `key`. The `T` data type requires implementation of the Decoder interface.

#### Example

```rust
let res:EnvelopeStruct = database::get("key").unwrap();
```

From the example above we can see that the `database::get` method fetches data of the type `bytearray` from the chain, and then needs to be deserialized to obtain the result in the `EnvelopeStruct` format.

### Cross Contract Parameter Transfer

In the case of cross contract invocation, the parameters are transferred in the `bytearray` format. Thus, it is necessary to serialize different data types to `bytearray` format. An example for a cross contract invocation in the case of a WASM contract:

```rust
let (contract_address,method,a, b): (&Address,&str,u128, u128) = source.read().unwrap();
let mut sink = Sink::new(16);
sink.write(method);
sink.write(a);
sink.write(b);
let resv = runtime::call_contract(contract_address, sink.bytes()).expect("get no return");
```


# Inter-contract Interaction

Ontology WASM, NeoVM, and native smart contract interaction

Ontology mainnet currently supports three kinds of smart contracts-&#x20;

**Native contract**: The contract native to Ontology system, implemented in **Golang** and deployed in the Genesis block. Native contracts offer quick execution times.&#x20;

**NeoVM contract**: A NeoVM contract is run on the NeoVM engine. Certain characteristics of NeoVM smart contract are small contract file size, simple bytecode, and high performance.&#x20;

**WASM contract**: WASM contracts support multiple high level languages that can be compiled to bytecode. WASM contracts provide rich functionality, natively support several third-party database. The WASM development community is also very active.

But how do WASM contracts invoke native and NeoVM contracts? Here we illustrate how the mechanism is implemented.

Developers can clone the contract template, edit the `lib.rs` file, and start testing.

### Cross Contract API Call Using the Runtime Module

A general API has been encapsulated in the `ontology-wasm-cdt-rust` library, which can be used as follows:

```rust
pub fn call_contract(addr: &Address, input: &[u8]) -> Option<Vec<u8>>
```

This method takes two parameters. The `addr` parameter indicates the target contract address, and the `input` parameter is the name of the method to be invoked from the target contract and it's parameters. The name and parameters of the function should be correctly serialized. There are a few differences between the serialization process for NeoVM and native contract method and parameters. The details regarding serialization will be specified below.

### WASM Contract Invokes a Native Contract

The `ontology-wasm-cdt-rust` library includes API that can be used to invoke the `ONT` and `ONG` contracts. The `use ostd::contract::ont;` declaration can be used to import it and use it conveniently. An example of implementing an `ONT` transfer can be referred to below:

```rust
use ostd::contract::ont;
...
let (from, to, amount) = source.read().unwrap();
sink.write(ont::transfer(from, to, amount));
```

The source code for `ont::transfer` method is as follows:

```rust
pub fn transfer(from: &Address, to: &Address, val: U128) -> bool {
    let state = [TransferParam { from: *from, to: *to, amount: val }];
    super::util::transfer_inner(&ONT_CONTRACT_ADDRESS, state.as_ref())
}
```

The code above clearly illustrates that first an instance of `TransferParam` type is created, and then an array is defined. This is done to support multi account transfer. Next, the `ONT` contract address and the array created are passed to `util::transfer_inner` method. The definition for the `util::transfer_inner` method is as follows:

```rust
pub(crate) fn transfer_inner(
    contract_address: &Address, transfer: &[super::TransferParam],
) -> bool {
    let mut sink = Sink::new(64);
    sink.write_native_varuint(transfer.len() as u64);

    for state in transfer.iter() {
        sink.write_native_address(&state.from);
        sink.write_native_address(&state.to);
        sink.write(u128_to_neo_bytes(state.amount));
    }
    let mut sink_param = Sink::new(64);
    sink_param.write(VERSION);
    sink_param.write("transfer");
    sink_param.write(sink.bytes());
    let res = runtime::call_contract(contract_address, sink_param.bytes());
    if let Some(data) = res {
        if !data.is_empty() {
            return true;
        }
    }
    false
}
```

The sample code above clearly illustrates that the tool used to serialize the parameters is a `Sink` instance. Since the parameter to be serialized is an array, the array length is serialized, and the type is converted to `U64` array before invoking the `sink.write_native_varuint` method to carry out serialization. Each element of the array is serialized after the array length serialized. The address is serialized using the `sink.write_native_address`. The data of `U128` type is first converted to `bytearray` and then serialized. This conversion can be carried out using the `u128_to_neo_bytes` method.&#x20;

At this point, the parameters have been serialized. To serialize the method name we first need to create a serialization instance that will be used to serialize the method name. Before the method name is serialized, the `version` is serialized first. This field is set to `0` by default. Next the method name is serialized and parameters are serialized again. Here, the conditions to invoke a native contract have been fulfilled and the `runtime` APIs method can be used to invoke the contract.

### WASM Contract Invokes a NeoVM Contract

When a NeoVM contract is invoked by a WASM contract, the `VmValueEncoder` and the `VmValueDecoder` API can be implemented to transfer the parameters. The `ontology-wasm-cdt-rust` library supports most commonly used data types, for e.g. `&str`, `&[u8]`, `bool`, `H256`, `U128`, `Address`. The `contract` module encasuplates the `neo` module and allows developers to use it's corresponding methods to invoke NeoVM contract. Refer to the sample code below:

```rust
use ostd::contract::neo;
...
let res = neo::call_contract(&NEO_CONTRACT_ADDR, ("init", ()));
match res {
    Some(res2) => {
        let mut parser = VmValueParser::new(res2.as_slice());
        let r = parser.bool();
        sink.write(r.unwrap_or(false));
    }
    _ => sink.write(false),
}
```

The `neo::call_contract` method takes two parameters. The first parameter is the target contract's address, and the second parameter is the name and parameters of the method to be called from the target contract. In the sample code above the method name is `init`, and the parameter passed is an empty tuple. The return value from the method needs to be serialized using the `VmValueParser` to obtain the final result.

The `neo::call_contract` method is defined as follows:

```rust
pub fn call_contract<T: crate::abi::VmValueEncoder>(
        contract_address: &Address, param: T,
) -> Option<Vec<u8>> {
    let mut builder = crate::abi::VmValueBuilder::new();
    param.serialize(&mut builder);
    crate::runtime::call_contract(contract_address, &builder.bytes())
}
```

The code above shows that the `neo::call_contract` takes two parameters. The first parameter is the target contract address and the second parameter is the method name and and the required parameters. The method name and the parameters must implement the `VmValueEncoder` API.

{% hint style="info" %}
The `VmValueBuilder` method should be used to serialize method name and the parameters instead of using `Sink`.
{% endhint %}

The macro function is a powerful feature of the Rust programming language. Macros are used to implement `VmValueEncoder` and `VmValueDecoder` for tuple type data. Tuple data `("inti",())` is imported when invoking the method.


# Developing Contracts in C++

C++ WASM Contract Development in C++

Much similar to EOS, developers can use **C++** to develop smart contracts on the Ontology platform. Let us take a look at a sample **Hello World** app.

#### Sample Code

```cpp
#include<ontiolib/ontio.hpp>
#include<stdio.h>

using namespace ontio;
class hello:public contract {
    public:
    using contract::contract:
    void sayHello(){
        printf("hello world!");
    }
};
ONTIO_DISPATCH(hello, (sayHello));
```

#### Smart Contract Entry Point

The [**Ontology WASM CDT Compiler**](https://github.com/ontio/ontology-wasm-cdt-cpp) encapsulates the required features for entry point and parameter processing. Thus, developers do not need to define entry point methods.

The entry point method can be called in the following manner:

```cpp
ONTIO_DISPATCH(hello, (sayHello));
```

The next important part of the contract would be the external interface. This interface would make the contract's services available to external parties. In the sample code above we use the `sayHello()` method to demonstrate the same.

```cpp
 printf("hello world!");
```

This "Hello World" will be printed out in the node log records at the respective "debug level". Practically speaking, the `printf()` method can only be used for debugging. A more realistic smart contract would need to implement many more complex features.

#### Smart Contract API

Ontology WASM provides an API that contains the following methods that allow communication with the blockchain system.

|         API        |                     Parameter                    | Return Value | Description                                                                   |
| :----------------: | :----------------------------------------------: | :----------: | ----------------------------------------------------------------------------- |
|      timestamp     |                       None                       |    uint64    | Current UNIX timestamp                                                        |
|    block\_height   |                       None                       |    uint32    | Current block height                                                          |
|    self\_address   |                       None                       |    address   | Contract address                                                              |
|   caller\_address  |                       None                       |    address   | Invocation address (Same as `self_address` if invocation is not external)     |
|   entry\_address   |                       None                       |    address   | Entry contract address (Same as `self_address` if invocation is not external) |
|   check\_witness   |                      address                     |     bool     | Check the signature of the incoming address                                   |
| current\_blockhash |                       None                       |     H256     | Current block hash                                                            |
|   current\_txhash  |                       None                       |     H256     | Current transaction hash                                                      |
|       notify       |                      string                      |     void     | Send even notification                                                        |
|    call\_native    |              address, params, result             |     void     | Invoke native contract                                                        |
|   call\_contract   |              address, params, result             |     void     | Invoke ordinary contract (WASM/NeoVM)                                         |
|    storage\_get    |                    key, result                   |     void     | Fetch stored data                                                             |
|    storage\_put    |                    key, value                    |     void     | Write data on the chain                                                       |
|   storage\_delete  |                        key                       |     void     | Delete stored data                                                            |
|  contract\_create  | code, vmtype, name, version, author, email, desc |    address   | Create new contract                                                           |
|  contract\_migrate | code, vmtype, name, version, author, email, desc |    address   | Migrate (upgrade) contract                                                    |
|  contract\_delete  |                      address                     |     void     | Delete contract                                                               |

Let us develop a slightly more complicated WASM contract to demonstrate how to use the API.

## Red Envelope Smart Contract

Giving and receiving red envelopes is a part of China's tradition on important festivals and occasions. Red envelopes can now be sent and received using many different tools including social networking and IM platforms such as WeChat. The amount collected can also be deposited to bank accounts.

Let us try an create a smart contract that works the way WeChat's red envelope mechanism works. **ONT**, **ONG**, and other OEP-4 standard cryptocurrencies and tokenized assets can be transferred in the form of red envelopes. The amount received is transferred to the receiver's wallet account.

### **1. Creating a New Contract**

```cpp
#include<ontiolib/ontio.hpp>

using namespace ontio;

class redEnvlope: public contract{

}
ONTIO_DISPATCH(redEnvlope, (createRedEnvlope)(queryEnvlope)(claimEnvlope));
```

First, we need to create a new contract file and rename it to `redEnvelope.cpp`.

In this contract we will be implementing three API methods.

`createRedEnvlope` : To create a new red envelope

`queryEnvlope` : Query existing red envelope details

`claimEnvlope` : To claim a red envelope

```cpp
    std::string rePrefix = "RE_PREFIX_";
    std::string sentPrefix = "SENT_COUNT_";
    std::string claimPrefix = "CLAIM_PREFIX_";
```

We need to store certain important data. Data is store in the form of key-value pairs withing the scope of the contract. The **key** to these data need to set the prefix to make querying more convenient.

```cpp
    address ONTAddress = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
    address ONGAddress = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2};
```

Since our contract supports the two native assets **ONT** and **ONG**, we can define the contract addresses of these these two assets.

{% hint style="info" %}
**Note:** Unlike a standard smart contact where the contract address is calculated based on contract hash, the address of the native contract is fixed.
{% endhint %}

```cpp
    struct receiveRecord{
        address account;   // user address
        asset amount;      // claimed amount  
        ONTLIB_SERIALIZE(receiveRecord,(account)(amount))
    };

    struct envlopeStruct{
        address tokenAddress;   // asset token address
        asset totalAmount;      // red envelope total amount
        asset totalPackageCount; // total no. of red envelopes
        asset remainAmount;      // remaining amount
        asset remainPackageCount; // remaining 
        std::vector<struct receiveRecord> records;  // claim records
        ONTLIB_SERIALIZE( envlopeStruct,  (tokenAddress)(totalAmount)(totalPackageCount)(remainAmount)(remainPackageCount)(records) )
    };
```

We need to store the red envelope information in the contract, such as asset related information (token contract address, red envelope total amount, no. of red envelopes, etc.)

```
ONTLIB_SERIALIZE(receiveRecord,(account)(amount))
```

The macros defined in **CDT** can be used to serialize the `struct` type data before storage.

The preparation is almost complete, and at this point we can start coding the specific API logic.

### **2. Creating a Red Envelope**

```cpp
bool createRedEnvlope(address owner,asset packcount, asset amount,address tokenAddr ){

        return true;
    }
```

A new red envelope is created by defining the creator's address, no. of red envelopes, red envelope amount, and the asset token address.&#x20;

```cpp
ontio_assert(check_witness(owner),"checkwitness failed");
```

Verify whether the creator has signed the action, and rollback the transaction if not.

{% hint style="warning" %}
With respect to `ontio_assert(expr, errormsg)` , when `expr` is `false`, an exception is thrown and the process is quit.
{% endhint %}

```cpp
        if (isONTToken(tokenAddr)){
            ontio_assert(amount >= packcount,"ONT amount should greater than packcount");
        }
```

If the red envelope asset is ONT, the amount of ONT must be equal to or greater than the no. of red envelopes, since the asset is indivisible (cannot be smaller than 1). So this condition ensures that each red envelope contains at least 1 ONT.

```cpp
        key sentkey = make_key(sentPrefix,owner.tohexstring());
        asset sentcount = 0;
        storage_get(sentkey,sentcount);
        sentcount += 1;
        storage_put(sentkey,sentcount);
```

For every red envelope creator, we need to maintain the record of the total number of red envelopes created and sent by them.

```cpp
        H256 hash ;

        hash256(make_key(owner,sentcount),hash) ;

        key rekey = make_key(rePrefix,hash256ToHexstring(hash));
```

A red envelope hash is generated for each red envelope. This hash value serves as a unique identifier.

```cpp
         address selfaddr = self_address();
        if (isONTToken(tokenAddr)){

            bool result = ont::transfer(owner,selfaddr ,amount);
            ontio_assert(result,"transfer native token failed!");

        }else if (isONGToken(tokenAddr)){

            bool result = ong::transfer(owner,selfaddr ,amount);
            ontio_assert(result,"transfer native token failed!");
        }else{
            std::vector<char> params = pack(std::string("transfer"),owner,selfaddr,amount);
            bool res; 
            call_contract(tokenAddr,params, res );

            ontio_assert(res,"transfer oep4 token failed!");
        }
```

A tokenized asset it imported to the contract based on its type. The `self_address()` method can be used to fetch the address of the invocation. The amount of token imported to the contract is based on the token type input by the user.

{% hint style="info" %}
**Note:** The transfer operation for the two native assets ONT and ONG is carried out using the `ont::transfer` API method provided in the CDT. Other **OEP-4** based tokens need to be transferred using the standard cross-contract invocation methods.
{% endhint %}

{% hint style="info" %}
**Note:** A smart contract address can receive assets of any type, just as a wallet address can. However, the contract address is generated based on the binary code hash of the contract code, and so the assets stored in the contract address cannot be manipulated without the corresponding private key. Hence, If asset related operations are not set within the contract, there is no way to control the assets stored in it.
{% endhint %}

```cpp
        struct envlopeStruct es ;
        es.tokenAddress = tokenAddr;
        es.totalAmount = amount;
        es.totalPackageCount = packcount;
        es.remainAmount = amount;
        es.remainPackageCount = packcount;
        es.records = {};
        storage_put(rekey, es);
```

The contract information is saved.

```cpp
        char buffer [100];
        sprintf(buffer, "{\"states\":[\"%s\", \"%s\", \"%s\"]}","createEnvlope",owner.tohexstring().c_str(),hash256ToHexstring(hash).c_str());

        notify(buffer);
        return true;
```

Next, the red envelope creation event is sent to the chain since this is an asynchronous event with respect to contract invocation. Upon successful execution, the contract notifies the client regarding the event. The specific format of this notification can be defined by the developer.

With this a simple red envelope is created. The next step is to implement the method that can query the red envelope information.

### **3. Querying Red Envelope Information**

```cpp
   std::string queryEnvlope(std::string hash){
        key rekey = make_key(rePrefix,hash);
        struct envlopeStruct es;
        storage_get(rekey,es);
        return formatEnvlope(es);
    }
```

The query logic for the red envelope is simple. The stored red envelope data needs to be fetched, re-formatted, and returned.

And finally, the users can claim the red envelope based on the red envelope hash (an ID).

{% hint style="info" %}
**Note:** For read-only operations of the smart contract, such as information query, the results can be fetched using pre-execution. Unlike the normal execution process, pre-execution does not require wallet authentication and does not consume **ONG**.
{% endhint %}

### **4. Claiming Red Envelope**

We have successfully imported the assets to the smart contract. At this point, the ID can be shared with other users and they can start claiming the red envelope.

```cpp
  bool claimEnvlope(address account, std::string hash){
      return true;
  }
```

Claiming a red envelope requires the claiming party's account address and the red envelope's **hash**.

```cpp
ontio_assert(check_witness(account),"checkwitness failed");
key claimkey = make_key(claimPrefix,hash,account);
asset claimed = 0 ;
storage_get(claimkey,claimed);
ontio_assert(claimed == 0,"you have claimed this envlope!");
```

Similarly, the claiming party's signature needs to be verified to ensure that a person may only claim a red envelope themselves, and not by proxy. Also, each user is allowed to claim a red envelope only once.

```cpp
        key rekey = make_key(rePrefix,hash);
        struct envlopeStruct es;
        storage_get(rekey,es);
        ontio_assert(es.remainAmount > 0, "the envlope has been claimed over!");
        ontio_assert(es.remainPackageCount > 0, "the envlope has been claimed over!");
```

Using the red envelope hash it's data can be fetched and can be determine whether a red envelope has been fully claimed.&#x20;

```cpp
        struct receiveRecord record ;
        record.account = account;
        asset claimAmount = 0;
```

The claim is added to the claim records.

```cpp
        if (es.remainPackageCount == 1){
            claimAmount = es.remainAmount;
            record.amount = claimAmount;
        }else{
            H256 random = current_blockhash() ;
            char part[8];
            memcpy(part,&random,8);
            uint64_t random_num = *(uint64_t*)part;
            uint32_t percent = random_num % 100 + 1;

            claimAmount = es.remainAmount * percent / 100;
            //ont case
            if (claimAmount == 0){
                claimAmount = 1;
            }else if(isONTToken(es.tokenAddress)){
                if ( (es.remainAmount - claimAmount) < (es.remainPackageCount - 1)){
                    claimAmount = es.remainAmount - es.remainPackageCount + 1;
                }
            }

            record.amount = claimAmount;
        }
        es.remainAmount -= claimAmount;
        es.remainPackageCount -= 1;
        es.records.push_back(record);
```

This part of the program logic is a little lengthy. Here, the logic is to calculate the amount of asset claimed from the red envelope. If it is the last red packet, then the amount left is the amount in the last red packet. Otherwise, the remaining asset amount is calculated using a random number generated using the current block hash. This remaining asset amount is then updated in the red envelope information.

```cpp
        address selfaddr = self_address();
        if (isONTToken(es.tokenAddress)){
            bool result = ont::transfer(selfaddr,account ,claimAmount);
            ontio_assert(result,"transfer ont token failed!");
        } else  if (isONGToken(es.tokenAddress)){
            bool result = ong::transfer(selfaddr,account ,claimAmount);
            ontio_assert(result,"transfer ong token failed!");
        } else{
            std::vector<char> params = pack(std::string("transfer"),selfaddr,account,claimAmount);

            bool res = false; 
            call_contract(es.tokenAddress,params, res );
            ontio_assert(res,"transfer oep4 token failed!");
        }
```

Based on the claimed asset, the calculated amount of the corresponding asset is transferred to the claim account address from the contract.

```cpp
        storage_put(claimkey,claimAmount);
        storage_put(rekey,es);
        char buffer [100];        
        std::sprintf(buffer, "{\"states\":[\"%s\",\"%s\",\"%s\",\"%lld\"]}","claimEnvlope",hash.c_str(),account.tohexstring().c_str(),claimAmount);

        notify(buffer);
        return true;
```

The claim records are stored and the updated red envelope information is stored along with the notification of the event being sent out.

As stated above, the `claimEnvlope()` method is the only way to move an asset out of this contract. Hence, we establish that the assets stored in the contract are safe.

The simple logic for the red envelope system is complete. The entire smart contract sample code is available [**here**](https://github.com/JasonZhouPW/pubdocs/blob/master/redEnvlope.cpp) for reference.

## Testing a Smart Contract

### Using the CLI

Please refer to： <https://github.com/ontio/ontology-wasm-cdt-cpp/blob/master/How_To_Run_ontologywasm_node.md>

### Using the Golang SDK

Please refer to: <https://github.com/ontio/ontology-wasm-cdt-cpp/blob/master/example/other/main.go>

This example serves to demonstrate how a complete Ontology WASM contract uses API methods to interact with the blockchain. If a complete product is to be developed using this technology, there would be several other considerations such as privacy related concerns for the red envelope. Anyone can monitor a red envelope events to get the hash, and then claim it. This issue can be solved by fixing the addresses, and thereby the users who can claim a red packet. Interested developers can make the necessary changes to the code and test it out.


# Publish Contract Source Code

Publish your contract details on Ontology Explorer

Once your contract is deployed, people can search for your contract in the Ontology[ Explorer](https://explorer.ont.io/home) and view related on-chain data on a dedicated page.&#x20;

You can publish the source code along with more details about your contract on this page to unveil how things work under the hood. Contracts with extra details are listed on the **"**[**View Contracts**](https://explorer.ont.io/contracts/10/1#)**"** page to encourage community members to use and improve these contracts.

To publish more details, click on **"Contracts"** - **"**[**Submit Contract**](https://explorer.ont.io/contracts/submit)**"** in the Explorer and specify below details:&#x20;

### **Virtual Machine**

Select the virtual machine (EVM, NeoVM or WASM) that executes your contract.&#x20;

You are supposed to provide all the following information if you submit an **EVM** contract, and less is required for the other two types.&#x20;

### **Contract Address**

Fill in your contract address.

### **Contract Description (**&#x6F;ptional)

Introduce your contract with one sentence.&#x20;

### **Compiler Type & Compiler Version**

Choose the compiler information from the menu. Currently Solidity (single file) and Solidity (multi-part files) supported.&#x20;

### **Optimization**

Select the option used when compiling the contract.&#x20;

### **Constructor Arguments ABI-encoded (Hex String, Optional)**&#x20;

Fill in this field if your contract is created with constructor parameters. You need to provide constructor arguments in ABI hex encoded form so we can compare if what you provided is consistent with the existing bytecodes.&#x20;

The constructor arguments are appended to the end of the contract source bytecode when the contract is compiled by Solidity. You can find them by comparing the compiled code and the input creation bytecode.

You can also figure out the constructor arguments by using this [online tool](https://abi.hashex.org/)**.**

**Step 1**: Fill in parameters and deploy your contract.

![](https://lh3.googleusercontent.com/lD-FiM5eIKI_LJgijkikb9GxtNZVwt9V_c6dTTCB55KZ5f0R67aIF1e9y5AOzCD4IQk64LI2scDO8f1lSaMQwdBlIa29qPxgET3UwLLWflyMLtEQNqAGY-psgUOMHEqEb9f4DWEhYlqvprkvgQ)

**Step 2**: Fill in the parameters in the [online tool](https://abi.hashex.org/), you will get a hex string that represents the contractor arguments.

![](https://lh3.googleusercontent.com/vJvnqHe-0GH29hr3OmzDdhMa1plf9TWT5KONvDa3q1DrWKvxdExqx9BQ2drU6Tncz_dUBBqy_mP_h6PjPJYvIBlHOtRLS1UxQ8dLIRpmw7_8p1RKsu1F1-PJXPad1ZUnoIaHoMmSlWXjmNLVkA)

### **Contract Library Address (Optional, up to 10)**

Enter names and contract addresses of the libraries used.

### **Runs (Optimizer)**

Fill in this field if you choose "Yes" for "Optimization". The value represents how many times the code is likely to be run, and it will be optimized accordingly. Leave the value as "200" if you are unsure.

### **EVM Version**

Select which version of EVM to compile your code for.

### **License Type Settings**

Select a license type for your source code:

1. [No License (None)](https://github.com/github/choosealicense.com/blob/a40ef42140d137770161addf4fefc715709d8ccd/no-permission.md)
2. [The Unlicense (Unlicense)](https://unlicense.org/)
3. [MIT License (MIT)](https://github.com/github/choosealicense.com/blob/gh-pages/_licenses/mit.txt)
4. [GNU General Public License v2.0 (GNU GPLv2)](https://github.com/github/choosealicense.com/blob/gh-pages/_licenses/gpl-2.0.txt)
5. [GNU General Public License v3.0 (GNU GPLv3)](https://github.com/github/choosealicense.com/blob/gh-pages/_licenses/gpl-3.0.txt)
6. [GNU Lesser General Public License v2.1 (GNU LGPLv2.1)](https://github.com/github/choosealicense.com/blob/gh-pages/_licenses/lgpl-2.1.txt)
7. [GNU Lesser General Public License v3.0 (GNU LGPLv3)](https://github.com/github/choosealicense.com/blob/gh-pages/_licenses/lgpl-3.0.txt)
8. [BSD 2-clause "Simplified" license (BSD-2-Clause)](https://github.com/github/choosealicense.com/blob/gh-pages/_licenses/bsd-2-clause.txt)
9. [BSD 3-clause "New" Or "Revised" license\* (BSD-3-Clause)](https://github.com/github/choosealicense.com/blob/gh-pages/_licenses/bsd-3-clause.txt)
10. [Mozilla Public License 2.0 (MPL-2.0)](https://github.com/github/choosealicense.com/blob/gh-pages/_licenses/mpl-2.0.txt)
11. [Open Software License 3.0 (OSL-3.0)](https://github.com/github/choosealicense.com/blob/gh-pages/_licenses/osl-3.0.txt)
12. [Apache 2.0 (Apache-2.0)](https://github.com/github/choosealicense.com/blob/gh-pages/_licenses/apache-2.0.txt)
13. [GNU Affero General Public License (GNU AGPLv3)](https://github.com/github/choosealicense.com/blob/gh-pages/_licenses/agpl-3.0.txt)
14. [Business Source License (BSL 1.1)](https://mariadb.com/bsl-faq-adopting/#whatis)

### **Contract Source Code**

Select and upload Solidity (\*.sol) files of the source code.

### Submit Information

After filled and checked everything, click on the arrow button to submit the content. The Ontology team will review the content and publish it.

![](https://lh4.googleusercontent.com/4WeM7qu9z83uwNn6kX1qYP6wgukpRSP2qP7C2Ttwh3bRfR9LW7ylY8N7PHkIVW3OUvzj_r1N9hyxkqupBYBsDCrC_S4QIlsfmpHZqTCRQ0nRrlq-BJuBEvmReA1creM7EnDTsup8yseKbTwWzw)


# Integration Guides


# dApp Integration

Integrating Ontology into dApps


# dAPI Integration

General integration methods and functionalities

## Primary Functionality

From a developer's point of view, the functions that facilitate interaction with the Ontology blockchain can be broadly categorized as follows:

* **Login:**  Allows user identity verification, and querying account or identity related information
* **Transactions:**  The transaction service for both `ONT` and `ONG`, or the other `OEP` token related transactions can be carried out by deploying smart contracts. An example of an `ONG` based transaction-

```python
OntCversion = '2.0.0'
from ontology.interop.Ontology.Native import Invoke
from ontology.builtins import state
from ontology.interop.System.Runtime import Notify
from ontology.interop.System.ExecutionEngine import GetExecutingScriptHash
from ontology.interop.Ontology.Runtime import Base58ToAddress,AddressToBase58


# ONG Big endian Script Hash: 0x0200000000000000000000000000000000000000
OngContract = Base58ToAddress("AFmseVrdL9f9oyCzZefL9tG6UbvhfRZMHJ")


def Main(operation, args):
    if operation == "transferOng":
        if len(args) != 3:
            return False
        return transferOng(args[0], args[1], args[2])

    return False

def transferOng(from_base58, to_base58,  ong_amount):
    from_acct = Base58ToAddress(from_base58)
    to_acct = Base58ToAddress(to_base58)
    param = state(from_acct, to_acct, ong_amount)
    res = Invoke(0, OngContract, "transfer", [param])
    if res and res == b'\x01':
        Notify([True,from_base58, to_base58,  ong_amount])
        return True
    else:
        Notify([False,from_base58, to_base58,  ong_amount])
        return False
```

* **Smart contract development:**  As far as the vast majority of `dApps` are concerned, logic implementation either relies completely, or at least in part, on smart contracts. Considering games, for instance, functions such as buying, selling, renting, or generating random numbers, etc. can conveniently be implemented using smart contracts. For more details on smart contracts, feel free to check [this](/guides-and-tutorials/integration-guides/dapps/dapi-integration) out.
* **Tokenizing assets:**  Developers always have the option to tokenize and issue many different types of assets, such as `OEP4`, `OEP5`, `OEP8`, etc. For a more detailed explanation of the aforementioned assets, refer to [this](/guides-and-tutorials/integration-guides/dapps/dapi-integration).

## Integration Options

Keeping in mind the different circumstances and scenarios that the developers might be working with, Ontology provides multiple ways to integrate the platform into a `dApp`.

* The multiple decentralized methods that use the `dAPI`, including the option to open a `dApp` from within a mobile wallet, and the `Cyano` wallet chrome plugin, all allow the `dApp` to interact with the blockchain.
* Integrating using one of the multiple `SDKs`,  a method which is also decentralized at its core. For example, games that use the `Unity 3D` engine and `C#`. would encounter the need to integrate through the respective `SDKs`.
* Making the application open-platform using the ONT ID. Though, this method is not completely decentralized.

No matter which one of the above methods you choose to integrate your `dApp`, the login feature and the ability to deploy smart contracts remains constant and unaffected. Therefore, developers can freely choose any of the method to integrate `dApps`.

As discussed above, there are two technically decentralized `dApp` integration methods, both of which offer the same functionality in every way. The choice rests with the developer.

To satisfy that the requirement for `dApps` to be accessible on both the browser and the mobile version, here we provide examples that involve using `dAPI` in three different scenarios. You can refer to:

* **Mobile version** `dAPI` **implementation -** [dAPI for mobile](https://github.com/ontio-cyano/cyano-bridge)
* **Chrome plugin wallet** `dAPI` **implementation -** [dAPI for chrome](https://github.com/ontio/ontology-dapi)
* **Example** `dAPI` **code compatible with both the Chrome plugin and the mobile version -** [dAPI-universal](https://github.com/ontio-cyano/dapi-universal)

## dAPI Compatibility

Unlike traditional apps, a `dApp` doesn't have a centralized back end platform that manages accounts. The user maintains full possession and control of their identity and assets. That is the reason why apart from building the app's logic using smart contracts, `dApps` need to employ various means to interact and communicate with the blockchain.

To bring down the difficulty level of `dApp` development, Ontology provides plenty of `dAPI` methods for developers to use and allow `dApps` to communicate with the blockchain. Ontology's current framework and technology is compatible with, and can run a `dApp` on virtually any mainstream device.

Currently, the following scenarios are supported-

* **dApp invokes the Chrome wallet plugin**
* **dApp launched from within the mobile wallet**
* **The mobile wallet scans QR codes to execute smart contracts**
* **Application wakes the mobile wallet**

Wallets that already support `dAPI` protocol-

* Math wallet
* Banko
* Huobi wallet

The dApps that are currently using dAPI can be found by following the below link-

{% embed url="<https://github.com/ontio-community/dapp-store>" %}

To ensure that the requirement for `dApps` to be accessible on both the browser and the mobile version, here we provide examples that involve using `dAPI` in three different scenarios. You can refer to:

* **Mobile version** `dAPI` **implementation -** [**dAPI for mobile**](https://github.com/ontio-cyano/cyano-bridge)
* **Chrome plugin wallet** `dAPI` **implementation -** [**dAPI for chrome**](https://github.com/ontio/ontology-dapi)
* **Example** `dAPI` **code compatible with both the Chrome plugin and the mobile version -** [**dAPI-universal**](https://github.com/ontio-cyano/dapi-universal)

## Wallet Demonstration

The most common method of launching a `dApp` from within the wallet is illustrated here. The process and a few basic functions are demonstrated below.

{% hint style="info" %}
**H5 demo dApp source code:** <https://github.com/ontio-cyano/mobile-dapp-demo>

**H5 demo dApp link:** <http://101.132.193.149:5000/#/>

**Cyano wallet mobile version (Android):** <http://101.132.193.149/files/app-debug.apk>
{% endhint %}

After completing the installation of `Cyano` wallet, you can test your `dApp` by performing transactions through the demo app.

### 1. Open a dApp in the wallet

Launch Cyano wallet and access the "DApp" section. Open the "PRIVATE APPS" tab and input this address to access the demo `dApp`: <http://101.132.193.149:5000/#/>

You can also input your local address where you have deployed your `dApp` to open your own app.

![](/files/-LvskNlw_e88tCZaKUKd)

### 2. Fetch Account or Identity Information

![](/files/-LvskNlyrbFrGDqI7OaB)

Clicking on the Get Identity button will directly fetch the `ONT ID` of the account. Enter the password when prompted and the ID will appear in the blank field below. You can carry out the authorization/KYC by uploading your document information, for e.g, passport number, picture of the first page, etc.

![](/files/-LvPYVH_Rqo4A4FAZnMe)

### 3. Login into the dApp

![](/files/-LvskNm3sjmPR-TzEzgC)

In case there is a need to verify the user's identity, `dApp` sends a message to the wallet to carry out the signature process, and then verifies the signature.

As illustrated above, the wallet prompts the user to enter the password. Once confirmed, the contract related details can be accessed.

### 4. dApp Contract Deployment

![](/files/-LvskNm9j1Gt1jZ1dVCB)

The contract deployment process involves the following steps:

1. After the signature verification is completed successfully, the contract is pre-processed.
2. The user confirms and transmits the transaction via the wallet.
3. The `hash` value of the transaction is returned to the `dApp`.

There are 2 advantages of using the the `dAPI` integration method-

* The user can maintain possession of the assets and data.
* The wallet login `dApp` can be readily integrated and conveniently used.

For detailed information on the **integration protocol,** please follow [this](https://github.com/ontio-cyano/CEPs/blob/master/CEPS/CEP1.mediawiki) link.


# Chrome Plugin

Integrating the Google Chrome Cyano wallet plugin

Before using the [dAPI for Chrome](https://github.com/ontio/ontology-dapi), it is necessary to first install and implement a wallet that has the `dAPI provider` functionality built into it, for e.g., [Cyano Wallet for Chrome](https://github.com/OntologyCommunityDevelopers/cyano-wallet).

The `dAPI` can be implemented using `TypeScript`, and can also be used in `JavaScript` programs.

Some of the more popular usage channels of `dApps`, apart from opening the `dApp` in the `Chrome` browser, also consist of launching the `dApp` from withing the mobile wallet. The access scheme for opening a `dApp` in the wallet is illustrated [here](https://dev-docs.ont.io/#/docs-cn/dApp-Integration/01-DAppDocking-Wallet-Opens-DApp).

Here is a step by step guide to assist developers with the integration process:

## 1. Development environment set-up and installation

Before starting with the actual development process, do ensure that the following tools are installed and set-up on your local machine.

* **Node.js v6+  (LTS with npm) -** [Download link](https://nodejs.org/en/download/)
* **Google Chrome -** [Download link](https://www.google.com/chrome/)
* **Cyano Wallet Chrome Plugin -** [Download link](https://chrome.google.com/webstore/detail/ontology-web-wallet/dkdedlpgdmmkkfjabffeganieamfklkm)
* **Git -** [Download link](https://git-scm.com/downloads)

Next, we can install Ontology's `dAPI`. While building `dApps`, this `dAPI` serves as one of the core APIs that allow us to communicate with the chain. The source code can be downloaded [here](https://github.com/ontio/ontology-dapi). To carry out the installation using `npm`, use the following shell command:

```bash
npm install ontology-dapi
```

## 2. Creating a dAPI instance

Creating a `dAPI` instance involves importing and registering the client-side, as such:

```javascript
import { client } from 'ontology-dapi';
client.registerClient({});
```

## 3. Deploying dAPI methods

Once a `dAPI` instance is created successfully, `dAPI` methods can be used in a given `dApp`.

### Fetching account or identity information

```javascript
account = await client.api.asset.getAccount()
res = await client.api.identity.getIdentity();
```

### **Smart contract methods**

```javascript
const result = await client.api.smartContract.invoke({contract,method,parameters,gasPrice,gasLimit,requireIdentity});
const result = await client.api.smartContract.invokeRead({ contract, method, parameters });
const result = await client.api.smartContract.deploy({code,name,version,author,email,description,needStorage,gasPrice,gasLimit});
```

### **Communication methods that assist interaction with the chain**

```javascript
const network = await client.api.network.getNetwork();
const height = await client.api.network.getBlockHeight();
const block = await client.api.network.getBlock({ block: 1 });
const transaction = await client.api.network.getTransaction({txHash: '314e24e5bb0bd88852b2f13e673e5dcdfd53bdab909de8b9812644d6871bc05f'});
const balance = await client.api.network.getBalance({ address: 'AcyLq3tokVpkMBMLALVMWRdVJ83TTgBUwU' });
```

### **Account transfer method**

```javascript
const result = await client.api.asset.makeTransfer({ recipient, asset, amount });
```

### Data signature methods

```javascript
const message: string = values.message;
const signature: Signature = {
  data,
  publicKey
};
const result = await client.api.message.signMessage({ message });
const result = await client.api.message.verifyMessage({ message, signature });
```

For a comprehensive list of all the available `dAPI` methods, please refer to the [dAPI Specification](https://github.com/backslash47/OEPs/blob/oep-dapp-api/OEP-6/OEP-6.mediawiki).

## 4. dAPI demonstration

Follow the link below to refer to a demo `dApp` that utilizes the `dAPI` methods mentioned above.

{% content-ref url="/pages/-LwHH-VnNiKNrmo3qrRd" %}
[Using the dAPI](/guides-and-tutorials/development-guides/dapp-dev/using-dapi)
{% endcontent-ref %}

### How to set the gaslimit and gasprice

Every transaction that takes place on the chain includes a `gaslimit` and `gasprice`.

`gasprice` has a correlation with the amount of standby time while the given transaction is packaged. Currently, the lowest value of `gasprice` is 500 units on the TestNet and MainNet.

The `gaslimit` of deployment contracts is set based on the complexity of smart contract's execution process. The minimum `gaslimit` value of a contract can be determined before deploying it by carrying out a pre-execution. The default `gaslimit` value of `native` contracts is 20000, while that of deployment contracts is usually higher than 20000000 units, generally speaking.

### How to handle addresses

The Chrome plugin `Cyano` wallet only accepts addresses in `ByteArray` format when importing addresses. While testing smart contracts in `SmartX`, the IDE automatically converts addresses to `ByteArray` format. So, there will be no address related issues during the deployment phase. However, in the developer's local environment, if the conversion is not carried out manually, the system will return an error.

The following method can be used to convert addresses to `ByteArray` format in JavaScript:

```javascript
import {Crypto} from 'ontology-ts-sdk';
var address = new Crypto.Address(account).serialize() //The "address" assigned here is in ByteArray format
```


# Mobile wallet dApp

Launching the dApp inside the mobile wallet

Considering the current scenario, mobile wallets are an important channel of access to `dApps`. After integrating Ontology's `cyano-bridge` package, the developer can implement and invoke `dAPI` that adheres to OEP-1 standards, and can communicate with any wallet `dApp` that integrates the `Provider SDK` to carry out chain-related operations.

{% hint style="info" %}
Details regarding the OEP-1 protocol can be found [here](https://github.com/ontio-cyano/CEPs/blob/master/CEPS/CEP1.mediawiki).
{% endhint %}

## Fundamental concepts

Let us take a look at the processes that distributed technologies such as `dApps` and mobile wallets carry out.

### Role of dApps

The `dApp` back end primarily carries out the following tasks:

* `dApp` operations, i.e., generating the relevant login parameters, or the parameters for invoking smart contracts.
* Synchronizing with the on-chain data, and fetching the results of login, or smart contract invocation.

### Role of mobile wallets

A mobile wallet acts as a `provider`. It carries out the roles that involve interacting with the chain, such as providing the signature data, pre-executing and executing transactions, etc.

{% hint style="info" %}
The above description is with respect to the wallets that can serve as providers. Currently, the following are supported:

* [**ONTO**](https://onto.app/)
* [**Cyano Wallet**](http://101.132.193.149/files/app-debug.apk)
* [**O-Wallet**](https://github.com/ontio/OWallet/releases)
* [**Math Wallet**](http://www.mathwallet.org/en/)
* [**Banko**](http://bankowallet.com/pc.html)
* [**Huobi Wallet**](https://www.huobiwallet.com/)
  {% endhint %}

## Interaction Process

Generally speaking, application users' primary concerns are the login and transaction procedure.

The process flow is illustrated in the following figure:

![](/files/-LvPYVGGlWet3gTk61JN)

### Login scenario

1. A `dApp` is opened in the wallet's `dApp` store.
2. Next, there are two possible circumstances - either the `dApp` sends an account query request to the wallet, and the wallet returns the asset account's address, or the `dApp` sends a login request to the wallet and the wallet returns signature data.
3. If the `dApp` verification is completed, access is granted.

### Smart Contract invocation scenario

1. The `dApp` sends an invocation request to the wallet.
2. The wallet digitally signs the transaction, pre-executes it, sends it to the chain, and returns the transaction `hash` to the `dApp`.

## dAPI protocol usage

### 1. Installation

Based on subjective requirements, one of the following two methods can be chosen to install `cyanobridge`.

**npm installation-**

```bash
npm install cyanobridge
```

**CDN installation-**

Currently, the latest version can be acquired using `jsDelivr`. Paste the following script on the page's code to instantly start using the `dAPI`.

```markup
<script src="https://cdn.jsdelivr.net/npm/cyanobridge/lib/browser.min.js"></script>
```

{% hint style="warning" %}
CDN users are advised to fix the version in the above link so as to avoid compatibility issues during updates.
{% endhint %}

### 2. Import

#### **CommonJS**

```javascript
var client = require('cyanobridge').client
```

#### **ES6 module**

```javascript
import { client } from 'cyanobridge'
```

#### Web Page Embed

To import the **browser.js** file inside the `./lib` directory:

```markup
<script src="./lib/browser.js"></script>

var client = CyanoMobile.client;
```

### 3. Initialization

The `dAPI` needs to be initialized and registered before being used.

```javascript
import { client } from 'cyanobridge'
client.registerClient();
```

### 4. Method Usage

#### **Fetch account or user identity information**

`dApp` information is optional. The developer may choose not to fill it when making the function call.

```javascript
import { client } from 'cyanobridge'

const params = {
​    dappName: 'My dapp',
​    dappIcon: '' // some url points to the dapp icon
}

try {
​    const res = await client.api.asset.getAccount(params);
    const res = await client.api.identity.getIdentity(params);
​    console.log(res)
} catch(err) {
​    console.log(err)
}
```

#### **Login**

Login is signed on the wallet's end. The `dApp` carries out the verification signature.

```javascript
const params = {
    type: 'account',// account or identity that will sign the message
    dappName: 'My dapp', // dapp's name
    dappIcon: 'http://mydapp.com/icon.png', // the URL that points to the dapp's icon resource
    message: 'test message', // message sent from dapp that will be signed by native client
    expired: new Date('2019-01-01').getTime(), // expiry date of login
    callback: '' // callback url of dapp
}
let res;
try {
    res = await client.api.message.login(params);
    console.log(res)
}catch(err) {
    console.log(err)
}
```

#### **Invoke contract or initiate payment**

```javascript
const scriptHash = '8b344a43204e60750e7ccc8c1b708a67f88f2c43';
const operation = 'transferOng'
const args = [
   {
        "name": "arg0-id",
        "value": "String:hedgsg"
    }, {
        "name": "arg1-from",
        "value": "Address:AecaeSEBkt5GcBCxwz1F41TvdjX3dnKBkJ"
    }, {
        "name": "arg2-to",
        "value": "Address:AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ"
    }, {
        "name": "arg3-int",
        "value": 1
    }
]
const gasPrice = 500;
const gasLimit = 20000;
const payer = 'AecaeSEBkt5GcBCxwz1F41TvdjX3dnKBkJ'
const config = {
​    "login": true,
​    "message": "invoke smart contract test"
}
const params = {
          scriptHash,
          operation,
          args,
          gasPrice,
          gasLimit,
          payer,
          config
        }
try {
   const res = await client.api.smartContract.invoke(params);
   } catch(err) {
​    console.log(err)
}
```

#### Error codes

This is the list of error codes that the system returns.

| Error Code |   Description  |
| :--------: | :------------: |
|      0     |     Success    |
|    80001   |  Params error  |
|    80002   |  Method error  |
|    80003   | Internal error |

An example of the code returned (JSON):

```yaml
{
    "action": "login",
    "error": 0,
    "desc": "SUCCESS",
    "result": true
}
```

## Code base for Reference

|                                              **Signature verification methods**                                              |                                                     **Transaction event query methods**                                                    |                         **Cyano Wallet**                        |                      **dAPI - Mobile provider SDK**                     | **dAPI - Mobile client SDK**                                |
| :--------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------: | :---------------------------------------------------------------------: | ----------------------------------------------------------- |
| [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/interface.md#%E7%AD%BE%E5%90%8D%E9%AA%8C%E7%AD%BE) | [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/basic.md#%E4%B8%8E%E9%93%BE%E4%BA%A4%E4%BA%92%E6%8E%A5%E5%8F%A3) | [Cyano - Android](https://github.com/ontio-cyano/cyano-android) | [Cyano - Android SDK](https://github.com/ontio-cyano/cyano-android-sdk) | [Cyano Bridge](https://github.com/ontio-cyano/cyano-bridge) |
|               [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/ecdsa.crypto.test.ts)               |                        [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/websocket.test.ts)                       |     [Cyano - iOS](https://github.com/ontio-cyano/cyano-ios)     |     [Cyano - iOS SDK](https://github.com/ontio-cyano/cyano-ios-sdk)     |                                                             |


# QR code mechanism

Mobile wallet QR code functionality

This section aims at assisting the developer with integrating the QR code protocol `dAPI` into a dApp. This would allow the user to carry out services like login, invoke smart contracts, and more by scanning QR codes.

The parties involved in the process are:

* The `dApp` :  Blanket term that represents`dApps` developed for the users of Ontology ecosystem.
* The `Provider`: Wallets that support `dAPI` , and adhere to it's specifications.

## Interaction Process

The following charts illustrate the login and smart contract invocation process.

**Login**

![](/files/-LvskNmTHofh_7GtLyfQ)

1. `dApp` submits the QR code
2. The `dApp` server executes the login method
3. The `dApp` back end verifies the signature

**Smart Contract Invocation**

![](/files/-LvPYVGkjaLWjXFLYan-)

1. `dApp` submits the QR code
2. `Provider` initiates the transaction, the user authenticates and signs, the contract is pre-executed, the user confirms, the process is transmitted onto the chain, and at the end the transaction hash is returned to the `dApp` back end
3. `dApp` back end confirms whether the transaction event was a success or failure by querying the chain

## dAPI protocol usage

The dAPI protocol currently supports login and smart contract deployment actions.

### 1. Login

The standard for supported QR codes:

```yaml
{
    "action": "login",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or account",
        "dappName": "dapp Name",
        "dappIcon": "link",
        "message": "helloworld",
        "expire": 1546415363, // QR Code expire time
        "callback": "http://101.132.193.149:4027/blockchain/v1/common/test-onto-login"
    }
}
```

Specification for the above fields-

|   Field  | Data type | Description                                                                                                              |
| :------: | :-------: | ------------------------------------------------------------------------------------------------------------------------ |
|  action  |   string  | Describes the function of the QR code, login is defined as `login`, and smart contract invocation is defined as `invoke` |
|    id    |   string  | A serial number (optional)                                                                                               |
|   type   |   string  | Login action using ONTID is defined as`ontid`, wallet address login is defined as `account`                              |
| dappName |   string  | Name of the `dApp`                                                                                                       |
| dappIcon |   string  | `dApp` icon resource (link)                                                                                              |
|  message |   string  | Randomly generated, used for identity verification                                                                       |
|  expire  |    long   | Unix timestamp (optional)                                                                                                |
| callback |   string  | The URL sent to the `dApp` back end after the user scans the QR code and completes authentication                        |

#### dApp server side login interface

{% hint style="info" %}
This interface is invoked after the wallet is done handling callback procedure. The server address must be an external IP address
{% endhint %}

```yaml
method: post

{
    "action": "login",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or account",
        "user": "did:ont:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz",
        "message": "helloworld",
        "publickey": "0205c8fff4b1d21f4b2ec3b48cf88004e38402933d7e914b2a0eda0de15e73ba61",
        "signature": "01abd7ea9d79c857cd838cabbbaad3efb44a6fc4f5a5ef52ea8461d6c055b8a7cf324d1a58962988709705cefe40df5b26e88af3ca387ec5036ec7f5e6640a1754"
    }
}
```

Specification for the above fields-

|   Field   | Data type | Description                                                                                  |
| :-------: | :-------: | -------------------------------------------------------------------------------------------- |
|   action  |   string  | Operation type                                                                               |
|     id    |   string  | Serial number (optional)                                                                     |
|   params  |   string  | Method arguments                                                                             |
|    type   |   string  | Login action using ONTID is defined as `ontid`, wallet address login is defined as `account` |
|    user   |   string  | The user account that authenticates the transaction - `ontid` or `wallet` address            |
|  message  |   string  | Randomly generated, used for identity verification                                           |
| publickey |   string  | Wallet account public key                                                                    |
| signature |   string  | User's signature - private key                                                               |

***Success response:***

```yaml
{
  "action": "login",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 0,
  "desc": "SUCCESS",
  "result": true
}
```

***Failure response:***

```yaml
{
  "action": "login",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 80001,
  "desc": "PARAMS ERROR",
  "result": 1
}
```

### 2. Data Signature

This process is analogous to the login protocol in every aspect, with the difference being when the `dApp` requests data signature the `dApp` name and `icon` are not required.

The QR code data of the data signature request looks like:

```yaml
{
    "action": "signMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "message": "helloworld",
        "ishex": false
        "callback": "http://101.132.193.149:4027/blockchain/v1/common/test-onto-login"
    }
}
```

Multi-signature data model:

```yaml
{
    "action": "signMultiMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "message": ["aabbccdd"],
        "ishex": true
        "callback": "http://101.132.193.149:4027/blockchain/v1/common/test-onto-login"
    }
}
```

|   Field  |  Type  | Description                                                                                                                                         |
| :------: | :----: | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|  action  | string | Operation type                                                                                                                                      |
|   type   | string | Login action using ONTID is defined as`ontid`, wallet address login is defined as `address`, if left blank the field is set to `address` by default |
|  message | string | Randomly generated, used for identity verification                                                                                                  |
|   ishex  |  bool  | Whether or not the message is a hex code                                                                                                            |
| callback | string | The URL sent to the `dApp` back end after the user scans the QR code and completes authentication                                                   |

After the wallet's response is decoded by the **URI decoder** and the **Base64 decoder**, the resultant data follows the format illustrated below.

The success response returned to the callback address is of the form:

```yaml
method: post
{
    "action": "signMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "error": 0,
    "desc": "SUCCESS",
    "result": {
        "type": "ontid or address",
        "user": "did:ont:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz or AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz",
        "message": "helloworld",
        "publickey": "0205c8fff4b1d21f4b2ec3b48cf88004e38402933d7e914b2a0eda0de15e73ba61",
        "signature": "01abd7ea9d79c857cd838cabbbaad3efb44a6fc4f5a5ef52ea8461d6c055b8a7cf324d1a58962988709705cefe40df5b26e88af3ca387ec5036ec7f5e6640a1754"
    }
}

If the action is signMultiMessage, the result is an array
```

### 3. Smart Contract Invocation

Transactions are also a feature of smart contracts. Here's the standard for smart contract invocation QR code:

```yaml
{
    "action": "invoke",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "login": true,
        "callback": "http://101.132.193.149:4027/invoke/callback",
        "expire": 1546415363, // QR code expiry
        "qrcodeUrl": "http://101.132.193.149:4027/qrcode/AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ"
    }
}
```

| Field     | Data type | Description                                                                                       |
| --------- | --------- | ------------------------------------------------------------------------------------------------- |
| action    | string    | Operation type, login is defined as `login`, and smart contract invocation is defined as `invoke` |
| qrcodeUrl | string    | QR code argument address                                                                          |
| callback  | string    | Returns the transaction hash to the `dApp` server side (optional)                                 |
| expire    | long      | Unix timestamp of QR code expiration (optional)                                                   |

The GET request content based on QR code's `qrcodeUrl` is as follows:

```yaml
{
    "action": "invoke",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "invokeConfig": {
            "contractHash": "16edbe366d1337eb510c2ff61099424c94aeef02",  //contract address
            "functions": [{
                "operation": "method name", //name of the method in the invoked smart contract
                "args": [{   //contract invocation arguments
                    "name": "arg0-list",//argument index 1's value is an array
                    "value": [true, 100, "Long:100000000000", "Address:AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ", "ByteArray:aabb", "String:hello", [true, 100], {
                        "key": 6
                    }]
                }, {
                    "name": "arg1-map",//argument index 2's value is a map
                    "value": {
                        "key": "String:hello",
                        "key1": "ByteArray:aabb",
                        "key2": "Long:100000000000",
                        "key3": true,
                        "key4": 100,
                        "key5": [100],
                        "key6": {
                            "key": 6
                        }
                    }
                },{
                       "name": "arg2-ByteArray", //argument index 3's value is a ByteArray
                       "value": "ByteArray:aabbcc"
                },{
                    "name": "arg3-int", //arguement index 4's value is int/long
                    "value": 100
                },{
                    "name": "arg4-str", //argument index 5's value is string
                    "value": "String:test"
                }]
            }],
            "payer": "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ",
            "gasLimit": 20000,
            "gasPrice": 500
        }
    }
}
```

{% hint style="info" %}
A Base58 address, for e.g., *AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ* can be used to fill the `%address` parameter. The wallet converts the `%address` to the wallet's asset address. If the argument contains the `%ontid`, the wallet converts it to the wallet's `ontid` address.
{% endhint %}

When a smart contract is deployed, if the `payer` is not specified in the QR code, it is taken from the wallet. If the `payer` has been explicitly specified, the wallet verifies if the `payer` specified is identical with the wallet's asset address.

The `provider` initiates transactions, carries out user authentication and signature, pre-executes the contract, and finally passes the transaction has to the callback URL via POST method.

If the transaction succeeds, the wallet returns the following to callback:

```yaml
{
  "action": "invoke",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 0,
  "desc": "SUCCESS",
  "result": "tx hash"
}
```

If the transaction fails, the wallet returns:

```yaml
{
  "action": "invoke",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 80001,
  "desc": "SEND TX ERROR",
  "result": 1
}
```

## Code base for Reference

|                                              **Signature verification methods**                                              |                                                     **Transaction event query methods**                                                    |                         **Cyano Wallet**                        |                      **dAPI - Mobile provider SDK**                     | **dAPI - Mobile client SDK**                                |
| :--------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------: | :---------------------------------------------------------------------: | ----------------------------------------------------------- |
| [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/interface.md#%E7%AD%BE%E5%90%8D%E9%AA%8C%E7%AD%BE) | [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/basic.md#%E4%B8%8E%E9%93%BE%E4%BA%A4%E4%BA%92%E6%8E%A5%E5%8F%A3) | [Cyano - Android](https://github.com/ontio-cyano/cyano-android) | [Cyano - Android SDK](https://github.com/ontio-cyano/cyano-android-sdk) | [Cyano Bridge](https://github.com/ontio-cyano/cyano-bridge) |
|               [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/ecdsa.crypto.test.ts)               |                        [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/websocket.test.ts)                       |     [Cyano - iOS](https://github.com/ontio-cyano/cyano-ios)     |     [Cyano - iOS SDK](https://github.com/ontio-cyano/cyano-ios-sdk)     |                                                             |


# Wake call mechanism

Applications wake the wallet service

Certain wallet applications that implement special adaptation layers support being called from within other applications on the phone.

In this section, we talk about how to wake the wallet from inside an application and implement features such as login and smart contract invocation (including payment method). For more details on the application wake mechanism, please refer to [Android application demo](https://github.com/ontio-cyano/android-app-demo).

## Interaction Process

### Login flow

![](/files/-LvPYVHlNTOszXx6yeIR)

### Transaction flow

![](/files/-LvPYVGoHuNiDZp5wuiY)

## dAPI protocol usage

With respect to the wake call, the development process involves implementing two functions - **login** and **smart contract invocation.**

The login process is simpler at it's core, so we won't go into any unnecessary details. The process is illustrated in the following section.

Smart contract invocation has a much broader scope of application. `dApps` can use smart contracts to implement various different kinds of logic. For example, in the case of a game, there are different operations and services that can be carried out using smart contracts, such as buying, selling, renting, etc.

### 1. Login

The core sequence of the login operation is illustrated in the picture below:

![](/files/-LvPYVHpaywIGCevHdNe)

1. The `dApp` communicates with the back end to fetch the callback URL and a message to be sent to the dedicated `provider`, along with other information (depending upon the implementation logic), and wakes the wallet.
2. The `provider` wallet carries out user authentication and signs the message.&#x20;
3. The signed message is then returned to the `dApp` back end using the designated callback URL, along with the signed message, the signature and a public key for verification purposes.
4. The back end finally verifies the signature and sends a success/failure response to the `dApp`.

#### Login Data

When the `dApp` needs to login, it fetches the relevant login data in order to send it to the `provider` wallet.

An example of the data structure:

```yaml
{
    "action": "login",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "version": "v1.0.0",
    "params": {
        "type": "ontid or account",
        "dappName": "dapp Name",
        "dappIcon": "dapp Icon",
        "message": "helloworld",
        "expire": 1546415363,
        "callback": "http://127.0.0.1:80/login/callback"
    }
}
```

#### Specific usage procedure

1. Establish whether or not `Cyano Wallet` is installed on the system. An example verification method is provided below.

```java
public static boolean checkInstallCynoApp(Context context) {
       final PackageManager packageManager = context.getPackageManager();// Fetch the package manager
       List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);// Get a list of all the installed packaged on the system
       if (pinfo != null) {
           for (int i = 0; i < pinfo.size(); i++) {
               String pn = pinfo.get(i).packageName.toLowerCase(Locale.ENGLISH);
               if (pn.equals("com.github.ont.cyanowallet")) {
                   return true;
               }
           }
       }
       return false;
   }
```

1. `dApp` sends the data it received from the `dApp` server to the dedicated provider (wallet). This can be realized in the following manner:

```java
   String data = "{\"action\":\"login\",\"id\":\"10ba038e-48da-487b-96e8-8d3b99b6d18a\",\"version\":\"v1.0.0\",\"params\":{\"type\":\"ontid or account\",\"dappName\":\"dapp Name\",\"dappIcon\":\"dapp Icon\",\"message\":\"helloworld\",\"expire\":1546415363,\"callback\":\"http://127.0.0.1:80/login/callback\"}}"; //此处就是将之前的登录数据拼接后的状态。

   String sendData = Base64.encodeToString(Uri.encode(data).getBytes(), Base64.NO_WRAP);
   Intent intent = new Intent("android.intent.action.VIEW");
   intent.setData(Uri.parse("ontprovider://ont.io?param=" + sendData ));
   intent.addCategory("android.intent.category.DEFAULT");
   startActivity(intent);
```

1. The `provider` verifies the submitted information and signs it, and transmits it back to the specified callback address. The developer need not execute this step manually.
2. The `dApp` back end verifies the signature to establish whether the login succeeded or failed and notifies the `dApp`.

### 2. Smart Contract Invocation

The core contract invocation process is illustrated in the figure below:

![](/files/-LvPYVHrg7QysBzPiwS6)

1. `dApp` side creates a contract invocation data set and sends it to the dedicated `provider`.
2. The `provider` carries out user authentication, signature process, and carries out the transaction by communicating with the blockchain.
3. The `provider` receives the transaction hash from the blockchain and transmits it to the `dApp` back end using the specified callback address.
4. The `dApp` server end queries the blockchain for the execution result using the transaction `hash`.
5. The final result is returned to the `dApp`, made accessible to the user.

#### Smart Contract invocation data

A sample contract invocation data set:

```yaml
{
    "action": "invoke",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "login": true,
        "message": "will pay 1 ONT in this transaction",
        "callback": "http://101.132.193.149:4027/invoke/callback",
        "invokeConfig": {
            "contractHash": "16edbe366d1337eb510c2ff61099424c94aeef02",  //contract address
            "functions": [{
                "operation": "method name", //name of the method in the invoked smart contract
                "args": [{   //contract invocation arguments
                    "name": "arg0-list",//argument index 1's value is an array
                    "value": [true, 100, "Long:100000000000", "Address:AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ", "ByteArray:aabb", "String:hello", [true, 100], {
                        "key": 6
                    }]
                }, {
                    "name": "arg1-map",//argument index 2's value is a map
                    "value": {
                        "key": "String:hello",
                        "key1": "ByteArray:aabb",
                        "key2": "Long:100000000000",
                        "key3": true,
                        "key4": 100,
                        "key5": [100],
                        "key6": {
                            "key": 6
                        }
                    }
                },{
                       "name": "arg2-ByteArray", //argument index 3's value is a ByteArray
                       "value": "ByteArray:aabbcc"
                },{
                    "name": "arg3-int", //arguement index 4's value is int/long
                    "value": 100
                },{
                    "name": "arg4-str", //argument index 5's value is string
                    "value": "String:test"
                }]
            }],
            "payer": "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ",
            "gasLimit": 20000,
            "gasPrice": 500
        }
    }
}
```

{% hint style="info" %}
A `Base58` address, for e.g., `AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ` \_\_can be used to fill the `%address` parameter. The wallet converts the `%address` to the wallet's asset address. If the argument contains the `%ontid`, the wallet converts it to the wallet's `ontid` address.
{% endhint %}

#### Implementation Sequence

1. Ensuring the `Provider-sdk` wallet application is installed and deployed on the phone.
2. Composing the contract invocation `JSON` data set, making the wake call to the wallet.

Sample code:

```java
String data="{\"action\":\"invoke\",\"version\":\"v1.0.0\",\"id\":\"10ba038e-48da-487b-96e8-8d3b99b6d18a\",\"params\":{\"login\":true,\"qrcodeUrl\":\"http://101.132.193.149:4027/qrcode/AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ\",\"message\":\"will pay 1 ONT in this transaction\",\"callback\":\"http://101.132.193.149:4027/invoke/callback\"}}";


String sendData = Base64.encodeToString(Uri.encode(data).getBytes(), Base64.NO_WRAP);
Intent intent = new Intent("android.intent.action.VIEW");
intent.setData(Uri.parse("ontprovider://ont.io?param=" + sendData ));
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
```

1. The `provider` authenticates, signs, pre-executes, and finally transmits the transaction to the chain. (This step does not require manual implementation)
2. The `provider` sends the transaction hash retrieved from the blockchain to the `dApp` back end. (This step is carried out depending on the `dApp's` event sequence)
3. `dApp` queries the result from the blockchain.

{% hint style="success" %}
Query methods reference:

* [Java SDK transaction event query methods](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/basic.md#%E4%B8%8E%E9%93%BE%E4%BA%A4%E4%BA%92%E6%8E%A5%E5%8F%A3)
* [TypeScript transaction event query methods](https://github.com/ontio/ontology-ts-sdk/blob/master/test/websocket.test.ts)&#x20;
  {% endhint %}

1. The `dApp` back end returns the result to the `dApp`, from where the user can access it. (Depends on the logic of the `dApp`)

#### dApp Server Callback Interface

The `provider` initiates transactions, carries out user authentication and signature, pre-executes the contract, and finally passes the transaction has to the callback URL via POST method.

If the transaction succeeds, the wallet returns the following to callback:

```yaml
{
  "action": "invoke",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 0,
  "desc": "SUCCESS",
  "result": "tx hash"
}
```

If the transaction fails, the wallet returns:

```yaml
{
  "action": "invoke",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 80001,
  "desc": "SEND TX ERROR",
  "result": 1
}
```

## Demonstration

The two example applications demonstrate the wake call for specially designated wallets. The code can be used for reference.

* [Wake wallet - Demo application](https://github.com/ontio-cyano/android-app-demo)
* [Unity game demonstration](https://dev-docs.ont.io/#/docs-cn/dApp-Integration/12-unity_integration)

## Code base for Reference

|                                              **Signature verification methods**                                              |                                                     **Transaction event query methods**                                                    |                         **Cyano Wallet**                        |                      **dAPI - Mobile provider SDK**                     | **dAPI - Mobile client SDK**                                |
| :--------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------: | :---------------------------------------------------------------------: | ----------------------------------------------------------- |
| [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/interface.md#%E7%AD%BE%E5%90%8D%E9%AA%8C%E7%AD%BE) | [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/basic.md#%E4%B8%8E%E9%93%BE%E4%BA%A4%E4%BA%92%E6%8E%A5%E5%8F%A3) | [Cyano - Android](https://github.com/ontio-cyano/cyano-android) | [Cyano - Android SDK](https://github.com/ontio-cyano/cyano-android-sdk) | [Cyano Bridge](https://github.com/ontio-cyano/cyano-bridge) |
|               [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/ecdsa.crypto.test.ts)               |                        [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/websocket.test.ts)                       |     [Cyano - iOS](https://github.com/ontio-cyano/cyano-ios)     |     [Cyano - iOS SDK](https://github.com/ontio-cyano/cyano-ios-sdk)     |                                                             |


# Cocos 2D-x


# Unity 3D applications

Integrating Ontology's dAPI in Unity based games

Unity 3D is an integrated cross-platform game engine that is used to build interactive 3D games, animations, visualizations, 3D models, etc.

Generally speaking, blockchain platform integration is carried out after the game clears it's development phase. Ontology provides two swift methods of integrating blockchain technology in Unity based games: `dAPI`, and `SDK` based integration.

* Integrating `dAPI` using the `Cyano` wallet Chrome plugin. These games must be compiled and rendered using `Web GL`. Here's a demo for web based games: <https://github.com/ontio-community/unity-dapi-demo>
* Integrating `dAPI` via the PC version of the wallet. The game must be PC compatible to be able to implement this method of integration.
* Integrating `dAPI` using the `C# SDK`. This method can be used for games that are mobile based, as well as other platforms. Demo code: <https://github.com/ontio-community/unity-demo>


# Mobile Wallet Integration

For wallets that want to connect to the Ontology platform

Considering mobile wallets, there are two levels of integration which wallets can employ based on functional requirements:

* **Asset Docking:** For wallets that intend to support `ONT/ONG` based transactions along with being able to support `OEP-4` transfers.
* **Provider SDK:** For wallets that intend to be able to support and launch the wide variety of Ontology's `dApps`.&#x20;

After completing integration on both the levels, event based integration can be carried out.

Whether the integration was completed successfully or not can be tested by using the `polaris` test network. Once confirmed, the application can be deployed on the `main-net`.

![](/files/-LvPYWOF67fXeSxR6hBS)

## Asset Docking

Asset docking is the foundation of mobile wallet integration process. A wallet app that integrates Ontology's `SDK`, paired with `Explorer API` can carry out digital asset manipulation and account management operations. This would suffice to cater to the asset management needs of a large majority of Ontology user community.

![](/files/-LvPYVFrZ_W4Wlv476hQ)

## Provider SDK integration

After integrating the above `SDK` in order to perform asset related functions, developers may choose to integrate the `Provider SDK`.

Since all the `dApps` that are part of the Ontology ecosystem adhere to a unified standard, a wallet app that integrates the `provider SDK` can become a launching platform for Ontology `dApps`, thereby eliminating the need to integrate them one by one and making the deployment process a lot more efficient.

![](/files/-LwHD9HmU-kE3yyMBS59)

Integrating the `Provider SDK` would allow the wallet to carry out login, make transfers, and invoke smart contracts using the following channels:

* **QR codes**
* From within the **mobile wallet application**
* Accessing the **web version**
* **waking the wallet app** from within other applications

{% hint style="success" %}
Currently, the following wallets are compatible with Ontology's `dAPI` and can serve as providers:

* [**ONTO**](https://onto.app/)
* [**Cyano Wallet**](http://101.132.193.149/files/app-debug.apk)
* [**O-Wallet**](https://github.com/ontio/OWallet/releases)
* [**Math Wallet**](http://www.mathwallet.org/en/)
* [**Banko**](http://bankowallet.com/pc.html)
* [**Huobi Wallet**](https://www.huobiwallet.com/)
  {% endhint %}

## dApp test links

After completing the integration process, access the following links from the wallet to test whether the integration was successful or not:

* **Test net dApp:**  <http://101.132.193.149:5000/#/>
* **Main net dApp:**  <https://github.com/ontio-community/dapp-store/blob/master/mobile-dapps.json>


# SDK integration

Use one of Ontology's SDKs to integrate the platform

Wallet apps that integrate Ontology's `SDK` can use `Explorer API` to carry out digital asset related operations and transactions, and account management functions.

![](/files/-LvskNklyn99tEifa9RG)

## SDK usage

Ontology's `SDK` acts as the bridge of communication between application programs and the Ontology network.

To cater to different needs of developers, Ontology provides `SDKs` for multiple languages that are all based on a standard development specification.

After successfully integrating the `SDK`, a wallet can perform the following functions:

* Communicate and interact with Ontology **blockchain**
* Create and maintain **accounts**.
* Generate and manipulate **assets**, including primary, and `OEP-4`, `OEP-5`, `OEP-8` based assets.
* Realize a **digital identity**.
* **Node** staking.

Please follow the links specified below to navigate to language specific SDK usage instructions and reference:

|                                                                                                      |                                          Ontology SDK family                                          |                                                                                                  |
| :--------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------: |
|     [Go SDK](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration)     |     [Java SDK](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration)    | [Python SDK](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration) |
| [TypeScript SDK](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration) |     [PHP SDK](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration)     |  [Swift SDK](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration) |
|   [Android SDK](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration)  | [Objective-C SDK](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration) |   [C# SDK](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration)   |

## Explorer API

`Explorer API` has been made available for developers, institutions, and cryptocurrency exchange platforms to enable them to query transaction and account related information from the Ontology blockchain.

Currently, the following can be queried to fetch information from the chain:

* [Blocks](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration)
* [Accounts](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration)
* [Transactions](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration)
* [ONT ID](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration)
* [Statistics](/guides-and-tutorials/integration-guides/mobile-wallet-integration/sdk-integration)


# dAPI Integration

Integrating a mobile wallet using the dAPI

Integrating the `dAPI` is practically equivalent to integrating the `Provider SDK`. The `Provider SDK` encapsulates methods for `iOS/Android webview`, and supports communication between web based `dApps` and `iOS/Android webview`.

![](/files/-LvPYVGeMfZeV9Z6pqe1)

{% hint style="info" %}
For the `dAPI` method handbook for both **Android** and **iOS** operating systems, please follow this [link](/developer-tools/cyano-wallet/mobile-version-provider).
{% endhint %}

## dAPI usage scenarios

Mobile version of `dAPI` can allow the wallet to perform the following features based on `dApp` scenarios-

* `dApps` are launched **in the wallet**
* Wallet scans **QR codes**
* Applications **wake the wallet**

### dApps open in the wallet

![](/files/-LvPYVGg7rrDr22ZP-kF)

The execution process is as follows:

1. The `dApp` is opened in the wallet
2. Account or identity information is fetched
3. `dApp` logs in
4. `dApp` invokes smart contract

### Wallet scans a QR code

#### Login Process

![](/files/-LvskNjGjutt26ec-DER)

The execution process is as follows:

1. Wallet scans the QR code provided by the `dApp`
2. Provider receives the `callback URL` and verification message, user authenticates and signs the message, the message is sent to the `callback URL` provided.
3. `dApp` back end carries out the verification process for the message.

#### Invoking a smart contract

![](/files/-LvskNjIdhgQ-1Uzskbs)

The execution process is as follows:

1. Wallet scans the QR code provided by the `dApp`
2. Wallet initiates the transaction, the user authenticates and signs, the contract is pre-executed, user confirms, transaction is transmitted to the blockchain, transaction `hash` is returned to the callback address
3. `dApp` back end queries transaction event

### dApp wakes the wallet

#### dApp sends a login request

![](/files/-LvPYVF-9hNyFlZbhBQg)

1. `dApp` sends the wake call to the wallet
2. Wallet fetches the `callback URL` and the verification message, user enter authenticates and signs the message, wallet returns the signature to the callback address
3. `dApp` back end verifies the message

#### dApp sends an invocation request

![](/files/-LvPYVF145l4fEBoJNQ1)

1. `dApp` sends the wake call to the wallet
2. Wallet initiates the transaction, the user authenticates and signs, wallet pre-executes the transaction, the transaction is transmitted to the blockchain, the transaction `hash` is returned to the `callback` address
3. `dApp` back end queries the transaction event on the blockchain using the transaction `hash`

## Demonstration

Here is a basic demonstration of some of the basic functions that the wallet can perform. A demo wallet which can be downloaded using the link below has been used to mimic a second party.

{% hint style="info" %}
**H5 demo dApp source code:** <https://github.com/ontio-cyano/mobile-dapp-demo>

**H5 demo dApp link:** <http://101.132.193.149:5000/#/>

**Cyano wallet mobile version (Android):** <http://101.132.193.149/files/app-debug.apk>

**Cyano wallet source code(Android):** <https://github.com/ontio-cyano/cyano-android>

**Cyano wallet source code(iOS):** <https://github.com/ontio-cyano/cyano-ios>
{% endhint %}

After completing the installation of `Cyano` wallet and the demo app, features of both the wallets can be tested along with the source code as reference.

Transactions can be performed to test smart contract logic and confirming whether or not the platform has been integrated successfully.

### 1. Open a dApp in the wallet

Launch Cyano wallet and access the "DApp" section. Open the "PRIVATE APPS" tab and input this address to access the demo `dApp`: <http://101.132.193.149:5000/#/>

![](/files/-LvPYVHWXWguUuqprpJV)

### 2. Fetch Account or Identity Information

![](/files/-LvPYVGsMXp1SybViifo)

Clicking on the Get Identity button will directly fetch the `ONT ID` of the account. Enter the password when prompted and the ID will appear in the blank field below. You can carry out the authorization/KYC by uploading your document information, for e.g, passport number, picture of the first page, etc.

![](/files/-LvskNjQ4LxRdWpCwV6P)

### 3. Login into the dApp

![](/files/-LvPYVHbk6XX6Qu8W0Bt)

In case there is a need to verify the user's identity, `dApp` sends a message to the wallet to carry out the signature process, and then verifies the signature.

As illustrated above, the wallet prompts the user to enter the password. Once confirmed, the contract related details can be accessed.

### 4. dApp Contract Deployment

![](/files/-LvPYVGySVtuJFquTfzo)

The contract deployment process involves the following steps:

1. After the signature verification is completed successfully, the contract is pre-processed.
2. The user confirms and transmits the transaction via the wallet.
3. The `hash` value of the transaction is returned to the `dApp`.


# In-wallet applications

Launching applications in the mobile wallet

The following section serves to guide developers on how to enable wallets to support Ontology's `dAPI`, along with `Provider SDK` integration into mobile wallet apps. It may be worth referring to the respective open source Android and iOS wallet [source code](https://github.com/ontio-cyano).

The two parties involved in the integration process are:

* The `dApp` :  Blanket term that represents`dApps` developed for the users of Ontology ecosystem.
* The `Provider`: Wallets that support `dAPI` , and adhere to it's specifications.

{% hint style="info" %}
Wallets that currently support the `dAPI` protocol:

* [**ONTO**](https://onto.app/)
* [**Cyano Wallet**](http://101.132.193.149/files/app-debug.apk)
* [**O-Wallet**](https://github.com/ontio/OWallet/releases)
* [**Math Wallet**](http://www.mathwallet.org/en/)
* [**Banko**](http://bankowallet.com/pc.html)
* [**Huobi Wallet**](https://www.huobiwallet.com/)
  {% endhint %}

## Interaction process

The URI scheme that the `dApp` uses when sending requests:

```
ontprovider://ont.io?param=Base64.encode(Uri.encode({the json data}.toString()))
```

The process can be broadly divided in the following manner:

![](/files/-LwHH1PTXL7zEXqwsaKD)

#### Step 1：Wallet uses Webview to open dApps (H5 design)

Wallet uses `Webview` to open `H5 dApps` in the `dApp` store page layout

#### Step 2：dApp sends a request to fetch wallet's address

There are two ways to retrieve account information-

* Using the `getAccount` method
* Using the `login` method

#### Step 3：dApp sends a contract invocation request

The steps involved-

1. `dApp` sends **invocation request**
2. The wallet initiates transaction, carries out user **authentication** and **signature**
3. Wallet **pre-executes** the transaction
4. Transaction is transmitted to the **blockchain**
5. Wallet returns **transaction `hash`** to the `dApp`

## dAPI protocol usage

The dAPI protocol is extensible in nature. It's core features can be laid out in terms of the following functions.

* Querying `Provider` information
* Querying **wallet** or **account/identity** related information
* **Authentication** and login
* Message **signature**
* Smart contract **invocation**

### Querying provider information

The query request that the `dApp` sends to the wallet to fetch the `provider` information is first encoded in `URI` and `Base64`, and then sent. The data is structured in the following manner:

```yaml
{
    "action": "getProvider",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "version": "v1.0.0",
    "params": {
    }
}
```

Data specification for the fields mentioned above-

|  Field | Data type |   Description  |
| :----: | :-------: | :------------: |
| action |   string  | Operation type |
|   id   |   string  |  Serial number |

The data set of provider information that the wallet returns, after `URI` and `Base64` decoding, is structured in the following manner:

```yaml
{
    "action": "getProvider",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "error": 0,
    "desc": "SUCCESS",
    "result": {
        "provider": "cyano walllet",
        "version": "1.0.0"
    }
}
```

### Querying the wallet account or identity information

The query request that the `dApp` sends to the wallet to fetch the account or identity information is first encoded in `URI` and `Base64`, and then sent. The data is structured in the following manner:

```yaml
{
    "action": "getAccount", // or getIdentity
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "dappName": "dapp Name",
        "dappIcon": "dapp Icon"
    }
}
```

Data specification for the fields mentioned above-

|   Field  | Data type |       Description       |
| :------: | :-------: | :---------------------: |
|  action  |   string  |      Operation type     |
| dappName |   string  |        dApp name        |
| dappIcon |   string  | dApp icon resource link |

The data set that the wallet returns, after `URI` and `Base64` decoding, has the following structure:

```yaml
{
    "action": "getAccount", // or getIdentity
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "error": 0,
    "desc": "SUCCESS",
    "result": "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ"  // or  "did:ont:AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ"
}
```

### Login

The login request that the `dApp` sends to the wallet is first encoded in `URI` and `Base64`, and then sent. The data is structured in the following manner:

```yaml
{
    "action": "login",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "dappName": "dapp Name",
        "dappIcon": "dapp Icon",
        "message": "helloworld"
    }
}
```

Data specification for the fields mentioned above-

| Fields   | Data type | Description                                                                                                              |
| -------- | --------- | ------------------------------------------------------------------------------------------------------------------------ |
| action   | string    | Operation type                                                                                                           |
| type     | string    | Specifying the login method. ONT ID login is specified using "ontid", and wallet address login is specified as "address" |
| dappName | string    | dApp name                                                                                                                |
| dappIcon | string    | dApp icon resource link                                                                                                  |
| message  | string    | Randomly generated, used for identity verification                                                                       |

The wallet's response to the login request is of the following format after decoding:

***Success response***

```yaml
{
    "action": "login",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "error": 0,
    "desc": "SUCCESS",
    "result": {
        "type": "ontid or account",
        "user": "did:ont:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz or AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz",
        "message": "helloworld",
        "publickey": "0205c8fff4b1d21f4b2ec3b48cf88004e38402933d7e914b2a0eda0de15e73ba61",
        "signature": "01abd7ea9d79c857cd838cabbbaad3efb44a6fc4f5a5ef52ea8461d6c055b8a7cf324d1a58962988709705cefe40df5b26e88af3ca387ec5036ec7f5e6640a1754"
    }
}
```

***Failure response***

```yaml
{
  "action": "login",
  "version": "v1.0.0",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 80001,
  "desc": "PARAMS ERROR",
  "result": 1
}
```

Data specification for the fields mentioned above-

| Field     | Data type | Description                                                                                                              |
| --------- | --------- | ------------------------------------------------------------------------------------------------------------------------ |
| action    | string    | Operation type                                                                                                           |
| result    | string    | The result to be returned                                                                                                |
| type      | string    | Specifying the login method. ONT ID login is specified using "ontid", and wallet address login is specified as "address" |
| user      | string    | The account used for signature, ONT ID or wallet address                                                                 |
| message   | string    | Randomly generated, used for identity verification                                                                       |
| publickey | string    | Account's public key                                                                                                     |
| signature | string    | User's signature                                                                                                         |

### Message signature

The structure remains the same as the login request, with the difference being that `dApp` name and icon are not needed. The request is encoded in `URI` and `Base64`, and then sent to the wallet.

```yaml
{
    "action": "signMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "message": "helloworld"
    }
}
```

Data specification for the fields mentioned above-

| Field   | Data type | Description                                                                                                   |
| ------- | --------- | ------------------------------------------------------------------------------------------------------------- |
| action  | string    | Operation type                                                                                                |
| type    | string    | Specifying the access method. ONT ID is specified using "ontid", and wallet address is specified as "address" |
| message | string    | Randomly generated, used for identity verification                                                            |

The wallet's success response to the request is of the following format after decoding:

```yaml
{
    "action": "signMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "error": 0,
    "desc": "SUCCESS",
    "result": {
        "type": "ontid or address",
        "user": "did:ont:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz or AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz",
        "message": "helloworld",
        "publickey": "0205c8fff4b1d21f4b2ec3b48cf88004e38402933d7e914b2a0eda0de15e73ba61",
        "signature": "01abd7ea9d79c857cd838cabbbaad3efb44a6fc4f5a5ef52ea8461d6c055b8a7cf324d1a58962988709705cefe40df5b26e88af3ca387ec5036ec7f5e6640a1754"
    }
}
```

### Contract invocation

Different invocation methods can be chosen using the `action` parameter. The available options are:

| Parameter value    | Function                                                                                       |
| ------------------ | ---------------------------------------------------------------------------------------------- |
| invoke             | Normal process                                                                                 |
| invokeRead         | Pre-execute the contract, the user does not need to sign, the result is returned to the `dApp` |
| invokePasswordFree | Invoke without the need of authentication, user does not need to enter password                |

{% hint style="info" %}
The `invokePasswordFree` function can be used for scenarios a contract needs to be invoked without prompting the user to enter their password. For example, games that stake money at regular intervals. Though, the use still needs to enter password once.
{% endhint %}

The platform only trusts fixed methods and parameters, and not all the methods that are part of the contract. After authentication, the transaction parameters are saved as `((InvokeCode)txs[0]).code`

{% hint style="success" %}
If another request that requires the same data is submitted, the user does not need to enter the password again, and the smart contract does not need to be pre-executed on more time.
{% endhint %}

{% hint style="danger" %}
When the user exits the `dApp`, please ensure that the parameters and the private key data are cleared from the memory.
{% endhint %}

#### dApp sends an invocation request

The data set of the request is encoded in `URI` and `Base64` and sent out. The structure is:

```yaml
{
    "action": "invoke",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "invokeConfig": {
            "contractHash": "16edbe366d1337eb510c2ff61099424c94aeef02",
            "functions": [{
                "operation": "method name",
                "args": [{
                    "name": "arg0-list",
                    "value": [true, 100, "Long:100000000000", "Address:AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ", "ByteArray:aabb", "String:hello", [true, 100], {
                        "key": 6
                    }]
                }, {
                    "name": "arg1-map",
                    "value": {
                        "key": "String:hello",
                        "key1": "ByteArray:aabb",
                        "key2": "Long:100000000000",
                        "key3": true,
                        "key4": 100,
                        "key5": [100],
                        "key6": {
                            "key": 6
                        }
                    }
                }, {
                    "name": "arg2-str",
                    "value": "String:test"
                }]
            }],
            "payer": "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ",
            "gasLimit": 20000,
            "gasPrice": 500
        }
    }
}
```

{% hint style="info" %}
Base58 addresses such as `AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ` can be assigned to the `%address` parameter, and the wallet will automatically assign it as the wallet's asset address. If the parameters contain an `%ontid`, the wallet will also automatically assign it to the wallet's `ONT ID` address.
{% endhint %}

#### Wallet responds to the invocation request

First the wallet carries out URI and Base64 decoding. And then,

1. Wallet **initiates** a transaction
2. Wallet carries out user **authentication** and **signature**
3. The transaction is **pre-executed**
4. Wallet receives **user confirmation**
5. The transaction is **transmitted** onto the chain
6. Transaction **hash** is returned to the `dApp`

The success response sent to the `dApp` is:

```yaml
{
  "action": "invoke",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 0,
  "desc": "SUCCESS",
  "result": "tx hash"
}
```

The failure response sent to the `dApp` is:

```yaml
{
  "action": "invoke",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 80001,
  "desc": "SEND TX ERROR",
  "result": ""
}
```

#### Pre-executing transactions

The amount of `ONT` and `ONG` that the user is going to expend in the transaction can be determined from the `notify` response, which is a result of the pre-execution.

A connection must be established with the following nodes:

* **MainNet** - <http://dappnode3.ont.io/>
* **TestNet** - <http://polaris5.ont.io/>

{% hint style="info" %}
It is advised to first completely analyze the `notify` response before making a judgement pertaining to a transaction, as there may be multiple transfers or events taking place. The nature of the token (`ONT` or `ONG`) can be determined from the contract address, while the `transfer` method and recipient can be determined later.
{% endhint %}

```yaml
{
    "Notify": [{
        "States": ["transfer", "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ", "AecaeSEBkt5GcBCxwz1F41TvdjX3dnKBkJ", 1],
        "ContractAddress": "0100000000000000000000000000000000000000"
    }],
    "State": 1,
    "Gas": 20000,
    "Result": "01"
}
```

## dAPI provider SDK integration

`dAPI provider SDK` aids communication between `Android webview` and a web based `dApp`. It encapsulates a few methods for `webview`. Separate details with respect to [Android](https://github.com/ontio-cyano/cyano-android-sdk) and [iOS](https://github.com/ontio-cyano/cyano-ios-sdk) platforms are available for reference.

#### Android SDK sample code

```java
//init
CyanoWebView cyanoWebView=new CyanoWebView(context);
cyanoWebView.loadUrl(url);

//Action handle
cyanoWebView.getNativeJsBridge().setHandleGetAccount(new NativeJsBridge.HandleGetAccount() {
            @Override
            public void handleAction(String data) {
              /* TODO
               * 1.Send wallet address to webView
               * com.alibaba.fastjson.JSONObject reqJson = JSON.parseObject(data);
               * String action=reqJson.getString("action");
               * String version=reqJson.getString("version");
               * String id=reqJson.getString("id");
               * cyanoWebView.sendSuccessToWeb(action,version, id, *wallet address*);
               */
            }
    });

cyanoWebView.getNativeJsBridge().setHandleInvoke(new NativeJsBridge.HandleInvoke() {
            @Override
            public void handleAction(String data) {
              /* TODO
               * 1. Password input prompt, resolve wallet account, build transaction using the data, carry out signature, pre-execute, note the processing time
               * 
               * 2. Analyze the pre-execution notify reseponse, display transaction fees, if the result contains the contract address determine ONT/ONT, display recipient address and transfer amount
               * 
               * 3. Transmit the transaction onto the chain after user confirmation
               * 
               * 4. Send the transaction hash to webview
               *
               * com.alibaba.fastjson.JSONObject reqJson = JSON.parseObject(data);
               * String action=reqJson.getString("action");
               * String version=reqJson.getString("version");
               * String id=reqJson.getString("id");
               * cyanoWebView.sendSuccessToWeb(action,version, id, 交易 hash);
               */
            }
    });

cyanoWebView.getNativeJsBridge().setHandleInvokeRead(new NativeJsBridge.HandleInvokeRead() {
        @Override
        public void handleAction(String data) {
               /* TODO
                * 1. Build transaction using the data, note the processing time
                * 
                * 2 Send the pre-execution results to webview
                * com.alibaba.fastjson.JSONObject reqJson = JSON.parseObject(data);
                * String action=reqJson.getString("action");
                * String version=reqJson.getString("version");
                * String id=reqJson.getString("id");
                * cyanoWebView.sendSuccessToWeb(action,version, id, 预知行结果);
                */
        }
});


cyanoWebView.getNativeJsBridge().setHandleInvokePasswordFree(new NativeJsBridge.HandleInvokePasswordFree() {
        @Override
        public void handleAction(String data, String message) {
          /* TODO
           * 1. Executing for the first time is the same as action : invoke, both the password and the message are saved
           * 
           * 2. When the same request arrives for the second time, use the saved password for signature and fetch pre-execution result
           * 
           * 3. The pre-execution results need not display for the user to confirmation
           * 
           * 4. Send the transaction hash to the webview
           * com.alibaba.fastjson.JSONObject reqJson = JSON.parseObject(data);
           * String action=reqJson.getString("action");
           * String version=reqJson.getString("version");
           * String id=reqJson.getString("id");
           * cyanoWebView.sendSuccessToWeb(action,version, id, 交易hash);
           */
        }
});

//response
Map map = new HashMap<>();
map.put("action", "");
map.put("error", 0);
map.put("desc", "SUCCESS");
map.put("result", message);
cyanoWebView.sendBack(Base64.encodeToString(Uri.encode(JSON.toJSONString(map)).getBytes(), Base64.NO_WRAP));
```

#### iOS SDK sample code

```objectivec
RNJsWebView * webView = [[RNJsWebView alloc]initWithFrame:CGRectZero];
[webView setURL:@""];

[webView setGetAccountCallback:^(NSDictionary *callbackDic) {

}];


[webView setInvokeTransactionCallback:^(NSDictionary *callbackDic) {

}];

[webView setInvokeReadCallback:^(NSDictionary *callbackDic) {

}];


NSDictionary *params = @{
                         @"action":@"",
                         @"version":@"v1.0.0",
                         @"error":@0,
                         @"desc":@"SUCCESS",
                         @"result":@""
                         };
[webView sendMessageToWeb:params];
```

## Code base for reference

|                                              **Signature verification methods**                                              |                                                     **Transaction event query methods**                                                    |                         **Cyano Wallet**                        |                      **dAPI - Mobile provider SDK**                     | **dAPI - Mobile client SDK**                                |
| :--------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------: | :---------------------------------------------------------------------: | ----------------------------------------------------------- |
| [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/interface.md#%E7%AD%BE%E5%90%8D%E9%AA%8C%E7%AD%BE) | [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/basic.md#%E4%B8%8E%E9%93%BE%E4%BA%A4%E4%BA%92%E6%8E%A5%E5%8F%A3) | [Cyano - Android](https://github.com/ontio-cyano/cyano-android) | [Cyano - Android SDK](https://github.com/ontio-cyano/cyano-android-sdk) | [Cyano Bridge](https://github.com/ontio-cyano/cyano-bridge) |
|               [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/ecdsa.crypto.test.ts)               |                        [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/websocket.test.ts)                       |     [Cyano - iOS](https://github.com/ontio-cyano/cyano-ios)     |     [Cyano - iOS SDK](https://github.com/ontio-cyano/cyano-ios-sdk)     |                                                             |


# QR code mechanism

Scanning QR codes

This section serves to illustrate how wallets can employ the QR code scanning feature to carry out tasks such as login, smart contract invocation, and other services.

There are two parties that are involved in the process:

* The `dApp` :  Blanket term that represents`dApps` developed for the users of Ontology ecosystem.
* The `Provider`: Wallets that support `dAPI` , and adhere to it's specifications.

## Interaction process

A dApp provides a QR code and the user scans it using the wallet. The QR code mechanism currently supports two functions: login and contract invocation.

### Login by scanning QR code

![](/files/-LvPYVGiR6Nj5rLpvWGM)

The process flow is as follows-

1. Wallet scans the QR code provided by the `dApp`.
2. `Provider` fetches the `callback URL` and the verification message, carries out user authentication and signature, and the transaction is carries out using the `dApps` callback address.
3. The `dApp` back end carries out signature verification and returns the result to the wallet.

### Invoke smart contract using QR code

![](/files/-LvskNo6m247YTTuJepu)

The process flow is as follows-

1. Wallet scans the QR code provided by the `dApp`.
2. Wallet initiates a transaction, the user signs it, the transaction is pre-executed, the user provides confirmation, the information is transmitted on to the chain, and finally the transaction `hash` is returned to the `dApp` back end using the callback address provided.
3. `dApp` back end uses the transaction `hash` to query the successful contract execution and transaction details.

## dAPI protocol usage

The following scenarios can be realized by integrating the dAPI -

### Login

Authentication is carried out by scanning the QR code from the wallet. The wallet fetches login parameters, carries out signature authorization and sends them to the `dApp` back end.

```yaml
{
    "action": "login",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "dappName": "dapp Name",
        "dappIcon": "dapp Icon",
        "message": "helloworld",
        "expire": 1546415363, # QR Code expire time
        "callback": "http://101.132.193.149:4027/blockchain/v1/common/test-onto-login"
    }
}
```

| Field    | Data type | Description                                                                                                      |
| -------- | --------- | ---------------------------------------------------------------------------------------------------------------- |
| action   | string    | States the function performed by the QR code, Login to be defined as "login" and contract invocation as "invoke" |
| id       | string    | Serial number (optional)                                                                                         |
| type     | string    | Login method used, ONT ID login to be set as "ontid" and wallet address login to be set as "address"             |
| dappName | string    | Name of the dApp                                                                                                 |
| dappIcon | string    | dApp icon resource link                                                                                          |
| message  | string    | Randomly generated message for identity verification                                                             |
| expire   | long      | Unix time stamp for when the QR code expires (optional)                                                          |
| callback | string    | Callback URL to communicate with the dApp back end                                                               |

#### dApp back end's return interface

Here's the post method message structure:

```yaml
# method:post
{
    "action": "login",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "user": "did:ont:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz or AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz",
        "message": "helloworld",
        "publickey": "0205c8fff4b1d21f4b2ec3b48cf88004e38402933d7e914b2a0eda0de15e73ba61",
        "signature": "01abd7ea9d79c857cd838cabbbaad3efb44a6fc4f5a5ef52ea8461d6c055b8a7cf324d1a58962988709705cefe40df5b26e88af3ca387ec5036ec7f5e6640a1754"
    }
}
```

| Field     | Data type | Description                                                                                                  |
| --------- | --------- | ------------------------------------------------------------------------------------------------------------ |
| action    | string    | Operation type                                                                                               |
| id        | string    | Serial number (optional)                                                                                     |
| params    | string    | Parameters required by the method                                                                            |
| type      | string    | Login method used, "ontid" if ONT ID is used to login and "address" when the wallet address is used to login |
| user      | string    | Identifier of the account that is used for signature                                                         |
| message   | string    | Randomly generated message for identity verification                                                         |
| publickey | string    | Account's public key                                                                                         |
| signature | string    | Digital signature                                                                                            |

If the transaction was successful, the s**uccess message** is sent in response.

```yaml
{
  "action": "login",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 0,
  "desc": "SUCCESS",
  "result": true
}
```

Otherwise, the **failure message** is sent in response.

```yaml
{
  "action": "login",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 80001,
  "desc": "PARAMS ERROR",
  "result": 1
}
```

### Message Signature

Message signature is essentially the same as login protocol, except that the `dApp` name and the icon are not a part of the request that is sent.

The structure of the signature request sent by the `dApp` after `URI` and `Base64` encoding are as follows:

```yaml
{
    "action": "signMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "message": "helloworld",
        "ishex": false
        "callback": "http://101.132.193.149:4027/blockchain/v1/common/test-onto-login"
    }
}
```

Or when multiple messages are signed:

```yaml
{
    "action": "signMultiMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "message": ["aabbccdd"],
        "ishex": true
        "callback": "http://101.132.193.149:4027/blockchain/v1/common/test-onto-login"
    }
}
```

| Field    | Data type | Description                                                                                         |
| -------- | --------- | --------------------------------------------------------------------------------------------------- |
| action   | string    | Operation type                                                                                      |
| type     | string    | Login method used, "ontid" if ONT ID is used to login and "address" when the wallet address is used |
| message  | string    | Randomly generated message for identity verification                                                |
| ishex    | bool      | Whether the message is a hex code                                                                   |
| callback | string    | Callback URL to communicate with the dApp back end                                                  |

The response that the wallet sends back to the `dApp`, after `URI` and `Base 64` encoding, is structured as follows:

```yaml
# method: post
{
    "action": "signMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "error": 0,
    "desc": "SUCCESS",
    "result": {
        "type": "ontid or address",
        "user": "did:ont:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz or AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz",
        "message": "helloworld",
        "publickey": "0205c8fff4b1d21f4b2ec3b48cf88004e38402933d7e914b2a0eda0de15e73ba61",
        "signature": "01abd7ea9d79c857cd838cabbbaad3efb44a6fc4f5a5ef52ea8461d6c055b8a7cf324d1a58962988709705cefe40df5b26e88af3ca387ec5036ec7f5e6640a1754"
    }
}
```

{% hint style="info" %}
If the action is "multimessage" the response sent back to the `dApp` is an array
{% endhint %}

### Contract Invocation

A payment operation also falls under the category of contract invocation, adopting a uniform protocol standard. The standard can be defined as follows:

```yaml
{
    "action": "invoke",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "login": true,
        "callback": "http://101.132.193.149:4027/invoke/callback",
        "qrcodeUrl": "http://101.132.193.149:4027/qrcode/AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ"
    }
}
```

| Field     | Data type | Description                                                                        |
| --------- | --------- | ---------------------------------------------------------------------------------- |
| action    | string    | Operation type, Login to be defined as "login" and contract invocation as "invoke" |
| qrcodeUrl | string    | Address for QR code parameters                                                     |
| callback  | string    | The callback address to send the transaction `hash` to the `dApp` back end         |

The data obtained from the `qrcodeURL` link's `GET` method is as follows-

```yaml
{
    "action": "invoke",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "invokeConfig": {
            "contractHash": "16edbe366d1337eb510c2ff61099424c94aeef02",
            "functions": [{
                "operation": "method name",
                "args": [{
                    "name": "arg0-list",
                    "value": [true, 100, "Long:100000000000", "Address:AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ", "ByteArray:aabb", "String:hello", [true, 100], {
                        "key": 6
                    }]
                }, {
                    "name": "arg1-map",
                    "value": {
                        "key": "String:hello",
                        "key1": "ByteArray:aabb",
                        "key2": "Long:100000000000",
                        "key3": true,
                        "key4": 100,
                        "key5": [100],
                        "key6": {
                            "key": 6
                        }
                    }
                }, {
                    "name": "arg2-str",
                    "value": "String:test"
                }]
            }],
            "payer": "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ",
            "gasLimit": 20000,
            "gasPrice": 500
        }
    }
}
```

{% hint style="info" %}
Base58 addresses such as `AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ` can be assigned to the `%address` parameter, and the wallet will automatically assign it as the wallet's asset address. If the parameters contain an `%ontid`, the wallet will also automatically assign it to the wallet's `ONT ID` address.
{% endhint %}

The wallet initiates a transaction, the user authenticates and signs it, the transaction is pre-executed, issued, and then the transaction `hash` is sent to the `callback URL` using `POST` method.

The success message has the following structure:

```yaml
{
  "action": "invoke",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 0,
  "desc": "SUCCESS",
  "result": "tx hash"
}
```

And the failure message is as follows:

```yaml
{
  "action": "invoke",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 80001,
  "desc": "SEND TX ERROR",
  "result": 1
}
```

#### Pre-executing a transaction

Pre-executing a transaction is optional. One of the main functions is serves is informing the user how much `ONT` or `ONG` is involved in a particular transaction. The `Notify` message that is returned upon pre-execution can deliver the information regarding the amount of `ONT/ONG` the user will spend for a particular transaction in terms of transaction costs.

{% hint style="info" %}
The `Notify` message needs to be parsed to make a judgement, because a transaction may have multiple transfer or smart contract events. If the other contract events don't need to handled, then the nature of transferred tokens can be judged from the address i.e. `ONT/ONG` and the `transfer` method along with the sender.

It is also advised that the the sender and `amount` should be displayed on the `UI`. There is a transaction fee which roughly equals to 0.01`ONG`
{% endhint %}

If the pre-execution is a success the response from the node is:

```yaml
{
  "Action": "sendrawtransaction",
  "Desc": "SUCCESS",
  "Error": 0,
  "Result": {
                "Notify": [{
                    "States": ["transfer", "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ", "AecaeSEBkt5GcBCxwz1F41TvdjX3dnKBkJ", 1],
                    "ContractAddress": "0100000000000000000000000000000000000000"
                }],
                "State": 1,
                "Gas": 20000,
                "Result": "01"
   },
  "Version": "1.0.0"
}
```

But if it fails, the `Error` value would be greater than 0.

## Code for reference

|                                              **Signature verification methods**                                              |                                                     **Transaction event query methods**                                                    |                         **Cyano Wallet**                        |                      **dAPI - Mobile provider SDK**                     | **dAPI - Mobile client SDK**                                |
| :--------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------: | :---------------------------------------------------------------------: | ----------------------------------------------------------- |
| [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/interface.md#%E7%AD%BE%E5%90%8D%E9%AA%8C%E7%AD%BE) | [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/basic.md#%E4%B8%8E%E9%93%BE%E4%BA%A4%E4%BA%92%E6%8E%A5%E5%8F%A3) | [Cyano - Android](https://github.com/ontio-cyano/cyano-android) | [Cyano - Android SDK](https://github.com/ontio-cyano/cyano-android-sdk) | [Cyano Bridge](https://github.com/ontio-cyano/cyano-bridge) |
|               [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/ecdsa.crypto.test.ts)               |                        [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/websocket.test.ts)                       |     [Cyano - iOS](https://github.com/ontio-cyano/cyano-ios)     |     [Cyano - iOS SDK](https://github.com/ontio-cyano/cyano-ios-sdk)     |                                                             |


# Wake call mechanism

Applications wake the wallet service

This section aims at providing a guide to how the wallet uses the wake up service to support login and contract invocation functionality.

For wallet implementation, please refer to the Cyano open source wallet Github [repository](https://github.com/ontio-cyano). For application wake up call implementation, refer to this [demo](https://github.com/ontio-cyano/android-app-demo).

The two parties involved in this process are:

* The `dApp` :  Blanket term that represents`dApps` developed for the users of Ontology ecosystem.
* The `Provider`: Wallets that support `dAPI` , and adhere to it's specifications.

## Interaction process

`dApp` data request `URI scheme`:

```javascript
ontprovider://ont.io?param=Base64.encode(Uri.encode({the json data}.toString()))
```

### dApp sends a login request

![](/files/-LwHH0_-2UKqbwoZPJvI)

1. `dApp` sends the wake up call to the wallet.
2. Wallet receives the `callback URL` the information to be verified. The user authenticates and signs, and the wallet invokes the `dApp` back end's callback method.
3. `dApp` back end verifies the signature.

### dApp sends out the contract invocation request

![](/files/-LwHH0_1osmYIllh2KZy)

1. dApp wakes the wallet
2. The wallet initiates a transaction, the user authenticates and signs, the wallet pre-executes the transaction, it is transmitted to the chain and finally the transaction `hash` is returned to the `callback` address.
3. `dApp` back end can query the results of the transaction event using the transaction `hash`.

## dAPI protocol introduction

The requests sent by the dApp to the wallet to perform login and contract invocation functions are illustrated below.

### Login

After URI and Base64 encoding, the structure of the request is as follows:

```yaml
{
    "action": "login",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",    
    "params": {
        "type": "ontid or address",
        "dappName": "dapp Name",
        "dappIcon": "dapp Icon",
        "message": "helloworld",
        "callback": "http://127.0.0.1:80/login/callback"
    }
}
```

| Field    | Data type | Description                                                                                                  |
| -------- | --------- | ------------------------------------------------------------------------------------------------------------ |
| action   | string    | Operation type                                                                                               |
| type     | string    | Login method used, "ontid" if ONT ID is used to login and "address" when the wallet address is used to login |
| dappName | string    | Name of the dApp                                                                                             |
| dappIcon | string    | dApp icon resource link                                                                                      |
| message  | string    | Randomly generated message for identity verification                                                         |
| callback | string    | Callback URL to send information to after the user carries out signature                                     |

Wallet carries out the login process, URI and Base 64 encoding, signs the message, and sends the following message to the callback address using POST method:

```yaml
{
    "action": "login",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",    
    "params": {
        "type": "ontid or account",
        "user": "did:ont:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz",
        "message": "helloworld",
        "publickey": "0205c8fff4b1d21f4b2ec3b48cf88004e38402933d7e914b2a0eda0de15e73ba61",
        "signature": "01abd7ea9d79c857cd838cabbbaad3efb44a6fc4f5a5ef52ea8461d6c055b8a7cf324d1a58962988709705cefe40df5b26e88af3ca387ec5036ec7f5e6640a1754"
    }
}
```

| Fields    | Data type | Description                                                                                                  |
| --------- | --------- | ------------------------------------------------------------------------------------------------------------ |
| action    | string    | Operation type                                                                                               |
| params    | string    | The parameters needed by methods                                                                             |
| type      | string    | Login method used, "ontid" if ONT ID is used to login and "account" when the wallet address is used to login |
| user      | string    | Identifier of the account that is used for signature, say a wallet address or ONT ID                         |
| message   | string    | Randomly generated message for identity verification                                                         |
| publickey | string    | Account public key                                                                                           |
| signature | string    | Account digital signature                                                                                    |

#### dApp server callback interface

Success response after signature verification-

```yaml
{
  "action": "login",
  "version": "v1.0.0",  
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",  
  "error": 0,
  "desc": "SUCCESS",
  "result": true
}
```

Failure response after signature verification-

```yaml
{
  "action": "login",
  "version": "v1.0.0",  
  "error": 80001,
  "desc": "PARAMS ERROR",
  "result": 1
}
```

### Message signature

The signature protocol is essentially the same as login, only that the dApp name and icon need not be passed. The `dApp` sends a request with the following data, after `URI` and `Base64` encoding：

```yaml
{
    "action": "signMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "message": "helloworld"
    }
}
```

| Field   | Data type | Description                                                                                                                                    |
| ------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| action  | string    | Operation type                                                                                                                                 |
| type    | string    | Set to "ontid" if the login method is ONT ID, and "address" if the wallet address is used, set to "address" by default if nothing is specified |
| message | string    | Generated randomly, used for identity verification                                                                                             |

The wallet's response to the login request, sent after `URI` and `Base64` encoding is of the following form-

#### Success response

```yaml
{
    "action": "signMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "error": 0,
    "desc": "SUCCESS",
    "result": {
        "type": "ontid or address",
        "user": "did:ont:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz or AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz",
        "message": "helloworld",
        "publickey": "0205c8fff4b1d21f4b2ec3b48cf88004e38402933d7e914b2a0eda0de15e73ba61",
        "signature": "01abd7ea9d79c857cd838cabbbaad3efb44a6fc4f5a5ef52ea8461d6c055b8a7cf324d1a58962988709705cefe40df5b26e88af3ca387ec5036ec7f5e6640a1754"
    }
}
```

### Contract invocation

The data structure of the wake call that is sent to the wallet after URI and Base64 encoding is as follows:

```yaml
{
    "action": "invoke",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "login": true,
        "callback": "http://101.132.193.149:4027/invoke/callback",        
        "invokeConfig": {
            "contractHash": "16edbe366d1337eb510c2ff61099424c94aeef02",
            "functions": [{
                "operation": "method name",
                "args": [{
                    "name": "arg0-list",
                    "value": [true, 100, "Long:100000000000", "Address:AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ", "ByteArray:aabb", "String:hello", [true, 100], {
                        "key": 6
                    }]
                }, {
                    "name": "arg1-map",
                    "value": {
                        "key": "String:hello",
                        "key1": "ByteArray:aabb",
                        "key2": "Long:100000000000",
                        "key3": true,
                        "key4": 100,
                        "key5": [100],
                        "key6": {
                            "key": 6
                        }
                    }
                }, {
                    "name": "arg2-str",
                    "value": "String:test"
                }]
            }],
            "payer": "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ",
            "gasLimit": 20000,
            "gasPrice": 500
        }
    }
}
```

{% hint style="info" %}
A `Base58` address, for e.g., `AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ` \_\_can be used to fill the `%address` parameter. The wallet converts the `%address` to the wallet's asset address. If the argument contains the `%ontid`, the wallet converts it to the wallet's `ontid` address.
{% endhint %}

#### Pre-executing transactions

The `notify` result returned after pre-execution can be used to find out the token expended by the user in the particular transaction. (ONT/ONG)

{% hint style="info" %}
The `Notify` message needs to be parsed to make a judgement, because a transaction may have multiple transfer or smart contract events. If the other contract events don't need to handled, then the nature of transferred tokens can be judged from the address i.e. `ONT/ONG` and the `transfer` method along with the sender.
{% endhint %}

```yaml
{
    "Notify": [{
        "States": ["transfer", "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ", "AecaeSEBkt5GcBCxwz1F41TvdjX3dnKBkJ", 1],
        "ContractAddress": "0100000000000000000000000000000000000000"
    }],
    "State": 1,
    "Gas": 20000,
    "Result": "01"
}
```

## Code for reference

|                                              **Signature verification methods**                                              |                                                     **Transaction event query methods**                                                    |                         **Cyano Wallet**                        |                      **dAPI - Mobile provider SDK**                     | **dAPI - Mobile client SDK**                                |
| :--------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------: | :---------------------------------------------------------------------: | ----------------------------------------------------------- |
| [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/interface.md#%E7%AD%BE%E5%90%8D%E9%AA%8C%E7%AD%BE) | [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/basic.md#%E4%B8%8E%E9%93%BE%E4%BA%A4%E4%BA%92%E6%8E%A5%E5%8F%A3) | [Cyano - Android](https://github.com/ontio-cyano/cyano-android) | [Cyano - Android SDK](https://github.com/ontio-cyano/cyano-android-sdk) | [Cyano Bridge](https://github.com/ontio-cyano/cyano-bridge) |
|               [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/ecdsa.crypto.test.ts)               |                        [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/websocket.test.ts)                       |     [Cyano - iOS](https://github.com/ontio-cyano/cyano-ios)     |     [Cyano - iOS SDK](https://github.com/ontio-cyano/cyano-ios-sdk)     |                                                             |


# Stake

To be updated soon!


# Using ONT ID

Integrating ONT ID to centralized and decentralized systems

**ONT ID** can be integrated to centralized and decentralized systems alike to implement a decentralized identity and account mechanism with a rich variety of other functions. The Ontology framework is flexible in terms of the languages that are supported. There are several public [SDKs](https://docs.ont.io/developer-tools/sdk) that are available for the community to work and experiment with.

{% content-ref url="/pages/-LwHH-VWs1EEoLXAyGVg" %}
[ONT ID](/decentralized-identity-and-data/ontid)
{% endcontent-ref %}

{% hint style="success" %}
Developers can glance over [**ONT ID specifications**](/decentralized-identity-and-data/ontid/decentralized-identifiers/specification) to get a better understanding of the technical architecture.
{% endhint %}

The **ONT ID** protocol has been implemented on the Ontology chain using native smart contracts. API methods can be invoked to carry out **ONT ID** related actions such as registration, cancellation, attribute modification, etc. Follow the link below to navigate to the **ONT ID** contract API reference.

{% content-ref url="/pages/-M8n8zm\_vUsaCbzbhLxX" %}
[ONT ID Contract API](/developer-tools/api/ont-id-contract-api)
{% endcontent-ref %}

Integrating the **ONT ID** framework is a simple enough process. The major steps have been illustrated below.

## Use OWallet tool to create a new wallet

**OWallet** is a wallet tool that can be used to work with Ontology wallets and carry out staking on the Ontology network. You can download the latest version of OWallet by following [this](https://github.com/ontio/OWallet/releases) link.

Download and install OWallet, and then in the main 'wallets' window click on the '+' icon. Follow the prompts to create a new Ontology wallet. You'll need this perform any interactions with the Ontology chain.

You'll be able to see your wallet address on the top after successfully creating your wallet and exporting the `.dat` wallet file.

{% hint style="info" %}
We encourage and value any contributions that are made by community developers to the SDKs for other languages. Support for **ONT ID 2.0** allows the developer community to integrate this safe and decentralized identity management protocol to the new applications swiftly and conveniently.
{% endhint %}

## Fetch testnet ONG

Performing on-chain actions consumes `ONG` in the form of gas/transaction costs. Follow [**this**](https://developer.ont.io/applyOng) link to apply for testnet ONG that will come in handy when developing on and working within the Ontology ecosystem. Use your wallet address to apply for testnet ONG tokens on the portal.

## Set up SDK environment

{% hint style="info" %}
Currently, the [**Java**](https://github.com/ontio/ontology-java-sdk)**,** [**Golang**](https://github.com/ontio/ontology-go-sdk)**,** and [**Typescript**](https://github.com/ontio/ontology-ts-sdk) SDKs support the updated **ONT ID 2.0** specifications. For the rest of the SDKs that for now support **ONT ID 1.0** can be accessed using the link below.
{% endhint %}

{% content-ref url="/pages/-LwHH-WcLtHrtlsf2SEj" %}
[SDKs](/developer-tools/sdk)
{% endcontent-ref %}

After obtaining testnet ONG, you're all set to start working with the Ontology framework. The SDKs illustrated below can be used to implement ONT ID related functions. But first, we must set up the environment to use the SDK libraries in your project. Execute the commands specified to set up the SDK.

### Golang SDK

{% hint style="info" %}
Please ensure that you have the latest version of Go set up and running on your local machine.
{% endhint %}

#### 1. Clone the SDK library

```
git clone https://github.com/ontio/ontology-go-sdk.git
```

#### 2. Install dependencies

Run the following command to enable Go modules in your environment in case they aren't already enabled.

```go
export GO111MODULE="on"
```

{% hint style="info" %}
For **Windows OS**, configure the environment variables in system settings to enable Go modules.
{% endhint %}

And then run the following command to install the necessary dependencies.

```go
go mod vendor
```

### Java SDK

{% hint style="info" %}
Please confirm that you have the latest version of **Java** and **Maven** set up and running on your system.
{% endhint %}

#### 1. Clone the SDK library

```
git clone https://github.com/ontio/ontology-java-sdk.git
```

#### 2. Install dependencies&#x20;

```
mvn clean install
```

### TypeScript SDK

{% hint style="info" %}
Please ensure that you have a **NodeJS** and **TypeScript** environment set up and running on your local system (we'll be using `npm`)
{% endhint %}

#### 1. Clone the SDK library

```
git clone https://github.com/ontio/ontology-ts-sdk.git
```

#### 2. Install the necessary dependencies&#x20;

```
npm install
```

## Initialize and invoke SDK

Once the environment is set up, next up would be initializing the respective SDK. The process has been briefly described individually for each SDK using the testing package that contains several useful demos for reference. Roughly speaking the sequence is as follows:

1. **Instantiate** and **initialize** the SDK
2. **Create** a **wallet** object that will be used when executing methods and making API calls
3. **Create** a new **ONT** **ID** linked to the account
4. **Register** the action **on chain** by storing the **DID document** into the contract
5. **Add attributes** if necessary
6. **Fetch** ONT ID and respective **attribute** related **details**

All the sample code used below is used for the purpose of illustration and has been taken from test or demo files that come with the SDK. The name of the file has also been specified with each code snippet.

{% hint style="success" %}
Move the newly created wallet to the SDK main directory before proceeding to initialize the SDK
{% endhint %}

### Go SDK

One way to initialize an SDK instance would be:

```go
/* ontology-go-sdk/ont_sdk_test.go */

func Init() {
    testOntSdk = NewOntologySdk()
    testOntSdk.NewRpcClient().SetAddress("http://polaris1.ont.io") // Set RPC client address to testnet node address
    var err error
    var wallet *Wallet
    if !common.FileExisted("./wallet.dat") {// Checks if a wallet exists in the main directory
        fmt.Println("Wallet not found")
        }
    } else { 
        testWallet, err = testOntSdk.OpenWallet("./wallet.dat") // Imports and uses wallet for the SDK instance
        if err != nil {
            fmt.Println("[OpenWallet] error:", err)
            return
        }
    }
}
```

Next we can generate an ONT ID and start working with it. The sample code illustrates how to execute certain basic operations.

```go
/* ontology-go-sdk/native_contract_test.go */

func TestOntId(t *testing.T) {
    Init() // Initializing the SDK

    /* Generating a new ONT ID */

    testIdentity, err := testWallet.NewDefaultSettingIdentity(testPasswd) // Generating a new ONT ID with the default settings
    if err != nil {
        t.Errorf("TestOntId NewDefaultSettingIdentity error:%s", err)
        return
    }
    _, err = testOntSdk.Native.OntId.RegIDWithPublicKey(testGasPrice, testGasLimit, testDefAcc, testIdentity.ID, testDefAcc) // Sends transaction to register ONT ID with the wallet account
    if err != nil {
        t.Errorf("TestOntId RegIDWithPublicKey error:%s", err)
        return
    }
    testOntSdk.WaitForGenerateBlock(30 * time.Second) // Timeout till next block

    /* Add attributes for the ONT ID */

    attributes := []*DDOAttribute{ // Define DDO attributes for the ONT ID
        &DDOAttribute{
            Key:       []byte("1"),
            Value:     []byte("2"),
            ValueType: []byte("3"),
        },
    }

    /* Add attributes to the DDO document in the ONT ID contract on chain */

    _, err = testOntSdk.Native.OntId.AddAttributesByIndex(testGasPrice, testGasLimit, testDefAcc, testIdentity.ID, attributes, 1, testDefAcc) // Sending the transaction
    if err != nil {
        t.Errorf("TestOntId AddAttributesByIndex error:%s", err)
        return
    }
    testOntSdk.WaitForGenerateBlock(30 * time.Second) // Timeout till next block

    /* Fetch details for particular attribute */

    attribute, err := testOntSdk.Native.OntId.GetAttributeByKey(testIdentity.ID, "1") // Method call to pass the attribute key
    if err != nil {
        t.Errorf("TestOntId GetAttributeByKey error:%s", err)
        return
    }
    fmt.Printf("TestOntId GetAttributeByKey:%+v\n", attribute)

    /* Fetch DDO for particular ONT ID */

    document, err := testOntSdk.Native.OntId.GetDocumentJson(testIdentity.ID) // Method call to pass the ONT ID
    if err != nil {
        t.Errorf("TestOntId GetDocumentJson error:%s", err)
        return
    }
    fmt.Printf("TestOntId GetDocumentJson:%+v\n", string(document))
    return
}
```

The addresses for the currently active **Polaris testnet** nodes can be found [**here**](https://docs.ont.io/ontology-node/interact-with-public-node#using-public-nodes).

For a more detailed and practical test case, you can refer to `cred_test.go`.

{% hint style="info" %}
Follow [**this**](https://github.com/ontio/ontology-go-sdk#25-ont-id-api) link to find the **Go SDK** reference on **Github.**
{% endhint %}

### Java SDK

To instantiate and initialize an SDK object:

```java
/* src/test/java/com/github/ontio/smartcontract/nativevm/NativeOntIdTxTest.java */

public void setUp() throws Exception {
        ontSdk = OntSdk.getInstance();
        // Set testnet node URL
        ontSdk.setRestful(OntSdkTest.URL);
        ontSdk.setDefaultConnect(ontSdk.getRestful());
        // Open wallet with SDK object
        ontSdk.openWalletFile(walletFile);
//      ontSdk.setSignatureScheme(SignatureScheme.SHA256WITHECDSA);
        payer = new Account(SignatureScheme.SHA256WITHECDSA);
        payerAcct = payer;
        // Generate ONT ID
        identity = ontSdk.getWalletMgr().createIdentity(password);
        account = new com.github.ontio.account.Account(SignatureScheme.SHA256WITHECDSA);
        // Record action on chain
//      ontSdk.nativevm().ontId().sendRegister(identity,password,payerAcct,ontSdk.DEFAULT_GAS_LIMIT,0);
        Thread.sleep(6000);

    }
```

The above method is defined in the `NativeOntIdTest` class. You can refer to the source file and run the test respective test cases.

Sample code that illustrates basic operations:

```java
/* src/test/java/com/github/ontio/smartcontract/nativevmNativeOntIdTxTest.java */

public void sendRegister() throws Exception {

        // Record ONT ID allocation action on chain 
        Transaction tx = ontSdk.nativevm().ontId().makeRegister(identity.ontid, account.serializePublicKey(), payer.getAddressU160().toBase58(), ontSdk.DEFAULT_GAS_LIMIT, 0);
        ontSdk.addSign(tx, account);
        ontSdk.addSign(tx, payerAcct);
        ontSdk.getConnect().sendRawTransaction(tx);

        Identity identity2 = ontSdk.getWalletMgr().createIdentity(password);

        ontSdk.nativevm().ontId().sendRegister(identity2.ontid, account, payerAcct, ontSdk.DEFAULT_GAS_LIMIT, 0);

        //Adding attributes to an ONT ID
        Identity identity3 = ontSdk.getWalletMgr().createIdentity(password);
        Attribute[] attributes = new Attribute[1];
        attributes[0] = new Attribute("key2".getBytes(), "value2".getBytes(), "type2".getBytes());
        ontSdk.nativevm().ontId().sendRegisterWithAttrs(identity3.ontid, attributes, account, payerAcct, ontSdk.DEFAULT_GAS_LIMIT, 0);

        Thread.sleep(6000);

        //Fetch DDO object from contract
        String ddo = ontSdk.nativevm().ontId().sendGetDDO(identity.ontid);
        Assert.assertTrue(ddo.contains(identity.ontid));

        String dd02 = ontSdk.nativevm().ontId().sendGetDDO(identity3.ontid);
        Assert.assertTrue(dd02.contains("key2"));

        String keystate = ontSdk.nativevm().ontId().sendGetKeyState(identity.ontid, 1);
        Assert.assertNotNull(keystate);

        //merkleproof
        Object merkleproof = ontSdk.nativevm().ontId().getMerkleProof(tx.hash().toHexString());
        boolean b = ontSdk.nativevm().ontId().verifyMerkleProof(JSONObject.toJSONString(merkleproof));
        Assert.assertTrue(b);

        //claim
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("Issuer", identity.ontid);
        map.put("Subject", identity2.ontid);

        Map clmRevMap = new HashMap();
        clmRevMap.put("typ", "AttestContract");
        clmRevMap.put("addr", identity.ontid.replace(Common.didont, ""));

        String claim = ontSdk.nativevm().ontId().createOntIdClaim(identity.ontid, account, "claim:context", map, map, clmRevMap, System.currentTimeMillis() / 1000 + 100000);
        boolean b2 = ontSdk.nativevm().ontId().verifyOntIdClaim(claim);
        Assert.assertTrue(b2);
    }
```

You can refer to the `NativeOntIdTxTest.java` in the `test` directory of the SDK to find and experiment with the test class methods.

{% hint style="info" %}
Follow [**this**](https://github.com/ontio/documentation/blob/master/dev-website-docs/docs-en/SDKs/java-sdk-ontid.md) link to find the **Java SDK** reference on **Github.**
{% endhint %}

### TypeScript SDK

```typescript
/* test/newOntidContractTxBuilder.test.ts */

    // Generate ONT ID and send a transaction to record action on chain
    test('buildRegIDWithPublicKeyTx', async () => {
        const tx = NewOntidTxBuilder.buildRegIDWithPublicKeyTx(did1, pk1, gasPrice, gasLimit, address1);
        signTransaction(tx, privateKey1);
        const res = await socketClient.sendRawTransaction(tx.serialize(), false, true);
        console.log(res);
        expect(res.Error).toEqual(0);
    }, 100000);

    // Add attributes to an ONT ID document
    test('buildAddAttributeTx', async () => {
        const attr = new DDOAttribute();
        attr.key = 'hello2';
        attr.type = 'string',
        attr.value = 'world2';
        const tx = NewOntidTxBuilder.buildAddAttributeTx(did4, [attr], pk4, gasPrice, gasLimit, address4);
        signTransaction(tx, pri4);
        const res = await socketClient.sendRawTransaction(tx.serialize(), false, true);
        console.log(res);
        expect(res.Error).toEqual(0);
    }, 100000);

    // Fetch attribute information
    test('buildGetAttributesTx', async () => {
        const tx = NewOntidTxBuilder.buildGetAttributesTx(did4);
        const res = await socketClient.sendRawTransaction(tx.serialize(), true);
        console.log(res);
        expect(res.Error).toEqual(0);
    }, 100000);

    // Fetch document information
    test('buildGetDocumentTx', async () => {
        const ontid = 'did:ont:AN3iwgee5JKzZV99gknpdmQf5XUJJbQ7xQ';
        const doc = await NewOntidTxBuilder.getDocumentJson(ontid, 'http://polaris1.ont.io:20334');
        console.log(doc);
    }, 100000);
```

{% hint style="info" %}
Follow [**this**](https://github.com/ontio/documentation/blob/master/dev-website-docs/docs-en/SDKs/ts-sdk-ontid.md) link to find the **TypeScript SDK** reference on **Github.**
{% endhint %}

A wide variety of functions operations can be performed with ONT ID by calling the **public API** exposed from the native contract deployed on the Ontology chain. The **API reference** for the contract and the chain itself is available [**here**](https://docs.ont.io/developer-tools/api/)**.**


# Exchange Integration


# Exchange Docking Guide

There are two kinds of assets in ONT: native assets and contract assets. Native assets are ONT and ONG. When docking with the exchange, it mainly processes deposit and withdrawal of these two assets.

## Deploy Ontology Synchronization Node

There are two ways to deploy Ontology synchronization nodes:

### Get from source code

Clone ontology repository to **$GOPATH/src/github.com/ontio** directory

```
$ git clone https://github.com/ontio/ontology.git
```

Or

```
$ go get github.com/ontio/ontology
```

Use the third-party package management tool glide to manage the dependent libraries

```
$ cd $GOPATH/src/github.com/ontio/ontology
$ glide install
```

Compile source code with make

```
$ make
```

An executable program will be generated after a successful compilation (using `make all` command will generate sig server under 'tools' directory ）

* `ontology`: Node program/node control program provided by command line

### Get from release

[release page](https://github.com/ontio/ontology/releases)

### Server deployment

1. **Create wallet(not mandatory for sync node)**
   * Create the wallet file - wallet.dat that is required for nodes running through the CLI

     ```
     $ ./ontology account add -d
     Use default setting '-t ecdsa -b 256 -s SHA256withECDSA' 
     	signature algorithm: ecdsa 
     	curve: P-256 
     	signature scheme: SHA256withECDSA 
     Password:
     Re-enter Password:

     Index: 1
     Label: 
     Address: AWVNFw74G8Sx9vcxGbmh4gT54ayuwb3bcm
     Public key: 02c17cd91acf618d497f65f1fc4f52de7952c8b2337883f898dda887953cd29dd7
     Signature scheme: SHA256withECDSA

     Create account successfully.
     ```
   * Directory Structure

     ```
        $ tree
        └── ontology
            ├── ontology
            └── wallet.dat
     ```
2. **Start up node**

   start up command:

   `./ontology`

   By default, the node startup will close the websocket and the rest port. If you want to open above-mentioned ports, you can configure the following parameters:

   ```
   RESTFUL OPTIONS:
     --rest            Enable restful api server
     --restport value  Restful server listening port (default: 20334)
     
   WEB SOCKET OPTIONS:
     --ws            Enable websocket server
     --wsport value  Ws server listening port (default: 20335)
   ```

## Use CLI Client

### Security policy

Mandatory: The exchange must use a whitelist or firewall to block external server requests, otherwise there will be a serious security risk.

The CLI does not provide remote open/close wallet function and there is no verification process when opening the wallet. Therefore, the security policy needs to be set by the exchange based on its own situation. Since the wallet must remain open in order to process the users' withdrawal, from a security point of view, the wallet must be running on a separate server, and the exchange configures the firewall with reference to the following table.

|               | MainNet default port |
| ------------- | -------------------- |
| Rest Port     | 20334                |
| Websorcket    | 20335                |
| Json RPC port | 20336                |
| Node port     | 20338                |

### CLI instruction

#### Create wallet

The exchange needs to create an online wallet to manage user deposit address. A wallet is used to store account (including public and private keys), contract address and other information, which is the most important certificate for users to hold assets. It is important to keep wallet files and wallet passwords safe and prevent them from loss or disclosure. The exchange does not need to create a wallet file for each address. Usually a wallet file can store all the user's deposit addresses. You can also use a cold wallet (offline wallet) as a more secure storage.

```
$ ./ontology account add -d
Use default setting '-t ecdsa -b 256 -s SHA256withECDSA' 
	signature algorithm: ecdsa 
	curve: P-256 
	signature scheme: SHA256withECDSA 
Password:
Re-enter Password:

Index: 1
Label: 
Address: AWVNFw74G8Sx9vcxGbmh4gT54ayuwb3bcm
Public key: 02c17cd91acf618d497f65f1fc4f52de7952c8b2337883f898dda887953cd29dd7
Signature scheme: SHA256withECDSA

Create account successfully.
```

**The public and private key generation algorithms of ONT are consistent with NEO. The public key addresses of ONT and NEO corresponding to the same private key are the same.**

**Generate deposit address**

**Note: ONT and ONG address is case-sensitive**

A wallet can store multiple addresses, and the exchange needs to generate a deposit address for each user.

There are two ways to generate deposit addresses:

* When the user first deposits (ONT/ONG), the program dynamically creates the ONT address. Advantages: No manual creation of addresses is required. Disadvantages: It is inconvenient to back up the wallet.

To create an address dynamically, you can use the Java SDK's implementation and the program will return the created address. Please refer to Java SDK [Create account randomly](https://github.com/ontio/documentation/blob/master/exchangeDocs/Ontology%2BExchange%2BDocking%2BDocument.md#create-account-randomly).

* The exchange creates a batch of ONT addresses in advance and assigns the user an ONT address when the user deposits for the first time (ONT/ONG). Advantages: It is easy to back up wallet; disadvantages: Manually create ONT address when the address is insufficient.

  To create a batch of addresses, executing the ./ontology account add -n \[n] -w \[wallet file] command in the CLI. The -d bracket is an optional parameter and the default value is 1. -w specifies the wallet file and the default file is wallet.dat. For example, to create 100 addresses at one time:

```
$ ./ontology account add -n 100 -d -w wat.dat
Use default setting '-t ecdsa -b 256 -s SHA256withECDSA' 
	signature algorithm: ecdsa 
	curve: P-256 
	signature scheme: SHA256withECDSA 
Password:
Re-enter Password:

Index: 1
Label: 
Address: ATh1dt4pKZTASu45VeRChPi3iYmk8nYKJH
Public key: 03f8e59f0059d11dcec2902c44a9e7a2466adc9b25a61b1d94d2027d13f78ac45a
Signature scheme: SHA256withECDSA

Index: 2
Label: 
Address: AdYpqD8kn3NwBkkDktqfLfT8jJMCaD7BrB
Public key: 03e05424e711faa1591ee62a20648b45d8328f40c1ad5c479484501445fea62c50
Signature scheme: SHA256withECDSA

Index: 3
Label: 
Address: AY5hDhn2z8ND6F4JF9rQV1a4SDUT4aUr88
Public key: 03de554a6e3eea61aa9f78fa683ce9069ca8980a9f44b85eebe1d2c2e9a611875c
Signature scheme: SHA256withECDSA

....
```

## Process Asset Transactions

### Transaction docking program the exchange needs to develop

1. Monitor new blocks using CLI/API
2. Complete user deposit according to the transaction information
3. Store transaction records of exchanges

### User deposit

For user deposit, the exchange needs to understand the following:

* In general, due to the different strategies of each exchange, the balance in the exchange's deposit address may not equal to the user's balance in the exchange.
* Ontology address contains ONT and ONG assets. When processing the users' deposit, the exchange needs to judge the asset type so as not to mix up the ONT and ONG deposit.
* The Ontology wallet is a full node. To synchronize the blocks, the wallet needs to be online. You can view the current block height through the CLI command and judge the node status.

  ```
  $ ./ontology info curblockheight
  CurrentBlockHeight:2
  ```
* Transfers between users within the exchange do not need to go through the blockchain, so the exchange can directly modify the users' balance in the database. Only deposit and withdrawal need to go through the blockchain.

Example:

1. A user deposits tokens to the address - `TA8MoGmzS4T6g3T1CMGEVFiNGkZnn7ixw9`
2. Monitor block information by CLI `./ontology info block <block number | block hash>`

   ```
   $ ./ontology info block 209304
   {
      "Hash": "83a70a5380532ededb4f3d65bcd4d3a8cd52f7f87bf1863d68bada59b95133d4",
      "Header": {
         "Version": 0,
         "PrevBlockHash": "e63ede75d1a1784c150edd537b2b5439cc3893be909d5e6970b7baa8b39a5437",
         "TransactionsRoot": "24ac1b3dbecedbac41413ef4578769dd858aab42ccb60b2918c879b129edbf5d",
         "BlockRoot": "8a03e9f3e9adb8abde5b129ba5f833a3555719ffbbf3dd97a931450620a6bbf0",
         "Timestamp": 1528959514,
         "Height": 3016,
         "ConsensusData": 8772979148630824583,
         "ConsensusPayload": "",
         "NextBookkeeper": "AQGN8sEz2dycryR5BxLCQCPYiqKPN5BMnx",
         "Bookkeepers": [
            "0217c25948722c14c1a6fa8e06b78691e722f4598585805671b0beaa7fd6c7662b"
         ],
         "SigData": [
            "a6faf7a3fe356e36977c249f858b8f0a11b719ae310470948e374b69cfb4c3f3d295ac3e81244ebbfc13a4ea94c3deee132ee9ef0caa745b4b6eaf21aeb92c40"
         ],
         "Hash": "83a70a5380532ededb4f3d65bcd4d3a8cd52f7f87bf1863d68bada59b95133d4"
      },
      "Transactions": [
         {
            "Version": 0,
            "Nonce": 4023588455,
            "GasPrice": 0,
            "GasLimit": 30000,
            "Payer": "f72c773b346d3cdf9672fcf9d1a9e0daababa270",
            "TxType": 209,
            "Payload": {
               "Code": "00c66b14e98f4998d837fcdd44a50561f7f32140c7c6c2606a7cc814dd803188dcc41329b6e9faa775a6085269b5db376a7cc808e8030000000000006a7cc86c51c1087472616e736665721400000000000000000000000000000000000000010068164f6e746f6c6f67792e4e61746976652e496e766f6b65",
               "GasLimit": 0
            },
            "Attributes": [],
            "Sigs": [
               {
                  "PubKeys": [
                     "0217c25948722c14c1a6fa8e06b78691e722f4598585805671b0beaa7fd6c7662b"
                  ],
                  "M": 1,
                  "SigData": [
                     "0160ade36dc83fc79e8aee00ca2d7553bbef876a14b511bb68555247903732853134ecae9b9ce053c61b0fb65167e9745fdf7e85bd85861fde901430c3fd4de516"
                  ]
               },
               {
                  "PubKeys": [
                     "0250291da2e26b9f155e19d9a0aae1980124caa55760fcade32217fd93e8a0e750"
                  ],
                  "M": 1,
                  "SigData": [
                     "0106956ada8fb0fe2effe88215b39e607f7faa37f07428b5151a359868b03f701ff04b689bd9a96f5fb3272ee362d6176176f0a04959b953c0c85f220f1198d25f"
                  ]
               }
            ],
            "Hash": "bce10eb97c6cd122131e448ddf415bcd15aabbddd466e6850074c6c839a26596"
         },
         {
            "Version": 0,
            "Nonce": 238868671,
            "GasPrice": 0,
            "GasLimit": 30000,
            "Payer": "f72c773b346d3cdf9672fcf9d1a9e0daababa270",
            "TxType": 209,
            "Payload": {
               "Code": "00c66b14e98f4998d837fcdd44a50561f7f32140c7c6c2606a7cc814dd803188dcc41329b6e9faa775a6085269b5db376a7cc808b0040000000000006a7cc86c51c1087472616e736665721400000000000000000000000000000000000000020068164f6e746f6c6f67792e4e61746976652e496e766f6b65",
               "GasLimit": 0
            },
            "Attributes": [],
            "Sigs": [
               {
                  "PubKeys": [
                     "0217c25948722c14c1a6fa8e06b78691e722f4598585805671b0beaa7fd6c7662b"
                  ],
                  "M": 1,
                  "SigData": [
                     "0167697964e63236565e81ca35670b7b160fe4c5365bd437d54d467a63c83084f1988dc6c429d683a71ee590520a5c3ee1735657a485a9f549a4bbef76258db67b"
                  ]
               },
               {
                  "PubKeys": [
                     "0250291da2e26b9f155e19d9a0aae1980124caa55760fcade32217fd93e8a0e750"
                  ],
                  "M": 1,
                  "SigData": [
                     "01980eb20147a016b7ddf614107f4d178be3d7d66d56a5ecc56e80daa89bfed11b081f4a907c89338bbe1182d692307b2727d1227809f75c18662c5f3f9f0c43b4"
                  ]
               }
            ],
            "Hash": "10ccaf9188e249a7ff61aa68e429f9e5a916ca01bbeb55ccaec38588b1227518"
         }
      ]
   }
   ```
3. Get all transaction information in the block according to Transaction Hash by CLI `./ontology info status`

```
$ ./ontology info status bce10eb97c6cd122131e448ddf415bcd15aabbddd466e6850074c6c839a26596
Transaction states:
{
   "TxHash": "bce10eb97c6cd122131e448ddf415bcd15aabbddd466e6850074c6c839a26596",
   "State": 1,
   "GasConsumed": 0,
   "Notify": [
      {
         "ContractAddress": "0100000000000000000000000000000000000000",
         "States": [
            "transfer",
            "Ad4pjz2bqep4RhQrUAzMuZJkBC3qJ1tZuT",
            "Aby4Yw4tNEUN28cWY3cYK5Hk3t7opENq8q",
            1000
         ]
      }
   ]
}
```

"State" is 1 representing transaction success, and 0 representing the failure

Parse the "Notify" array:

​ ContractAddress: Contract address： `0100000000000000000000000000000000000000` is for ONT

​ `0200000000000000000000000000000000000000` is for ONG

​ States：array

​ The first element: "transfer" represents a transfer operation

​ The second element: From address

​ The third element: To address

​ The fourth element: The transfer amounts （**The actual number of ONT is the number of ONT \* 1, and the actual number of ONG is the number of ONG \* 10^9**）

To obtain the user's deposit record, you can filter the to address that is generated by the exchange for users.

### Deposit record

Same as user deposit, the exchange needs to write code to monitor all transactions in all blocks, and record all deposit and withdrawal transactions in the database. If there is a deposit transaction, the exchange needs to modify the corresponding user's balance in the database.

### Process user withdrawal request

With regard to user withdrawal, the exchange needs to complete the following operations:

1. Record user withdrawals and modify users' account balances.
2. Use the CLI command to transfer tokens to the user's withdrawal address:

```
   $ ./ontology asset transfer --from Ad4pjz2bqep4RhQrUAzMuZJkBC3qJ1tZuT --to AS3SCXw8GKTEeXpdwVw7EcC4rqSebFYpfb --amount 10 
   Password:
   Transfer ONT
     From:Ad4pjz2bqep4RhQrUAzMuZJkBC3qJ1tZuT
     To:AS3SCXw8GKTEeXpdwVw7EcC4rqSebFYpfb
     Amount:10
     TxHash:49a705f6beb6a15b92493db496f56e8bcddc95b803dac1e4a02b4579ce760b3f

   Tip:
     Using './ontology info status 49a705f6beb6a15b92493db496f56e8bcddc95b803dac1e4a02b4579ce760b3f' to query transaction status
```

The list of parameters for the command is as follows:

\--wallet, -w\
Wallet specifies the wallet path of transfer-out account. The default value is: "./wallet.dat".

\--gasprice\
The total ONG cost of a transaction is the gaslimit \* Gasprice The gasprice parameter specifies the gas price of the transfer transaction. The gas price of the transaction cannot be less than the lowest gas price set by node's transaction pool, otherwise the transaction will be rejected. The default value is 0. When there are transactions that are queued for packing into the block in the transaction pool, the transaction pool will deal with transactions according to the gas price and transactions with high gas prices will be prioritized.

\--gaslimit\
The gas limit is called the limit because it's the maximum amount of units of gas you are willing to spend on a transaction. However, the actual gas cost is determined by the number of steps or APIs executed by the VM, assuming the following two conditions:\
1\. gaslimit>= actual cost, the transaction will be executed successfully, and return the unconsumed gas;\
2\. Gaslimt< actual cost, the transaction will fail to execute and consume the gas that the VM has already executed;

```
    The minimum gas limit allowed for trading is 30,000. Transactions below this amount will not be packaged.
       Gaslimit can be calculate by transaction pre-execution. (Of course by different execution context, such as time, this is not a definite value).  
       In order to make the use of ONT/ONG simpler, all methods of ONT/ONG are set to the lowest gas limit, ie, 30000 gas.
```

\--asset\
The asset parameter specifies the asset type of the transfer. Ont indicates the ONT and ong indicates the ONG. The default value is ONT.

\--from\
The from parameter specifies the transfer-out account address.

\--to\
The to parameter specifies the transfer-in account address.

\--amount\
The amount parameter specifies the transfer amount. Note: Since the precision of the ONT is 1, if the input is a floating-point value, then the value of the fractional part will be discarded; the precision of the ONG is 9, so the fractional part beyond 9 bits will be discarded.

Confirm the transaction result:

* Use the returned transaction hash to query directly:

```
  $ ./ontology info status 49a705f6beb6a15b92493db496f56e8bcddc95b803dac1e4a02b4579ce760b3f
  Transaction states:
  {
     "TxHash": "49a705f6beb6a15b92493db496f56e8bcddc95b803dac1e4a02b4579ce760b3f",
     "State": 1,
     "GasConsumed": 0,
     "Notify": [
        {
           "ContractAddress": "0100000000000000000000000000000000000000",
           "States": [
              "transfer",
              "Ad4pjz2bqep4RhQrUAzMuZJkBC3qJ1tZuT",
              "AS3SCXw8GKTEeXpdwVw7EcC4rqSebFYpfb",
              10
           ]
        }
     ]
  }
 
```

​

* Same as ”user deposit“, monitor transactions in new blocks and filter out successful transactions which are from exchange addresses to user's withdrawal addresses

1. Extract the transaction ID from the returned transaction details of Json format and record it in the database.
2. Wait for the blockchain confirmation. After confirmation, marking the withdrawal record as successful withdrawal.

   Similar to monitoring the blockchain during deposit, the withdrawal process is also the same. If a certain transaction ID in the block is found to be equal to the transaction ID in the withdrawal record during monitoring, the transaction is confirmed and the withdrawal is successful.
3. If the transaction is not confirmed all the time, that is, the corresponding event log cannot be queried through the transaction hash, then
   * Check if the transaction is in the transaction pool via RPC/SDK interface（refer to [Java SDK:ONT and ONG transfer](https://github.com/ontio/ontology-java-sdk/blob/master/docs/en/sdk_get_start.md#2-%E5%8E%9F%E7%94%9F%E8%B5%84%E4%BA%A7ont%E5%92%8Cong%E8%BD%AC%E8%B4%A6)), if it exists you need to wait for the consensus node to pack and then query
   * If not, the transaction can be considered as failure and the transfer operation needs to be executed again.
   * If the transaction is not packaged for a long time, it may be due to the gas price being too low.

## Java SDK Tutorials

Java SDK Tutorials: [Java SDK Tutorials](https://github.com/ontio/ontology-java-sdk/blob/master/docs/en/sdk_get_start.md)

### Account management

#### Do not use wallet management

**Create account randomly**

```java
com.github.ontio.account.Account acct = new com.github.ontio.account.Account(ontSdk.defaultSignScheme);
acct.serializePrivateKey();//Private key
acct.serializePublicKey();//Public key
acct.getAddressU160().toBase58();//base58 address
```

**Create account based on private key**

```java
com.github.ontio.account.Account acct0 = new com.github.ontio.account.Account(Helper.hexToBytes(privatekey0), ontSdk.defaultSignScheme);
com.github.ontio.account.Account acct1 = new com.github.ontio.account.Account(Helper.hexToBytes(privatekey1), ontSdk.defaultSignScheme);
com.github.ontio.account.Account acct2 = new com.github.ontio.account.Account(Helper.hexToBytes(privatekey2), ontSdk.defaultSignScheme);
```

#### Use wallet management

[Example](https://github.com/ontio/ontology-java-sdk/blob/master/src/main/java/demo/WalletDemo.java)

```java

#### Create a batch of account in the wallet
ontSdk.getWalletMgr().createAccounts(10, "passwordtest");
ontSdk.getWalletMgr().writeWallet();

Create account randomly
AccountInfo info0 = ontSdk.getWalletMgr().createAccountInfo("passwordtest");

Create account based on private key
AccountInfo info = ontSdk.getWalletMgr().createAccountInfoFromPriKey("passwordtest","e467a2a9c9f56b012c71cf2270df42843a9d7ff181934068b4a62bcdd570e8be");

Get account
com.github.ontio.account.Account acct0 = ontSdk.getWalletMgr().getAccount(info.addressBase58,"passwordtest");
```

### Address generation

The address includes single-signature address and multi-signature address, and the generation method is the same as the NEO address.

```
single-signature address generation
String privatekey0 = "c19f16785b8f3543bbaf5e1dbb5d398dfa6c85aaad54fc9d71203ce83e505c07";
String privatekey1 = "49855b16636e70f100cc5f4f42bc20a6535d7414fb8845e7310f8dd065a97221";
String privatekey2 = "1094e90dd7c4fdfd849c14798d725ac351ae0d924b29a279a9ffa77d5737bd96";

//Generate account and get address
com.github.ontio.account.Account acct0 = new com.github.ontio.account.Account(Helper.hexToBytes(privatekey0), ontSdk.defaultSignScheme);
Address sender = acct0.getAddressU160();

//base58 address decode
sender = Address.decodeBase58("AVcv8YBABi9m6vH7faq3t8jWNamDXYytU2")；

//multi-signature address generation
Address recvAddr = Address.addressFromMultiPubKeys(2, acct1.serializePublicKey(), acct2.serializePublicKey());

```

| Method Name             | Parameter                | Parameter Description                                                     |
| ----------------------- | ------------------------ | ------------------------------------------------------------------------- |
| addressFromMultiPubkeys | int m,byte\[]... pubkeys | The minimum number of signatures (<=the number of public keys)，public key |

### ONT and ONG transfer

Example：[Example](https://github.com/ontio/ontology-java-sdk/blob/master/src/main/java/demo/MakeTxWithoutWalletDemo.java)

#### 1. Initialization

```
String ip = "http://polaris1.ont.io";
String rpcUrl = ip + ":" + "20336";
OntSdk ontSdk = OntSdk.getInstance();
ontSdk.setRpc(rpcUrl);
ontSdk.setDefaultConnect(ontSdk.getRpc());
```

#### 2. Query

**Query ONT, ONG Balance**

```
ontSdk.getConnect().getBalance("AVcv8YBABi9m6vH7faq3t8jWNamDXYytU2");

View ONT information:
System.out.println(ontSdk.nativevm().ont().queryName());
System.out.println(ontSdk.nativevm().ont().querySymbol());
System.out.println(ontSdk.nativevm().ont().queryDecimals());
System.out.println(ontSdk.nativevm().ont().queryTotalSupply());

View ONG information:
System.out.println(ontSdk.nativevm().ong().queryName());
System.out.println(ontSdk.nativevm().ong().querySymbol());
System.out.println(ontSdk.nativevm().ong().queryDecimals());
System.out.println(ontSdk.nativevm().ong().queryTotalSupply());
```

**Query whether the transaction is in the transaction pool**

```
ontSdk.getConnect().getMemPoolTxState("d441a967315989116bf0afad498e4016f542c1e7f8605da943f07633996c24cc")


response:transaction is in the tx pool

{
    "Action": "getmempooltxstate",
    "Desc": "SUCCESS",
    "Error": 0,
    "Result": {
        "State":[
            {
              "Type":1,
              "Height":744,
              "ErrCode":0
            },
            {
              "Type":0,
              "Height":0,
              "ErrCode":0
            }
       ]
    },
    "Version": "1.0.0"
}

Or transaction is Not in the tx pool:

{
    "Action": "getmempooltxstate",
    "Desc": "UNKNOWN TRANSACTION",
    "Error": 44001,
    "Result": "",
    "Version": "1.0.0"
}

```

**Query whether the transaction is successful**

Query pushing content of a smart contract

```
ontSdk.getConnect().getSmartCodeEvent("d441a967315989116bf0afad498e4016f542c1e7f8605da943f07633996c24cc")


response:
{
    "Action": "getsmartcodeeventbyhash",
    "Desc": "SUCCESS",
    "Error": 0,
    "Result": {
        "TxHash": "20046da68ef6a91f6959caa798a5ac7660cc80cf4098921bc63604d93208a8ac",
        "State": 1,
        "GasConsumed": 0,
        "Notify": [
            {
                "ContractAddress": "0100000000000000000000000000000000000000",
                "States": [
                    "transfer",
                    "Ad4pjz2bqep4RhQrUAzMuZJkBC3qJ1tZuT",
                    "AS3SCXw8GKTEeXpdwVw7EcC4rqSebFYpfb",
                    1000000000
                ]
            }
        ]
    },
    "Version": "1.0.0"
}
```

You can use the block height to query a smart contract event, and the event transaction detail will be returned.

```
ontSdk.getConnect().getSmartCodeEvent(10)

response:
{
    "Action": "getsmartcodeeventbyhash",
    "Desc": "SUCCESS",
    "Error": 0,
    "Result": [
                             {
                                  "TxHash": "7e8c19fdd4f9ba67f95659833e336eac37116f74ea8bf7be4541ada05b13503e",
                                  "State": 1,
                                  "GasConsumed": 0,
                                  "Notify": [
                                      {
                                          "ContractAddress": "0200000000000000000000000000000000000000",
                                          "States": [
                                              "transfer",
                                              "AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM",
                                              "AFmseVrdL9f9oyCzZefL9tG6UbvhUMqNMV",
                                              1000000000000000000
                                          ]
                                      }
                                  ]
                              },
                              {
                                  "TxHash": "fc82cd363271729367098fbabcfd0c02cf6ded1e535700d04658b596d53cf07d",
                                  "State": 1,
                                  "GasConsumed": 0,
                                  "Notify": [
                                      {
                                          "ContractAddress": "0200000000000000000000000000000000000000",
                                          "States": [
                                              "transfer",
                                              "AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM",
                                              "AFmseVrdL9f9oyCzZefL9tG6UbvhUMqNMV",
                                              1000000000000000000
                                          ]
                                      }
                                  ]
                              }
     ],
    "Version": "1.0.0"
}
```

**The list of chain interaction interfaces**

<table><thead><tr><th width="150">No</th><th align="center">Main Function</th><th align="center">Description</th></tr></thead><tbody><tr><td>1</td><td align="center">ontSdk.getConnect().getGenerateBlockTime()</td><td align="center">Query VBFT block-out time</td></tr><tr><td>2</td><td align="center">ontSdk.getConnect().getNodeCount()</td><td align="center">Query the number of nodes</td></tr><tr><td>3</td><td align="center">ontSdk.getConnect().getBlock(15)</td><td align="center">Query block info</td></tr><tr><td>4</td><td align="center">ontSdk.getConnect().getBlockJson(15)</td><td align="center">Query block info</td></tr><tr><td>5</td><td align="center">ontSdk.getConnect().getBlockJson("txhash")</td><td align="center">Query block info</td></tr><tr><td>6</td><td align="center">ontSdk.getConnect().getBlock("txhash")</td><td align="center">Query block info</td></tr><tr><td>7</td><td align="center">ontSdk.getConnect().getBlockHeight()</td><td align="center">Query current block height</td></tr><tr><td>8</td><td align="center">ontSdk.getConnect().getTransaction("txhash")</td><td align="center">Query transaction</td></tr><tr><td>9</td><td align="center">ontSdk.getConnect().getStorage("contractaddress", key)</td><td align="center">Query smart contract storage</td></tr><tr><td>10</td><td align="center">ontSdk.getConnect().getBalance("address")</td><td align="center">Query balance</td></tr><tr><td>11</td><td align="center">ontSdk.getConnect().getContractJson("contractaddress")</td><td align="center">Query smart contract</td></tr><tr><td>12</td><td align="center">ontSdk.getConnect().getSmartCodeEvent(59)</td><td align="center">Query the event in the smart contract</td></tr><tr><td>13</td><td align="center">ontSdk.getConnect().getSmartCodeEvent("txhash")</td><td align="center">Query the event in the smart contract</td></tr><tr><td>14</td><td align="center">ontSdk.getConnect().getBlockHeightByTxHash("txhash")</td><td align="center">Query the block height by transaction hash</td></tr><tr><td>15</td><td align="center">ontSdk.getConnect().getMerkleProof("txhash")</td><td align="center">Get merkle proof</td></tr><tr><td>16</td><td align="center">ontSdk.getConnect().sendRawTransaction("txhexString")</td><td align="center">Send transaction</td></tr><tr><td>17</td><td align="center">ontSdk.getConnect().sendRawTransaction(Transaction)</td><td align="center">Send transaction</td></tr><tr><td>18</td><td align="center">ontSdk.getConnect().sendRawTransactionPreExec()</td><td align="center">Send a pre-execution transaction</td></tr><tr><td>19</td><td align="center">ontSdk.getConnect().getAllowance("ont","from","to")</td><td align="center">Query Allowed Values</td></tr><tr><td>20</td><td align="center">ontSdk.getConnect().getMemPoolTxCount()</td><td align="center">Query total transaction volume in the transaction pool</td></tr><tr><td>21</td><td align="center">ontSdk.getConnect().getMemPoolTxState()</td><td align="center">Query transaction status in the transaction pool</td></tr></tbody></table>

#### 3. ONT transfer

**Construct transfer transaction and send**

```
// Transferee and payee address
Address sender = acct0.getAddressU160();
Address recvAddr = acct1;

// Multiple address generation
//Address recvAddr = Address.addressFromMultiPubKeys(2, acct1.serializePublicKey(), acct2.serializePublicKey());

// Construct a transfer transaction
long amount = 1000;
Transaction tx = ontSdk.nativevm().ont().makeTransfer(sender.toBase58(),recvAddr.toBase58(), amount,sender.toBase58(),30000,0);

// Sign a transaction
ontSdk.signTx(tx, new com.github.ontio.account.Account[][]{{acct0}});
//Signature scheme of multiple address
ontSdk.signTx(tx, new com.github.ontio.account.Account[][]{{acct1, acct2}});
//If the addresses of the transferee and the payer who pay the network fee are different, the payer’s signature needs to be added.

// Send a transaction
ontSdk.getConnect().sendRawTransaction(tx.toHexString());

```

<table><thead><tr><th width="200.33333333333331">Method Name</th><th>Parameter</th><th>Parameter Description</th></tr></thead><tbody><tr><td>makeTransfer</td><td>String sender，String recvAddr,long amount,String payer,long gaslimit,long gasprice</td><td>sender address, receiver address, amount, network fee payer address, gaslimit, gasprice</td></tr><tr><td>makeTransfer</td><td>State[] states, String payer, long gaslimit, long gasprice</td><td>A transaction contains multiple transfers</td></tr></tbody></table>

**Multiple signatures**

If the addresses of the transferee and the payer who pay the network fee are different, the payer’s signature needs to be added.

```
// 1.Add single signature 
ontSdk.addSign(tx,acct0);

// 2.Add multiple signatures 
ontSdk.addMultiSign(tx,2,new com.github.ontio.account.Account[]{acct0,acct1});
```

**One to multiple or multiple to multiple**

1. Construct a transaction with multiple states
2. Signature
3. A transaction includes 1024 transfers at most

```
Address sender1 = acct0.getAddressU160();
Address sender2 = Address.addressFromMultiPubKeys(2, acct1.serializePublicKey(), acct2.serializePublicKey());
int amount = 10;
int amount2 = 20;

State state = new State(sender1, recvAddr, amount);
State state2 = new State(sender2, recvAddr, amount2);
Transaction tx = ontSdk.nativevm().ont().makeTransfer(new State[]{state1,state2},sender1.toBase58(),30000,0);

//The first transferee is a single-signature address, and the second transferee is a multiple-signature address
ontSdk.signTx(tx, new com.github.ontio.account.Account[][]{{acct0}});
ontSdk.addMultiSign(tx,2,new com.github.ontio.account.Account[]{acct1, acct2});
```

**Use signature server to sign**

* **Construct transaction and sign**

1. Construct a transaction, serialize a transaction, send a transaction to the signature server
2. The signature server receives the transaction, deserializes, checks the transaction, and adds the signature
3. Send transaction

```
//Send serialized transaction to signature server
Transaction tx = ontSdk.nativevm().ont().makeTransfer(sender.toBase58(),recvAddr.toBase58(), amount,sender.toBase58(),30000,0);
String txHex = tx.toHexString();

//The receiver deserializes the transaction and signs it
Transaction txRx = Transaction.deserializeFrom(Helper.hexToBytes(txHex));
//View transfer content in the transaction
System.out.println(Transfers.deserializeFrom(Contract.deserializeFrom(txRx.code).args).json());

//Sign
ontSdk.addSign(txRx,acct0);
```

* **Sign data**

[Example](https://github.com/ontio/ontology-java-sdk/blob/master/src/main/java/demo/SignatureDemo.java)

```
com.github.ontio.account.Account acct = new com.github.ontio.account.Account(ontSdk.defaultSignScheme);

byte[] data = "12345".getBytes();
byte[] signature = ontSdk.signatureData(acct, data);

System.out.println(ontSdk.verifySignature(acct.serializePublicKey(), data, signature));
```

#### 4. ONG transfer

**ONG transfer**

The interface is similar to ONT:

```
ontSdk.nativevm().ong().makeTransfer...
```

**Withdraw ONG**

1. Check the balance of ONG
2. Create account
3. Construct transaction
4. Signature
5. Send transaction that withdraw ONG

```
//Query non-withdrawal ONG
String addr = acct0.getAddressU160().toBase58();
String ong = sdk.nativevm().ong().unboundOng(addr);

//Claim ong，withdraw ONG
com.github.ontio.account.Account account = new com.github.ontio.account.Account(Helper.hexToBytes(privatekey0), ontSdk.signatureScheme);
String hash = sdk.nativevm().ong().withdrawOng(account,toAddr,64000L,payerAcct,30000,500);
```

| Method Name  | Parameter                                                                          | Parameter Description                                                  |
| ------------ | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| makeClaimOng | String claimer, String to, long amount, String payer, long gaslimit, long gasprice | claimer, who to send，amount, network payer address, gaslimit, gasprice |

## Distribute ONG to Users

**NOTE: the following section unavailable since ontology 2.0 update on July 7th 2020**

The exchange can choose whether to distribute the ONG to users. The ONG is used to pay for the Ontology blockchain bookkeeping fees, network fees, and other service fees.

### What is ONG

The total number of ONG is 1 billion with a precision of 9. When the ONT transfer transaction occurs, the unlocked ONG will be authorized by the ONT contract to the transfer sender and receiver. The ONG quantity that the ONT holder can obtain is the percentage of the total amount of ONT owned by the ONT holder. If the transfer transaction has not been triggered, the ONG authorized to the ONT holder will be accumulated and will be issued at the time of the next transfer transaction. This part of the ONG needs to be manually withdrew into wallet address.

### Calculate the amount of ONG that can withdraw

The number of unlocked ONGs is determined by the time interval. The unlock rule is as follows: Unlocking ONG once every second. The number of unlocked ONG is not constant and the unlocked number is determined by ontology unlocked distribution curve. Ontology unlocked distribution curve interval is \[5, 4, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]. Approximately every 31536000 blocks, the unlocked value of ONG will be changed. After about 18 years, all ONGs will be unlocked.

&#x20;

![ONG locked list](/files/lZIIXOlYWRFjOb0UTqE0)

### Distribute ONG to users

View locked ONG Balances via the CLI：`./ontology asset unboundong <address|index|label>`

```
$ ./ontology asset unboundong 1
Unclaim Ong:
  Account:Ad4pjz2bqep4RhQrUAzMuZJkBC3qJ1tZuT
  ONG:23698.8755104
```

Withdraw unlocked ONG via CLI：`./ontology asset withdrawong <address|index|label>`

\--wallet, -w\
Wallet specifies the wallet path of withdrawal account. The default value is: "./wallet.dat".

\--gasprice\
The gasprice parameter specifies the gas price of the transfer transaction. The gas price of the transaction cannot be less than the lowest gas price set by node's transaction pool, otherwise the transaction will be rejected. The default value is 0. When there are transactions that are queued for packing into the block in the transaction pool, the transaction pool will deal with transactions according to the gas price and transactions with high gas prices will be prioritized.

\--gaslimit\
The gaslimit parameter specifies the gas limit of the transfer transaction. The gas limit of the transaction cannot be less than the minimum gas limit set by the node's transaction pool, otherwise the transaction will be rejected. Gasprice \* gaslimit is actual ONG costs. The default value is 30000.

```
$ ./ontology asset withdrawong 1
Password:
Claim Ong:
  Account:Ad4pjz2bqep4RhQrUAzMuZJkBC3qJ1tZuT
  Amount:23698.8755104
  TxHash:c696033f1589a88c7b849dbd2ad0c13a9ca695c3220e4f846f9b1096d0972b80

Tip:
  Using './ontology info status c696033f1589a88c7b849dbd2ad0c13a9ca695c3220e4f846f9b1096d0972b80' to query transaction status
```

Same as user deposit，you can use `./ontology info status c696033f1589a88c7b849dbd2ad0c13a9ca695c3220e4f846f9b1096d0972b80` to query the result of the ONG withdrawal.

Example:

Assuming that all addresses of the exchange are in one wallet, the following figure shows the process and calculation formula about how an exchange distributes ONG to a user:

![](/files/5UzimUeazkq7hAJMtPFu)

### Users withdraw ONG

The process of withdrawing the ONG is the same as the process of withdrawing the ONT, just specify the asset parameter as ong:

```
$ ./ontology asset transfer --from Ad4pjz2bqep4RhQrUAzMuZJkBC3qJ1tZuT --to AS3SCXw8GKTEeXpdwVw7EcC4rqSebFYpfb --amount 10 --asset ong
Password:
Transfer ONG
  From:Ad4pjz2bqep4RhQrUAzMuZJkBC3qJ1tZuT
  To:AS3SCXw8GKTEeXpdwVw7EcC4rqSebFYpfb
  Amount:10
  TxHash:76b19689042d255f3dac2aaf1b30c86fd83c5abfc983d80b8c64fdcc86f33f5e

Tip:
  Using './ontology info status 76b19689042d255f3dac2aaf1b30c86fd83c5abfc983d80b8c64fdcc86f33f5e' to query transaction status
```

Use Java SDK to withdraw ONG, please refer to [Java SDK:ONG transfer](https://github.com/ontio/ontology-java-sdk/blob/master/docs/en/sdk_get_start.md#24-ong%E8%BD%AC%E8%B4%A6)

## Signature service

When your system doesn't support the SDKs and CLI, you can use the sign server to make and sign transactions:

[Ontology Signature Server Tutorials](https://github.com/ontio/ontology/blob/master/docs/specifications/sigsvr.md)

## OEP4 Token

OEP4 is ontology token protocol : [OEP-4 instruction](https://github.com/ontio/OEPs/blob/master/OEPS/OEP-4.mediawiki)

Use Java SDK:

1. Set OEP4 contract hash to SDK:

   ```
   OntSdk wm = OntSdk.getInstance();
           wm.setRpc(rpcUrl);
           wm.setRestful(restUrl);
           wm.setDefaultConnect(wm.getRestful());
           wm.neovm().oep4().setContractAddress("55e02438c938f6f4eb15a9cb315b26d0169b7fd7");
   ```
2. transfer

   ```
   String txhash = ontSdk.neovm().oep4().sendTransfer(account,  //from
   acct.getAddressU160().toBase58(),             //to
   1000,                                         //amount
   account,                                      //payer
   20000,											//gaslimit					
   500);                                         //gasprice    
   ```
3. monitor contract events

   ```
   Object result = ontSdk.getConnect().getSmartCodeEvent(height)
   ```

   the result is:

   ```
   [  
      {  
         "GasConsumed":0,
         "Notify":[  
            {  
               "States":[  
                  "7472616e73666572",
                  "e98f4998d837fcdd44a50561f7f32140c7c6c260",
                  "9d1ce056ac1eb29d73104b3e3c7dfc793c879918",
                  "00a0724e1809"
               ],
               "ContractAddress":"75a5cdc00164266a1ba859da785e31cd914ddbd0"
            }
         ],
         "TxHash":"be0430a6d01404350f4f7a724fabea5e5c3c939668e03979362c5bb6fad68fea",
         "State":1
      }
   ]
   ```

   familiar with ONT and ONG:

   "State":1 means the transaction is succeed

   "ContractAddress":"75a5cdc00164266a1ba859da785e31cd914ddbd0" is the OEP4 contract hash

   "States":\[\
   "7472616e73666572", //method "e98f4998d837fcdd44a50561f7f32140c7c6c260", //from "9d1ce056ac1eb29d73104b3e3c7dfc793c879918", //to "00a0724e1809" //amount ]

   For a standard OEP4 contract transfer , the event notify should contains "transfer",from address, to address and amount fields, currently all the OEP4 contracts is Neovm contract, so we need to do decode the fields like below:

   method:

   ```
   byte[] bs =Helper.hexToBytes("7472616e73666572");
   String s = new String(bs); //s is "transfer"
   ```

   from address:

   ```
   Address from = Address.parse("e98f4998d837fcdd44a50561f7f32140c7c6c260");
   System.out.println("from is " + from.toBase58());
   ```

   to address:

   ```
    Address to = Address.parse("70a2ababdae0a9d1f9fc7296df3c6d343b772cf7");
    System.out.println("to is " + to.toBase58());
   ```

   amount:

   ```
   BigInteger amount = Helper.BigIntFromNeoBytes(Helper.hexToBytes("00a0724e1809"));
   System.out.println("amount is " + amount);
   ```

   ***Note*** amount value is contains the "decimal"，you can get it by

   ```
   ontSdk.neovm().oep4().queryDecimals()
   ```

   for the sig server solution, please refer to the [sigserver guide](https://github.com/ontio/documentation/blob/master/exchangeDocs/Sigsvr_Exchange_Guide.md#6-oep4-tokens-transfer)

   ### 7. PAX token

   Pax is an OEP4 Protocol stable token issued by [Paxos](https://www.paxos.com/pax/) on ontology，same with other OEP4 token , you just need to change the contractAddress to: 6bbc07bae862db0d7867e4e5b1a13c663e2b4bc8 .

   [browser](https://explorer.ont.io/contract/6bbc07bae862db0d7867e4e5b1a13c663e2b4bc8/10/1)

## Native contract address

| Name               | Address (hex)                            | Address (base58)                   |
| ------------------ | ---------------------------------------- | ---------------------------------- |
| ONT Token          | 0100000000000000000000000000000000000000 | AFmseVrdL9f9oyCzZefL9tG6UbvhUMqNMV |
| ONG Token          | 0200000000000000000000000000000000000000 | AFmseVrdL9f9oyCzZefL9tG6UbvhfRZMHJ |
| OntIDContract      | 0300000000000000000000000000000000000000 | AFmseVrdL9f9oyCzZefL9tG6Ubvho7BUwN |
| ParamContract      | 0400000000000000000000000000000000000000 | AFmseVrdL9f9oyCzZefL9tG6UbvhrUqmc2 |
| AuthContract       | 0600000000000000000000000000000000000000 | AFmseVrdL9f9oyCzZefL9tG6Ubvi9BuggV |
| GovernanceContract | 0700000000000000000000000000000000000000 | AFmseVrdL9f9oyCzZefL9tG6UbviEH9ugK |
| HeaderSyncContract | 0800000000000000000000000000000000000000 | AFmseVrdL9f9oyCzZefL9tG6UbviKTaSnK |
| CrossChainContract | 0900000000000000000000000000000000000000 | AFmseVrdL9f9oyCzZefL9tG6UbviRj6Fv6 |
| LockProxyContract  | 0a00000000000000000000000000000000000000 | AFmseVrdL9f9oyCzZefL9tG6UbviXz2jMT |
| OntFSContract      | 0b00000000000000000000000000000000000000 | AFmseVrdL9f9oyCzZefL9tG6Ubvigeqa5R |
| SystemContract     | ff00000000000000000000000000000000000000 | AFmseVrdL9f9oyCzZefL9tG6UbwC9m2yJG |

## FAQ

[FAQ](https://github.com/ontio/documentation/blob/master/exchangeDocs/ONT%2BExchange%2BDocking%2BFAQ.md)

## MainNet update note

please refer to the following note to check whether you need to upgrade your SDK version or not: [Update note](https://github.com/ontio/documentation/blob/master/exchangeDocs/Ontology%20mainnet%20update%20note.md)

### ONT / ONG Decimals

please refer to this [doc](/guides-and-tutorials/evm-and-token-decimals-upgrade).


# Exchange API

For cryptocurrency and data exchange platforms

## Ontology Exchange Docking Document

There are two kinds of assets that are part of the Ontology system: **native assets** and **contract assets**.

Native assets are `ONT` and `ONG`. Upon integration with exchange platforms they are enabled to process exchange and redeeming of these tokens.

### Deploying a Synchronization Node

There are two ways to deploy Ontology synchronization nodes:

#### Get from source code

Clone ontology repository to **$GOPATH/src/github.com/ontio** directory

```bash
$ git clone https://github.com/ontio/ontology.git
```

Or

```
$ go get github.com/ontio/ontology
```

Use the third-party package management tool glide to manage the dependent libraries

```
$ cd $GOPATH/src/github.com/ontio/ontology
$ glide install
```

Compile source code with make

```
$ make
```

An executable program will be generated after a successful compilation (using `make all` command will generate sig server under 'tools' directory ）

* `ontology`: Node program/node control program provided by command line

#### Get from release

[release page](https://github.com/ontio/ontology/releases)

#### Server deployment

1. **Create wallet(not mandatory for sync node)**

Create the wallet file `wallet.dat` that is required for nodes running through the CLI

```bash
$ ./ontology account add -d
Use default setting '-t ecdsa -b 256 -s SHA256withECDSA' 
    signature algorithm: ecdsa 
    curve: P-256 
    signature scheme: SHA256withECDSA 
Password:
Re-enter Password:

Index: 1
Label: 
Address: AWVNFw74G8Sx9vcxGbmh4gT54ayuwb3bcm
Public key: 02c17cd91acf618d497f65f1fc4f52de7952c8b2337883f898dda887953cd29dd7
Signature scheme: SHA256withECDSA

Create account successfully.
```

​

#### Directory Structure

```
   $ tree
   └── ontology
       ├── ontology
       └── wallet.dat
```


# Ontology for dApp Stores

dApp stores integrating Ontology

A list of all the **dApp** stores that have either partially or fully integrated the Ontology platform.

* [DappReview](https://www.dapp.review/explore/ont)
* [Tokenview](https://dappstore.tokenview.com/cn/ont/all)
* [SpiderStore](http://www.spider.store/en/ranking/ont/hot)
* [DAppTotal](https://dapptotal.com/ont)
* [Dappbirds](http://dappbirds.com/explore)
* [DAPP.CC](http://www.dapp.cc/dapp/index)

The total supply of `ONT` and `ONG` can be found out by following link.

{% embed url="<https://explorer.ont.io/v2/summary/native/total-supply/ONT>" %}

{% embed url="<https://explorer.ont.io/v2/summary/native/total-supply/ONG>" %}

The relevant data from all the **dApps** that use Ontology can be queried using a `GET` method `URL`:

```
/api/v1/explorer/summary/{type}/{starttime}/{endtime}
```

And the response of the `GET` method is as follows:

```yaml
{
    "Action": "QuerySummary",
    "Error": 0,
    "Desc": "SUCCESS",
    "Version": "1.0",
    "Result": {
      "Total": 3,
      "SummaryList": [
          {
              "TxnCount": 0,
              "ActiveAddress": 0,
              "BlockCount": 0,
              "OngCount": "0.000000000",
              "OntIdActiveCount": 0,
              "OntIdNewCount": 0,
              "NewAddress": 0,
              "OntCount": "0.000000000",
              "Time": "2018-07-02",
      "OntIdSum": 0,
      "AddressSum": 0
          },
        .......
       ]
  }
}
```

|   ResponseField  |  Type  |
| :--------------: | :----: |
|       Total      |   int  |
|       Time       | String |
|     TxnCount     |   int  |
|    BlockCount    |   int  |
|    AddressSum    |   int  |
|   ActiveAddress  |   int  |
|    NewAddress    |   int  |
|     OntCount     | String |
|     OngCount     | String |
|     OntIdSum     |   int  |
| OntIdActiveCount |   int  |
|   OntIdNewCount  |   int  |

{% hint style="info" %}
Follow [this](https://github.com/ontio-community/dapp-store/blob/master/all-dapps.json) link to find a list of all the **dApps** that have integrated the Ontology platform.
{% endhint %}

For more details on Ontology's **Explorer API**, follow the link below to navigate to another section of this documentation.

{% content-ref url="/pages/-LwHH-WXxF9nsH1qNxGZ" %}
[Explorer v2 API](/developer-tools/api/explorer-api)
{% endcontent-ref %}

If interested in integrating the **dApp** store `API`, please first get in touch with us at **<contact@ont.io>**




---

[Next Page](/llms-full.txt/1)

