ergo_lib_c_core/
input.rs

1//! Ergo input
2
3use ergo_lib::{chain, ergotree_interpreter::sigma_protocol::prover::ProofBytes};
4
5use crate::{
6    context_extension::{ContextExtension, ContextExtensionPtr},
7    ergo_box::{BoxId, BoxIdPtr},
8    util::{const_ptr_as_ref, mut_ptr_as_mut},
9    Error,
10};
11
12/// Unsigned inputs used in constructing unsigned transactions
13#[derive(PartialEq, Eq, Debug, Clone)]
14pub struct UnsignedInput(pub chain::transaction::UnsignedInput);
15pub type UnsignedInputPtr = *mut UnsignedInput;
16pub type ConstUnsignedInputPtr = *const UnsignedInput;
17
18/// Get box id
19pub unsafe fn unsigned_input_box_id(
20    unsigned_input_ptr: ConstUnsignedInputPtr,
21    box_id_out: *mut BoxIdPtr,
22) -> Result<(), Error> {
23    let box_id_out = mut_ptr_as_mut(box_id_out, "box_id_out")?;
24    let unsigned_input = const_ptr_as_ref(unsigned_input_ptr, "unsigned_input_ptr")?;
25    let box_id = BoxId(unsigned_input.0.box_id);
26    *box_id_out = Box::into_raw(Box::new(box_id));
27    Ok(())
28}
29
30/// Get extension
31pub unsafe fn unsigned_input_context_extension(
32    unsigned_input_ptr: ConstUnsignedInputPtr,
33    context_extension_out: *mut ContextExtensionPtr,
34) -> Result<(), Error> {
35    let context_extension_out = mut_ptr_as_mut(context_extension_out, "context_extension_out")?;
36    let unsigned_input = const_ptr_as_ref(unsigned_input_ptr, "unsigned_input_ptr")?;
37    let context_extension = ContextExtension(unsigned_input.0.extension.clone());
38    *context_extension_out = Box::into_raw(Box::new(context_extension));
39    Ok(())
40}
41
42/// Signed inputs used in signed transactions
43#[derive(PartialEq, Eq, Debug, Clone)]
44pub struct Input(pub(crate) chain::transaction::Input);
45pub type InputPtr = *mut Input;
46pub type ConstInputPtr = *const Input;
47
48/// Get box id
49pub unsafe fn input_box_id(
50    input_ptr: ConstInputPtr,
51    box_id_out: *mut BoxIdPtr,
52) -> Result<(), Error> {
53    let box_id_out = mut_ptr_as_mut(box_id_out, "box_id_out")?;
54    let input = const_ptr_as_ref(input_ptr, "input_ptr")?;
55    let box_id = BoxId(input.0.box_id);
56    *box_id_out = Box::into_raw(Box::new(box_id));
57    Ok(())
58}
59
60/// Get the spending proof
61pub unsafe fn input_spending_proof(
62    input_ptr: ConstInputPtr,
63    prover_result_out: *mut ProverResultPtr,
64) -> Result<(), Error> {
65    let prover_result_out = mut_ptr_as_mut(prover_result_out, "prover_result_out")?;
66    let input = const_ptr_as_ref(input_ptr, "input_ptr")?;
67    let prover_result = ProverResult(input.0.spending_proof.clone());
68    *prover_result_out = Box::into_raw(Box::new(prover_result));
69    Ok(())
70}
71
72/// Proof of correctness of tx spending
73#[derive(PartialEq, Eq, Debug, Clone)]
74pub struct ProverResult(chain::transaction::input::prover_result::ProverResult);
75pub type ProverResultPtr = *mut ProverResult;
76pub type ConstProverResultPtr = *const ProverResult;
77
78/// Return the number of bytes that make up the proof.
79pub unsafe fn prover_result_proof_len(
80    prover_result_ptr: ConstProverResultPtr,
81) -> Result<usize, Error> {
82    let prover_result = const_ptr_as_ref(prover_result_ptr, "prover_result_ptr")?;
83    Ok(match &prover_result.0.proof {
84        ProofBytes::Some(b) => b.len(),
85        ProofBytes::Empty => 0,
86    })
87}
88
89/// Get proof. Key assumption: enough memory has been allocated at the address pointed-to by
90/// `output`. Use `prover_result_proof_len` to determine the length of the byte
91/// array.
92pub unsafe fn prover_result_proof(
93    prover_result_ptr: ConstProverResultPtr,
94    output: *mut u8,
95) -> Result<(), Error> {
96    let prover_result = const_ptr_as_ref(prover_result_ptr, "prover_result_ptr")?;
97    let src: Vec<_> = prover_result.0.proof.clone().into();
98    std::ptr::copy_nonoverlapping(src.as_ptr(), output, src.len());
99    Ok(())
100}
101
102/// Get extension
103pub unsafe fn prover_result_context_extension(
104    prover_result_ptr: ConstProverResultPtr,
105    context_extension_out: *mut ContextExtensionPtr,
106) -> Result<(), Error> {
107    let prover_result = const_ptr_as_ref(prover_result_ptr, "prover_result_ptr")?;
108    let context_extension_out = mut_ptr_as_mut(context_extension_out, "context_extension_out")?;
109    *context_extension_out = Box::into_raw(Box::new(ContextExtension(
110        prover_result.0.extension.clone(),
111    )));
112    Ok(())
113}
114
115/// JSON representation as text (compatible with Ergo Node/Explorer API, numbers are encoded as numbers)
116pub unsafe fn prover_result_to_json(
117    prover_result_ptr: ConstProverResultPtr,
118) -> Result<String, Error> {
119    let prover_result = const_ptr_as_ref(prover_result_ptr, "prover_result_ptr")?;
120    let s = serde_json::to_string_pretty(&prover_result.0.clone())?;
121    Ok(s)
122}