A k6 extension to interact with EVM based blockchains.
Build or Install BlockSpeed
Check the examples folder to learn how to use it
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
To build a k6
binary with this plugin, first ensure you have the prerequisites:
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
.Then:
Install xk6
:
go install go.k6.io/xk6/cmd/xk6@latest
Build the binary:
xk6 build --with github.com/distribworks/xk6-ethereum
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';
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:
import eth from 'k6/x/ethereum';
const client = new eth.Client({
url: 'http://localhost:8545',
});
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
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
It exposes the following metrics:
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;
}