Skip to content

zabo-api/hedera-sdk-go

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

https://github.com/QuestofIranon/hedera-sdk-go.git# Hedera SDK for Go

GoDoc

This repo contains the Go SDK for interacting with the Hedera platform. Hedera is the only public distributed ledger licensed to use the Hashgraph consensus algorithm for fast, fair and secure transactions. By using any of the Hedera SDKs, developers will be empowered to build an entirely new class of decentralized applications.

Following the instructions below should help you to reach the position where you can send transactions and queries to a Hedera testnet or the Hedera mainnet.

Table of Contents


Developer Rewards

Developers who create Hedera accounts and test their applications on our testnet will be offered the opportunity to earn real mainnet (hbars) based upon that testing activity. The SDKs are intended to facilitate application development and encourage such testing. See the Hedera Account section for further details.

Developers who create Hedera accounts and test their applications on our testnet are offered the opportunity to earn real mainnet (hbars) based upon that testing activity. The SDKs are intended to facilitate application development and encourage such testing. See the Hedera Account section for further details.

Hbars:

Hbars are the native cryptocurrency that is used to pay for transactions on the Hedera platform and to secure the network from certain types of cyberattacks. They are the native platform coin needed to interact with and exchange value on Hedera.

The symbol for hbars is "" so 5 ℏ means 5 hbars

Tinybars:

Tinybars are (not surprisingly) smaller than hbars. They are used to divide hbars into smaller amounts. One hbar is equivalent to one hundred million tinybars.

The symbol for tinybars is "tℏ" so it is correct to say 1 ℏ = 100,000,000 tℏ

Important Note: The values of all fees and transfers throughout the Hedera SDKs are represented in tinybars, though the term hbars may be used for the purposes of brevity.

Architectural Overview

All Hedera SDKs are intended to provide a developer-friendly means to leverage the Hedera API, which is based on Google Protobuf. Protobuf supports code generation for a growing number of languages and is highly optimised for efficient communications. For those interesting in viewing the underlying protobuf message definitions, see the Hedera Protobuf Message Definitions repo.

Developers who wish to work in other languages are at liberty to do so, but should be aware that implementation of cryptographic key generation and manipulation is not a trivial undertaking. The source code for the cryptography libraries used by this project can be found in the Hedera SDK for Rust repository although they are compiled to C for inclusion in this project. We would recommend use of these same libraries for developers interested in adding support for other languages.

Prerequisites

Software

  • Go – version 1.11 or higher (download here).

    • Installation instructions for Go can be found here.
    • An introduction to the Go programming language can be found here.
  • Git LFS is used to assist dependency and version management, speeding up repo cloning. In the case of this project, libraries built from the Hedera SDK for Rust project are included in ./libs. It is important that Git LFS be installed before the running go get... command below.

    • Installing Git LFS on Mac OS X (using homebrew). Run the following commands from a terminal window:

      brew install git-lfs
      git lfs install
    • Installing Git LFS on Ubuntu or Debian. Run the following commands from a terminal window:

      sudo apt install git-lfs
      git lfs install
    • Installing Git LFS on Windows

      Download and run git-lfs.exe. Open your git console – under Git Bash if you installed Git through git-scm.com.

      git lfs install

Hedera Account

The Hedera Portal allows people to create a Hedera Account facilitating access to the Hedera mainnet and Hedera testnets. A Hedera Account allows entry of a testnet access code, in order to add a number of testnet (hbars) to a testnet account created (as can be seen below) using Hedera SDKs. The public key associated with a testnet account must also be associated with your Hedera account. A detailed explanation of this whole process is contained within this document.

  • In order to gain early access (before Open Access) to a Hedera testnet or the Hedera mainnet users must create a Hedera account, including full identity verification. You can do this using the Hedera Portal.
  • We want to allow devs to earn (hbars) by helping us to test our SDKs. Hedera is based in the USA, so for us to be allowed to do this under US law we need to verify your identity as a part of the account creation process.

A full explanation of the Portal, Hedera accounts, identity verification and many other topics can be found at Hedera Help. New users should head for the Getting Started section.

Hedera testnet access

