smplx-std 0.0.3

A blazingly-fast, ux-first simplicity development framework
Documentation
/*
 * Computes the "State Commitment" — the expected Script PubKey (address) 
 * for a specific state value.
 *
 * HOW IT WORKS:
 * In Simplicity/Liquid, state is not stored in a dedicated database. Instead, 
 * it is verified via a "Commitment Scheme" inside the Taproot tree of the UTXO.
 *
 * This function reconstructs the Taproot structure to validate that the provided 
 * witness data (state_data) was indeed cryptographically embedded into the 
 * transaction output that is currently being spent.
 *
 * LOGIC FLOW:
 * 1. Takes state_data (passed via witness at runtime).
 * 2. Hashes it as a non-executable TapData leaf.
 * 3. Combines it with the current program's CMR (tapleaf_hash).
 * 4. Derives the tweaked_key (Internal Key + Merkle Root).
 * 5. Returns the final SHA256 script hash (SegWit v1).
 *
 * USAGE:
 * - In main, we verify: CalculatedHash(witness::STATE) == input_script_hash.
 * - This assertion proves that the UTXO is "locked" not just by the code, 
 * but specifically by THIS instance of the state data.
 */

fn script_hash_for_input_script(state_data: u256) -> u256 {
    // This is the bulk of our "compute state commitment" logic from above.
    let tap_leaf: u256 = jet::tapleaf_hash();
    let state_ctx1: Ctx8 = jet::tapdata_init();
    let state_ctx2: Ctx8 = jet::sha_256_ctx_8_add_32(state_ctx1, state_data);
    let state_leaf: u256 = jet::sha_256_ctx_8_finalize(state_ctx2);
    let tap_node: u256 = jet::build_tapbranch(tap_leaf, state_leaf);

    // Compute a taptweak using this.
    let bip0341_key: u256 = 0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0;
    let tweaked_key: u256 = jet::build_taptweak(bip0341_key, tap_node);
    
    // Turn the taptweak into a script hash
    let hash_ctx1: Ctx8 = jet::sha_256_ctx_8_init();
    let hash_ctx2: Ctx8 = jet::sha_256_ctx_8_add_2(hash_ctx1, 0x5120); // Segwit v1, length 32
    let hash_ctx3: Ctx8 = jet::sha_256_ctx_8_add_32(hash_ctx2, tweaked_key);
    jet::sha_256_ctx_8_finalize(hash_ctx3)
}

fn main() {
    let state_data: u256 = witness::STATE;
    let (state1, state2, state3, state4): (u64, u64, u64, u64) = <u256>::into(state_data);
    
    // Assert that the input is correct, i.e. "load".
    assert!(jet::eq_256(
        script_hash_for_input_script(state_data),
        unwrap(jet::input_script_hash(jet::current_index()))
    ));

    // Do a state update (and fail on 64-bit overflow even though we've got 192 other
    // bits we could be using..)
    let (carry, new_state4): (bool, u64) = jet::increment_64(state4);
    assert!(jet::eq_1(<bool>::into(carry), 0));
    
    let new_state: u256 = <(u64, u64, u64, u64)>::into((state1, state2, state3, new_state4));
    // Assert that the output is correct, i.e. "store".
    assert!(jet::eq_256(
        script_hash_for_input_script(new_state),
        unwrap(jet::output_script_hash(jet::current_index()))
    ));
}