Skip to content

Instantly share code, notes, and snippets.

@g1ibby
Created October 27, 2020 09:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save g1ibby/42fe1b7dd2e478d467b5ea192a05d1fe to your computer and use it in GitHub Desktop.
Save g1ibby/42fe1b7dd2e478d467b5ea192a05d1fe to your computer and use it in GitHub Desktop.
Base functions for working with the ethereum network
package activity
import (
"context"
"crypto/ecdsa"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/powerman/structlog"
)
var log = structlog.New()
var gasLimit = uint64(21000)
type Activity struct {
client *ethclient.Client
}
func New(c *ethclient.Client) *Activity {
return &Activity{client: c}
}
func (a *Activity) LatestBlock() (*Block, error) {
header, _ := a.client.HeaderByNumber(context.Background(), nil)
blockNumber := big.NewInt(header.Number.Int64())
block, err := a.client.BlockByNumber(context.Background(), blockNumber)
if err != nil {
return nil, err
}
_block := &Block{
BlockNumber: block.Number().Int64(),
Timestamp: block.Time(),
Difficulty: block.Difficulty().Uint64(),
Hash: block.Hash().String(),
TransactionsCount: len(block.Transactions()),
Transactions: []Transaction{},
}
for _, tx := range block.Transactions() {
_block.Transactions = append(_block.Transactions, Transaction{
Hash: tx.Hash().String(),
Value: tx.Value().String(),
Gas: tx.Gas(),
GasPrice: tx.GasPrice().Uint64(),
Nonce: tx.Nonce(),
To: tx.To().String(),
})
}
return _block, nil
}
func (a *Activity) GetAddressBalance(address string) (*Balance, error) {
account := common.HexToAddress(address)
balance, err := a.client.BalanceAt(context.Background(), account, nil)
if err != nil {
return nil, err
}
return &Balance{
Address: address,
Balance: balance.String(),
Symbol: "Ether",
Units: "Wei",
}, nil
}
func (a *Activity) TransferEth(privKey string, to string, amount int64) (*common.Hash, error) {
privateKey, err := crypto.HexToECDSA(privKey)
if err != nil {
return nil, err
}
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
return nil, err
}
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
nonce, err := a.client.PendingNonceAt(context.Background(), fromAddress)
if err != nil {
return nil, err
}
value := big.NewInt(amount * 1000000000000000000) // in wei (1 eth)
gasLimit := uint64(21000) // in units
gasPrice, err := a.client.SuggestGasPrice(context.Background())
if err != nil {
return nil, err
}
toAddress := common.HexToAddress(to)
var data []byte
tx := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data)
chainID, err := a.client.NetworkID(context.Background())
if err != nil {
return nil, err
}
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
if err != nil {
return nil, err
}
err = a.client.SendTransaction(context.Background(), signedTx)
if err != nil {
return nil, err
}
hash := signedTx.Hash()
return &hash, nil
}
func (a *Activity) GetTxByHash(hash common.Hash) (*Transaction, error) {
tx, pending, err := a.client.TransactionByHash(context.Background(), hash)
if err != nil {
return nil, err
}
return &Transaction{
Hash: tx.Hash().String(),
Value: tx.Value().String(),
Gas: tx.Gas(),
GasPrice: tx.GasPrice().Uint64(),
To: tx.To().String(),
Pending: pending,
Nonce: tx.Nonce(),
}, nil
}
client, err := ethclient.Dial("http://localhost:7545")
if err != nil {
log.Fatal(err)
}
a := activity.New(client)
block, err := a.LatestBlock()
if err != nil {
log.Fatal(err)
}
log.Debug("LatestBlock", "block", string(must.MarshalJSON(block)))
balance, err := a.GetAddressBalance(ac1Addr)
if err != nil {
log.Fatal(err)
}
log.Debug("GetAddressBalance", "balance", string(must.MarshalJSON(balance)))
// Send transaction from ac1 to ac2 1eth
txHash, err := a.TransferEth(ac1Key, ac2Addr, 1)
if err != nil {
log.Fatal(err)
}
log.Debug("TransferEth", "txHash", txHash.String())
// get transaction by txHash
tx, err := a.GetTxByHash(*txHash)
if err != nil {
log.Fatal(err)
}
log.Debug("GetTxByHash", "tx", string(must.MarshalJSON(tx)))
package activity
import (
"crypto/ecdsa"
"math/big"
"github.com/ethereum/go-ethereum/common"
)
// Block data structure
type Block struct {
BlockNumber int64 `json:"blockNumber"`
Timestamp uint64 `json:"timestamp"`
Difficulty uint64 `json:"difficulty"`
Hash string `json:"hash"`
TransactionsCount int `json:"transactionsCount"`
Transactions []Transaction `json:"transactions"`
}
// Transaction data structure
type Transaction struct {
Hash string `json:"hash"`
Value string `json:"value"`
Gas uint64 `json:"gas"`
GasPrice uint64 `json:"gasPrice"`
Nonce uint64 `json:"nonce"`
To string `json:"to"`
Pending bool `json:"pending"`
}
// TransferEthRequest data structure
type TransferEthRequest struct {
PrivKey string `json:"privKey"`
To string `json:"to"`
Amount int64 `json:"amount"`
}
// HashResponse data structure
type HashResponse struct {
Hash string `json:"hash"`
}
type Balance struct {
Address string `json:"address"`
Balance string `json:"balance"`
Symbol string `json:"symbol"`
Units string `json:"units"`
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment