<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hiroshi Ichiyanagi</title>
    <description>The latest articles on DEV Community by Hiroshi Ichiyanagi (@hiroshi_ichiyanagi).</description>
    <link>https://dev.to/hiroshi_ichiyanagi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3972440%2F7f22d04a-c966-4bf1-82cf-70880167a72e.png</url>
      <title>DEV Community: Hiroshi Ichiyanagi</title>
      <link>https://dev.to/hiroshi_ichiyanagi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hiroshi_ichiyanagi"/>
    <language>en</language>
    <item>
      <title>Don’t trust me, verify me: openunit, a unit of account you can recompute byte-for-byte</title>
      <dc:creator>Hiroshi Ichiyanagi</dc:creator>
      <pubDate>Sat, 13 Jun 2026 23:37:25 +0000</pubDate>
      <link>https://dev.to/hiroshi_ichiyanagi/dont-trust-me-verify-me-openunit-a-unit-of-account-you-can-recompute-byte-for-byte-4d9h</link>
      <guid>https://dev.to/hiroshi_ichiyanagi/dont-trust-me-verify-me-openunit-a-unit-of-account-you-can-recompute-byte-for-byte-4d9h</guid>
      <description>&lt;h2&gt;
  
  
  The promise
&lt;/h2&gt;

&lt;p&gt;Most numbers you read about the economy ask for your trust. A price index, an exchange rate, a “fair value” — you take the institution’s word for it, because you can’t recompute it yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;openunit&lt;/strong&gt; is built the other way around. It’s a small, open reference implementation of a &lt;em&gt;unit of account&lt;/em&gt;: a measuring stick for value. The entire design goal is that you don’t have to trust me. You clone the repo, run two commands, and get the exact same number I published — down to the last digit — along with the exact same SHA-256 hashes. Change a single byte of the inputs and the hash changes and verification fails.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don’t trust me. Verify me.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sentence is the whole project in five words. This post is about how the reproducibility actually works, and why a measuring stick should be built this way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is (and what it isn’t)
&lt;/h2&gt;

&lt;p&gt;openunit is a &lt;strong&gt;fixed-basket index&lt;/strong&gt; — think of the IMF’s SDR, but with the basket weights chosen by &lt;em&gt;population&lt;/em&gt; instead of by reserve-currency politics. At a low-frequency “vintage” it pins a fixed quantity of each currency, derived from how many people each economy has. The unit’s value is then read off market (or PPP) exchange rates.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;not&lt;/strong&gt; money. It issues no token, holds no reserves, settles no payments, and predicts no returns. It only &lt;em&gt;measures&lt;/em&gt;. The value is quoted in a numeraire (US dollars) purely as a readable denomination; the unit itself is defined by the basket.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why population?
&lt;/h2&gt;

&lt;p&gt;Expressing value in a single national currency bakes in the politics of whoever issues it. openunit counts people equally instead — one person, one vote.&lt;/p&gt;

&lt;p&gt;I want to be upfront: &lt;strong&gt;that is a value choice, not a neutral fact.&lt;/strong&gt; Population-weighting favors populous economies; GDP-weighting favors large ones; PPP-weighting favors welfare comparisons. openunit doesn’t pretend its choice is objective. It fixes the choice, writes it down, and makes it &lt;em&gt;contestable&lt;/em&gt; — the method is auditable, so the politics of the weighting can be argued in the open instead of hidden inside an opaque index. (There’s a whole section of the spec, “On fairness,” that says exactly this.)&lt;/p&gt;

&lt;p&gt;The engineering is what makes that honesty enforceable. If the method weren’t reproducible, “it’s a transparent choice” would be an empty claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the reproducibility works
&lt;/h2&gt;

