Flow Go SDK
Flow Go SDK allows users to interact with the Flow Access API. This allows Go code applications to send requests directly to the network. The SDK has the ability to send transactions, scripts and get information about the state of the network.
Sending a Transaction
Flow SDK exposes the method SendTransaction
to send transactions to the Flow Network.
In this example the amount of 100 FLOW tokens will be sent between the service account and the RECEIVER_ACCOUNT
.
In the prepare
phase of the transaction, the reference to the sender's vault is retrieved and the specified amount of tokens is withdrawn to a temporary vault.
In the execute
phase of the transaction, the FungibleToken.Receiver
capability is used to get access to the deposit function of the receiver's vault.
The tokens are then deposited to the receiver from the temporary vault.
/// 0xFUNGIBLE_TOKEN and 0xFLOW_TOKEN are place for the actual addresses of the contracts that differ from network to network.
import FungibleToken from 0xFUNGIBLE_TOKEN
import FlowToken from 0xFLOW_TOKEN
transaction() {
let sentVault: @FungibleToken.Vault
prepare(signer: AuthAccount) {
// Get a reference to the signer's stored vault
let vaultRef = signer.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault)
?? panic("Could not borrow reference to the owner's Vault!")
// Withdraw tokens from the signer's stored vault
self.sentVault <- vaultRef.withdraw(amount: 100)
}
execute {
// Get a reference to the recipient's Receiver
let receiverRef = getAccount(0xRECEIVER_ACCOUNT)
.getCapability(/public/flowTokenReceiver)
.borrow<&{FungibleToken.Receiver}>()
?? panic("Could not borrow receiver reference to the recipient's Vault")
// Deposit the withdrawn tokens in the recipient's receiver
receiverRef.deposit(from: <-self.sentVault)
}
}
Using the SDK the script connects to the access node using client.New(ADDRESS)
, then gets the private key and the first account key of the service account and uses it to pay and sign the transaction.
Finally, the transaction is sent.
package main
import (
"context"
"github.com/onflow/flow-go-sdk"
"github.com/onflow/flow-go-sdk/crypto"
)
var (
cadenceScript = "Cadence transaction code describing token transfer..."
serviceAccountAddress = "0xADDRESS"
serviceAccountPrivateKey = "privateKey"
)
func main() {
ctx := context.Background()
cli, err := client.New("127.0.0.1", grpc.WithInsecure())
if err != nil {
panic(err)
}
privateKey, err := crypto.DecodePrivateKeyHex(crypto.ECDSA_P256, serviceAccountPrivateKey)
if err != nil {
panic(err)
}
addr := flow.HexToAddress(serviceAccountAddress)
acc, err := cli.GetAccount(ctx, addr)
if err != nil {
panic(err)
}
accountKey := acc.Keys[0]
signer := crypto.NewInMemorySigner(privateKey, accountKey.HashAlgo)
tx := flow.NewTransaction().
SetPayer(addr).
SetProposalKey(addr, accountKey.Index, accountKey.SequenceNumber).
SetScript([]byte(cadenceScript))
err := tx.SignEnvelope(addr, accountKey.Index, signer)
if err != nil {
panic(err)
}
err := cli.SendTransaction(ctx, tx)
if err != nil {
panic(err)
}
}
Sending a Script
Flow SDK exposes the method ExecuteScriptAtLatestBlock
to execute a script on the latest block.
It also offers two more functions to execute scripts on a block at a defined height or referenced by its id: ExecuteScriptAtBlockHeight
and ExecuteScriptAtBlockID
respectively.
To get the current FLOW token balance from an account the following cadence script should be executed.
In this script the ACCOUNT
placeholder is the account address of the target balance.
import FlowToken from 0xFLOW_TOKEN
pub fun main() {
let account = getAccount(0xACCOUNT)
let balanceRef = account.getCapability<&FlowToken.Vault{FlowToken.Balance}>(/public/flowTokenBalance)
.borrow()
?? panic("Could not borrow a reference to the account balance")
return balanceRef.balance
}
To execute the script from the Go SDK first it requires to create a new connection to an access node.
This is done using client.New(ACCESS_NODE_ADDRESS)
.
With this connection the script can be executed using ExecuteScriptAtLatestBlock(CONTEXT, CADENCE_SCRIPT, ARGUMENTS)
.
package main
import (
"context"
"fmt"
"github.com/onflow/flow-go-sdk"
)
var (
cadenceScript = "Cadence script code describing retrieving token balance..."
)
func main() {
ctx := context.Background()
cli, err := client.New("127.0.0.1", grpc.WithInsecure())
if err != nil {
panic(err)
}
script := []byte(cadenceScript)
value, err := cli.ExecuteScriptAtLatestBlock(ctx, script, nil)
if err != nil {
panic(err)
}
fmt.Printf("\nValue: %s", value.String())
}