VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

How to Learn Blockchain Technology | Build a First Offline Coding Project

Three learners review open books together at a classroom table, with stacks of textbooks, stationery and a whiteboard in the bright room.

Your first blockchain-related coding project can be small, offline and fully explainable. You do not need to begin with a wallet, a deployed contract or a live node. This guide implements the previous article's data-reading exercise so you can connect a written rule, a pure function, an expected result and a test.

The complete Python file appears in this article, including its tests. It distinguishes a bounded hexadecimal integer profile from a bounded byte profile, formats exact integer counts and preserves the raw input in a reading card. The learning goal is understanding the implementation and its limits, not producing a general blockchain toolkit.

Everything uses synthetic data. The program has no network client, credentials, signing function, account access or transaction submission. It is a local educational lab, not a production RPC decoder, security audit, financial tool or claim of conformance with every relevant standard.

The featured photograph illustrates study, not a verified blockchain class.

Find your next learning step

How to Learn Blockchain Technology · Guide 18

Choose the question · Define the objects · Work the case · Check and vary · Test transfer

Chapter index · Complete learning route

Contents

Chapters 1–5

1. Choose an output small enough to explain

2. Preserve the offline authority boundary

3. Copy the complete contract before writing code

4. Separate shared syntax from typed meaning

5. Make invalid input a specified outcome

Chapters 6–10

6. Use integer arithmetic for the exact display

7. Write expected results independently of the implementation

8. Decide which claims the tests can support

9. Read the runtime requirements calmly

10. Inspect the complete program and tests

Chapters 11–15

11. Run one local command only if you choose

12. Interpret the recorded run accurately

13. Read a failure before editing the code

14. Check whether the tests notice deliberate mistakes

15. Add one feature only through a changed contract

Chapters 16–20

16. Keep a source-to-code crosswalk

17. Explain the implementation through teach-back

18. Assess the project with a ten-point rubric

19. Choose the next learning route deliberately

20. Hand off a reproducible learning result

CHAPTER 1 OF 20 · Learn and check

1. Choose an output small enough to explain

Back to contents

Define the project as four functions and a test suite. One function decodes NLab strings into integers. Another decodes BLab strings into bytes. A formatter turns an exact integer and declared scale into a fixed display. A composition function retains raw input, integer, scale and display in one result card.

This is a blockchain-related learning project because it practises representation, typing, exact quantities and evidence-preserving interpretation that recur in blockchain data work. It is not itself a blockchain. There are no blocks, consensus, persistent ledger, cryptographic proofs or distributed participants in this program.

Write that distinction at the top of your project note. A small program is useful when its purpose is clear. Calling it a complete chain or secure wallet would add unsupported meaning without improving the learning task. The technical library remains available for those different subjects when you have the prerequisites and a separately authorised project.

Your first milestone is to explain every function's input, output and failure condition before adding a user interface. If you cannot yet classify the six paper cards, return to the previous data-reading guide. Coding should make the rule inspectable, not hide an unresolved type distinction behind a button that appears to work.

Contents · Next

CHAPTER 2 OF 20 · Learn and check

2. Preserve the offline authority boundary

Back to contents

The program receives only explicit arguments. It does not read environment variables, open files, connect to services, restore keys or inspect accounts. Running the test suite prints local test results. It does not publish a page, send a message or change a remote system.

Do not add provider URLs or secrets to make this first task feel more realistic. The synthetic fixtures already contain everything needed to check the stated contract. A live integration would introduce new questions about identity, permissions, observation time, errors and service behaviour. Those deserve a separate task with its own scope and evidence.

Likewise, do not copy a real private key or customer record into the examples. Neither is needed to understand a parser or formatter. The security paper lab and Wallets and Custody: Map Who Can Act, Block and Recover provide routes for learning custody distinctions, but this project implements no custody operation and makes no recovery promise.

Keep a capability list in your project note: local string validation, integer conversion, byte conversion, exact display, composition and tests. Then list absent capabilities. This makes the boundary visible to a future reader or tutor. It also helps you notice scope expansion: if a proposed feature needs external authority or sensitive data, it is no longer a small unexamined addition to this offline exercise.

Contents · Previous · Next

CHAPTER 3 OF 20 · Learn and check

3. Copy the complete contract before writing code

Back to contents

