# Building DAppChain Clients

### &#x20;Overview <a href="#overview" id="overview"></a>

The `go-zeknd` library contains everything you need to build Go apps & services that interact with `zeknd` DAppChains, and to build the smart contracts that live on those DAppChains.

To get started, install `go-zeknd` by running the following command:

```
go get github.com/zekndnetwork/go-zeknd
```

In this section, you'll be introduced to the `go-zeknd` API that you will use to write Go code that interacts with a `zeknd` DAppChain. Writing smart contracts in Go will be covered in a later section.

In the `go-zeknd` package you will find a number of examples. `examples/cli` contains a CLI app that can be used to interact with the `examples/plugins/helloworld` smart contract. We'll start by building and test driving the CLI app, then we'll introduce you to the `go-zeknd` API that was used to build it.

Let's start by generating the `./example-cli` executable:

```
make example-cli
```

### #Example CLI app <a href="#example-cli-app" id="example-cli-app"></a>

The helloworld smart contract has a public `SetMsg` method that can be called to store an association between a key and a value:

```
./example-cli call set_msg -k 123 -v 456 --contract [contract_name] -p [priv_key]
```

The smart contract also has a public read-only `GetMsg` method that can be called to look up an association between a key and a value:

```
./example-cli call get_msg -k 123 -p [priv_key]
```

You should see the following response:

```
{
  Key: '123',
  Value: '456'
}
```

And that concludes our demonstration of the functionality of the example CLI app. Now it's time to take a look at the parts of the `go-zeknd` API that were used to implement it.

### #Connecting to a DAppChain <a href="#connecting-to-a-dappchain" id="connecting-to-a-dappchain"></a>

The `client.Contract` type provides a convenient way to interact with a smart contract running on a `zeknd` DAppChain. Let's write a function that creates a `client.Contract` instance to interact with the sample helloworld smart contract from the `zeknd` SDK:

```
package main

import (
  "github.com/zekndnetwork/go-zeknd/auth"
  "github.com/zekndnetwork/go-zeknd/client"
  "github.com/zekndnetwork/go-zeknd/examples/types"
  "golang.org/x/crypto/ed25519"
)

// getContract creates a new `Contract` instance that can be used to interact with a smart contract.
func getContract(contractName string) (*client.Contract, error) {
  rpcClient := client.NewDAppChainRPCClient(
    "default",
    "http://localhost:46658/rpc",
    "http://localhost:46658/query",
  )
  contractAddr, err := rpcClient.Resolve(contractName)
  if err != nil {
    return nil, err
  }
  return client.NewContract(rpcClient, contractAddr.Local), nil
}
```

### #Writing data to a DAppChain <a href="#writing-data-to-a-dappchain" id="writing-data-to-a-dappchain"></a>

To mutate the state of a smart contract you need to call one of its public methods. To do so, a signed transaction must be sent to and validated by the DAppChain. Fortunately, the `client.Contract` type takes care of most of this when you use the `Contract.Call()` method.

The helloworld smart contract has a public `SetMsg` method that can be called to store an association between a key and a value. Let's write a function that calls this method:

```
func store(contract *client.Contract, key, value string, signer auth.Signer) error {
  params := types.MapEntry{
    Key: key,
    Value: value,
  }
  if _, err := contract.Call("SetMsg", &params, signer, nil); err != nil {
    return err
  }
  return nil
}

```

### #Reading data from a DAppChain <a href="#reading-data-from-a-dappchain" id="reading-data-from-a-dappchain"></a>

To read the state of a smart contract you need to call one of its public read-only methods, you can do so by using the `Contract.StaticCall()` method.

The helloworld smart contract has a public `GetMsg` method that can be called to look up an association between a key and a value. Let's write a function that calls this method:

```
func load(contract *client.Contract, key string) (string, error) {
  params := types.MapEntry{
    Key: key, // The smart contract will look up the value stored under this key.
  }
  var result types.MapEntry
  if _, err := contract.StaticCall("GetMsg", &params, contract.Address, &result); err != nil {
    return "", err
  }
  return result.Value, nil
}
```

### #Putting it all together <a href="#putting-it-all-together" id="putting-it-all-together"></a>

Now that we have all the pieces in place make sure that you have the DAppChain running. Then, run the following code:

```
func main() {
  _, privateKey, err := ed25519.GenerateKey(nil)
  if err != nil {
    panic(err)
  }
  signer := auth.NewEd25519Signer(privateKey)
  contract, err := getContract("helloworld")
  if err != nil {
    panic(err)
  }
  store(contract, "123", "hello!", signer)
  value, err := load(contract, "123")
  if err != nil {
    panic(err)
  }
  fmt.Printf("Value: %s\n", value)
}
```

You should see `Value: hello!` printed to the console.


---

# 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/go-contract-sdk/building-dappchain-clients.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.