&lt;p&gt;The engine is a single &lt;strong&gt;standard-library Python module&lt;/strong&gt; — no third-party dependencies, on purpose. Five rules make the output bit-for-bit identical on any machine, any OS, and every Python from 3.8 up (3.8–3.12 in CI):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Exact arithmetic.&lt;/strong&gt; Every number is parsed from a &lt;em&gt;string&lt;/em&gt; into &lt;code&gt;decimal.Decimal&lt;/code&gt; at precision 50, rounding &lt;code&gt;ROUND_HALF_EVEN&lt;/code&gt;, inside an isolated context. No floats, ever. Float math gives platform-dependent rounding — exactly what you can’t have if hashes must match.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No wall clock.&lt;/strong&gt; The engine never imports or calls &lt;code&gt;datetime&lt;/code&gt;/&lt;code&gt;time&lt;/code&gt;. The result depends only on the inputs, never on &lt;em&gt;when&lt;/em&gt; it runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canonical JSON for hashing.&lt;/strong&gt; &lt;code&gt;json.dumps(obj, sort_keys=True, separators=(",", ":"), ensure_ascii=False)&lt;/code&gt;, encoded UTF-8. Sorted keys, no insignificant whitespace, the same bytes everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SHA-256, twice.&lt;/strong&gt; &lt;code&gt;input_digest&lt;/code&gt; = hash of the canonical spec. &lt;code&gt;artifact_hash&lt;/code&gt; = hash of the canonical artifact minus the hash field itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strings in, strings out.&lt;/strong&gt; Every quantity in the published artifact is an exact decimal string, so there’s nothing to re-round on the way back in.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The interesting part is how this is &lt;em&gt;enforced&lt;/em&gt;, not just promised. A determinism guard (standalone and in CI across 3.8–3.12) checks four invariants:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;same input → same output, including a full JSON round-trip;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;no wall-clock read&lt;/strong&gt; — verified two ways: a source scan &lt;em&gt;and&lt;/em&gt; monkey-patching &lt;code&gt;time.*&lt;/code&gt; to throw at runtime, so any hidden clock call would crash the build;&lt;/li&gt;
&lt;li&gt;tamper detection — flip one field and verification fails;&lt;/li&gt;
&lt;li&gt;the pinned realized weights equal the population shares at precision 60.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That second one is my favorite: the test literally poisons &lt;code&gt;time.time&lt;/code&gt; and friends, then builds an artifact. If the engine touched the clock, it would blow up. It doesn’t.&lt;/p&gt;

&lt;h2&gt;
  
  
  The artifacts
&lt;/h2&gt;

&lt;p&gt;Two real, pinned vintages ship in the repo. Each is a &lt;code&gt;spec.json&lt;/code&gt; (the hashed input), an &lt;code&gt;artifact.json&lt;/code&gt; (the built, self-verifying result), and a &lt;code&gt;SOURCES.md&lt;/code&gt; with full provenance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;v0.1 — real market data.&lt;/strong&gt; One person, one vote, on UN World Population Prospects 2024 and ECB euro reference rates (baseline 2026-01-09, valuation 2026-05-15):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 openunit = 0.985631 USD
artifact_hash: sha256:1e615cf7…9a3a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Population-pinned weights: India 39.08%, China 37.39%, United States 9.24%, euro area 9.20%, Japan 3.24%, United Kingdom 1.85%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;v0.2 — PPP-aware.&lt;/strong&gt; Same weights, but the value leg reads purchasing-power-parity rates from the World Bank (&lt;code&gt;PA.NUS.PPP&lt;/code&gt;, ICP 2024), so the unit is read in &lt;em&gt;international dollars&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 openunit = 2.848010 international dollars
artifact_hash: sha256:566c95c1…b97a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reading the unit at PPP shifts &lt;em&gt;realized&lt;/em&gt; weight toward lower-price economies: India moves from a 39.08% headcount share to a 64.48% realized weight, while the US falls from 9.24% to 3.24%.&lt;/p&gt;

&lt;p&gt;A small honesty note from building v0.2: the World Bank publishes no single “Euro area” PPP figure — I checked both the CSV and the API, and the cell is empty. So the euro-area factor is a &lt;strong&gt;population-weighted blend of the 20 member states’&lt;/strong&gt; real World Bank values, using the same UN populations as the headcount basket. It came out to 0.642950 — lower than a GDP-weighted blend would give, because low-price members carry real per-person weight. That’s documented as a contestable choice, not smuggled in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify it yourself
&lt;/h2&gt;