NLab accepts only exact strings with lowercase0x prefix and one through 64 lowercase hexadecimal digits. A leading zero is forbidden unless the entire body is 0. It returns a nonnegative integer. BLab uses the same prefix and character set but permits an even body length from zero through 64; it returns bytes and retains leading zero pairs.

The formatter accepts exact Python integers q and d, explicitly excluding Booleans. It requires0 <= q < 2 to the power256 and0 <= d <= 6. It returns q divided by 10 to the power d as a string with exactly d fractional digits, or no decimal point when d 0. Invalid input raises ValueError in this lab.

The combined reader decodes NLab, applies the formatter and returns four fields: raw, integer, decimals and display. It performs no metadata lookup and does not guess a missing scale. The local length and lowercase restrictions are teaching choices, not claims about every blockchain field or client.

Use the specification-reading guide to check whether you have retained types, conditions and limits. A parser accepting more inputs may be useful for a different contract, but that does not make it correct for this one. Decide the contract first, then compare code and test outcomes with it.

Contents · Previous · Next

CHAPTER 4 OF 20 · Learn and check

4. Separate shared syntax from typed meaning

Back to contents

Both decoders need exact prefix, length and character checks, so the implementation shares a small helper called _body. The helper returns the validated body text. It does not decide whether that text is a valid integer representation or a whole-byte sequence.

NLab then applies its nonempty and minimal-representation conditions before integer conversion. BLab separately applies even length before byte conversion. Keeping those branches distinct prevents one profile's rule from leaking into the other. Empty text after the prefix is valid only on the BLab path.

This is a local example of separating responsibility, not a universal software architecture prescription. The architecture study guide and Monolithic and Modular Blockchains: Map the Responsibilities and Trust Boundaries explore responsibility mapping in wider systems. Here the complete program is small enough to inspect every branch without adding a framework or external package.

Draw a function map with the shared helper feeding two different typed results. Label integer and bytes explicitly. If a learner describes both outputs as decoded data, ask which operations each result supports under the contract. A clear type boundary is part of the explanation, even when a language can convert between representations through additional explicit functions. This lab deliberately does not add those extra conversions.

Contents · Previous · Next

CHAPTER 5 OF 20 · Learn and check

5. Make invalid input a specified outcome

Back to contents

The lab uses ValueError for every input outside its declared contract, including wrong types. That is an explicit API choice for this exercise. It is not a claim that every Python library should use the same exception type or that all production error reporting should be identical.

Inputs are rejected rather than silently trimmed, lowercased or padded. If the caller supplies0x01 to NLab, the original representation fails. If a future user interface wants to offer a repair, it should present that as a separately labelled transformation with its own rules, not pretend the original input passed.

A predictable failure path is testable. The suite includes missing prefixes, uppercase characters, spaces, nonhexadecimal characters, signs, wrong types and excessive lengths. The formatter tests Booleans, negative values, floats, strings and out-of-range scales. Each case checks a named condition rather than relying on a vague belief that the program handles errors.

For study, record an invalid input beside the expected exception and the requirement it exercises. A program that returns zero for a rejected value would blur failure and success. That would contradict this contract, even if a screen displaying0 looked tidy. The learner should be able to explain why preserving the distinction matters before adding any presentation layer.

Contents · Previous · Next

CHAPTER 6 OF 20 · Learn and check

6. Use integer arithmetic for the exact display

Back to contents

The formatter first checks q and d, then handles d 0 directly. For a positive d, it calculates whole and fraction using divmod with 10 to the power d. It formats the fraction to exactly d positions with leading zeros. No floating-point intermediate is needed for this contract.

The worked examples remain q 1250,d 2 ->12.50; q 1250,d 3 ->1.250; q 1001,d 3 ->1.001; and q 0,d 2 ->0.00. These strings preserve the selected display places. They do not imply measurement precision or a real asset's value.

Python's documentation describes integers as arbitrary precision and notes the relationship between Boolean and integer types. The code uses exact type checks to exclude Boolean parameters from this local contract rather than accepting them through integer-subtype behaviour. Python built-in types

Keep mathematical requirements separate from language choices. Another implementation could satisfy the same display rule with a different exact representation, but it would need appropriate evidence. The provided tests include a large synthetic integer so small examples are not the only check. Passing them supports the tested cases in the stated environment; it does not establish every language, runtime or future version.

