Processing Orders with the order_accept
This tutorial guides developers through the `order_accept` web method in the `broadcast.asmx` C# web service, part of the TallyBox ecosystem. The method processes financial orders by validating inputs, checking balances, verifying cryptographic signatures, and storing orders in a database. It uses a tilde-separated `order_csv` string to receive order details and employs robust checks to ensure security and integrity. This tutorial focuses on the algorithm, logic, and data flow, with pseudo-code to aid implementation and understanding.
Step 1: Parse Order Data from order_csv
The `order_accept` method receives order details in a tilde (`~`) separated string (`order_csv`). The process involves:
- Split the `order_csv` string into an array using the tilde separator.
- Verify the first element is "tallybox" to confirm the parcel's starting point.
- Iterate through the array to extract key-value pairs (e.g., `graph_from`, `wallet_from`, `order_currency`) and assign values to variables.
- Expected fields include: `graph_from`, `graph_to`, `wallet_from`, `wallet_to`, `order_currency`, `order_amount`, `order_id`, `order_utc_unix`, `the_sign`, and `publicKey_xy_compressed`.
Pseudo-Code: Parse order_csv
                
FUNCTION parse_order_csv(order_csv):
    separators = ["~"]
    fields = split(order_csv, separators)
    IF fields[0] != "tallybox" THEN
        RETURN error("Invalid parcel starting point")
    END IF
    order_data = {}
    FOR i = 0 TO length(fields) - 2:
        key = fields[i]
        value = fields[i + 1]
        IF key IN ["graph_from", "graph_to", "wallet_from", "wallet_to", "order_currency", 
                   "order_amount", "order_id", "order_utc_unix", "the_sign", 
                   "publicKey_xy_compressed"]:
            order_data[key] = value
        END IF
    END FOR
    RETURN order_data
END FUNCTION
                
                
            Example Process:
                order_csv: tallybox~parcel_of_transaction~graph_from~tallybox.mixoftix.net~graph_to~tallybox.mixoftix.net~wallet_from~boxB2bbc15c8c135W8PzPEZf98cEu2h2muhkeJQS3MwTYUaTHVkFTgihcS7~wallet_to~boxB2bbc15c8c135W8PzPEZf98cEu2h2muhkeJQS3MwTYUaTHVkFTgihcS7~order_currency~2ZR~order_amount~3500.00000000~order_id~778844~order_utc_unix~1741675583~the_sign~MEYCIQCxzNKhOUXijLr+z2mI9npu/+KZijiEv3//W7Ya3VpvzgIhAI1m7wJLJ9ldP2m5jmYfUreuvoKTjoZmFQmt5e6foakp~publicKey_xy_compressed~2C7SVvEj45VMWwbd8UQNoYYWMeCMeyKm6qfDNQXhHkKK*1
                Parsed Output:
                graph_from: tallybox.mixoftix.net
                graph_to: tallybox.mixoftix.net
                wallet_from: boxB2bbc15c8c135W8PzPEZf98cEu2h2muhkeJQS3MwTYUaTHVkFTgihcS7
                wallet_to: boxB2bbc15c8c135W8PzPEZf98cEu2h2muhkeJQS3MwTYUaTHVkFTgihcS7
                order_currency: 2ZR
                order_amount: 3500.00000000
                order_id: 778844
                order_utc_unix: 1741675583
                the_sign: MEYCIQCxzNKhOUXijLr+z2mI9npu/+KZijiEv3//W7Ya3VpvzgIhAI1m7wJLJ9ldP2m5jmYfUreuvoKTjoZmFQmt5e6foakp
                publicKey_xy_compressed: 2C7SVvEj45VMWwbd8UQNoYYWMeCMeyKm6qfDNQXhHkKK*1
References:
                String.Split Method (Microsoft Docs)
                Delimiter-Separated Values (Wikipedia)
            
Step 2: Validate Input Formats
Validate the format of extracted order data to ensure compliance with expected standards. The process involves:
- Check that `graph_from` and `graph_to` contain a dot (`.`) to resemble domain names (e.g., `tallybox.mixoftix.net`).
- Verify `wallet_from` and `wallet_to` using a wallet quality check function (`wallet_qc`).
- Confirm `order_currency` is a recognized currency using an `iscurrency` function.
- Ensure `order_utc_unix` is a numeric value using an `isnumeric` function.
Pseudo-Code: Validate Formats
                
FUNCTION validate_formats(order_data):
    IF NOT contains(order_data.graph_from, ".") THEN
        RETURN error("305", "invalid graph format", "graph_from - " + order_data.graph_from)
    END IF
    IF NOT contains(order_data.graph_to, ".") THEN
        RETURN error("305", "invalid graph format", "graph_to - " + order_data.graph_to)
    END IF
    IF NOT wallet_qc(order_data.wallet_from) THEN
        RETURN error("301", "invalid wallet format", "wallet_from")
    END IF
    IF NOT wallet_qc(order_data.wallet_to) THEN
        RETURN error("301", "invalid wallet format", "wallet_to")
    END IF
    IF NOT iscurrency(order_data.order_currency) THEN
        RETURN error("302", "invalid currency", "order_currency")
    END IF
    IF NOT isnumeric(order_data.order_utc_unix) THEN
        RETURN error("303", "invalid numeric data", "order_utc_unix")
    END IF
    RETURN success
