Skip to content

amolabs/amo-client-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

amo-client-go GoDoc

Reference implementation of AMO client for golang. This document is available in Korean also.

Introduction

An AMO client is any software or hardware application conforming to AMO client RPC specification, and optionally, AMO storage specification. AMO Labs provides a CLI software program as a reference implementation, but it can be usable for day-to-day workflow. This program interacts with two types of remote servers: AMO blockchain nodes and AMO storage servers. It is essential to interact with AMO blockchain nodes, but it is unnecessary to interact with AMO storage servers unless you intend to trade parcels on your own.

The purposes of this software are:

  • To provide a reference implementation for demonstrating how to interact with AMO blockchain nodes, and optionally, AMO storage services.
  • To provide a ready-to-use library for those who don't have much resources to write their own client implementation.
  • To provide a out-of-the-stock CLI program to quickly interact with AMO infrastructure services.

with the following conditions:

  • As little dependency to the AMO ABCI codes as possible (hopefully, no dependency)
  • No direct dependency to the Tendermint codes
  • No direct dependency to the Ceph or librgw codes

Installation

Install pre-compiled binary

TBA

Install from source code

Before compile and install amo-client-go, you need to install the followings:

  • git
  • make
    • For Debian or Ubuntu linux, you can install build-essential package.
    • For MacOS, you can use make from Xcode, or install GNU Make via Homebrew.
  • golang v1.13 or later (for Go Modules)
    • In some cases, you need to set GOPATH and GOBIN environment variable manually. Check these variables are set before you proceed.

You can just type go get github.com/amolabs/amo-client-go/cmd/amocli in the terminal, or do every step on your own as the following:

  • download source code from github:
mkdir -p $GOPATH/src/github.com/amolabs
cd $GOPATH/src/github.com/amolabs
git clone https://github.com/amolabs/amo-client-go
  • complie and install:
cd amo-client-go
make install

Compiled bianry will be installed in $GOPATH/bin/amocli. If your PATH environment variable contains $GOBIN, then you can just type amocli in a termianl to invoke a amo-client-go program.

Install client library

No prior installation is needed. You may use https://github.com/amolabs/amo-client-go/lib package as a golang library for your client program.

Remote servers

Since amocli is a client program, it needs remote server addresses to perform user requests. There are two types of remote servers:

  • AMO blockchain RPC node
  • AMO storage API server

AMO blockchain RPC node is any AMO blockchain node which is connected to AMO blockchain network and provides an RPC service. You can connect to any publicly available nodes or run your own dedicated node for your clients. An RPC node address is composed of an IP address and a port number. The default port number is 26657. Make sure the firewall of your network does not block this port number.

TBA: Public RPC node addresses provided by AMO Labs

AMO storage API server is an API endpoint of a storage service of your choice. There can be numerous AMO storage services and you can select your storage from them. Since there might be an availability issue, AMO Labs provides a default storage service, called AMO default storage service.

TBA: Address of default storage serivce API endpoint

Keyring protection

Any transaction sent to the blockchain should be signed with a user key. amocli utilizes keys saved in a keyring file located at $HOME/.amocli/keys/keys.json. There may be an unencrypted key in a keyring if appropriate option is given. So you need to protect this keyring. It is recommended to set a read and write permissions of this keyring file to owner-only (use mode 0600 on Linux and MacOS when using chmod command).

Usage

Structure

amocli can be used as amocli [flags] <command> [args...] or amocli [flags] <command> <subcommand> {args...} depending on command.

Commands working locally:

  • amocli [flags] version: print current amocli version
  • amocli [flags] key <subcommand>: manage keys in the local keyring

Commands working with a remote server:

  • amocli [flags] query <subcommand>: query blockchain data
  • amocli [flags] tx <subcommand>: send a signed transaction to the blockchain
  • amocli [flags] parcel <subcommand>: manage data parcels in the storage service

Global flags

