Package: chainlib
chainlibOverviewChainlib is an attempt at employing a universal interface to manipulate
and access blockchains regardless of underlying architecture.It makes the following assumptions:A block MUST have a interpretable serializable format, and contains
zero of more transactionsA transaction MUST have a interpretable serializable formatA transaction MUST have a nonce associated with a sender address. This
uniquely identifies the transaction on the network.A transaction MUST have a fee bid to get the transaction executed on
the network (a network that does not care about bids can just ignore
this property).A transaction signature MAY be locked to a particular chain identifierThe sender key of a transaction MAY be recovered by the signature of
the transactionChainlib is specifically designed for building command line interface
tools. It provides templates for handling configuration, argument
parsing and environment variable processing to build RPC connections to
chain nodes for network queries and signing operations.Command line interface provisionsThe base CLI provisions ofchainlibsimplifies the generation of a
some base object instances by command line arguments, environment
variables and configuration schemas.To use CLI provisions,chainlib.clishould be imported. This
automatically imports the following submodules:argDefine and/or select command-line argumentsconfigProcess configuration from command-line arguments and environment
variablesrpcCreate RPC connection from configurationwalletCreate wallet from configurationAny chain implementation building onchainlibshould extend one or
more of the classes in these modules as needed, for example order to add
more configuration directives or command line argument flags.Argumentschainlibdefines a set of arguments that are common concepts for
interfacing with blockchain RPCs. Which arguments to use for a specific
instantiation can be defined using flags or symbols that define groups
of flags.This functionality is provided by thechainlib.cli.args.ArgumentParserclass. It is a thin wrapper around the standard libraryargparser.ArgumentParserclass, only adding a method to add arguments
to the instance based on the aforementioned flags.Following is a description of all pre-defined arguments that are
available withchainlib.-c, –configOverride configuration directives by reading ini-files in the given
directory.Only configuration directives defined in the schema may be overridden.
Seechainlib-config.–env-prefixPrepend the given string to configuration directives when overriding by
environment variablesNormally, if a configuration directiveFOO_BARexists, the environment
variableFOO_BARwill override its value. If--env-prefix BAZis
passed, the environment variableBAZ_FOO_BARwill be used instead to
override the configuration directiveFOO_BAR. The environment variableFOO_BARwill in this casenotbe used.–heightQuery the chain RPC for results at a specific block height.Applies toreadoperations only.-i, –chain-specChain specification string for the blockchain connection.This informs the implementing code about the architecture and deployment
of the blockchain network. It can also be relevant when creating
signatures for the network (e.g. the EIP155 signature scheme for EVM).–fee-limitUse the exact given fee multiplier to calculate the final bid to get
transaction executed on the network.How the fee semantics are employed depend on the chain implementation,
but the final resulting bidmust alwaysbe the product ofprice * limit.Ifnotdefined, the multiplier will be retrieved using the fees
provider defined by the implementation.–fee-priceUse the exact given fee price as factor to calculate bid to get
transaction executed on the network.How the fee semantics are employed depend on the chain implementation,
but the final resulting bidmust alwaysbe the product ofprice * limit.Ifnotdefined, the current recommended price will be retrieved from
the fees provider defined by the implementation.-n, –namespaceAppend the given namespace to implicit configuration override paths.For example, if linux xdg-basedir path is used, a namespace argument offooin implementation domainbarwill result in the configuration
override path$HOME/.config/bar/foo.–nonceStart at the exact given nonce for the query.Ifnotdefined, the next nonce will be retrieved from the nonce
provider defined by the implementation.-p, –providerURL of the chain RPC provider.-s, –sendCLI tools building on chainlib shouldneversubmit to the network by
default. Instead, resulting transactions ready for network submission
should be output to terminal.If the implementation wishes to allow the user to directly send to the
network, the-sflagmustbe used for this purpose.–seqBy default, a random RPC id will be generated for every RPC call.However, some RPCs will only allow sequential serial numbers to be used
as RPC ids, in which case this flag should be used.–rawGenerate output suitable for passing to another command (e.g. UNIX
pipes).–rpc-authTells the implementer which RPC authentication scheme to use (e.g.
"basic" for http basic).–rpc-credentialsTells the implemented wich RPC authentication credentials to use for
selected rpc authentication scheme (e.g. "foo:bar" for user foo pass bar
in scheme "basic" a.k.a. http basic).Credentials may for example also be a single value, like a private key,
depending on the scheme and implementation.–rpc-dialectTells the implementer to optimize query, result and error reporting for
the specific chain RPC backend dialect.-u, –unsafeAllow arguments with blockchain addresses that are not checksum
protected.-v, -vvDefines logging verbosity.Specifically,-vwill set loglevel toINFO, wheres-vvwill set
loglevel toDEBUG.Default loglevel is up to the implementer, but it is advisable to keep
it atWARNING.-w, -wwToggles blocking in relation to chain RPC calls.If-wis set, the implementer should only block to obtain the result
of thelast, and as few as possible precedingRPC transactions.If-wwis set, the implementer should block to retrieve the results ofallof the preceding RPC transactions.If the implementation consists of a single transaction, the effect of-wand-wwwill always be the same. Nonetheless, the implementation
will be forced to provide both arguments.If neither flag is set, the typical consequence is that the network
transaction hash of the last transaction will be returned.-y, –key-fileRead private key from the given key file.Rendering configurationsConfigurations inchainlibare processed, rendered and interfaced
using theconfinipython package.In short,confiniextends the functionality of Python’s standard
libraryconfigparserpackage to allow merging of directives by parsing
multiple ini-files from multiple directories.Furthermore, it employs this same multi-file approach when defining a
configurationschema, aswell as defining source tooverridethe
values defined in the schema.Seehttps://gitlab.com/nolash/python-confinifor further details onconfini.Configuration schema in chainlibThe chainlib configuration schema is, along with the provided command
line arguments and environment variables, designed to cover the settings
necessary for most normal chain RPC operations.Configuration mappingBelow follows a mapping of configuration directives to command line
arguments and environment variables.Note that any configuration directives prefixed by"_"are not defined
in the configuration schema, and are not overrideable by environment
variables. These are values typically are only valid within the context
of a single execution of the implemented tool.argconfigenv——CONFINI_DIR [^1]-c. –config [^2]——-i, –chain-specCHAIN_SPECCHAIN_SPEC–height_HEIGHT—–fee-limit_FEE_LIMIT—–fee-price_FEE_PRICE—-n, –namespaceCONFIG_USER_NAMESPACECONFIG_USER_NAMESPACE–nonce_NONCE—-p, –rpc-providerRPC_HTTP_PROVIDERRPC_HTTP_PROVIDER-a, -recipient_RECIPIENT—-e, –executable-address_EXEC_ADDRESS—–rpc-authRPC_AUTHRPC_AUTH—RPC_PROVIDERRPC_PROVIDER [^3]—RPC_SCHEMERPC_SCHEME [^4]–rpc-credentialsRPC_CREDENTIALSRPC_CREDENTIALS–rpc-dialectRPC_DIALECTRPC_DIALECT-s, –send_RPC_SEND—–seq_SEQ—-u, –unsafe_UNSAFE—-w_WAIT—-ww_WAIT_ALL—-y, –key-fileWALLET_KEY_FILEWALLET_KEY_FILE— [^5]WALLET_PASSPHRASEWALLET_PASSPHRASECurrentlychainlibonly supports HTTP(S) when building RPC connections
from command line arguments and configuration.Base library contentsPluggable method interfaceThe base chainlib blockchain interface is defined by thechainlib.interface.ChainInterface class. All of the methods in this
class are unimplemented. Together they make up the methods necessary to
interface withanyblockchain RPC.It is up to the implemenenter to choose which of the methods that are
needed in any particular context. The implementer would then connect the
method symbols with actual code.Most methods in this class will return objects that can be passed to an
RPC connection that fits the block context.The available methods are:block_latestRetrieve the latest block from the networkblock_by_hashRetrieve the block corresponding to the given block hashblock_by_numberRetrieve the block corresponding to the given block numberblock_from_srcRender a chainlib.block.Block derivative object from an
architecture-dependent block representation sourceblock_to_srcRender an architecture dependent transaction representation from the
given Block objecttx_by_hashRetrieve the transaction corresponding to the given transaction hashtx_by_blockRetrieve the transaction corresponding to the given block hash and
transaction indextx_receiptRetrieve the details of a confirmed transactiontx_rawGenerate an RPC query from raw transaction wire datatx_packGenerate raw transaction wire data from an architecture dependent
transaction representationtx_unpackGenerate architecture dependent transaction representation from raw
transaction wire datatx_from_srcRender a chainlib.tx.Tx derivative object from an architecture-dependent
tx representation sourcetx_to_srcRender an architecture dependent transaction representation from the
given Tx objectaddress_safeGenerate a checksum-safe network addressaddress_normalGenerate an unambiguous network addresssrc_normalizeGenerate an unambiguous dictionary from the given dictionary. For
example, this can mean generating camel-case key equivalents for
snake-case values.The RPC interfacechainlib.connectioncurrently has support for HTTP(S) and UNIX socket
RPC connections. Both rely on the Pythonstandard libraryonly
(urllibandsocket).It provides a thread-safe connection factory mechanism where connection
constructor and location pairs are associated with string labels.There is also explicit builtin support for the JSONRPC RPC protocol,
which allows for a pluggable error translater that can be customized to
every RPC "dialect" that needs to be supported (examples are "geth" and
"openethereum" dialects of the Ethereum node fauna). Classes to handle
JSONRPC results, requests and errors are defined in thechainlib.jsonrpcmodule.Blocks and transactionsCommon block and transaction concepts are represented by thechainlib.block.Blockandchainlib.tx.Txobjects. These are very
minimal base-classes that need to be extended for every blockchain
implementation that is to be supported.When building transactions, implementations of thechainlib.sign.Signer,chainlib.nonce.NonceOracleandchainlib.fee.FeeOracleinterfaces will provide the transaction factory
object of the implementation with signatures, transaction nonces and
transaction fee details respectively.Other code featuresThis section lists features that are considered outside the core of thechainlibpackageRPC authenticatorIf you are relying on an RPC provider instead of running your own node
(although, you know youshouldrun your own node, right?), then RPC
authentication may be relevant.chainlib.authprovides two authentication mechanisms for HTTP:BasicAuthThe HTTP basic Authorization schemeCustomHeaderTokenAuthDefine an arbitrary header name and valueFee price aggregatorThechainlib.stat.ChainStatclass provides a simple implementation of
a running average aggregator for network fee prices. This can be used to
generate more precise fee price heuristics that in turn can be fed to a
Fee Oracle.[^1]: TheCONFINI_DIRenvironment variable defines an explicit
configurationschemapath.[^2]: The-cflag defines an explicit configurationoverridepath.[^3]: RPC_PROVIDER will always be set to the same value as
RPC_HTTP_PROVIDER by default.[^4]: The RPC_SCHEME configuration directive is always set to ’http’ by
default.[^5]: This flag is not provided because it is simply not safe to define
passphrases as an argument on the command line.