From a Real-World Kefir Handover to an On-Chain Commitment with Node.js, SHA-256 and Base

Leader 1 3 43
calendar_today agoschedule4 min read

From a Real-World Kefir Handover to an On-Chain Commitment with Node.js, SHA-256 and Base

Most blockchain demos begin with a smart contract.

This one began with a real person handing kefir culture to another person.

While building MyZubster, I wanted to test a practical question:

How can we connect a real-world event to public blockchain evidence without storing personal data on-chain — and without pretending that blockchain proves the physical event itself?

We now have a working end-to-end experiment.

The architecture

The flow is intentionally simple:

Physical handover

MarketplaceHandover

RECORDED

Canonical payload

SHA-256

Blockchain commitment

Base Sepolia

Transaction verification

Blockchain receipt stored in MyZubster

The important part is that the blockchain is not the database.

MongoDB maintains the application state and structured evidence. The public blockchain provides an independent timestamped commitment.

  1. Creating the handover record

The physical kefir exchange progressed through explicit application states:

ACCEPTED

HANDED_OVER

RECEIVED

RECORDED

Only after reaching RECORDED do we allow preparation of the blockchain commitment.

That distinction matters.

Creating a hash does not mean something has been anchored.

Preparing a transaction does not mean it has been confirmed.

And storing a transaction ID does not automatically mean the expected commitment actually exists on-chain.

  1. Building the commitment

For the first implementation we defined:

myzubster.marketplace-handover.v1

The committed payload contains the identifiers, handover method, state and relevant event timestamps.

From its deterministic representation we calculate a SHA-256 digest.

For this real handover:

ba9973f08ce86d16a3611c3cccbb9cc2cc779b9ea1cb6fd87a2e5864e557b6b9

Instead of publishing the original record, the transaction contains:

MZ-HANDOVER-V1:
ba9973f08ce86d16a3611c3cccbb9cc2cc779b9ea1cb6fd87a2e5864e557b6b9

This means the public chain receives the cryptographic commitment, not the participant's personal information.

  1. Anchoring it on Base Sepolia

We then performed the actual transaction.

Network: Base Sepolia
Chain ID: 84532
Value: 0 ETH
Block: 46933575
Gas used: 24160
Status: CONFIRMED
Confirmed: 2026-09-17T08:57:18.000Z

Transaction:

0x998a98b1733312e248f74a1387319dae30aab8123a6115c517e4ffe0ef9584bf

You don't have to trust this article.

You can inspect the transaction yourself:

https://sepolia.basescan.org/tx/0x998a98b1733312e248f74a1387319dae30aab8123a6115c517e4ffe0ef9584bf

  1. Verifying before trusting

Before writing the blockchain receipt back into MyZubster, we verified the transaction against the chain.

The verification included the expected chain ID, transaction, block, calldata commitment and confirmation.

Only after those checks did MyZubster persist the blockchain metadata.

The resulting state is conceptually:

{
state: "RECORDED",

blockchainCommitment: {

schema: "myzubster.marketplace-handover.v1",
algorithm: "SHA-256",
hash: "ba9973f08ce86d16a3611c3cccbb9cc2cc779b9ea1cb6fd87a2e5864e557b6b9",
network: "base-sepolia",
txId: "0x998a98b1733312e248f74a1387319dae30aab8123a6115c517e4ffe0ef9584bf",
confirmedAt: "2026-09-17T08:57:18.000Z"

}
}

And the application derives:

const onchainRecorded = Boolean(
commitment.network &&
commitment.txId &&
commitment.confirmedAt
);

So we deliberately keep these concepts separate:

state = RECORDED

onchainRecorded = true

ONCHAIN_RECORDED does not replace the domain state.

It adds another evidence layer.

  1. Moving the experiment into reusable code

A one-off transaction isn't enough.

We therefore added blockchain commitment metadata to the MarketplaceHandover model and implemented an authenticated endpoint:

POST /:handoverId/prepare-blockchain-commitment

The model can now represent:

