/go-libra

Libra go client library with crypto verifications

Primary LanguageGoApache License 2.0Apache-2.0

go-libra

Build Status codecov Go Report Card Codacy Badge

A golang client library for Libra blockchain.

It has all cryptographic verification algorithms, including validator-signature-based consensus verification, ledger history accumulator proof, and account state sparse Merkle tree proof, etc.

Features

Compatible with testnet 2019/12/11 (commit hash 503af53ac0).

  • Data models with all necessary cryptographic verification algorithms
    • Ledger state: signature-based consensus verification
    • Ledger consistency verification: detects reset or hard-forks
    • Transaction info and event: Merkle tree accumulator proof
    • Transaction list: Merkle tree accumulator proof on a range of transactions
    • Transaction signature: ed25519 signature
    • Account state: sparse Merkle tree proof
    • Events: event list hash based on Merkle tree accumulator
  • RPC functions
    • Query account states
    • Make P2P transaction, and wait for ledger inclusion
    • Query transaction list by ledger version
    • Query account transaction by sequence number
    • Query sent or received event list by account

Installation

$ # download the code
$ go get -u github.com/the729/go-libra

$ # build example client
$ cd example/cli_client && go build

$ # see example/cli_client/README.md
$ ./cli_client a ls

Usage

Godoc reference to client package and types package.

Get account balance, cryptographically proven

package main

import (
	"context"
	"log"

	"github.com/the729/go-libra/client"
)

const (
	defaultServer    = "ac.testnet.libra.org:8000"
	trustedPeersFile = "../consensus_peers.config.toml"
)

func main() {
	c, err := client.New(defaultServer, trustedPeersFile)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	addrStr := "18b553473df736e5e363e7214bd624735ca66ac22a7048e3295c9b9b9adfc26a"
	// Parse hex string into binary address
	addr := client.MustToAddress(addrStr)

	// provenState is cryptographically proven state of account
	provenState, err := c.QueryAccountState(context.TODO(), addr)
	if err != nil {
		log.Fatal(err)
	}

	if provenState.IsNil() {
		log.Printf("Account %s does not exist at version %d.", addrStr, provenState.GetVersion())
		return
	}

	provenResource, err := c.GetLibraCoinResourceFromAccountBlob(provenState.GetAccountBlob())
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("Balance (microLibra): %d", provenResource.GetBalance())
	log.Printf("Sequence Number: %d", provenResource.GetSequenceNumber())
}

Make peer-to-peer transaction

// Get current account sequence of sender
seq, err := c.GetAccountSequenceNumber(senderAddr)
if err != nil {
	log.Fatal(err)
}

// Build a raw transaction
rawTxn, err := types.NewRawP2PTransaction(
	senderAddr, recvAddr, seq,
	amountMicro, maxGasAmount, gasUnitPrice, expiration,
)
if err != nil {
	log.Fatal(err)
}

// Sign and submit transaction
err = c.SubmitRawTransaction(context.TODO(), rawTxn, priKey)
if err != nil {
	log.Fatal(err)
}

// Wait until transaction is included in ledger, or timeout
err = c.PollSequenceUntil(context.TODO(), senderAddr, seq+1, expiration)
if err != nil {
	log.Fatal(err)
}

Other examples

Several examples are included in example folder.

Contributions are welcome