ethereum

package module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 6, 2024 License: MIT Imports: 22 Imported by: 0

README

xk6-ethereum

A k6 extension to interact with EVM based blockchains.

Getting started

  1. Build or Install BlockSpeed

  2. Check the examples folder to learn how to use it

Run and visualize

You can visualize benchmark results in your local machines using the provided Grafana + InfluxDB instance:

docker-compose up -d
xk6 run --out influxdb=http://localhost:8086/blockspeed examples/multiple.js

Navigate to http://localhost:3000/d/BuduMUd4k/blockspeed?orgId=1

Build

To build a k6 binary with this plugin, first ensure you have the prerequisites:

  • Go toolchain
  • If you're using SQLite, a build toolchain for your system that includes gcc or another C compiler. On Debian and derivatives install the build-essential package. On Windows you can use tdm-gcc. Make sure that gcc is in your PATH.
  • Git

Then:

  1. Install xk6:
go install go.k6.io/xk6/cmd/xk6@latest
  1. Build the binary:
xk6 build --with github.com/distribworks/xk6-ethereum

Javascript API

Module k6/x/ethereum

The k6/x/ethereum module contains the Ethereum extension to interact with Ethereum RPC API. To import the module add

import eth from 'k6/x/ethereum';
Class eth.Client({[url, mnemonic, privateKey]})

The class Client is an Ethereum RPC client that can perform several operations to an Ethereum node. The constructor takes the following arguments:

Example:
import eth from 'k6/x/ethereum';
const client = new eth.Client({
    url: 'http://localhost:8545',
});
Methods
  • gasPrice() number
  • getBalance(address: string, blockNumber: number) number
  • blockNumber() number
  • getBlockByNumber(block: number, full: boolean) Block
  • getNonce(address: string) number
  • estimateGas(tx: Transaction) number
  • sendTransaction(tx: Transaction) string
  • sendRawTransaction(tx: Transaction) string
  • getTransactionReceipt(tx_hash: string) Receipt
  • waitForTransactionReceipt(tx_hash: string) => Promise<Receipt>
  • accounts() string[]
  • newContract(address: string, abi: string) Contract
  • deployContract(abi: string, bytecode: string, args[]) Receipt
Objects
Transaction
{
  from:        string
  to:          string
  input:       object
  gas_price:   number
  gas_fee_cap: number
  gas_tip_cap: number
  gas:         number
  value:       number
  nonce:       number
  // eip-2930 values
  chain_id: number
}
Receipt
{
  transaction_hash:    object
  transaction_index:   number
  contract_address:    string
  block_hash:          object
  from:                string
  block_number:        number
  gas_used:            number
  cumulative_gas_used: number
  logs_bloom:          object
  logs:                Log[]
  status:              number
}
Log
{
  removed:           bool
  log_index:         number
  transaction_index: number
  transaction_hash:  object
  block_hash:        object
  block_number:      number
  address:           string
  topics:            object[]
  data:              object
}
Contract{}

txn() Receipt
call() object
Metrics

It exposes the following metrics:

  • ethereum_block: Blocks in the chain during the test
  • ethereum_req_duration: Time taken to perform an API call to the client
  • ethereum_tps: Computation of Transactions Per Second mined
  • ethereum_time_to_mine: Time it took since a transaction was sent to the client and it has been included in a block
Example
import eth from 'k6/x/ethereum';

const client = new eth.Client({
    url: 'http://localhost:8545',
    // You can also specify a private key here
    // privateKey: 'private key of your account',
    // or a mnemonic
    // mnemonic: 'my mnemonic'
});

// You can use an existing premined account
const root_address = "0x85da99c8a7c2c95964c8efd687e95e632fc533d6"

export function setup() {
  return { nonce: client.getNonce(root_address) };
}

export default function (data) {
  console.log(`nonce => ${data.nonce}`);
  const gas = client.gasPrice();
  console.log(`gas price => ${gas}`);

  const bal = client.getBalance(root_address, client.blockNumber());
  console.log(`bal => ${bal}`);
  
  const tx = {
    to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF",
    value: Number(0.0001 * 1e18),
    gas_price: gas,
    nonce: data.nonce,
  };
  
  const txh = client.sendRawTransaction(tx)
  console.log("tx hash => " + txh);
  // Optional: wait for the transaction to be mined
  // const receipt = client.waitForTransactionReceipt(txh).then((receipt) => {
  //   console.log("tx block hash => " + receipt.block_hash);
  //   console.log(typeof receipt.block_number);
  // });
  data.nonce = data.nonce + 1;
}

Documentation

Overview

xk6 build --with github.com/distribworks/xk6-ethereum=.

xk6 build --with github.com/grafana/xk6-ethereum=.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func PrivateKeyToHexString added in v1.0.1