Commands working with a remote server may need either --rpc or --sto flag. (In most cases, they need one of them.)

  • --rpc <ip>:<port>: used to specify remote AMO blockchain RPC node
    • status, query, tx commands
  • --sto <ip>:<port>: used to specify remote AMO storage service endpoint
    • parcel command

--json flag is used to indicate that command result should be displayed as a JSON object rather than a human-friendly format.

When you execute commands requiring a user key, you need to specify which user key should be used. If you supply a --user flag, amocli will search in the keyring for the specified user key. Otherwise, amocli will display the list of stored keys and pause for username. In case the user key is encrypted in the keyring, amocli will display a prompt message and pause for a passphrase input. This action can be suppressed if you supply a --pass flag to the command.

Version command

amocli version

Print current amocli version.

Key command

amocli key <subcommand>

Manage keys in a local keyring. amocli manages keys saved in a local keyring file. Each key is associated with a username. This username is used to differentiate between keys and increase usability, but does not have special meaning in the AMO blockchain protocol. It is just a convenience feature for a human user.

amocli key list

Print a list of stored keys in the local keyring. Output comprises of the following columns:

  • #: index in the keyring
  • username: username for this key
  • enc: encrypted(o) or not(x)
  • address: account address for this key
amocli key import <private_key> --useranme <username> [flags]

Import a private key into the local keyring. <private_key> is assumed to be a base64-encoded string. Available flags are:

  • --encrypt[=false]: store a key in an encrypted form or not (default true)
amocli key export <username>

Export a private key from the local keyring.

CAUTION: current implementation just prints a private key in a plain-text form to the terminal. So, be careful not to expose this plain-text key.

amocli key generate <username> [flags]

Generate a new key and add to the local keyring. Available flags are:

  • --seed <seed_string>: arbitrary string used as a seed when generating a private key
  • --encrypt[=false]: store a key in an encrypted form or not (default true)

CAUTION: if the seed string is exposed, anyone can generate the same key as yours. Your assets are in danger in that case. So, be careful not to expose this seed string.

amocli key remove <username>

Remove a key from the local keyring.

CAUTION: there is no backup in current implementation. So the key is lost permanently. If this is the key for the address holding some digital assets, you will lose control over these assets.

Query command

amocli query <subcommand>

Query blockchain data. All of query subcommands do not require user key.

amocli query node [flags]

Print blockchain node status.

amocli query config [flags]

Print blockchain node config.

amocli query balance <address> [flags]

Print AMO balance of an account. <address> is a HEX-encoded byte array. Account balance is displayed in two ways: in AMO unit and in mote unit. 1 AMO is equivalent to 1000000000000000000 mote. When supplied with --json flag, only mote unit is displayed as a string form. When supplied with --udc <udc_id> flag, print UDC balance of an account.

amocli query udc <udc_id> [flags]

Print general information of UDC issued on blockchain. <udc_id> is a decimal number.

amocli query lock <udc_id> <address> [flags]

Print locked UDC balance of an account. <udc_id> is a decimal number. <address> is a HEX-encoded byte array. Locked balance is displayed in two ways: in AMO unit and in mote unit. 1 AMO is equivalent to 1000000000000000000 mote. When supplied with --json flag, only mote unit is displayed as a string form.

amocli query stake <address> [flags]

Print stake info of an account. <address> is a HEX-encoded byte array. This subcommand displays a validator public key associated with a stake. When supplied with --json flag, output has the following form:

{"amount":"100000000000000000000","validator":"1A8EFD2CDD19BA884E4DA53C733F960C18845846D09B5A390F7F8F8266D57C44"}

Validator public key is displayed as hex-encoded byte array.

amocli query delegate <address> [flags]

Print delegated stake info of an account. <address> is a HEX-encoded byte array.

amocli query incentive <block_height | address> [flags]

Print incentive info of either <block_height> or <address>. Both of them can be given at the same time. <block_height> is a decimal number. <address> is a HEX-encoded byte array.

amocli query draft <draft_id> [flags]

Print proposed draft status. <draft_id> is a decimal number.