Contents · Previous · Next

CHAPTER 7 OF 20 · Learn and check

7. Write expected results independently of the implementation

Back to contents

Before running code, preserve the paper answer set. The six cards produce three NLab successes and four BLab successes under the prior guide. The formatter's quotient and remainder determine its strings. These expected results should not be generated by asking the first implementation what it happens to return.

For NLab,0x0 returns0 and0xff returns255, while0x00 is rejected. For BLab,0x is empty bytes,0x00 is one zero byte and0x1 is rejected. Those contrasts are enough to expose several common rule confusions without querying a live network.

Tests should compare the actual result with the independently stated expectation. Rejection tests should check the specified exception. The Python unittest documentation explains assertion methods including equality and expected exceptions; our choice of fixtures and teaching contract is original. Python unittest documentation

Give each fixture a reason. A case with 0x0001 checks preservation of byte length; q 1001,d 3 checks fractional padding; a Boolean parameter checks exact type exclusion. Named reasons make failures easier to interpret. They also help you tell whether adding another test expands a meaningful boundary or merely repeats a case without improving your understanding of the contract.

Contents · Previous · Next

CHAPTER 8 OF 20 · Learn and check

8. Decide which claims the tests can support

Back to contents

A matching test provides evidence for its particular input, expected result and tested implementation. A collection of matching tests is useful, but it does not automatically prove complete correctness, security or compliance with an external standard. Keep the implementation version and environment attached to the result.

This lab includes ten test methods, several containing multiple cases. Two methods check round trips for values0 through 255: minimal hexadecimal integer strings and single-byte strings. Those loops examine finite sets. They do not exhaust every input up to 256 bits or every possible malformed string.

The boundary method checks the maximum accepted NLab value,32-byte BLab acceptance and the next oversized examples. That is targeted evidence for selected limits. It is not a resource-exhaustion audit or a claim that the code is suitable for hostile production traffic.

Use the learning portfolio to preserve both the successful observations and the missing coverage. A concise report might say ten methods passed in the named runtime with the supplied fixtures. Do not inflate that into universal correctness. The specification guide explains the same difference between document requirements and finite implementation evidence, while Reading a Blockchain Audit Packet: Code Versions, Proof Scope and Upgrade Authority provides a technical route for understanding the scope of assurance claims.

Contents · Previous · Next

CHAPTER 9 OF 20 · Learn and check

9. Read the runtime requirements calmly

Back to contents

The file uses Python's standard library only: re for the explicit character check and unittest for the local test suite. No package installation, account setup or network access is required by the program. The supplied version was run in a Python 3.12.14 environment during this publication workflow.

That run does not install Python on your device or establish that your local command points to the same interpreter. If you choose to run it, use an environment you are authorised to use and identify its version separately. A reader can also study the code and paper results without executing anything.

Keep the file name blockchain_data_lab.py so the running instructions and the included artifact refer to the same object. Save the entire code block, not just the first function. The tests belong in the same file for this deliberately small teaching project, reducing the number of moving parts a beginner must coordinate.

If a runtime or file-path problem occurs, separate it from a failed assertion. A command that cannot find the file has not evaluated the contract. A syntax error means the program did not complete its intended test run. A test failure means an observed result differs from its expectation. These call for different next checks, which the later troubleshooting section will make explicit.

Contents · Previous · Next

CHAPTER 10 OF 20 · Learn and check

10. Inspect the complete program and tests

Back to contents

The following native code block contains the complete file, including imports, all four public functions, the shared helper, ten test methods and the test-runner entry point. It is the same source supplied with this batch's downloadable materials. There are no omitted unchanged sections or secret configuration steps.

Read one function at a time against the contract. _body checks syntax and size; decode_quantity adds NLab's minimal nonempty rule; decode_data adds BLab's byte-pair rule; format_units checks exact integers and formats their quotient and remainder; read_quantity retains the interpretation fields together.

The tests are part of the teaching explanation. Find the input that exposes leading-zero confusion, the one that checks an empty byte sequence and the one that catches a missing fractional zero. Predict each result before reading its assertion. This connects code branches to the paper concepts rather than treating the suite as a magic green indicator.

