# Getting Started 👋🏽

🔥The DappHero documentation site🔥

{% hint style="danger" %}
DappHero has been OpenSourced. DappHero will be retired at the end of 2020. \
\
Update: The DappHero Codebase (the code that the DappHero Team created) is now in the public domain. This does not include whatever code DappHero is built upon and has it's own license (for example: React). This only applies to the code that DappHero wrote.\
\
The code will remain freely accessible here: \
<https://github.com/DappHeroCore/dapphero-core>
{% endhint %}

### Welcome! Vítejte! **Bienvenido**! Willkommen! **Καλώς ορίσατε!  أهلا وسهلا! 歡迎! ようこそ! स्वागत!**&#x20;

Now that we're introduced, let's talk about what **DappHero** is!&#x20;

DappHero is a simple low-code/no-code tool that lets you easily connect blockchain to your website, small business, portfolio, online store, blog, and much more! Our goal is to empower you to connect blockchain to *all the things,* without needing to code! Our motto is *you do you*. 🙌

#### Tell me more!

DappHero is a small plugin that runs *inside* your webpage and connects your elements to blockchain. After adding DappHero to your website, label each element you want to connect to the blockchain, then we do all the work. When your users come to your site, the blockchain is *automagically* there!&#x20;

Converting an existing website to a blockchain-powered *masterpiece* takes only a few moments, and when users visit your site, the blockchain is ready and waiting!&#x20;

Take a look at the original video that started it all!

{% embed url="<https://www.youtube.com/watch?v=d82kBDWgEKQ&t=>" %}
The original video that started it all!
{% endembed %}

### Is this for me?&#x20;

**Yes!** We are working hard to make DappHero accessible to everyone starting with you: the creator, designer, visionary, and entrepreneur! All without needing to know how to code.&#x20;

We promise, if you are already here- then DappHero is for you. We made this documentation to help you get up and running quickly.

‌ We are building DappHero for people who may have little-to-no experience coding, but DappHero is just as powerful, if not more, if you have some experience designing with HTML.