&lt;p&gt;This is the part that matters. Clone it and check my numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Hiroshi-Ichiyanagi/openunit
&lt;span class="nb"&gt;cd &lt;/span&gt;openunit
python3 test_determinism_guard.py     &lt;span class="c"&gt;# 4/4 determinism checks&lt;/span&gt;
python3 make_vintages.py &lt;span class="nt"&gt;--verify&lt;/span&gt;     &lt;span class="c"&gt;# vintages reproduce, byte-for-byte&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4/4 PASS
PASS  v0.1-2026-05-15 reproduces  hash=sha256:1e615cf7…9a3a
PASS  v0.2-ppp-2026-05-15 reproduces  hash=sha256:566c95c1…b97a
2/2 vintages reproduce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your machine produces those exact hashes, you’ve independently confirmed the published values. If it doesn’t, something is wrong — and you’ll know. Nothing to install; it’s standard library only. There’s also a CLI (&lt;code&gt;openunit build&lt;/code&gt; / &lt;code&gt;verify&lt;/code&gt; / &lt;code&gt;show&lt;/code&gt;) so you can verify &lt;em&gt;someone else’s&lt;/em&gt; published artifact from just their &lt;code&gt;spec.json&lt;/code&gt; and &lt;code&gt;artifact.json&lt;/code&gt;. And for the strongest check, &lt;code&gt;verify_independent.py&lt;/code&gt; is a second implementation written from the spec alone — it shares no code with the engine, yet recomputes the same hash. When two independent implementations agree, the number no longer rests on trusting my code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tamper-evidence
&lt;/h2&gt;

&lt;p&gt;A measuring stick should also be hard to silently revise. openunit has an optional, offline, keyless &lt;strong&gt;hash-chain anchor&lt;/strong&gt;: it commits an &lt;code&gt;artifact_hash&lt;/code&gt; into an append-only record, so a publisher can show an artifact existed by some point and hasn’t been quietly changed. A local chain proves &lt;em&gt;integrity and order&lt;/em&gt;, not &lt;em&gt;time&lt;/em&gt; — so the record carries an &lt;code&gt;external_proof&lt;/code&gt; slot (outside the commitment) for a public timestamp, and attaching one never changes any hash.&lt;/p&gt;

&lt;p&gt;Both shipped vintages already carry one. Each &lt;code&gt;artifact.json&lt;/code&gt; has an &lt;strong&gt;OpenTimestamps&lt;/strong&gt; proof committed to the Bitcoin blockchain — &lt;code&gt;BitcoinBlockHeaderAttestation&lt;/code&gt;s at block heights 953507 / 953528 / 953536. So you don’t have to take &lt;em&gt;2026-05-15&lt;/em&gt; on faith either: &lt;code&gt;ots verify data/v0.1-2026-05-15/artifact.json.ots&lt;/code&gt; checks the artifact against the Bitcoin chain itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it’s going
&lt;/h2&gt;

&lt;p&gt;v0.1 and v0.2 are real and pinned; the determinism guard is green across Python 3.8–3.12; an engine-independent verifier and Bitcoin-anchored timestamps already ship. Next: more real vintages as the dates roll forward, tightening the input domain (rejecting negative populations — currently disclosed and pinned by test, slated for v0.3), and writing the artifact format up as a standalone spec. It’s early — an alpha — and the point is precisely that you can check every claim above rather than take my word for it.&lt;/p&gt;

&lt;p&gt;If you think population-weighting is the wrong value choice, good — that’s a real argument, and the method is fixed and auditable so we can actually have it. If you find a way to make the build non-deterministic, that’s a bug I want to know about.&lt;/p&gt;

&lt;p&gt;Repo: &lt;strong&gt;&lt;a href="https://github.com/Hiroshi-Ichiyanagi/openunit" rel="noopener noreferrer"&gt;https://github.com/Hiroshi-Ichiyanagi/openunit&lt;/a&gt;&lt;/strong&gt; (Apache-2.0).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don’t trust me. Verify me.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>opensource</category>
      <category>python</category>
      <category>economics</category>
      <category>showdev</category>
    </item>
    <item>
      <title>openreserve: offline-verifiable proof-of-reserves for the off-chain world</title>
      <dc:creator>Hiroshi Ichiyanagi</dc:creator>
      <pubDate>Sun, 07 Jun 2026 11:45:22 +0000</pubDate>
      <link>https://dev.to/hiroshi_ichiyanagi/openreserve-offline-verifiable-proof-of-reserves-for-the-off-chain-world-hbg</link>
      <guid>https://dev.to/hiroshi_ichiyanagi/openreserve-offline-verifiable-proof-of-reserves-for-the-off-chain-world-hbg</guid>
      <description>&lt;p&gt;"Are the reserves actually there?" has become a recurring, expensive question. A string of high-profile failures — where customer funds turned out not to fully back the liabilities — has made &lt;em&gt;verifiable&lt;/em&gt; reserves a live concern rather than a back-office footnote. In parallel, there's a broader drift toward periodic, independently-checkable reserve attestation for some classes of issuers and custodians.&lt;/p&gt;

