This is a light-weight golang SDK for the 2.x version of the Neo network.
Simply add this SDK to GOPATH:
go get github.com/joeqian10/neo-gogogo
This SDK has seven modules, and the structure of how these modules compose each other is shown here. For example, the "helper", "sc", "tx", "wallet" modules are all composed of "crypto" module.
classDiagram
wallet *-- crypto
wallet *-- helper
wallet *-- sc
wallet *--* tx
tx *-- crypto
tx *-- helper
tx *-- rpc
tx *-- sc
nep5 *-- helper
nep5 *-- rpc
nep5 *-- sc
sc *-- crypto
sc *-- helper
rpc *-- helper
helper *-- crypto:Â composition
This module offers methods used for cryptography purposes, such as AES encryption/decryption, Base58 encoding/decoding, Hash160/Hash256 hashing functions. For more information about the crypto algorithms used in neo, refer to Cryptography.
func AESEncrypt(src, key []byte) ([]byte, error)
func AESDecrypt(crypted, key []byte) ([]byte, error)
func Base58CheckEncode(input []byte) string
func Base58CheckDecode(input string) ([]byte, error)
func Sha256(b []byte) []byte
func Hash256(ba []byte) []byte
Hash256
gets the twice SHA-256 hash value of ba
.
func Hash160(ba []byte) []byte
Hash160
first calculates SHA-256 hash result of ba
, then calcaulates RIPEMD-160 hash of the result.
Typical usage:
package sample
import "encoding/hex"
import "github.com/joeqian10/neo-gogogo/crypto"
func SampleMethod() {
// AES encryption/decryption
src := hex.DecodeString("3b75c0cee38f1e4fa123fad71c3f3e43dc8599c9bedb3aa16e4f8b9239a6d946")
key := hex.DecodeString("e23c14a11c4ccefda68918331cbd2caf3e680d78b72e19c1fc8675b9636d0de8")
encrypted, err := crypto.AESEncrypt(xr, derivedKey2)
decrypted, err := crypto.AESDecrypt(encrypted, derivedKey2)
// Base58Check encoding/decoding
var b58CheckEncoded = "KxhEDBQyyEFymvfJD96q8stMbJMbZUb6D1PmXqBWZDU2WvbvVs9o"
var b58CheckDecodedHex = "802bfe58ab6d9fd575bdc3a624e4825dd2b375d64ac033fbc46ea79dbab4f69a3e01"
b58CheckDecoded, _ := hex.DecodeString(b58CheckDecodedHex)
encoded := crypto.Base58CheckEncode(b58CheckDecoded)
decoded, err := crypto.Base58CheckDecode(b58CheckEncoded)
// Sha256, Hash256, Hash160
b := []byte("Hello World")
s1 := crypto.Sha256(b)
s1 := crypto.Hash256(b)
s1 := crypto.Hash160(b)
...
}
As its name indicated, this module acts as a helper and provides some standard data types used in neo, such as Fixed8
, UInt160
, UInt256
, and some auxiliary methods with basic functionalities including conversion between a hex string and a byte array, conversion between a script hash and a standard neo address, concatenating/reversing byte arrays and so on.
func NewFixed8(data int64) Fixed8
NewFixed8
returns a Fixed8 using an int64 as raw data.
func Fixed8FromInt64(val int64) Fixed8
The difference between this API and NewFixed8
is the parameter val
here will be multiplied by a constant 100000000, then become the raw value.
func Fixed8FromFloat64(val int64) Fixed8
func UInt160FromString(s string) (UInt160, error)
func UInt160FromBytes(b []byte) (u UInt160, err error)
func UInt256FromString(s string) (UInt160, error)
func UInt256FromBytes(b []byte) (u UInt160, err error)
func ReverseBytes(data []byte) []byte
func ConcatBytes(b1 []byte, b2 []byte) []byte
func BytesToHex(b []byte) string
func HexTobytes(hexstring string) (b []byte)
func ScriptHashToAddress(scriptHash UInt160) string
func AddressToScriptHash(address string) (UInt160, error)
Typical usage:
package sample
import "encoding/hex"
import "github.com/joeqian10/neo-gogogo/helper"
func SampleMethod() {
// Fixed8
f1 := helper.NewFixed8(1234567800000000)
f2 := helper.Fixed8FromInt64(12345678)
f3 := helper.Fixed8FromFloat64(12345678.0)
// f1, f2, f3 are all equal
// UInt160
hexStr := "2d3b96ae1bcc5a585e075e3b81920210dec16302"
v1, err := helper.UInt160FromString(hexStr)
b1, err := hex.DecodeString(hexStr)
v2, err := helper.UInt160FromBytes(ReverseBytes(b))
// v1 and v2 are equal
// UInt256
str := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d"
u1, err := helper.UInt256FromString(str)
b2, err := hex.DecodeString(hexStr)
u2, err := helper.UInt256FromBytes(ReverseBytes(b))
// u1 and u2 are equal
// reverse bytes
b3 := []byte{1, 2, 3}
r := helper.ReverseBytes(b3)
// concatenate bytes
b4 := []byte{4, 5, 6}
c := helper.ConcatBytes(b3, b4)
// convert byte array to hex string
s := helper.BytesToHex(b3)
// convert hex string to byte array
b5 := helper.HexToBytes(s)
// convert ScriptHash to address string
a := helper.ScriptHashToAddress(v1)
// convert address string to ScriptHash
v3, _ := helper.AddressToScriptHash(a)
...
}
This module provides structs and methods which can be used to send RPC requests to and receive RPC responses from a neo node. For more information about neo RPC API, refer to API Reference.
func NewClient(endpoint string) *RpcClient
endPoint
can be the RPC port of a MainNet, TestNet or a LocalNet neo node.
func (n *RpcClient) ClaimGas(address string) ClaimGasResponse
func (n *RpcClient) GetAccountState(address string) GetAccountStateResponse
func (n *RpcClient) GetApplicationLog(txId string) GetApplicationLogResponse
...
There are around 40 RPC APIs and they will not be all listed in this document. Please find what you need from the source code.
Typical usage:
package sample
import "github.com/joeqian10/neo-gogogo/rpc"
func SampleMethod() {
// create a rpc client
var TestNetEndPoint = "http://seed1.ngd.network:20332"
client := rpc.NewClient(TestNetEndPoint)
// get block count
r1 := client.GetBlockCount()
height := r1.Result
// get raw mempool, get all the transactions' id in this node's mempool
r2 := client.GetRawMemPool()
transactions := r2.Result
// get transaction detail by its id
r3 := client.GetRawTransaction("your transaction id string")
tx := r3.Result
// send raw transaction
r4 := client.SendRawTransaction("raw transaction hex string")
...
}
This module is mainly used to build smart contract scripts which can be run in a neo virtual machine. For more information about neo smart contract and virtual machine, refer to NeoContract and NeoVM.
func NewScriptBuilder() ScriptBuilder
func (sb *ScriptBuilder) MakeInvocationScript(scriptHash []byte, operation string, args []ContractParameter)
func (sb *ScriptBuilder) Emit(op OpCode, arg ...byte) error
func (sb *ScriptBuilder) EmitAppCall(scriptHah []byte, useTailCall bool) error
func (sb *ScriptBuilder) EmitJump(op OpCode, offset int16) error
func (sb *ScriptBuilder) EmitPushBigInt(number big.Int) error
func (sb *ScriptBuilder) EmitPushInt(number int) error
func (sb *ScriptBuilder) EmitPushBool(data bool) error
func (sb *ScriptBuilder) EmitPushBytes(data []byte) error
func (sb *ScriptBuilder) EmitPushString(data string) error
func (sb *ScriptBuilder) EmitPushParameter(data ContractParameter) error
func (sb *ScriptBuilder) EmitSysCall(api string, compress bool) error
Typical usage:
package sample
import "github.com/joeqian10/neo-gogogo/sc"
func SampleMethod() {
// create a script builder
sb := sc.NewScriptBuilder()
// make invocation script, call a specific method from a specific contract
scriptHash, _ := helper.UInt160FromString("b9d7ea3062e6aeeb3e8ad9548220c4ba1361d263")
sb.MakeInvocationScript(scriptHash.Bytes(), "name", []ContractParameter{})
bytes := sb.ToArray()
...
}
This module defines different types of transactions in the neo network and also provides structs and methods for building transactions from scratch. For more information about neo transactions, refer to Transaction.
func NewTransactionBuilder(endPoint string) *TransactionBuilder
func (tb *TransactionBuilder)MakeContractTransaction(from helper.UInt160, to helper.UInt160, assetId helper.UInt256, amount helper.Fixed8, attributes []*TransactionAttribute, changeAddress helper.UInt160, fee helper.Fixed8) (*ContractTransaction, error)
func (tb *TransactionBuilder)GetTransactionInputs(from helper.UInt160, assetId helper.UInt256, amount helper.Fixed8) ([]*CoinReference, helper.Fixed8, error)
func (tb *TransactionBuilder) GetBalance(account helper.UInt160, assetId helper.UInt256) (*models.UnspentBalance, helper.Fixed8, error)
func (tb *TransactionBuilder)MakeInvocationTransaction(script []byte, from helper.UInt160, attributes []*TransactionAttribute, changeAddress helper.UInt160, fee helper.Fixed8) (*InvocationTransaction, error)
func (tb *TransactionBuilder)GetGasConsumed(script []byte) (*helper.Fixed8, error)
func (tb *TransactionBuilder)MakeClaimTransaction(from helper.UInt160, changeAddress helper.UInt160, attributes []*TransactionAttribute) (*ClaimTransaction, error)
func (tb *TransactionBuilder)GetClaimables(from helper.UInt160) ([]*CoinReference, *helper.Fixed8, error)
Typical usage:
package sample
import "github.com/joeqian10/neo-gogogo/tx"
func SampleMethod() {
// create a transaction builder
var TestNetEndPoint = "http://seed1.ngd.network:20332"
tb := tx.NewTransactionBuilder(TestNetEndPoint)
// build a contract transaction
from, _ := helper.AddressToScriptHash("APPmjituYcgfNxjuQDy9vP73R2PmhFsYJR")
to, _ := helper.AddressToScriptHash("AdQk428wVzpkHTxc4MP5UMdsgNdrm36dyV")
assetId := NeoToken
amount := helper.Fixed8FromInt64(50000000)
ctx, _ := tb.MakeContractTransaction(from, to, assetId, amount, nil, helper.UInt160{}, helper.Fixed8FromInt64(0))
// get the raw byte array of this transaction
unsignedRaw := ctx.UnsignedRawTransaction()
...
}
This module defines the account and wallet in the neo network, and methods for creating an account or a wallet, signing a message/verifying signature with private/public key pair are also provided. For more information about the neo wallet, refer to Wallet.
func NewAccount() (*Account, error)
func NewAccountFromWIF(wif string) (*Account, error)
func NewAccountFromNep2(nep2Key, passphrase string) (*Account, error)
func NewWallet() *Wallet
func (w *Wallet) AddNewAccount() error
func (w *Wallet) ImportFromWIF(wif string) error
func (w *Wallet) ImportFromNep2Key(nep2Key, passphare string) error
func (w *Wallet) AddAccount(acc *Account)
func NewWalletHelper(txBuilder *tx.TransactionBuilder, account *Account) *WalletHelper
func (w *WalletHelper) Transfer(assetId helper.UInt256, from string, to string, amount float64) (bool, error)
func (w *WalletHelper) ClaimGas(from string) (bool, error)
func (w *WalletHelper) TransferNep5(assetId helper.UInt160, from string, to string, amount float64) (bool, error)
Typical usage:
package sample
import "github.com/joeqian10/neo-gogogo/tx"
import "github.com/joeqian10/neo-gogogo/wallet"
func SampleMethod() {
// create an account with a random generated private key
a1, err := wallet.NewAccount()
// or create an account with your own private key in WIF format
a2, err := wallet.NewAccountFromWIF("your private key in WIF format")
// or create an account with a private key encrypted in NEP-2 standard and a passphrase
a3, err := wallet.NewAccountFromNep2("your private key encrypted in NEP-2 standard", "your passphrase")
// create a new wallet
w := wallet.NewWallet()
// add a new account into the wallet
w.AddNewAccount()
// or import an account from a WIF key
w.ImportFromWIF("your account private key in WIF format")
// or import an account from a private key encrypted in NEP-2 standard and a passphrase
w.ImportFromNep2Key("your account private key encrypted in NEP-2 standard", "your account passphrase")
// or simply add an existing account
w.AddAccount(a1)
// create a WalletHelper
var TestNetEndPoint = "http://seed1.ngd.network:20332"
tb := tx.NewTransactionBuilder(TestNetEndPoint)
wh := wallet.NewWalletHelper(tb, a2)
// transfer some neo
wh.Transfer(tx.NeoToken, a2.Address, a3.Address, 80000)
// claim gas
wh.ClaimGas(a2.Address)
...
}
This module is to make life easier when dealing with NEP-5 tokens. Methods for querying basic information of a NEP-5 token, such as name, total supply, are provided. Also, it offers the ability to test run the scripts to transfer and get the balance of a NEP-5 token. For more information about NEP-5, refer to NEP-5.
func NewNep5Helper(scriptHash helper.UInt160, endPoint string) *Nep5Helper
func (n *Nep5Helper) TotalSupply() (uint64, error)
func (n *Nep5Helper) Name() (string, error)
func (n *Nep5Helper) Symbol() (string, error)
func (n *Nep5Helper) Decimals() (uint8, error)
func (n *Nep5Helper) BalanceOf(address helper.UInt160) (uint64, error)
func (n *Nep5Helper) Transfer(from helper.UInt160, to helper.UInt160, amount helper.Fixed8) (bool, []byte, error)
func (c *CgasHelper) MintTokens(from *wallet.Account, amount float64) (string, error)
func (c *CgasHelper) MintTokens(from *wallet.Account, amount float64) (string, error)
Typical usage:
package sample
import "github.com/joeqian10/neo-gogogo/nep5"
import "github.com/joeqian10/neo-gogogo/wallet"
func SampleMethod() {
// create a Nep5Helper
scriptHash, _ := helper.UInt160FromString("0xb9d7ea3062e6aeeb3e8ad9548220c4ba1361d263")
var testNetEndPoint = "http://seed1.ngd.network:20332"
nh := nep5.NewNep5Helper(scriptHash, testNetEndPoint)
// get the name of a NEP-5 token
name, err := nh.Name()
// get the total supply of a NEP-5 token
s, e := nh.TotalSupply()
// get the balance of a NEP-5 token of an address
address, _ := helper.AddressToScriptHash("AUrE5r4NHznrgvqoFAGhoUbu96PE5YeDZY")
u, e := nh.BalanceOf(address)
// test run the script for transfer a NEP-5 token
address1, _ := helper.AddressToScriptHash("AUrE5r4NHznrgvqoFAGhoUbu96PE5YeDZY")
address2, _ := helper.AddressToScriptHash("AdQk428wVzpkHTxc4MP5UMdsgNdrm36dyV")
b, e := nh.Transfer(address1, address2, 1)
...
}
Any help is welcome! Please sign off your commits and pull requests, and add proper comments.
This project is licensed under the MIT License.