Do not add network calls while copying the program. It needs none. Do not replace a failing assertion with the program's current output just to obtain a pass. If you deliberately change the contract, create a labelled new version and update the reasoning and expectations together. Otherwise, use the failure to locate which existing requirement the implementation has violated.

"""Offline teaching profile, not a production blockchain/RPC decoder."""
import re
import unittest

HEX = re.compile(r"[0-9a-f]*", re.ASCII)


def _body(text):
    if type(text) is not str:
        raise ValueError("expected a string")
    if not text.startswith("0x"):
        raise ValueError("expected lowercase 0x prefix")
    body = text[2:]
    if len(body) > 64 or HEX.fullmatch(body) is None:
        raise ValueError("expected at most 64 lowercase hex digits")
    return body


def decode_quantity(text):
    """NLab: zero or a minimal nonnegative hex integer, at most 64 digits."""
    body = _body(text)
    if not body or (len(body) > 1 and body[0] == "0"):
        raise ValueError("expected minimal nonempty quantity")
    return int(body, 16)


def decode_data(text):
    """BLab: zero to 32 bytes; each byte has exactly two hex digits."""
    body = _body(text)
    if len(body) % 2:
        raise ValueError("expected two hex digits per byte")
    return bytes.fromhex(body)


def format_units(amount, decimals):
    """Exact fixed-decimal display for this bounded educational profile."""
    if type(amount) is not int or not 0 <= amount < 2**256:
        raise ValueError("amount must be an integer in [0, 2**256)")
    if type(decimals) is not int or not 0 <= decimals <= 6:
        raise ValueError("decimals must be an integer from 0 to 6")
    if decimals == 0:
        return str(amount)
    whole, fraction = divmod(amount, 10**decimals)
    return f"{whole}.{fraction:0{decimals}d}"


def read_quantity(text, decimals):
    amount = decode_quantity(text)
    return {"raw": text, "integer": amount, "decimals": decimals,
            "display": format_units(amount, decimals)}


class DataLabTests(unittest.TestCase):
    def test_quantity_cases(self):
        for raw, expected in [("0x0", 0), ("0x1", 1), ("0xff", 255),
                              ("0x4e2", 1250), ("0x3e9", 1001)]:
            with self.subTest(raw=raw):
                self.assertEqual(decode_quantity(raw), expected)

    def test_quantity_rejections(self):
        for raw in ["0x", "0x00", "0x01", "0x04e2", "ff", "0X1",
                    "0xFF", " 0x1", "0x1 ", "0x-1", "0xg", True, 1, None]:
            with self.subTest(raw=raw):
                with self.assertRaises(ValueError):
                    decode_quantity(raw)

    def test_data_cases(self):
        for raw, expected in [("0x", b""), ("0x00", b"\x00"),
                              ("0x01", b"\x01"), ("0x0001", b"\x00\x01"),
                              ("0xff", b"\xff")]:
            with self.subTest(raw=raw):
                self.assertEqual(decode_data(raw), expected)

    def test_data_rejections(self):
        for raw in ["0x0", "0x1", "0x4e2", "0xGG", "0xFF", "00",
                    "0X00", "0x00 ", "0x 00", True, None]:
            with self.subTest(raw=raw):
                with self.assertRaises(ValueError):
                    decode_data(raw)

    def test_format_cases(self):
        for amount, decimals, expected in [(1250, 2, "12.50"),
                (1250, 3, "1.250"), (1001, 3, "1.001"),
                (1000, 3, "1.000"), (0, 2, "0.00"), (7, 0, "7"),
                (9007199254740993, 2, "90071992547409.93")]:
            with self.subTest(amount=amount, decimals=decimals):
                self.assertEqual(format_units(amount, decimals), expected)

    def test_format_rejections(self):
        for amount, decimals in [(True, 2), (-1, 2), (1.0, 2),
                ("1", 2), (1, True), (1, -1), (1, 7), (1, 2.0),
                (2**256, 2)]:
            with self.subTest(amount=amount, decimals=decimals):
                with self.assertRaises(ValueError):
                    format_units(amount, decimals)

    def test_read_card(self):
        self.assertEqual(read_quantity("0x4e2", 2),
            {"raw": "0x4e2", "integer": 1250, "decimals": 2, "display": "12.50"})
        with self.assertRaises(ValueError):
            read_quantity("0x4e2", 7)

    def test_bounds(self):
        self.assertEqual(decode_quantity("0x" + "f" * 64), 2**256 - 1)
        self.assertEqual(len(decode_data("0x" + "00" * 32)), 32)
        with self.assertRaises(ValueError):
            decode_quantity("0x1" + "0" * 64)
        with self.assertRaises(ValueError):
            decode_data("0x" + "00" * 33)

    def test_small_quantity_roundtrip(self):
        for amount in range(256):
            with self.subTest(amount=amount):
                self.assertEqual(decode_quantity(hex(amount)), amount)

    def test_single_byte_roundtrip(self):
        for amount in range(256):
            with self.subTest(amount=amount):
                value = bytes([amount])
                self.assertEqual(decode_data("0x" + value.hex()), value)


