Go
Here are the articles in this section:
Instantiating the SDK provider
Creating, signing and broadcasting transactions
Deploy and invoke smart contracts
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 type | Encoder type prefix |
---|---|
int8 | i8 , I8 |
int16 | i16 , I16 |
int32 | i32 , I32 |
int64 | i64 , I64 |
uint8 | u8 , U8 |
uint16 | u16 , U16 |
uint32 | u32 , U32 |
uint64 | u64 , U64 |
*big.Int, BigUint(rust sdk) | BigInt , bigint , BigUint , biguint , bi , n , BI , N |
ManagedAddress | Address , address , a , A |
BigFloat | BigFloat , bigfloat , bf , BF , f , F |
ManagedBuffer | ManagedBuffer , managedbuffer |
TokenIdentifer | TokenIdentifer , tokenidentifier |
String | string , String |
Boolean | bool , boolean , b , B |
Empty argument | empty , 0 , e , E |