blockchainCommitment: {
schema,
algorithm,
hash,
preparedAt,
network,
txId,
anchoredAt,
confirmedAt
}

The endpoint requires an eligible RECORDED handover and checks participant authorization before generating the commitment.

The implementation is public here:

https://github.com/MyZubster-Ecosystem/myzubster/pull/1230

Main MyZubster repository:

https://github.com/MyZubster-Ecosystem/myzubster

  1. Testing it

After installing the repository's declared dependencies, we ran the relevant marketplace test suites:

PASS tests/marketplaceFlow.test.js
PASS tests/marketplaceEvidence.test.js

Test Suites: 2 passed, 2 total
Tests: 4 passed, 4 total
TEST_EXIT=0

The point wasn't simply to get a transaction onto a block explorer.

The blockchain representation also needed to fit the existing marketplace/evidence architecture without breaking the application flow.

What does the blockchain actually prove?

This is the most important part.

The transaction does not prove that the kefir was safe.

It does not provide microbiological validation.

It does not independently prove that the physical handover occurred exactly as described.

And it certainly doesn't turn an observation into scientific evidence.

What it gives us is much narrower:

A public, timestamped cryptographic commitment that can later be compared with the corresponding digital record.

That's useful because it allows us to ask a precise technical question:

Does the record I have now produce the same commitment that was publicly anchored at that point in time?

Why I like this architecture

Instead of asking blockchain to become the source of all truth, we can separate responsibilities:

Human action

Application evidence

Structured representation

Cryptographic commitment

Public timestamp / receipt

Each layer proves something different.

That's a much more useful model for provenance than simply putting a "verified on blockchain" badge on an application.

Next step: independent verification

The natural next step is a verifier that can reproduce the process independently:

record
→ canonicalize()
→ sha256()
→ expectedCommitment
→ fetchTransaction()
→ decodeCalldata()
→ compare()
→ MATCH | NO_MATCH

Eventually, I'd like verification to require as little trust in the MyZubster application itself as practical.

Project links

MyZubster:

https://www.myzubster.com

Main source code:

https://github.com/MyZubster-Ecosystem/myzubster

MyZubster GitHub organization:

https://github.com/MyZubster-Ecosystem

On-chain handover integration — PR #1230:

https://github.com/MyZubster-Ecosystem/myzubster/pull/1230

Kefir / fermentation knowledge repository:

https://github.com/DanielIoni-creator/Myzubster-fermentation-kefir

MyZubster Marketplace:

https://github.com/DanielIoni-creator/MyZubster-Marketplace

Base Sepolia transaction:

https://sepolia.basescan.org/tx/0x998a98b1733312e248f74a1387319dae30aab8123a6115c517e4ffe0ef9584bf

What started as one person sharing kefir culture with another became a useful test of how physical events, application state, cryptographic evidence and public blockchain infrastructure can coexist without confusing one for another.

There is still a lot to build, particularly around canonicalization, independent verification, batching and evidence schemas.

But now we have something much more valuable than a diagram:

a real event, a real application record, real code, a reproducible SHA-256 commitment and a real confirmed public transaction.

And every layer can be inspected.

MyZubster — Share → Try → Observe → Improve → Share again.

nodejs #blockchain #web3 #opensource #mongodb #sha256 #base #cryptography #softwarearchitecture #provenance

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

ERC20 Edge Cases Every Smart Contract Engineer Should Know

BinnaDev - Jun 24

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelski - Mar 19

Understanding Blockchain: A Developer's Guide to Blocks, Consensus, and Smart Contracts

Soumabha Mahapatra - Jul 12

Cisco's Amy Chang: A Model's "Passport" Doesn't Tell You Where It Actually Came From

Tom Smithverified - Aug 27

Building an Agent SKILL for SeraProtocol: The Ultimate Guide to On-chain FX Automation

Haruki Kondo - Mar 19
chevron_left
2.2k Points47 Badges
Rimini
56Posts
3Comments
17Connections

Related Jobs

View all jobs →

Commenters (This Week)

2 comments
2 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!