if __name__ == "__main__":
    unittest.main(verbosity=2)

Contents · Previous · Next

CHAPTER 11 OF 20 · Learn and check

11. Run one local command only if you choose

Back to contents

With the complete file saved in your chosen working folder and an appropriate Python 3 interpreter available, the local command is python3 blockchain_data_lab.py. Run it from the folder containing that file or use its actual path. This is a reader option, not an action this article performs on your machine.

The program's entry point invokes unittest with verbose output. It reports the test method names and whether they pass. It does not ask for a wallet, a seed phrase, a service endpoint or payment. If instructions elsewhere request those to run this file, they are not requirements of this teaching project.

Preserve the command, runtime version, source version and test output in your own study record if you actually execute it. Do not copy the publication's run report as though it were your local result. A reader who only inspected the source should label the task as code reading rather than execution.

You can then call a function interactively in a separately chosen local session, but that is not necessary for the supplied tests. Begin by predicting the read card for0x4e2 with scale 2: raw0x4e2, integer 1250, decimals2 and display12.50. The test already checks this exact composition, making the relationship between paper expectation and executable result visible.

python3 blockchain_data_lab.py

Contents · Previous · Next

CHAPTER 12 OF 20 · Learn and check

12. Interpret the recorded run accurately

Back to contents

During preparation, the supplied file completed ten unittest test methods successfully under Python 3.12.14. This includes the two finite round-trip loops and the listed valid, invalid, formatting, composition and boundary fixtures. The recorded result is about this file and run, not a test of a real blockchain node.

The output's “Ran 10 tests” counts test methods here, not ten individual input values. Several methods contain subtests, and each round-trip loop covers256 values. Do not claim that the headline count describes every comparison, or that the loops cover every possible input.

Execution speed printed by a test runner is incidental for this lesson. It is not a throughput benchmark and should not be compared with blockchain transaction rates. The program performs local conversions in a tiny teaching workload, with no network endpoint or accepted-state criterion.

If you run the file elsewhere, record your own observation and any differences. A different elapsed time does not imply a different semantic result; a failed assertion does. Keep these questions separate. The scaling and infrastructure learning guides provide deeper routes for workload boundaries and observations, but their measurement frameworks are not automatically supplied by a passing parser suite.

Contents · Previous · Next

CHAPTER 13 OF 20 · Learn and check

13. Read a failure before editing the code

Back to contents

Suppose the fractional-padding test reports expected1.001 but actual1.1. The likely violated relationship is padding the remainder to three places, not hexadecimal decoding. Inspect format_units and its declared display rule before changing the test. The same code can decode quantities correctly while formatting this case incorrectly.

Suppose the NLab rejection test accepts0x01. Inspect the minimal-body condition. Do not fix it by rejecting all leading-zero bytes in decode_data, because BLab intentionally retains them. A local failure should be repaired in the responsible function without importing the wrong profile's rule.

Suppose a Boolean amount is accepted. Check the exact type guard and the contract's explicit Boolean exclusion. Python's convenient numeric relationship does not override the local API rule. Preserve other correct cases while repairing this branch, then rerun the relevant tests and full suite.

For a command-not-found or missing-file error, check environment and path instead. No assertion has yet supplied evidence about the parser. This classification keeps incidental setup problems from becoming claims that the algorithm is wrong. A useful repair log states the observed failure, the requirement involved, the change made and the subsequent test result, rather than merely recording that it works now.

Contents · Previous · Next

CHAPTER 14 OF 20 · Learn and check