A Hedera testnet provides a test environment for testing your code without having to spend "real" mainnet (hbars). Testnet hbars are akin to "monopoly money" and have no intrinsic value, but testing against testnets will help you earn real mainnet ℏ (hbars). It is worth noting that the virtual infrastructure used to provide testnets is not intended for performance testing, as the specification of nodes is not in any way equivalent to that of mainnet nodes. Further information on this topic is included within the "Testnet Performance and Throttling" section further on in these instructions.

  • Once you have your Hedera account set up, you can request access to Hedera test networks by filling out the form here.
  • Check for answers to your testnet-related questions in the Testnet Activation section on this page.
  • Please note that there is a waiting list for testnet access; please be patient. If you haven't had a response withing 10 days, reach out to to the team on discord.
  • Once you have received a testnet access code, enter it into the testnet access box and push the proceed/arrow button. You should see a message "Access code confirmed. By activating this code you will switch to testnetXXX with a starting value of 1000 hbars." Please note that these are testnet hbars and should not to be confused with mainnet hbars.
  • Pushing the "Activate and switch network" button will credit your testnet account with those testnet hbars and switch the portal to the testnet. You can switch the portal between mainnet and testnet at any time by using the drop-down at the top of the page.

Installing the Hedera SDK for Go

To clone the repo and all required dependencies, run the following command from a terminal window. Note that this command will create a files and folders from within your current folder.

Remember that the software prerequisites described above must be installed before proceeding.

go get github.com/launchbadge/hedera-sdk-go

Creating a public/private keypair for testnet use

As a general principle, it is bad practice to use your mainnet keys on a testnet. The code below shows the content of the generate_key example file. This shows how you can create new public and private keys using the Hedera SDK for Go:

package main

import (
  "fmt"
  "github.com/launchbadge/hedera-sdk-go"
)

func main() {
  secret, mnemonic := hedera.GenerateSecretKey()
  fmt.Printf("secret   = %v\n", secret)
  fmt.Printf("mnemonic = %v\n", mnemonic)

  public := secret.Public()
  fmt.Printf("public   = %v\n", public)
}
  • It can be executed from a terminal window by changing to the examples/generate_key folder and typing:
go run main.go
  • Make careful note of the 24-word mnemonic and both of the keys that are generateed. For a testnet you can copy and paste this information into a text file. For security reasons you should never do this for mainnet.

Development Environment Note

All of the commands described in these instructions can also be executed using an IDE – such as VSCode or Goland, or editors such as Atom – according to each developer's preferences and budget. Hedera has no affiliation with the companies providing these or other equivalent tools.

Throughout these instructions you'll find the phrase "Run the following command from a terminal window." Feel free to use your IDE whenever you see this – if that's how you prefer to work. Terminal is used in this document to avoid ambiguity.

Associating your public key with your Hedera testnet account

Once you have generated a public/private keypair as described above, you need to link the public key to your Hedera testnet account. To do this, return to the Hedera portal and ensure that you have the testnet selected in the drop-down at the top of the page.

You should see the box asking you to Enter your Public Key. Copy the long hex value of the public key and paste it into that textbox in the portal. Do make sure you that you select all of the characters. Click Submit.

You should briefly see an "Account Pending" message, which will be replaced with an Account ID box. You should make a note of your account ID - perhaps in the same text file where you have stored your public and private testnet keys.

All Hedera IDs consist of three numbers (int64s) separated by the "." symbol. The three numbers represent Shard number, Realm number and Account number respectively. Shards and Realms are not yet in use so expect the first two numbers to be zeros.

You should also scroll down until you see a box labelled "Network" and make a note of the Address, which will be something like testnet.hedera.com:50222. You should also take note of the Node, which represents the account ID of a node on the testnet; it will be something like 0.0.3.

Your First Hedera Application

Checking your account balance

A more complete example, which includes code fragments in this section can be found in the get_account_balance example file located in the examples folder of this repo. This simplified example is broken into bite-sized pieces here so that accompanying explanations can be seen in context alongside each fragment.

Create a new main.go file importing fmt (for Printf) and the Hedera SDK. The time package is also imported but commented here. This package will be required later in this example and can be un-commented when required by removing the preceding //.

It's also useful to create a variable oneHbar to represent the number of tinybars in one hbar:

package main

import (
  "fmt"
  //"time"
  "github.com/launchbadge/hedera-sdk-go"
)

