Skip to content

Tamper Tutorial

Febin Francis edited this page Oct 10, 2026 · 1 revision

Change signed lamports and observe rejection

The tamper tutorial changes a meaningful value inside a signed receipt body while keeping the export syntactically valid. A fixed byte offset is unsuitable because it can damage JSON syntax or hit an unsigned description. A parser rejecting malformed JSON does not demonstrate that a valid but modified transfer body fails integrity verification. Keep the original export and create a separate modified copy.

Prepare the input

Use a compatible export with a receipts array and body strings. For a real-transfer demonstration, first complete and observe the devnet transaction, then export that operation's receipt. A fixture can be used to practice, but label it fixture throughout. Run the verifier on the original before modifying anything. If the original fails, investigate that failure instead of proceeding to a comparison whose baseline is already broken.

import json
from pathlib import Path
original = Path("receipt.json")
doc = json.loads(original.read_text(encoding="utf-8"))
for record in doc["receipts"]:
    body = json.loads(record["body"])
    value = body.get("lamports")
    if isinstance(value, int) and not isinstance(value, bool):
        body["lamports"] = value + 1
        record["body"] = json.dumps(body, separators=(",", ":"))
        break
else:
    raise SystemExit("No signed body with integer lamports; no copy written")
Path("receipt-tampered.json").write_text(
    json.dumps(doc, indent=2), encoding="utf-8"
)

The script does not update the stored digest or signature. That is intentional: the changed body should no longer match its original SHA-256. The bool check avoids Python's integer subtype behavior when validating input. If the export schema changes, adapt the script to the actual protected body rather than blindly finding an amount-looking field anywhere in the document.

Run both checks

Verify receipt.json, then receipt-tampered.json. Preserve the output and process status for each. The observed fixture demonstration returned PASS for the original and FAIL with a body digest mismatch after lamports increased by one. This is the expected comparison for a signed-content mutation. The tutorial itself does not produce a live transfer and should not be used to imply one.

Changing body serialization can also alter signed bytes. In this tutorial the amount change is explicit and meaningful, but the verifier protects exact content, not a normalized semantic interpretation. A stronger automated test inventory can isolate individual changes and test recomputed digests to reach signature validation. Those are separate tests; a video does not need to reproduce every parser and cryptographic case.

Explain the boundary in the video

Show the original receipt's operation identity, the original verification result, the changed lamports and the rejection. Say that signed receipt contents are integrity protected. Do not say every export field is signed. Notes, labels and other unsigned descriptive metadata can remain outside this guarantee. A documented boundary is more credible than an expansive claim a simple mutation can disprove.

Keep the evidence reusable

Store both files, their hashes, the checker revision and logs. If the export contains sensitive document names or account context, review whether it is appropriate for public publication; do not edit the original signed body to redact it and still call it the original. Use a separate development operation with non-sensitive data when preparing public evidence. The acceptance result is a valid baseline and rejected signed-content modification, with the fixture or real-transfer status made explicit.


Wiki home · Qualification updates · Sources and credits

EdgeORE

Home

Qualification updates

Sources and credits

Clone this wiki locally