It seems page is loading.

If message not gone, probably your browser doesn't support the features required so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chromium/Chrome, Safari or Firefox browser.

Authentication on ETH

@knarkhov, 5th Feb, πŸ¦‹ Raku dev room at FOSDEM22 conf

Evolution of authenticators

PoA consensus network

Prove the auth

Principal software model

Authenticator software could be classified as on-chain and off-chain. These both parts work together, but actually are independent and interact via third-party provider β€” Ethereum node client.

Which side of the force do u belong 2?

Trivial authenticator 😠

Authenticator with balances 🀬

Attack vectors

Generic smart contract for authenticator

State update function:

function * updateState() public only_owner returns (bool success);

State retrieve function:

function * getPkey() public view only_owner returns (bytes32 publickey);

Source code:

Why randomizer is weak?

State retrieve function getPkey() uses private function getPseudoRand() for pseudo random private key generation.

It uses a few block parameters (block.difficulty, block.coinbase, block.gaslimit, block.number, block.timestamp) and truly random seed pushed to authenticator smart contract constructor from the backend on every update.

This random seed make it a little bit safer.

Backend + frontend schema

Backend is completely written in Raku, I used Pheix content management system as the prototype. On one hand it's the only CMS with Ethereum Blockchain native support, on other β€” it's well scalable and extendable via addons.

Pheix is based on concept of hybrid CMS. It works as a legacy CMS while global templates rendering, and as a headless CMS while fetching content via async API requests.

Try built-in API debugger:


    "credentials": {
        "token": "196bd812-7bd1-11ec-90d6-0242ac120003"
    "method": "GET",
    "route": "/api/admin"


  "status": 1,
  "render": "0.090812881",
  "content": {
    "tparams": {
      "table": "embeddedadmin/login",
      "header": "Welcome"
    "component_render": "0.086556",
    "component": "PGRpdj4KPGZvcm0gY2xhc3M9Il9waHgtY250 ... kaXY+Cg=="
  "msg": "/api/admin fetch is successful"


   <form class="_phx-cntr _pheix-admin-form-signin" onsubmit="window.PheixAuth.login();">
      <i class="_pheix-admin-form-signin-login-ico fas fa-sign-in-alt"></i>
      <h1 class="h3 mb-3 font-weight-normal">{ props.header }</h1>
      <label for="inputEmail" class="sr-only">Email address</label>
      <button class="btn btn-lg btn-primary btn-block" type="submit">Log in</button>

Shadow/ghost sessions

Sample auth module routes

"routing": {
    "group": {
        "routes": {
            "login": {
                "label":"Default route",
                "route": {
                    "hdlr": { "default": "browse", "/api": "browse_api" }
            "authentication": {
                "label":"Authentication route",
                "route": {
                    "hdlr": { "/api": "auth_api" }
            "session": {
                "label":"Validate session route",
                "route": {
                    "hdlr": { "/api": "sess_api" }

Module global definition

The module should be added to Pheix global config file:

"addons": {
    "group": {
        "installed": {
            "embedadm": "Pheix::Addons::Embedded::Admin"

Specific methods required by Pheix

method init_json_config returns Pheix::Model::JSОN;
method get(:$ctrl!) returns Pheix::Addons::Embedded::User;
method get_class returns Str;
method get_name returns Str;
method get_sm returns List;
method fill_seodata(:%matchctrl!) returns Hash;

Authenticator features

Trivial authenticator algorithm is supported by /admin/auth and /admin/sess routes: e.g. by auth_api() and sess_api() authenticator module methods. These methods are mostly wrappers over:

method auth_on_blockchain(Str :$addr!, Str :$pwd!, :$authgateway!) returns Hash;
method validate_on_blockchain(Str :$token!, :$authgateway!) returns Hash;
method session_details(Str :$trx!, :$authgateway!) returns Str;

Catch contract feature (sticky contract)

Catch contract feature depends on authenticator smart contracts with ability to emit event in constructor.

The catch contract feature should be integrated to trivial authenticator's authentication section right before the deploy authenticator smart contract call. Just a few new nodes:

Algorithm update no.1

Filter events in Geth

var CurrFilterRes;
    fromBlock: 0,
    toBlock: 'latest',
    topics: [
        '0x' + web3.padLeft('1', 64)
}).get(function(error, result){
    if (!error) CurrFilterRes = result;
        else console.log(error);

πŸ™ˆ in this snippet 1 is used to filter smart contract deployments, 2 should be used to filter update state trxs.

Filtering results

    address: "0x78d8183710ecbb204e2f0220d24110d97cd36ea8",
    blockHash: "0x0860e9cd3638...",
    blockNumber: 25,
    data: "0x",
    logIndex: 0,
    removed: false,
    topics: ["0x1afba253d164...", "0x0000...0001"],
    transactionHash: "0xd9d60c237989..."
}, {
    address: "0x92f2d25504ef38ee3c9cdabde6e309a061c67e20",
    blockHash: "0x3ce94da169a7...",
    blockNumber: 468,
    data: "0x",
    logIndex: 0,
    removed: false,
    topics: ["0x1afba253d164...", "0x0000...0001"],
    transactionHash: "0x091f999c7162..."

Open auth on public Ethereum networks

Authenticator on public Ethereum networks could be useful for the cases, while you are building open, transparent and traceable authentication flow for independent applications or systems.

Advantages of public blockchain authenticators are seemingly valuable. On the one hand, blockchain provides a truly decentralized and transparent audit platform for the authentication, and from other side, it makes the authentication and identification flow much more anonymous.

Algorithm update no.2

Naive administrative layer concept

Blog is also powered by Pheix. This site was opened in the middle of 2020 (right before the The Perl Conference in the Cloud) and since the start it collects access statistics and saves the crash logs.

Usually I'm just checking them via server console, with a few bash commands, like:

cat bigbro.tnk | \
perl -lne 'print localtime($1)."|$3" if /^([0-9]+)\|(^|.)*\|([a-z]+)$/i' | \
grep "Jan 23"

Baby stats πŸ€¦β€β™‚οΈ

Sun Jan 23 09:28:36 2022|US
Sun Jan 23 14:59:58 2022|US
Sun Jan 23 15:41:31 2022|US
Sun Jan 23 15:42:10 2022|US
Sun Jan 23 15:45:32 2022|CA
Sun Jan 23 18:12:14 2022|DE
Sun Jan 23 20:57:47 2022|US
Sun Jan 23 22:01:51 2022|RU
Sun Jan 23 22:27:08 2022|RU

Crash logs

Crash logs a little bit complicated β€” log entries are base64 encoded πŸ˜€, so:

cat logs.tnk | \
perl -MMIME::Base64 -MTerm::ANSIColor -lne \
'print color("bold blue").localtime($1).color("reset").
"\n".decode_base64($2)."\n".color("red").(q{=} x 72).
"\n".color("reset") if /^([0-9]+)\|([^|.]+)$/i'

Yet another way to make things better

For now there are the next related to authenticator issuses at Pheix tracker:

Open call

I would like to invite you to Pheix dev process β€” code review, forks and merge requests are very welcome at

Feel free to join our matrix workspace for any questions and feedback: 😎

Thanks for ur attention!



Decentralized Authentication