# Web3, ZekndProvider and Truffle

### Overview <a href="#overview" id="overview"></a>

The zeknd-js library comes with the zeknd`Provider` which makes it possible to connect with `Web3.js` as a provider. This way, Ethereum developers can deploy, send transactions to smart contracts, and listen for smart contracts events running on zeknd DAppChains. Also, it is possible to use Truffle Framework to manage tests, deployments and solidity smart contracts. For further details check out EVM page.

#### #Web3 <a href="#web3" id="web3"></a>

As the official documentation for `Web3.js` states:

> `Web3.js` is a collection of libraries which allow you to interact with a local or remote ethereum node, using an HTTP or IPC connection.

For the zeknd DAppChains, the communication happens using `WebSockets` instead `HTTP` or `IPC`. However, in-depth knowledge isn't required since `Web3.js` abstracts that part.

#### #zekndProvider <a href="#loomprovider" id="loomprovider"></a>

A `Provider` is a bridge that connects the `Web3.js` API to an Ethereum node. So, in order to make `Web3.js` calls compatible with zeknd DAppChain, you should use the zeknd`Provider`

Combining `Web3.js` and zeknd`Provider` is a good option to interact with smart contracts deployed on zeknd DAppChain because `Web3.js` abstracts the construction of API calls.

### #Deploying with Truffle <a href="#deploying-with-truffle" id="deploying-with-truffle"></a>

#### #Download and Install <a href="#download-and-install" id="download-and-install"></a>

First, you'll need to install `Truffle`:

```
# Currently supported version
npm install -g truffle
```

Once `Truffle` is installed, let's create a directory and initialize a project:

```
# Create directory and access
mkdir simple-store
cd simple-store

# Initialize a project from zero with truffle
truffle init
```

The new directory structure will look like this:

```
.
├── contracts
│   └── Migrations.sol
├── migrations
│   └── 1_initial_migration.js
├── test
├── truffle-config.js
└── truffle.js
```

#### #Adding contract and migration <a href="#adding-contract-and-migration" id="adding-contract-and-migration"></a>

In the `contracts` directory, we're going to add the famous `SimpleStore.sol`, a smart contract which has:

* a `set` function that takes a parameter called `_value` and changes the state by saving it to the blockchain. Then, it fires an event called `NewValueSet`.
* a `get` function that lets you read the `value` variable.

```
pragma solidity ^0.4.22;

contract SimpleStore {
  uint value;

  event NewValueSet(uint _value);

  function set(uint _value) public {
    value = _value;
    emit NewValueSet(value);
  }

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

Next, let's add a migration, `Truffle` works with the concept of migrations, which makes it useful to track changes and updates. In the `migrations` directory, create a new file called `2_simple_store.js` and paste the following content into it:

```
var SimpleStore = artifacts.require("./SimpleStore.sol");

module.exports = function(deployer) {
  deployer.deploy(SimpleStore);
};
```

> We've already built a complete example of how to integrate with Truffle. You can check it out here.

#### #Download and configure zeknd Truffle Provider <a href="#download-and-configure-loom-truffle-provider" id="download-and-configure-loom-truffle-provider"></a>

The last cog to be added is the zeknd `Truffle Provider`. This plugin basically connects `Truffle` with the zeknd DAppChain. Let's install it by running:

```
npm install zeknd-truffle-provider --save
#or
yarn add zeknd-truffle-provider
```

Now, let's edit the file `truffle.js` to add the necessary configuration:

```
const { readFileSync } = require('fs')
const zekndTruffleProvider = require('zeknd-truffle-provider')

const chainId    = 'default'
const writeUrl   = 'http://127.0.0.1:46658/rpc'
const readUrl    = 'http://127.0.0.1:46658/query'
const privateKey = readFileSync('./private_key', 'utf-8')

const zekndTruffleProvider = new zekndTruffleProvider(chainId, writeUrl, readUrl, privateKey)

module.exports = {
  networks: {
    zeknd_dapp_chain: {
      provider: zekndTruffleProvider,
      network_id: '*'
    }
  }
}
```

> Don't forget to generate your keys by running zeknd `genkey -a public_key -k private_key`.

#### #Running Truffle deploy command <a href="#running-truffle-deploy-command" id="running-truffle-deploy-command"></a>

Now we're ready to deploy our smart contract:

```
truffle deploy --network zeknd_dapp_chain
```

> We're assuming zeknd is already running on your computer. If not, follow this tutorial.

> If you already deployed and want to reset the deployment, you can run the command `truffle deploy --reset --network` zeknd`_dapp_chain`

#### #Adding more accounts <a href="#adding-more-accounts" id="adding-more-accounts"></a>

In order to access the `accounts` with zeknd`TruffleProvider`, you should do something like this:

```
const zekndTruffleProvider = new zekndTruffleProvider(chainId, writeUrl, readUrl, privateKey)
const zekndProvider = zekndTruffleProvider.getProviderEngine()

console.log("Accounts list", zekndProvider.accountsAddrList)
console.log("Accounts and Private Keys", zekndProvider.accounts)
```

To add more accouns, just call `createExtraAccounts`:

```
const zekndTruffleProvider = new zekndTruffleProvider(chainId, writeUrl, readUrl, privateKey)
zekndTruffleProvider.createExtraAccounts(10)
```

### #Configuring and running Web3.js +zekndProvider <a href="#configuring-and-running-web3-js-loomprovider" id="configuring-and-running-web3-js-loomprovider"></a>

#### #Download and Install <a href="#download-and-install-2" id="download-and-install-2"></a>

Install `Web3.js`latest version using `npm`:

```
npm install web3 --save
# or
yarn add web3
```

Install zeknd`-js` which includes zeknd`Provider`:

```
npm install zeknd-js --save
# or
yarn add zeknd-js
```

#### #Adding to project and configuring <a href="#adding-to-project-and-configuring" id="adding-to-project-and-configuring"></a>

To add `Web3.js` to a Node.js project is fairly simple:

```
// Node.JS 8 or greater
const Web3 = require('web3')

// Webpack with ES2016 support
import Web3 from 'web3'
```

> If you're using webpack, the process should be similar.

The next step is to configure the zeknd`Provider`:

```
const privateKey = CryptoUtils.generatePrivateKey()
const publicKey = CryptoUtils.publicKeyFromPrivateKey(privateKey)

// Create the client
const client = new Client(
  'default',
  'ws://127.0.0.1:46658/websocket',
  'ws://127.0.0.1:46658/queryws',
)

// The address for the caller of the function
const from = LocalAddress.fromPublicKey(publicKey).toString()

// Instantiate web3 client using zekndProvider
const web3 = new Web3(new zekndProvider(client, privateKey))

const ABI = [{"anonymous":false,"inputs":[{"indexed":false,"name":"_value","type":"uint256"}],"name":"NewValueSet","type":"event"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]

const contractAddress = '0x...'

// Instantiate the contract and let it ready to be used
const contract = new web3.eth.Contract(ABI, contractAddress, {from})
```

#### #Running Web3 contract instance <a href="#running-web3-contract-instance" id="running-web3-contract-instance"></a>

Now, we can call `set` and `get` functions like this:

```
// Set the value 47
const tx = await contract.methods.set(47).send()

// Get the value 47
const value = await contract.methods.get().call()
```

Also, we can listen to events::

```
contract.events.NewValueSet({}, (err, event) => {
  if (err) {
    return console.error(err)
  }

  console.log('New value set', event.returnValues._value)
})
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developer.opzeknd.xyz/javascript-client-sdk/web3-zekndprovider-and-truffle.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