func main() {

  oneHbar := 100000000

Create and set a myAccount variable, replacing 1234 with your own Account ID from the portal. Note that the Shard ID and Realm ID are not required at this time so they are defaulted to zero unless explicitly included. If the accountID shown in the portal is 0.0.1234 only the last number 1234 need be used. This is the account for which we will retrieve the balance.

  myAccount := hedera.AccountID{Account: 1234}

Next, you will want to establish a connection to the Hedera testnet using the Address you noted earlier from the network section shown on the Hedera portal. Make sure that the testnet address contained within the quotation marks matches the one you copied from the portal.

You should also handle any errors and defer disconnection from the tesnet to keep things clean and orderly.

  client, err := hedera.Dial("testnet.hedera.com:50222")
  if err == nil {
    defer client.Close()
  } else {
    panic(err)
  }

Once a connection has been established, you need to decide which node to send your query to. Testnets provide each developer with a single node's account ID (labelled node in the portal) in order to simplify this and limit testnet infrastructure burden. On mainnet it will be the responsibility of the application to choose a node - usually at random.

Node Account Defaults: The client.SetNode() function sets the default node account for all future transactions until changed and unless overridden. In these examples this is not strictly necessary as all of the transaction examples in this document include Node(nodeAccount). When using testnets, it is also worth noting that the SDK uses node account 0.0.3 by default – even when neither of these mechanisms is used.

The node account ID should look something like 0.0.3. Since Shard ID and Realm ID are not yet in use, they are defaulted to zero. It is the last number (in this example 3) that you should use in the following code:

  nodeAccount := hedera.AccountID{Account: 3}
  client.SetNode(nodeAccount)

It is also important to specify which account is initiating this query – known as the operator account – so that the account can be charged a small fee for the execution of this query. In order to authorise the payment of such a fee, the operator must sign the request using their private key.

Security Tip: In the get_account_balance example file located in the examples folder, the os.Getenv("OPERATOR_SECRET") function is used. This retrieves the private key from an environment variable called OPERATOR_SECRET. It is good practice to use this technique, as it avoids accidental publication of private keys when storing code in public repos or sharing them accidentally via collaboration tools. Don't forget: If someone else knows your private key, they effectively own your account! Although the impact of this is low when using testnets, it could be a very expensive mistake on mainnet. For purposes of clarity, the example below has been simplified and does not use an environment variable

Replace <my-private-key> with the private key you generated near the beginning of these instructions.

  operatorSecret, err := hedera.SecretKeyFromString("<my-private-key>")
  if err != nil {
    panic(err)
  }
  client.SetOperator(myAccount, func() hedera.SecretKey {
    return operatorSecret
  })

Again, note that the client.SetOperator() function is used to set the default operator account for subsequent transactions. This is not necessary if both Operator() and Sign() are used when creating the transaction, but is included here in order to explain both approaches.

At this point, you're ready to query your account balance. The client.Account(myAccount).Balance() constructs the request; adding .Get() executes that request. Once again, don't forget to handle possible failures.

You can the output the balance using fmt.Printf and end the program by closing the braces for func main.

For illustrative purposes, we're showing the balance in tinybars and hbars. The Hedera SDKs represent all quantities for transfers and fees as integers using tinybars. There are one hundred million (100,000,000) tinybars in one hbar.

  myBalance, err := client.Account(myAccount).Balance().Get()
  if err != nil {
    panic(err)
  }

  fmt.Printf("Account %v balance = %v tinybars\n", myAccount.Account, myBalance)
  fmt.Printf("Account %v balance = %.5f hbars\n", myAccount.Account, float64(myBalance)/float64(oneHbar))
}

You should now be able to run your first Hedera program by executing go run main.go from terminal.

If everything went according to plan you should see something like this:

Account 1234 balance = 100500005000 tinybars
Account 1234 balance = 1005.00005 hbars

Testnet performance and throttling

For the present, our testnets have been throttled, allowing a limited number of Hedera transactions per account per second. We're using virtual infrastructure to support the huge demand we have had for testnet access, and prefer to foster innovative use of these resources and discourage folks from trying to generate metrics using underspecified hardware.

If you see error messages like transaction failed the pre-check: Busy, it is likely that you are exceeding these throttling thresholds. To avoid such errors, short delays can be added. To add a one second delay, for example, use the following code between transactions or queries:

 time.Sleep(1 * time.Second)

Don't forget to remove the // comment symbols before "time" (in the import section at the beginning of the program) to gain access to the functions in the go time package. Some IDEs will automatically add missing packages when detected, so don't be surprised if you find that a new "time" line has appeared alongside //"time".