14. Check whether the tests notice deliberate mistakes

Back to contents

As an optional learning task, make a separately labelled experimental copy and deliberately remove the minimal-body rule, remove fractional padding or replace the byte-pair decision with the wrong condition. Predict which existing fixture should fail before executing that copy. Keep the supplied reference file unchanged.

This task is about inspecting the relationship between a fault and a test. It does not mean that tests capable of noticing a few deliberate mistakes can detect every defect. An untested path may still contain an error. Do not turn a small mutation exercise into a proof of complete coverage.

If a deliberate fault is not noticed, ask whether a suitable assertion exists and whether it actually reaches the changed branch. Add an independently justified fixture rather than an arbitrary extra test. If the fault is noticed, explain the failing requirement and preserve that observation in the portfolio.

Restore or return to the reference version when the experiment ends, keeping the experimental copy clearly identified. This article does not instruct you to edit a production service or weaken a security control. The program is offline and synthetic. The learning goal is to understand why a particular check matters, while keeping the original contract, reference source and experimental result distinct.

Contents · Previous · Next

CHAPTER 15 OF 20 · Learn and check

15. Add one feature only through a changed contract

Back to contents

Suppose you want uppercase hexadecimal letters to be accepted. That is a new local profile, not a bug fix to the lowercase-only reference. Write the revised condition, decide whether raw text remains unchanged in the read card and add fixtures showing the intended behaviour before altering the code.

Or suppose you want display scales beyond6. You must change the declared range and review the resource implications and tests. Do not remove the bound merely because a single larger example looks convenient. The current small limit is a teaching choice with a clear, testable role.

Adding a real provider connection is a larger change still. It requires a separate scope covering service identity, permissions, request parameters, state selection, response errors and provenance. Comparing Blockchain RPC Answers: Match the Network, Block and Question provides a technical reading route for the complete observation question. The current lab supplies none of those live integration guarantees.

The discipline is to version the task before expanding the implementation. Retain the original source and results so another reader can tell whether a changed output reflects a regression or a deliberately changed requirement. This connects directly to the specification-reading and governance learning guides: a released artifact, its required behaviour and an observed run are related objects, not interchangeable labels.

Contents · Previous · Next

CHAPTER 16 OF 20 · Learn and check

16. Keep a source-to-code crosswalk

Back to contents

Build a table with requirement, implementing function, fixture and limitation. For minimal integer representation, point to decode_quantity and a leading-zero rejection. For byte preservation, point to decode_data and0x0001. For display padding, point to format_units and q 1001,d 3. For result provenance within the lab, point to read_quantity's retained raw field.

The limitation column should remain concrete. Retaining raw text does not authenticate a real RPC source. Correct byte conversion does not validate a signature. Exact display does not establish economic value. Passing local fixtures does not demonstrate network compatibility. These are different missing relationships rather than one generic warning.

The real documents provide vocabulary and language-library behaviour. The bounded profiles, fixture choices, composition card and educational assessment are original. Preserve that distinction when you describe the source-to-code relationship. Do not attribute the64-digit or scale 6 limits to every external standard.

Use the learning portfolio to keep this crosswalk beside your first explanation and run evidence. It gives a future reader a direct path from an observed failure to the relevant rule and function. The same method can later scale to a separately authorised project, but the existence of a tidy crosswalk here does not certify the larger project's completeness or safety.

RequirementFunctionFixtureLimit
Minimal integerdecode_quantityReject 0x01Local NLab only
Byte preservationdecode_data0x0001 -> two bytesNo signature verification
Exact paddingformat_units1001, 3 -> 1.001No value or precision claim
Retain originalread_quantityraw + integer + scale + displayNo RPC-source authentication
An original source-to-code crosswalk with a separate limitation for each contribution.

Contents · Previous · Next

CHAPTER 17 OF 20 · Learn and check

17. Explain the implementation through teach-back

Back to contents

Close the source and explain why0x0 succeeds as NLab but fails BLab, why0x00 has the reverse outcome and why0xff can satisfy both while producing different output types. Then explain why q 1001,d 3 must display1.001. These questions connect branches to concepts rather than to memorised function names.

Next explain what the program never does. A complete short answer names the absence of network access, credentials, signing, remote state verification and transaction submission. It also identifies the local profile limits. This keeps implementation confidence from expanding into unsupported authority.

