Santiant
← Technical cases
Blockchain Alastria Java REST API Docker Architecture

Document hash stamping service on Alastria blockchain

Design and implementation of a Java REST service, deployable via Docker, that abstracts away the complexity of the Alastria Red-T network to store and verify document hashes on-chain.

S
Santiago Moreno Arce ·

Document hash stamping service on Alastria blockchain

Summary

A company needed to guarantee the integrity and traceability of documents generated by their internal applications, by recording their hashes on the Alastria Red-T network. The work involved designing a Java service deployable via Docker that exposes a simple REST API to stamp and query hashes on-chain, hiding all the complexity inherent in blockchain interaction (key management, nonces, transaction errors, node synchronization).

Context

The organization had several internal applications generating documents that were relevant from a legal and operational standpoint: contracts, evidence, internal certificates and audit records. The need was twofold:

  • Being able to prove in the future that a specific document existed at a particular point in time and had not been altered.
  • Doing so on a blockchain network with institutional backing — in this case Alastria Red-T, a permissioned network widely adopted in Spain.

The problem was not technical from a business perspective, but from a development one: none of the client applications should need to know anything about blockchain. Application teams wanted something as simple as “take this hash and store it reliably.”

Problem

Integrating each application directly against the network presented several challenges:

  • Each team would need to learn Web3j, manage wallets, sign transactions and handle nonces.
  • Blockchain errors (insufficient gas, desynchronized nonce, node unavailable, reverted transaction) are specific and unintuitive for conventional backend developers.
  • Distributed private key management across each application would have been a security and operational risk.
  • On-chain transactions are not instantaneous, so any naive integration would block the client applications.

The solution needed to be a service that any application team could call without knowing anything about blockchain.

Technical approach

Single responsibility REST service. A Java service was built exposing two endpoints: stamp a hash (POST) and verify/query a hash (GET). The contract with client applications is simple and stable. All blockchain complexity is internal to the service.

Key and wallet management centralized. The service manages the private key and wallet used for signing transactions. Client applications never handle cryptographic material. Rotation or migration of keys is a concern of the service, not of each consumer.

Nonce and transaction lifecycle management. One of the most common failure points when interacting with blockchain is nonce management (each transaction from an account must have a unique, sequential nonce). The service handles this internally, with a mechanism to detect and recover from desynchronized nonces without intervention.

Async confirmation with status tracking. Submitting a transaction to the blockchain does not mean it is immediately confirmed. The service accepts the stamp request, submits the transaction, and allows querying the status (pending, confirmed, failed) via a transaction reference. Client applications are not blocked waiting for blockchain confirmation.

Retries and fault tolerance. Transient node failures, temporary congestion and recoverable errors are handled with configurable retry and backoff. The service distinguishes retryable errors from permanent failures and responds accordingly.

Dockerized deployment. The service is packaged as a self-contained Docker container: configuration via environment variables, no state on disk (state lives on-chain and in a minimal operational database for pending transaction tracking). Easy to deploy, replicate or move between environments.

Minimal smart contract. The on-chain part is a deliberately simple contract: it stores a hash associated with a timestamp and an identifier, emits an event for each registration and exposes a read function for verification. No complex logic on-chain. The complexity lives in the service, where it can be maintained and evolved without blockchain constraints.

Decisions and trade-offs

Centralized service vs. SDK per application. Providing an SDK that each team would integrate directly was considered. It was ruled out: it would spread blockchain knowledge and responsibility across teams that don’t need it, complicate maintenance and create security risks from distributed key management. The service adds a network hop but keeps the responsibility boundary clean.

Synchronous vs. asynchronous confirmation. Exposing synchronous confirmation (wait until the transaction is mined before responding) would simplify the client API but block applications for seconds or minutes. The async approach with status querying is slightly more complex but correct for the nature of blockchain.

Minimal on-chain contract. Putting more logic in the contract was considered. It was ruled out for the same reason as in other blockchain projects: every line of on-chain logic is harder to evolve and has a real gas cost. The contract does exactly one thing: record a hash with a timestamp.

Result

  • A production-ready REST service that any internal application can use to stamp and verify document hashes on Alastria Red-T without any blockchain knowledge.
  • Centralized key and nonce management, with no cryptographic material distributed across client applications.
  • Correct handling of the on-chain transaction lifecycle, including transient failures and confirmation latency.
  • Deployable and reproducible infrastructure via Docker.
  • Client teams can integrate in a few hours, regardless of their blockchain experience.

Tech stack

  • Java
  • Web3j
  • Alastria Red-T (permissioned blockchain)
  • Solidity (smart contract)
  • REST API
  • Docker
  • PostgreSQL (operational state for pending transactions)

What this case demonstrates

This case demonstrates the ability to design a service whose value is precisely in what it hides: the complexity of blockchain interaction. It requires knowing the domain well enough to decide what belongs in the public interface and what belongs in the implementation, managing non-trivial failure modes (nonces, reverts, confirmation latency) and delivering something that genuinely simplifies the lives of the teams that use it.


Need to add document traceability or integrity guarantees to your internal applications without your teams having to learn blockchain? I can help you design and build the right abstraction for your infrastructure.