END FUNCTION
                
                
            Example Process:
                graph_from: tallybox.mixoftix.net (Valid: contains ".")
                graph_to: tallybox.mixoftix.net (Valid: contains ".")
                wallet_from: boxB2bbc15c8c135W8PzPEZf98cEu2h2muhkeJQS3MwTYUaTHVkFTgihcS7 (Valid: passes wallet_qc)
                wallet_to: boxB2bbc15c8c135W8PzPEZf98cEu2h2muhkeJQS3MwTYUaTHVkFTgihcS7 (Valid: passes wallet_qc)
                order_currency: 2ZR (Valid: recognized currency)
                order_utc_unix: 1741675583 (Valid: numeric)
                Result: Proceed to next step
References:
                Domain Name System (Wikipedia)
                String.Contains Method (Microsoft Docs)
            
Step 3: Verify Database Records
Ensure that `graph_from` and `graph_to` exist in the database. The process involves:
- Query the `tbl_system_graph` table to check if `graph_from` and `graph_to` are registered domains using a `sql_find_record` function.
- If either returns `no_record`, return an error (`207`).
Pseudo-Code: Verify Database Records
                
FUNCTION verify_database_records(order_data):
    graph_from_id = sql_find_record("tbl_system_graph", "graph_id", "graph_domain", order_data.graph_from)
    IF graph_from_id == "no_record" THEN
        RETURN error("207", "invalid graph", "graph_from")
    END IF
    graph_to_id = sql_find_record("tbl_system_graph", "graph_id", "graph_domain", order_data.graph_to)
    IF graph_to_id == "no_record" THEN
        RETURN error("207", "invalid graph", "graph_to")
    END IF
    RETURN success
END FUNCTION
                
                
            Example Process:
                graph_from: tallybox.mixoftix.net
                Database Query: SELECT graph_id FROM tbl_system_graph WHERE graph_domain = 'tallybox.mixoftix.net'
                Result: graph_id = 123 (Valid)
                graph_to: tallybox.mixoftix.net
                Database Query: SELECT graph_id FROM tbl_system_graph WHERE graph_domain = 'tallybox.mixoftix.net'
                Result: graph_id = 123 (Valid)
                Result: Proceed to next step
References:
                Database Concepts (Microsoft Docs)
                SQL (Wikipedia)
            
Step 4: Validate Treasury and Balances
Verify treasury orders (if `order_id` starts with `$`) and ensure sufficient balances for non-treasury orders. The process involves:
- Treasury Orders:
                        - Check if `order_id` exists in `tbl_system_treasury`.
- Ensure it hasn’t been used (check `tbl_tallybox_sign`).
- Verify that treasury’s currency, amount, and wallet match the order’s details.
 
- Non-Treasury Orders:
                        - Ensure `order_id` is numeric.
- Verify `wallet_from` has enough balance for fees (3 * 250.0 IRR).
- Check `wallet_from` balance for `order_amount` (plus fees if currency is IRR).
 
Pseudo-Code: Validate Treasury and Balances
                
FUNCTION validate_treasury_and_balances(order_data, base_fee_amount, base_fee_token):
    IF starts_with(order_data.order_id, "$"):
        treasury_id = sql_find_record("tbl_system_treasury", "treasury_id", "treasury_id", order_data.order_id)
        IF treasury_id == "no_record" THEN
            RETURN error("204", "invalid treasury_id", "order_id")
        END IF
        used_id = sql_find_record("tbl_tallybox_sign", "order_id", "order_id", order_data.order_id)
        IF used_id != "no_record" THEN
            RETURN error("205", "double spending error", "order_id")
        END IF
        treasury_currency = sql_find_record("tbl_system_treasury", "authorized_currency", "treasury_id", order_data.order_id)
        treasury_amount = sql_find_record("tbl_system_treasury", "authorized_amount", "treasury_id", order_data.order_id)
        treasury_wallet = sql_find_record("tbl_system_treasury", "authorized_wallet", "treasury_id", order_data.order_id)
        IF treasury_currency != order_data.order_currency OR 
           treasury_amount != order_data.order_amount OR 
           treasury_wallet != order_data.wallet_from THEN
            RETURN error("206", "treasury mismatch error", "order_id")
        END IF
    ELSE
        IF NOT isnumeric(order_data.order_id) THEN
            RETURN error("303", "invalid numeric data", "order_id")
        END IF
    END IF
    IF NOT isnumeric(order_data.order_amount) THEN
        RETURN error("303", "invalid numeric data", "order_amount")
    END IF
    IF NOT starts_with(order_data.order_id, "$"):
        fee_balance = wallet_left_amount(order_data.graph_from, order_data.wallet_from, base_fee_token)
        IF fee_balance < 3 * base_fee_amount THEN
            RETURN error("203", "no enough fee", "balance of " + base_fee_token + " < " + (3 * base_fee_amount))
        END IF
        IF order_data.order_currency == base_fee_token:
            total_balance = wallet_left_amount(order_data.graph_from, order_data.wallet_from, order_data.order_currency)
            IF total_balance < (order_data.order_amount + 3 * base_fee_amount) THEN
                RETURN error("204", "no enough balance", "order_amount: " + total_balance)
            END IF
        ELSE
            total_balance = wallet_left_amount(order_data.graph_from, order_data.wallet_from, order_data.order_currency)
            IF total_balance < order_data.order_amount THEN
                RETURN error("205", "no enough balance", "order_amount: " + total_balance)
            END IF
        END IF
    END IF
    RETURN success