Fans of no-code will be happy to see that we work with popular [no-code tools like WebFlow](https:///@dapphero/s/dapphero-docs/~/drafts/-LzOYFj5XIyCphmkaMw4/integrations/using-weblow/starting-with-webflow). For our HTML fans, you can start designing directly in tools like Glitch, or even by hand! It only takes a couple lines of HTML to turn your page into a full-blown Ethereum powered website!&#x20;

{% hint style="info" %}
Want to brush up on your HTML skills? Check out: <https://www.learn-html.org/en/Basic_Elements>
{% endhint %}

{% hint style="warning" %}
Note for our Alpha Users!&#x20;

Currently in our Alpha version users **are required to use MetaMask,** it can be installed [here](https://metamask.io/). In future versions of DappHero we will remove this requirement and you and your users will have an entirely seamless experience when connecting to Ethereum.

Additionally because we are in Alpha there may be bugs or errors in the code. Be very careful when interacting with smart contracts on main-net or when sending ether and inform your users to double check their transactions. We make no guarantees or warrantees!&#x20;
{% endhint %}


# How does it work? 🧐

All about the magic.

All websites are constructed with items called *elements* that are described using HTML. When collected together, they form your website and include all the text, images, and designs that are displayed on a user's screen when they visit your site.&#x20;

With DappHero, you add special attributes to each element you want to use with blockchain. When  DappHero runs, it will automatically replace your existing elements with super-powered blockchain-connected elements!

Take a quick look at the HTML example below, this is the HTML required to display the name of the currently connected ethereum network. &#x20;

```markup
<div 
    data-dh-feature="network"
    data-dh-property-name="true"
>
Network name will appear here! (Mainnet, Rinkeby, Ropsten, etc)
</div>
```

It's that easy

DappHero can do a wide range of things: get your user's Ethereum address, their 3Box profile name, even connect to Smart Contracts to read data from the blockchain or send money!&#x20;

### What if I don't know HTML?

No problem! We have been working hard to make DappHero easy to use for people who love no-code tools (just like we do!).&#x20;

Our first officially supported no-code platform is [WebFlow](/integrations/using-weblow), a fantastic tool that lets you design brilliant websites AND uses DappHero without ever writing a line of code! We also have some [templates](/integrations/using-weblow/start-from-a-template) that will help you get started quickly.&#x20;

We are working hard to support DappHero in other platforms, but generally anywhere that you can add a `<script/>` tag and `data` attributes to elements on your webpage, DappHero will work. Our users have been testing out DappHero on many platforms, you can see a [list of the latest](https://forum.dapphero.io/t/supported-platforms/16) on our forum.&#x20;

### Want us to support your favorite tool? [Let us know!](https://forum.dapphero.io/t/supported-platforms/16)


# Setting Up Your Project 🏗️

The basics.

Getting started with DappHero is easy!

1. Signup, login, and create a new project.&#x20;
2. Copy your custom script tag and embed it in your website, right before the closing `</body>` tag.&#x20;
3. Tag your elements and check out the awesomeness!

### 1. Signup

### 2. Create a new project

![](/files/-MBBGIwtqLWlOXdPyo8U)

### 3. Create or Add smart contracts (optional)&#x20;

![You can edit your smart contract on the "Contracts" tab which will be visible on the menu to the left.](/files/-MBBH40IJrNbDsII6gp5)

### 4. Copy your custom script tag

![This script tag is the MAGIC of DappHero, it must be incorprated into your project to work.](/files/-MBBGdz2UQnyX0SA6iJu)

### 5. Embed the script tag in your webpage: (Raw HTML Version)&#x20;

![Example of where to place your Script Tag in Glitch](/files/-M-Vn7Q3gcOVeS3tmFQo)

### 5. Embed the script tag in your webpage: (WebFlow Version)&#x20;

![This should be similar for most sites that allow you to edit HTML](/files/-M-VnrrpHSaP2fhr-ukW)

{% hint style="warning" %}
When starting with WebFlow from scratch, you will need at least a [Lite Account](https://webflow.com/pricing#site) to add custom script tags. You can always start by cloning our Custom Templates which already have the script tag embedded.&#x20;
{% endhint %}

{% hint style="info" %}
Like Webflow? Love No-Code? Head over to [Getting Started with Webflow](/integrations/using-weblow/starting-with-webflow)
{% endhint %}

Here is a [bare-bones HTML](https://glitch.com/~dapphero-intro) version of how to add your script tag so you can understand where it needs to be. Regardless of your no-code tool or website builder, the script tag location should be more or less the same. A quick primer on [adding script tags](https://www.wikihow.com/Add-JavaScript-to-Your-Website-Using-HTML).


# Projects

About the project page

Projects are the core organizational tool in DappHero. Loosely they represent one 'website' where the DappHero engine should coordinate providing blockchain services. A single webpage can have only one DappHero project per page.&#x20;

Currently, in a project, you add smart contracts, which are then accessible on the website where DappHero is loaded.&#x20;

#### Project Script Tag

The project script tag is found at the top of the Project page. This tag is what needs to be added to your HTML to enable DappHero to run inside the browser.&#x20;

![](/files/-MBBId5LNJjginS8X6jY)

#### Name

This is the name of your project. It should be unique, without any special characters or spaces, and not include private information.

#### Description

‌The description is used internally for your own organization. It is useful to provide notes or details here that might be needed in the future.

![](/files/-MBBIhDPUypvMa389i0j)

#### Cover Image

The cover image will be automatically displayed if you use the auto-generated HTML functionality.&#x20;

![](/files/-MBBIkZG9MbjWktTQ2zC)

#### Networks

Currently, projects can support only a single Ethereum based blockchain per project. This network needs to match your smart contracts network. Select your network first, and click "Add" to add it to your project.&#x20;

After you select a network the "Add Smart contract" drop-down will be populated with your smart contracts deployed on your selected project network.  Once you have selected a network and added a smart contract you will not be able to select a new network until you have deleted all your smart contracts. &#x20;

#### Contracts

Once you've added a network, your list of smart contracts that you have previously created on the contracts page will populate based on your selected network. It is only possible to add a contract that is deployed on your selected network.

If you choose to "Create new contract" a new contract will be created and added to your project, however, you will need to edit it from the Contracts tab on the menu bar to the left.&#x20;

![](/files/-MBBJH7aDCbZDaV-F-4h)

#### **Pause/Enabled**

In some cases, you may wish to pause the DappHero engine while working on your site.&#x20;

#### Protect‌

When enabled, your project can not be changed or deleted. This is helpful to prevent accidentally changing features.&#x20;


# Smart Contracts

The Smart Contract Page

Smart contracts are the primary way of interacting with the Ethereum blockchain. DappHero does not currently create or deploy smart contracts, so you will need to have already a smart contract deployed to a network to connect.

![The new Contract interface](/files/-MBBO6dZWKoJ0UvpjHR_)

#### Name

Each smart contract needs a name inside DappHero. The name does not have to be the "official" name of the smart contract as deployed on the blockchain. DappHero will use to refer to the configuration settings regarding your contract, and it is essential to remember precisely. Pick something without spaces or special characters. This information should not be secret.&#x20;

#### Description

Here you can leave notes about the smart contract. It is useful if you need to refer to your project in the future and want to organize some information regarding your settings.&#x20;

#### Network&#x20;

The Network settings are where you *describe* your contract. Here you will need to provide three things:

* Network - this can be Mainnet Ethereum or any of the public testnets. Private networks are currently not supported.
* Deployed Address - this is the actual *ethereum address* at which the contract you wish to connect is deployed.
* Contract ABI - this is a JSON object which describes the smart contract and smart contract methods you are trying to connect in DappHero.&#x20;

#### Load ABI from Etherscan&#x20;

For smart contracts that have been **verified** on the block explorer [Etherscan.io](https://www.etherscan.io/) it is now possible to automatically load their ABI. This feature is supported by Mainnet, Rinkeby, Ropsten, Kovan, and Goerli. It will not work on other networks.&#x20;

To have your contract verified, you can [use this tool](https://etherscan.io/verifyContract) a helpful article to [learn more](https://medium.com/coinmonks/how-to-verify-and-publish-on-etherscan-52cf25312945) about verifying smart contracts.&#x20;

#### Protect

When green and locked, your contract settings can not be accidentally changed.&#x20;


# An Intro to Features 🎁

Get started with the basic building blocks of DappHero

There's a million things you can do with DappHero, so we've grouped them together into categories that describe what they do or where they connect.  Our feature list is constantly growing, so check back often to see whats new.&#x20;

### Features

#### [Network](/features/network) &#x20;

The Network feature gives you access to information about the current blockchain network your user is connected to.

#### [User](/features/user)

The User feature gives you access to information about the currently connected user.&#x20;

#### [3Box](/features/3box)

If your user has a [3Box](http://www.3box.io) profile, you will be able to access (and in the future edit) their profile information.&#x20;

#### [Smart Contracts](/features/3box)

Connect to any smart contract using the ethereum protocol&#x20;

[Collectibles](/features/what-are-nfts)

Easily create galleries for Crypto Collectibles

####


# Network ⛓️

Connecting to the Network and sending ETH

The Network feature allows you to connect and get information from the current Ethereum network. You can read information from the currently connected network, allow a user to enable the connection to the current network, and give the User the ability to send ETH.&#x20;

{% hint style="info" %}
Want to get started quick with no-code? Check out our no-code template in Webflow!
{% endhint %}

{% embed url="<https://webflow.com/website/DappHero-network>" %}
Click "clone" to make it yours!
{% endembed %}

{% hint style="info" %}
Prefer to dig in and get your hands dirty with HTML? Remix our Demo on Glitch!
{% endhint %}

{% embed url="<https://glitch.com/~dapphero-network>" %}
Click "remix" to start your own project!
{% endembed %}

### Network Enable

{% hint style="info" %}
It is **required** that you implement a **Network Enable** element in your webpage. This should ideally be a **`button`**&#x74;ype element that a user clicks to connect to ethereum. Without it, DappHero won't load!
{% endhint %}

| Tag                       | Property  | Required? | Output |
| ------------------------- | --------- | --------- | ------ |
| `data-dh-feature`         | "network" | Yes       | none   |
| `data-dh-property-enable` | "true"    | Yes       | none   |

We recommend that you feature this button prominently, where users will see it immediately. As a matter of privacy and security, DappHero will only be able to process transactions and access your users information once the connection has been approved.&#x20;

An example of what an Enable button might look like. When a user clicks on it, they will be requested by MetaMask to give their permission to be connected to your website.&#x20;

```markup
<button
    data-dh-feature="network"
    data-dh-property-enable="true">
    *Button Text*
</button>
```

### Network Data

| Tag                         | Property  | Required? | Output           |
| --------------------------- | --------- | --------- | ---------------- |
| **To Display Data**         |           |           |                  |
| `data-dh-feature`           | "network" | Yes       | none             |
| `data-dh-property-id`       | "true"    | optional  | Network Id       |
| `data-dh-property-name`     | "true"    | optional  | Network Name     |
| `data-dh-property-provider` | "true"    | optional  | Network Provider |

There are many different kinds of Ethereum networks, each have their own ID. To get the value of the current network ID, use:&#x20;

```markup
<div
    data-dh-feature="network"
    data-dh-property-id="true">
    *placeholder text*
</div>
```

When your webpage loads, the word "placeholder text" will be replaced with the value of the currently connected Network ID.&#x20;

#### Network Name

Along with a Network ID, most public Ethereum networks also have a network name, which can be more intuitive to users than Network ID. Note, if you are connected to a private network or special purpose network, your network may not have a known network name.&#x20;

```markup
<div
    data-dh-feature="network"
    data-dh-property-name="true">
    *placeholder text*
</div>
```

#### Network Provider

Currently, users will be bringing their own connection to the Ethereum Blockchain in the form of an in browser wallet such as [MetaMask](http://www.metamask.io). To get the name of the current provider, use:&#x20;

```markup
<div
    data-dh-feature="network"
    data-dh-property-provider="true">
    *placeholder text*
</div>
```

{% hint style="info" %}
Currently DappHero supports only MetaMask for users, but will be expanding the number of providers it supports in the near future.&#x20;
{% endhint %}

## Transferring ETH

The DappHero Network feature also allows you to let a user transfer ETH. To do this you would add input `elements` to your webpage that you tag for `amount` and recipient `address` respectively.&#x20;

{% hint style="info" %}
Current there can be only one instance of ETH transfer per page. This will be changed in a future release of DappHero to allow for multiple transfers per page.
{% endhint %}

| Tag                              | Property         | Required? | Output         |
| -------------------------------- | ---------------- | --------- | -------------- |
| **FOR SENDING ETH**              |                  |           |                |
| `data-dh-feature`                | "network"        | Yes       | none           |
| `data-dh-property-transfer`      | "input"          | Yes       | none           |
| **Input Elements**               |                  |           |                |
| `data-dh-property-input-name`    | "amount"         | Yes       | none           |
| `data-dh-property-input-name`    | "address"        | Yes       | none           |
| **Invoke Button**                |                  |           |                |
| `data-dh-property-transfer`      | "invoke"         | Yes       | none           |
| **Units Modifier**               |                  |           |                |
| `data-dh-modifier-display-units` | "ether" \| "wei" | optional  | Input Modifier |

```markup
<!-- An input field for the amount of ETH to send, with the units set to ETH -->
<input 
            data-dh-feature="network"
            data-dh-property-transfer="input" 
            data-dh-property-input-name="amount" 
            data-dh-modifier-display-units="ether">
</input>
      
<!-- An input field for the address to receive the ETH -->
<input
            data-dh-feature="network" 
            data-dh-property-transfer="input"
            data-dh-property-input-name="address">
</input>
    
<!-- A button to invoke the action of sending ETH and request user signature -->
<button 
            data-dh-feature="network" 
            data-dh-property-transfer="invoke">
            Click to transfer!
</button>
```

To require users to send a specific amount of ETH or to a predefined address, you would set the value of the inputs manually and set their style to `display: none` to effectively hide them from the user.&#x20;

```markup
<!-- An input field for the amount of ETH to send, with the units set to ETH -->
<input 
            data-dh-feature="network"
            data-dh-property-transfer="input" 
            data-dh-property-input-name="amount" 
            data-dh-modifier-display-units="ether"
            style="display:none;"
            value="<<predefined amount of ETH>>">
</input>
      
<!-- An input field for the address to receive the ETH -->
<input
            data-dh-feature="network" 
            data-dh-property-transfer="input"
            data-dh-property-input-name="address"
            style="display:none;"
            value="<<predefined address>>">
</input>
    
<!-- A button to invoke the action of sending ETH and request user signature -->
<button 
            data-dh-feature="network" 
            data-dh-property-transfer="invoke">
            Click to transfer!
</button>
```


# User 🤖

Accessing the current users information

The User feature allows you to access information about the currently connected user.&#x20;

{% hint style="info" %}
To access the current user, you must implement a [Network Enable](/features/network#network-enable) element first.&#x20;
{% endhint %}

### Static User Features

Most user features are `static` features, meaning they are loaded as soon as the user clicks the `network enable` element.  Additionally, some User Features have formatting and display options that allow you to customize how the returned data is displayed to the user.&#x20;

### Current User Address Feature

&#x20;Display the current user's full Ethereum address:

```markup
<div
   data-dh-feature="user" 
   data-dh-property-address="true">
   *User Address*
</div>

```

| Tag                        | Accepted Values | Required |
| -------------------------- | --------------- | -------- |
| `data-dh-feature`          | `user`          | Yes      |
| `data-dh-property-address` | `true` `false`  | Yes      |
| `data-dh-modifier-display` | `short`         | optional |

### Displaying Shortened Addresses&#x20;

To show a truncated address, you can also add `data-dh-modifier-display="short"` to the element like the example below:

```markup
<h2
   data-dh-feature="user" 
   data-dh-property-address="true"
   data-dh-modifier-display="short">
   *User Address Truncated*
</h2>
```

This will display the address in the following format `0x5...EaEA`

###

### User Balance

Display the current user's balance:

```markup
<div
    data-dh-feature="user"
    data-dh-property-balance>
    *User Balance*
</div>
```

**Example Return Value:** `7511222555444777333`

### Define the units and precision of the balance&#x20;

To show the user's balance in ether add `data-dh-modifier-display-units="ether"`

To define the number of decimal places add `data-dh-modifier-units=3`

```markup
<div
          data-dh-feature="user"
          data-dh-property-balance
          data-dh-modifier-units="ether" 
          data-dh-modifier-decimals="3">
          *User Balance*
</div>
```

| Tag                         | Accepted Values | Required |
| --------------------------- | --------------- | -------- |
| `data-dh-feature`           | `user`          | Yes      |
| `data-dh-property-balance`  | none            | Yes      |
| `data-dh-modifier-units`    | `ether` `wei`   | optional |
| `data-dh-modifier-decimals` | `integer`       | optional |


# 3box 👯‍♂️

Learn how to access decentralized 3Box user profiles

[3box](https://3box.io/) offers a decentralized storage layer for applications. Currently if a user has created a [3box profile](https://3box.io/hub) with the address they use when visiting your site, you will be able to use DappHero to access their profile information.&#x20;

{% embed url="<https://webflow.com/website/DappHero-3box-profile>" %}
Click "clone" to make it yours!
{% endembed %}

You may want to consider adding some placeholder or default text, as some users will not have set up their 3box profiles. In addition, some users will only have uploaded parts of their profile leaving certain properties blank.

### 3Box Feature Reference

| Tag                            | Property   | Required | Displays          |
| ------------------------------ | ---------- | -------- | ----------------- |
| `data-dh-feature`              | "threebox" | Yes      | nothing           |
| `data-dh-property-name`        | "true"     | optional | Users Name        |
| `data-dh-property-website`     | "true"     | optional | Users Website     |
| `data-dh-property-location`    | "true"     | optional | Users Location    |
| `data-dh-property-emoji`       | "true"     | optional | Users Emoji       |
| `data-dh-property-job`         | "true"     | optional | Users Job         |
| `data-dh-property-description` | "true"     | optional | Users Description |
| **Three Box Image**            |            |          |                   |
| `data-dh-property-image`       | "true"     | optional | Users Image       |

To access any of the above properties, with the exception of the image property, follow this template, replacing the property with your desired property value.&#x20;

### Display the current user's 3Box Name

```markup
<div
    data-dh-feature="threebox"
    data-dh-property-name="true"
>
    Name will be displayed here
</div>
```

### Display the current user's 3Box Profile Image

To access a user's profile image, it is important to attach the feature to an image element.&#x20;

```markup
<img
    src="placeholder image URL"
    data-dh-feature="threebox"
    data-dh-property-image="true"
>
```


# Smart Contracts 👩🏾‍🔬

Connecting to Smart Contracts

{% hint style="danger" %}
DappHero is currently in **BETA** meaning things might not always work. Please be careful about using it on Mainnet and inform your users to also double check their transactions before confirming.&#x20;
{% endhint %}

Traditionally to connect to smart contracts in your website you needed to import javascript libraries into the browser, create a large amount of custom javascript code, and be careful to check for a wide range of conditions. DappHero makes connecting to smart contracts painless and simplifies this task enormously so that you can focus on **what** you are building, rather than **how** to build it.

A DappHero project can be used to connect to any number of smart contracts, there's no limit!

To get started with Smart Contracts, let's quickly review some basics before diving into more detail.&#x20;

### How it works

Interacting with custom smart contracts generally takes five steps:

1. [Add a Smart Contract to your project on dapphero.io](/features/using-smart-contracts/adding-smart-contracts)&#x20;
2. [Create a Method Instance element in your website](/features/using-smart-contracts/create-a-method-instance)
3. [Create your input elements](/features/using-smart-contracts/inputs)
4. [Decide how your method is invoked](/features/using-smart-contracts/invoke)
5. [Display the outputs](/features/using-smart-contracts/outputs)

{% hint style="info" %}
Read the following paragraphs about Unique ID's to understand how functionality is grouped in DappHero.&#x20;
{% endhint %}

### Methods

Smart contracts are made up of **methods,** (think of **functions** if you have a programing background) which allow you to interact with the state of the blockchain. You can retrieve information or send information to the blockchain using methods.&#x20;

Interacting with smart contracts in DappHero is organized around interacting with *specific* smart contract method&#x73;**.** Each method does something specific, and you can connect to as few or as many methods of a smart contract as you like on your website. In this way, DappHero represents each method for each contract as a  **method instance.** In practice this makes it very easy to work with smart contracts, as you don't need to worry about the entire smart contract, only the methods you wish to use.&#x20;

Learn more about [Creating a Method Instance](/features/using-smart-contracts/create-a-method-instance).

### Unique ID

`CustomContracts` methods are different than other DappHero features as their functionality requires multiple components. Unlike `Network` or `User` features which require only one tag to identify an element and replace its data, `CustomContracts` require a variable number of elements that can potentially be located anywhere on the screen.&#x20;

To account for the fact that you can put your elements for a `CustomContract` anywhere on the page, we have introduced a special tag,  `data-dh-property-method-id`, which has a custom unique value that you determine, and which should be used for all elements related to the same functionality.&#x20;

```markup
// This tag gives information about the method instance
<div ...
data-dh-property-method-id="myUniqueTag"
....
/>

// This element is where you define the input
<input ...
data-dh-property-method-id="myUniqueTag"
...
/>

// This button will invoke the method
<button ...
data-dh-property-method-id="myUniqueTag"
...
/>

// This element will display the output
<div ...
data-dh-property-method-id="myUniqueTag"
...
/>
```

In the above example, all the elements for a Custom Contract integration are marked with the same unique tag id, `myUniqueTag` in this way, the DappHero Engine knows all these different elements, regardless of where they are on the page, belong together in the same functionality.&#x20;


# Adding Smart Contracts 🏗️

How to Add Smart Contracts to your project

### Add a Smart Contract

Once you've created a project in your DappHero admin, you can add a smart contract by clicking on the "Contract" button on the lefthand menu.&#x20;

### Adding your Contract

To add a new contract, you will need to know a few things first:&#x20;

{% hint style="info" %}
Learn more about getting your [Contract Detail](/features/using-smart-contracts/adding-smart-contracts/contract-details)
{% endhint %}

1. **Address** - (The location on the blockchain where the contract lives)
2. **Network** - (The specific blockchain network where the contract live)
3. **ABI** - (This is a special code object, called JSON, which tells DappHero how the contract works)

The Contract Name is also required, but this value can be anything you like.&#x20;

![](/files/-MBBPSgJLKwvPgEY9eTO)


# Contract Details

Whats an ABI? Where does a Contract live?

### Getting your contract Details

To connect to smart contract, you need to have some information available: the address, network and abi.&#x20;

{% hint style="warning" %}
Note: Currently DappHero works with public networks and test networks. We are working on adding local development network support, coming soon!
{% endhint %}

### Address

Every contract deployed on the blockchain has it's own unique address. This address is what ensures when we connect to a contract, we are connecting to only the contract we want. It's very important to have the right address!

If you are creating your own smart contract, then you will receive this address at the end of your deployment process.&#x20;

If you are connecting to an existing smart contract, you will need to obtain this address. A popular tool to explore the Ethereum blockchain is [Etherscan](https://etherscan.io/) and here you can find lots of information, including contract information. When you find a contract you want to connect to, you can get it's address here:&#x20;

![A contract address will say "Contract" at the top and then show the address](/files/-M-uKqBMIPtgw4NopmxR)

### Network

Contracts are deployed not just to unique addresses, but also to unique *networks*. When choosing a contract you will also have to specify the network where it lives. While there are a wide range of different networks where your contract can be deployed, DappHero currently supports a limited subset of popular Test networks, and Ethereum Mainnet.&#x20;

When using Etherscan you can see the network you are connect to here:&#x20;

![](/files/-M-uLU5QbmYRE5hE_qI4)

If there is no mention of a "testnet", this means you are looking at the Ethereum Mainnet.

![On the Ethereum Mainnet you see only the price of ETH, no mention of a testnet.](/files/-M-uLfPIN-sh64tV4eKJ)

### ABI

Finally, you will need your contracts ABI. While all three pieces of information are required : Address, Network and ABI, the **ABI** is arguably the most important, because it tells DappHero how the contract works and what **methods** are available to use.&#x20;

{% hint style="warning" %}
It is very important you have the CORRECT ABI for your contract. DappHero can not check your ABI to be sure it's correct as the engine has no way of knowing what should be expected. For this reason it is very important to be sure you enter the correct ABI for your contract.
{% endhint %}

How ABI's work is an advanced topic that we won't cover here, but if you are creating your smart contract yourself then you will find the ABI generated after compiling your smart contract code. Be sure to copy only the ABI object from your generated contract artifacts, not the entire contract artifact which contains far more information that DappHero needs.&#x20;

#### Getting the ABI from EtherScan

Alternatively, you can get the ABI for popular, *verified,* smart contracts directly from EtherScan.&#x20;

When you visit a contract on Etherscan, you should click the "contract" button. If it is verified, and thus has a publicly available ABI, it should have a small green checkmark. If there is no green check mark, you will not be able to get the ABI from the contract on Etherscan.&#x20;

![](/files/-M-uN5ttbRUgoxxSzlAe)

Once you click on "contract" scroll down to "ABI", there is a small button which will allow you to copy only the ABI, which is exactly what DappHero needs. Past that into your "New Contract" in DappHero

![](/files/-M-uNjZsUL1PhMvz34u5)


# Create a Method Instance

How to create a Method Instance for your customContract

DappHero organizes functionality for a contract method around a **method instance**. To create a method instance all you need to do is add special data-property tags to your elements (an easy-to-do task in Webflow or Glitch) and DappHero will do the rest.&#x20;

### Create an instance of your method:&#x20;

First you need to create an instance of your method that you would like to interact with. You will then be able to add elements on your webpage that interact with this method, and by giving them each the same unique id, they will all be related, regardless of their placement on your webpage.&#x20;

What does this look like?&#x20;

```markup
<div
    data-dh-feature="customContract"
    data-dh-property-contract-name="dappherotest"
    data-dh-property-method-name="hello"
    data-dh-property-method-id="000"
    data-dh-property-eth-value="1" 
>
optional text
</div>
```

&#x20;`data-dh-feature` **(required)** This is how we identify to the DappHero engine that you intend to connect to a smart contract.&#x20;

`data-dh-property-contract-name` **(required)** This is the name of your smart contract, it needs to match the name you have listed in your DappHero Admin project exactly.&#x20;

`data-dh-property-method-name` **(required)** This is the actual method you are trying to invoke on your smart contract. For example if you have a method `getBalance` on your smart contract, you would add the method name here.&#x20;

`data-dh-property-method-id` **(required)** This is custom id that you give your webpage element. All of the elements which are related to this `customContract` method will need to have the **same** id. This way you can place the elements anywhere on the page and DappHero will know they belong together.

`data-dh-property-eth-value` **(optional)** For contract methods that accept ETH (aka: payable functions) you can hard-code an amount of ETH to be sent to a contract method whenever a user makes a transaction. This is useful when you want users to send a fixed amount of ETH to a contract method.  If you want to let your users define the amount of ETH themselves, you can use an Input field instead.

### Custom Contract Reference:&#x20;

| Tag                              | Property                    | Required? |
| -------------------------------- | --------------------------- | --------- |
| `data-dh-feature`                | customContract              | Yes       |
| `data-dh-property-contract-name` | `<<your-contract-name>>`    | Yes       |
| `data-dh-property-method-name`   | `<<yourMethodName>>`        | Yes       |
| `data-dh-property-method-id`     | `<<aUniqueValue>>`          | Yes       |
| `data-dh-property-eth-value`     | `<<amount of ETH to send>>` | optional  |


# Inputs

How to get information from the user, to send to your contract method

For contract methods that require user input we can use input fields on our website to collect this input from users.&#x20;

An example Input Tag would look like:&#x20;

```markup
<input
    data-dh-property-method-id="000"
    data-dh-property-input-name="simpleMessage"
/>
```

`data-dh-property-method-id` This is the `id` that was set when we created our Method Instance. This needs to match exactly so that the DappHero engine knows that this input is intended for that method instance.&#x20;

`data-dh-property-input-name` This is the name of the argument for the method that you are trying to interact with. This must match the name defined in the Smart Contract ABI &#x20;

So for example if you had a function written in solidity like this:&#x20;

```javascript
function foo(uint bar) public {
    ...
}
```

The value of `data-dh-property-input-name` would be `bar`. This is how we link the input field on our website with the input argument required by the smart contract. **It needs to match for the DappHero engine to know where to put the input data!**

{% hint style="success" %}
A method can take any number of input arguments, but you are required to provide **all** the input arguments for a method in order to make a successful method call.&#x20;
{% endhint %}

### Invisible Inputs

For some method instances you might want to hard-code the value of inputs and not give users the option to change the input value. To do this, you can use standard HTML to set the value of an input, and then hide it from the webpage so it is unseen. This is very useful for methods which auto-invoke on page load, but require inputs.

```markup
<input
    data-dh-property-method-id="000"
    data-dh-property-input-name="simpleMessage"
    value="some input value"
    style="display:none;"
/>
```

### AutoClear Inputs

DappHero will automatically clear the input values of form fields, regardless of the visibility. This is intended to give users a nice experience of having a form 'reset' after clicking submit.&#x20;

Normal HTML form behavior is that when a user inputs some information into a form field, then clicks "submit" the default behavior is to clear the form field to prepare it to accept new data.&#x20;

For invisible inputs however, with values that are intended to stay the same, reseting the input is most likely not the desired functionality. To prevent this behavior it is necessary to add a `auto-clear` tag to the input to explicitly tell the DappHero engine if you want the form value to be cleared after invocation.&#x20;

For various reasons this may or may not be the desired behavior in your application. This can specifically be a problem for **invisible inputs** which will, by default, automatically be cleared after your user clicks 'invoke'.&#x20;

```markup
<input
    data-dh-property-method-id="000"
    data-dh-property-input-name="simpleMessage"
    value="some input value"
    style="display:none;"
    data-dh-property-auto-clear="false"
/>
```

To avoid this problem, you can add a special tag: `data-dh-property-auto-clear="false"` to tell DappHero to not clear your input after a user clicks 'invoke'.&#x20;

To learn more about the `auto-clear` flag, read [Advanced: Automatically clearing Inputs](/features/using-smart-contracts/advanced-automatically-clearing-inputs).

```markup
<input 
    data-dh-property-method-id="000"
    data-dh-property-input-name="simpleMessage"
    data=dh-property-auto-clear="false"
    value="some default value I don't want deleted"
    style="display:none;"
/>
```

### Units

### Single Anonymous Inputs

When working with Ethereum Smart Contracts, there are some automatically generated public methods created to access lists of information, these are *arrays* and *mappings.* They can be accessed the same as regular public variables, with a minor change in syntax.

```javascript
//Example Solidity Psuedo Code

contract BallotTest {
   
    string[] public proposalNameArray;
    //or
    mapping(uint => string) public proposalNameMapping;

...other stuff...
}
```

To access a value inside a public array or mapping it is necessary to provide an index or key to request a specific piece of data back from the blockchain. In the above example it would be necessary to first provide an integer to get back a single `proposalNameArray` or `proposalNameMapping`. &#x20;

Because these methods are automatically generated by the Solidity compiler, they are given *anonymous* input names. This means that they have no corresponding `data-dh-property-input-name` to access their values.&#x20;

In order to get a value out of an anonymous input, (arrays or mappings) you will need to use the special constant: **$true**.

```markup
<input
    data-dh-property-method-id="000"
    data-dh-property-input-name="$true"
/>
```

This will properly inform the DappHero engine that this is a generated anonymous public method and allow you to pass in data from the user to request specific pieces of data inside of public arrays and mappings.&#x20;

{% hint style="warning" %}
The tag format: `data-dh-property-input-name="$true"` is scheduled to be deprecated at some point in the future. For now, continue to use it, but check back regularly to learn when we will plan the change.&#x20;
{% endhint %}

### Multiple Anonymous Inputs

There are some situations where you may have more than one anonymous input. A good example of this is the popular [**Wrapped-Eth**](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code) contract (which holds over $500 million dollars in ether!).&#x20;

In this contract we have these public method which is a `mapping` of a `mapping`.

```markup
    mapping (address => mapping (address => uint))  public  allowance;
```

The resulting contract ABI looks like this:

`{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}]`

If you notice there are **two** inputs with a `name` value of empty string: `''`. To access these we have recently introduced **array indices** notation. To access the the first argument (The outer address mapping) you would use the following tag:&#x20;

```markup
<input
    data-dh-property-method-id="000"
    data-dh-property-input-name="[0]" <!-- Notice the array notation 
/>
```

To access the second input you would use:&#x20;

```markup
<input
    data-dh-property-method-id="000"
    data-dh-property-input-name="[1]"
/>
```

Remember in programming with arrays we alway start counting from zero!

### Units

The input units for a contract method are defined on the contract ABI and can not be changed. In some cases however the units required by a smart contract can be confusing to a user and thus need to be converted.&#x20;

DappHero currently supports converting between `bytes32` and `ascii` as well as `ether` and `wei`.

```markup
<input
    data-dh-property-method-id="000"
    data-dh-property-input-name="simpleMessage"
    data-dh-modifier-display-units="ascii"
    data-dh-modifier-contract-units="bytes32"
/>
```

In this example, a user can enter text in `ascii` (ASCII is the standard way of entering normal text) but DappHero will convert it to `bytes32` before sending it to the contract.

### Inputs Reference

| Tag                               | Property                        | Required? |
| --------------------------------- | ------------------------------- | --------- |
| `data-dh-property-method-id`      | `<<aUniqueString>>`             | Yes       |
| `data-dh-property-input-name`     | `<<input name>> \|\| $true`     | Yes       |
| `data-dh-property-auto-clear`     | `false \|\| true`               | optional  |
| `data-dh-modifier-display-units`  | `ether` `wei` `bytes32` `ascii` | Optional  |
| `data-dh-modifier-contract-units` | `ether` `wei` `bytes32` `ascii` | Optional  |


# Invoke

Activating Methods on page load or button click

Once you've created your Smart Contract method instance, optionally gathered your users inputs (not all methods require inputs!) now we need to *invoke* our method- **Activate it!**

We can invoke a method in one of two ways: on page load, when your website first loads for the user, or by clicking a button.

#### Invoke on Page Load

To invoke on page load, all you need to do is add `data-dh-property-auto-invoke="true"` to the **method instance** element we created earlier (thats the one that has the `data-dh-property-contract-name` and `data-dh-property-method-name` attributes.

```markup
<div
    data-dh-feature="customContract"
    data-dh-property-contract-name="dappherotest"
    data-dh-property-method-name="hello"
    data-dh-property-method-id="000"
    data-dh-property-auto-invoke="true"
>
```

This will now auto-invoke a method on page load. This is useful for when you want to pre-populate some data on your website from a smart contract without needing to user to click on a button first.&#x20;

For auto-invoked methods which require inputs, use [Invisible Inputs](/features/using-smart-contracts/inputs#invisible-inputs).

{% hint style="info" %}
Invoke on page Load will only work for View Methods. Transactions can not be invoked on page.
{% endhint %}

#### Invoke on Button Click

If you want your user to invoke the method, create a button instance and add the tag `data-dh-property-invoke` this will tell the DappHero engine to invoke the smart contract method when the button is clicked.

```markup
<button 
    data-dh-property-method-id="000" 
    data-dh-property-invoke="true"
>
Click Here to Call Your Smart Contract!
</button>
```

### Invoke Reference

| Tag                            | Value                      | Required |
| ------------------------------ | -------------------------- | -------- |
| `data-dh-property-invoke`      | true                       | yes      |
| `data-dh-property-auto-invoke` | true                       | optional |
| `data-dh-property-method-id`   | `<<yourUniqueIdentifier>>` | yes      |


# Outputs

Getting data back from the blockchain

There are essentially two kinds of public Ethereum smart contract methods which are accessible to users outside of the blockchain: view methods, and transactions (optionally payable transactions).&#x20;

#### **View Methods**

View methods allow us to read data from the blockchain without needing to make a transaction or pay ETH. They are free to invoke and are useful for getting information about the current state of a smart contract.&#x20;

To receive and display data from View Methods we need only to add two attributes to a div (or other element). When DappHero receives this information from the smart contract (either when the page loads because of an `auto-invoke` or when a user clicks an `invoke` button) it will replace the content inside of the tagged element with the returned data.&#x20;

#### Outputs&#x20;

To receive the output of a view method, use the following code. This will return all the outputs returned by a view method as is useful for methods that return a single piece of data.&#x20;

For methods that return multiple pieces of data, you might want to consider [Named Outputs](/features/using-smart-contracts/outputs#named-outputs) as otherwise, you will not have control over each piece of returned data.&#x20;

```markup
<div 
    data-dh-property-method-id="000" 
    data-dh-property-outputs="true">
*-Placeholder for returned data-*
</div>
```

#### Named Outputs

Some view methods can return multiple pieces of information. To access those individually, it is necessary to refer to each output by their output variable name as specified on the contract ABI.&#x20;

```markup
<div 
    data-dh-property-method-id="000"
    data-dh-property-output-name="theNameOfTheOutput">
*-Placeholder for returned data-*
</div>
```

{% hint style="warning" %}
Note, you can not mix `data-dh-property-outputs="true"` with `data-dh-property-output-name="theNameOfTheOutput"` in the same element. You must pick one or the other.
{% endhint %}

{% hint style="warning" %}
**Experimental**:&#x20;

Sometimes view methods return multiple values without giving them output names. To access them, you can reference them by their position in the output data array.

Example: `data-dh-property-output-name="0"`&#x20;

Support will be expanded for accessing outputs (and inputs) by array position in a coming release.
{% endhint %}

### Units

DappHero also allows for conversation of units for output data. The `contract-units` always refers to the units that the smart contract is returning, while the `display-units` is the format that you wish you display the data to your users.&#x20;

```markup
<div 
    data-dh-property-method-id="000" 
    data-dh-property-outputs="true"
    data-dh-modifier-contract-units="bytes32" 
    data-dh-modifier-display-units="ascii" >
*-Placeholder for returned data-*
</div>
```

### Decimals

Currently DappHero allows for conversion of numerical unites between `wei` and `ether`. You can change the decimal places of precision using the `data-dh-modifier-decimals` tag. Support for custom units is coming soon.&#x20;

### View Method Reference

| Tag                               | Value                            | Required |
| --------------------------------- | -------------------------------- | -------- |
| `data-dh-property-method-id`      | "<\<id>>"                        | Required |
| `data-dh-property-outputs`        | none                             | Required |
| `data-dh-property-output-name`    | `<<outputName>>`                 |          |
| `data-dh-modifier-display-units`  | `wei` `ether` `bytes32` `string` | Optional |
| `data-dh-modifier-contract-units` | `wei` `ether` `bytes32` `string` | Optional |
| `data-dh-modifier-decimal-units`  | Integer                          | Optional |

## **Transactions**

Transactions are different than view methods and we access them in a similar way to view methods, but instead of trying to read some information from a smart contract, we are trying to *change* some information on the blockchain.&#x20;

Unlike view methods, transactions only ever return a [transaction receipt](https://medium.com/@kctheservant/transactions-in-ethereum-e85a73068f74). This means we can not get data back from the blockchain, even if the ABI seems to indicate there is a return value. For transactions, return values are accessible only to other smart contracts inside the blockchain.

To learn how to send ETH when making a transaction read our advanced topics, [Sending ETH to a Contract](/features/using-smart-contracts/sending-eth-to-a-contract).

#### Return Value

Sending transactions works exactly the same as when interacting with View Methods. The only difference is that the returned value from the method transaction will be the hash of the transaction. To access this value, you can use&#x20;

```markup
<div 
    data-dh-property-method-id="000" 
    data-dh-property-outputs="true">
*-Returned Transaction Hash-*
</div>
```

### Transaction Reference

| Tag                          | Value    | Required |
| ---------------------------- | -------- | -------- |
| `data-dh-property-method-id` | `<<id>>` | Required |
| `data-dh-property-outputs`   | True     | Required |

For transactions, we will only ever receive the *transaction receipt* which is a long random number and letter hash string. Some users however may like to be able to see their transaction receipt, as users can copy and past the receipt into tools like [Etherscan](http://etherscan.com/) to check and follow the status fo their transactions.&#x20;

#### Notifications

Additionally as a convenience, DappHero injects a notification toaster system in your website that gives convenient information to the users on the status of their transaction. As soon as a transaction is started, this pop-up will appear and will inform users on the success or failure of a transaction.&#x20;

![An example of the transaction status popup.](/files/-M-AjvudItwvca06BwEs)


# Events

Contrat Events

Contract events are not currently supported by DappHero. There is a good reason for this (scalability) but we are working hard to consider a solution for this.&#x20;


# Advanced: Automatically clearing Inputs

How to enable or disable automatically clearing a form input field

When using a HTML Input form field as an input to a smart contract method, DappHero will automatically clear the value of the input form field after each invocation (IE: each time someone click the submit button). This behavior was designed to give users a familiar experience when interacting with a DH powered and to make user their inputs are cleared.&#x20;

However there are some situation where clearing the input field might not be desired, so we have included the ability to override this functionality.&#x20;

### Overriding the default functionality

To override the default functionality, it is necessary to add `auto-clear` flag with a value, `true` or `false`. This should be added any input for which you wish to change the default functionality, or perhaps give the ability to change the functionality while loaded on the page.&#x20;

```markup
<input
    data-dh-property-method-id="000"
    data-dh-property-input-name="simpleMessage"
    data-dh-property-auto-clear="false"
/>
```

| Tag        | Property   | Required? |
| ---------- | ---------- | --------- |
| auto-clear | true/false | optional  |

If there is no `auto-clear` flag, DappHero will clear the input value after the first invocation.&#x20;

Learn more about using `auto-clear` with [invisible inputs](/features/using-smart-contracts/inputs#invisible-inputs).


# Advanced: Getting the Current User's Address Dynamically

Getting the value of the current user as an input

## $CURRENT\_USER

A common use case for many smart contracts is to return information from a public view method that is associated with the current user. An example would be retrieving the balance of the current users ERC20 token amount. While you could create a normal input field and let a user populate it with their address, for many use cases this would be an inconvenient solution where you might want to show some smart contract state related to the current user on page load.&#x20;

To address this common use case,  we have created the reserved keyword **`$CURRENT_USER`** that can be used inside of inputs for smart contracts.&#x20;

```markup
<input
      data-dh-property-method-id="000"
      data-dh-property-input-name="<<input method argument name>>"
      value="$CURRENT_USER"
/>
```

In this example, the input field's value would be automatically populated with the value of the current users Ethereum address.&#x20;

The `$CURRENT_USER` keyword is particularly useful when the input is hidden. To do this, set the display value of the input to none.&#x20;

```markup
<input
      data-dh-property-method-id="000"
      data-dh-property-input-name="<<input method argument name>>"
      style="display:none;"
      value="$CURRENT_USER"
/>
```


# Advanced: Sending ETH to a contract method

How to optionally send ETH to a contract method.

Sometimes when you are interacting with a contract method, you want to be able to specify that a user can optionally send ETH. To do this with DappHero we have the option to either hardcode the ETH amount (for example if a contract requires exactly 1 ETH to do some task) or allow users to optionally input the amount themselves.&#x20;

### Hardcoded

{% hint style="danger" %}
This example is in the process of being deprecated. Please try to use&#x20;
{% endhint %}

In the case that you wish to hard-code the amount of ETH that should be sent upon interacting with a contract method, you should define the amount in the method instance object with a `data-dh-property-eth-value` tag.&#x20;

| Tag                          | Value               | Units |
| ---------------------------- | ------------------- | ----- |
| `data-dh-property-eth-value` | `<<amountOfEther>>` | Ether |

The value for this tag is the amount of ETH to send&#x20;

Here is an example of how it could be used in a Method Instance:&#x20;

```markup
<div
    data-dh-feature="customContract"
    data-dh-property-contract-name="MyStore"
    data-dh-property-method-name="buyItem"
    data-dh-property-method-id="000"
    data-dh-property-eth-value="1.5"
>
```

In this example, when this method is invoked, 1.5 ETH will be added to the transaction and if the user approves the transaction, this ETH will be sent to the smart contract.&#x20;

### Input Fields

In the case that you want to allow your users to specify the amount of ETH they would like to send to a smart contract method, you can attach a `data-dh-property-input-name="EthValue"` tag directly to an input element.

{% hint style="info" %}
Input fields can also be used for sending Hard coded amounts of ETH. Rather than the deprecated method above use the following tags. To hide the input from the user, use `style="display: none;"` as an additional tag.&#x20;
{% endhint %}

| Tag                           | Value      |
| ----------------------------- | ---------- |
| `data-dh-property-input-name` | `EthValue` |

An example of this for an input element would look like this:&#x20;

```markup
<input
    data-dh-property-method-id="000"
    data-dh-property-input-name="EthValue"
/>
```

In this example, when the method is invoked, the amount of ETH to be sent along with the transaction will be defined by the amount in the input `data-dh-property-input-name="EthValue"` is attached.&#x20;


# Listening to Events

Getting advanced functionality

{% hint style="warning" %}
This documentation describes functionality that is in development. For latest version check the [nightly build](/updates/changelog).
{% endhint %}

For more advanced builders looking to use external scripts to add custom functionality to DappHero powered websites, we are in the process of exposing events.&#x20;

**Events**

Listening to events gives you the ability to "monitor" the DappHero engine and react to changes in the state of the blockchain or smart contracts. Events can be used from HTML javascript, jQuery scripts, React or any Javascript Framework.&#x20;

**Adding an Event Listener**

To add an event listener in Javascript you would use the following code. In this example, the code will print "DappHero loaded" as soon as DappHero has loaded and is ready.&#x20;

```javascript
document.addEventListener("dappHeroConfigLoaded", ({ detail: dappHero }) => {
      // Inside here you can listen to any event you want	
      console.log("DappHero loaded")
});
```

For smart contracts, to listen to a change, for example to monitor the success or failure of a transaction, you would use:&#x20;

```javascript
document.addEventListener("dappHeroConfigLoaded", ({ detail: dappHero }) => {
        dappHero.listenToTransactionStatusChange(data => {	
                console.log("Listening to transactionStatusChange", data);	
        });
});
```

The `data` object will contain information about the current action taking place, the status and the contract method Name. This will fire on any smart contract change made in the browser. In the case of `auto-invoke` this can be very noisy. To filter for specific smart contract method you can evaluate the `data.mythodNameKey.value` to see if it matches the specific smart contract method you are interested in.

**Complete Example**

To listen to the smart contract method `transferTokens` from a script (possibly jQuery) you would use the following code. It will fire whenever a user or `auto-invoke` interacts with the smart contract method `transferTokens`.&#x20;

```javascript
<script>
      document.addEventListener("dappHeroConfigLoaded", ({ detail: dappHero }) => {  
      const methodName = 'transferTokens'
      dappHero.listenToTransactionStatusChange(data => {	
        if(data.methodNameKey.value === methodName) 
        console.log(`Listening to change in ${methodName}`, data);	
      });});
</script>
```


# Resources: Learn More

Where to go to learn more.

Interested in learning even more about Ethereum? Want to learn how to write your own smart contracts? The following are all excellent resources.

{% embed url="<https://www.udemy.com/course/ethereum-and-solidity-the-complete-developers-guide/>" %}
Steven Grider
{% endembed %}

{% embed url="<https://consensys.net/academy/>" %}
ConsenSys Academy
{% endembed %}

{% embed url="<https://www.zastrin.com/>" %}
Zastrin
{% endembed %}

{% embed url="<https://cryptozombies.io/>" %}
CryptoZombies
{% endembed %}


# Resources: Test Contracts

Want to practice your skills? We have the tools for you!

To help test that you're accessing your smart contracts in the correct way, we have created and deployed a number of test contracts to all the major networks to allow you to test against:&#x20;

Mainnet:&#x20;

<https://etherscan.io/address/0x29f7324836a88d04ce760e240e6cd7f0780aa255#code>

Ropsten:

<https://ropsten.etherscan.io/address/0xe2a6dd166b1840db90b2e4462ca7a90187562ddc#code>

Rinkeby:

<https://rinkeby.etherscan.io/address/0x6eefcb4ea22ed10f0094e0e6a8076275c7422220#code>

### Kovan:&#x20;

<https://kovan.etherscan.io/address/0x08c64b4d01881e29c5f4a8454de7e29ec395b544#code>

### Goerli:

<https://goerli.etherscan.io/address/0x08c64b4d01881e29c5f4a8454de7e29ec395b544#code>

xDai:&#x20;

GithubGist:&#x20;

<https://gist.github.com/crazyrabbitLTC/ed45a52cdcc559feb6ac5703ee93c8b2>

Solidity Code:&#x20;

```
pragma solidity 0.5.0;

contract DappHeroTest {
    uint public important = 777;
    bytes32 public hello = "Howdy";
    
    address public owner;
    
    event EventTrigger(address indexed sender, uint value);
    event ValueSent(address indexed sender);
    event EmitString(string message);
    event ValueSentWithMessage(address indexed sender, bytes32 message);

    constructor() public {
       owner = msg.sender;
    }

    function viewNoArgsMultipleReturn() public view returns(uint importantNumber, bytes32 sayHello){
        return (
            importantNumber,
            hello
        );
    }
    
    function viewMultipleArgsSingleReturn(address fromAddress, uint amount) public view returns(uint singleInt){
        return 89898989;
    }
    
    function viewMultipleArgsMultipleReturn(address fromAddress, uint amount) public view returns(uint longInteger, bytes32 sayHello){
        return (
            8989898989,
            hello
        );
    }

    function triggerEvent(uint anyInputValue) public {
        emit EventTrigger (msg.sender, 10);
    }

    function sendEthNoArgs() public payable {
        emit ValueSent(msg.sender);
        msg.sender.transfer(msg.value);
    }
    
    function makeTxNoArgs() public {
        emit EventTrigger(msg.sender, important);
    }
    
    function makeTxWithArgs(string memory myString) public {
        emit EmitString(myString);
    }

    function sendEthWithArgs(bytes32 simpleMessage) public payable {
        emit ValueSentWithMessage(msg.sender, "message");
        msg.sender.transfer(msg.value);
    }

    function sendMinimumTwoEthNoArgs() public payable {
        require(msg.value >= 2);
        emit ValueSent(msg.sender);
        msg.sender.transfer(msg.value);
    }

    function sendMinimumTwoEthWithArgs(bytes32 message) public payable {
        require(msg.value >= 2);
        emit ValueSentWithMessage(msg.sender, message);
        msg.sender.transfer(msg.value);
    }
}
```

ABI:&#x20;

<https://gist.github.com/crazyrabbitLTC/e4432070cd41b6f7181f3935d260871e>


# Collectibles 🃏

Want to learn what Collectables are? You're in the right spot! 🃏

### A bit about Tokens

Collectible are a type of *non-fungible* token. Non-fungible sounds complicated, but it simply means that each token is unique, and they are not interchangeable on a 1:1 basis. A great example would be Magic the Gathering trading cards: they are all *type* Magic the Gathering, but each individual card is *unique* in its' type.&#x20;

Collectibles are a way of representing unique things on the blockchain. Sometimes they can represent purely digital items like [*CryptoKitties*](https://www.cryptokitties.co/) or [*BlockCities*](https://www.blockcities.build/) but they can also be used to track real world physical items like bars of gold, or shares in real estate.&#x20;

In Ethereum, these collectible tokens are called NFTs (Non-fungible Token) and are defined by several token standards, the most popular of which is the [ERC721 Token Standard](http://erc721.org/).&#x20;

DappHero lets you build and connect websites to the world of Digital Collectibles, allowing you to build trophy rooms, create new market places, sell goods or just make awesome games!

DappHero's current Collectible integration works on Ethereum Mainnet, and sources data from the awesome open marketplace: [OpenSea](https://opensea.io/) so if you're looking for inspiration on how to *create* a digital collectible that you can then sell and trade for real money, check out their great [developer resources](https://docs.opensea.io/).&#x20;

### Read Only

Currently the DappHero integration for Collectibles is *read only* meaning you can only use it to display information about collectible tokens which already exist on the blockchain, not mint, transfer, burn or otherwise. To create a transaction for a collectible ERC721 contract, you will need to use DappHero to connect directly to the collectible smart contract to access these features.&#x20;

### Learn more

To learn more about the underlying technology and standards for ERC721 tokens, DappHero highly recommends looking at the OpenZeppelin documentation for [ERC721 contracts](https://docs.openzeppelin.com/contracts/2.x/erc721). Here you will find the technical documentation around the ERC721 standard and the most secure and trusted implementation of the code. You can even learn how to create and deploy your own ERC721 contract from scratch!

### Sample Project

Have a look at these sample projects with Glitch.io and Webflow to see how easy it is to get started!

#### Glitch.io

<https://glitch.com/~dapphero-nft-example>

#### Webflow

<https://webflow.com/website/Blockchain-powered-Collectible-Tokens>


# Getting Started

Using Collectibles in your DappHero project

### Things to keep in Mind

The syntax for working with Collectibles is relatively similar to that of working with smart contracts. We need to create an *instance* and *elements* which are connected via a `uniqueId` to link them both together.&#x20;

### Feature Collectibles vs Feature Custom Contract

Collectibles are managed by smart contracts deployed on the blockchain. This means you *could* access them directly using DappHero's Smart Contract Feature. For some uses cases it might be preferable to access the smart contracts directly, however for common uses Collectible smart contracts (most commonly ERC721 contracts) it will be easier to use the Collectible feature as we have simplified some of the more common use cases.&#x20;

The advantage of using the Collectibles feature is that DappHero simplifies the process of interacting with the JSON objects which are used to store the [metadata](https://docs.opensea.io/docs/metadata-standards) which represent individual collectible tokens in a standard way. Following these standards are important if you want your collectible token to be interoperable with public marketplaces.&#x20;

## General Concepts

### Unique ID

When you create an *instance* of a collectible object, you will be able to place the collectibles *elements* anywhere on your webpage. To link the correct instance with the correct elements, we have introduced a special tag,  `data-dh-property-method-id`, which has a custom unique value that you determine, and which should be used for all elements related to the same functionality.&#x20;

```markup
// This element creates our collectable instance
<div ...
data-dh-feature="nft"
data-dh-property-tag-id="myUniqueTag" 
....
/>

// This element is where we are going to be displaying a collectable item
<div ...
data-dh-property-tag-id="myUniqueTag" 
data-dh-property-asset-item="true"
...
/>

```

In the above example, all the elements for a `Collectable` integration are marked with the same unique tag id, `myUniqueTag` in this way, the DappHero Engine knows all these different elements, regardless of where they are on the page, belong together in the same functionality.&#x20;

### TokenId

In the ERC721 standard, each token is given a TokenId that represents it as a unique item. This TokenId is needed to identify the specific collectible.&#x20;

### Contract Address

As collectibles are governed by smart contracts, such as the [CryptoKitties](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d#code) Contract or [BlockCities](https://etherscan.io/address/0x2f2d5aa0efdb9ca3c9bb789693d06bebea88792f#code) Contract, they each have a unique Ethereum Address. This address is what differentiates tokenId# 100 on CryptoKitties from tokenId# 100 for BlockCities. A good way to mentally think about this is; *TokenId# 100 for Contract Address: 0x0.....*

### JSON Path

When calling an ERC721 Collectible contract for a specific token, most standard tokens will return a *tokenURI.* This *tokenURI* generally is a link which points to a place on the internet that stores metadata *about the token* generally this is a JSON object with properties which describe what the token represents, such as a CryptoKitty name or a CryptoKitty picture.&#x20;

To access this metadata,  we use a special DappHero Tag: `data-dh-property-asset-json-path` followed by the item we are looking for such as `image_url` or `name`. This element will be defined on the JSON object returned by the metadata.&#x20;

```markup
//psuedo code

//Displaying a token's Image
<img data-dh-property-asset-json-path="image_url" />

//Getting a token name as H3 text                  
<h3 data-dh-property-asset-json-path="name"></h3>
```

Unfortunately while there are some [standards](https://docs.opensea.io/docs/metadata-standards) for how MetaData should be structured, they are not 100% standard. If connecting to a contract with non-standard meta-data you will need to contact the contract creators to understand the format returned by the collectible contract.

### Collectable Data Source and Networks

DappHero uses the [OpenSea API](https://opensea.io/) as a data source for Collectables, currently it does not pull the data directly from the blockchain network. This means that currently the `Collectable` feature only supports the Ethereum Mainnet.&#x20;


# Single Collectibles

Retrieving a single collectible and displaying it's data

Collectibles are represented by smart contracts, and this means they have a number of standard properties such as a contract, a deployed contract address, and collectible owners. Depending on what we are trying to do, we will need difficult combinations of these parameters to get the right token.

#### Get a single Collectible by TokenID and Owner Address

This will return any single token with a `TokenId` and owned by `OwnerAddress` If there are multiple tokens with `TokenId` owned by this address, it will only return the first token that it finds.

```markup
<!-- This top level div is the method Instance -->
<div
    data-dh-feature="nft"
    data-dh-property-tag-id="<<uniqueID>>"
    data-dh-property-asset-token-id="<<TokenId>>"
    data-dh-property-asset-owner-address="<<OwnerAddress>>">
    
    <div data-dh-property-tag-id="<<uniqueID>>" 
         data-dh-property-asset-item="true">
         
         <img data-dh-property-asset-json-path="image_url" />
         <h3 data-dh-property-asset-json-path="name"></h3>
         
    </div>
    
</div>
```

In the case that an owner potentially owns multiple tokens with the same `TokenId` in different Collectible contracts you can filter by using:&#x20;

`data-dh-property-asset-contract-address="<<Address>>"`  in the Collectible instance after specifying the `asset-owner-address`. This will return results only from this specific collectible contract address.

#### Get a single Collectible by TokenID and Contract Address

If the owner address is not relevant, by suppling only a `TokenId` and `ContractAddress` a single token will be returned.&#x20;

```markup
<!-- This top level div is the method Instance -->
<div
    data-dh-feature="nft"
    data-dh-property-tag-id="<uniqueID>>"
    data-dh-property-asset-token-id="<<TokenID>>"
    data-dh-property-asset-contract-address="<<ContractAddress>>">
   
    <div data-dh-property-tag-id="<<uniqueID>>" 
         data-dh-property-asset-item="true">
         
        <img data-dh-property-asset-json-path="image_url" />
        <h3 data-dh-property-asset-json-path="name"></h3>
        
    </div>
      
</div>
```


# Listing Collectibles

How to display lists of Collectibles

## General Concepts

Lists in DappHero work a bit different than most features. With lists, we create first an *instance* of our feature, we then also create a *container* that represents the data we wish to display. When our website is live, the DappHero engine will duplicate the container for each piece of data inside our "list" that is returned.&#x20;

The *container* in DappHero is created by assigning an HTML element a `data-dh-property-asset-item` tag and a `UniqueID` which matches our *instance* `UniqueID`. The DappHero engine will recognize this block of HTML as the block you wish to duplicated for each Collectible item for which you want to display information and can be used to create exciting dynamic lists with barely any code!&#x20;

The Collectible feature is powered by the [OpenSea API](https://opensea.io/) and will only return tokens indexed by their mainnet service (currently over 10 million items).

#### List all Collectibles owned by an address

To list all the Collectible tokens that are owned by an address, it is necessary to provide only the owners address. This can be a contract address or a users address and it will return a list of all the tokens owned by this address, regardless of Collectible contract address.&#x20;

```markup
<!-- This top level div is the method Instance -->
<div
      data-dh-feature="nft"
      data-dh-property-tag-id="<<UniqueID>>"
      data-dh-property-asset-owner-address="<<address>>">
      
      <div data-dh-property-tag-id="<<UniqueID>>" 
           data-dh-property-asset-item="true">
      
        <img data-dh-property-asset-json-path="image_url" />
        <h3 data-dh-property-asset-json-path="name"></h3>
        
      </div>
</div>
```

#### Filtering by Contract Address

To filter by a specific contract address, add the line `data-dh-property-asset-contract-address="<<Address>>"` and it will filter for only the contracts owned by the user of this particular collectible contract. This is useful, for example, to show all the CryptoKitties owned by a single address.

#### List of all Collectibles by Collectible contract address

To list all the collectibles created by a specific contract, it is necessary only to provide the collectible contract address. The order displayed will be the order returned from the OpenSea API.&#x20;

```markup
<!-- This top level div is the method Instance -->
<div
      data-dh-feature="nft"
      data-dh-property-tag-id="<<UniqueID>>"
      data-dh-property-asset-contract-address="<<Address>>">
      
      <div data-dh-property-tag-id="<<UniqueID>>" 
           data-dh-property-asset-item="true">
           
        <img data-dh-property-asset-json-path="image_url" />
        <h3 data-dh-property-asset-json-path="name"></h3>
        
      </div>
</div>
```

### List of specific Collectibles by owner

```markup
<div
      data-dh-feature="nft"
      data-dh-property-tag-id="<<UniqueID>>"
      data-dh-property-asset-token-id="list of ids, 1,2,3"
      data-dh-property-asset-owner-address="<<Address>>">
      
      <div data-dh-property-tag-id="<<UniqueID>>" 
           data-dh-property-asset-item="true">
        
        <img data-dh-property-asset-json-path="image_url" />
        <h3 data-dh-property-asset-json-path="name"></h3>
        
      </div>
</div>
```

In this case:&#x20;

```markup
data-dh-property-asset-token-id="list of ids, 1,2,3"
```

The List of IDs is a list that is formatted as a comma separated array of values. So in this case if we wanted to see the tokens 101,102,103 of the owner of `address` we would do:&#x20;

```markup
data-dh-property-asset-token-id="101,102,103"
```

{% hint style="warning" %}
Note: When listing a specific group of tokens with the `data-dh-property-asset-token-id` tag, you will not be able to combine it with the `pagination-offset` or `pagination-limit` tags. The result will return no tokens.&#x20;
{% endhint %}

## Pagination and Limits

When working with lists of Collectible tokens, controlling the number of items retrieved from the API or displayed to the user is very important. To do this we have created pagination modifiers that allow you to control the number of items displayed, and to add handy pagination buttons to give users the chance to page through large sets of items.&#x20;

| Tag                                  | Property | Required |
| ------------------------------------ | -------- | -------- |
| `data-dh-property-pagination-limit`  | integer  | optional |
| `data-dh-property-pagination-offset` | integer  | optional |
| `data-dh-property-pagination-prev`   | none     | optional |
| `data-dh-property-pagination-next`   | none     | optional |

#### pagination-limit

This is the number of tokens you want returned in a list. The default is 20 and the max is 300. This is also the number of tokens that will be displayed on your website. This can be used without `pagination-prev` or `pagination-next` to limit the number of displayed results.&#x20;

#### pagination-offset

In situations where the number of Collectible tokens returned (for example: all the CryptoKitties) is greater than you can display, the `pagination-offset` value allows you to choose from where in the list you start displaying the Collectibles. So for example, if you have a limit of 20 out of a possible total of 40, then an offset of 0 would display Collectibles 1-20, while an offset of 1 would display Collectibles 21-40.

#### pagination-prev

By attaching `data-dh-property-pagination-prev` to a button element, by clicking on the button users will be able to move backwards in the list.

#### pagination-next

The opposite of `pagination-prev`

```markup
<div
      data-dh-feature="nft"
      data-dh-property-tag-id="<<UniqueID>>"
      ...
      data-dh-property-pagination-limit="<<number of tokens>>"
      data-dh-property-pagination-offset="<<the offset>>"
      data-dh-property-asset-owner-address="<<Address>>">
      

      <button data-dh-property-tag-id="<<UniqueID>>" 
      data-dh-property-pagination-prev="true">prev</button>
      

      <button data-dh-property-tag-id="<<UniqueID>>" 
      data-dh-property-pagination-next="true">next</button>

      <div data-dh-property-tag-id="<<UniqueID>>" 
           data-dh-property-asset-item="true">
           
        <img data-dh-property-asset-json-path="image_url"/>
        <h3 data-dh-property-asset-json-path="name"></h3>
      
      </div>
</div>
```

These tags effectively lets us "page" through a long list of results. This is useful if you wish to limit the number of resulting tokens that are displayed on a single page. This can be helpful for design when for example, you want to show only a single token per page and allow the users to page through through the like a gallery.&#x20;


# Displaying Token Metadata

Collectible tokens are based on the ERC721 standard, and most (not all) adhere to a [standard Metadata](https://docs.opensea.io/docs/metadata-standards) format popularized by OpenSea the online collectible marketplace.&#x20;

{% hint style="info" %}
We will be adding more information and support for metadata at a later date
{% endhint %}

### Loading Metadata

Metadata exists on collectibles as a JSON formatted object. On this object will be information that describes the various characteristics of the collectible. Because this metadata can be virtually anything, we have created a special tag `data-dh-property-asset-json-path` to help you access  it.&#x20;

Note: metadata can be potentially extremely nested data, `data-dh-property-asset-json-path` will do it's best to identify the piece of data you are specifically interested in, but for some complex objects or with repeating key names at different levels, it can struggle. Additionally, not all tokens respect the metadata format, even within the same collectible group. We will be releasing a new tag in the future to allow you to identify the exact data attribute you want in the future.&#x20;

#### Getting the token Name and ImageURL

Lets take a sample collectible JSON object:&#x20;

```javascript
{
  "description": "Friendly OpenSea Creature that enjoys long swims in the ocean.", 
  "external_url": "https://openseacreatures.io/3", 
  "image": "https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png", 
  "name": "Dave Starbelly",
  "attributes": [ ... ], 
}
```

Here we have a description, an external URL, image, name and array of attributes. The top level elements, "image" or "name" for example can be access using the following tags:&#x20;

```markup
<div
      data-dh-feature="nft"
      data-dh-property-tag-id="000"
      data-dh-property-asset-owner-address="<<User Address>>">

      <div 
          data-dh-property-tag-id="000" 
          data-dh-property-asset-item="true">
        <img data-dh-property-asset-json-path="image_url" />
        <h3 data-dh-property-asset-json-path="name"></h3>
      </div>
</div>
```

In this example we are retrieving a list of collectibles owned by the `user address` the *method instance* is described in the div from lines 1-4, the parent asset container is the div that opens on line 6 and closes on line 11. The children elements are the `img` tag which displays the token image and the `h3` tag which displays the assets name. As this is a list, it will display multiple tokens owned by this address, with the image and name coming from each respective token.&#x20;

For the "attributes" they currently are not natively accessibly via HTML tags, and will require the use of jQuery to access. Look forward to a future DappHero feature to handle this use case!


# Advanced: $CURRENT\_USER

Dynamically getting the address of the current user

In situations where it doesn't make sense to hard-code the address of the user for which you would like to retrieve a Collectible or list of Collectibles, the special constant `$CURRENT_USER` can be used to dynamically insert the current users address.&#x20;

This constant can be used to help create dynamic websites with Collectibles.&#x20;

```markup
<div
    data-dh-feature="nft"
    data-dh-property-tag-id="<<UniqueID>>"
    data-dh-property-asset-token-id="<<TokenID>>"
    data-dh-property-asset-owner-address="$CURRENT_USER">
    
    <div 
        data-dh-property-tag-id="<<UniqueID>>" 
        data-dh-property-asset-item="true">
        
        <img data-dh-property-asset-json-path="image_url" />
        <h3 data-dh-property-asset-json-path="name"></h3>
    </div>
</div>
```


# Advanced: $URL

Set the Collectible Feature instance via URL query params

### Background

To set `data-dh-property-asset-token-id` , `data-dh-property-asset-owner-address` , and `data-dh-property-contract-address` via the URL bar, we can use the special value: `$URL`

This can be a very handy feature for creating dynamic websites that can display a list of Collectible tokens in a dynamic way. Consider for example a webpage that shows a list of tokens owned by user, but then when a user clicks on a particular token in that list, it loads a new webpage that now shows only a single token.&#x20;

To do this could be very complicated, but with DappHero $URL query params we've created a shortcut to allow you to create dynamic and exciting experiences around Collectible tokens. By allowing the use of query params, users can now create a single template for their Collectible features without hardcoding any variables. Users can load the same HTML file in their browser but with different query params and it will load different sets of Collectible tokens.&#x20;

{% hint style="warning" %}
$URL Query Params can only be used by a single Collectible feature instance per webpage.&#x20;
{% endhint %}

To use the `$URL` special variable, simply replace the `token-id`, `owner-address`, or `contract-address` with the value `$URL` and the DappHero engine will search for the values from the browsers URL bar.

```markup
http://www.yourDomain.com/?assetTokenId=...tokenId&assetOwnerAddress=...ownerAddress&assetContractAddress=...contractAddress
```

### HTML

```markup
<div
      data-dh-feature="nft"
      data-dh-property-tag-id="<<UniqueID>>"
      data-dh-property-asset-token-id="$URL"
      data-dh-property-asset-owner-address="$URL" 
      data-dh-property-asset-contract-address="$URL">
      
      <div 
        data-dh-property-tag-id="<<UniqueID>>" 
        data-dh-property-asset-item="true">
      
        <img data-dh-property-asset-json-path="image_url" />
        <h3 data-dh-property-asset-json-path="name"></h3>
        
      </div>
</div>
```


# Advanced: $THIS

Referring to the current Collectible's information

{% hint style="info" %}
This documentation is unfinished
{% endhint %}

Advanced features such as [getting parameters from the URL bar](/features/what-are-nfts/advanced-url-query-params), or referencing the [current user](/features/what-are-nfts/advanced-usdcurrent_user) are important to building dynamic functionality for Collectibles. To complete this functionality and give users the ability to dynamically generate links from Collectibles in a list to a page of a single collectible, we have created the ability for an HTML block to dynamic reference itself with the const `$THIS...`

### Usage

The `$THIS...` const is useful when it is necessary to refer to the current item, for example when creating dynamic links that should be unique for each collectible item. &#x20;

| CONST                   | Purpose                                   |
| ----------------------- | ----------------------------------------- |
| `$THIS_ContractAddress` | Substituted with current Contract Address |
| `$THIS_TokenID`         | Substituted with current TokenID          |
| `$THIS_OwnerAddress`    | Substitutes with current OwnerAddress     |

### Example

For a live Demo: [DappHero-nft-example](https://glitch.com/~dapphero-nft-example).

Suppose you wanted to build a webpage that showed a dynamic list of Collectibles based on the contract address of a particular NFT contract. This is fairly easy to do, [ list the Collectibles](/features/what-are-nfts/listing-collectables#general-concepts). Now let's say you wrap each Token's image in an `anchor` tag, turning the image itself into a link that when clicked upon takes the user to a new webpage that shows a [Single Collectible](/features/what-are-nfts/single-collectibles). Creating a Single Collectible is also fairly easy, but the question is- how would you pass the data about WHICH collectible you want to display on the Single Collectible page?&#x20;

This is where we use `$THIS...`

```markup
<div
      data-dh-feature="nft"
      data-dh-property-tag-id="000"
      data-dh-property-asset-contract-address="<<contractAddress>>">
     
   <div
      data-dh-property-tag-id="000"
      data-dh-property-asset-item="true">
      <a
         href="./singleNFT.html?assetTokenId=$THIS_TokenID&assetContractAddress=$THIS_ContractAddress">
         <img data-dh-property-asset-json-path="image_url"/>
         </a>
     </div></div>
```

Let us take a closer look at line 9-12. What we are doing here is creating a link to a new page but passing URL Query Params for the DappHero engine to catch in the `singleNFT.html` page. You could manually pass the details `assetTokenId=1234` but then you would be stuck always rendering this one token. Instead, because we are inside the `asset container` from line 6-9 which gets rendered for each Collectible returned, we can access THIS specific token. If we use $THIS\_TokenID in the `href` link, it will get replaced with the token currently displayed, for example '1234'. If we do the same for the `assetContractAddress` we can now link to the `singleNFT.html` page passing all the information required for that page to render dynamically the specific collectible token we are interested in.&#x20;

```markup
<a
href="./singleNFT.html?assetTokenId=$THIS_TokenID&assetContractAddress=$THIS_ContractAddress">
<img data-dh-property-asset-json-path="image_url"/>
</a>
```

### Forms

Using the `$THIS...` const is useful for more than just creating dynamic links- it can also be used to create dynamic forms. This means you can combine the Collectible feature with other features like smart contracts- allowing users to interact with smart contracts using the about the current token they are looking for. A great example for this would be to create a Collectible store front connected to a smart contract to let people buy or sell Collectibles directly from your website!

Have a look at this simple example.&#x20;

```markup
<form action="">
        TokenID: <input type="text" value="$THIS_TokenID"><br><br>
        Owner Address: <input type="text" value="$THIS_OwnerAddress"><br><br>
        <input type="submit" value="Submit">
</form> 
```


# Advanced: Properties


# Calling Smart Contracts inside Collectibles

{% hint style="warning" %}
It is not currently possible to use Smart contracts inside of the Collectible feature.

This functionality is on the DappHero Roadmap and will be announced in the near future.&#x20;
{% endhint %}


# Collectible Example

A complete example of using Collectibles

To help get you started using the Collectible feature of DappHero we have prepared a sample project using Glitch to help you experiment.&#x20;

Visit the [Example](https://glitch.com/edit/#!/dapphero-nft-example).

In this example we take advantage of multiple collectible features. We start by showing a [list of collectibles](/features/what-are-nfts/listing-collectables) from a particular smart contract and we add Forward and Backwards buttons to [page through Collectibles](/features/what-are-nfts/listing-collectables#pagination-and-limits). Then we create a second page that shows a [single collectible](/features/what-are-nfts/single-collectibles). We link the two pages via the [$THIS](/features/what-are-nfts/advanced-usdthis) keyword and allow dynamic page loading by getting the relevant collectible details from the URL bar with[ $URL](/features/what-are-nfts/advanced-url-query-params). &#x20;


# Webflow 🎁

No-Code option for powerful websites.

Webflow is a powerful, no-code, website builder used by a large number of people and powers countless websites. It caters towards users looking to build exciting, design focused web experiences.&#x20;

Getting started with Webflow is free, however to really experience the power and flexibility, or publish a public project to production, you will need to signup to a subscription.&#x20;

DappHero integrates with WebFlow for our users who prefer to use an entirely no-code solution.&#x20;

![](/files/-M-oTnkilm2hEMdS6nYn)


# Getting Started with Webflow

A powerful no-code tool that works with DappHero

DappHero is fully equipped to work with [Webflow](https://webflow.com/), a popular drag-and-drop no-code tool for building websites. After adding a Script tag to your Webflow project, you can access all the power of DappHero by adding tags to your elements directly in the Webflow interface.&#x20;

To get started on Webflow:

* Signup to Webflow and [create an account](https://webflow.com/discover/popular#)
* (Quick Start) Clone a pre-made template from the [DappHero team page](https://webflow.com/team/DappHero) and change the script tag
* (Clean Start) Create a new project and add a script tag (requires a paid Webflow plan)&#x20;
* Start building your site, using DappHero tags

### Signup To Webflow

![Getting started from a DappHero Template](/files/-M-oPrdBUlITrdfFM-A9)

### Clone a template

Once you are signed into Webflow, you can revisit the [DappHero team page](https://webflow.com/team/DappHero) and choose a template to start with. Click "clone" to create a copy of the template to your account.&#x20;

![](/files/-M-oQ2mo84_KD6yNPKe_)

### Create your Project

After you the template to your account, you can click "Create" to start editing.&#x20;

![](/files/-M-oQZGbXjqJ4k95aNyK)

### Change the Script tag

Each template comes with a script tag already added. If you have added custom smart contracts to your project, you will want to change the script tag for the one in your DappHero Project.&#x20;

#### Edit your page settings

{% hint style="info" %}
Note: the DappHero script tag needs to be added to each page you wish to enable DappHero.
{% endhint %}

![Click the small gear that appears when you hover over your page name](/files/-M-oRDcWCWlMpVTcSQV_)

#### Copy the script tag from your project

![Copy your script tag from your project](/files/-M-oR6etmbmAhH4Mmb3w)

#### Paste or Edit your Script Tag

![Scroll to the bottom of your Page settings, and paste/edit your script tag. ](/files/-M-oReVV_eSqwZmbFADH)


# Add DappHero Elements

How to label your elements

Creating new DappHero Elements in WebFlow is a straightforward task. Using the Custom Attributes panel, any element you create in WebFlow can be labeled with tags to enable DappHero functionality.

### Adding DappHero Custom Attribute

To turn an ordinary element into a DappHero Element, you need only to give it a custom attribute to tell it how you want it to work. To add the Network Feature to an element &#x20;

![Add the 'data-dh-feature' as the name](/files/-LzE65S4XnW4bQn279As)

###

This will put the custom attribute "data-dh-feature" on your \<div> element with the value `network`. When WebFlow eventually generates HTML, the output HTML will look something like this:&#x20;

```markup
<div data-dh-feature="network">...</div>
```

This tells the DappHero engine that this element is meant to connect to the Network Feature, and it will inject the data from **network** into the Div when your user visits your website.&#x20;

## Learn more about Custom Attributes at Webflow:

To learn more, we highly recommend you watch this short video from WebFlow about how to add custom elements:&#x20;

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

{% embed url="<https://university.webflow.com/article/how-to-add-custom-attributes-to-an-element-in-webflow>" %}
Additional Resources at Webflow University
{% endembed %}


# Learn more about WebFlow

Resources to keep you moving

To learn more about how to use Webflow, check out their awesome [Webflow University](https://university.webflow.com/) with tons of videos and educational materials to get you up and running fast.&#x20;

{% embed url="<https://university.webflow.com/>" %}


# Coming soon...


# Engine Events

Listening to the DappHero Core engine

When creating more advanced code and logic it can be important to listen internally to the changes happening inside the DappHero-Core engine. To help do this, we have provided a number of event listeners to help you react to internal changes to DappHero Core processes.&#x20;

All listeners take a callback and will be triggered on an event change internally.&#x20;

To use these, first listen for the event that signals DappHero has loaded, and then you can listen for DappHero specific events. &#x20;

```javascript
<script>
      document.addEventListener(
        "dappHeroConfigLoaded",
        ({ detail: dappHero }) => {
          // Inside here you can listen to any event you want
  
          // dappHero.listenToSmartContractBlockchainEvent(data => {
          //   console.log("The blockChain Events: ", data)
          // })
        }
      );
</script>
```

### List of Listeners:&#x20;

#### Smart Contracts

`listenToTransactionStatusChange()`

Fires for each step in the process of preparing and submitting a transaction to the blockchain. &#x20;

`listenToSmartContractBlockchainEvent()`

Fires for each event [emitted by an Ethereum smart contract](https://solidity.readthedocs.io/en/develop/abi-spec.html?highlight=events#events).&#x20;

`listenToContractOutputChange()`

Fires for a change in smart contract output.

`listenToContractAutoInvokeChange()`

Fires each time a public smart contract method is auto-invoked. For auto-invoked elements, this can be noisy.&#x20;

`listenToContractInvokeTriggerChange()`

Fires each time a smart contract is invoked.

#### Network Feature (ETH Transfer)

`listentoEthTransfer()`

Fires for an Ethereum transfer event.

#### 3Box Feature

`listenTo3BoxProfile()`

Fires for a 3Box feature event.

#### NFT Feature

These events will fire based on their related functionality. They each work the same.&#x20;

`listenToNFTLoadAllToken()`

`listenToNFTLoadMultipleToken()`

`listenToNFTLoadSingleToken()`

#### User Feature

`listenToUserAddressChange()`

Fires for a change in the user address, for example, when switching addresses in MetaMask.

`listenToUserBalanceChange()`

Fires when a users balance changes.&#x20;


# Force Refresh

How to programmatically force refresh the DappHero Engine

{% hint style="danger" %}
Force Refresh functionality is experimental.
{% endhint %}

For more advanced use cases, such as manipulation of the DOM via external script such as jQuery, it can be useful to force DappHero to refresh its view of the user's DOM.&#x20;

An example use case would be using jQuery to append new DOM elements to the user's webpage. DappHero by default only scans the DOM once, at page load, so if DappHero enabled elements are programmatically added to the DOM after page load, the engine will not be aware of them. &#x20;

Additionally, the DappHero core engine does not "watch" the user's DOM, so if a DappHero powered website element is altered via a script, the engine will not be aware of the change. For example, if you were to use jQuery to change the input value of a form field or the value of an invisible input for an auto-invoked method, DappHero will be unaware of this change.&#x20;

To assist builders looking to add functionality via external scripts, we have exposed a function on the window that when called will trigger a refresh of the DappHero engine. Call this function at the end of any external script manipulation to ensure DappHero always has the most recent version of the DOM.&#x20;

```
window.dappHero.retriggerEngine()
// or without window
dappHero.retriggerEngine()
```

By invoking the `retriggerEngine()` function, DappHero will re-run and recheck the webpage DOM for changes.&#x20;


# Database

A simple end-to-end encrypted database in the browser

{% hint style="info" %}
This is an experimental feature, have fun, but remember it \*could\* break
{% endhint %}

### Details

The DappHero database is a super simple, in browser, end-to-end encrypted database that can be access directly from the window object in the browser.&#x20;

Each database is scoped to the `ProjectId` of your project and can be used as a fast, efficient `key:value` store.&#x20;

Users are scoped to DappHero, so a user that signs up at any DappHero site will also be a valid user on your site and vice versa. The Database however is not shared, so the data available to you will be specific to your projectId.&#x20;

The data in the database is encrypted client side in the browser for each user and is backed up to Amazon AWS in an encrypted format. DappHero can not access this data and can not retrieve user credentials, so if they lose their login- it's gone.&#x20;

All functions are async. DappHero Database is based on [UserBase](https://docs.dapphero.io/advanced/www.userbase.io).

### signUp

`window.dapphero.db.signUp({username: "my name", password: "xxxxx"})`

### signIn

`window.dapphero.db.signIn({username, password})`

### signOut

`window.dapphero.db.signOut()`

### openDatabase

`window.dapphero.db.openDatabase(callbackToReceiveDatabase)`

### insertItem

`window.dapphero.db.insertItem(item)`

### updateItem

`window.dapphero.db.updateItem(item, itemId)`

### deleteItem

`window.dapphero.db.deleteItem(itemId)`

###


# Ethereum Provider

Connecting to the exposed ethereum provider with DappHero

For more builders who are incorporating DappHero on mixed technology websites, we have offered the ability to get access to the underlying Ethereum Provider.&#x20;

### Window object

An [Ethers.js](https://docs.ethers.io/ethers.js/html/) (v5) powered Ethereum provider is available at `window.dappHero.provider`. This provider can be used to create new connections to the Ethereum blockchain without needing DappHero.

```
window.dappHero.provider
// or without window
dappHero.provider
```


# ChangeLog

A list of things we are working on here at DappHero!

Nightly Builds

Monday, May 18th, 2020

* Alpha V2 is now active. The **main.js** script tag now has all mainline features including collectibles. Bug releases are forthcoming. Until then there won't be any new nightly builds as we move towards beta.&#x20;

Nightly Builds

* Latest nightly build: (Nightly builds are experimental)
  * **main-05-14-2020.js**
    * Improved support for Collectibles and Smart Contract Events.
  * **main-05-11-2020.js**
    * Improved support for the $THIS keyword
  * **main-05-08-2020.js**
    * Support for smart contract events
  * **main-05-06-2020.js**
    * Add auto-clear property for inputs.&#x20;
  * **main-05-04-2020.js**
    * fix for collectibles
  * **main-05-01-2020.js**
    * ethUserBalance now updates faster
  * **main-04-27-2020.js**
    * various improvements

Sunday, April 26, 2020

* Updated DappHero Docs:&#x20;

  * **$true** [Accessing anonymous inputs](/features/using-smart-contracts/inputs#anonymous-inputs)
  * [AutoClear tag](/features/using-smart-contracts/inputs#autoclear-inputs)


# Bug Bounty

Get paid to find bugs!

### Bugs already found currently in the queue to be fixed:&#x20;

~~July 14, 2020 : there is an error when trying to generate an HTML page with an incomplete/malformed contract~~

July 14, 2020: there is an error when copying an ABI from Remix in that the methods tab for contracts does not properly display the method HTML.&#x20;

(note the date above was wrong, it should have been 14/15, not 24/25!)

~~July 15, 2020: There is an error for login with google.~~&#x20;

{% hint style="info" %}
So far two bug bounties of $25 have already been claimed and the bugs fixed!
{% endhint %}

### Get Started

While we are in Beta, we're creating a Bug Bounty to help us find bugs. We are paying out a token amount of DAI to show our appreciation. It's not a ton, but we do want to show we care!

### $25 USD in DAI

For any bug in the User Interface hosted at DappHero.io. This can be problems with the login, problems with the UI (functional, not just aestetic)  or anything in that realm. If something is broken or not working correctly on the website, that will probably count, so let us know!

### $50 USD in DAI

For any bug found in the actual DappHero core engine that runs client-side in users browsers. There are some exceptions that will be at our own discretion: sometimes Web3 and Ethereum can perform in strange ways.&#x20;

### Rules

To get a bug bounty you need to do a couple things, first you **must** email the bug information to us at: **<dennison@dapphero.io>**. Please do not post the bug in the Telegram group or in the forum. We want to have a chance to fix it before we make it public.&#x20;

Second, to get the payout, you must confirm for us in your email that you are not a person on the US sanctions list, nor a resident/citizen of any country on the US sanction list. &#x20;

Third, we might not list the bugs that are found, but you will have to trust us if we say the bug has already been reported. There might be some bugs for which we decide not to fix right now, we will try to make that list of bugs public, but again, you're going to have to trust us on that one. &#x20;

### Terms and Conditions

So, there are some caveats. Bug bounties are at our own discretion. We will try to get back to you within 7 days for a bug report. We may, at any time, limit the total number of bounties we give out. We might stop the program without telling anyone. This is intended to thank our users and beta-testers, so please keep everything civil. Thanks!


