# Verify onchain program

## Example program

```leo
// The 'verify_onchain' program.
program verify_onchain.aleo {
    // Example admin address that has authority to add or remove issuer
    const ADMIN: address = aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px; 

    struct Credentials {
        issuer: address,
        subject: address,
        dob: u32,
        nationality: field,
        expiry: u32
    }

    // Stores approved issuers
    mapping is_issuer: address => bool;

    async transition add_issuer(
        public issuer: address
    ) -> Future {
        assert_eq(self.caller, ADMIN);
        return add_issuer_finalize(issuer);
    }

    async function add_issuer_finalize(
        issuer: address
    ) {
        is_issuer.set(issuer, true);
    }

    async transition remove_issuer(
        public issuer: address
    ) -> Future {
        assert_eq(self.caller, ADMIN);
        return remove_issuer_finalize(issuer);
    }

    async function remove_issuer_finalize(
        issuer: address
    ) {
        is_issuer.set(issuer, false);
    }

    // msg and r are used to construct a public commitment for ownership verification
    // Any message works as long the prover is able to open the commitment
    async transition verify(
        msg: field,
        r: scalar,
        sig: signature,
        public issuer: address,
        dob: u32,
        nationality: field,
        expiry: u32
    ) -> (public field, Future) {
        let creds: Credentials = Credentials {
            issuer: issuer,
            subject: self.signer,
            dob: dob,
            nationality: nationality,
            expiry: expiry
        };
        let res: bool = signature::verify(sig, creds.issuer, Poseidon2::hash_to_field(creds));
        assert_eq(res, true);

        // Return the commitment publicly
        return (BHP256::commit_to_field(msg, r), verify_finalize(issuer));
    }

    async function verify_finalize(
        public issuer: address
    ) {
        // Ensure the issuer is approved
        assert_eq(is_issuer.get(issuer), true);
    }
}
```

Similar to verifying an off-chain program, but with on-chain storage, the approved issuer can be checked directly on the network without the need to manually read and compare the issuer's address.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zpass.docs.aleo.org/zpass-programs/verify-onchain-program.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
