Net::Ethereum
Raku interface for Ethereum blockchain
A Raku interface for interacting with the Ethereum blockchain and ecosystem via JSON RPC API.
Synopsys
Quick start: compile and deploy new contract
#!/usr/bin/env raku
use Net::Ethereum;
my $ne = Net::Ethereum.new(
:api_url('http://127.0.0.1:8501'),
:show_progress(True),
:unlockpwd('ospasswd'),
);
my %h = $ne.compile_and_deploy_contract(
:contract_path('./sample.sol'),
:compile_output_path('./compile'), # will be created automatically if it does not exist
);
%h.gist.say;Net::Ethereum class attributes
api_url- URL of Ethereum node RPC server (http://127.0.0.1:8501 by default, public mutable);abi- contents of .abi file generated by solidity compiler (public mutable);contract_id- contract address (e.g. 0xb3abfa488058dba76206071b3600ae6e0dec3205, public mutable);tx_wait_sec- methodwait_for_transaction()waits for transactions to be mined in iterations, each iteration sleeping for$!tx_wait_secseconds ([+Ā 15Ā +] by default).tx_wait_iters- maximum number of iterations forwait_for_transaction()([+Ā 20Ā +] by default).keepalive- set to [+Ā TrueĀ +] if you want to reuse HTTP connections when the underlying HTTP client supports it ([-Ā FalseĀ -] by default);solidity- path to solidity compiler (/usr/local/bin/solcby default);conn_name- connection name used by theHTTP::UserAgentbackend when keep-alive is enabled; for the defaultHTTP::Tinybackend this is ignored ([+Ā local-ethereum-nodeĀ +] by default);debug- debugging flag ([-Ā FalseĀ -] by default);return_raw_data- this flag enables including of raw data to Hash returned byunmarshal()method (it's useful while debugging);show_progress- if this flag is set you will see textual progress bar while transaction acceptance waiting ([-Ā FalseĀ -] by default);cleanup- this flag enables cleanup aftercompile_and_deploy_contract()method: unlink .abi and .bin files ([+Ā TrueĀ +] by default);unlockpwd- password for account unlocking, this attribute is immutable and could be set in constructor;evmver- EVM code name to be used as a command line arg to Solidity compilersolc, ([+ paris +] by default);max_fee_per_gas_multiplier- additional multiplier to be applied on max fee per gas calculation, useful if you want to increase/decrease the fee ([+ 2.1 +] by default);max_fee_per_blob_multiplier- additional multiplier to be applied on max fee per blob calculation ([+ 1.1 +] by default);legacy_ua- switch betweenHTTP::TinyandHTTP::UserAgentbackends ([-Ā FalseĀ -] by default, means thatHTTP::Tinyis used);
Fee and gas handling
Net::Ethereum derives fee data from the node and falls back gracefully on older or partially featured nodes:
eth_gasPriceis always queried and exposed asgasPrice.If the latest block exposes
baseFeePerGas(EIP-1559):maxPriorityFeePerGasdefaults to the result ofeth_maxPriorityFeePerGas(or an internal default).maxFeePerGasis computed frombaseFeePerGas,maxPriorityFeePerGas, andmax_fee_per_gas_multiplier.
If
baseFeePerGasis missing (legacy/pre-EIP-1559 nodes):The module falls back to
gasPriceformaxFeePerGaswhile still computing a reasonablemaxPriorityFeePerGas.
If blob gas fields (
excessBlobGas,blobGasUsed) are present:get_base_fee_per_blob_gasandmax_fee_per_blob_multiplierare used to computebaseFeePerBlobGasandmaxFeePerBlobGas.
See get_fee_data and get_base_fee_per_blob_gas in lib/Net/Ethereum.rakumod for details.
HTTP transport
All JSON-RPC calls in Net::Ethereum go through a small HTTP client abstraction (Net::Ethereum::HTTP::Client):
By default,
Net::EthereumusesNet::Ethereum::HTTP::Client::Tiny, which is built onHTTP::Tinyand supports connection reuse via standardConnection: Keep-Aliveheaders.For legacy setups you can supply a
Net::Ethereum::HTTP::Client::UserAgentinstance, which wrapsHTTP::UserAgentand preserves the olderconn_name-based keep-alive semantics.
In normal usage you do not need to configure this explicitly; Net::Ethereum.new constructs a suitable HTTP client for you.
Dependencies and compatibility
This module is tested primarily against a Rakudo 6.d toolchain with the following Raku dependencies (declared in META6.json):
Node::Ethereum::Keccak256::NativeJSON::FastHTTP::Tiny(default HTTP backend)Test::Mock(test-only)(Optional)
HTTP::UserAgent:ver<1.1.58+>,HTTP::Request:ver<1.1.58+>,HTTP::Cookies:ver<1.1.58+>if you use the legacyNet::Ethereum::HTTP::Client::UserAgentadapter explicitly
A typical local setup is:
zef install . # installs Net::Ethereum along with the dependencies aboveYou can also use a containerized environment (e.g. Docker) that:
Provides Rakudo and
zef.Installs this module and its dependencies (e.g. via
zef install .).Runs an Ethereum node reachable at
http://127.0.0.1:8501and/usr/local/bin/solcinside the container.
Refer to CI configuration (e.g. .gitlab-ci.yml) for an example of such an environment.
API documentation
This module was ported from Perl5 Net::Ethereum with core refactoring and breaking changes. Original Perl5 documentation could be incompatible with Raku Net::Ethereum, so feel free to report issues.
Known API differences
In Perl5 Net::Ethereum there are wait_for_contract and wait_for_transaction subroutines. Quick look for source code shows that this functions are very similar. In Raku Net::Ethereum we have one common method wait_for_transaction().
method wait_for_transaction( :@hashes!, Int :$iters?, Bool :$contract? ) returns Array { ... }Method arguments are:
@hashes- array of transaction hashes to be mined;$iters- optional timeout iterations (overrides thetx_wait_itersattribute when provided).$contract- optional boolean: True if we're waiting for contract deploy transaction, False for other transactions;
By default, the effective maximum wait time is:
tx_wait_itersĆtx_wait_sec=20 Ć 15 = 300seconds (5 minutes).
Running tests from test-bundle
Tests from test-bundle are rather adjustable and full function testing is available if:
ethereum node is running and available at http://127.0.0.1:8501;
solidity compiler is installed, working properly and available at
/usr/local/bin/solc;
If your node running on different port, use helper-script hooks/forward.sh for quick forwarding:
./hooks/forward.sh 8501 <your_actual_node_port>Environment
You should set contract transaction hash at global env variable TXHASH:
export TXHASH=0x244409bb2cced62a2b93b2688167438ef47f60f1b5aa8b6c64e9de460ddec604Run tests
Test could be ran with prove or prove6:
prove6 ./tprove -ve 'raku -Ilib'Author
Please contact me via Matrix or LinkedIn. Your feedback is welcome at narkhov.pro.
Perl5 Net::Ethereum