Enhance your application to check a friend's account balance

If you know the account ID of another account on your testnet – perhaps a friend or colleague – you can also check their balance.

Creating an additional testnet account

If your friends won’t share their accounts, or if you don’t have any friends, see the Create Account Example included in this repo.

If you do choose to create an account using that example, don't forget to do the following:

  1. Create a local environment variable OPERATOR_SECRET that contains your private key.
  2. Adjust the nodeAccountID variable to the ID you see in the portal.
  3. Update the testnet.hedera.com:... testnet address to the correct one.
  4. Change the operatorAccountID variable value to your own testnet account ID.
  5. Change the InitialBalance to an acceptable quantity of testnet tinybars.
  • For the purposes of this example, an Account ID of 0:0:1235 will be used for that second account. Don't forget to amend 1235 to the account number of your friend's account. If you forget to do this will you will probably see a transaction failed the pre-check: InvalidAccount message.

  • To continue with this example, add the following code into your existing func main function, just before the closing braces:

  • As mentioned above, we will add a small delay to ensure that we do not exceed testnet throttling limits. For brevity, this statement will be included without further comment in all subsequent examples. If you get an error here, you need to remove the // before "time" in the import block near the beginning of the program.

  • Before executing any transfers, you can initialise a second variable friendAccount representing the second account, query its balance and output the result.

  time.Sleep(1 * time.Second)

  friendAccount := hedera.AccountID{Account: 1235}

  friendBalance, err := client.Account(friendAccount).Balance().Get()
  if err != nil {
    panic(err)
  }

  fmt.Printf("Account %v balance = %v tinybars\n", friendAccount.Account, friendBalance)
  fmt.Printf("Account %v balance = %.5f hbars\n", friendAccount.Account, float64(friendBalance)/float64(oneHbar))
  • Run the program again by executing go run main.go from terminal.

  • You should see your balance followed by your friend's balance.

Transaction and Query Fees

Note that your balance will decrease slightly each time you execute your code. This is due to the small fees associated with each query or transaction on the Hedera platform. On a testnet, this is not all that important, but it's worth keeping on mind when using mainnet.

Next step: Transferring hbars to a friend's account

  • A transferAmount variable can be used to make the next steps more readable. In this case, we'll transfer 10 ℏ and output details of the intended transaction.
  transferAmount := int64(10 * oneHbar)
  fmt.Printf("Starting transfer of %v tinybars from Account %v to Account %v\n", transferAmount, myAccount.Account, friendAccount.Account)
  • It is worth re-stating that a secret key (also known as private key) is required in order to transfer hbars from an account. Separate signatures are required for the operator account and each Transfer line with a negative amount – even if they're the same account.

  • The next statement is a little more complex so each line is explained individually below the code.

  transaction, err := client.CryptoTransfer().
    Transfer(myAccount, -transferAmount).
    Transfer(friendAccount, transferAmount).
    Operator(myAccount).
    Node(nodeAccount).
    Memo("My first transfer of hbars! w00t!").
    Sign(operatorSecret).
    Sign(operatorSecret).
    Execute()
    if err != nil {
      panic(err)
    }

Explanation of the above code block by line number

1. transaction, err := client.CryptoTransfer(). creates a transaction to transfer hbars between accounts.

2. Transfer(myAccount, -transferAmount). sets up part of the transfer. In this case from your account. Note that the "-" (minus sign) denotes that hbars will be deducted from this account.

3. Transfer(friendAccount, transferAmount). sets up the second part of this transfer. In this case to your friend's account. A positive number indicates that this account will be incremented by the specified amount.

4. Operator(myAccount). specifies the account initiating the transaction and to which transaction fees will be charged.

5. Node(nodeAccount). indicates the node to which this transaction and associated fee payments will be sent.

6. Memo("My first transfer of hbars! w00t!"). assigns a label to the transaction of up to 100 bytes. Use of this field is at the developer's discretion and does not affect the behaviour of the plaform.

7. Sign(operatorSecret). adds a signature for the operator account. This is required as fees will be deducted from this account.

8. Sign(operatorSecret). adds a signature for the account from which hbars will de debited. In this case the operator account is the same as the account sending hbars so the same signature can be re-used.

9. Execute() executes the transaction.