If you can run the suite but cannot explain a branch, return to the relevant paper case before adding features. If you understand the rule but the code fails it, make a targeted repair and rerun the tests. These are different learning gaps and should have different portfolio notes.

For bilingual study, preserve the identifiers, quantities, Boolean exclusions and failure rule across English and Chinese explanations. A fluent translation that turns empty bytes into integer zero has changed the concept. The teach-back guide provides a local assessment method, while this article supplies a new implementation object to explain. Use your actual results rather than inheriting the fictional scores from another lesson.

Contents · Previous · Next

CHAPTER 18 OF 20 · Learn and check

18. Assess the project with a ten-point rubric

Back to contents

Use five categories, two points each: state the complete local contract; explain the typed function boundaries; reproduce valid and rejected fixtures; explain exact display and type guards; and report execution evidence with its limits. Award two for all relationships present and correct, one for partial understanding and zero for absence or contradiction.

A learner who obtains a green run but calls BLab bytes an authenticated record should lose scope credit. A learner who explains NLab correctly but silently accepts Boolean scales should not receive full type-guard credit. The point is to connect observed work to a specific repair, not to reward the largest feature list.

This rubric is educational and local. It does not award a software qualification, prove production security or establish readiness to operate a real blockchain service. The included reference run belongs to the publication workflow; your own code-reading or execution task should be labelled accurately.

Save an initial explanation, any implementation change, the resulting tests and a fresh variation. If you copied the complete reference, describe it as studying and running the reference rather than independently designing every function. Honest assistance labels make the portfolio more informative. They show which connection you can now explain and what work remains before a wider claim would be justified.

Contents · Previous · Next

CHAPTER 19 OF 20 · Learn and check

19. Choose the next learning route deliberately

Back to contents

If types remain unclear, return to the preceding data-reading guide. If requirements drift during coding, return to the specification notebook. If an implementation runs but its meaning is hard to explain, use teach-back. These are targeted routes, not instructions to restart the whole curriculum.

For cryptographic verification, choose the relevant cryptography articles rather than adding a field called verified to this parser. For state transitions, use the published execution exercises. For network observations, use the infrastructure evidence notebook. Each new capability requires its own assumptions, task and checking evidence.

The next project could remain offline: a separately specified fixture reader or a given-rule state simulator. It should have complete premises and independent expected outcomes. A live contract or account integration is not an automatic next step merely because this file passes its tests.

Write one next task and one stopping point in the portfolio. For example, explain a changed lowercase rule and propose new fixtures without implementing live access. Progress is a growing set of relationships you can state, implement and check under declared conditions. Keep the programme's wider possibilities visible while protecting the clarity and bounded authority of the task you actually completed.

Contents · Previous · Next

CHAPTER 20 OF 20 · Learn and check

20. Hand off a reproducible learning result

Back to contents

A useful completion note identifies the source file, local profile, runtime, executed tests and limitations. For this supplied reference, the note is: “blockchain_data_lab.py implements the stated NLab, BLab and exact-display teaching contract. Ten test methods passed in Python 3.12.14 during preparation. The fixtures are synthetic and finite; the program performs no network access, signing or blockchain verification.”

If you only read the program, change the note to say code inspection and paper prediction. If you execute it yourself, record your own runtime and output. If you modify it, give the new version and revised contract. The evidence statement should match the work actually performed, not borrow the publication's result without distinction.

Keep the complete code, tests, source-to-code crosswalk and first explanation together. Another reader can then inspect a result, trace it to a requirement and understand a correction. That is a strong first project outcome even though the program is deliberately small.

Return to the learning hub for the next missing connection. The published library gives depth across blockchain technology; this lab demonstrates how a narrow slice can become an understandable implementation with explicit checks. Its value is not the breadth of its claims, but the clarity of the relationship between its rules, code, observed results and remaining limits.

Contents · Previous · Next

Continue learning

Technical article library

Sources and scope

NLab, BLab, their bounded display rules, fixtures and educational rubrics are original teaching profiles. The offline file is not a general RPC decoder, a security audit, a financial tool or a blockchain implementation. Linked technical articles retain their own examples and conditions. Sources and published routes checked on 15 October 2026. Reading and paper practice do not certify implementation competence.

Python built-in types

Python unittest