# What is Second State

Rust and WebAssembly for cloud services

Second State builds the next-generation open source “operating system” for the cloud and the decentralized web. The Second State Virtual Machine (SSVM) is a WebAssembly runtime optimized for server-side applications. It works seamlessly with existing application frameworks, such as Node.js, but provides a secure and lightweight runtime at native performance. It is a managed alternative to native code, and is ideal for building AI and big data microservices. [Check out why](https://www.secondstate.io/articles/why-webassembly-server/) you want to use WebAssembly on the server-side.

{% hint style="info" %}
Node.js and Rust developers [get started here](https://www.secondstate.io/articles/getting-started-with-rust-function/)! Create high-performance Rust + JavaScript hybrid apps in Node.js.
{% endhint %}

The SSVM also powers decentralized applications as the execution engine for leading public blockchains, such as [Ethereum 2.0](https://blog.secondstate.io/post/20191022-soll-compiler-project/), [Ethereum Classic](https://blog.secondstate.io/post/20190901-etc-partners-with-secondstate/), [Polkadot / Web3](https://blog.secondstate.io/post/20200302-polkadot-en/), [Oasis](https://www.coindesk.com/a16z-leads-45-million-raise-for-blockchain-startup-oasis-labs), and [CyberMiles](https://docs.secondstate.io/buidl-developer-tool/getting-started/develop-for-cybermiles). If you are interested in our blockchain-related technologies, [check out here](https://docs.secondstate.io).

The [Second State BUIDL IDE](https://www.secondstate.io/buidl/) brings the cloud experience to decentralized apps (DApps) developers. It is an entirely browser-based IDE that enables you to

* Write, compile, and deploy smart contracts (Solidity & Lity)
* Develop rule-based smart contracts using the Lity rules engine
* Develop & run JavaScript DApps based on smart contracts
* Access web3 & smart contract search engine JS libraries
* Allow other people to run your H5 JavaScript DApp
* Interact with your own Second State blockchain

{% hint style="info" %}
[Create and publish](/buidl-developer-tool/getting-started) a blockchain-based web application (known as Decentralized Apps or Dapps) in 5 minutes. [Get the book!](https://www.buildingblockchainapps.com/)
{% endhint %}

The Second State Virtual Machine (SSVM) is a WebAssembly runtime optimized for server-side applications. It has applications [beyond the blockchain](https://cloud.secondstate.io/).

{% hint style="info" %}
Node.js and Rust developers [get started here!](https://cloud.secondstate.io/server-side-webassembly/getting-started) Create high-performance Rust + JavaScript hybrid apps in Node.js.
{% endhint %}

Second State is a Venture Capital backed startup with offices in USA, Taiwan, China, and Australia.


# Why BUIDL

Create and deploy your first public blockchain-based app in 5 minutes

[BUIDL](https://buidl.secondstate.io/) is a browser-based IDE that enables developers to create and deploy Decentralized Applications (DApps) on blockchains with ease. For the impatient, watch the [Getting started](/buidl-developer-tool/getting-started) video below.

{% embed url="<https://www.youtube.com/watch?v=K8gMUeOwz1s>" %}

{% content-ref url="/pages/-LjtQUnA9z\_QVhSr1WBe" %}
[Getting started](/buidl-developer-tool/getting-started)
{% endcontent-ref %}

## Before BUIDL

Before BUIDL came along, developers would have to endure many steps in order to deploy a DApp on a public blockchain. The old way was time consuming, taking between **4 to 8 hours** to complete the entire setup. The following steps are an example of what developers **used to do in the past**.

* Install the [Chrome browser](https://www.google.com/chrome/)
* Install [metamask Chrome extension](https://metamask.io/)&#x20;
* Create and manage accounts in metamask&#x20;
* Beg for tokens to add to accounts&#x20;
* Install compiler and deployment tools&#x20;
  * [Solc](https://solidity.readthedocs.io/en/v0.5.3/installing-solidity.html), [web3](https://web3js.readthedocs.io/en/v1.2.1/getting-started.html#adding-web3), [node.js](https://nodejs.org/), [GETH](https://geth.ethereum.org/), or [Parity](https://www.parity.io/ethereum/)&#x20;
  * [Truffle](https://www.trufflesuite.com/)&#x20;
  * or use [Remix](https://remix.ethereum.org/)&#x20;
* Write, compile, debug, and deploy smart contracts&#x20;
* Test and debug on Ethereum networks&#x20;
  * Response time is in minutes or even hours
* Write DApp&#x20;
  * HTML&#x20;
  * CSS&#x20;
  * JavaScript&#x20;
  * web3&#x20;
* Setup a personal web server&#x20;
* Deploy the DApp to the web server&#x20;
* Test and debug&#x20;
  * Response time is in minutes

## After BUIDL

Now with BUIDL, you can write and deploy your DApp in just minutes.

**Go to** [**http://buidl.secondstate.io**](http://buidl.secondstate.io) **from any browser, including smartphones.**

{% embed url="<https://www.youtube.com/watch?v=6sQHDUkbz6k>" %}

{% content-ref url="/pages/-LjtUZEeCcCF8YPS2zDp" %}
[Data-driven DApps](/buidl-developer-tool/access-contracts-data)
{% endcontent-ref %}

{% embed url="<https://www.youtube.com/watch?v=xIdelB4GG_c>" %}

{% content-ref url="/pages/-LjtQaOsO8ynnAnuneqT" %}
[Rule-based smart contract](/buidl-developer-tool/rule-based-smart-contract)
{% endcontent-ref %}

### The BUIDL advantage

* Very fast [underlying blockchain](/devchain/getting-started) with 1s confirmation time
* Support all [Ethereum compatible blockchains](broken://pages/-LjtXvkmmi-7m1tS8BnU)
* [Lity](http://www.litylang.org) language extension to Solidity (e.g., [Rule-based smart contracts](https://www.litylang.org/business_rules/))
* [Built-in](/buidl-developer-tool/access-contracts-data) real-time [smart contract search engine](/white-papers/google-for-smart-contracts) based on ElasticSearch

What are you waiting for? [Getting started now](/buidl-developer-tool/getting-started)!


# Getting started

The BUIDL online IDE can create complete DApps (smart contracts + web3 + ElasticSearch + JS + HTML / CSS) in minutes without installing any software.

In this section, we will walk through the default example that comes with the [BUIDL](http://buidl.secondstate.io/) IDE. The complete source code for this example is [available here](https://github.com/second-state/buidl/tree/master/demo/default).

**Access the BUIDL IDE from your browser:** [**https://buidl.secondstate.io/**](https://buidl.secondstate.io/)

{% embed url="<https://www.youtube.com/watch?v=K8gMUeOwz1s>" %}
Watch a 4-min video on how to create your first DApp in BUIDL
{% endembed %}

{% hint style="info" %}
BUIDL works with the [Second State DevChain](/devchain/getting-started) by default. It could also work with any [blockchain started by the Second BaaS](/buidl-developer-tool/working-with-baas) service, as well as any [Ethereum compatible blockchains](broken://pages/-LjtXvkmmi-7m1tS8BnU).
{% endhint %}

#### Step 1: Create and deploy a simple Solidity smart contract

Load [BUIDL](http://buidl.secondstate.io/) in your web browser. You will see a simple smart contract already in the online editor window.

![](/files/-LjvsJyJ8nxi2hJ-LiDn)

The contract simply allows you to store a number on the blockchain. You can view or update the stored number by calling its functions `get()` and `set()`.

Click on the **Compile** button to compile the contract. A side bar will open to show you the compiled ABI and bytecode of the contract.

![](/files/-Ljvt0TCDNmMVAyWB7Ap)

Next, you can press the **Deploy to the chain** button on the left panel to instantiate and deploy the contract to the [Second State DevChain](/smart-contracts-search-engine/getting-started). You can interact with deployed contracts by calling its public methods from inside [BUIDL](http://buidl.secondstate.io/) -- you can **set** its value and click on the **Transact** button to save the value onto the blockchain, and then click on the **Call** button to see the value in the **LOG** panel.

![](/files/-LjvtBzOEBmrEDsKAX9G)

#### Step 2: Create a UI in HTML

Once deployed, click on the **dapp** button on the left bar to work on your DApp.

![](/files/-LjvtS5gzcg150d5Y5yC)

The HTML tab above shows a simple HTML page with two buttons.

#### Step 3: Create JS script to interact with the smart contract

Next, go to the JS tab. It shows JavaScript on how to interact with the smart contract.

![](/files/-Lq2d8Bzjyph4VxkOGYS)

The JS has four sections. The first section is `Don't modify` as it is populated by the BUIDL tool itself. It contains information about the contract you just deployed via BUIDL.

The second section shows you the boilerplate to instantiate the `contract` and `instance` objects using data from the first section.

```javascript
var contract = window.web3 && web3.ss && web3.ss.contract(abi);
var instance = contract && contract.at(cAddr);
window.addEventListener('web3Ready', function() {
  contract = web3.ss.contract(abi);
  instance = contract.at(cAddr);
});
```

The third section is the event handler for the **Set Data** button. It shows how to call the smart contract's `set()` function in a transaction from JavaScript.

```javascript
document.querySelector("#s").addEventListener("click", function() {
  var n = window.prompt("Input the number:");
  n && instance.set(n);
});
```

The last section is the event handler for the **Get Data** button. It calls the smart contract’s `get()` function and displays the result.

```javascript
document.querySelector("#g").addEventListener("click", function() {
  console.log(instance.get().toString());
});
```

#### Step 4: Run the DApp

Finally, click on the **Run** button to run the DApp. You will see the DApp UI in the right panel. You can click on the **Set Data** button to store a number, and **Get Data** button to retrieve the stored number.

![](/files/-LjvviN3FlXf14V8PpSB)

Congratulations. You now have a complete DApp deployed on a public blockchain!&#x20;

Next, you could explore how to develop more complex DApps on BUIDL, such as [data driven DApps](/buidl-developer-tool/access-contracts-data) or [rules-based DApps](/buidl-developer-tool/rule-based-smart-contract).


# Develop for Ethereum Classic

Use the BUIDL IDE to create and deploy applications on the Ethereum Classic blockchain

The Ethereum Classic blockchain is ideal for application developers looking for a reliable, fast, and low cost public blockchain to deploy decentralized applications (dapps). Ethereum Classic is a secured by a large global network of miners and is one of the most highly valued blockchain networks. The native cryptocurrency, ETC, is a well-known store-of-value, which makes it a great DeFi platform. Compared with Ethereum (ETH), Ethereum Classic (ETC) is much less congested and hence much faster. For developers and users, paying blockchain "gas" using ETC costs only about 5% of ETH gas.&#x20;

To develop decentralized applications (dapps) on Ethereum Classic using BUIDL is as simple as 1-2-3.

## Step1 Configure BUIDL for Ethereum Classic

The easy way is to just click the link below to launch BUIDL in your browser. It pre-loads all the configurations for you.&#x20;

<https://buidl.secondstate.io/etc>

Of course, you can also manually setup the configurations from the **Providers** tab at the lower left panel of BUIDL.

| Setting                | Value                                                                       |
| ---------------------- | --------------------------------------------------------------------------- |
| ES Provider Endpoint   | <https://etc.search.secondstate.io>                                         |
| Web3 Provider Endpoint | [https://www.ethercluster.com/etc](<https://www.ethercluster.com/etc&#xA;>) |
| Chain ID               | 61                                                                          |
| Custom Tx Gas          | Checked                                                                     |
| Gas Price              | 3000000000                                                                  |
| Gas Limit              | 5000000                                                                     |

The gas price and limit are the default values when you use BUIDL to deploy or call contracts. They are also used when you call `web3.ss` functions in the JavaScript application without specifying gas.

Furthermore, since the Ethereum Classic requires bytecode generated from Solidity compiler version 0.4.2, you will need to append a `/?s042` URL parameter to BUIDL. All these are done for you at <https://buidl.secondstate.io/etc>

## Step 2 Get some ETCs for gas

In the **Accounts** tab, you will see 5 auto-generated ETC addresses, and you can set any of them as default. The default address is used to sign transactions from both BUIDL and `web3.ss` applications. Because of that, you will need to send a little ETC (0.1 ETC is enough) into that account to pay for gas fees.

If you do not have ETC and do not know where to buy it, send an email with your **Accounts** screenshot and your default address to <etc@secondstate.io>, and we will send you 0.1 ETC.

## Step 3 Develop and deploy

You can now follow the [Getting Started guide](/buidl-developer-tool/getting-started) to develop and deploy your smart contract and dapp. The `web3.ss` package is a fully featured replacement for the `web3.eth` package. Of course, in your JavaScript code, you can still use `web3.eth` if you wish.

{% content-ref url="/pages/-LjtQUnA9z\_QVhSr1WBe" %}
[Getting started](/buidl-developer-tool/getting-started)
{% endcontent-ref %}

The contract creation, and function calls are all executed with the gas price and gas limit you set. You can still specify the gas price and limit on a per transaction basis. Here is an example.

```
instance.set(n, {
  gas: 100000,
  gasPrice: 10000000000
}, function (e, result) {
  // ... ...
});
```

That's it. Happy coding on Ethereum Classic!


# Develop for CyberMiles

Use the BUIDL IDE to create and deploy applications on the CyberMiles public blockchain

The CyberMiles blockchain is fully compatible with the Ethereum protocol. It is very fast and very cheap to use. To develop decentralized applications (dapps) on CyberMiles using BUIDL is as simple as 1-2-3.

## Step1 Configure BUIDL for CyberMiles

The easy way is to just click the link below to launch BUIDL in your browser. It pre-loads all the configurations for you.&#x20;

<https://buidl.secondstate.io/cmt>

Of course, you can also manually setup the configurations from the **Providers** tab at the lower left panel of BUIDL.

| Setting                | Value                               |
| ---------------------- | ----------------------------------- |
| ES Provider Endpoint   | <https://cmt.search.secondstate.io> |
| Web3 Provider Endpoint | <https://rpc.cybermiles.io:8545>    |
| Chain ID               | 18                                  |
| Custom Tx Gas          | Checked                             |
| Gas Price              | 5000000000                          |
| Gas Limit              | 8000000                             |

The gas price and limit are the default values when you use BUIDL to deploy or call contracts. They are also used when you call `web3.ss` functions in the JavaScript application without specifying gas.

## Step 2 Get some CMTs for gas

In the **Accounts** tab, you will see 5 auto-generated CMT addresses, and you can set any of them as default. The default address is used to sign transactions from both BUIDL and `web3.ss` applications. Because of that, you will need to send a little CMT (1 CMT is enough) into that account to pay for gas fees.

If you do not have CMT and do not know where to buy it, send an email with your **Accounts** screenshot and your default address to <cmt@secondstate.io>, and we will send you 1 CMT.

## Step 3 Develop and deploy

You can now follow the [Getting Started guide](/buidl-developer-tool/getting-started) to develop and deploy your smart contract and dapp. The `web3.ss` package is a fully featured replacement for the `web3.eth` package. Of course, in your JavaScript code, you can still use `web3.eth` if you wish.

{% content-ref url="/pages/-LjtQUnA9z\_QVhSr1WBe" %}
[Getting started](/buidl-developer-tool/getting-started)
{% endcontent-ref %}

The contract creation, and function calls are all executed with the gas price and gas limit you set. You can still specify the gas price and limit on a per transaction basis. Here is an example.

```
instance.set(n, {
  gas: 100000,
  gasPrice: 10000000000
}, function (e, result) {
  // ... ...
});
```

That's it. Happy coding on CyberMiles!


# Develop for Ethereum

Use the BUIDL IDE to create and deploy applications on the Ethereum blockchain

The Ethereum blockchain is the most widely used blockchain smart contract platform. However, it is also heavy congested and very expensive to deploy and run decentralized applications (dapp). For Ethereum application developers, we recommend you to develop and run your applications on Ethereum Classic or CyberMiles instead.

{% content-ref url="/pages/-Lp0RW\_mcKUKZ8oAhif\_" %}
[Develop for Ethereum Classic](/buidl-developer-tool/getting-started/develop-for-ethereum-classic)
{% endcontent-ref %}

{% content-ref url="/pages/-Lp1e\_7jBjgIAbs3dvtZ" %}
[Develop for CyberMiles](/buidl-developer-tool/getting-started/develop-for-cybermiles)
{% endcontent-ref %}

That said, to develop decentralized applications (dapps) on Ethereum using BUIDL is as simple as 1-2-3.

## Step1 Configure BUIDL for Ethereum

The easy way is to just click the link below to launch BUIDL in your browser. It pre-loads all the configurations for you.&#x20;

<https://buidl.secondstate.io/eth>

Of course, you can also manually setup the configurations from the **Providers** tab at the lower left panel of BUIDL.

| Setting                | Value                               |
| ---------------------- | ----------------------------------- |
| ES Provider Endpoint   | <https://eth.search.secondstate.io> |
| Web3 Provider Endpoint | <https://mainnet.infura.io>         |
| Chain ID               | 1                                   |
| Custom Tx Gas          | Checked                             |
| Gas Price              | 10000000000                         |
| Gas Limit              | 8000000                             |

The gas price and limit are the default values when you use BUIDL to deploy or call contracts. They are also used when you call `web3.ss` functions in the JavaScript application without specifying gas.

## Step 2 Get some ETHs for gas

In the **Accounts** tab, you will see 5 auto-generated ETH addresses, and you can set any of them as default. The default address is used to sign transactions from both BUIDL and `web3.ss` applications. Because of that, you will need to send a little ETH (0.1 ETH is enough) into that account to pay for gas fees.

## Step 3 Develop and deploy

You can now follow the [Getting Started guide](/buidl-developer-tool/getting-started) to develop and deploy your smart contract and dapp. The `web3.ss` package is a fully featured replacement for the `web3.eth` package. Of course, in your JavaScript code, you can still use `web3.eth` if you wish.

{% content-ref url="/pages/-LjtQUnA9z\_QVhSr1WBe" %}
[Getting started](/buidl-developer-tool/getting-started)
{% endcontent-ref %}

The contract creation, and function calls are all executed with the gas price and gas limit you set. You can still specify the gas price and limit on a per transaction basis. Here is an example.

```
instance.set(n, {
  gas: 100000,
  gasPrice: 10000000000
}, function (e, result) {
  // ... ...
});
```

That's it. Happy coding on Ethereum!


# MetaMask notes

## Developers

If you have MetaMask installed, you can use MetaMask (or Venus for CMT) as the web3 provider for BUIDL. Just select MetaMask (or Venus) from the **Providers** tab. BUIDL will use MetaMask account to pay gas for deploying or calling contracts. The web3 instance in the dapp will also now come from MetaMask.

![](/files/-Lq2n-PTZMucysZ3cS13)

However, when you publish the dapp, you will be asked to fill in a "backup" web3 provider since we cannot assume all users also have MetaMask installed.

## Users

If a user has MetaMask (or Venus for CMT) installed, she can switch to MetaMask or Venus at the account switcher on the published dapp. The dapp will use the web3 object from the MetaMask or Venus account.

![](/files/-Lq2n8Mb2kp0bWrVgYqK)


# Data-driven DApps

The [Getting started guide](/buidl-developer-tool/getting-started) showcased a number storage contract and DApp. In this section, we will use a similar smart contract, but to develop a new DApp that highlights data capabilities of the Second State platform, which supports [web3](https://github.com/second-state/web3-ss.js) for transactional data and [elastic search](https://github.com/second-state/es-ss.js) for state data. The complete source code for this example is [available here](https://github.com/second-state/buidl/tree/master/demo/data-v2).

**Access the BUIDL IDE from your browser:** [**https://buidl.secondstate.io/**](https://buidl.secondstate.io/)

Let’s first see how the DApp works. It displays a number of `AccountBalanceDemo` contracts deployed on the blockchain. Each of those contracts stores a number that can be changed by the user. The search engine tracks and displays the tally of those numbers inside the contracts in real time.

{% embed url="<https://www.youtube.com/watch?v=6sQHDUkbz6k>" %}
Watch a video on how to create and run the DApp
{% endembed %}

Now, let’s review the code to see how this is done.

#### Step 1: Copy and paste the following code into contract tab

```typescript
pragma solidity >=0.4.0 <0.6.0;

contract AccountBalanceDemo {

    string accountName;
    uint accountBalance;

    constructor(string _accountName) public {
        accountName = _accountName;
    }

    function setAccountBalance(uint _accountBalance) public {
        accountBalance = _accountBalance;
    }

    function getAccountName() public view returns(string) {
        return accountName;
    }

    function getAccountBalance() public view returns(uint) {
        return accountBalance;
    }
}
```

Compile and deploy the smart contract via the **Compile** and **Deploy on the chain** buttons as we did in the [Getting started guide](/buidl-developer-tool/getting-started).&#x20;

> Make sure that you give the account a name in the `_accountName` field above the **Deploy on the chain** button.

#### Step 2: Copy and paste the follow HTML code into the dapp -> HTML tab

```markup
<!doctype html>
<html lang="en">
   <head>
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
      <title>Data Stores</title>
   </head>
   <body>
      <div class="container">
         <p>This page shows a list of individual accounts and their individual balances.</p>
         <p>Each account entity (each instantiation of the smart contract) is not aware of the other accounts, or their balances</p>
         <p>This page demonstrates how the smart contract search engine can provide the sum total of all accounts combined.</p>
         <br />
         <b>Sum total of all accounts</b>
         <table class="table">
            <thead>
               <tr><th scope="col">Total</th></tr>
            </thead>
            <tbody id="totalBody"></tbody>
         </table>
         <br />
         <b>Name and balance of individual accounts</b>
         <table class="table">
            <thead>
               <tr>
                  <th scope="col">Account Name</th>
                  <th scope="col">Account Balance</th>
                  <th scope="col"></th>
               </tr>
            </thead>
            <tbody id="individualBody"></tbody>
         </table>
      </div>
   </body>
</html>
```

The HTML code demonstrates how to use the bootstrap 4 CSS framework. If you have additional CSS style rules for this page, you can put them in the CSS tab.

The HTML renders a table that lists all the `AccountBalanceDemo` contracts, as well as the total tally from those contracts.

#### Step 3: Copy and paste the following into the dapp -> JS tab

```javascript
var contract = window.web3 && web3.ss && web3.ss.contract(abi);
var instance = contract && contract.at(cAddr);
window.addEventListener('web3Ready', function() {
  contract = web3.ss.contract(abi);
  instance = contract.at(cAddr);
  reload();
});

function reload() {
    document.querySelector("#totalBody").innerHTML = "";
    document.querySelector("#individualBody").innerHTML = "";
    var tbodyInner = "";
    esss.shaAbi(JSON.stringify(abi)).then((shaResult) => {
        var sha = JSON.parse(shaResult).abiSha3;
        esss.searchUsingAbi(sha).then((searchResult) => {
            var items = JSON.parse(searchResult);
            items.sort(compareItem);
            items.forEach(function(item) {
                tbodyInner = tbodyInner +
                    "<tr id='" + item.contractAddress + "'><td>" + item.functionData.getAccountName +
                    "</td><td>" + item.functionData.getAccountBalance +
                    "</td><td><button class='btn btn-info' onclick='setNumber(this)'>Update balance</button></td></tr>";
            }); // end of JSON iterator
            document.querySelector("#individualBody").innerHTML = tbodyInner;
            displayTotal();
        });
    }); // end of esss
}

function displayTotal() {
    esss.shaAbi(JSON.stringify(abi)).then((shaResult) => {
        var sha = JSON.parse(shaResult).abiSha3;
        esss.searchUsingAbi(sha).then((searchResult) => {
            var items = JSON.parse(searchResult);
            var totalBodyInner = "";
            var total = 0;
            items.forEach(function(item) {
                total = total + parseInt(item.functionData.getAccountBalance);
            });
            totalBodyInner = totalBodyInner + "<tr id='total'><td>" + total + "</tr>";
            document.querySelector("#totalBody").innerHTML = totalBodyInner;
        });
    }); // end of esss
}

function setNumber(element) {
    var tr = element.closest("tr");
    instance = contract.at(tr.id);
    var n = window.prompt("Input a number:");
    n && instance.setAccountBalance(n);
    setTimeout(function() {
        element.innerHTML = "Sending ...";
        esss.updateStateOfContractAddress(JSON.stringify(abi), instance.address).then((c2i) => {
            element.innerHTML = "Calculating ...";
            setTimeout(function() {
                reload();
            }, 5 * 1000);
        });
    }, 1 * 1000);
}

function compareItem(a, b) {
    let comparison = 0;
    if (a.functionData.getAccountName < b.functionData.getAccountName) {
        comparison = -1;
    } else if (a.functionData.getAccountName > b.functionData.getAccountName) {
        comparison = 1;
    }
    return comparison;
}
```

When the page loads, the `reload()` JS function calls the elastic search API to get all contracts with the `AccountBalanceDemo` type from the blockchain. It then constructs a table body to display those contracts. Notice that the current state, ie the stored number, of each contract is contained in the search result. We can simply display this information without having to interact with the slower blockchain nodes.

```javascript
esss.shaAbi(JSON.stringify(abi)).then((shaResult) => {
  var sha = JSON.parse(shaResult).abiSha3;
  esss.searchUsingAbi(sha).then((searchResult) => {
    var items = JSON.parse(searchResult);
    // Puts the items into the table
    displayTotal();
  });
});
```

The `displayTotal()` JS function tallies the account balances from all contracts in the search result, and displays the sum on the UI.

```javascript
function displayTotal() {
    esss.shaAbi(JSON.stringify(abi)).then((shaResult) => {
        var sha = JSON.parse(shaResult).abiSha3;
        esss.searchUsingAbi(sha).then((searchResult) => {
            var items = JSON.parse(searchResult);
            var totalBodyInner = "";
            var total = 0;
            items.forEach(function(item) {
                total = total + parseInt(item.functionData.getAccountBalance);
            });
            totalBodyInner = totalBodyInner +
                "<tr id='total'><td>" + total + "</tr>";
            document.querySelector("#totalBody").innerHTML = totalBodyInner;
        });
    }); // end of esss
}
```

The **Update balance** buttons in the table trigger the `setNumber()` JS function, which in turn call the contract’s `setAccountBalance()` function via web3. It then calls the `esss.updateStateOfContractAddress()` function to explicitly inform the search engine that this contract has changed. It then waits a short time before calling the `reload()` JS function to reload and display all contracts and the total from the search engine again. Notice that the search engine works in near real-time, as the account balance you just updated is reflected in the search results in seconds.

```javascript
function setNumber(element) {
    var tr = element.closest("tr");
    instance = contract.at(tr.id);
    var n = window.prompt("Input a number:");
    n && instance.setAccountBalance(n);
    setTimeout(function() {
        element.innerHTML = "Sending ...";
        esss.updateStateOfContractAddress(JSON.stringify(abi), instance.address).then((c2i) => {
            element.innerHTML = "Calculating ...";
            setTimeout(function() {
                reload();
            }, 5 * 1000);
        });
    }, 1 * 1000);
}
```

#### Step 4: Hit the Run button to launch the DApp

You will see the web app running inside the right panel. You can update the balance in each account, and see the total changes.

In this article, we demonstrated how to use [web3](https://github.com/second-state/web3-ss.js) and [elastic search](https://github.com/second-state/es-ss.js) APIs together to build high performance and data driven DApps. The [FairPlay DApp](https://www.fairplaydapp.com/) is a successful real world example based on [this approach](/white-papers/fairplay-a-new-type-of-dapp).

If you are interested in learning more about the smart contract search engine, please read on to the next article on how to [create and index contracts](/buidl-developer-tool/access-contracts-data/example-contract-indexing) programmatically. Or, you can skip ahead and learn how to write [rule-based smart contracts](/buidl-developer-tool/rule-based-smart-contract) in BUIDL.


# Create and index contracts

In the previous article, we showed how to use the smart contract search engine together with web3 to update and keep track of data states of smart contracts. In this example, we will further explain how to create a smart contract from your DApp and index it with the search engine.

**Access the BUIDL IDE from your browser:** [**https://buidl.secondstate.io/**](https://buidl.secondstate.io/)

{% embed url="<https://youtu.be/fN1EmmEk25Q>" %}
Watch a video on how to create and run the DApp
{% endembed %}

Let’s first see how the DApp works. It displays all the storage contracts deployed on the blockchain, and then allows the user to store numbers in those contracts. But most importantly, it allows users to create new storage contracts, and have them immediately indexed and displayed in the DApp.

![](/files/-LjwAGfPTXKRRjcZUyUe)

Now, let’s review the code to see how this is done.

#### Step 1: Copy and paste the following code into contract tab

```typescript
pragma solidity >=0.4.0 <0.6.0;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}
```

Compile and deploy the smart contract via the **Compile** and **Deploy to the chain** buttons as we did in the [Getting started guide](/buidl-developer-tool/getting-started).

![](/files/-LjwB7O4u7knZ_VGzcqG)

#### Step 2: Copy and paste the follow HTML code into the dapp -> HTML tab

```markup
<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    
    <title>Data Stores</title>
  </head>
  <body>
    <div class="container">
        <p><br/>The table shows on-chain storage contracts. You can create a new one, or change the number stored in an existing one. All actions are recorded on-chain as immutable history.</p>
        <p><button id="create" class="btn btn-primary" onclick="create(this)">Create a new storage contract</button></p>
        <table class="table">
            <thead>
                <tr>
                    <th scope="col">Created</th>
                    <th scope="col">Data</th>
                    <th scope="col"></th>
                </tr>
            </thead>
            <tbody id="tbody">
            </tbody>
        </table>
    </div>
  </body>
</html>
```

The HTML code demonstrates how to use the bootstrap 4 CSS framework. If you have additional CSS style rules for this page, you can put them in the CSS tab.

The HTML renders a button to create new storage contracts, as well as a table that lists all the contracts. The table is initially empty, and will be filled by the JavaScript, which we see next.

#### Step 3: Copy and paste the following into the dapp -> JS tab

```javascript
var contract = window.web3 && web3.ss && web3.ss.contract(abi);
var instance = contract && contract.at(cAddr);
window.addEventListener('web3Ready', function() {
  contract = web3.ss.contract(abi);
  instance = contract.at(cAddr);
  reload();
});

function reload() {
    document.querySelector("#create").innerHTML = "Create a new storage contract";
    var tbodyInner = "";
    esss.shaAbi(JSON.stringify(abi)).then((shaResult) => {
        var sha = JSON.parse(shaResult).abiSha3;
        esss.searchUsingAbi(sha).then((searchResult) => {
            var items = JSON.parse(searchResult);
            items.sort(compareItem);
            items.forEach(function(item) {
                tbodyInner = tbodyInner +
                    "<tr id='" + item.contractAddress + "'><td>" + item.blockNumber +
                    "</td><td>" + item.functionData.get +
                    "</td><td><button class='btn btn-info' onclick='setData(this)'>Set</button></td></tr>";
            }); // end of JSON iterator
            document.querySelector("#tbody").innerHTML = tbodyInner;
        });
    }); // end of esss
}

function create(element) {
    element.innerHTML = "Wait ...";
    var data = '0x' + contract.new.getData({
        data: bytecode
    });
    contract.new({
        data: data
    }, function(ee, i) {
        if (!ee && i.address != null) {
            esss.submitAbi(JSON.stringify(abi), i.transactionHash).then((submitResults) => {
                setTimeout(function() {
                    reload();
                }, 3 * 1000);
            });
        }
    });
}

function setData(element) {
    var tr = element.closest("tr");
    instance = contract.at(tr.id);
    var n = window.prompt("Input a number:");
    n && instance.set(n);
    setTimeout(function() {
        esss.updateStateOfContractAddress(JSON.stringify(abi), instance.address).then((c2i) => {
            setTimeout(function() {
                esss.searchUsingAddress(instance.address).then((r) => {
                    var data = JSON.parse(r);
                    resultToDisplay = JSON.stringify(data.functionData.get);
                    element.closest("td").previousSibling.innerHTML = resultToDisplay.replace(/['"]+/g, '');
                    element.innerHTML = "Set";
                });
            }, 1 * 1000);
        });
    }, 1 * 1000);
    element.innerHTML = "Wait ...";
}

function compareItem(a, b) {
    let comparison = 0;
    if (a.blockNumber < b.blockNumber) {
        comparison = 1;
    } else if (a.blockNumber > b.blockNumber) {
        comparison = -1;
    }
    return comparison;
}
```

When the page loads, the `reload()` function below calls the elastic search API to get all contracts with the ABI from the blockchain. It then constructs a table body to display those contracts. Notice that the current state, ie the stored number, of each contract is also contained in the search result. We can simply display this information without having to interact with the slower blockchain nodes.

```javascript
esss.shaAbi(JSON.stringify(abi)).then((shaResult) => {
  var sha = JSON.parse(shaResult).abiSha3;
  esss.searchUsingAbi(sha).then((searchResult) => {
    var items = JSON.parse(searchResult);
    // Puts the items into the table
  });
});
```

The **Set Data** buttons in the table trigger the `setData()` JS function, which in turn calls the contract’s `set()` function via web3.

```javascript
function setData (element) {
  instance = contract.at(element.id);
  var n = window.prompt("Input a number:");
  n && instance.set(n);
}
```

The **Create new storage contract** button triggers the `create()` JS function to create a new contract on the blockchain. The contract creation is a regular web3 transaction. After the contract is successfully created, we submit it to the ElasticSearch engine via `esss.submitAbi()` so that it can be indexed and tracked for all future state updates.

```javascript
function create (element) {
  element.innerHTML = "Wait ...";
  var data = '0x' + contract.new.getData({data:bytecode});
  contract.new({
    data: data
  }, function (ee, i) {
    if (!ee && i.address != null) {
      esss.submitAbi(JSON.stringify(abi), i.transactionHash);
      setTimeout(function () {
        reload ();
      }, 5 * 1000);
    }
  });
}
```

#### Step 4: Hit the Run button to launch the DApp

You will see the web app running inside the right panel. You can now create a new storage contract, and then change its stored number.

In this article, we demonstrated how to use [web3](https://github.com/second-state/web3-ss.js) and [elastic search](https://github.com/second-state/es-ss.js) APIs together to build high performance and data driven DApps. The [FairPlay DApp](https://www.fairplaydapp.com/) is a successful real world example based on [this approach](/white-papers/fairplay-a-new-type-of-dapp).

In the next article, we will show how to write [rule-based smart contracts](/buidl-developer-tool/rule-based-smart-contract) in BUIDL.


# Rule-based smart contract

Smart contracts a rule-based systems. The Second State smart contract platform supports a [formal rules language](https://www.litylang.org/business_rules/) inside smart contracts. The rules language makes it easy to write rigorous and correct smart contracts, and in turn, smart contracts make business rules transparent and more collaborative. The complete source code for this example is [available here](https://github.com/second-state/buidl/tree/master/demo/rules).

**Access the BUIDL IDE from your browser:** [**https://buidl.secondstate.io/**](https://buidl.secondstate.io/)

{% embed url="<https://www.youtube.com/watch?v=xIdelB4GG_c>" %}
The rule-based smart contract in BUIDL
{% endembed %}

Let’s first see how the DApp works. It show a contract that calculates rebates for a customer based on rules. The customer gets 5% rebate, up to $100, for every purchase that is $100 or more. You can click on the **Add** button to simulate a purchase made by this user. The contract automatically computes the rebate as soon as a new purchase is made.

![](/files/-LkD3kVkFke75J2zmSJQ)

#### Step 1: Copy and paste the following code into contract tab

```typescript
pragma lity ^1.2.6;

contract Person {
    struct Purchase {
        int price;
        bool rebated;
    }
    struct Total {
        int paid;
        int rebate;
    }
    string name;
    Purchase purchase;
    Total total;

    constructor (string _name) public {
        name = _name;
        total = Total (0,0);
        factInsert total;
    }

    function buy (int _price) public {
        purchase = Purchase (_price, false);
        total.paid += _price;

        uint256 idx = factInsert purchase;
        fireAllRules;
        factDelete idx;
    }

    function getInfo () view public returns (string, int, int) {
        return (name, total.paid, total.rebate);
    }

    rule "computeRebate" when {
        p: Purchase(price >= 100, !rebated);
        t: Total(rebate < 100);
    } then {
        p.rebated = true;
        t.rebate += p.price * 5 / 100;
        update p;
        update t;
    }
}
```

The important code segment is at the end of the contract, where we specify how the rebates should be given in a set of formal rules named `computeRebate`. The contract uses `factInsert`, `factDelete`, and `fireAllRules` built-in functions to manage the data and execution of this rule. For more details, you can read the [Lity rules documentation](https://lity.readthedocs.io/en/latest/rule-engine-guide.html).

Compile and deploy the smart contract via the **Compile** and **Deploy** buttons. Notice that the contract requires a constructor parameter. The parameter is a person's name. This contract represents his or her shopping history.

![](/files/-LkD81Rx23vHIYGEvO9h)

#### Step 2: Copy and paste the follow HTML code into the dapp -> HTML tab

```markup
<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <title>Rule-based rebate</title>
  </head>
  <body>
    <div class="container">
        <p><br/>Rebate rules</p>
        <ul>
            <li>Purchases of $100 or more gets 5% rebate</li>
            <li>Each purchase can only get one rebate</li>
            <li>Max rebate is $100 per person</li>
        </ul>
        <p>Use the <b>Add</b> button to add a purchase, and update the rebate.</p>
        <h3>Record for <span id="name"></span></h3>
        <table class="table">
            <tbody id="tbody">
                <tr>
                    <td>Purchases</td>
                    <td id="purchase"></td>
                    <td><button class='btn btn-info btn-sm' onclick='buy(this)'>Add</button></td>
                </tr>
                <tr>
                    <td>Rebate</td>
                    <td id="rebate"></td>
                    <td></td>
                </tr>
            </tbody>
        </table>
    </div>
  </body>
</html>
```

The HTML page presents a UI that allows users to add purchases for this person. With each purchase, the rebate is re-calculated according to the rule.

#### Step 3: Copy and paste the following into the dapp -> JS tab

```javascript
var contract = window.web3 && web3.ss && web3.ss.contract(abi);
var instance = contract && contract.at(cAddr);
window.addEventListener('web3Ready', function() {
  contract = web3.ss.contract(abi);
  instance = contract.at(cAddr);
  reload();
});

instance.getInfo.call (function (e, r) {
  if (e) {
    console.log(e);
    return;
  } else {
    console.log(r);
    document.querySelector("#name").innerHTML = r[0];
    document.querySelector("#purchase").innerHTML = r[1];
    document.querySelector("#rebate").innerHTML = r[2];
  }
});

function buy (element) {
  element.innerHTML = "Wait ...";
  var n = window.prompt("Amount paid for purchase:");
  n && instance.buy(n);
  setTimeout(function () {
    instance.getInfo.call (function (e, r) {
      if (e) {
        console.log(e);
        return;
      } else {
        document.querySelector("#purchase").innerHTML = r[1];
        document.querySelector("#rebate").innerHTML = r[2];
        element.innerHTML = "Add";
      }
    });
  }, 2 * 1000);
}
```

BUIDL pre-fills the JavaScript with the smart contract's compiled artifacts (ABI and bytecode), and its deployed address on the blockchain. The script starts by making a `getInfo()` call against the contract instance (i.e., a person) via web3 to get the current state of the contract.&#x20;

The `buy()` method prompts the user to enter a purchase amount to add to this person. It waits for 2 seconds and then calls `getInfo()` again to get the updated purchase and rebate information for this person from the blockchain smart contract.

#### Step 4: Hit the Run button to launch the DApp

You will see the web app running inside the right panel. You can now add purchases to the person, and see his or her rebates change.

There is also a more complex example of the rebate rules, which allows you to create new persons (one contract per person), and then manage all persons in a table. Try the [source code here](https://github.com/second-state/buidl/tree/master/demo/rules-es).


# Sharing your DApp

With the DApp now developed and smart contract deployed on chain, it is easy to share your DApp with family, friends, and colleagues. Just click on the **Publish** button. BUIDL will package the application frontend into a single HTML file and upload it to a public web site. Once it is done, it shows a **Launched** link. Click on that link to open the DApp web site. You can now share this link with anyone.

![Publish the DApp to a public web site](/files/-LmQTjIqD6GY0poF_OyT)

{% hint style="info" %}
If you use MetaMask (or Venus for CMT) as the web3 provider for BUIDL, you will be asked to provide a "backup" web3 provider when you publish. That is because we cannot assume the dapp users also have MetaMask.
{% endhint %}

You can also download and save the HTML file from that **Launched** link onto your local computer hard drive. You can put the HTML file on any web host and make it accessible to the world. There are many free services to host your HTML files for the world. Here are some examples.

* [Github pages](https://pages.github.com)
* [Netlify](https://www.netlify.com/)
* [Drive to web](https://drv.tw) for Google Drive

When users comes to the web page to interact with your DApp, they will see a small gadget at the bottom of the page that allows the user to select his or her blockchain address. Note that all those addresses are automatically generated and the selected address serves as the user’s on chain ID.

![Selected a blockchain account from your exported web page](/files/-LmAQ5ifBkFvyaV8dVeU)

{% hint style="info" %}
If the user has MetaMask (or Venus for CMT) installed, she will also be able to select MetaMask from the accounts list.
{% endhint %}

In a production deployment environment, you might need to provision addresses and private keys for your authorized users. For assistance on enterprise use, please contact us.<br>


# Working with BaaS

By default, the BUIDL tool works with the Second State DevChain, a high performance public blockchain. However, there are definitely cases when you might want to deploy on your own private or consortium blockchain. The Second State Blockchain as a Service (BaaS) enables you to create, customize and deploy a brand new blockchain with one click. Then, you can use BUIDL to develop and deploy on your own blockchain.

First, just go to the Second State BaaS web app and configure your blockchain. It is free of charge during the current pilot period. [Go try it!](http://baas-mvp.secondstate.io/)

![Create a new blockchain with one click from Second State BaaS](/files/-LmAS699KQGIVIbogQf-)

It takes a few minutes to create and deploy your new blockchain. Once you are done, you should see the URLs to the new blockchain’s RPC node and ElasticSearch service. Put those URLs into your BUIDL config panel, and all your BUIDL contracts and DApps will now deploy to the new blockchain!

![Customize endpoints to work with a new blockchain](/files/-LmASKFCfUiyOm_6MzGQ)

Alternatively, the BaaS site provides a direct link to BUDIL. The link automatically configures BUIDL to use your new RPC and ElasticSearch endpoints.


# DEMO: A voting dapp

The example dapp is a web application where people can vote thumb up or thumb down on a statement. All the votes are recorded on the blockchain.

![](/files/-Lq38GS31rwA0NqfJZsW)

![](/files/-Lq38OzBmh8EimhN9Mqb)

How to deploy and publish this application on different public blockchains.

{% content-ref url="/pages/-Lq3DrmnDjI9ExobNXoh" %}
[DevChain](/buidl-developer-tool/demo-a-voting-dapp/devchain)
{% endcontent-ref %}

{% content-ref url="/pages/-Lq38u0qiL4sFrffiStE" %}
[Ethereum Classic](/buidl-developer-tool/demo-a-voting-dapp/ethereum-classic)
{% endcontent-ref %}

{% content-ref url="/pages/-Lq3FDpnzxxCS4usOBHT" %}
[CyberMiles](/buidl-developer-tool/demo-a-voting-dapp/cybermiles)
{% endcontent-ref %}


# DevChain

No gas needed. Accounts are only for identification purposes.

## See the dapp in action

{% content-ref url="/pages/-Lq2p5O6GWWL3qBCS1KH" %}
[DEMO: A voting dapp](/buidl-developer-tool/demo-a-voting-dapp)
{% endcontent-ref %}

## **Step 1**&#x20;

Open the BUIDL IDE tool in any browser. <http://buidl.secondstate.io/>

## **Step 2**&#x20;

### 2.1 Copy and paste the following code to the contract section of BUIDL.

The smart contract is very simple. It provides the text and image url to be voted on, and keeps a record of votes. The `vote()` method is called by voters to vote thumb up or down.&#x20;

```typescript
pragma solidity >= 0.4.0;

contract Vote {

    string public greeting;
    string public photoUrl;
    mapping (address => int) votes;
    uint ups;
    uint downs;

    constructor(string _greeting, string _photoUrl) public {
        greeting = _greeting;
        photoUrl = _photoUrl;
    }

    function vote (int _choice) public {
        require (votes[msg.sender] == 0);
        require (_choice == 1 || _choice == -1);
        votes[msg.sender] = _choice;
        if (_choice == 1) ups++;
        if (_choice == -1) downs++;
    }

    function getVotes () view public returns (uint, uint) {
        return (ups, downs);
    }

    function getVote (address _addr) view public returns (int) {
        return votes[_addr];
    }
}
```

### 2.2 Click on Compile and you will see the following. Enter your text and image URL to be voted on, and then click on deploy on chain.

![](/files/-Lq3ARo2YZmxvHGN7IfA)

The contract is now deployed on the DevChain, and you can call its functions directly from inside BUIDL.

![](/files/-Lq3AYVxO86BrtTvxHg3)

### 2.3 Go to the dapp section. Click on the Resources tab, and add the following as resources.

* CSS: <https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css>
* JavaScript: <https://code.jquery.com/jquery-3.4.1.min.js>

### 2.4 Next, copy and paste the following HTML code into the HTML editor.

```markup
<div class="container">
   <br/>
   <div class="jumbotron">
      <p class="lead" id="greeting"></p>
      <div id="imageDiv" style="display:none">
         <img id="image" src="" class="img-fluid img-thumbnail"/>
      </div>
      <hr/>
      <p id="votes" style="display:none">
         <span id="ups"></span> voted 👍 |
         <span id="downs"></span> voted 👎
      </p>
      <form id="form" class="form-inline" style="display:none">
         <button id="voteUp" type="button" onclick="return vote(1);" class="btn btn-secondary mb-2">👍</button>
         <button id="voteDown" type="button" onclick="return vote(-1);" class="btn btn-secondary mb-2">👎</button>
      </form>
      <div id="formSubmitted" style="display:none">Please wait 2 seconds ...</div>
      <div id="myVoteUp" style="display:none">You have already voted 👍</div>
      <div id="myVoteDown" style="display:none">You have already voted 👎</div>
   </div>
</div>
```

### 2.5 Copy and paste the following JavaScript code into the JS editor.

```javascript
var instance = null;
window.addEventListener('web3Ready', function() {
  var contract = web3.ss.contract(abi);
  instance = contract.at(cAddr);
  reload();
});

function reload() {
    instance.greeting(function (e, r) {
        $("#greeting").html(r);
    });
    instance.photoUrl(function (e, r) {
        if (!e && r) {
            $("#imageDiv").css("display", "block");
            $("#image").attr("src", r);
        }
    });
    instance.getVotes(function (e, r) {
        if (!e && (r[0] > 0 || r[1] > 0)) {
            $("#votes").css("display", "block");
            $("#ups").text(r[0]);
            $("#downs").text(r[1]);
        }
    });

    $("#form").css("display", "none");
    $("#formSubmitted").css("display", "none");
    web3.ss.getAccounts(function (e, address) {
        if (!e) {
            instance.getVote(address, function (ee, r) {
                if (r == 1) {
                    $("#myVoteUp").css("display", "block");
                } else if (r == -1) {
                    $("#myVoteDown").css("display", "block");
                } else {
                    $("#form").css("display", "block");
                }
            });
        }
    });
}

function vote (choice) {
    web3.ss.getAccounts(function (e, address) {
        if (!e) {
            $("#form").css("display", "none");
            $("#formSubmitted").css("display", "block");
            instance.vote(choice, function (ee, result) {
                if (ee) {
                    window.alert("Failed for " + address);
                }
            });
            setTimeout(function () {
                reload ();
            }, 2 * 1000);
        }
    });
    return false;
}
```

### 2.6 Click on Run to see the dapp in action! You can now vote thumb up or down inside BUIDL.

![](/files/-Lq3B9ZfurV1jk5-h-7_)

### 2.7 Finally, you can publish the dapp.&#x20;

Just click on the Publish button and give the dapp a name. Once published, you can share the published URL to the public to vote on your issue! Notice that the DevChain requires no gas to operate. So the user can vote from any of the auto-created or imported DevChain accounts.


# Ethereum Classic

Both developers and users need accounts with little ETC for gas. Metamask for ETC is supported for both developers and users.

## See the dapp in action

{% content-ref url="/pages/-Lq2p5O6GWWL3qBCS1KH" %}
[DEMO: A voting dapp](/buidl-developer-tool/demo-a-voting-dapp)
{% endcontent-ref %}

## **Step 1**&#x20;

Open the BUIDL IDE tool in any browser. <http://buidl.secondstate.io/etc>

## **Step 2**&#x20;

Open the Accounts tab and send a little ETC to your default account. If you do not have ETC, you can ask for some from <etc@secondstate.io>

{% hint style="info" %}
If you have Metamask for ETC, you could opt to use Metamask in the Providers tab. BUIDL and dapps it creates will now use the default account in Metamask to make contract calls and to pay for gas.
{% endhint %}

## **Step 3**&#x20;

### 3.1 Copy and paste the following code to the contract section of BUIDL.

The smart contract is very simple. It provides the text and image url to be voted on, and keeps a record of votes. The `vote()` method is called by voters to vote thumb up or down. The contract is to be compiled by Solidity 0.4.2, and hence the syntax is a little dated.

```typescript
pragma solidity >= 0.4.0;

contract Vote {

    string public greeting;
    string public photoUrl;
    mapping (address => int) votes;
    uint ups;
    uint downs;

    function Vote (string _greeting, string _photoUrl) public {
        greeting = _greeting;
        photoUrl = _photoUrl;
    }

    function vote (int _choice) public {
        if (votes[msg.sender] != 0) { throw; }
        if (_choice != 1 && _choice != -1) { throw; }
        votes[msg.sender] = _choice;
        if (_choice == 1) ups++;
        if (_choice == -1) downs++;
    }

    function getVotes () public constant returns (uint, uint) {
        return (ups, downs);
    }

    function getVote (address _addr) public constant returns (int) {
        return votes[_addr];
    }
}
```

{% hint style="info" %}
If you are not using MetaMask for ETC as the Provider, please open the Accounts tab and make sure that the default address has a little ETC.
{% endhint %}

### 3.2 Click on Compile and you will see the following. Enter your text and image URL to be voted on, and then click on deploy on chain.

![](/files/-Lq3ARo2YZmxvHGN7IfA)

The contract is now deployed on the ETC blockchain, and you can call its functions directly from inside BUIDL.

![](/files/-Lq3AYVxO86BrtTvxHg3)

### 3.3 Go to the dapp section. Click on the Resources tab, and add the following as resources.

* CSS: <https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css>
* JavaScript: <https://code.jquery.com/jquery-3.4.1.min.js>

### 3.4 Next, copy and paste the following HTML code into the HTML editor.

```markup
<div class="container">
   <br/>
   <div class="alert alert-primary" role="alert">If you have MetaMask for ETC, select MetaMask in the accounts widget at bottom right.</div>
   <div class="jumbotron">
      <p class="lead" id="greeting"></p>
      <div id="imageDiv" style="display:none">
         <img id="image" src="" class="img-fluid img-thumbnail"/>
      </div>
      <hr/>
      <p id="votes" style="display:none">
         <span id="ups"></span> voted 👍 |
         <span id="downs"></span> voted 👎
      </p>
      <form id="form" class="form-inline" style="display:none">
         <button id="voteUp" type="button" onclick="return vote(1);" class="btn btn-secondary mb-2">👍</button>
         <button id="voteDown" type="button" onclick="return vote(-1);" class="btn btn-secondary mb-2">👎</button>
      </form>
      <div id="formSubmitted" style="display:none">Please wait up to 42 seconds for confirmation ...</div>
      <div id="myVoteUp" style="display:none">You have already voted 👍</div>
      <div id="myVoteDown" style="display:none">You have already voted 👎</div>
   </div>
   <p>You need to pay a tiny amount of ETCs to vote. Make sure that you have at least 0.1 ETC at your current account address: <a target="_blank" href="" id="myAddr"></a></p>
   <p style="text-align:center">Created with <a target="_blank" href="https://www.secondstate.io/etc/">BUIDL for ETC</a>. Checkout the <a target="_blank" href="https://docs.secondstate.io/buidl-developer-tool/demo-a-voting-dapp/ethereum-classic">tutorial</a> to create your own!</p>
</div>
```

### 3.5 Copy and paste the following JavaScript code into the JS editor.

```javascript
var instance = null;
window.addEventListener('web3Ready', function() {
  var contract = web3.ss.contract(abi);
  instance = contract.at(cAddr);
  reload();
});

function reload() {
    instance.greeting(function (e, r) {
        $("#greeting").html(r);
    });
    instance.photoUrl(function (e, r) {
        if (!e && r) {
            $("#imageDiv").css("display", "block");
            $("#image").attr("src", r);
        }
    });
    instance.getVotes(function (e, r) {
        if (!e && (r[0] > 0 || r[1] > 0)) {
            $("#votes").css("display", "block");
            $("#ups").text(r[0]);
            $("#downs").text(r[1]);
        }
    });

    $("#form").css("display", "none");
    $("#formSubmitted").css("display", "none");
    web3.ss.getAccounts(function (e, address) {
        if (!e) {
            instance.getVote(address, function (ee, r) {
                if (r == 1) {
                    $("#myVoteUp").css("display", "block");
                } else if (r == -1) {
                    $("#myVoteDown").css("display", "block");
                } else {
                    $("#form").css("display", "block");
                }
            });
            $("#myAddr").text(address);
            $("#myAddr").attr("href", "https://blockscout.com/etc/mainnet/address/" + address);
        }
    });
}

function vote (choice) {
    web3.ss.getAccounts(function (e, address) {
        if (!e) {
            $("#form").css("display", "none");
            $("#formSubmitted").css("display", "block");
            instance.vote(choice, {
                gas: 400000,
                gasPrice: 5000000000
            }, function (ee, result) {
                if (ee) {
                    window.alert("Failed. Check if there is at least 0.1 ETC (for gas fee) in your account " + address);
                }
            });
            setTimeout(function () {
                reload ();
            }, 42 * 1000);
        }
    });
    return false;
}
```

### 3.6 Click on Run to see the dapp in action! You can now vote thumb up or down inside BUIDL.

![](/files/-Lq3B9ZfurV1jk5-h-7_)

### 3.7 Finally, you can publish the dapp.&#x20;

Just click on the Publish button and give the dapp a name. Once published, you can share the published URL to the public to vote on your issue!

{% hint style="info" %}
If the dapp user has MetaMask for ETC installed, the dapp will ask whether she would like to use her MetaMask account instead of auto-generated or imported accounts.
{% endhint %}


# CyberMiles

Developers require CMT to deploy contracts. Users can access contracts without gas.

## See the dapp in action

{% content-ref url="/pages/-Lq2p5O6GWWL3qBCS1KH" %}
[DEMO: A voting dapp](/buidl-developer-tool/demo-a-voting-dapp)
{% endcontent-ref %}

## **Step 1**&#x20;

Open the BUIDL IDE tool in any browser. <http://buidl.secondstate.io/cmt>

## **Step 2**&#x20;

Open the Accounts tab and send a little CMTs to your default account. If you do not have CMT, you can ask for some from <cmt@secondstate.io>

{% hint style="info" %}
If you have CyberMiles' Venus wallet, you could opt to use Venus in the Providers tab. BUIDL and dapps it creates will now use the default account in Venus to make contract calls and to pay for gas.
{% endhint %}

## **Step 3**&#x20;

### 3.1 Copy and paste the following code to the contract section of BUIDL.

The smart contract is very simple. It provides the text and image url to be voted on, and keeps a record of votes. The `vote()` method is called by voters to vote thumb up or down.

```typescript
pragma solidity >= 0.4.0;

contract Vote {

    string public greeting;
    string public photoUrl;
    mapping (address => int) votes;
    uint ups;
    uint downs;

    constructor(string _greeting, string _photoUrl) public {
        greeting = _greeting;
        photoUrl = _photoUrl;
    }

    function vote (int _choice) public {
        require (votes[msg.sender] == 0);
        require (_choice == 1 || _choice == -1);
        votes[msg.sender] = _choice;
        if (_choice == 1) ups++;
        if (_choice == -1) downs++;
    }

    function getVotes () view public returns (uint, uint) {
        return (ups, downs);
    }

    function getVote (address _addr) view public returns (int) {
        return votes[_addr];
    }
}
```

{% hint style="info" %}
If you are not using Venus as the Provider, please open the Accounts tab and make sure that the default address has a little CMTs.
{% endhint %}

### 3.2 Click on Compile and you will see the following. Enter your text and image URL to be voted on, and then click on deploy on chain.

![](/files/-Lq3ARo2YZmxvHGN7IfA)

The contract is now deployed on the CyberMiles blockchain, and you can call its functions directly from inside BUIDL.

![](/files/-Lq3AYVxO86BrtTvxHg3)

### 3.3 Go to the dapp section. Click on the Resources tab, and add the following as resources.

* CSS: <https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css>
* JavaScript: <https://code.jquery.com/jquery-3.4.1.min.js>

### 3.4 Next, copy and paste the following HTML code into the HTML editor.

```markup
<div class="container">
   <br/>
   <div class="jumbotron">
      <p class="lead" id="greeting"></p>
      <div id="imageDiv" style="display:none">
         <img id="image" src="" class="img-fluid img-thumbnail"/>
      </div>
      <hr/>
      <p id="votes" style="display:none">
         <span id="ups"></span> voted 👍 |
         <span id="downs"></span> voted 👎
      </p>
      <form id="form" class="form-inline" style="display:none">
         <button id="voteUp" type="button" onclick="return vote(1);" class="btn btn-secondary mb-2">👍</button>
         <button id="voteDown" type="button" onclick="return vote(-1);" class="btn btn-secondary mb-2">👎</button>
      </form>
      <div id="formSubmitted" style="display:none">Please wait 20 seconds ...</div>
      <div id="myVoteUp" style="display:none">You have already voted 👍</div>
      <div id="myVoteDown" style="display:none">You have already voted 👎</div>
   </div>
</div>
```

### 3.5 Copy and paste the following JavaScript code into the JS editor.

```javascript
var instance = null;
window.addEventListener('web3Ready', function() {
  var contract = web3.ss.contract(abi);
  instance = contract.at(cAddr);
  reload();
});

function reload() {
    instance.greeting(function (e, r) {
        $("#greeting").html(r);
    });
    instance.photoUrl(function (e, r) {
        if (!e && r) {
            $("#imageDiv").css("display", "block");
            $("#image").attr("src", r);
        }
    });
    instance.getVotes(function (e, r) {
        if (!e && (r[0] > 0 || r[1] > 0)) {
            $("#votes").css("display", "block");
            $("#ups").text(r[0]);
            $("#downs").text(r[1]);
        }
    });

    $("#form").css("display", "none");
    $("#formSubmitted").css("display", "none");
    web3.ss.getAccounts(function (e, address) {
        if (!e) {
            instance.getVote(address, function (ee, r) {
                if (r == 1) {
                    $("#myVoteUp").css("display", "block");
                } else if (r == -1) {
                    $("#myVoteDown").css("display", "block");
                } else {
                    $("#form").css("display", "block");
                }
            });
        }
    });
}

function vote (choice) {
    web3.ss.getAccounts(function (e, address) {
        if (!e) {
            $("#form").css("display", "none");
            $("#formSubmitted").css("display", "block");
            instance.vote(choice, {
                gas: 400000,
                gasPrice: 0
            }, function (ee, result) {
                if (ee) {
                    window.alert("Failed for " + address);
                }
            });
            setTimeout(function () {
                reload ();
            }, 20 * 1000);
        }
    });
    return false;
}
```

{% hint style="info" %}
On CyberMiles, we can make contract function calls with gas price set to zero. That is because CyberMiles allows gas free operations for many operations.
{% endhint %}

### 3.6 Click on Run to see the dapp in action! You can now vote thumb up or down inside BUIDL.

![](/files/-Lq3B9ZfurV1jk5-h-7_)

### 3.7 Finally, you can publish the dapp.&#x20;

Just click on the Publish button and give the dapp a name. Once published, you can share the published URL to the public to vote on your issue!

{% hint style="info" %}
If the dapp user has Venus for CMT installed, the dapp will ask whether she would like to use her Venus account instead of auto-generated or imported accounts.
{% endhint %}


# Getting started

Deploy Ethereum smart contracts and DApps using tools you already use

The Oasis Network is a high-performance and privacy-first blockchain network. It is operated by a group of independent and decentralized nodes. Each node is free to run its own software and to provide computing services to the public, as long as the network can reach a consensus on the computational results.

Second State has created the Oasis Ethereum runtime that supports both EVM and Ewasm smart contracts and dapps (decentralized applications). A network of Oasis validator nodes will deploy the Second State runtime and provide Ethereum services to the public. With BUIDL, it is a breeze to develop dapps on Oasis Network's Ethereum runtime nodes.

## Step1 Configure BUIDL for Oasis Ethereum

The easy way is to just click the link below to launch BUIDL in your browser. It pre-loads all the configurations for you.

{% embed url="<http://oasiseth.org/dev>" %}

![](/files/-MF6fX_7tCpxVLbI_8ID)

## Step 2 Get some Oasis ETH tokens for gas

In the **Accounts** tab, you will see 5 auto-generated addresses, and you can set any of them as default. The default address is used to sign transactions. Because of that, you will need to send a little Oasis ETH into that account to pay for gas fees.

![](/files/-MF6fdipeHO3vJR4c12C)

Go to the faucet website, enter your default address from BUIDL and give yourself some gas.

{% embed url="<http://faucet.oasiseth.org>" %}

![](/files/-MVvrfspEF_gWJgi6vpr)

Now, go back to BUILD's Accounts tab and you should see 0.01 OETH (or 10^18 wei) in your default address.

![](/files/-MF6g2V3uYCHlORcRshL)

## Step 3 Compile and deploy a smart contract

Click on the **Compile** button to compile the contract. A sidebar will open to show you the compiled ABI and bytecode of the contract.

![](/files/-Ljvt0TCDNmMVAyWB7Ap)

Next, you can press the **Deploy to the chain** button on the left panel to instantiate and deploy the contract to Oasis Network Ethereum runtime nodes. You can interact with deployed contracts by calling its public methods from inside [BUIDL](http://buidl.secondstate.io/) -- you can **set** its value and click on the **Transact** button to save the value onto the blockchain, and then click on the **Call** button to see the value in the **LOG** panel.

![](/files/-LjvtBzOEBmrEDsKAX9G)

## Step 4 Create an HTML Dapp

Once deployed, click on the **dapp** button on the left bar to work on your DApp.

![](/files/-LjvtS5gzcg150d5Y5yC)

The HTML tab above shows a simple HTML page with two buttons.

Next, go to the JS tab. It shows JavaScript on how to interact with the smart contract. It provides event handlers for the buttons. When a user clicks on the button, the JavaScript calls the smart contract functions via the web3 library.

![](/files/-MF6j7TcNY0EfPe9kMI0)

Finally, click on the **Run** button to run the DApp. You will see the DApp UI in the right panel. You can click on the **Set Data** button to store a number, and **Get Data** button to retrieve the stored number.

![](/files/-LjvviN3FlXf14V8PpSB)

Congratulations. You now have a complete DApp deployed on the Oasis Network!

Next, you can go through our tutorials to create and publish a [decentralized social media app](/oasis-network-ethereum-runtime/tutorial-oasistweet) or your own [ERC-20 tokens to be traded on Uniswap](/oasis-network-ethereum-runtime/tutorial-erc20)!


# Tutorial: publish a decentralized social media post

Complete this tutorial and share your own message on social media. People have to pay you to comment on your post -- no spam!

Today’s big tech social media are plagued by the twin evil of censorship and hate speech. Is there a way to make it easy for everyone to express themselves, but also make it hard to spam and bully? Blockchain technology is here to rescue. Public blockchains, like the Oasis network, are censorship-resistant and have built-in economic incentives to punish bad behaviors.

In this tutorial, we will show you how to publish your opinions and thoughts on the Oasis Ethereum ParaTime blockchain. While anyone can comment on your publishes messages, they will have to pay you a price you ask for in order to have their message recorded. Complete this tutorial and share your own message on social media.

Intrigued? Let’s get started.

{% embed url="<https://youtu.be/pCT5Ej-6N7k>" %}

## Load the IDE

You can load the web-based IDE by going to the link below. There is no software to download!

{% embed url="<http://oasiseth.org/dev/hack>" %}
Start the IDE in your browser. No software download is needed!
{% endembed %}

Now you can see two sample projects. The first one is a simple “hello world” to show you the very basics of an Ethereum smart contract and Dapp. For the purpose of this tutorial, select the second sample app called OasisTweet.

![Figure 1. Select the OasisTweet project](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Ljq8VpUhFWpzGRMLvdp%2Fuploads%2FiwzYt5bJpci5vYa5ptua%2Ffile.png?alt=media)

## Get some OETH from a faucet

Since this is the first time you start this IDE, it creates several new Ethereum account addresses for you to use. You will need to have some OETH tokens in those accounts so that you can pay “gas” to deploy and use your smart contracts. Click on the **Accounts** tab on the IDE and copy the selected default address.

![Figure 2. The auto-generated addresses](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Ljq8VpUhFWpzGRMLvdp%2Fuploads%2FgZqLGBjBBAW4fPa44IH2%2Ffile.png?alt=media)

Next, go to the OETH developer faucet below, and paste your address. It takes about 10 seconds for the OETH to be deposited into your account.

{% embed url="<http://faucet.oasiseth.org/>" %}
The Oasis ETH (OETH) faucet for developers
{% endembed %}

![Figure 3. Get 0.01 OETH for your account address](/files/-MVvs5go9DAnd-N_OgCv)

## Solidity smart contract

Now, let's go back to the IDE, and review the smart contract. As you can see, it has data fields for an URL to an image and text message. The image and the message will be recorded on the blockchain and displayed on the Dapp web page you create later.

It also has an array called `comments`. It allows any user to leave a comment on your Dapp web page. However, it is important to notice the price field and the `addComment()` function. The user must pay the `price` amount of OETH to YOU in order to leave a comment on your page!

```
contract OasisTweet {
    address owner;
    string public message;
    string public image;
    uint256 public price;
    struct Comment {
        string name;
        string comment;
        bool isValue;
    }
    mapping (address => Comment) comments;

    ... ...

    function OasisTweet (string _message, string _image, uint256 _price) public {
        owner = msg.sender;
        message = _message;
        image = _image;
        price = _price;
    }

    function addComment (string _name, string _comment) public payable {
        require(msg.value >= price);
        if (!comments[msg.sender].isValue) {
            addrs.push(msg.sender);
        }
        comments[msg.sender] = Comment(_name, _comment, true);
    }
}
```

## Deploy the smart contract

Click on the **Compile** button and the IDE compiles the smart contract into Ethereum bytecode.

![Figure 4. Compile the smart contract](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Ljq8VpUhFWpzGRMLvdp%2Fuploads%2FiJgWnnl41fLy7EotTNI5%2Ffile.png?alt=media)

Before you deploy the contract to the blockchain, fill out your message, image URL, and price you demand for each comment. Those will be stored on the blockchain with the contract.

![Figure 5. Populate your message, image URL, and price before deploying the contract.](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Ljq8VpUhFWpzGRMLvdp%2Fuploads%2FKh42YezwqGx340TrAImX%2Ffile.png?alt=media)

Then click on the **Deploy on the chain** button to deploy the smart contract to the Oasis Ethereum ParaTime blockchain. It will take about 10 seconds to confirm the contract by Oasis blockchain validators. You will see a success message in the log panel. If you encounter an error at this point, make sure that your default account has an OETH balance!

![Figure 6. Successful deployment of the contract. You must have OETH in your default address.](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Ljq8VpUhFWpzGRMLvdp%2Fuploads%2FXhvCSk8xt7hEpv0VKEVy%2Ffile.png?alt=media)

## Web app

Next, let’s build a web UI that interacts with the on-chain smart contract we just deployed. Switch over to the Dapp tab. The HTML section is the web page. All the data fields such as image URL, message, and comments are HTML placeholders and will be filled in by JavaScript in the JS tab.

![Figure 7. The web app has HTML and JS sections](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Ljq8VpUhFWpzGRMLvdp%2Fuploads%2FxYQNhYJqBWD5TQNrvCwl%2Ffile.png?alt=media)

The `reload()` function in the JavaScript loads data from the blockchain contract and populates them on the HTML page. Pay attention to the `instance.addComment()` function. It takes a user comment from the web form and sends it to the contract in a transaction. In the transaction, the user pays price OETH to the contract in addition to gas fees to the network.

```
var contract = web3.ss.contract(abi);
instance = contract.at(cAddr);

instance.message(function (e, r) {
    $("#message").html(r);
});
instance.image(function (e, r) {
    $("#image").prop("src", r);
});
instance.price(function (e, r) {
    price = r;
    $("#pricealert").html("Requires " + price + " wei to comment");
});

instance.addComment ($("#name").val(), $("#comment").val(), {
    value: price,
    gas: 499000,
    gasPrice: 1
}
```

## Try the web app

Click on the **Run** button on the IDE to run the web app. You will see the web page in the right panel of the IDE. You can now interact with it by paying and leaving a comment.

![Figure 8. Run the Dapp web UI in the IDE](/files/-MJ8qVjwmNWi2h9kSvfX)

## Publish it

Finally, you are ready to publish your Dapp! You can take the HTML and JS content and put them on any static web page host. Or, you can click on the **Publish** button on the IDE.

![Figure 9. Publish the Dapp web page](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Ljq8VpUhFWpzGRMLvdp%2Fuploads%2FORq7PhAMUhYUsZhzdAjA%2Ffile.png?alt=media)

The published web page is [a link you can share anywhere](https://opendapps.secondstate.io/Oasis_Demo_1602110987953.html). For users who want to leave a comment, they will need a MetaMask wallet connected to Oasis Ethereum, or fund OETH in their default address on the web page.

![Figure 10. The Dapp web page is accessible to all. But commenters need to pay OETHs.](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Ljq8VpUhFWpzGRMLvdp%2Fuploads%2FyfNwNLW2At8YL51PUEpm%2Ffile.png?alt=media)

Next, create and deploy an [ERC-20 contract, and add the ERC-20 tokens to Oasis Uniswap for trading](/oasis-network-ethereum-runtime/tutorial-erc20)!

{% embed url="<https://youtu.be/O11_o5chHL4>" %}

Happy coding!


# Tutorial: mint and trade your own ERC-20 tokens

Deploy an ERC-20 contract and trade the tokens on Uniswap on Oasis Ethereum ParaTime!

This tutorial will walk you through the following tasks.

1. How to issue an ERC20 token on Oasis Ethereum ParaTime. You will get 100 to 500 ROSE after completing this step.
2. Build a liquidity pool on Uniswap, trade your ERC20 tokens and OETH, you will get 400 ROSE.

## Deploy the ERC20 smart contract

Oasis Ethereum ParaTime is fully compatible with Ethereum, so ERC20 contracts written in solidity can be deployed directly to Oasis Ethereum ParaTime without any changes.

This part can still be developed using the development tool, [BUIDL](http://oasiseth.org/dev/hack), that has been configured for the development environment.

### **Step 1 Set up MetaMask**

> :warning: **Warning**: Pasting the private key of an account with a lot of value (i.e. a holding account) is not recommended whatsoever. Instead, please only transfer a tiny amount of value to a **new one-off development account** address and only use this new development account when writing and deploying your contracts. After all, you only need enough value to pay for gas; nothing else. Keep your holding account safe by never sharing its private keys.

It is recommended that the third challenge to be completed with MetaMask wallet because our newly issued ERC20 token is under the created address, which is easier.

Open **MetaMask**, and select **custom RPC**. Enter the network name and add the RPC link of Oasis Ethereum: <https://rpc.oasiseth.org:8545>, and make sure that MetaMask is in the Oasis Ethereum environment.

![](/files/-MJrSo7wt9zuowhfS_5s)

Then deposit 1 OETH to this MetaMask account from the OETH developer faucet.

{% embed url="<http://faucet.oasiseth.org/>" %}

### **Step 2 Import the MetaMask account address into the BUIDL Account**

### ![image.png](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Ljq8VpUhFWpzGRMLvdp%2Fuploads%2FG3sd3R1VA1PHeh2I6BB8%2Ffile.png?alt=media)

Click to open “**account**”, select **Import,** import the MetaMask private key just set up into the BUIDL account, and prepare for the deployment of ERC20 contracts to pay gas fees.

### Step 3 compile and deploy the smart contract

You can load the web-based IDE by going to the link below. There is no software to download!

{% embed url="<http://oasiseth.org/dev/hack>" %}
Start the IDE in your browser. No software download is needed!
{% endembed %}

Select the ERC-20 sample project from the menu.

![](/files/-MJrTCYbOwgIPpr9edfn)

> Tips: Now you can choose the solidity language version on BUIDL.

The smart contract source code is as follows.

```
contract TestToken is PausableToken {

  string public name = "Test Token";
  string public symbol = "TTT";
  uint public decimals = 10;
  uint public totalSupply = 100000000000000000000;

  constructor () public {
    balances[msg.sender] = totalSupply;
  }
}
```

At the end of the contract code, `contract TestToken` is the specifics of ERC20 tokens. Here, tweak the code to customize the name of the ERC20 token to your preferences, symbol, decimal, and total supply.

Click the **Compile** button and select TestToken to deploy to the blockchain.

![Depoly the ERC20 Token](/files/-MJrTNfFXF3TMwI8lj8n)

After the deployment is successful, the task of issuing ERC 20 tokens on Oasis Ethereum ParaTime is nailed. Please note that the *token address* here needs to be saved and used when adding tokens in MetaMask. Also, this address also needs to be submitted to the organizer when filling this form.

![](/files/-MJrLNQPGu9dUGN6z79_)

The next step is to complete the task for bonus rewards: building a liquidity pool for your ERC20 tokens on Uniswap, and start transactions.

## Add a Liquidity pool on Uniswap

To create a liquidity pool for tokens on Uniswap, you need to work with MetaMask. Please ensure that MetaMask is connected to the beta version of the Oasis Ethereum mainnet.

### **Step 1 Add the ERC20 token you just issued in MetaMask**

![](/files/-MJrTssboHU8RXycxbFE)

Under the current account, slide to the end, click **Add Token**—>**Custom Token**, and fill the **token address** just saved before. The decimal *\*\**&#x61;nd symbol of your token will be automatically added.

### **Step 2 Create Exchange for your Token**

Open Website: <https://uniswap.oasiseth.org/swap>, go to **Pool**.

<https://uniswap.oasiseth.org/swap>

Click **Add Liquidity**, select **Create Exchange** in the pop-up option box, and then add the token address just saved. Then click **Create Exchange** and click **Confirm** to pay the gas fee.

![Create Exchange](/files/-MYhM3qOk0DcyoJQ92Cf)

### **Step 3 Create a liquidity pool**

Return to the **Pool** page, click **Add Liquidity**, and select **Add Liquidity** in the opened options. Select the token issued by yourself at the deposit place below and click **Unlock**.

![Unlock your Token](/files/-MJrPdGkT41alsxtXDoz)

After clicking **Unlock**, MetaMask will automatically launch a transaction prompt. Here, MetaMask is authorized to manage the previous MFT of Uniswap.

After the word “unlock” disappears, you can set any exchange ratio between the token you issued and OETH, and finally, click **Add Liquidity** at the bottom to generate a liquidity pool.

![](/files/-MJrQVLrjcUlSrjs6_Cg)

### **Step 4 Swap with OETH**

Go to **Swap**, enter the amount of OETH you want to exchange, and Uniswap will automatically convert the amount at the ratio set immediately. Click the **Swap** button to trade the token you just issued with OETH in Uniswap.

![](/files/-MJrQjQDHn2Dz1BIFQSO)

Now you have minted and traded your own tokens on the Oasis Ethereum ParaTime! You can watch the YouTube video below to review the entire process.

{% embed url="<https://www.youtube.com/watch?v=O11_o5chHL4&feature=emb_title>" %}

Happy coding!


# Tutorial: mint and transfer your own ERC-721(NFT) tokens

> Mint an ERC-721 token to represent your digital asset on the Oasis Ethereum ParaTime, and send this newly minted unique token to friends and family! Could worth millions one day, who knows?

This tutorial will walk you through the following tasks.

* How to deploy an ERC-721 smart contract on Oasis Ethereum ParaTime Mainnet.
* Mint an ERC-721 token with an associated digital asset.
* Transfer the ERC-721 Token to another person.

## What is an ERC-721 Token？

[ERC721 tokens,](https://education.district0x.io/general-topics/understanding-ethereum/erc-721-tokens) more commonly known as Non-Fungible tokens (NFTs), have captured developers’ imagination since it was first introduced as an EIP in September of 2017. Non-Fungible tokens allow issuers to tokenize the ownership of digital assets, drastically increasing the design space of what can be represented as a token on the Ethereum and EVM-compatible blockchain.

## **Deploy the ERC-721 smart contract**

Oasis Ethereum ParaTime is fully compatible with the Ethereum protocol. ERC721 smart contracts written in Solidity can be deployed directly to Oasis Ethereum ParaTime without any changes.

You can use an online IDE tool called BUIDL to code and deploy an ERC-721 smart contract on Oasis Ethereum.

{% embed url="<http://oasiseth.org/dev/hack>" %}

**Step 1 Set up MetaMask**

Open **MetaMask**, and select **custom RPC**. Enter the network name and add the RPC link of Oasis Ethereum: [*https://rpc.oasiseth.org:8545*](https://rpc.oasiseth.org:8545/)*.* That configures the MetaMask wallet to use the Oasis Ethereum blockchain.

![](/files/-MWFWJdHxczuBmzwSotU)

Then deposit 0.01 OETH to this MetaMask account from t[he OETH developer faucet.](http://faucet.oasiseth.org/)

You can export the private key of this account via MetaMask’s "Account details" menu.

> :warning: **Warning**: Pasting the private key of an account with a lot of value (i.e. a holding account) is not recommended whatsoever. Instead, please only transfer a tiny amount of value to a **new one-off development account** address and only use this new development account when writing and deploying your contracts. After all, you only need enough value to pay for gas; nothing else. Keep your holding account safe by never sharing its private keys.

### Step 2 Import the MetaMask account address into the BUIDL Account

Next open the BUIDL online IDE for Oasis Ethereum.

{% embed url="<http://oasiseth.org/dev/hack>" %}

Click to open “**account**”, select **Import,** import the MetaMask private key, and you will see your MetaMask account address in BUIDL. You will use this account address to deploy ERC-721 contracts and to mint the NFT tokens.

![](/files/-MWFVp7bfPyd51r39NCn)

### Step 3 compile and deploy the smart contract

Next, choose the Solidity language compiler version in BUIDL. Choose Solidity 0.4.26 here.

![](/files/-MJrTCYbOwgIPpr9edfn)

Copy and paste the source code into the Contract Tab.

> You can find the ERC-721 smart contract source code [here](https://github.com/second-state/oasis-ssvm-runtime/wiki/ERC-721-Smart-Contract).

```
......

contract MyNFT is ERC721Full, ERC721Mintable {
    constructor() ERC721Full("MyNFT", "MNFT") public {
  }


  function mintToken(address to, uint256 tokenId, string uri) public {
      mint(to, tokenId);
      require(_exists(tokenId));
      _setTokenURI(tokenId, uri);
  }
  function burnToken(address owner, uint256 tokenId) public {
      _burn(owner, tokenId);
  }

}
```

At the end of the contract code, `contract MyNFT` is to mint the ERC-721 tokens. Here, you can specify a symbol for your ERC-721 tokens.

Click the **Compile** button and select MyNFT to deploy to the blockchain.

![](/files/-MWFWomxk8q1bhyBmut7)

The deployment is successful, and you are now half way through issuing ERC-721 tokens on Oasis Ethereum ParaTime. Call the `totalSupply` function in BUIDL, and see that it returns 0. There is no token in this contract yet. The next step is to mint ERC-721 tokens with digital assets.

![](/files/-MWFX5wnGTjkSPcJqD8h)

Go to the `mintToken` function. Enter an address in `to` to assign the owner of the new ERC721 token. Enter an integer number in `tokenId` to set the unique id of the ERC721 token. Enter the URL of your digital asset, such as an image or a video, in `uri` to associate the digital asset with the ERC721 token.

Click the Transact button to mint the ERC-721 token. If you want to mint more ERC-721 tokens, simply set other `to, tokenId, uri` parameters in the `mintToken` function. Please note, every token id can only correspond to one digital asset URL. If you want to mint a new ERC-721 token for a new URL, you need to use a different token id.

![](/files/-MWFXMepEWw59Btjaa7R)

After the Tx is confirmed, we can check the status of the deployed ERC-721 contract and the minted ERC-721 token.

Call the `totalSupply` function again, and it returns 1 this time.

![](/files/-MWFXXfhHCnBwAcoesrv)

Enter the tokenId and call the `ownerOf` function. It returns the address we just entered in the `mintToken` function.

![](/files/-MWFXmrZDRWW1Zjcpgo6)

Enter the tokenId and call the `tokenURI` function, it returns the URL we just entered in the `mintToken` function.

![](/files/-MWFXzGv67zZQLFGYk7e)

## Transfer the ERC-721 Token

### Step 1 Get the permission to transfer the ERC-721 Token

The `approve` function gives permission to `to` to transfer `tokenId` token to another account. The function caller must own the `tokenId` token. So we need to import the private key of the owner account of `tokenId` token into BUIDL.

**How to deploy the contract**

> Please ignore this step if you use the same account to deploy the ERC-721 smart contract and receive the minted ERC 721 Token. Just call the `approve` function.

1. Copy the ERC 721 smart contract address.
2. Import your account that received the ERC-721 token.
3. Copy and paste the same smart contract source code.
4. Click the Compile button and choose MyNFT.
5. Paste the ERC 721 contract address and click At. Now, we have an instance to the deployed ERC 721 contract in BUIDL.

![](/files/-MWFYNGOVhUVyF8QLD4L)

We see the previously deployed ERC-721 contract.

![](/files/-MWFckgFRVxDx1lmM9rS)

Go to the `approve` function. Enter an address in `to` to assign the receiver of the given ERC721. Enter the id in `tokenId` to transfer the unique NFT Token. Different `tokenId` means different NFT Tokens.

![](/files/-MWFd0VXFr4hxnp57tx6)

### Step 2 Transfer the ERC-721 Token

The `safeTransferFrom` function transfers `tokenId` token from `from` to `to`.

Enter the owner's address in `from`. Enter the receiver address in `to` . Enter the id in `tokenId`. The three parameters will make sure you are transferring the correct NFT Token.

![](/files/-MWFdDpx4G20IHQC-iaO)

We can call `ownerOf` and `balanceOf` functions to see the status of the given token. The owner of the given token has been transferred to `0xbf9a58574aab193f0c442f6f7dea22ec413db648`.

![](/files/-MWFdQGtV0b-YrrWVTP9)

### Next Step

We will create a web-based Dapp to display and send your NFTs. Stay tuned!

Please remember to save your `token address` and `tokenId`, which need to be submitted to the [hackathon](https://oasisprotocol.org/oasis-eth-hackaton-tcs) organizer through this form.

{% embed url="<https://oasisprotocol.org/oasis-eth-hackaton-tcs>" %}


# Ethereum flavored WebAssembly (Ewasm)

Ewasm is the next generation Ethereum virtual machine.

The Ewasm is the future of Ethereum smart contracts and applications. It is highly-efficient, supported by the mainstream tech communities, and could support more programming languages on the frontend.

## Step 1 Compile your smart contract to WebAssembly bytecode

Here is a [simple ERC20 smart contract](https://github.com/second-state/oasis-ssvm-runtime/blob/ssvm/resources/erc20/erc20.sol) written in Solidity. Compiling it with the [Second State SOLL compiler](https://github.com/second-state/SOLL), you will get a [WebAssembly bytecode](https://github.com/second-state/oasis-ssvm-runtime/blob/ssvm/resources/erc20/erc20.wasm) file. Then, convert it to [HEX text](https://github.com/second-state/oasis-ssvm-runtime/blob/ssvm/resources/erc20/erc20.hex) so that we can deploy via web3 JavaScript.

* [erc20.sol](https://github.com/second-state/oasis-ssvm-runtime/blob/ssvm/resources/erc20/erc20.sol)
  * This file is an ERC20 contract written in Solidity.
* [erc20.wasm](https://github.com/second-state/oasis-ssvm-runtime/blob/ssvm/resources/erc20/erc20.wasm)
  * This file is a wasm file generate from `erc20.sol` by [SOLL](https://github.com/second-state/soll)
  * Command to generate wasm file: `soll -deploy=Normal erc20.sol`
* [erc20.hex](https://github.com/second-state/oasis-ssvm-runtime/blob/ssvm/resources/erc20/erc20.hex)
  * To deploy wasm file to our node, we need to convert `erc20.wasm` to hex.
  * Command to generate hex file: `xxd -p erc20.wasm | tr -d $'\n' > erc20.hex`

## Step 2 Deploy the contract via web3

The Node.js application [`deploy_contract.js`](http://buidl.secondstate.io/oasis-testnet/deploy_contract.js) deploys the ERC20 smart contract to the mainnet node. It uses the HEX bytecode from SOLL, as well as the private key from a known address to pay for "gas", and then initiate a coin transfer transaction.

```
$ node deploy_contract.js

Web3 is connected.
accounts: ["0x1BbE5edc5Caabf4517e40b766D64c3DEd86822Df"]
Contract created at 0x984718904f853A004F145d133dEAb0c1dE50466B
contract.balanceOf(0x1BbE5edc5Caabf4517e40b766D64c3DEd86822Df) = 1000
```

## Step 3 Make an ERC20 coin transfer

The Node.js application [`transfer_erc20.js`](http://buidl.secondstate.io/oasis-testnet/transfer_erc20.js) makes a transfer from the ERC20 contract we just created. It transfers from the contract creator's address, which we know the private key of, to another address, and then prints the balance. The first argument is the ERC20 contract address, the second argument is the TO address that receives the ERC20 tokens, and the third argument is the amount of ERC20 tokens to transfer.

```
$ node transfer_erc20.js 0x984718904f853A004F145d133dEAb0c1dE50466B 0x987652e1C2B3B953354A43171063499DCE16dC8f 10

Web3 is connected.
accounts: ["0x1BbE5edc5Caabf4517e40b766D64c3DEd86822Df"]
Contract instaniated at 0x984718904f853A004F145d133dEAb0c1dE50466B

Initial balances
0x1BbE5edc5Caabf4517e40b766D64c3DEd86822Df = 1000
0x987652e1C2B3B953354A43171063499DCE16dC8f = 0
Transfer 10 token from address(0x1BbE5edc5Caabf4517e40b766D64c3DEd86822Df) to address(0x987652e1C2B3B953354A43171063499DCE16dC8f)

End balances
0x1BbE5edc5Caabf4517e40b766D64c3DEd86822Df = 990
0x987652e1C2B3B953354A43171063499DCE16dC8f = 10
```

This is just a taste of the future. As Ewasm evolves, we will see many more smart contracts and dapps written in WebAssembly in the future.


# Getting started

Create and deploy a blockchain in 10 minutes

This document describes how to get started with application development on the Second State DevChain. The Second State DevChain features a powerful and easy-to-use virtual machine that can quickly get you started with smart contract and DApp development.

{% hint style="info" %}
With the [Second State Blockchain as a Service (BaaS)](/devchain/baas), you can start a new Second State blockchain with its innovative virtual machines and smart contract search engines with one click of the mouse.
{% endhint %}

In this document, we will explain how to create and run the Second State blockchain. You can then connect and test basic features such as coin transactions and smart contract functions.

The easiest way to get started is to use our pre-build Docker images. Please make sure that you have [Docker installed](https://docs.docker.com/install/) and that your [Docker can work without sudo](https://docs.docker.com/install/linux/linux-postinstall/).

For example, on Ubuntu, you can use the following commands.

```bash
$ sudo apt install docker.io
$ sudo usermod -a -G docker $USER
$ docker pull secondstate/devchain:devchain
```

### Initialize

Let’s initialize the DevChain configuration and genesis settings.

```bash
$ docker run --rm -v $HOME/.devchain:/devchain secondstate/devchain:devchain node init --home /devchain
```

Note: If you are running a cluster, you should now copy over the cluster wide `genesis.json` and `config.toml` files to the `$HOME/.devchain/config` directory.

### Run

Now you can start the DevChain node in docker.

```bash
$ docker run --rm -v $HOME/.devchain:/devchain -p 26657:26657 -p 8545:8545 secondstate/devchain:devchain node start --home /devchain
```

You should see blocks like the following in the log.

```
INFO [07-14|07:23:05] Imported new chain segment               blocks=1 txs=0 mgas=0.000 elapsed=431.085µs mgasps=0.000 number=163 hash=05e16c…a06228
INFO [07-14|07:23:15] Imported new chain segment               blocks=1 txs=0 mgas=0.000 elapsed=461.465µs mgasps=0.000 number=164 hash=933b97…0c340c
```

### Connect

Next, open another terminal window to interact with the running node.

You can get the ID of the running Docker container.

```bash
$ docker container ls
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                                                         NAMES
0bcd9da5bf05        secondstate/devchain   "./devchain node sta…"   4 minutes ago       Up 4 minutes        0.0.0.0:8545->8545/tcp, 0.0.0.0:26657->26657/tcp, 26656/tcp   pedantic_mendeleev
```

Next, log into that container.

```bash
$ docker exec -i -t 0bcd9da5bf05 bash
root@0bcd9da5bf05:/app# ls
devchain  devchain.sha256  lib
```

Finally, you can attach a console to the node to run web3 commands.

```bash
root@0bcd9da5bf05:/app# ./devchain attach http://localhost:8545
...
> cmt.syncing
{
  catching_up: false,
  latest_app_hash: "C7D8AECE081DF06FFC9BF6144A50B37CA5DD8A8E",
  latest_block_hash: "B592D63AB78C571E0FB695A052681E65F6DFE15B",
  latest_block_height: 35,
  latest_block_time: "2019-05-04T02:59:30.542783017Z"
}
```

### Test accounts

If you go with the default setup, the chain starts with two accounts that already have CMT balances (CMT is the native currency here).

* 0x77beb894fc9b0ed41231e51f128a347043960a9d is the coinbase account with 10,000,000,000,000,000 CMTs.
* 0x7eff122b94897ea5b0e2a9abf47b86337fafebdc is a validator account with 10,000,000,000,000,000 CMTs.

{% hint style="danger" %}
You MUST NOT use those two addresses in your production systems. Their private keys are well known and anyone could move fund from them!!! To create a new blockchain with your own genesis accounts, you will need to use this tool to create new config files.
{% endhint %}

We already put keystore files for the two default genesis accounts in your `.devchain/keystore` directory. The passphrase to both keystores are `1234`.

```typescript
$ ls .devchain/keystore
UTC--2016-10-21T22-30-03.071787745Z--7eff122b94897ea5b0e2a9abf47b86337fafebdc
UTC--2018-04-09T09-48-47.241470000Z--77beb894fc9b0ed41231e51f128a347043960a9d
```

Next, you can paste the following script into the client console, at the > prompt.

```typescript
function checkAllBalances() {
  var totalBal = 0;
  for (var acctNum in cmt.accounts) {
      var acct = cmt.accounts[acctNum];
      var acctBal = web3.fromWei(cmt.getBalance(acct), "cmt");
      totalBal += parseFloat(acctBal);
      console.log("  cmt.accounts[" + acctNum + "]: \t" + acct + " \tbalance: " + acctBal + " CMT");
  }
  console.log("  Total balance: " + totalBal + "CMT");
};
```

You can now run the script in the console, and see the results.

```typescript
> checkAllBalances();
  cmt.accounts[0]: 	0x7eff122b94897ea5b0e2a9abf47b86337fafebdc 	balance: 10000000000000000 CMT
  cmt.accounts[1]: 	0x77beb894fc9b0ed41231e51f128a347043960a9d 	balance: 10000000000000000 CMT
  Total balance: 20000000000000000CMT
```

Aside from the default public (UNSECURE) accounts, you can create your own accounts like the following. The keystore for the newly created accounts will be in your local `.devchain/keystore` folder.

```typescript
> personal.newAccount("mypass")
"0x6fa1f61bfb38b204d1b44b0116a166155bb4a161"
```

Those accounts start from 0 CMT balance, and you will need to transfer CMTs from the genesis accounts for them to be useful.

### Test transactions

You can now send a transaction between accounts like the following. Again, the passphrase is `1234` for the unsecure public keystores.

```typescript
personal.unlockAccount("from_address")
Passphrase:
cmt.sendTransaction({"from": "from_address", "to": "to_address", "value": web3.toWei(0.001, "cmt")})
```

Next, run the `checkAllBalances()` script in the console, and see the results.

```typescript
> checkAllBalances();
cmt.accounts[0]:      0x6....................................230      balance: 466.798526 CMT
cmt.accounts[1]:      0x6....................................244      balance: 1531 CMT
Total balance: 1997.798526CMT
```


# Run an ewasm smart contract

Next generation Ethereum smart contracts at your finger tip

One of the key features of the Second State DevChain is its support for the next-gen Ethereum virtual machine, Ewasm. Smart contracts compiled to Ewasm can be deployed on the DevChain.&#x20;

{% embed url="<https://youtu.be/1RRt3UrUXAg>" %}
Run a ERC20 EWASM smart contract now!
{% endembed %}

{% hint style="warning" %}
Before you start, please make sure that you have a Second State DevChain up and running. If not, follow the [Getting Started tutorial](https://docs.secondstate.io/devchain/getting-started). It takes about 10 minutes.
{% endhint %}

You can use the [SOLL compiler](https://github.com/second-state/soll) to compile Solidity or YUL source code to Ewasm bytecode. Follow the[ instructions here](https://github.com/second-state/SOLL/blob/master/README.md). The Solidity source code the smart contract is as follows. It is a simplified ERC20 contract.

```
pragma solidity ^0.5.0;
contract Token {
	uint256 private totalSupply;
	string public name;
	string public symbol;
	mapping(address => uint256) public balances;

	event Transfer(address indexed _from, address indexed _to, uint256 _value);

	// Safemath
	function add(uint256 a, uint256 b) internal pure returns (uint256) {
		uint256 c = a + b;
		require(c >= a, "SafeMath: addition overflow");

		return c;
	}

	function sub(uint256 a, uint256 b) internal pure returns (uint256) {
		require(b <= a, "SafeMath: subtraction overflow");
		uint256 c = a - b;

		return c;
	}

	constructor() public {
		totalSupply = 100000000;
		name = "ERC20TokenDemo";
		symbol = "ETD";
		balances[msg.sender] = totalSupply;
	}

	function balanceOf(address account) view public returns (uint256) {
		return balances[account];
	}

	function transfer(address to, uint256 amount) public returns (bool) {
		balances[msg.sender] = sub(balances[msg.sender], amount);
		balances[to] = add(balances[to], amount);
		emit Transfer(msg.sender, to, amount);
		return true;
	}

	function () external payable {}
}
```

The compiled ewasm bytecode is converted to text using the `xxd` tool.

```
$ xxd -p contract.wasm | tr -d $'\n'
0061736d0100000001270760027f7f0060000060017f0060037f7f7f0060057f7e7e7e7e0060047e7f7f7f017f6000017e02c7010908657468657265756d0c67657443616c6c56616c7565000208657468657265756d0c73746f7261676553746f7265000008657468657265756d0967657443616c6c6572000208657468657265756d0a6765744761734c656674000608657468657265756d0a63616c6c537461746963000508657468657265756d0e72657475726e44617461436f7079000308657468657265756d0b73746f726167654c6f6164000008657468657265756d06726576657274000008657468657265756d0666696e697368000003040304010105030100020608017f0141e0ad040b071102066d656d6f72790200046d61696e000b0abf0d038d0300200020044228884280fe03832004421888428080fc0783200442088842808080f80f8320044208864280808080f01f832004421886428080808080e03f83200442288642808080808080c0ff00832004423886200442388884848484848484370300200041186a20014228884280fe03832001421888428080fc0783200142088842808080f80f8320014208864280808080f01f832001421886428080808080e03f83200142288642808080808080c0ff00832001423886848484848484200142388884370300200020024228884280fe03832002421888428080fc0783200242088842808080f80f8320024208864280808080f01f832002421886428080808080e03f83200242288642808080808080c0ff00832002423886848484848484200242388884370310200020034228884280fe03832003421888428080fc0783200342088842808080f80f8320034208864280808080f01f832003421886428080808080e03f83200342288642808080808080c0ff008320034238868484848484842003423888843703080ba00a02067f087e23004190026b220024002000220141c8016a100020012903c801200141d0016a29030084500440200041606a220322022400200241606a220422052400200241786a4280808080d0a0fdf000370300200241706a4200370300200241686a420037030020044200370300200041786a4200370300200041706a4200370300200041686a4200370300200342003703002003200410012005220041606a2202220324002000416c6a41edde013b0100200041686a220441e5dc91aa06360200200242c5a48d928386d5b7eb00370300200041786a220220022903004280808080808080801c84220637030020042903002107200041706a29030021082003220041606a220322022400200241606a220422052400200241786a2006370300200241706a2008370300200241686a2007370300200442c5a48d928386d5b7eb00370300200041786a42808080808080808001370300200041706a4200370300200041686a4200370300200342003703002003200410012005220041606a220222032400200041626a41c4003a0000200241c5a8013b0100200041786a220420042903004280808080808080800684220637030020022903002107200041686a2903002108200041706a29030021092003220041606a220322022400200241606a220422052400200241786a2006370300200241706a2009370300200241686a200837030020042007370300200041786a42808080808080808002370300200041706a4200370300200041686a4200370300200342003703002003200410012005220041606a22022203240020021002200141a8016a4200200229030022064220862006422088200041686a290300220642208684200041706a350200422086200642208884100920014188016a20012903a801200141b0016a290300200141b8016a3502004200100920014190016a290300210620014198016a2903002107200141a0016a290300210820012903880121092003220041406a220222032400200041786a42808080808080808003370300200041706a4200370300200041686a4200370300200041606a4200370300200041586a2008370300200041506a2007370300200041486a2006370300200220093703002001420037038002200142003703f801200142808080103e0288021003200141f8016a200241c00010041a200141d8016a410041201005200141e8006a20012903d801200141e0016a290300200141e8016a290300200141f0016a290300100920014180016a2903002106200141f8006a2903002107200141f0006a2903002108200129036821092003220041606a220322022400200241606a220422052400200041786a4200370300200041706a4200370300200041686a420037030020034200370300200320041006200141c8006a2004290300200241686a290300200241706a290300200241786a2903001009200141286a20092008200720061009200141306a2903002106200141386a2903002107200141406b290300210820012903282109200141086a2001290348200141d0006a290300200141d8006a290300200141e0006a2903001009200141106a290300210a200141186a290300210b200141206a290300210c2001290308210d2005220041606a220322022400200241606a22042400200241786a200c370300200241706a200b370300200241686a200a3703002004200d370300200041786a2008370300200041706a2007370300200041686a20063703002003200937030020032004100120014190026a24000f0b41800841171007000b0c00100a41970841c42510080b0be32501004180080bdb2546756e6374696f6e206973206e6f742070617961626c650061736d0100000001460b60027f7f0060017f0060037f7f7f0060000060077f7f7f7f7f7f7f0060047f7e7e7e0060057f7e7e7e7e0060077e7e7e7e7e7e7e006000017f60047e7f7f7f017f6000017e0289020c08657468657265756d0c67657443616c6c56616c7565000108657468657265756d0a6765744761734c656674000a08657468657265756d0a63616c6c537461746963000908657468657265756d0e72657475726e44617461436f7079000208657468657265756d0b73746f726167654c6f6164000008657468657265756d06726576657274000008657468657265756d0967657443616c6c6572000108657468657265756d0c73746f7261676553746f7265000008657468657265756d036c6f67000408657468657265756d0f67657443616c6c4461746153697a65000808657468657265756d0c63616c6c44617461436f7079000208657468657265756d0666696e69736800000305040605070305030100020608017f0141f088040b071102066d656d6f72790200046d61696e000f0ac321048d0300200020044228884280fe03832004421888428080fc0783200442088842808080f80f8320044208864280808080f01f832004421886428080808080e03f83200442288642808080808080c0ff00832004423886200442388884848484848484370300200041186a20014228884280fe03832001421888428080fc0783200142088842808080f80f8320014208864280808080f01f832001421886428080808080e03f83200142288642808080808080c0ff00832001423886848484848484200142388884370300200020024228884280fe03832002421888428080fc0783200242088842808080f80f8320024208864280808080f01f832002421886428080808080e03f83200242288642808080808080c0ff00832002423886848484848484200242388884370310200020034228884280fe03832003421888428080fc0783200342088842808080f80f8320034208864280808080f01f832003421886428080808080e03f83200342288642808080808080c0ff008320034238868484848484842003423888843703080baf0402057f017e230041d0016b22052400200522044188016a100020042903880120044190016a29030084500440200441e8006a20012002200342ffffffff0f834200100c200441f0006a2903002101200441f8006a290300210220044180016a290300210320042903682109200541406a220622072400200541786a42808080808080808003370300200541706a4200370300200541686a4200370300200541606a4200370300200541586a2003370300200541506a2002370300200541486a200137030020062009370300200442003703c001200442003703b801200442808080103e02c8011001200441b8016a200641c00010021a20044198016a410041201003200441c8006a200429039801200441a0016a290300200441a8016a290300200441b0016a290300100c200441286a2004290348200441d0006a290300200441d8006a290300200441e0006a290300100c200441306a2903002101200441386a2903002102200441406b2903002103200429032821092007220541606a220722062400200641606a22082400200541786a2003370300200541706a2002370300200541686a200137030020072009370300200720081004200441086a2008290300200641686a290300200641706a290300200641786a290300100c200441106a2903002101200441186a290300210220042903082103200041186a200441206a290300370300200020023703102000200137030820002003370300200441d0016a24000f0b41d90841171005000bec1502077f0b7e230041d0056b22082400200822074188056a1000024002400240024020072903880520074190056a29030084500440200841606a2209220b240020091006200741e8046a42002009290300220e422086200e422088200841686a290300220e42208684200841706a350200422086200e42208884100c200741c8046a20072903e804200741f0046a290300200741f8046a3502004200100c200741d0046a290300210e200741d8046a290300210f200741e0046a290300211020072903c8042112200b220841406a2209220a2400200841786a42808080808080808003370300200841706a4200370300200841686a4200370300200841606a4200370300200841586a2010370300200841506a200f370300200841486a200e37030020092012370300200742003703c005200742003703b805200742808080103e02c8051001200741b8056a200941c00010021a20074198056a410041201003200741a8046a200729039805200741a0056a220b290300200741a8056a220c290300200741b0056a220d290300100c200741c0046a2903002111200741b8046a2903002113200741b0046a290300211420072903a8042115200a220841606a2209220a24002009100620074188046a42002009290300220e422086200e422088200841686a290300220e42208684200841706a350200422086200e42208884100c200741e8036a20072903880420074190046a29030020074198046a3502004200100c200741f0036a290300210e200741f8036a290300210f20074180046a290300211020072903e8032112200a220841406a2209220a2400200841786a42808080808080808003370300200841706a4200370300200841686a4200370300200841606a4200370300200841586a2010370300200841506a200f370300200841486a200e37030020092012370300200742003703c005200742003703b805200742808080103e02c8051001200741b8056a200941c00010021a20074198056a410041201003200741c8036a200729039805200b290300200c290300200d290300100c200741a8036a20072903c803200741d0036a290300200741d8036a290300200741e0036a290300100c200741b0036a290300210e200741b8036a290300210f200741c0036a290300211020072903a8032112200a220841606a220a22092400200941606a220c220d2400200841786a2010370300200841706a200f370300200841686a200e370300200a2012370300200a200c100420074188036a200c290300200941686a290300200941706a290300200941786a290300100c200741a0036a290300210e20074198036a290300210f20074190036a2903002110200729038803211220074198056a1000200729039805200b290300844200520d0120122003542208201020045420042010511b2209200f200554220b200e2006542006200e511b2005200f852006200e8584501b0d02200741e8026a2015201420132011100c200741f0026a2903002111200741f8026a290300211320074180036a290300211420072903e8022115200741c8026a201220037d201020047d2008ad7d200f20057d220f2009ad22107d200e20067d200bad7d200f201054ad7d100c200741d0026a290300210e200741d8026a290300210f200741e0026a290300211020072903c8022112200d220841606a220b22092400200941606a220a220c2400200941786a2010370300200941706a200f370300200941686a200e370300200a2012370300200841786a2014370300200841706a2013370300200841686a2011370300200b2015370300200b200a1007200741a8026a20002001200242ffffffff0f834200100c200741b0026a2903002110200741b8026a2903002112200741c0026a290300210020072903a8022101200c220841406a2209220a2400200841786a42808080808080808003370300200841706a4200370300200841686a4200370300200841606a4200370300200841586a2000370300200841506a2012370300200841486a201037030020092001370300200742003703c005200742003703b805200742808080103e02c8051001200741b8056a200941c00010021a20074198056a41004120100320074188026a200729039805200741a0056a220b290300200741a8056a220c290300200741b0056a220d290300100c200741a0026a290300211420074198026a290300211520074190026a29030021162007290388022117200a220841406a2209220a2400200841786a42808080808080808003370300200841706a4200370300200841686a4200370300200841606a4200370300200841586a2000370300200841506a2012370300200841486a201037030020092001370300200742003703c005200742003703b805200742808080103e02c8051001200741b8056a200941c00010021a20074198056a410041201003200741e8016a200729039805200b290300200c290300200d290300100c200741c8016a20072903e801200741f0016a290300200741f8016a29030020074180026a290300100c200741d0016a290300210e200741d8016a290300210f200741e0016a290300210220072903c8012111200a220841606a220a22092400200941606a220c220d2400200841786a2002370300200841706a200f370300200841686a200e370300200a2011370300200a200c1004200741a8016a200c290300200941686a290300200941706a290300200941786a290300100c200741c0016a290300210e200741b8016a290300210f200741b0016a290300210220072903a801211120074198056a1000200729039805200b290300844200520d03200320117c221820115422082008ad200220047c7c221320025420022013511b22082005200f7c22112008ad7c2202200f542002201154ad2011200f54ad2006200e7c7c7c2211200e54200e2011511b2002200f85200e20118584501b0d0420074188016a2017201620152014100c20074190016a290300210e20074198016a290300210f200741a0016a29030021142007290388012115200741e8006a2018201320022011100c200741f0006a2903002102200741f8006a290300211120074180016a290300211320072903682116200d220841606a220b22092400200941606a220a220c2400200941786a2013370300200941706a2011370300200941686a2002370300200a2016370300200841786a2014370300200841706a200f370300200841686a200e370300200b2015370300200b200a1007200c220841606a2209220b240020091006200741c8006a42002009290300220e422086200e422088200841686a290300220e42208684200841706a350200422086200e42208884100c200741d0006a290300210e200741d8006a350200210f20072903482102200b220841606a2209220b2400200741286a2002200e200f4200100c200741306a290300210e200741386a290300210f20072903282102200841786a200741406b290300370300200841706a200f370300200841686a200e37030020092002370300200b220841606a220b220a2400200841786a2000370300200841706a2012370300200841686a2010370300200b2001370300200a220841606a220a2400200741086a2003200420052006100c200741106a2903002106200741186a290300210420072903082105200841786a200741206a290300370300200841706a2004370300200841686a2006370300200a2005370300200a412041034180082009200b41001008200741d0056a24000f0b41d90841171005000b41d90841171005000b41bb08411e1005000b41d90841171005000b41a008411b1005000b920402047f047e230041a0016b2200210120002400024002400240100941034d0d00200041706a220022022400200041004104100a2000280200220041a98bf0dc7b460d01200041f0c08a8c03470d002002220041606a220222032400200241044120100a200141406b2002290300200041686a290300200041706a290300200041786a290300100c200141206a2001290340200141c8006a290300200141d0006a350200100d20012001290320200141286a290300200141306a290300200141386a290300100c200141086a2903002104200141106a2903002105200141186a2903002106200129030021072003220041606a22022400200041786a2006370300200041706a2005370300200041686a20043703002002200737030020024120100b0c020b41004100100b0c010b2002220041406a2202220324002002410441c000100a20014180016a2002290300200041486a290300200041506a290300200041586a290300100c200141e0006a200041606a290300200041686a290300200041706a290300200041786a290300100c20012903800120014188016a29030020014190016a3502002001290360200141e8006a290300200141f0006a290300200141f8006a290300100e2003220041606a22022400200041786a42808080808080808001370300200041706a4200370300200041686a42003703002002420037030020024120100b0b200141a0016a24000b0b7701004180080b70ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef536166654d6174683a206164646974696f6e206f766572666c6f77536166654d6174683a207375627472616374696f6e206f766572666c6f7746756e6374696f6e206973206e6f742070617961626c65
```

Now, let's prefix the ewasm code with `0x` and deploy it to the blockchain from the default coinbase address. Recall that the default passphrase for the coinbase is `1234`. All you need is an address that has some CMTs in it.

```
> personal.unlockAccount("0x7eff122b94897ea5b0e2a9abf47b86337fafebdc")
Passphrase:
> cmt.sendTransaction({
    from: "0x7eff122b94897ea5b0e2a9abf47b86337fafebdc",
    gas: 5000000,
    data: "0x0061736d0100000001270760027f7f0060000060017f0060037f7f7f0060057f7e7e7e7e0060047e7f7f7f017f6000017e02c7010908657468657265756d0c67657443616c6c56616c7565000208657468657265756d0c73746f7261676553746f7265000008657468657265756d0967657443616c6c6572000208657468657265756d0a6765744761734c656674000608657468657265756d0a63616c6c537461746963000508657468657265756d0e72657475726e44617461436f7079000308657468657265756d0b73746f726167654c6f6164000008657468657265756d06726576657274000008657468657265756d0666696e697368000003040304010105030100020608017f0141e0ad040b071102066d656d6f72790200046d61696e000b0abf0d038d0300200020044228884280fe03832004421888428080fc0783200442088842808080f80f8320044208864280808080f01f832004421886428080808080e03f83200442288642808080808080c0ff00832004423886200442388884848484848484370300200041186a20014228884280fe03832001421888428080fc0783200142088842808080f80f8320014208864280808080f01f832001421886428080808080e03f83200142288642808080808080c0ff00832001423886848484848484200142388884370300200020024228884280fe03832002421888428080fc0783200242088842808080f80f8320024208864280808080f01f832002421886428080808080e03f83200242288642808080808080c0ff00832002423886848484848484200242388884370310200020034228884280fe03832003421888428080fc0783200342088842808080f80f8320034208864280808080f01f832003421886428080808080e03f83200342288642808080808080c0ff008320034238868484848484842003423888843703080ba00a02067f087e23004190026b220024002000220141c8016a100020012903c801200141d0016a29030084500440200041606a220322022400200241606a220422052400200241786a4280808080d0a0fdf000370300200241706a4200370300200241686a420037030020044200370300200041786a4200370300200041706a4200370300200041686a4200370300200342003703002003200410012005220041606a2202220324002000416c6a41edde013b0100200041686a220441e5dc91aa06360200200242c5a48d928386d5b7eb00370300200041786a220220022903004280808080808080801c84220637030020042903002107200041706a29030021082003220041606a220322022400200241606a220422052400200241786a2006370300200241706a2008370300200241686a2007370300200442c5a48d928386d5b7eb00370300200041786a42808080808080808001370300200041706a4200370300200041686a4200370300200342003703002003200410012005220041606a220222032400200041626a41c4003a0000200241c5a8013b0100200041786a220420042903004280808080808080800684220637030020022903002107200041686a2903002108200041706a29030021092003220041606a220322022400200241606a220422052400200241786a2006370300200241706a2009370300200241686a200837030020042007370300200041786a42808080808080808002370300200041706a4200370300200041686a4200370300200342003703002003200410012005220041606a22022203240020021002200141a8016a4200200229030022064220862006422088200041686a290300220642208684200041706a350200422086200642208884100920014188016a20012903a801200141b0016a290300200141b8016a3502004200100920014190016a290300210620014198016a2903002107200141a0016a290300210820012903880121092003220041406a220222032400200041786a42808080808080808003370300200041706a4200370300200041686a4200370300200041606a4200370300200041586a2008370300200041506a2007370300200041486a2006370300200220093703002001420037038002200142003703f801200142808080103e0288021003200141f8016a200241c00010041a200141d8016a410041201005200141e8006a20012903d801200141e0016a290300200141e8016a290300200141f0016a290300100920014180016a2903002106200141f8006a2903002107200141f0006a2903002108200129036821092003220041606a220322022400200241606a220422052400200041786a4200370300200041706a4200370300200041686a420037030020034200370300200320041006200141c8006a2004290300200241686a290300200241706a290300200241786a2903001009200141286a20092008200720061009200141306a2903002106200141386a2903002107200141406b290300210820012903282109200141086a2001290348200141d0006a290300200141d8006a290300200141e0006a2903001009200141106a290300210a200141186a290300210b200141206a290300210c2001290308210d2005220041606a220322022400200241606a22042400200241786a200c370300200241706a200b370300200241686a200a3703002004200d370300200041786a2008370300200041706a2007370300200041686a20063703002003200937030020032004100120014190026a24000f0b41800841171007000b0c00100a41970841c42510080b0be32501004180080bdb2546756e6374696f6e206973206e6f742070617961626c650061736d0100000001460b60027f7f0060017f0060037f7f7f0060000060077f7f7f7f7f7f7f0060047f7e7e7e0060057f7e7e7e7e0060077e7e7e7e7e7e7e006000017f60047e7f7f7f017f6000017e0289020c08657468657265756d0c67657443616c6c56616c7565000108657468657265756d0a6765744761734c656674000a08657468657265756d0a63616c6c537461746963000908657468657265756d0e72657475726e44617461436f7079000208657468657265756d0b73746f726167654c6f6164000008657468657265756d06726576657274000008657468657265756d0967657443616c6c6572000108657468657265756d0c73746f7261676553746f7265000008657468657265756d036c6f67000408657468657265756d0f67657443616c6c4461746153697a65000808657468657265756d0c63616c6c44617461436f7079000208657468657265756d0666696e69736800000305040605070305030100020608017f0141f088040b071102066d656d6f72790200046d61696e000f0ac321048d0300200020044228884280fe03832004421888428080fc0783200442088842808080f80f8320044208864280808080f01f832004421886428080808080e03f83200442288642808080808080c0ff00832004423886200442388884848484848484370300200041186a20014228884280fe03832001421888428080fc0783200142088842808080f80f8320014208864280808080f01f832001421886428080808080e03f83200142288642808080808080c0ff00832001423886848484848484200142388884370300200020024228884280fe03832002421888428080fc0783200242088842808080f80f8320024208864280808080f01f832002421886428080808080e03f83200242288642808080808080c0ff00832002423886848484848484200242388884370310200020034228884280fe03832003421888428080fc0783200342088842808080f80f8320034208864280808080f01f832003421886428080808080e03f83200342288642808080808080c0ff008320034238868484848484842003423888843703080baf0402057f017e230041d0016b22052400200522044188016a100020042903880120044190016a29030084500440200441e8006a20012002200342ffffffff0f834200100c200441f0006a2903002101200441f8006a290300210220044180016a290300210320042903682109200541406a220622072400200541786a42808080808080808003370300200541706a4200370300200541686a4200370300200541606a4200370300200541586a2003370300200541506a2002370300200541486a200137030020062009370300200442003703c001200442003703b801200442808080103e02c8011001200441b8016a200641c00010021a20044198016a410041201003200441c8006a200429039801200441a0016a290300200441a8016a290300200441b0016a290300100c200441286a2004290348200441d0006a290300200441d8006a290300200441e0006a290300100c200441306a2903002101200441386a2903002102200441406b2903002103200429032821092007220541606a220722062400200641606a22082400200541786a2003370300200541706a2002370300200541686a200137030020072009370300200720081004200441086a2008290300200641686a290300200641706a290300200641786a290300100c200441106a2903002101200441186a290300210220042903082103200041186a200441206a290300370300200020023703102000200137030820002003370300200441d0016a24000f0b41d90841171005000bec1502077f0b7e230041d0056b22082400200822074188056a1000024002400240024020072903880520074190056a29030084500440200841606a2209220b240020091006200741e8046a42002009290300220e422086200e422088200841686a290300220e42208684200841706a350200422086200e42208884100c200741c8046a20072903e804200741f0046a290300200741f8046a3502004200100c200741d0046a290300210e200741d8046a290300210f200741e0046a290300211020072903c8042112200b220841406a2209220a2400200841786a42808080808080808003370300200841706a4200370300200841686a4200370300200841606a4200370300200841586a2010370300200841506a200f370300200841486a200e37030020092012370300200742003703c005200742003703b805200742808080103e02c8051001200741b8056a200941c00010021a20074198056a410041201003200741a8046a200729039805200741a0056a220b290300200741a8056a220c290300200741b0056a220d290300100c200741c0046a2903002111200741b8046a2903002113200741b0046a290300211420072903a8042115200a220841606a2209220a24002009100620074188046a42002009290300220e422086200e422088200841686a290300220e42208684200841706a350200422086200e42208884100c200741e8036a20072903880420074190046a29030020074198046a3502004200100c200741f0036a290300210e200741f8036a290300210f20074180046a290300211020072903e8032112200a220841406a2209220a2400200841786a42808080808080808003370300200841706a4200370300200841686a4200370300200841606a4200370300200841586a2010370300200841506a200f370300200841486a200e37030020092012370300200742003703c005200742003703b805200742808080103e02c8051001200741b8056a200941c00010021a20074198056a410041201003200741c8036a200729039805200b290300200c290300200d290300100c200741a8036a20072903c803200741d0036a290300200741d8036a290300200741e0036a290300100c200741b0036a290300210e200741b8036a290300210f200741c0036a290300211020072903a8032112200a220841606a220a22092400200941606a220c220d2400200841786a2010370300200841706a200f370300200841686a200e370300200a2012370300200a200c100420074188036a200c290300200941686a290300200941706a290300200941786a290300100c200741a0036a290300210e20074198036a290300210f20074190036a2903002110200729038803211220074198056a1000200729039805200b290300844200520d0120122003542208201020045420042010511b2209200f200554220b200e2006542006200e511b2005200f852006200e8584501b0d02200741e8026a2015201420132011100c200741f0026a2903002111200741f8026a290300211320074180036a290300211420072903e8022115200741c8026a201220037d201020047d2008ad7d200f20057d220f2009ad22107d200e20067d200bad7d200f201054ad7d100c200741d0026a290300210e200741d8026a290300210f200741e0026a290300211020072903c8022112200d220841606a220b22092400200941606a220a220c2400200941786a2010370300200941706a200f370300200941686a200e370300200a2012370300200841786a2014370300200841706a2013370300200841686a2011370300200b2015370300200b200a1007200741a8026a20002001200242ffffffff0f834200100c200741b0026a2903002110200741b8026a2903002112200741c0026a290300210020072903a8022101200c220841406a2209220a2400200841786a42808080808080808003370300200841706a4200370300200841686a4200370300200841606a4200370300200841586a2000370300200841506a2012370300200841486a201037030020092001370300200742003703c005200742003703b805200742808080103e02c8051001200741b8056a200941c00010021a20074198056a41004120100320074188026a200729039805200741a0056a220b290300200741a8056a220c290300200741b0056a220d290300100c200741a0026a290300211420074198026a290300211520074190026a29030021162007290388022117200a220841406a2209220a2400200841786a42808080808080808003370300200841706a4200370300200841686a4200370300200841606a4200370300200841586a2000370300200841506a2012370300200841486a201037030020092001370300200742003703c005200742003703b805200742808080103e02c8051001200741b8056a200941c00010021a20074198056a410041201003200741e8016a200729039805200b290300200c290300200d290300100c200741c8016a20072903e801200741f0016a290300200741f8016a29030020074180026a290300100c200741d0016a290300210e200741d8016a290300210f200741e0016a290300210220072903c8012111200a220841606a220a22092400200941606a220c220d2400200841786a2002370300200841706a200f370300200841686a200e370300200a2011370300200a200c1004200741a8016a200c290300200941686a290300200941706a290300200941786a290300100c200741c0016a290300210e200741b8016a290300210f200741b0016a290300210220072903a801211120074198056a1000200729039805200b290300844200520d03200320117c221820115422082008ad200220047c7c221320025420022013511b22082005200f7c22112008ad7c2202200f542002201154ad2011200f54ad2006200e7c7c7c2211200e54200e2011511b2002200f85200e20118584501b0d0420074188016a2017201620152014100c20074190016a290300210e20074198016a290300210f200741a0016a29030021142007290388012115200741e8006a2018201320022011100c200741f0006a2903002102200741f8006a290300211120074180016a290300211320072903682116200d220841606a220b22092400200941606a220a220c2400200941786a2013370300200941706a2011370300200941686a2002370300200a2016370300200841786a2014370300200841706a200f370300200841686a200e370300200b2015370300200b200a1007200c220841606a2209220b240020091006200741c8006a42002009290300220e422086200e422088200841686a290300220e42208684200841706a350200422086200e42208884100c200741d0006a290300210e200741d8006a350200210f20072903482102200b220841606a2209220b2400200741286a2002200e200f4200100c200741306a290300210e200741386a290300210f20072903282102200841786a200741406b290300370300200841706a200f370300200841686a200e37030020092002370300200b220841606a220b220a2400200841786a2000370300200841706a2012370300200841686a2010370300200b2001370300200a220841606a220a2400200741086a2003200420052006100c200741106a2903002106200741186a290300210420072903082105200841786a200741206a290300370300200841706a2004370300200841686a2006370300200a2005370300200a412041034180082009200b41001008200741d0056a24000f0b41d90841171005000b41d90841171005000b41bb08411e1005000b41d90841171005000b41a008411b1005000b920402047f047e230041a0016b2200210120002400024002400240100941034d0d00200041706a220022022400200041004104100a2000280200220041a98bf0dc7b460d01200041f0c08a8c03470d002002220041606a220222032400200241044120100a200141406b2002290300200041686a290300200041706a290300200041786a290300100c200141206a2001290340200141c8006a290300200141d0006a350200100d20012001290320200141286a290300200141306a290300200141386a290300100c200141086a2903002104200141106a2903002105200141186a2903002106200129030021072003220041606a22022400200041786a2006370300200041706a2005370300200041686a20043703002002200737030020024120100b0c020b41004100100b0c010b2002220041406a2202220324002002410441c000100a20014180016a2002290300200041486a290300200041506a290300200041586a290300100c200141e0006a200041606a290300200041686a290300200041706a290300200041786a290300100c20012903800120014188016a29030020014190016a3502002001290360200141e8006a290300200141f0006a290300200141f8006a290300100e2003220041606a22022400200041786a42808080808080808001370300200041706a4200370300200041686a42003703002002420037030020024120100b0b200141a0016a24000b0b7701004180080b70ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef536166654d6174683a206164646974696f6e206f766572666c6f77536166654d6174683a207375627472616374696f6e206f766572666c6f7746756e6374696f6e206973206e6f742070617961626c65"
})
"0x008d8ab4d995cdef95fcc61b0d009470b7a69f6b3d37e0d76734bcacf62319fe"
```

Note the return value from the `sendTransaction` is the transaction hash. We can use it to find the address of the newly created contract.

```
// USE THE TX HASH FROM ABOVE
> cmt.getTransactionReceipt("0x008d8ab4d995cdef95fcc61b0d009470b7a69f6b3d37e0d76734bcacf62319fe")
{
  blockHash: "0xff8aabe3b70ea6796cc1b945b10d717d462ae24c49f8e05dbec2dc2f4511790f",
  blockNumber: 27978,
  contractAddress: "0x70f94d58cc3fdcbeac7140f35a087da9fcd09b94",
  cumulativeGasUsed: 1519352,
  from: "0x7eff122b94897ea5b0e2a9abf47b86337fafebdc",
  gasUsed: 1519352,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  status: "0x1",
  to: null,
  transactionHash: "0x8b102fb7744f3472328131f921efdbad3a9ef3c6225c682196ad2a3a8bb34a6e",
  transactionIndex: 0
}
// SET THE CONTRACT ADDRESS
> contractAddress = "0x70f94d58cc3fdcbeac7140f35a087da9fcd09b94"
```

Next, create an instance of this contract at the above address. You will need the ABI for this contract (based on the Solidity source code) for this to work. Then, we can query the account balances in this ERC20 token contract. The creator address of this contact has all the initial supply of the tokens, and everyone else is zero.

```
> abi = [{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"}]
> contract = cmt.contract(abi);
> contractInstance = contract.at(contractAddress);
> contractInstance.balanceOf.call("0x7eff122b94897ea5b0e2a9abf47b86337fafebdc");
100000000
> contractInstance.balanceOf.call("0x77beb894fc9b0ed41231e51f128a347043960a9d");
0
```

Finally, we can make `transfer` calls on the contract to transfer ERC20 tokens between accounts.

```
> contractInstance.transfer.sendTransaction(
    "0x77beb894fc9b0ed41231e51f128a347043960a9d",
    123, 
    {
        from: "0x7eff122b94897ea5b0e2a9abf47b86337fafebdc",
        gas: 5000000
    }
);
> contractInstance.balanceOf.call("0x7eff122b94897ea5b0e2a9abf47b86337fafebdc");
99999877
> contractInstance.balanceOf.call("0x77beb894fc9b0ed41231e51f128a347043960a9d");
123
```

That's it. You have now deployed and executed an ewasm smart contract on a real blockchain. Welcome to the future of Ethereum!


# CyberMiles ewasm testnet

Deploy and test ewasm smart contracts via an interactive web3 console

The CyberMiles Public Blockchain runs an Ewasm testnet based on its blockchain software and Second State's SSVM. The easiest way to access the testnet is via Docker.

![https://asciinema.org/a/321762?speed=8](/files/-M5LJhvx6QI9be5a5S9K)

Start by pulling the Second State DevChain Docker image.

```
$ docker pull secondstate/devchain:devchain
```

You can now start the interactive console via Docker. Please note that the password is subject to change. Do not abuse it!

```
$ docker run --rm -it secondstate/devchain:devchain attach http://ewasm:3WAeT4CYSkMTAPuF@23.98.151.156
```

We recommend you to create your own account and then give yourself a little CMTs from our faucet account (`0x1bba632055efb57aa991a9b0e900194e2ea037ad`).

```
// Create a new account
> personal.newAccount("mypass");
"0xMY_ACCOUNT_ADDRESS"

// Unlock the faucet account
> personal.unlockAccount("0x1bba632055efb57aa991a9b0e900194e2ea037ad", "3WAeT4CYSkMTAPuF");
true

// Transfer 5 CMTs from the facuet account to the newly created account
> cmt.sendTransaction({"from": "0x1bba632055efb57aa991a9b0e900194e2ea037ad", "to": "0xMY_ACCOUNT_ADDRESS", "value": web3.toWei(5, "cmt")})

// Unlock the new account
> personal.unlockAccount("0xMY_ACCOUNT_ADDRESS", "mypass");
```

Now you can [follow the tutorial](/devchain/getting-started/run-an-ewasm-smart-contract) to deploy and test your ewasm smart contracts.

{% content-ref url="/pages/-M4H5ZXPQ-HmXj5ePCBK" %}
[Run an ewasm smart contract](/devchain/getting-started/run-an-ewasm-smart-contract)
{% endcontent-ref %}

![https://asciinema.org/a/321767?speed=8](/files/-M5LKLUHQy5cR5Nz0qhj)


# Build

This document describes how to build the Second State DevChain.

### Binary build

Binary builds of the Second State DevChain are limited to Ubuntu 16.04 and CentOS 7.

#### Ubuntu 16.04

First, let’s install and update necessary packages on a clean Ubuntu 16.04 install.

```bash
$ sudo apt update -y
$ sudo apt install -y curl wget git bison build-essential
```

Next, you must have GO language version 1.10+ installed. The easiest way to get GO 1.10 is through the GVM. Below are the commands.

```bash
$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
$ gvm install go1.10.3 -B
$ gvm use go1.10.3 --default
```

Now, pull the devchain source code from Github, and then build the binary executable for Ubuntu 16.04.

```bash
$ go get github.com/second-state/devchain
$ cd $GOPATH/src/github.com/second-state/devchain
$ make all
```

Once successful, the binary executable from the build is `$GOPATH/bin/devchain`.

```bash
$ which devchain
/home/ubuntu/.gvm/pkgsets/go1.10.3/global/bin/devchain
```

#### CentOS 7

TBD

### Docker build

First, install Docker.

```bash
$ sudo apt install docker.io
$ sudo usermod -a -G docker $USER
```

Log out and then log back in. Clone the repository from Github to your build machine.

```bash
$ git clone https://github.com/second-state/devchain.git
$ cd devchain
```

Next, build a Docker image for the build environment.

```bash
$ docker build -t secondstate/devchain-build -f Dockerfile.build.ubuntu .
...
Successfully tagged secondstate/devchain-build:latest
```

Finally, you can build the Docker image of the node.

```bash
$ docker build -t secondstate/devchain .
...
Successfully tagged secondstate/devchain:latest
```

You can now see the Docker image you just built.

```bash
$ docker image ls
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
secondstate/devchain         latest              c800759441b6        5 minutes ago       246MB
secondstate/devchain-build   latest              364c7a4700b9        4 hours ago         732MB
ubuntu                        16.04               a3551444fc85        7 days ago          119MB
```


# Run

This document describes how to run the Second State DevChain.

### Binary

The binary executable `devchain` is the software that runs blockchain nodes.

#### Single node

First, you need to initialize the configurations and settings on the node computer.

```bash
$ devchain node init --home $HOME/.devchain
```

The `genesis.json` and `config.toml` files will be created under the `$HOME/.devchain/config` directory. You can make changes to those files to customize your blockchain. Then, `set env` variables for libENI.

```bash
$ mkdir -p $HOME/.devchain/eni/lib
$ cd $HOME/.devchain/eni

# Get the lib file. For centos 7 the file name is libeni-1.3.4_centos-7.tgz
$ wget https://github.com/second-state/libeni/releases/download/v1.3.4/libeni-1.3.4_ubuntu-16.04.tgz
$ tar zxvf *.tgz
$ cp libeni-1.3.4/lib/* lib

# For convenience, you should also put these two lines in your .bashrc or .zshrc
export ENI_LIBRARY_PATH=$HOME/.devchain/eni/lib
export LD_LIBRARY_PATH=$HOME/.devchain/eni/lib
```

Now you can start the node.

```bash
$ devchain node start --home $HOME/.devchain
```

Next, in a new terminal window, run the following command to connect to the local DevChain node.

```bash
$ devchain attach http://localhost:8545
> cmt.syncing
{
  catching_up: false,
  latest_app_hash: "07FA113DF14AAC49773DD7EE2B8418740D9DD552",
  latest_block_hash: "AF1415AF0057C52C4A1F7DC80298217A33291AEE",
  latest_block_height: 23,
  latest_block_time: "2019-05-03T21:41:14.581000291Z"
}
```

#### Multiple nodes

First, you need to initialize the configurations and settings on each of the node computer. Run the following command on each machine.

```bash
$ devchain node init --home $HOME/.devchain
```

* Each node has a different `$HOME/.devchain/config/priv_validator.json` key file. Note down the public key for each of them.
* On each node, run command `devchain node show_node_id –home $HOME/.devchain` and note down the seed for each. It is in the format of `seed@ip:26656`

Next, use [this tool](https://github.com/second-state/devchain-config) to generate a new set of `genesis.json` and `config.toml` files for the entire cluster. Enter all the public keys and seeds from the last step into the tool. For example, here is how to create a `genesis.json` with a custom `chain_id`, a custom `gas_price` and public keys from multiple nodes.

```bash
$ node index.js --type genesis --config_path ./genesis.json.template --chain_id test --params.gas_price 0 --validators.1.pub_key test1 --validators.1.power 101 --validators.2.pub_key test2 --validators.1.power 102
```

Here is how to create a `config.toml` file with the seeds.

```bash
$ node index.js --type config --config_path ./config.toml.template --p2p.seeds seed1@ip1:26656,seed2@ip2:26656
```

Copy the generated `genesis.json` and `config.toml` files back into each node’s `$HOME/.devchain/config` directory.

Next, set env variables for libENI.

```bash
$ mkdir -p $HOME/.devchain/eni/lib
$ cd $HOME/.devchain/eni

# Get the lib file. For centos 7 the file name is libeni-1.3.4_centos-7.tgz
$ wget https://github.com/second-state/libeni/releases/download/v1.3.4/libeni-1.3.4_ubuntu-16.04.tgz
$ tar zxvf *.tgz
$ cp libeni-1.3.4/lib/* lib

# For convenience, you should also put these two lines in your .bashrc or .zshrc
export ENI_LIBRARY_PATH=$HOME/.devchain/eni/lib
export LD_LIBRARY_PATH=$HOME/.devchain/eni/lib
```

Now you can start each node, and they will form a cluster.

```bash
$ devchain node start --home $HOME/.devchain
```

Next, in a new terminal window, run the following command to connect to a local DevChain node in the cluster.

```bash
$ devchain attach http://localhost:8545
> cmt.syncing
{
  catching_up: false,
  latest_app_hash: "07FA113DF14AAC49773DD7EE2B8418740D9DD552",
  latest_block_hash: "AF1415AF0057C52C4A1F7DC80298217A33291AEE",
  latest_block_height: 23,
  latest_block_time: "2019-05-03T21:41:14.581000291Z"
}
```

### Docker

In the previous section, we have built a Docker image for the node software under the name `secondstate/devchain`.

#### Single node

First, you need to initialize the configurations and settings on the node computer.

```bash
$ docker run --rm -v $HOME/.devchain:/devchain secondstate/devchain:develop node init --home /devchain
```

The `genesis.json` and `config.toml` files will be created under the `$HOME/.devchain/config` directory. You can make changes to those files to customize your blockchain. You may need to `sudo su -` in order to edit those files since they are created by the root user. The libENI libraries have been built into the docker image so you don’t need to worry about it. Then, you can start the node.

```bash
$ docker run --rm -v $HOME/.devchain:/devchain -p 26657:26657 -p 8545:8545 secondstate/devchain:develop node start --home /devchain
```

From a second terminal window, you can get the ID of the running Docker container.

```bash
$ docker container ls
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                                                         NAMES
0bcd9da5bf05        secondstate/devchain   "./devchain node sta…"   4 minutes ago       Up 4 minutes        0.0.0.0:8545->8545/tcp, 0.0.0.0:26657->26657/tcp, 26656/tcp   pedantic_mendeleev
```

Next, log into that container.

```bash
$ docker exec -i -t 0bcd9da5bf05 bash
root@0bcd9da5bf05:/app# ls
devchain  devchain.sha256  lib
```

Finally, you can attach a console to the node to run web3 commands.

```bash
root@0bcd9da5bf05:/app# ./devchain attach http://localhost:8545
...
> cmt.syncing
{
  catching_up: false,
  latest_app_hash: "C7D8AECE081DF06FFC9BF6144A50B37CA5DD8A8E",
  latest_block_hash: "B592D63AB78C571E0FB695A052681E65F6DFE15B",
  latest_block_height: 35,
  latest_block_time: "2019-05-04T02:59:30.542783017Z"
}
```

#### Multiple nodes

First, you need to initialize the configurations and settings on each of the node computer. Run the following command on each machine.

```bash
$ docker run --rm -v $HOME/.devchain:/devchain secondstate/devchain:develop node init --home /devchain
```

* Each node has a different `$HOME/.devchain/config/priv_validator.json` key file. Note down the public key for each of them.
* On each node, run command `devchain node show_node_id –home $HOME/.devchain` and note down the seed for each. It is in the format of `seed@ip:26656`

Next, use [this tool](https://github.com/second-state/devchain-config) to generate a new set of `genesis.json` and `config.toml` files for the entire cluster. Enter all the public keys and seeds from the last step into the tool. For example, here is how to create a `genesis.json` with a custom `chain_id`, a custom `gas_price` and public keys from multiple nodes.

```bash
$ node index.js --type genesis --config_path ./genesis.json.template --chain_id test --params.gas_price 0 --validators.1.pub_key test1 --validators.1.power 101 --validators.2.pub_key test2 --validators.1.power 102
```

Here is how to create a `config.toml` file with the seeds.

```bash
$ node index.js --type config --config_path ./config.toml.template --p2p.seeds seed1@ip1:26656,seed2@ip2:26656
```

Copy the generated `genesis.json` and `config.toml` files back into each node's `$HOME/.devchain/config` directory.

Now you can start each node, and they will form a cluster.

```bash
$ docker run --rm -v $HOME/.devchain:/devchain -p 26657:26657 -p 8545:8545 secondstate/devchain:develop node start --home /devchain
```

On a second terminal window on each node, you can get the ID of the running Docker container.

```bash
$ docker container ls
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                                                         NAMES
0bcd9da5bf05        secondstate/devchain   "./devchain node sta…"   4 minutes ago       Up 4 minutes        0.0.0.0:8545->8545/tcp, 0.0.0.0:26657->26657/tcp, 26656/tcp   pedantic_mendeleev
```

Next, log into that container on a node.

```bash
$ docker exec -i -t 0bcd9da5bf05 bash
root@0bcd9da5bf05:/app# ls
devchain  devchain.sha256  lib
```

Finally, you can attach a console to the node to run web3 commands.

```bash
root@0bcd9da5bf05:/app# ./devchain attach http://localhost:8545
...
> cmt.syncing
{
  catching_up: false,
  latest_app_hash: "C7D8AECE081DF06FFC9BF6144A50B37CA5DD8A8E",
  latest_block_hash: "B592D63AB78C571E0FB695A052681E65F6DFE15B",
  latest_block_height: 35,
  latest_block_time: "2019-05-04T02:59:30.542783017Z"
}
```


# BaaS

The Second State Blockchain as a Service enables users to start a multiple node blockchain with the complete Second State software, including the [Second State Virtual Machine](https://github.com/second-state/lityvm) and [smart contract search engine](https://github.com/second-state/smart-contract-search-engine), with just one click of the mouse. Once it starts, you can [configure BUIDL](/buidl-developer-tool/working-with-baas) to use the newly created blockchain immediately!

[Create your own blockchain now!](http://baas-mvp.secondstate.io/)


# Getting started

{% embed url="<https://youtu.be/0m6fiNzukbM>" %}
Checkout a video demo of the smart contract search engine
{% endembed %}

## Overview

The following image illustrates how the smart contract search engine integrates with a) a blockchain, b) a decentralized application (DApp) and any potential c) third-party application and service.

![](/files/-LlUI1XJvfOtlxORLsq3)

The smart contract search engine can:

* index any Ethereum compatible blockchain
* index any number of smart contracts
* index any number of blocks
* be called via Curl
* be queried via client side Javascript
* be queried via server side NodeJS

## Installation

You can quickly install and use your very own smart contract search engine via [a Docker instance](https://github.com/second-state/whitepapers/blob/master/smart-contracts-search-engine/start-a-search-engine-docker.md). Alternatively, you can install and configure the smart contract search engine for use on [your own Ubuntu Server instance](https://github.com/second-state/whitepapers/blob/master/smart-contracts-search-engine/start-a-search-engine.md).

## Usage

### Configuring the smart contract search engine

All of the configuration for the harvesting is stored in [a single, config.ini, Python configuration file](https://github.com/second-state/smart-contract-search-engine/blob/master/python/config.ini). The explaination for each of the configuration settings i.e. rpc endpoint, index names etc. can be found [here](https://github.com/second-state/whitepapers/blob/master/smart-contracts-search-engine/start-a-search-engine.md#configuring-the-python-harvester-a-single-configini-file).

### Harvesting smart contract data (writing blockchain data to the indices)

The core of the smart contract search engine is [a single, harvest.py, Python file](https://github.com/second-state/smart-contract-search-engine/blob/master/python/harvest.py). All of the harvesting functionality resides in the harvest.py file.

#### Recommended usage - running the harvest.py file once at startup

The harvest.py file is designed to manage all of the tasks associated with harvesting. However, due to the vast differences in blockchains (block intervals, number of blocks, number of ABIs, number of contracts etc.) the harvest.py is designed so that each of the separate tasks can be individually called, using the `-m` mode flag. The documentation on how to "run once at startup" can be found [here](https://github.com/second-state/whitepapers/blob/master/smart-contracts-search-engine/start-a-search-engine.md#recommended-usage---run-once-at-startup). However, before you just employ that approach, please take the time to read what each of the modes do. This [Detailed explanation of harvesting modes](https://github.com/second-state/whitepapers/blob/master/smart-contracts-search-engine/start-a-search-engine.md#detailed-explanation-of-harvesting-modes) documentation will help you taylor your search engine's operation to best suit your needs.

#### Using the harvest.py file as a library (useful for testing in certain circumstances)

Whilst technically not the recommended usage, the harvest.py file can also be utilized as a library in the following way. Firstly by starting a Python terminal.

```bash
# Bash syntax
cd /home/smart-contract-search-engine/python
python3.6
```

Then by importing the Harvest code

```python
# Python syntax
from harvest import Harvest
```

Then, the following code will automatically read all of the required configuration from the config.ini file (as the Harvest() object is instantiated as the variable `harvester`).

```python
harvester = Harvest()
```

The above code will allow any of the Harvest functions to be called individually. For example.

```python
_addressHash = "0x123...567"
harvester.getDataUsingAddressHash(_addressHash)
```

### Consuming smart contract data (reading blockchain data from the indices)

The smart contract data is consumed on an ABI basis. The smart contract search engine creates a unique deterministic hash of the ABI of a given smart contract. If a DApp wants to access data which is related to an instantiation of that particular smart contract, it can query the indices using the hash as a filter. Consider the following example.

The following smart contract called `ChildContract` produces an ABI.

Solidity

```javascript
pragma solidity >=0.4.0 <0.6.0;

contract ParentContract {
    uint parentContractData = 5;

    function setParentContractData(uint _parentContractData) public {
        parentContractData = _parentContractData;
    }
    function getParentContractData() public view returns (uint){
        return parentContractData;
    }
}
contract ChildContract is ParentContract{
    uint childContractData;

    function setChildContractData(uint _childContractData) public {
        childContractData = _childContractData;
    }

    function getChildContractData() public view returns (uint) {
        return childContractData;
    }
}
```

ChildContract ABI

```javascript
[
  {
    "constant": false,
    "inputs": [
      {
        "name": "_parentContractData",
        "type": "uint256"
      }
    ],
    "name": "setParentContractData",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [],
    "name": "getChildContractData",
    "outputs": [
      {
        "name": "",
        "type": "uint256"
      }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [],
    "name": "getParentContractData",
    "outputs": [
      {
        "name": "",
        "type": "uint256"
      }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
  },
  {
    "constant": false,
    "inputs": [
      {
        "name": "_childContractData",
        "type": "uint256"
      }
    ],
    "name": "setChildContractData",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
  }
]
```

If we look closely at the `ChildContract` we can see that it inherits from the `ParentContract`. If you are thinking that there should technically be two ABIs in relation to the above source code you would be right! Here is the ABI of the `ParentContract`.

ParentContract ABI

```javascript
[
  {
    "constant": false,
    "inputs": [
      {
        "name": "_parentContractData",
        "type": "uint256"
      }
    ],
    "name": "setParentContractData",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [],
    "name": "getParentContractData",
    "outputs": [
      {
        "name": "",
        "type": "uint256"
      }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
  }
]
```

Nested ABIs, like the ones shown above, are very common. In order to provide the most flexibility, the smart contract search engine stores both of the ABIs against any smart contract address which houses an instance of the above deployed `ChildContract`. The hash for the `ParentContract` is `0x5dc306fb7e9065cf256a57f077267b73491a0df567d2aa8c1e89250e96f87011` and the hash for the `ChildContract` is `0xfa13b708346165ef225d79a51acbc17c24b9a2f523b71272fc6160cd9d54ced7`. We can see these hashes in the `abiShaList` section of the raw smart contract data shown below.

```javascript
{
    "took": 0,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 1,
        "max_score": 1.6739764,
        "hits": [
            {
                "_index": "devchaintwo",
                "_type": "_doc",
                "_id": "0xDd27F736AC616141b72eb67D2d79D3f6b1eD7d6f",
                "_score": 1.6739764,
                "_source": {
                    "TxHash": "0x2e8bab6c377a10747a78bad4cbcd4f56bc8789ad8e4f60848d1bcd6518cf6435",
                    "abiShaList": [
                        "0xfa13b708346165ef225d79a51acbc17c24b9a2f523b71272fc6160cd9d54ced7",
                        "0x5dc306fb7e9065cf256a57f077267b73491a0df567d2aa8c1e89250e96f87011"
                    ],
                    "blockNumber": 2220917,
                    "creator": "0xb0695b88e44c27c8a203bba5aed78e2ae475cc68",
                    "contractAddress": "0xDd27F736AC616141b72eb67D2d79D3f6b1eD7d6f",
                    "functionDataList": {
                        "0": [
                            {
                                "functionDataId": "0x2ea80e958837c05ba351ea4d77e4247518f0ab9df296f632963417c79ceac7f4",
                                "functionData": {
                                    "getChildContractData": "0",
                                    "getParentContractData": "5"
                                },
                                "uniqueAbiAndAddressHash": "0xe666c441714e77c45920a855b1e93c9306f0c8768769627637993c9ae4d15bac"
                            }
                        ]
                    },
                    "requiresUpdating": "yes",
                    "quality": "50",
                    "indexInProgress": "false"
                }
            }
        ]
    }
}
```

If we would like to access all instances of the `ChildContract` we could query the search engine using the ABI hash of the `ChildContract`. We can [query using traditional client-side Javascript](https://github.com/second-state/es-ss.js/tree/master/traditional_non_node_js) or [query using server-side NodeJS Javascript](https://github.com/second-state/es-ss.js). Here is an example of both.

#### Client-side Javascript

```javascript
var esss = new ESSS("https://devchain-es.secondstate.io")
abi = '0xfa13b708346165ef225d79a51acbc17c24b9a2f523b71272fc6160cd9d54ced7';
esss.searchUsingAbi(abi)
    .then(function(result) {
        console.log(result)
    })
    .catch(function() {
        console.log("Error");
    });
```

#### Server-side NodeJS Example

```javascript
let esss = require('./es-ss');  
let ESSS = esss.ESSS;
let searchEngineProvider = new ESSS('https://devchain-es.secondstate.io');
abiHash = '0xfa13b708346165ef225d79a51acbc17c24b9a2f523b71272fc6160cd9d54ced7';
var abiSearch = searchEngineProvider.searchUsingAbi(abiHash);
abiSearch.then(function(result) {
    console.log("Result is " + result);
  })
  .catch(function() {
    console.log("Error");
  });
```

The above request queries will return, deduplicated data from the smart contract, such as the following

```javascript
[
  {
    "TxHash": "0x2e8bab6c377a10747a78bad4cbcd4f56bc8789ad8e4f60848d1bcd6518cf6435", 
    "abiShaList": [
      "0xfa13b708346165ef225d79a51acbc17c24b9a2f523b71272fc6160cd9d54ced7", 
      "0x5dc306fb7e9065cf256a57f077267b73491a0df567d2aa8c1e89250e96f87011"
    ], 
    "blockNumber": 2220917, 
    "contractAddress": "0xDd27F736AC616141b72eb67D2d79D3f6b1eD7d6f", 
    "creator": "0xb0695b88e44c27c8a203bba5aed78e2ae475cc68", 
    "functionData": {
      "getChildContractData": "0", 
      "getParentContractData": "5"
    }, 
    "functionDataId": "0x2ea80e958837c05ba351ea4d77e4247518f0ab9df296f632963417c79ceac7f4", 
    "indexInProgress": "false", 
    "quality": "50", 
    "requiresUpdating": "yes", 
    "uniqueAbiAndAddressHash": "0xe666c441714e77c45920a855b1e93c9306f0c8768769627637993c9ae4d15bac"
  }
]
```

### Displaying smart contract data in your DApp

The strength of this system lies in the fact that there is no display configuration or schema required. In addition to this benefit, front-end developers are not required to learn any new skills, other than their existing HTML, JS and CSS. This system only requires that the front-end developer is aware of the smart contract which is driving the DApp which is under construction. Specifically, the frontend developer only needs to know what the ABI hash is. From there the frontend developer can go ahead and create HTML, JS and CSS to suit the requirements of the DApp. Here is an example.

The following Javascript code queries the smart contract search engine using an ABI hash. Once all instances of smart contracts which adhere to that hash are returned, the Javascript iterates through the contracts and sums the total of every contract's individual account balance.

Click here to see the front-end Javascript

```javascript
function displayTotal() {
    esss.shaAbi(JSON.stringify(abi)).then((shaResult) => {
        var sha = JSON.parse(shaResult).abiSha3;
        esss.searchUsingAbi(sha).then((searchResult) => {
            var items = JSON.parse(searchResult);
            var totalBodyInner = "";
            var total = 0;
            items.forEach(function(item) {
                total = total + parseInt(item.functionData.getAccountBalance);
            });
            console.log(total)
            totalBodyInner = totalBodyInner + "<tr id='total'><td>" + total + "</tr>";
            document.querySelector("#totalBody").innerHTML = totalBodyInner;
        });
    }); // end of esss
}
```

This code (which uses the ABI hash as a filter) demonstrates that the front-end is only required to parse and iterate through the smallest amount of data. The smart contract search engine does all of the work on the server side and only passes the appropriate slices of filtered data to the DApp's JS and subsequently the HTML output.

![](/files/-LlZO_hF6-vwm3qf1EQY)

You can use the [Data Drive DApp's source code](https://github.com/second-state/buidl/tree/master/demo/data-v2) and try [this demonstration](https://docs.secondstate.io/buidl-developer-tool/access-contracts-data) inside the [SecondState BUIDL tool](http://buidl.secondstate.io/). It literally only takes a few minutes to complete and does not require you to have any cryptocurrency or a wallet. The BUIDL tool works in any browser and even handheld devices such as iPads.


# Start a search engine (Docker)

Start a smart contract search engine for your own DApp

This documentation details how you can start, and host, your own [smart contract search engine](https://github.com/second-state/smart-contract-search-engine) using [Docker](https://www.docker.com/). If you would like to build from scratch from a fresh Ubuntu install, please refer to [this document](/smart-contracts-search-engine/start-a-search-engine).

## Prerequisite

We start from a fresh install of Ubuntu 18.04. You should first follow [the instructions here to install Docker](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04).

Next install the Python pip and AWS CLI utilities as follows. The AWS CLI is required to access AWS ElasticSearch services.

```bash
$ sudo apt update
$ sudo apt install python-pip
$ sudo apt install awscli
```

## ElasticSearch

We use the AWS ElasticSearch services to run the search engine. You should [create a new ES cluster here](https://console.aws.amazon.com/es/home). For now, a single machine development cluster would suffice. In the Access Policy section, please select IAM users. You will need [an IAM user already set up](https://console.aws.amazon.com/iam/home?#/users) to access AWS ES services. Here is an example.

```
arn:aws:iam::522901590065:user/secondstatesearch
```

Once the ElasticSearch service is up and running, you should have an ES endpoint like the following.

```
search-smart-contract-search-engine-3paomceha6u4qzchkmbgsjdcqa.us-east-1.es.amazonaws.com
```

## Docker

Now, go back to the Ubuntu 18.04 machine.

### AWS credentials

Configure AWS CLI to access the ElasticSearch engine.

```bash
$ aws configure
```

It requires four pieces of information. The access keys are found in the [IAM user console](https://console.aws.amazon.com/iam/home?#/users) for the user you configured to access the ElasticSearch engine you just created.

```
AWS Access Key ID [None]: [IAM user console]
AWS Secret Access Key [None]: [IAM user console]
Default region name [None]: [Region for ES instance. eg us-east-1]
Default output format [None]: json
```

After configuration, AWS config and credentials are placed in `~/.aws/`.

### Configure search engine

Next, get the source code for the search engine.

```bash
$ git clone https://github.com/second-state/smart-contract-search-engine.git
$ cd smart-contract-search-engine
```

Fill in the following configuration options.

* `ServerName` in apache config `config/site.conf`. This could be your public IP address for now.
* `blockchain`, `elasticsearch` , and the initial ABI configs in `python/config.ini`.
* `publicIp` in `js/secondStateJS.js`. This could be your IP address for now.
* Check [here](https://github.com/second-state/whitepapers/tree/2d68282b29af48f62e2075a36bd229f10fe51aa3/smart-contracts-search-engine/start-a-search-engine/README.md#javascript) for details about configurations.

### Build Docker image

```bash
$ docker build -f docker/Dockerfile -t search-engine .
```

### Run Docker container

```bash
$ docker run -d -it --rm -p 80:80 -v $HOME/.aws:/root/.aws search-engine
```

{% hint style="info" %}
If the above command failed because the host port 80 is already taken, try the following command `sudo apachectl stop` to stop the host apache server.
{% endhint %}

Now you can visit `http://<your_host>` to check your smart contract search engine. Be patient, as it may take hours before the results show up on that page.

## Upload more ABIs

Your search engine is started with a single ABI to index from the `config.ini` file. You can add more ABIs to the index by executing the following script from inside the Docker instance.

You can find the `container_id` for your docker instance on your host OS, by running

```bash
$ docker container ls
```

Next, logging into your docker container using the `container_id`

```bash
$ docker exec -it container_id bash
```

Once logged, in the `/app` directory, create a file `upload_abi.py` like the following.

```python
import re
import json
import time
import requests
from harvest import Harvest

harvester = Harvest()

abiUrl1 = "http://A_raw_text_file_which_contains_only_an_abi's_text"
abiData1 = requests.get(abiUrl1).content
abiData1JSON = json.loads(abiData1)
theDeterministicHash1 = harvester.shaAnAbi(abiData1JSON)
cleanedAndOrderedAbiText1 = harvester.cleanAndConvertAbiToText(abiData1JSON)

data1 = {}
data1['indexInProgress'] = "false"
data1['epochOfLastUpdate'] = int(time.time())
data1['abi'] = cleanedAndOrderedAbiText1
harvester.es.index(index=harvester.abiIndex, id=theDeterministicHash1, body=data1)
```

Then run

```bash
$ python3.6 upload_abi.py
```

Also once all of this is done, please just exit docker and give it a reboot.

```bash
$ docker restart container_id
```


# Notes on SSL with Docker

Setting up SSL with Docker requires multiple steps. First, get your domain ready.

* Make sure that your DNS domain name is mapped to the docker host's IP address
* Get `certificate.crt`, `private.key`, and `ca_bundle.crt` files for your domain at [sslforfree.com](https://www.sslforfree.com/).

Second, make sure that you have the https link for `publicIp` in the `js/secondStateJS.js` file.&#x20;

Third, add the following in the `config/site.conf` file.&#x20;

```
<VirtualHost *:443>
    ProxyPreserveHost On
    ProxyPass /api http://127.0.0.1:8080/api
    ProxyPassReverse /api http://127.0.0.1:8080/api
    ServerName localhost
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error-ssl.log
    CustomLog ${APACHE_LOG_DIR}/access-ssl.log combined

    SSLEngine on
    SSLCertificateFile /etc/apache2/certificate.crt
    SSLCertificateKeyFile /etc/apache2/private.key
    SSLCertificateChainFile /etc/apache2/ca_bundle.crt

    <Location "/">
        Header always set Access-Control-Allow-Origin "*"
        Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"
        Header always set Access-Control-Max-Age "1000"
        Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
        RewriteEngine On
        RewriteCond %{REQUEST_METHOD} OPTIONS
        RewriteRule ^(.*)$ $1 [R=200,L]
    </Location>
</VirtualHost>
```

Fourth, build and then start Docker with the following command to turn on port 443.

```
$ docker run -d -it --rm -p 80:80 -p 443:443 -v $HOME/.aws:/root/.aws search-engine
```

Fifth, start Docker and login. Create the `certificate.crt`, `private.key`, and `ca_bundle.crt` files under directory `/etc/apache2/`

Sixth, enable SSL modules.

```
root# cd /etc/apache2/mods-enabled
root# ln -s ../mods-available/socache_shmcb.load socache_shmcb.load
root# ln -s ../mods-available/ssl.load ssl.load
root# ln -s ../mods-available/ssl.conf ssl.conf
```

Finally, restart Apache from inside Docker.

```
root# apachectl restart
```

## Use Let's Encrypt

Alternatively, you can use Let's Encrypt to setup SSL automatically. Start Docker with the following command to turn on port 443.

```
$ docker run -d -it --rm -p 80:80 -p 443:443 -v $HOME/.aws:/root/.aws search-engine
```

Log into Docker.

```bash
$ docker exec -it container_id bash
```

Next, use Let's Encrypt services to setup SSL.

```bash
$ apt update && apt upgrade
$ apt install wget
$ wget https://dl.eff.org/certbot-auto -O /usr/sbin/certbot-auto
$ chmod a+x /usr/sbin/certbot-auto
$ certbot-auto --apache -d search.domain.com
```

Next, please open the `/etc/apache2/sites-enabled/*-ssl.conf` file (which was created automatically by the above command) and add the following code inside the `VirtualHost` section.

```
<VirtualHost *:443>
    ... ...
    <Location "/">
        Header always set Access-Control-Allow-Origin "*"
        Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"
        Header always set Access-Control-Max-Age "1000"
        Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
        RewriteEngine On
        RewriteCond %{REQUEST_METHOD} OPTIONS
        RewriteRule ^(.*)$ $1 [R=200,L]
    </Location>
</VirtualHost>
```

Replace the HTTP IP address below with your new HTTPS domain name.

* `ServerName` in apache config `config/site.conf`.&#x20;
* `publicIp` in `js/secondStateJS.js`.

Exit docker and give it a reboot.

```bash
$ docker restart container_id
```

Now, you should be able access the search engine from `https://search.domain.com` now.


# Start a search engine (Ubuntu)

This documentation details how you can start, and host, your own [smart contract search engine](https://github.com/second-state/smart-contract-search-engine) using Ubuntu 18.04LTS.

### Apache 2

Update system and install Apache2

```bash
sudo apt-get update
sudo apt-get -y upgrade
sudo apt-get -y install apache2
```

List the firewall rules and add Apache2 on port 80 only

```
sudo ufw app list
sudo ufw allow 'Apache'
```

Check that Apache is running

```
sudo systemctl status apache2
```

Enable modules for the proxy

```bash
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo systemctl restart apache2
```

Get the domain name (as discussed at the start of this page) and use it in the following steps i.e. search-engine.com or 13.236.179.58 (just the IP without the protocol). In this example, we are just using fictitious search-engine.com

Set up Virtual Host

```
sudo mkdir -p /var/www/search-engine.com/html
sudo chown -R $USER:$USER /var/www/search-engine.com/html
sudo chmod -R 755 /var/www/search-engine.com
```

Create the following configuration file

```
sudo vi /etc/apache2/sites-available/search-engine.com.conf
```

Add the following content to the file which you just created (note: we will explain the Proxy component a little later in this document). Obviously you will need to replace search-engine.com with your public IP/Domain

```
<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass /api http://127.0.0.1:8080/api
    ProxyPassReverse /api http://127.0.0.1:8080/api
    ServerAdmin admin@search-engine.com
    ServerName search-engine.com
    ServerAlias www.search-engine.com
    DocumentRoot /var/www/search-engine.com/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
```

Enable the new site

```
sudo a2ensite search-engine.com.conf
```

Disable the original Apache2 site

```
sudo a2dissite 000-default.conf
```

Test the configuration which we just created

```
sudo apache2ctl configtest
```

Reload the system to show the new site

```
sudo systemctl reload apache2
```

Here is a quick reference of commands which you will find usefull in the future

```
## Stop and start
sudo systemctl stop apache2
sudo systemctl start apache2
## Restart
sudo systemctl restart apache2
## Reload without interuption
sudo systemctl reload apache2
```

### Search engine source code

```bash
cd ~
git clone https://github.com/second-state/smart-contract-search-engine.git
```

Place the code in the appropriate directories

```bash
cp -rp ~/smart-contract-search-engine/* /var/www/search-engine.com/html/
```

Set final permissions on all files

```bash
sudo chown -R $USER:$USER /var/www/search-engine.com/*
```

#### Javascript

This system uses a single Javascript file which passes events and data back and forth between the HTML and Python. The code repository currently has one Javascript file `secondStateJS.js` which services the [FairPlay - Product Giveaway site](https://cmt.search.secondstate.io/) and one Javascript file `ethJS.js` which services the [Ethereum Search Engine Demonstration](https://ethereum.search.secondstate.io/). One of the strong points of this search engine is that it allows you to create your own custom HTML/JS so that you can render your data in any way.

**publicIp**

**publicIp** If running this in global mode, please make sure that the `var publicIp = "";` in the [secondStateJS.js file](https://github.com/second-state/whitepapers/tree/47778a98d431c2d32819ec8b263d8094a73bf390/js/secondStateJS.js) is set to the public domain name of the server which is hosting the search engine (including the protocol) i.e.

```
var publicIp = "https://www.search-engine.com"; //No trailing slash please
```

**searchEngineNetwork**

**searchEngineNetwork** in secondStateJS.js Please ensure that the correct network id is set in the "searchEngineNetwork" variable in the secondStateJS.js file i.e.

```
var searchEngineNetwork = "18"; // CyberMiles MainNet
```

**esIndexName**

**esIndexName** name in secondStateJS.js Please ensure that the appropriate index name will be set (depending on which network you selected in the previous step) The logic is as follows.

```
if (searchEngineNetwork == "19") {
    blockExplorer = "https://testnet.cmttracking.io/";
    esIndexName = "testnet";
}

if (searchEngineNetwork == "18") {
    blockExplorer = "https://www.cmttracking.io/";
    esIndexName = "cmtmainnetmultiabi";
}
```

Just please make sure that you set the esIndexName to the same value as the config.ini (i.e. note how the below config.ini common index and the above secondStateJS.js esIndexName are both set to testnet).

**This Javascript configuration will be made part of the global configuration as per the GitHub Issue**

```
[commonindex]
network = testnet
```

```
if (searchEngineNetwork == "19") {
    blockExplorer = "https://testnet.cmttracking.io/";
    esIndexName = "testnet";
}

if (searchEngineNetwork == "18") {
    blockExplorer = "https://www.cmttracking.io/";
    esIndexName = "cmtmainnetmultiabi";
}
```

#### Configuring the Python harvester (a single config.ini file)

It is important that the search engine is pointing to the correct RPC endpoint i.e. CMT TestNet vs MainNet. It is also important that you set the average block time (this will make the system run more efficiently).

```
[blockchain]
rpc = https://testnet-rpc.cybermiles.io:8545
seconds_per_block = 1
```

**Elasticsearch** Please also put in your Elasticsearch URL and region.

```
[elasticSearch]
endpoint = search-smart-contract-search-engine-abcdefg.es.amazonaws.com
aws_region = ap-southeast-2
```

**Index names** The masterindex, abiindex and bytecode index can all stay as they are below. You might just want to change the commonindex to be more descriptive i.e. mainnet, testnet etc.

```
# Stores every transaction in the blockchain which has a contractAddress (an instantiation of a contract as apposed to a transaction which just moved funds from one EOA to another)
[masterindex]
all = all

# Just stores ABI data (an index which holds every ABI that could match up with a contract address and make up a contract instantiation)
[abiindex]
abi = abi

# Just stores a contracts bytecode with the appropriate key to find said bytecode
[bytecodeindex]
bytecode = bytecode

# Stores all of the smart contract instance details, ABI hashes, function data etc.
[commonindex]
network = network

# Ignore stores ABI and contract address Sha3 values which are not contract instantiations. This improves performance greatly because an ABI hash mixed with a contract address hash will either be a contract instance or not and this will never change once set.
[ignoreindex]
ignore = ignore

# The default number of threads is set to 500. However, this value can be raised if you also raise the ulimit when starting the harvest.py scripts i.e. adding ulimit -n 1000 will facilitate a setting here of max_threads = 1000
[system]
max_threads = 500

# Please provide a raw GitHub URL which contains your first ABI. This is required for the search engine to initialize
[abi_code]
initial_abi_url = https://raw.githubusercontent.com/tpmccallum/test_endpoint2/master/erc20_transfer_function_only_abi.txt
```

### SSL (HTTPS) using "lets encrypt"

```
sudo wget https://dl.eff.org/certbot-auto -O /usr/sbin/certbot-auto
```

```
sudo chmod a+x /usr/sbin/certbot-auto
```

```
sudo certbot-auto --apache -d search-engine.com  -d www.search-engine.com
```

### Potential issues with SSL

There is [a known issue](https://github.com/certbot/certbot/issues/6824) which results in the following error message...

```
subprocess.CalledProcessError: Command '['virtualenv', '--no-site-packages', '--python', '/usr/bin/python2.7', '/opt/eff.org/certbot/venv']' returned non-zero exit status 1
```

If you experience this, please use [this alternative solution](https://certbot.eff.org/lets-encrypt/ubuntubionic-apache) for certbot-auto

```
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
```

```
sudo apt-get install certbot python-certbot-apache
```

```
sudo certbot --apache
```

Then follow the prompts.

### Harvesting

Please follow the instructions below so that your system can automatically execute all of the search engine's scripts.

### Operating system libraries

Python3

```bash
sudo apt-get -y update
sudo apt-get -y upgrade

# If using Ubuntu 18.04LTS Python 3.6 will already be installed

# If using older Ubuntu, you will need to install Python3.6 and Python3.6-dev 
#sudo add-apt-repository ppa:jonathonf/python-3.6
#sudo apt-get -y update
#sudo apt-get install python3.6-dev
```

Pip3

```bash
sudo apt-get -y install python3-pip
```

Eth-Abi

```
python3.6 -m pip install eth-abi --user
```

Web3

```
python3.6 -m pip install web3 --user
```

Boto3

```bash
python3.6 -m pip install boto3 --user
```

AWS Requests Auth

Note: this particular implementation of the smart contract search engine uses AWS Elasticsearch and as such there is a small amount of Amazon and Elasticsearch specific configuration. You can choose to use your own local installation of Elasticsearch if you prefer that.

```
python3.6 -m pip install aws_requests_auth --user
```

AWS Command Line Interface (CLI)

```
sudo apt-get install awscli
```

Configuring AWS CLI See [official AWS documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) as required

```
aws configure
```

Elasticsearch

```
python3.6 -m pip install elasticsearch --user
```

### Elasticsearch

**AWS provides Elasticsearch as a service. To set up an AWS Elasticsearch instance visit your AWS console using the following URL.**

```
https://console.aws.amazon.com/console/home
```

### Amazon Web Services (AWS)

**Authentication and access control**

Please read the [Amazon Elasticsearch Service Access Control](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-ac.html) documentation. This very flexible authentication and access control can be set up after the fact by writing a policy.

### Recommended usage - Run once at startup!

**Run at startup**

Technically speaking you will just want to run all of these commands the **one** time, at startup!. The system will take care of itself. Here is an example of how to run this once at startup.

Create a bash file, say, `~/startup.sh` and make it executable with the `chmod a+x` command. Then put the following code in the file. **Please** be sure to replace `https://testnet-rpc.cybermiles.io:8545` with that of your RPC.

```bash
#!/bin/bash
while true
do
  STATUS=$(curl --max-time 30 -s -o /dev/null -w '%{http_code}' https://YOUR RPC NODE GOES HERE)
  if [ $STATUS -eq 200 ]; then
    cd /var/www/search-engine.com/html/python && ulimit -n 10000 && nohup /usr/bin/python3.6 harvest.py -m init >/dev/null 2>&1 &
    cd /var/www/search-engine.com/html/python && ulimit -n 10000 && nohup /usr/bin/python3.6 harvest.py -m abi >/dev/null 2>&1 &
    cd /var/www/search-engine.com/html/python && ulimit -n 10000 && nohup /usr/bin/python3.6 harvest.py -m full >/dev/null 2>&1 &
    cd /var/www/search-engine.com/html/python && ulimit -n 10000 && nohup /usr/bin/python3.6 harvest.py -m topup >/dev/null 2>&1 &
    cd /var/www/search-engine.com/html/python && ulimit -n 10000 && nohup /usr/bin/python3.6 harvest.py -m tx >/dev/null 2>&1 &
    cd /var/www/search-engine.com/html/python && ulimit -n 10000 && nohup /usr/bin/python3.6 harvest.py -m state >/dev/null 2>&1 &
    cd /var/www/search-engine.com/html/python && ulimit -n 10000 && nohup /usr/bin/python3.6 harvest.py -m bytecode >/dev/null 2>&1 &
    cd /var/www/search-engine.com/html/python && ulimit -n 10000 && nohup /usr/bin/python3.6 harvest.py -m indexed >/dev/null 2>&1 &
    cd /var/www/search-engine.com/html/python && ulimit -n 10000 && nohup /usr/bin/python3.6 harvest.py -m faster_state >/dev/null 2>&1 &
    break
  else
    echo "Got $STATUS please wait"
  fi
  sleep 10
done
```

Add the following command to cron using `crontab -e` command.

```bash
@reboot ~/startup.sh
```

The smart contract search engine will autonomously harvest upon bootup.

### Detailed explanation of harvesting modes

#### Full

The `harvest.py -m full` mode operates in the following way. It divides the number of blocks in the blockchain by the `max_threads` setting in the [config.ini](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L27) file, to create chunks of blocks. It then starts a separate thread for each of those chunks. Each chunk is harvested in parallel. For example, if the blockchain has 1 million blocks and the `max_threads` value is 500, there will be 500 individual threads processing 2, 000 blocks each.

The `harvest.py -m full` mode quickly and efficiently traverses the entire blockchain with its sole purpose being to find transactions which involve smart contracts. Transactions which involve smart contract creation i.e. have a contract address in the transaction receipt are stored in the smart contract search engine's [masterindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L9).

#### Topup

The `harvest.py -m topup` mode operates in the following way. It uses the following formular to determine how many of the most recent blocks to harvest.

```python
stopAtBlock = latestBlockNumber - math.floor(100 / int(self.secondsPerBlock))
```

For example if the blockchain has 1 million blocks and the `seconds_per_block` [in the config.ini](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L3) is set to 10, the system will process the most recent block `1000000` and stop at block `999990` (harvest only the 10 most recent blocks). Once executed, this topup will run repeatedly i.e. it does not have to be run using cron because it already uses Python `time.sleep` and will repeat as required.

The `harvest.py -m topup` mode quickly and efficiently traverses only a few of the latest blocks with its sole purpose being to find only the most recent transactions which involve smart contracts. These are stored in the smart contract search engine's [masterindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L9).

Both of the above modes have only identified (and saved to the masterindex) transactions which involve the creation of smart contracts. None of this data is searchable via the API. These full and topup modes are run at all times as they provide the definitive list of transactions which the search engine has to process on an ongoing basis.

#### Transaction (tx)

The `harvest.py -m tx` mode operates in the following way. It takes all of the known ABIs which are stored in the [abiindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L15) and all of the known smart contract related transactions which are stored in the smart contract search engine's [masterindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L9). It then creates a web3 smart contract instantiation for every combination and tests to see if web3 can sucessfully call all of the contract's public view functions.

If the contract address is *not* already in the commonindex, and the contract instance returns valid data for all of the public/view functions defined in the ABI, then a new entry is created in the [commonindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L12).

If the contract address is already indexed in the commonindex, there is still a chance that this particular ABI and smart contract combination is new. Therefore the code will go ahead and try to instantiate a web3 contract instance with the ABI and address at hand. If the public view functions of the contract instance are all returned perfectly then the code will assume that this is an associated ABI i.e. a valid ABI which is part of Solidity inheritance etc. The outcome of this process will include the abiShaList being updated as well as the functionDataList seeing the addition of the new data.

If the contract instance is unable to return valid data for each of the public view functions of the ABI in question, then it is assumed that the contract address and the ABI were never related. This combination goes into the [ignoreindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L21) because this will never change.

#### Faster State

The `harvest.py -m faster_state` mode operates in the following way. It traverses only the most recent blocks, calls the public/view functions of the contracts in those blocks and updates the [commonindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L12). Remembering that the commonindex is the index which provides the smart contract state data to the API.

*Note* This `-m faster_state` mode requires that the smart contract instantiation (both the transaction hash and all associated ABIs) is already known to the smart contract search engine indices. This requires work. This mode was created for a special case whereby the search engine was required to provide real-time data for a blockchain with 1 second block intervals. Part of this special use case required that the software which was responsible for instantiating new contracts explicitly indexed the contract's ABIs and also the transaction hash of the contract instantiation. This was achieved via the [submitManyAbis](https://github.com/second-state/es-ss.js#submit-many-abis-in-conjuntion-with-a-single-tx-hash-for-indexing) API call.

This mode provides the fastest data updates available. However, as mentioned above, it also needs to have each contract's ABIs and transaction hash to be purposely indexed asap. This mode is not about self discovery, but rather about explicit indexing in real-time. The system can perform self discovery but the self discovery process (testing combinations of many ABIs and many contract addresses i.e. millions of combinations) takes longer than 1 second.

#### ABI

The `harvest.py -m abi` mode operates in the following way. It fetches the already indexed records from the [commonindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L12) and also fetches all of the already indexed ABIs from the [abiindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L15). It then creates web3 contract instantiations for each of the combinations. Then in relation to each combination, if the contract instance is unable to return the public view function data perfectly then the ABI and address combiination is added to the ignoreindex. This prevents the abi mode from ever checking that particular ombination out again. On the other hand, if the public view functions of the contract instance are all returned perfectly, the code will assume that this is an associated ABI i.e. a valid ABI which is part of Solidity inheritance etc. The outcome of this process will include the abiShaList being updated as well as the functionDataList seeing the addition of the new data.

The primary purpose of the ABI mode is to introduce newly uploaded ABIs to pre-existing contract addresses of which they may be associated with.

#### State

The `harvest.py -m state` mode operates in the following way. It fetches all indexed contracts from the [commonindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L12). It reads their abiShaList and creates a web3 contract instance for each of the ABI / address combinations. Now the ABI address combinations are not questionable because they have already been through a process of making sure that they are a real relationship which can yield real data. The state mode fetches the public view data from the contract and updates the index if the data is different to what was originally stored. It also creates a local hash of the data so that when it repeats this process over and over it can compare hashes on local disk rather than remotely issuing queries to the index.

#### Bytecode

The `harvest.py -m bytecode` mode operates in the following way. It fetches all indexed contracts and matches their bytecode (which is in theie transaction instance input) with any individual bytecode entries in the [bytecodeindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L18)

#### Indexed

The `harvest.py -m indexed` mode operates in the following way. It loops through all of the indexed contracts from the [commonindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L12) and sets the `indexed` value of any item in the [masterindex](https://github.com/second-state/smart-contract-search-engine/blob/45ea54d0217fff0973a40f95c688ac03eedc2e1c/python/config.ini#L9) to `true` if the contract addresses from the two indices match. This is an independent script which does not have to be run, however it does help speed up performance slightly by excluding any already indexed items when the tx mode is executed.

### Flask

```
python3.6 -m pip install Flask --user
```

### Python Flask / Apache2 Integration

```bash
sudo ufw allow ssh
sudo ufw enable
sudo ufw allow 8080/tcp
sudo ufw allow 443/tcp
```

Open crontab for editing

```bash
crontab -e
```

Add the following line inside crontab

```bash
@reboot sudo ufw enable
@reboot cd /var/www/search-engine.com/html/python && nohup /usr/bin/python3.6 io.py >/dev/null 2>&1 &
```

### CORS (Allowing Javascript, from anywhere, to access the API)

To enable CORS please following these instructions.

Ensure that Apache2 has the mod\_rewrite enabled

```
sudo a2enmod rewrite
```

Ensure that Apache2 has the headers library enabled by typing the following command.

```
sudo a2enmod headers
```

Open the `/etc/apache2/apache2.conf` file and add the following.

```
<Directory /var/www/search-engine>
     Order Allow,Deny
     Allow from all
     AllowOverride all
     Header set Access-Control-Allow-Origin "*"
</Directory>
```

Then in addition to this, please open the `/etc/apache2/sites-enabled/search-engine-le-ssl.conf` file (which was created automatically by the above "lets encrypt" command) and add the following code inside the `VirtualHost` section.

```
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
```

Also once all of this is done, please just give the server a quick reboot; during this time all of the processes will fire off as per the cron etc.

```
sudo shutdown -r now
```

## Talking to the smart contract search engine from your DApp

The [es-ss.js](https://github.com/second-state/es-ss.js) data services library provides a simple way for your DApp to talk to the data (using native Javascript(client side) and/or Node(server side)) which is indexed in this system.


# Demos


# Enterprise middleware for blockchain smart contracts

Blockchain smart contracts enable enterprises to automate business decisions and processes in a transparent and collaborative environment. Second State creates a suite of open source infrastructure for enterprise middleware, including [blockchai](https://github.com/second-state/devchain)n, [virtual machine](https://github.com/second-state/lityvm), [rules engine](https://www.litylang.org/business_rules/), [search engine](https://github.com/second-state/smart-contract-search-engine), data analytics services, together with [development and DevOps tools](https://buidl.secondstate.io/), to support enterprise deployment of smart contracts.

## Smart contracts in enterprises

In the past several years, blockchain technology has seen increasing acceptance by enterprises. However, most enterprise blockchain use cases are still limited to shared ledger. For example,

* Businesses are increasingly accepting mainstream cryptocurrencies, such as BTC and ETH, as a payment option.
* Business to business payments, including inter-bank settlements, are conducted over permissioned blockchains using specialized cryptocurrencies such as Ripple or Stellar.
* Businesses are recording data, such as deeds, legal documents, and product sourcing information, on public and permissioned blockchains.

However, those use cases have only limited business value. The shared ledger only serves as a consensus data store without much intelligence. The true potential of blockchain in enterprises is to serve as a general platform for business computing. For example,

* It could make an automatic payment when a shipment is received.
* It could forfeit deposit when a deadline is missed.
* It could release insurance payout when an accident or disease diagnosis is confirmed.
* It could cancel service plans when a customer stops paying.
* It could compute bonus for employees when they work overtime.
* It could compute rewards for customers when they purchase products.

Currently, such business decisions are made by humans or proprietary application software behind firewalls. Costly disputes and unhappy customers are often the results. A better solution is radical transparency and automation in such business decisions.

Computing tasks performed on the blockchain are completely transparent to participants. The executable code is not only open source but verifiable at runtime. The agreements between parties in business transactions, known as contracts, are now codified as computer programs known as smart contracts.

The blockchain virtual machine is the key infrastructure component to enable diverse smart contracts. Virtual machine-based smart contracts can be written and deployed by any participant at any time without stopping the blockchain. An enterprise could make thousands of business decisions between parties every day, and all those decisions can be codified into smart contracts for automated and guaranteed enforcement.

**At Second State, we take an enterprise middleware approach to blockchain infrastructure.** While [the decentralized ledger](https://github.com/second-state/devchain) is analogous to a database, [the virtual machine](https://github.com/second-state/lityvm) is analogous to the application server. Smart contracts and blockchain data services are analogous to application services deployed on the application servers.

![Second State's enterprise middleware](/files/-Lp7EBMTOpjbxRsK9oxH)

In the rest of this paper, we will explore how the Second State open source middleware empowers enterprise developers to solve real-world business problems. We will cover topics such as

* [Virtual machine](https://github.com/second-state/lityvm) (application server) with enterprise features and optimizations
* Smart contract application services such as [rules engine](https://www.litylang.org/business_rules/) and [search engine](https://github.com/second-state/smart-contract-search-engine)
* [A modular smart contracts](https://docs.secondstate.io/white-papers/www.fairplaydapp.com) and DApps application framework
* Enterprise-ready data exploration and analytics tools
* [RAD developer tools](https://buidl.secondstate.io/)
* [One-click deployment solutions](http://baas-mvp.secondstate.io/)

Now let’s get started!

## Enterprise-ready smart contracts

[The Second State blockchain virtual machine](https://github.com/second-state/lityvm) is fully compatible with the Ethereum Virtual Machine, but with additional features required by enterprise customers. The Second State smart contract programming language is an extension to the Solidity language. It is called [Lity](https://docs.secondstate.io/white-papers/www.litylang.org).

### Business rules engine

In today’s enterprises, business rules engines (BREs) are widely used to make automated decisions. Rules engines and smart contracts are a perfect match for each other. On one hand, smart contracts are often just rules to be triggered and executed by blockchain transactions. On the other hand, business rules can be guaranteed to execute as written if they are codified in smart contracts. We believe that blockchains are perfect runtimes for rules engines especially when rules need to be audited and verified by multiple parties.

Lity allows users to [create formal business rules in smart contracts](https://www.litylang.org/business_rules/). The Lity rules language constructs are modeled after the popular Drools rules engine. It allows business analysts to create and update rules, and users to verify rules deployed on the blockchain. You can read more about [the Lity rules language here](https://www.litylang.org/business_rules/).

### On-chain and off-chain collaboration

In order to automate real-world business decisions, smart contracts must receive real-world information and events. Lity allows certain smart contracts methods to be only invoked by trusted and verified offline entities known as Oracles.

In Lity, [Oracles](https://www.litylang.org/trusted/) are first class programming constructs supported at the language level. Lity smart contracts could detect and trust transactions from the system’s validator nodes. This allows “ground truth”, such as real-world payment confirmations, product shipping confirmation, medical diagnosis, or even the weather, to be provided to enterprise smart contracts in a transparent and verifiable manner. You can read more about [Lity’s oracle support here](https://www.litylang.org/trusted/).

### More Lity enterprise features

Besides the smart contract rules engine, Lity provides several additional key enhancements to make smart contracts more usable to enterprises.

* Lity provides a native code extension to smart contracts called [libENI,](https://www.litylang.org/performance/) which allows computationally intensive tasks to be delegated to native code.
* Lity provides a comprehensive string library, including a JSON library for processing complex input/output data in smart contracts.
* Lity supports [secure random numbers](https://www.litylang.org/rand/) generated by its block producer nodes.

Taken together, [Lity](https://docs.secondstate.io/white-papers/www.litylang.org) is the most versatile and enterprise-friendly smart contract platform on the market today.

## Modular application services

Most of today’s DApps (Decentralized Apps, typically web UI for smart contracts) rely on a single monolithic smart contract to serve as the “backend”. The smart contract manages all application users and states. Even for systems that consist of multiple contracts, there is typically a registry or manager contract that provides aggregated information about the system.

However, a large smart contract is difficult to write and maintain. It tends to be error-prone, and nearly impossible to fix when an error or issue is discovered, exacerbating the security problems which have plagued DApps to this day. The registry contract is also constrained by the limitations of today’s smart contract programming languages and virtual machines. It cannot support complex data query operations.

A smart contract search engine can serve as the aggregation point of all on-chain data for a DApp. That allows the DApp to have a modular design. By breaking up a monolithic smart contract into many smaller ones, we make smart contracts easier to write, upgrade, and maintain.

For example, the [FairPlay DApp](https://www.fairplaydapp.com/) is a product promotion/giveaway DApp on the CyberMiles public blockchain based on Second State software.

### FairPlay: a case study

[Each FairPlay giveaway event](https://docs.secondstate.io/white-papers/www.fairplaydapp.com) is its own smart contract. When someone creates a new giveaway, she deploys a new instance of the FairPlay smart contract. That allows us to continuously improve the FairPlay contract to add features and fix bugs.

The FairPlay DApp home screen is the search engine. It allows users to find giveaways containing specific keywords or tags, as well as the user’s previously participated giveaways. The search engine indexes information from all FairPlay contracts deployed on the blockchain.

![Use case: FairPlay DApp](/files/-LoySAGjISoIttnymtcr)

The search engine-based DApps do not require monolithic smart contracts. Instead, each smart contract in the DApp is designed to complete a limited set of specific business transactions. All related smart contracts are aggregated in the search engine. This pattern allows smart contracts to be modular and focused, while still providing a good end user experience.

## Analytics and insights

The Second State smart contract search engine not only enables new modular DApp designs but also supports analytics of smart contract use on the enterprise blockchain. One of the challenges for blockchains is that transactions (including smart contract calls) are recorded chronologically in blocks. It is difficult to get a snapshot view of a specific account or contract at a given point of time. It is also difficult to follow transactions from or to specific addresses over time. That has given rise to blockchain explorers.

The blockchain explorers for legacy blockchains (eg [EtherScan.io](https://etherscan.io/) and [blockchain.com](https://www.blockchain.com/)) are focused on providing data for coin transactions. But for enterprise blockchains, coin transactions are often not important. Method calls, events, and state changes in smart contracts are important for enterprise users. The search engine allows us to find contracts of a specific type, examine their current states, and look into the state change history of individual contracts. The data can then be aggregated, graphed, and reported to users.

To see such smart contract search engines in action, check out our live demos on the [Ethereum](https://eth.search.secondstate.io/) and [CyberMiles](https://cmt.search.secondstate.io/) public blockchains.

## Developer tools

Enterprise blockchains built with Second State software all have standard interfaces for users to create, call, and manage smart contracts.

* Blockchain nodes provide network interfaces to accept remote RPC calls. The Second State RPC interfaces are backward compatible with the Ethereum RPC standard.
* The Second State search engine provides an ElasticSearch compatible JSON web services interfaces for queries.
* The node RPC and search engine JSON interfaces can be accessed via JavaScript wrapper libraries [web3-ss.js ](https://github.com/second-state/web3-ss.js)and s[earch-ss.js.](https://github.com/second-state/es-ss.js)

Besides the [web3-ss.js ](https://github.com/second-state/web3-ss.js)and [search-ss.js](https://github.com/second-state/es-ss.js) libraries, Second State provides a suite of open source tools for enterprise developers to create and deploy smart contracts on its software platform.

### Web-based IDE

For beginners, Second State hosts a [web-based IDE,](https://buidl.secondstate.io/) called BUIDL, to develop and deploy Lity smart contracts. You can create Lity smart contracts directly in any modern web browser, compile it to bytecode and ABI, and then deploy to a test blockchain (ie the[ DevChain](https://github.com/second-state/devchain), see below).

BUIDL also provides a JavaScript playground to write DApps that interact with the deployed contracts, and the search engine for the test environment. The BUIDL JavaScript playground already has [web3-ss.js](https://github.com/second-state/web3-ss.js) and [search-ss.js](https://github.com/second-state/es-ss.js) configured, and you can immediately start building.

You can access [the public BUIDL tool here](https://buidl.secondstate.io/).

### Command line tools

For more advanced users, Second State provides command line tools for the Lity language. You can compile and build Lity smart contracts using the lityc tool. The Lity command line tool also supports static analysis of smart contracts to ensure their safety and compliance to standards. You can read more about [the Lity static analyzers here](https://www.litylang.org/security/).

### The Second State DevChain

The BUIDL IDE connects to the Second State [DevChain,](http://baas-mvp.secondstate.io/) which is a public testnet running the latest stable software. You can also connect to the DevChain via RPC, ElasticSearch JSON, or web3-ss.js and search-ss.js.

It intends to be a test environment for smart contract and DApp developers. All applications deployed on the DevChain are public.

## Easy deployment

Second State enterprise blockchain and smart contract software is [open source](https://github.com/second-state). You can download the source code from [GitHub](https://github.com/second-state) and build your own enterprise blockchain. Or you can download our automated release builds, including Docker images. All free of charge.

But if you are interested in a worry-free and hassle-free supported solution in the cloud, you could consider the Second State hosted services. You can select features needed for your enterprise blockchain on a web interface, and click one button to deploy a production-ready blockchain across multiple cloud availability zones. The blockchain itself, its connected search engine, and its [BUIDL tools](https://buidl.secondstate.io/) would all be managed by Second State.

Give it a try!

As we had discussed before, a key feature of the Second State blockchain system is that it is very easy to deploy smart contracts on-demand. Once the blockchain is up and running, it is easy to deploy smart contracts onto it via [BUIDL](https://buidl.secondstate.io/), or web3-lity.js, or the node RPC interface.

## Conclusions

Second State provides a full stack of open source middleware to support enterprise applications on blockchains. Try our solutions, and get in touch if you are interested in further collaborations!


# Google for smart contracts

[Second State](https://www.secondstate.io) has released an [open source blockchain search engine](https://github.com/second-state/smart-contract-search-engine) for smart contracts. It is modular by design; providing flexibility and versatility, as well as scalability. It is the world’s first search engine to provide deep insights into smart contract data and transactions, and hence enable new types of innovative DApps to be developed and supported.

![](/files/-LlUI1XJvfOtlxORLsq3)

## Background

Blockchain technology is continually gaining popularity in diverse industries. This technology is poised to revolutionize both financial services and e-commerce industries, at a minimum.

Whilst, the original Bitcoin blockchain continues to provide a mechanism to secure and manage a decentralized cryptocurrency ledger, recent advances in blockchain technology have shown that blockchain networks can also be designed to function as general purpose computing platforms, which facilitate rule-based collaborations between untrusted parties.

The first generation of blockchain data browsers were focused primarily on providing snapshots of transaction details. For example, in the case of Bitcoin, displaying verbatim records of structured data; the results of valid transactions executed at the rigid base layer protocol.

The unprecedented rise of smart contracts, with customized data fields and unique internal programmable logic, has brought about the need for a new mechanism. One which can provide an easy way to search and visualize this new, and rich, unstructured blockchain data.

This mechanism would be analogous to the rise of search engines, as the web grew in the 1990s. However, blockchain networks are unique in that they record all data in a time series of transactions. Smart contract data needs to be indexed and made available to both end-users and machines in real-time. Traditional web search engine technology is seldom used in the blockchain world because the world wide web and blockchain networks are fundamentally different.

## Decentralized Application(DApps)

The ethos of decentralization is to empower the individual. In order to achieve this, we need to build software products which can run on inexpensive consumer grade (store bought) hardware.

The smart contract search engine can be thought of as a middle layer between a blockchain full node and a decentralized application (DApp). This product is an essential part of the future of DApps.

DApps primarily run on lightweight handheld, mobile devices. The continuous overhead of simultaneously storing and broadcasting all information on the blockchain network makes it impossible for mobile devices to participate as full blockchain nodes. Mobile devices need another way to access blockchain data.

It is a well-known fact that mobile and handheld devices have surpassed the traditional desktop PC, in terms of usage, for many years now. Deploying DApps on these smaller, more convenient and more popular, devices is paramount for the adoption and sustainability of DApps.

Second State, an enterprise blockchain startup, has released a[n open source search engine and API](https://ethereum.search.secondstate.io/) which allows DApps to easily access smart contract data on all Ethereum-compatible blockchains.

* For public blockchains, Second State is providing a free search engine service.
* For permissioned blockchains, Second State provides supported open source software to power search engines behind the firewall.
* For DApp developers, Second State provides open source software to build your own search engine as part of the DApp.

Note: DApp stores support DApps searches based on manual tags and labels. They do not search inside DApp smart contracts and do not search for past contract state changes and events caused by transactions. DApp stores are structured directory services (i.e. Yahoo) rather than an unstructured search engine (i.e. Google).

Now, let’s look into how the search engine gives business insights into smart contracts data. The search engine can make today’s smart contracts much easier to use.

## USE cases

Second State’s new [public search engine for the Ethereum blockchain ](https://eth.search.secondstate.io/)is based on our open source software. Compared with Ethereum blockchain explorers (such as EtherScan.org), the Second State public search engine specifically focuses on the data inside smart contracts as opposed to just coin transactions. Here are some more interesting use cases.

### Crypto assets

Crypto assets Crypto assets are represented by a large number of standard contracts such as ERC20, ERC721, and even ERC1400. A search engine could provide an aggregated view of all account balances and transactions across those contracts.

Essentially, every ERC smart contract standard could benefit from a search engine that aggregates and displays information across all contracts of the same type.

### DeFi

Decentralized crypto exchanges often have multiple asset pools each represented by a smart contract. A search engine can provide deep insights into the history and current state of those pools.

In general, DeFi (decentralized finance) solutions, such as algorithmic stable coins, crypto loans, staking pools, all have asset pools hold by smart contracts. A search engine could provide deep insights into those pools. Stay tuned for more from Second State on this front!

While searching into existing smart contracts is an important capability, it is only part of our story. More significantly, the search engine could enable new DApp designs that deliver enhanced user experience. The [FairPlay DApp](https://github.com/second-state/whitepapers/tree/6fa6091bc56cd5a11fccab42bef91975ebc05a46/white-papers/www.fairplaydapp.com) recently released on the CyberMiles public blockchain is a great example.

### Gaming

Blockchains allow participants, from anywhere in the world, to play games against each other without the need for a central operator or a trusted setup. A decentralized game is run entirely in accordance with a smart contract’s logic. The smart contract will not allow a player to perform an invalid move, or participate out of turn. The smart contract ensures correctness and fairness, right from the initial rules of engagement through to the final payout or reward.

DApps which constitute the front-end (a visually stimulating component of the game) obtain the real-time state of the game, programmatically, via the smart contract search engine API.

The entire ecosystem is safe and reliable. The steps below are repeated until a satisfactory outcome is achieved.

For example:

* The DApp visually displays the current state of the game to the end-users
* If it is their turn, each end-user makes a choice by touching or swiping the screen etc.
* The DApp submits that choice to the smart contract
* The smart contract validates the instruction set which the DApp sent
* The smart contract executes the instruction set if valid
* The smart contract’s state is/isn’t updated accordingly
* The DApp re-displays the current state of the game (via the API) to the end-users

## Modular DApps

Most of today’s DApps rely on a single monolithic smart contract to serve as the “backend”. The smart contract manages all application users and states. Even for systems that consist of multiple contracts, there is typically a registry or manager contract that provides aggregated information about the system.

However, a large smart contract is difficult to write and maintain. It tends to be error-prone, and nearly impossible to fix when an error or issue is discovered, exacerbating the security problems that had plagued DApps today. The registry contract is also constrained by the limitations of today’s smart contract programming languages and virtual machines. It cannot support complex data query operations.

A smart contract search engine can serve as the aggregation point of all on-chain data for a DApp. That allows the DApp to have a modular design. By breaking up a monolithic smart contract into many smaller ones, we make smart contracts easier to write, upgrade, and maintain.

For example, the FairPlay DApp is a [product promotion/giveaway DApp](https://github.com/second-state/whitepapers/tree/6fa6091bc56cd5a11fccab42bef91975ebc05a46/white-papers/www.fairplaydapp.com) on the CyberMiles public blockchain. With over 1000 DAU, it is one of the most popular blockchain DApps. The design of FairPlay is completely modular.

![](/files/-LjqDv73oE79gvQ3XDmf)

Each giveaway event is its own smart contract. When someone creates a new giveaway, she deploys a new instance of the FairPlay smart contract. That allows us to continuously improve the FairPlay contract to add features and fix bugs.

The FairPlay DApp home screen is the search engine. It allows users to find giveaways containing specific keywords or tags, as well as the user’s previously participated giveaways. The search engine indexes information from all FairPlay contracts deployed on the blockchain.

The search engine-based DApps do not require monolithic smart contracts. Instead, each smart contract in the DApp is designed to complete a limited set of specific business transactions. All related smart contracts are aggregated in the search engine. This pattern is much closer to the design goal of smart contracts, and hence allow the DApp to be more decentralized.

## The enterprise search engine

The smart contract search engine is especially useful in permissioned blockchains for enterprises.

A key characteristic of enterprise blockchains is that they tend to codify the repeatable business process into contract transactions. For example, a supply chain management blockchain solution could create a smart contract, modeled after a real-world legal contract, for each escrow payment. A clearinghouse/settlement blockchain could use smart contracts to compute settlement fees and exchange rates, and it could create a new contract for each pair of settlement parties. The search engine allows developers to build DApps that aggregate those contracts and provide a big picture view of the entire business process by connecting relevant contract transactions.

Every Second State managed enterprise blockchain comes with a dedicated search engine.

## Developers

To build a smart contract search engine for your own DApp or enterprise blockchain, please follow our instructions to build a Docker image for the search service and then configure it to index specific contracts on a specific blockchain.

To query the search engine or to submit new ABIs to index, you can use the Elastic Search API or use the [es-ss.js](https://github.com/second-state/es-ss.js) JavaScript library. The [es-ss.js](https://github.com/second-state/es-ss.js) library is also bundled in the [BUIDL tool](https://buidl.secondstate.io/) so that you can write search engine-enabled DApps directly from the online IDE. Every smart contract created from BUIDL is automatically indexed by the connected search engine. Check out how to get started with the search engine in BUIDL.

### Open source community

The smart contract search engine is completely open source. In its purest form, it uses the following FOSS products/code

* [Ubuntu](https://ubuntu.com/)
* [Apache2](https://httpd.apache.org/ABOUT_APACHE.html)
* [HTML ](https://www.w3schools.com/html/)
* [CSS](https://www.w3schools.com/css/)&#x20;
* [Python](https://www.python.org/)&#x20;
* [Web3py ](https://web3py.readthedocs.io/en/stable/)
* [Elasticsearch](https://www.elastic.co)&#x20;
* [LetsEncrypt](https://letsencrypt.org/)

Whilst it is possible to implement any combination of the above products/code on proprietary services, it is important to note that this smart contract search engine is not dependent on any proprietary systems or services. It will operate at its full capacity using open and free resources.

The presentation layer is built using standard and ubiquitous HTML/CSS/JavaScript. This means that not only is the frontend highly customizable, the presentation layer is able to be customized in parallel by one of your team members with HTML/JS skills. There is no need to learn about new application frameworks. There is also no need to install complex integrated development environments (IDEs) or build tools; a simple text editor will suffice, if that is all you have available.

The smart contract search engine is specifically designed to run in many modes. For example, it can be run on localhost (using HTML/JS and without the need for a web server). In contrast to this, it can also be run as a global public facing HTTPS website and/or as a public facing HTTPS API data endpoint.

The smart contract search engine allows you to upload one or many smart contract Application Binary Interface (ABI) files. Once an ABI is present, the system will sweep through the blockchain and index every contract instance which uses that ABI. Some use cases only require that one or two ABIs be indexed. For example the [FairPlay Product Giveaway DApp ](https://github.com/second-state/whitepapers/tree/6fa6091bc56cd5a11fccab42bef91975ebc05a46/white-papers/www.fairplaydapp.com)which currently has both a [version 1](https://github.com/CyberMiles/smart_contracts/tree/master/FairPlay/v1) and [version 2 ](https://github.com/CyberMiles/smart_contracts/tree/master/FairPlay/v2)of its smart contract. Perhaps in some other use cases many more ABIs are required. For example, the [Ethereum Search Engine Demonstration](https://eth.search.secondstate.io/) which has over 100 ABIs.

### Control and efficiency

All indexing/harvesting takes place in a single Python file. The functions in this file are reusable for your own custom external tooling. For example, you can [index a smart contract instance in under 10 lines of code](https://github.com/second-state/smart-contract-search-engine/blob/multiple_canonical_abi_support/python/upload_single_abi_and_tx.py). This is useful for rapid development and testing as well as system interoperability. You can easily achieve simple yet powerful and flexible integration of core functionality and even make this part of your public facing APIs.

One example of using the core Python file as a library would be to programmatically index smart contracts as they are created (in real time) or focusing on specific block ranges for maximum speed and efficiency.

The smart contract search engine gives you complete control over what is index and when. After all you and your team should not have to maintain an index of 7 million blocks if your DApp was only deployed within the last 100 blocks.

## What’s next

We believe that the smart contract search engine and [es-ss.js](https://github.com/second-state/es-ss.js) are complementary to the web3 on-chain data protocol. Together, they enable modular and powerful DApps.

If you are interested in building search engine-based DApps or rich data service for your enterprise blockchain, please get in touch!


# FairPlay: a new type of DApp

*Credits: FairPlay is developed by Second State, an open source enterprise smart contract platform, and deployed on the CyberMiles public blockchain.*

## What is FairPlay

[FairPlay](https://docs.secondstate.io/white-papers/www.fairplaydapp.com) uses smart contracts to conduct automated prize draws that are fair and transparent. It allows anyone to create and participate in product giveaways and e-commerce marketing campaigns. Since its launch, FairPlay has routinely reached a DAU (Daily Active Users) of 1000 (according to Google Analytics), with each giveaway receiving hundreds of on-chain transactions, making it one of the most popular DApps of all public blockchains.

<https://youtu.be/lQ6dKy_Q42s>

The user does not need any special software (ie a crypto wallet) to load the FairPlay web app, and view active and past giveaways. The FairPlay web application is simply a collection of HTML and JavaScript files. Any user can start a web server on her own computer and serve those files locally.

![](/files/-Ljv5koxouFRE7dPcn7I)

When the user needs to make a smart contract transaction, such as creating a new giveaway or participating in an existing giveaway, the web page directs the user to open the [CyberMiles App](https://app.cybermiles.io/) to digitally sign and complete the operation.

![](/files/-Ljv5koylzCtL-J3hrTB)

*Note: Secure random numbers are crucial for applications like FairPlay. FairPlay is deployed on the CyberMiles public blockchain to take advantage of the Lity Virtual Machine, which supports* [*secure random number generation*](https://www.litylang.org/rand/) *as a native operation. The* [*Lity Virtual Machine*](https://github.com/second-state/lityvm) *is an open source Ethereum compatible VM developed by Second State.*

From the surface, FairPlay is a DApp in front of blockchain smart contracts. However, under the hood, FairPlay has a modular architecture that is easy to develop and maintain. Key to this architecture is [a smart contract search engine](https://github.com/second-state/smart-contract-search-engine).

## A modular architecture

Most of today’s DApps rely on a single monolithic smart contract to serve as the “backend”. The smart contract manages all application users and states. Even for systems that consist of multiple contracts, there is typically a registry or manager contract that provides aggregated information about the system.

However, a large smart contract is difficult to write and maintain. It tends to be error-prone, and nearly impossible to fix when an error or issue is discovered, exacerbating the security problems that had plagued DApps today. The registry contract is also constrained by the limitations of today’s smart contract programming languages and virtual machines. It cannot support complex data query operations.

With the FairPlay DApp, we took a different approach. The DApp consists of many giveaway events, but[ each event](https://www.fairplaydapp.com/v1/play.html?contract=0x1437DDF7Eb26F93D1E34C14B64cC63Ab517701D7) is its own smart contract. When someone creates a new giveaway, she deploys a new instance of the FairPlay smart contract. When an event ends, its smart contract instance is discarded. That allows us to continuously improve the FairPlay contract to add features and fix bugs, as each future giveaway event uses a new smart contract. However, a key challenge in this approach is how the DApp organizes all those smart contracts created by different addresses at different times, and make the information inside all those contracts available in a unified UI. Enter the search engine.

## The smart contract search engine

The FairPlay DApp home screen is the search engine. It allows users to find giveaways containing specific keywords or tags, as well as the user’s previously participated giveaways. The search engine indexes information from all FairPlay contracts deployed on the blockchain.

![](/files/-Ljv5kozfFcJIGsyOHym)

The FairPlay DApp is powered by [the open source smart contract search engine](https://github.com/second-state/smart-contract-search-engine) developed by Second State. It is decentralized — anyone can create a search engine-based DApp in front of all deployed FairPlay smart contracts. Each search engine-based DApp could use different algorithms and queries to surface and promote FairPlay giveaways tailored to its users and audience.

![](/files/-Ljv5kp-jCdwwxt-NNWh)

The search engine-based DApps do not require monolithic smart contracts. Instead, each smart contract in the DApp is designed to complete a limited set of specific business transactions. All related smart contracts are aggregated in the search engine. This pattern is much closer to the design goal of smart contracts.

## Solving the on-boarding problem

A critical challenge that hinders DApp adoption today is the requirement of crypto wallets. It is nearly impossible to onboard users if they are asked to download and install an unfamiliar mobile app just to try a DApp. Furthermore, many DApps require the user to purchase cryptocurrencies, which often require the user to register for exchanges and purchase Bitcoin using bank transfers first, just to pay for a few cents of “gas fees” to complete a transaction. No wonder that there are very few DApp users.

A wallet account is needed for a DApp user to make transactions against the smart contracts. However, as we have seen from the FairPlay DApp, much of the DApp operations consist of searching, browsing, and viewing information. The user only occasionally needs to make transactions.

The FairPlay DApp allows users to access the search engine and detailed state information from each smart contract without any wallet account. When the user tries to create and send a transaction against the smart contract, the web app asks the user to open the [CyberMiles App ](https://app.cybermiles.io/)to complete the transaction. At the point, the user has the option to download the [CyberMiles ](https://app.cybermiles.io/)[App ](https://app.cybermiles.io/)if she does not already have it installed.

Of course, experienced users could always open the DApp directly from [CyberMiles App](https://app.cybermiles.io/)’s DApp browser. It provides the best user experience as the transactions are signed and sent seamlessly.

The FairPlay DApp runs on [the CyberMiles blockchain](https://app.cybermiles.io/), which supports multiple gas fee strategies. For example, the CyberMiles blockchain waives gas fees for casual users and allows contract creators to pay gas fees on behalf of end users. Together with UI optimizations in the CyberMiles App, FairPlay users typically would not see gas fee prompts when using the DApp. That dramatically increases the onboarding success rate for transactions.

## Conclusions

The FairPlay DApp is designed to improve DApp usability through innovative technologies such as [the smart contract search engine](https://github.com/second-state/smart-contract-search-engine), easy on-boarding of web applications, and [gas free transactions](https://www.litylang.org/gas/). Get in touch if you have ideas on how to further improve it!