amocli query vote <draft_id> <address> [flags]

Print vote status of given voter address. <draft_id> is a decimal number. <address> is a HEX-encoded byte array.

amocli query storage <storage_id> [flags]

Print storage info. <storage_id> is a decimal number.

amocli query parcel <parcelID> [flags]

Print registered parcel info. <parcelID> is a HEX-encoded byte array.

amocli query request <buyer_address> <parcel_id> [flags]

Print buyer request info on a parcel. <buyer_address> and <parcel_id> are HEX-encoded byte arrays.

amocli query usage <buyer_address> <parcel_id> [flags]

Print granted usage info on a parcel. <buyer_address> and <parcel_id> are HEX-encoded byte arrays.

Tx command

amocli tx <subcommand>

Send a signed transaction to the blockchain. All of tx subcommands require a user key, so you may supply --user and --pass flags to indicate which key to use when signing. And this user account is assumed to be the sender of the transaction.

amocli tx transfer <address> <amount> [flags]

The sender transfers <amount> of AMO coin (in mote unit) to the account associated with <address>.

amocli tx issue <udc_id> <amount> [flags]

The sender issues <amount> of UDC coin (in mote unit) with <udc_id>.

amocli tx burn <udc_id> <amount> [flags]

The sender burns <amount> of UDC coin (in mote unit) with <udc_id>.

amocli tx lock <udc_id> <holder_address> <amount> [flags]

The sender locks <amount> of UDC coin (in mote unit) owned by <holder_address> with <udc_id>.

amocli tx stake <validator_pubkey> <amount> [flags]

The sender creates a new stake or increase an existing stake associated with the <validator_pubkey> by <amount> of AMO coin. <validator_pubkey> is a HEX-encoded or base64-encoded byte array. A user cannot have multiple stakes with different validator public keys.

Staking coins means the user wants to participate in a block production process as a validator. Every validator node(see AMO blockchain network document) has a validator key pair. Staking coins associated with a validator key requires there exists a validator node loaded with the associated validator public key. Although it is possible to stake coins with a random byte array rather than a valid validator public key or a public key of a validator node not yet running, without actual running validator node the staker will not get any reward from the block production process. It is safer to run a validator node first and stake coins for the validator.

amocli tx withdraw <amount> [flags]

The sender withdraws <amount> of AMO coin staked for the account. If the staked AMO coin reaches zero, then the stake is removed completely.

amocli tx delegate <address> <amount> [flags]

The sender delegates his/her AMO coins to other account. This account must have staked coins. A user cannot delegate coins to multiple accounts.

amocli tx retract <amount> [flags]

The sender retract coin delegation by <amount> of AMO coins.

amocli tx propose <draft_id> <config> <desc> [flags]

The sender proposes a draft containing <config> expected to get applied to blockchain configuration with <draft_id> and <desc>. <draft_id> is a decimal number. <config> is a JSON object. <desc> is a human-readable string.

amocli tx vote <draft_id> <approve> [flags]

The sender votes for or against a draft with <draft_id> and <approve>. <draft_id> is a decimal number. <approve> is a boolean value; true or false.

amocli tx setup <storage_id> <url> <registration_fee> <hosting_fee> [flags]

The sender sets up a storage with <storage_id>, <url>, <registration_fee> and <hosting_fee>. <storage_id> is a decimal number. <url> is a homepage address; ex) https://amo.foundation. <registration_fee> is a certain amount of AMO coins which parcel owner pays storage host for registring the parcel. <hosting_fee> is a certain amount of AMO coins which parcel owner pays storage host for hosting the parcel.

amocli tx close <storage_id> [flags]

The sender closes a storage with <storage_id>. <storage_id> is a decimal number.

amocli tx register <parcel_id> <key_custody> [flags]

