Go

Here are the articles in this section:

Quick start guide

Breakdown of the start guide

Instantiating the SDK provider

Handling wallet and account

Creating, signing and broadcasting transactions

Deploy and invoke smart contracts

Encoding smart contract types

Quick start guide

Common flow example using our Go SDK:

package main

import (
	"fmt"
	"time"

	"github.com/klever-io/klever-go-sdk/core/wallet"
	"github.com/klever-io/klever-go-sdk/provider"
	"github.com/klever-io/klever-go-sdk/provider/network"
	"github.com/klever-io/klever-go-sdk/provider/utils"
)

func main() {
	/////////////////////////////////////////////////////////
	////////// Setup to connect to the kleverchain //////////
	/////////////////////////////////////////////////////////

	// Utility to create a network configuration
	net := network.NewNetworkConfig(network.TestNet)

	// Utility to create a http client plug and playh to interact with the kleverchain
	hc := utils.NewHttpClient(10 * time.Second)

	// Instantiates a new provider to interact with the kleverchain with specific network configuration and http client
	kc, err := provider.NewKleverChain(net, hc)
	if err != nil {
		panic(err)
	}

	/////////////////////////////////////////////////////////
	// Preparing user account to interact with Kleverchain //
	/////////////////////////////////////////////////////////

	// Loads user wallet from mnemonic
	w, err := wallet.NewWalletFromMnemonic("my wallet mnemonic separated by spaces")
	if err != nil {
		panic(err)
	}

	// Getting account from wallet
	acc, err := w.GetAccount()
	if err != nil {
		panic(err)
	}

	// Sync account with the kleverchain
	err = acc.Sync(kc)
	if err != nil {
		panic(err)
	}

	/////////////////////////////////////////////////////////
	//// Creating, signing and broadcasting transactions ///
	/////////////////////////////////////////////////////////

	// Send (transfer) example with fee payment in some KDA instead of KLV
	// Create a base transaction
	baseTransfer := acc.NewBaseTX()

	// Set a custom kda to kdaFee field on baseTX
	baseTransfer.KdaFee = "KDA-AB12"

	// Get the transfer receiver wallet and its account address
	rw, _ := wallet.NewWalletFromPEM("./path/to/receiver/wallet.pem")
	rAcc, _ := rw.GetAccount()

	// Create the transaction
	tx, err := kc.Send(baseTransfer, rAcc.Address().Bech32(), 10, "KLV")
	if err != nil {
		panic(err)
	}

	// Sign the transaction with the sender wallet
	err = tx.Sign(w)
	if err != nil {
		panic(err)
	}

	transferHash, err := tx.Broadcast(kc)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Transfer transaction hash: %s\n", transferHash)

	// Deploy smart contract example
	baseScDeploy := acc.NewBaseTX()

	deployTx, err := kc.DeploySmartContract(
		baseScDeploy,
		"./path/to/sc/wasm/file/lottery-kda.wasm",
		true, true, true, true, "",
	)
	if err != nil {
		panic(err)
	}

	err = deployTx.Sign(w)
	if err != nil {
		panic(err)
	}

	deployHash, err := deployTx.Broadcast(kc)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Smart contract deploy hash: %s\n", deployHash)

	// Invoke smart contract example

	baseScInvoke := acc.NewBaseTX()

	timeStamp := time.Now().Unix()
	lotteryDuration := int64(120) // 120 seconds -> 2 minutes
	lotteryDeadline := fmt.Sprintf("optionu64:%d", timeStamp+lotteryDuration)
	invokeTx, err := kc.InvokeSmartContract(
		baseScInvoke,
		"klv1qqqqqqqqqqqqqy0ur5m4rtc0ntr4act4ddres5",
		"createLotteryPool",
		map[string]int64{},
		"string:demo", "tokenidentifier:KLV", "N:10000000", "E:0", lotteryDeadline, "E:0", "E:0", "E:0",
	)
	if err != nil {
		panic(err)
	}

	err = invokeTx.Sign(w)
	if err != nil {
		panic(err)
	}

	invokeHash, err := invokeTx.Broadcast(kc)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Smart contract invoke hash: %s\n", invokeHash)
}

Breakdown of the start guide

The following breakdown shows the transactios of transfer, deploy, and invoke of smart contracts. For the other transaction available in kleverchain, simply inspect the methods of the sturct returned by provider.NewKleverChain(), which we named kc in the example, and golang's typing will guide you on the required arguments.

Instantiating the SDK provider

First we instantiates a new provider to interact with the kleverchain with specific network configuration (LocalNet, MainNet, TestNet, DevNet, Custom) and http client:

	// Utility to create a network configuration
	net := network.NewNetworkConfig(network.TestNet)

	// Utility to create a http client plug and playh to interact with the kleverchain
	hc := utils.NewHttpClient(10 * time.Second)

	// Instantiates a new provider to interact with the kleverchain with specific network configuration and http client
	kc, err := provider.NewKleverChain(net, hc)
	if err != nil {
		panic(err)
	}

Handling wallet and account

