Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split up SDK examples into separate docs #142

Merged
merged 10 commits into from
Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Flow GO SDK
description: Packages for Go developers to build applications that interact with the Flow network.
description: Packages for Go developers to build applications that interact with the Flow network
---
10thfloor marked this conversation as resolved.
Show resolved Hide resolved

[![GoDoc](https://godoc.org/github.com/onflow/flow-go-sdk?status.svg)](https://godoc.org/github.com/onflow/flow-go-sdk)
Expand Down
74 changes: 74 additions & 0 deletions docs/examples/creating-accounts.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
title: Creating Accounts
10thfloor marked this conversation as resolved.
Show resolved Hide resolved
10thfloor marked this conversation as resolved.
Show resolved Hide resolved
---

Once you have [generated a key pair](../generating-keys), you can create a new account
using its public key.

```go
import (
"github.com/onflow/flow-go-sdk"
"github.com/onflow/flow-go-sdk/crypto"
"github.com/onflow/flow-go-sdk/templates"
)

ctx := context.Background()

// generate a new private key for the account
// note: this is only an example, please use a secure random generator for the key seed
seed := []byte("elephant ears space cowboy octopus rodeo potato cannon pineapple")
privateKey, _ := crypto.GeneratePrivateKey(crypto.ECDSA_P256, seed)

// get the public key
publicKey := privateKey.PublicKey()

// construct an account key from the public key
accountKey := flow.NewAccountKey().
SetPublicKey(publicKey).
SetHashAlgo(crypto.SHA3_256). // pair this key with the SHA3_256 hashing algorithm
SetWeight(flow.AccountKeyWeightThreshold) // give this key full signing weight

// generate an account creation script
// this creates an account with a single public key and no code
script, _ := templates.CreateAccount([]*flow.AccountKey{accountKey}, nil)

// connect to an emulator running locally
c, err := client.New("localhost:3569")
if err != nil {
panic("failed to connect to emulator")
}

payer, payerKey, payerSigner := examples.ServiceAccount(c)

tx := flow.NewTransaction().
SetScript(script).
SetGasLimit(100).
SetProposalKey(payer, payerKey.Index, payerKey.SequenceNumber).
SetPayer(payer)

err = tx.SignEnvelope(payer, payerKey.Index, payerSigner)
if err != nil {
panic("failed to sign transaction")
}

err = c.SendTransaction(ctx, *tx)
if err != nil {
panic("failed to send transaction")
}

result, err := c.GetTransactionResult(ctx, tx.ID())
if err != nil {
panic("failed to get transaction result")
}

var myAddress flow.Address

if result.Status == flow.TransactionStatusSealed {
for _, event := range result.Events {
if event.Type == flow.EventAccountCreated {
accountCreatedEvent := flow.AccountCreatedEvent(event)
myAddress = accountCreatedEvent.Address()
}
}
}
```
44 changes: 44 additions & 0 deletions docs/examples/generating-keys.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
title: Generating Keys
---

Flow uses [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)
to control access to user accounts. Each key pair can be used in combination with
the SHA2-256 or SHA3-256 hashing algorithms.

Here's how to generate an ECDSA private key for the P-256 (secp256r1) curve:

```go
import "github.com/onflow/flow-go-sdk/crypto"

// deterministic seed phrase
// note: this is only an example, please use a secure random generator for the key seed
seed := []byte("elephant ears space cowboy octopus rodeo potato cannon pineapple")

privateKey, err := crypto.GeneratePrivateKey(crypto.ECDSA_P256, seed)
```

The private key can then be encoded as bytes (i.e. for storage):

```go
encPrivateKey := privateKey.Encode()
```

A private key has an accompanying public key:

```go
publicKey := privateKey.PublicKey()
```

### Supported Curves

The example above uses an ECDSA key pair on the P-256 (secp256r1) elliptic curve.
Flow also supports the secp256k1 curve used by Bitcoin and Ethereum.

Here's how to generate an ECDSA private key for the secp256k1 curve:

```go
privateKey, err := crypto.GeneratePrivateKey(crypto.ECDSA_secp256k1, seed)
```

Here's a full list of the supported signature and hash algorithms: [Flow Signature & Hash Algorithms](https://docs.onflow.org/concepts/accounts-and-keys.md#supported-signature--hash-algorithms)
23 changes: 23 additions & 0 deletions docs/examples/querying-accounts.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: Querying Accounts
---

You can query the state of an account with the `GetAccount` function:

```go
import "github.com/onflow/flow-go-sdk"

address := flow.HexToAddress("01")

account, err := c.GetAccount(ctx, address)
if err != nil {
panic("failed to fetch account")
}
```

A `flow.Account` contains the following fields:

- `Address: flow.Address` - The account address.
- `Balance: uint64` - The account balance.
- `Code: []byte` - The code deployed at this account.
- `Keys: []flow.AccountKey` - A list of the public keys associated with this account.
60 changes: 60 additions & 0 deletions docs/examples/querying-blocks.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
title: Querying Blocks
---

You can use the `GetLatestBlock` method to fetch the latest sealed or unsealed block:

```go
// fetch the latest sealed block
isSealed := true
latestBlock, err := c.GetLatestBlock(ctx, isSealed)
if err != nil {
panic("failed to fetch latest sealed block")
}

// fetch the latest unsealed block
isSealed := false
latestBlock, err := c.GetLatestBlock(ctx, isSealed)
if err != nil {
panic("failed to fetch latest unsealed block")
}
```

A block contains the following fields:

- `ID` - The ID (hash) of the block.
- `ParentBlockID` - The ID of the previous block in the chain.
- `Height` - The height of the block in the chain.
- `CollectionGuarantees` - The list of collections included in the block.

## Executing a Script

You can use the `ExecuteScriptAtLatestBlock` method to execute a read-only script against the latest sealed execution state.

This functionality can be used to read state from the blockchain.

Scripts must be in the following form:

- A single `main` function with a single return value

This is an example of a valid script:

```
fun main(): Int { return 1 }
```

```go
import "github.com/onflow/cadence"

script := []byte("fun main(): Int { return 1 }")

value, err := c.ExecuteScript(ctx, script)
if err != nil {
panic("failed to execute script")
}

ID := value.(cadence.Int)

// convert to Go int type
myID := ID.Int()
```
53 changes: 53 additions & 0 deletions docs/examples/querying-events.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: Querying Events
---

You can query events with the `GetEventsForHeightRange` function:

```go
import "github.com/onflow/flow-go-sdk/client"

blocks, err := c.GetEventsForHeightRange(ctx, client.EventRangeQuery{
Type: "flow.AccountCreated",
StartHeight: 10,
EndHeight: 15,
})
if err != nil {
panic("failed to query events")
}
```

### Event Query Format

An event query includes the following fields:

**Type**

The event type to filter by. Event types are namespaced by the account and contract in which they are declared.

For example, a `Transfer` event that was defined in the `Token` contract deployed at account `0x55555555555555555555` will have a type of `A.0x55555555555555555555.Token.Transfer`.

Read the [language documentation](https://docs.onflow.org/cadence/language/events/) for more information on how to define and emit events in Cadence.

**StartHeight, EndHeight**

The blocks to filter by. Events will be returned from blocks in the range `StartHeight` to `EndHeight`, inclusive.

### Event Results

The `GetEventsForHeightRange` function returns events grouped by block. Each block contains a list of events matching the query in order of execution.

```go
for _, block := range blocks {
fmt.Printf("Events for block %s:\n", block.BlockID)
for _, event := range block.Events {
fmt.Printf(" - %s", event)
}
}
```

<!--
### Decoding an Event

TODO: example for event decoding
-->
34 changes: 34 additions & 0 deletions docs/examples/querying-transactions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: Querying Transaction Results
---

After you have submitted a transaction, you can query its status by ID:

```go
result, err := c.GetTransactionResult(ctx, tx.ID())
if err != nil {
panic("failed to fetch transaction result")
}
```

The result includes a `Status` field that will be one of the following values:

- `UNKNOWN` - The transaction has not yet been seen by the network.
- `PENDING` - The transaction has not yet been included in a block.
- `FINALIZED` - The transaction has been included in a block.
- `EXECUTED` - The transaction has been executed but the result has not yet been sealed.
- `SEALED` - The transaction has been executed and the result is sealed in a block.

```go
if result.Status == flow.TransactionStatusSealed {
fmt.Println("Transaction is sealed!")
}
```

The result also contains an `Error` that holds the error information for a failed transaction.

```go
if result.Error != nil {
fmt.Printf("Transaction failed with error: %v\n", result.Error)
}
```
22 changes: 22 additions & 0 deletions docs/examples/sending-transactions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: Sending Transactions
---

You can submit a transaction to the network using the Access API client.

```go
import "github.com/onflow/flow-go-sdk/client"

// connect to an emulator running locally
c, err := client.New("localhost:3569")
if err != nil {
panic("failed to connect to emulator")
}

ctx := context.Background()

err = c.SendTransaction(ctx, tx)
if err != nil {
panic("failed to send transaction")
}
```
Loading