END FUNCTION
                
                
            Example Process:
                order_id: 778844 (Non-treasury, numeric)
                order_amount: 3500.00000000 (Numeric)
                Fee Balance Check: wallet_left_amount(tallybox.mixoftix.net, wallet_from, IRR) = 1000.0 IRR
                Result: Valid (1000.0 > 3 * 250.0 = 750.0)
                Currency Balance Check: wallet_left_amount(tallybox.mixoftix.net, wallet_from, 2ZR) = 5000.0 2ZR
                Result: Valid (5000.0 > 3500.0)
                Result: Proceed to next step
References:
                Double-Spending (Wikipedia)
                Decimal Type (Microsoft Docs)
            
Step 5: Verify Cryptographic Signature
Verify the order’s authenticity using an ECDSA signature on the secp256r1 curve. The process involves:
- Construct the order string: `graph_from~graph_to~wallet_from~wallet_to~order_currency~order_amount~order_id~order_utc_unix`.
- Decompress the `publicKey_xy_compressed` to obtain the public key coordinates (X, Y).
- Verify the signature (`the_sign`) against the order string using ECDSA.
- If the signature is invalid, return an error (`300`).
Pseudo-Code: Verify Signature
                
FUNCTION verify_signature(order_data, the_sign, public_key_compressed):
    order_string = join([order_data.graph_from, order_data.graph_to, order_data.wallet_from, 
                         order_data.wallet_to, order_data.order_currency, order_data.order_amount, 
                         order_data.order_id, order_data.order_utc_unix], "~")
    public_key_decompressed = decompress_b58_in_b58_out(public_key_compressed.replace("*", "~"), "secp256r1")
    IF NOT sign_data_b64_check(order_string, the_sign, public_key_decompressed, "secp256r1") THEN
        RETURN error("300", "invalid sign", "the_sign")
    END IF
    RETURN success
END FUNCTION
                
                
            Example Process:
                Order String: tallybox.mixoftix.net~tallybox.mixoftix.net~boxB2bbc15c8c135W8PzPEZf98cEu2h2muhkeJQS3MwTYUaTHVkFTgihcS7~boxB2bbc15c8c135W8PzPEZf98cEu2h2muhkeJQS3MwTYUaTHVkFTgihcS7~2ZR~3500.00000000~778844~1741675583
                Signature: MEYCIQCxzNKhOUXijLr+z2mI9npu/+KZijiEv3//W7Ya3VpvzgIhAI1m7wJLJ9ldP2m5jmYfUreuvoKTjoZmFQmt5e6foakp
                Public Key (Compressed): 2C7SVvEj45VMWwbd8UQNoYYWMeCMeyKm6qfDNQXhHkKK*1
                Signature Verification Result: Valid
References:
                ECDSA Algorithm (Wikipedia)
                SEC 2: Recommended Elliptic Curve Domain Parameters (secp256r1)
            
Step 6: Save Order to Database
Store the validated order in a sharded database table. The process involves:
- Generate the current Unix timestamp (`local_utc_unix`).
- Use the last digit of the timestamp to select a table shard (`tbl_order_dispatcher_X`).
- Construct and execute an SQL INSERT statement with order details.
- Return a success response: `submitted~200~`. 
Pseudo-Code: Save Order
                
FUNCTION save_order(order_data):
    local_utc_unix = get_current_unix_timestamp()
    dispatcher_line = last_digit(local_utc_unix)
    sql = "INSERT INTO tbl_order_dispatcher_" + dispatcher_line + " " +
          "(graph_from, graph_to, wallet_from, wallet_to, order_currency, order_amount, " +
          "order_utc_unix, order_id, public_key, the_sign, local_utc_unix) " +
          "VALUES ('" + order_data.graph_from + "', '" + order_data.graph_to + "', '" +
          order_data.wallet_from + "', '" + order_data.wallet_to + "', '" +
          order_data.order_currency + "', '" + order_data.order_amount + "', '" +
          order_data.order_utc_unix + "', '" + order_data.order_id + "', '" +
          order_data.publicKey_xy_compressed + "', '" + order_data.the_sign + "', '" +
          local_utc_unix + "')"
    run_sql(sql)
    RETURN "submitted~200~" + local_utc_unix
END FUNCTION
                
                
            Example Output:
                
References:
                SQL INSERT Statement (Microsoft Docs)
                Unix Time (Wikipedia)
            
Acknowledgments
Special thanks to Grok, for its invaluable assistance in creating this TallyBox order acceptance tutorial.