> For the complete documentation index, see [llms.txt](https://developer.opzeknd.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.opzeknd.xyz/go-contract-sdk/building-dappchain-clients.md).

# 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.