The sender registers a data parcel having <parcel_id> to the blockchain along with owner's key custody <key_custody>. <parcel_id> and <key_custody> are HEX-encoded byte arrays. <parcel_id> must be a value acquired from AMO storage service so that buyers can locate it later. Technically, <key_custody> can be an arbitrary value, but its purpose is to store owner's encryption key in a secure manner. So, it should be a data decryption key(DEK) encrypted by the owner's public key. The DEK is the key used to encrypt a data parcel body when uploading to one of AMO storage service.

amocli tx request <parcel_id> <amount> [flags]

The sender requests a data parcel <parcel_id> to the owner pledging he/she would pay <amount> of AMO coins as a data price. <amount> of AMO coins will be subtracted from the sender's account and it will be locked with the data parcel request in the blockchain.

amocli tx grant <parcel_id> <address> <key_custody> [flags]

The sender grant a usage on a data parcel <parcel_id> to an account <address> along with buyer's key custody <key_custody>. The buyer can query blockchain to acquire his/her encryption key later. Technically, <key_custody> can be an arbitrary value, but its purpose is to store buyer's encryption key in a secure manner. So, it should be a data encryption key(DEK) encrypted by the buyer's public key.

amocli tx discard <parcel_id> [flags]

The sender discard a data parcel <parcel_id> from the blockchain. After this, any buyer cannot download the data parcel from an AMO storage service.

amocli tx cancel <parcel_id> [flags]

The sender cancel a data parcel request sent from the sender and remove it from the blockchain. The pledged AMO coins will be refunded to the sender.

amocli tx revoke <parcel_id> <address> [flags]

The sender revoke a granted usage on a data parcel <parcel_id> to an account <address>. After this, the account <address> cannot download the data parcel from an AMO storage service.

Parcel command

amocli parcel <subcommand>

Manage data parcels in the storage service. Subcommands upload, download and remove require a user key, so you may supply --user and --pass flags to indicate which key to use when signing. And this user account is assumed to be the sender of the AMO storage API request.

amocli parcel upload {<hex> | --file <filename>} [flags]

The sender uploads a new data parcel to an AMO storage service. The sender will be designated as the owner of the uploaded data parcel. An AMO storage service will respond with a parcel id newly generated by the uploaded data. There are two ways to specify data to be uploaded: specify HEX-encoded byte array directly, or specify filename to be read. This is a client-side feature, and a server always receives HEX-encoded byte array as the data body.

amocli parcel download <parcelID> [flags]

The sender downloads a data parcel <parcelID> form an AMO storage service. If the owner of the data parcel have granted a usage on the data parcel to the sender, the server will respond with a data parcel body and metadata. Otherwise, the server will respond with an error. An owner of a data parcel can grant a data parcel usage using amocli tx grant command.

amocli parcel inspect <parcelID> [flags]

The sender downlaods a metadata of a data parcel <parcelID> from an AMO storage service. This command does not require any permission from the owner of the data parcel. It will always succeed if the parcel exists on the storage server.

amocli parcel remove <parcelID> [flags]

The sender removes a data parcel <parcelID> from an AMO storage service. The sender must be the owner the data parcel.

Lib

AMO blockchain RPC

https://godoc.org/github.com/amolabs/amo-client-go/lib/rpc

AMO blockchain is based on Tendermint. Client supports basic Tendermint RPCs.

rpc.NodeStatus()
rpc.BroadcastTx(tx)
rpc.ABCIQuery(path, queryData)

Client also provides wrapper of above functions for AMO blockchain specific RPCs

// Key is needed for signing transaction
// Transaction definition 
// https://github.com/amolabs/docs/blob/master/protocol.md

// Bank
rpc.Transfer(...)
// Stake
rpc.Stake(...)
// Governance
rpc.Propose(...)
// Parcel
rpc.Register(...)
// UDC
rpc.Issue(...)

// Return types of ABCI Query are defined in AMO blockchain RPC document
// https://github.com/amolabs/docs/blob/master/rpc.md#abci-query
// ABCI Query
rpc.QueryBalance(0, address)   // Query AMO of address
rpc.QueryBalance(udc, address) // Query UDC of address

AMO Storage

  • TODO