Next we load the user wallet from mnemonic (or through pem file, we'll see how further) and sync the account with the kleverchain:

	// Loads user wallet from mnemonic
	w, err := wallet.NewWalletFromMnemonic("my wallet mnemonic separated by spaces")
	if err != nil {
		panic(err)
	}

	// Getting account from wallet
	acc, err := w.GetAccount()
	if err != nil {
		panic(err)
	}

	// Sync account with the kleverchain
	err = acc.Sync(kc)
	if err != nil {
		panic(err)
	}

Creating, signing and broadcasting transactions

Now we're ready to create, sign and broadcast transactions in kleverchain.

Lets begin with a simple transfer contract. Initially you must create a base transaction usign NewBaseTX(), note that is possible to customize some base transaction fields, in the example we change the asset used to pay the fee to "KDA-AB12". Then to create the transfer transaction we call it from klever chain provider, kc.Send(), then we need to pass the base transaction, bech32 address of the asset receiver, the amount and the asset ticker, but in that particular case we get the receiver address from loading its wallet from a .pem file with the method NewWalletFromPEM(), then sign and finally broadcast it on kleverchain.

	// Send (transfer) example with fee payment in some KDA instead of KLV
	// Create a base transaction
	baseTransfer := acc.NewBaseTX()

	// Set a custom kda to kdaFee field on baseTX
	baseTransfer.KdaFee = "KDA-AB12"

	// Get the transfer receiver wallet and its account address
	rw, _ := wallet.NewWalletFromPEM("./path/to/receiver/wallet.pem")
	rAcc, _ := rw.GetAccount()

	// Create the transaction
	tx, err := kc.Send(baseTransfer, rAcc.Address().Bech32(), 10, "KLV")
	if err != nil {
		panic(err)
	}

	// Sign the transaction with the sender wallet
	err = tx.Sign(w)
	if err != nil {
		panic(err)
	}

	transferHash, err := tx.Broadcast(kc)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Transfer transaction hash: %s\n", transferHash)

Deploy and invoke smart contracts

Now lets see how to deploy a lottery smart contract on kleverchain. We create a new base transaction as we did in transfer, then to the kc.DeploySmartContract() kleverchain provider method we passe the base tx, the path to the wasm file, contract boolean flags, vmType (always empty string), and then variadic arguments with its types (we'll see this later) needeb by init() function of your smart contract.

	// Deploy smart contract example
	baseScDeploy := acc.NewBaseTX()

	deployTx, err := kc.DeploySmartContract(
		baseScDeploy,
		"./path/to/sc/wasm/file/lottery-kda.wasm",
		true, true, true, true, "",
	)
	if err != nil {
		panic(err)
	}

	err = deployTx.Sign(w)
	if err != nil {
		panic(err)
	}

	deployHash, err := deployTx.Broadcast(kc)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Smart contract deploy hash: %s\n", deployHash)

As our deployed smart contract now invokes one of its functions. A new base transaction, then we format the deadline timestamp and invoke the smart contract with the kc.InvokeSmartContract() method passing the base tx, the contract address, the function name, a map of assets and its amounts, in lottery case not needed to send assets, and the variadic arguments with its types needed by the function.

	// Invoke smart contract example

	baseScInvoke := acc.NewBaseTX()

	timeStamp := time.Now().Unix()
	lotteryDuration := int64(120) // 120 seconds -> 2 minutes
	lotteryDeadline := fmt.Sprintf("optionu64:%d", timeStamp+lotteryDuration)
	invokeTx, err := kc.InvokeSmartContract(
		baseScInvoke,
		"klv1qqqqqqqqqqqqqy0ur5m4rtc0ntr4act4ddres5",
		"createLotteryPool",
		map[string]int64{},
		"string:demo", "string:KLV", "N:10000000", "E:0", lotteryDeadline, "E:0", "E:0", "E:0",
	)
	if err != nil {
		panic(err)
	}

	err = invokeTx.Sign(w)
	if err != nil {
		panic(err)
	}

	invokeHash, err := invokeTx.Broadcast(kc)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Smart contract invoke hash: %s\n", invokeHash)

Encoding smart contract types

You've noticed the syntas type:value in variadic arguments to invoke (also need in deploy in case of init receive arguments). this syntax is necessary to sdk encode correctly the values because th klever virtual machine only accepts hexadecimal inputs encoded in a specific way. bellow theres a table relating the values with encoder types.

Value typeEncoder type prefix
int8i8, I8
int16i16, I16
int32i32, I32
int64i64, I64
uint8u8, U8
uint16u16, U16
uint32u32, U32
uint64u64, U64
*big.Int, BigUint(rust sdk)BigInt, bigint, BigUint, biguint, bi, n, BI, N
ManagedAddressAddress, address, a, A
BigFloatBigFloat, bigfloat, bf, BF, f, F
ManagedBufferManagedBuffer, managedbuffer
TokenIdentiferTokenIdentifer, tokenidentifier
Stringstring, String
Booleanbool, boolean, b, B
Empty argumentempty, 0, e, E

Was this page helpful?