If the client.SetOperator() function is used to set the default operator as illustrated above, lines 4 and 7 can be omitted. If the client.SetNode() function is used to set the default node as illustrated above, line 5 can also be omitted.

Multi-party transfers

It is possible to create a transfer transaction containing multiple to and multiple _from_accounts within that same transaction. In a case where multiple accounts were to be debited, signatures would be required for each one, and addition Sign(...). lines would be required.

Important: the sum of all amounts in Transfer(...) lines contained within in a CryptoTransfer must add up to zero.

  • The transaction is made up of the account ID and the transaction timestamp – right down to nanoseconds, which uniquely identifies it.

  • It makes sense to wait a little longer (2 seconds) after sending the transaction, so that the Hedera network can reach consensus on the transaction.

  fmt.Printf("Transfer Sent. Transaction ID is %v\n", transaction.String())

  time.Sleep(2 * time.Second)
  • To confirm that the transaction succeeded a receipt can be requested. Although this is not a mandatory step, it does verify that this transaction successfully reached network consensus.
  receipt, err := client.Transaction(transaction).Receipt().Get()
  if err != nil {
    panic(err)
  }

  if receipt.Status == hedera.StatusSuccess {
    fmt.Printf("Transaction Successful. Consensus confirmed.\n")
  } else {
    panic(fmt.Errorf("Transaction unsuccessful. Status: %v", receipt.Status.String()))
  }

  time.Sleep(1 * time.Second)
  • Finally, the balances of both accounts can be required to verify that the 10 ℏ was indeed transferred from your account to that of your friend.
  myBalance, err = client.Account(myAccount).Balance().Get()
  if err != nil {
    panic(err)
  }

  friendBalance, err = client.Account(friendAccount).Balance().Get()
  if err != nil {
    panic(err)
  }

  fmt.Printf("Account %v balance = %v tinybars\n", myAccount.Account, myBalance)
  fmt.Printf("Account %v balance = %.5f hbars\n", myAccount.Account, float64(myBalance)/float64(oneHbar))
  fmt.Printf("Account %v balance = %v tinybars\n", friendAccount.Account, friendBalance)
  fmt.Printf("Account %v balance = %.5f hbars\n", friendAccount.Account, float64(friendBalance)/float64(oneHbar))
  • Run the program again by executing go run main.go from terminal.

  • You should now see both balances prior to the transfer followed by details of the transfer including success/failure. You should then be able to see the balances of both accounts after the transfer, demonstrating that 10 ℏ has been transferred from your account to you friend's account. Hopefully it looks something like this:

Account 1234 balance = 96495305000 tinybars
Account 1234 balance = 964.95305 hbars
Account 1235 balance = 4000000000 tinybars
Account 1235 balance = 40.00000 hbars
Transfering 1000000000 tinybars from Account 1234 to Account 1235
Transfer Sent. Transaction ID is 0:0:1234@1548679850.429332000
Transaction Successful. Consensus confirmed.
Account 1234 balance = 95494805000 tinybars
Account 1234 balance = 954.94805 hbars
Account 1235 balance = 5000000000 tinybars
Account 1235 balance = 50.00000 hbars

Other resources

  • For an explanation of the underlying hashgraph algorithm, please consult our whitepaper or Dr. Leemon Baird's 52-minute Simple Explanation video.
  • Links to all Hedera news and information can be found in at Hedera Help – including Coq validation of the hashgraph ABFT algorithm.
  • 300+ Hedera interviews and videos on YouTube. Thanks to Arvydas – a Hedera MVP – for curating this list.

Deeper Development

Requirements

  • rustup

  • musl

    • Mac OS X

      brew install FiloSottile/musl-cross/musl-cross
  • MinGW

    • Mac OS X

      brew install mingw-w64

Build

./x.py

Getting in touch

Please reach out to us on the Hedera discord channels. We're fortunate to have an active community of over 5000 like-minded devs, who are passionate about our tech. The Hedera Developer Advocacy team also participates actively.

Contributing to this Project

We welcome participation from all developers! For instructions on how to contribute to this repo, please review the Contributing Guide.

License Information

Licensed under Apache License, Version 2.0 – see LICENSE in this repo or apache.org/licenses/LICENSE-2.0

Packages

No packages published

Languages

  • C 42.5%
  • Go 36.4%
  • C++ 13.5%
  • Python 7.6%