&lt;p&gt;Most of the tooling people reach for here is &lt;strong&gt;on-chain&lt;/strong&gt;: oracle-style proof-of-reserve systems (Chainlink's Proof of Reserve is the well-known example) designed for on-chain assets and smart-contract consumers. That's a real and useful domain — but it's not the one a payment processor, e-money issuer, wallet, or custodian lives in. Their ledger is in a normal database; their auditors and regulators are off-chain; an on-chain oracle is the wrong shape. &lt;strong&gt;openreserve&lt;/strong&gt; is a small attempt at the off-chain gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;p&gt;openreserve is a dependency-free Python library (standard library only); install it with &lt;code&gt;pip install openreserve&lt;/code&gt;. Given a &lt;strong&gt;ledger state&lt;/strong&gt; — an append-only, double-entry ledger — and an &lt;strong&gt;explicit point in time&lt;/strong&gt;, it produces and verifies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Proof of Reserves&lt;/strong&gt; — a Merkle tree over user-account balances plus reserve-account totals, with a solvency check (&lt;code&gt;reserves &amp;gt;= liabilities&lt;/code&gt;). A user can verify their own balance is included via a Merkle proof, without the operator revealing other users' balances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proof of Solvency&lt;/strong&gt; — per-currency proof-of-reserves aggregated with the audit chain's commitment hash.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit chain&lt;/strong&gt; — a hash-linked event log (&lt;code&gt;prev_hash → event_hash&lt;/code&gt;) with a &lt;code&gt;verify_chain()&lt;/code&gt; that detects any tampering with past entries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reserve / deposit calculation&lt;/strong&gt; — point-in-time required-reserve computation (settled balances plus in-flight obligations; negative balances excluded).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The artifacts are plain data. A proof's public summary is a JSON-serializable dict, so you can publish it at a static URL and a third party can fetch it and re-verify it offline using the same library primitives. openreserve does &lt;strong&gt;not&lt;/strong&gt; ship an HTTP serving layer — exposing an endpoint is the integrator's job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proof of Reserves vs Proof of Solvency
&lt;/h2&gt;

&lt;p&gt;These two are often conflated, so to be precise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Proof of Reserves&lt;/strong&gt; — evidence that the assets (reserves) actually exist / are held.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proof of Solvency&lt;/strong&gt; — evidence that &lt;strong&gt;assets ≥ liabilities&lt;/strong&gt;: the reserves actually cover what is owed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;openreserve does both: a Merkle-committed reserve proof, plus a per-currency solvency check (&lt;code&gt;reserves &amp;gt;= liabilities&lt;/code&gt;). The solvency claim is only as complete as the liabilities you include — see &lt;em&gt;Limitations&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who it's for
&lt;/h2&gt;

&lt;p&gt;The common shape is an operator whose balances are an &lt;strong&gt;off-chain liability&lt;/strong&gt; in a normal database, and whose auditors, counterparties, or regulators are off-chain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;E-money / prepaid-balance issuers&lt;/strong&gt; — customer balances are liabilities that must be backed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment processors / PSPs&lt;/strong&gt; holding client or settlement funds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custodians&lt;/strong&gt;, including the &lt;strong&gt;off-chain customer-balance ledger of a crypto exchange&lt;/strong&gt; (the familiar "CEX proof-of-reserves" case).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stablecoin issuers&lt;/strong&gt; attesting the &lt;strong&gt;off-chain reserve&lt;/strong&gt; backing (the reserve side, held in banks/custody — not the on-chain token).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loyalty-point / closed-loop wallet operators&lt;/strong&gt; — outstanding points are an off-chain liability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In every case the question is the same: &lt;em&gt;can a third party verify the reserves cover the off-chain liabilities, without trusting a dashboard?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The core property: determinism
&lt;/h2&gt;

&lt;p&gt;The reason any of this is worth doing is that the proofs are &lt;strong&gt;deterministic&lt;/strong&gt;. Proof generation takes the as-of / event time as an explicit, required input and never reads the wall clock. The same ledger state and the same timestamp produce a byte-identical Merkle root and audit hash.&lt;/p&gt;

&lt;p&gt;This is the difference between "trust our dashboard" and "verify our proof." If the output depended on &lt;code&gt;datetime.now()&lt;/code&gt;, no outsider could reproduce it. Because it doesn't, a regulator, auditor, or counterparty can take a published proof and check it themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't trust me, verify me
&lt;/h2&gt;

&lt;p&gt;The verification loop is one-directional — the operator publishes, anyone re-checks offline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OPERATOR SIDE
  ledger state + explicit as-of time
        |
        v
  generate proof            (deterministic: same state + time -&amp;gt; same hashes)
        |
        v
  publish proof as JSON     (static URL or file)
        |
========|=====================================================
        v
VERIFIER SIDE  (auditor / user / regulator -- offline, no trust in operator)
  fetch proof JSON
        |
        +--&amp;gt; recompute Merkle root
        +--&amp;gt; verify audit chain   (prev_hash -&amp;gt; event_hash)
        +--&amp;gt; check solvency       (reserves &amp;gt;= liabilities)
        +--&amp;gt; (a user) verify own balance is included via Merkle proof
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repo ships a determinism guard you can run yourself (clone the repo and run the test suite):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pytest tests/test_determinism_guard.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It asserts (a) the same ledger state + same &lt;code&gt;snapshot_at&lt;/code&gt; reproduces the same Merkle root and audit hash, and (b) with &lt;code&gt;datetime.now&lt;/code&gt; patched to raise, generation with an explicit time still succeeds — i.e. the wall clock is genuinely never touched.&lt;/p&gt;

&lt;p&gt;A minimal end-to-end example (after &lt;code&gt;pip install openreserve&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openreserve&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Currency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Ledger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OwnerType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ProofOfReservesGenerator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SQLiteLedgerStorage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TransactionBuilder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2026&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tzinfo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# explicit time — no wall clock
&lt;/span&gt;&lt;span class="n"&gt;ledger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Ledger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLiteLedgerStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:memory:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;platform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OwnerType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PLATFORM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Currency&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JPY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;platform&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;reserve&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OwnerType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RESERVE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Currency&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JPY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reserve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;alice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OwnerType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Currency&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JPY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fund&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;units&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TransactionBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FUND&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ops&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;initiated_at&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;account_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;account_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_units&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;units&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Currency&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JPY&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="n"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;settle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transaction_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;settled_at&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;fund&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reserve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1_000_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;fund&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ProofOfReservesGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Currency&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JPY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot_at&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_solvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_liabilities_total_cents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reserve_assets_total_cents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# True 300000 1000000
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;Being precise about what is and isn't guaranteed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Determinism is on the time axis.&lt;/strong&gt; Account and transaction identifiers are UUID-based, so two ledgers rebuilt independently won't share identifiers or hashes; identifier stability is &lt;em&gt;not&lt;/em&gt; claimed. What &lt;em&gt;is&lt;/em&gt; claimed: a given ledger state, at a given time, is reproducibly provable, and any published proof is independently verifiable. (Content-addressed, rebuild-stable identifiers are on the roadmap.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Liabilities completeness.&lt;/strong&gt; Like all proof-of-reserves, it proves assets cover the liabilities you &lt;em&gt;include&lt;/em&gt;; it can't force you to include every liability. Per-user Merkle inclusion raises the cost of silently omitting someone, but it is not a substitute for an attestation of completeness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No HTTP / serving layer.&lt;/strong&gt; Publishing a proof at an endpoint is the integrator's job; the library only produces and verifies the artifacts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No on-chain anchoring.&lt;/strong&gt; A proof isn't committed to a blockchain today (it could be layered on top); the core stays off-chain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Early and unproven.&lt;/strong&gt; v0.1.1, no production adoption, APIs may change.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it is not
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Not on-chain&lt;/strong&gt;, and not a replacement for or competitor to oracle-style PoR. Different domain, different consumers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a compliance product.&lt;/strong&gt; It makes no claim to satisfy any specific regulation, and nothing here is legal or financial advice. The regulatory climate is context, not an endorsement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not novel cryptography.&lt;/strong&gt; It's a clean integration of standard primitives (Merkle trees, hash chains) with a determinism discipline — the value is in the assembly and the verifiability, not in inventing new math.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Status &amp;amp; roadmap
&lt;/h2&gt;

&lt;p&gt;The determinism guarantee is on the time axis; UUID identifiers are the obvious next thing to make deterministic if cross-rebuild reproducibility is needed. There's no HTTP/serving layer and no on-chain anchoring (both could be layered on top). CI runs the suite on Python 3.11–3.13 plus a packaging check.&lt;/p&gt;

&lt;p&gt;Apache-2.0. On PyPI (&lt;code&gt;pip install openreserve&lt;/code&gt;); repo and issues: &lt;a href="https://github.com/Hiroshi-Ichiyanagi/openreserve" rel="noopener noreferrer"&gt;https://github.com/Hiroshi-Ichiyanagi/openreserve&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>fintech</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