func PrivateKeyToHexString(privateKey *ecdsa.PrivateKey) string

PrivateKeyToHexString converts a go-ethereum private key to its hexadecimal string representation.

func PublicKeyToHexString added in v1.0.1

func PublicKeyToHexString(publicKey *ecdsa.PublicKey) string

PublicKeyToHexString converts a go-ethereum public key to its hexadecimal string representation.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

func (*Client) Accounts

func (c *Client) Accounts() ([]string, error)

Accounts returns a list of addresses owned by client. This endpoint is not enabled in infrastructure providers.

func (*Client) BlockNumber

func (c *Client) BlockNumber() (uint64, error)

BlockNumber returns the current block number.

func (*Client) Call

func (c *Client) Call(method string, params ...interface{}) (interface{}, error)

func (*Client) DeployContract

func (c *Client) DeployContract(abistr string, bytecode string, args ...interface{}) (*ethgo.Receipt, error)

DeployContract deploys a contract to the blockchain.

func (*Client) EstimateGas

func (c *Client) EstimateGas(tx Transaction) (uint64, error)

EstimateGas returns the estimated gas for the given transaction.

func (*Client) Exports

func (c *Client) Exports() modules.Exports

func (*Client) GasPrice

func (c *Client) GasPrice() (uint64, error)

func (*Client) GetBalance

func (c *Client) GetBalance(address string, blockNumber ethgo.BlockNumber) (uint64, error)

func (*Client) GetBlockByNumber

func (c *Client) GetBlockByNumber(number ethgo.BlockNumber, full bool) (*ethgo.Block, error)

GetBlockByNumber returns the block with the given block number.

func (*Client) GetNonce

func (c *Client) GetNonce(address string) (uint64, error)

GetNonce returns the nonce for the given address.

func (*Client) GetTransactionReceipt

func (c *Client) GetTransactionReceipt(hash string) (*ethgo.Receipt, error)

GetTransactionReceipt returns the transaction receipt for the given transaction hash.

func (*Client) NewContract

func (c *Client) NewContract(address string, abistr string) (*Contract, error)

NewContract creates a new contract instance with the given ABI.

func (*Client) SendRawTransaction

func (c *Client) SendRawTransaction(tx Transaction) (string, error)

SendRawTransaction signs and sends transaction to the network.

func (*Client) SendTransaction

func (c *Client) SendTransaction(tx Transaction) (string, error)

SendTransaction sends a transaction to the network.

func (*Client) WaitForTransactionReceipt

func (c *Client) WaitForTransactionReceipt(hash string) *sobek.Promise

WaitForTransactionReceipt waits for the transaction receipt for the given transaction hash.

type Contract

type Contract struct {
	*contract.Contract
	// contains filtered or unexported fields
}

Contract exposes a contract

func (*Contract) Call

func (c *Contract) Call(method string, args ...interface{}) (map[string]interface{}, error)

Call executes a call on the contract

func (*Contract) Txn

func (c *Contract) Txn(method string, opts TxnOpts, args ...interface{}) (string, error)

Txn executes a transactions on the contract and waits for it to be mined TODO maybe use promise

type EthRoot

type EthRoot struct{}

EthRoot is the root module

func (*EthRoot) NewModuleInstance

func (*EthRoot) NewModuleInstance(vu modules.VU) modules.Instance

NewModuleInstance implements the modules.Module interface returning a new instance for each VU.

type Key

type Key struct {
	PrivateKey string
	Address    string
}

type ModuleInstance

type ModuleInstance struct {
	// contains filtered or unexported fields
}

func (*ModuleInstance) Exports

func (mi *ModuleInstance) Exports() modules.Exports

Exports implements the modules.Instance interface and returns the exported types for the JS module.

func (*ModuleInstance) NewClient

func (mi *ModuleInstance) NewClient(call sobek.ConstructorCall) *sobek.Object

type Transaction

type Transaction struct {
	From      string
	To        string
	Input     []byte
	GasPrice  uint64
	GasFeeCap uint64
	GasTipCap uint64
	Gas       uint64
	Value     int64
	Nonce     uint64
	// eip-2930 values
	ChainId int64
}

type TxnOpts

type TxnOpts struct {
	Value    uint64
	GasPrice uint64
	GasLimit uint64
	Nonce    uint64
}

type Wallet

type Wallet struct{}

func (*Wallet) DeriveFromMnemonicIndex added in v1.0.1

func (w *Wallet) DeriveFromMnemonicIndex(mnemonic string, index uint32) (*Key, error)

func (*Wallet) GenerateKey

func (w *Wallet) GenerateKey() (*Key, error)

GenerateKey key creates a random key

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL