ZiskStdin
ZiskStdin is the host-side, in-memory input buffer passed to the
guest program. Fill it with typed values or raw bytes before passing
it to prove() or execute(). For runtime-streamed inputs, use
ZiskStream instead.
Overview
The guest has no access to the outside world during execution. Every
byte it consumes must be loaded into a ZiskStdin (or a ZiskStream)
on the host before the run starts. ZiskStdin is a fully-buffered carrier:
every byte sits in memory before proving begins. Both ZiskStdin and
ZiskStream carry an Into<InputSource> implementation, so they are
interchangeable in client.prove(&program, ...) and client.execute(&program, ...).
Type
pub struct ZiskStdin(/* private */);
Constructors
new
Create an empty buffer.
pub fn new() -> ZiskStdin
Example
use zisk_sdk::ZiskStdin;
let stdin = ZiskStdin::new();
let proof = client.prove(&PROGRAM, stdin).run()?.await?;
from_bytes
Create a buffer pre-filled with raw bytes, equivalent to a new()
followed by a single write_slice.
pub fn from_bytes(bytes: Vec<u8>) -> ZiskStdin
Parameters
| Name | Type | Description |
|---|---|---|
bytes | Vec<u8> | Raw bytes to load as the initial buffer. |
Use this when the input already exists as a byte vector. For instance, when you build the bytes yourself or load them from a custom store.
from_file
Load a buffer from a binary file on disk. The file's contents become the entire input buffer.
pub fn from_file(path: impl AsRef<Path>) -> Result<ZiskStdin>
Parameters
| Name | Type | Description |
|---|---|---|
path | impl AsRef<Path> | Path to the binary input file. |
Returns
| Type | Description |
|---|---|
Result<ZiskStdin> | The loaded input, or an error if the file is missing. |
Use this to load pre-built inputs created by cargo-zisk or by a
previous stdin.save(...) call. Useful for reproducible test vectors.
Example
use zisk_sdk::ZiskStdin;
let stdin = ZiskStdin::from_file("inputs/test-vector.bin")?;
let proof = client.prove(&PROGRAM, stdin).run()?.await?;
from_uri
Load a buffer from a URI. Accepts a file:// URI (or None for an
empty buffer), letting the input location be configured at runtime.
pub fn from_uri<S: Into<String>>(uri: Option<S>) -> Result<ZiskStdin>
Parameters
| Name | Type | Description |
|---|---|---|
uri | Option<impl Into<String>> | Some(uri) to load from a file:// URI, None for an empty buffer. |
Write methods
write
Serialize value with bincode and append it to the input buffer.
Writes a u64 length header followed by the serialized bytes,
zero-padded to the next 8-byte boundary.
pub fn write<T: Serialize>(&self, data: &T)
Parameters
| Name | Type | Description |
|---|---|---|
data | &T: Serialize | The value to serialize and append. |
The guest reads this value with io::read::<T>(). The type T must
implement serde::Serialize on the host and serde::Deserialize on
the guest.
Example
let stdin = ZiskStdin::new();
// Typed primitives
stdin.write::<u64>(&3);
stdin.write::<u32>(&10);
// Typed struct
stdin.write(&MyStruct { x: 1, y: 2 });
// String
stdin.write(&String::from("Hello Zisk"));
write_slice
Append raw bytes to the input buffer with the same framing write
uses: a u64 length header followed by the bytes, zero-padded to
the next 8-byte boundary. The difference vs write is that the
bytes are not serialized through bincode.
pub fn write_slice(&self, data: &[u8])
Parameters
| Name | Type | Description |
|---|---|---|
data | &[u8] | Raw bytes to append to the buffer. |
Use write_slice when the data is already in a specific binary
format, or to avoid bincode overhead for large byte payloads.
Read methods
The read side mirrors the write side. It is most useful when the host
needs to inspect a ZiskStdin it received from elsewhere — for
example, replaying a saved test vector or asserting on the bytes built
by another layer of the application.
Each ZiskStdin carries an internal read cursor. The first read
starts at the beginning of the buffer; each subsequent read advances
the cursor past the value just consumed. Call reset or
rewind to bring the cursor back to the start.
read
Read and deserialize the next value from the buffer.
pub fn read<T: DeserializeOwned>(&self) -> Result<T>
Returns
| Type | Description |
|---|---|
Result<T> | The deserialized value, or an error on bad framing. |
The value is decoded with the same bincode configuration write uses.
The cursor advances past the length header and the payload (including
the 8-byte padding).
Example
let stdin = ZiskStdin::from_file("inputs/test-vector.bin")?;
let count: u64 = stdin.read()?;
let header: MyHeader = stdin.read()?;
read_bytes
Read the next raw byte record from the buffer.
pub fn read_bytes(&self) -> Vec<u8>
Returns
| Type | Description |
|---|---|
Vec<u8> | The bytes consumed at the current cursor. |
Pairs with write_slice on the host and io::read_slice on the
guest. Use it when you need to inspect raw payloads the host wrote
without going through bincode.
Cursor controls
reset
Reset the internal read position so the next read starts from the beginning of the buffer.
pub fn reset(&self)
rewind
Rewind the write cursor to the beginning. Equivalent to reset for the
read cursor.
pub fn rewind(&self)
clear
Clear the entire buffer. Subsequent reads see an empty input.
pub fn clear(&self)
Persistence
save
Write the buffered input to a binary file on disk.
pub fn save(&self, path: impl AsRef<Path>) -> Result<()>
Parameters
| Name | Type | Description |
|---|---|---|
path | impl AsRef<Path> | Destination path for the input file. |
The parent directory must exist. The file is created or overwritten if it already exists.
Example
let stdin = ZiskStdin::new();
stdin.write(&vec![10u32, 20, 30]);
stdin.write(&42u64);
stdin.save("inputs/test-vector.bin")?;