This is the official Go client library, which allows you to do the following:
- Create transactions
- Sign transactions
- Interact with an IRI node
This is beta software, so there may be performance and stability issues. Please report any issues in our issue tracker.
Table of contents |
---|
Prerequisites |
Downloading the library |
Getting started |
API reference |
Examples |
Supporting the project |
Joining the discussion |
License |
To download the IOTA Go client library and its dependencies, we recommend that you use vgo modules (since Go 1.11) to manage dependencies in your project.
To download the IOTA Go client library and its dependencies, do the following:
-
In any directory outside of GOPATH, initiate your project:
$ go mod init <your-module-path>
Note: Change the placeholder to your chosen path such as github.com/me/awesome-project.
-
Download the library:
$ go get github.com/iotaledger/iota.go/api
This command downloads the latest version of the IOTA Go client library and writes the version into
the go.mod
file (vgo is go get
agnostic).
After you've downloaded the library, you can connect to an IRI node to send transactions to it and interact with the ledger.
-
To connect to a local IRI node, do the following:
package main import ( . "github.com/iotaledger/iota.go/api" "fmt" ) var endpoint = "<node-url>" func main() { // compose a new API instance api, err := ComposeAPI(HTTPClientSettings{URI: endpoint}) must(err) nodeInfo, err := api.GetNodeInfo() must(err) fmt.Println("latest milestone index:", nodeInfo.LatestMilestoneIndex) } func must(err error) { if err != nil { panic(err) } }
For details on all available API methods, see the API folder.
As well as the following examples, you can take a look at our examples folder for more.
This example shows you how to create and send a transaction to an IRI node by calling the PrepareTransfers()
method and piping the prepared bundle to the SendTrytes()
method.
package main
import (
"fmt"
"github.com/iotaledger/iota.go/address"
. "github.com/iotaledger/iota.go/api"
"github.com/iotaledger/iota.go/bundle"
. "github.com/iotaledger/iota.go/consts"
"github.com/iotaledger/iota.go/pow"
"github.com/iotaledger/iota.go/trinary"
)
var endpoint = "<node-url>"
// must be 81 trytes long and truly random
var seed = trinary.Trytes("AAAA....")
// difficulty of the proof of work required to attach a transaction on the tangle
const mwm = 14
// how many milestones back to start the random walk from
const depth = 3
// must be 90 trytes long (with checksum)
const recipientAddress = "BBBB....."
func main() {
// get the best available PoW implementation
_, proofOfWorkFunc := pow.GetFastestProofOfWorkImpl()
// create a new API instance
api, err := ComposeAPI(HTTPClientSettings{
URI: endpoint,
// (!) if no PoWFunc is supplied, then the connected node is requested to do PoW for us
// via the AttachToTangle() API call.
LocalProofOfWorkFunc: proofOfWorkFunc,
})
must(err)
// create a transfer to the given recipient address
// optionally define a message and tag
transfers := bundle.Transfers{
{
// must be 90 trytes long (include the checksum)
Address: recipientAddress,
Value: 80,
},
}
// create inputs for the transfer
inputs := []Input{
{
// must be 90 trytes long (include the checksum)
Address: "CCCCC....",
Security: SecurityLevelMedium,
KeyIndex: 0,
Balance: 100,
},
}
// create an address for the remainder.
// in this case we will have 20 iotas as the remainder, since we spend 100 from our input
// address and only send 80 to the recipient.
remainderAddress, err := address.GenerateAddress(seed, 1, SecurityLevelMedium, true)
must(err)
// we don't need to set the security level or timestamp in the options because we supply
// the input and remainder addresses.
prepTransferOpts := PrepareTransfersOptions{Inputs: inputs, RemainderAddress: &remainderAddress}
// prepare the transfer by creating a bundle with the given transfers and inputs.
// the result are trytes ready for PoW.
trytes, err := api.PrepareTransfers(seed, transfers, prepTransferOpts)
must(err)
// you can decrease your chance of sending to a spent address by checking the address before
// broadcasting your bundle.
spent, err := api.WereAddressesSpentFrom(transfers[0].Address)
must(err)
if spent[0] {
fmt.Println("recipient address is spent from, aborting transfer")
return
}
// at this point the bundle trytes are signed.
// now we need to:
// 1. select two tips
// 2. do proof-of-work
// 3. broadcast the bundle
// 4. store the bundle
// SendTrytes() conveniently does the steps above for us.
bndl, err := api.SendTrytes(trytes, depth, mwm)
must(err)
fmt.Println("broadcasted bundle with tail tx hash: ", bundle.TailTransactionHash(bndl))
}
func must(err error) {
if err != nil {
panic(err)
}
}
If the library is compiled with CGO enabled, certain functions such as Curl's transform()
method will
run native C code for increased speed.
Certain PoW implementations are enabled if the correct flags are passed while compiling your program:
pow_avx
for AVX based PoWpow_sse
for SSE based PoWpow_c128
for C int128 based using PoWpow_arm_c128
for ARM64 int128 C based PoWpow_c
for C based PoW
PoW implementation in Go is always available.
If you want to use local PoW, make sure you define LocalProofOfWorkFunc
in your provider settings such as HTTPClientSettings
.
We thank everyone for their contributions. In order for your pull requests to be accepted, they must fulfill the following criteria:
- You must write tests for your additions with Ginkgo
- You must write example code that desribes the parameters and the functionality of your additions
- Your pull request must pass the continuous integration configuration
Before your pull requests can be accepted, you must test your code in Ginkgo.
-
Download Ginkgo:
$ go get github.com/onsi/ginkgo/ginkgo $ go get github.com/onsi/gomega/...
-
If you've written a new package, generate a corresponding test-suite file:
$ cd <dir-of-your-package> $ ginkgo bootstrap
-
Generate a new testing file:
$ ginkgo generate <package-name>
After creating a testing file, you'll have following two files:
- _suite_test.go
- _test.go
Note: You can use the existing tests as a reference on how to write Ginkgo tests or you can read the documentation.
- Run your tests:
$ go test -v === RUN TestAddress Running Suite: Address Suite ============================ Random Seed: 1542616006 Will run 11 of 11 specs ••••••••••• Ran 11 of 11 Specs in 0.261 seconds SUCCESS! -- 11 Passed | 0 Failed | 0 Pending | 0 Skipped --- PASS: TestAddress (0.26s) PASS ok github.com/iotaledger/iota.go/address 0.264s
While godoc.org gives a good enough documentation of the package already, the IOTA Foundation's documentation portal needs additional information, such as parameter description, examples and so on.
-
If non existent, add a
.examples
directory in your newly created package -
Create a new file with the following convention:
<package-name>_examples_test.go
inside the.examples
directory -
Write examples in the following schema:
// i req: s, The ASCII string to convert to Trytes.
// o: Trytes, The Trytes representation of the input ASCII string.
// o: error, Returned for non ASCII string inputs.
func ExampleASCIIToTrytes() {
trytes, err := converter.ASCIIToTrytes("IOTA")
if err != nil {
// handle error
return
}
fmt.Println(trytes) // output: "SBYBCCKB"
}
Symbol | Description |
---|---|
i req | Describes a parameter to the function. |
i | Describes an optional parameter to the function. |
o | Describes a return value of the function. |
Syntax:
- For parameters:
<symbol>: <parameter_name>, <description>.
- For return values:
<symbol>: <type>, <description>.
- Example function:
Example<OriginFunctionName>
If you want to get involved in the community, need help with getting setup, have any issues related with the library or just want to discuss blockchain, distributed ledgers, and IoT with other people, feel free to join our Discord.
The MIT license can be found here.