1use hashes::{sha256, Hash};
4
5use crate::ffi::sha256::CSha256Midstate;
6use crate::ffi::{c_size_t, c_uchar, c_uint, c_uint_fast32_t};
7
8#[derive(Debug)]
21pub struct RawOutputData {
22 pub asset: Vec<c_uchar>,
23 pub value: Vec<c_uchar>,
24 pub nonce: Vec<c_uchar>,
25 pub surjection_proof: Vec<c_uchar>,
26 pub range_proof: Vec<c_uchar>,
27}
28
29#[derive(Debug)]
30#[repr(C)]
31pub struct CRawBuffer {
32 pub ptr: *const c_uchar,
33 pub len: u32,
34}
35
36#[derive(Debug)]
38pub struct RawInputData {
39 pub annex: Option<Vec<c_uchar>>,
40 pub issuance_amount: Vec<c_uchar>,
42 pub issuance_inflation_keys: Vec<c_uchar>,
43 pub amount_range_proof: Vec<c_uchar>,
44 pub inflation_keys_range_proof: Vec<c_uchar>,
45 pub asset: Vec<c_uchar>,
47 pub value: Vec<c_uchar>,
48}
49
50#[derive(Debug)]
52pub struct RawTransactionData {
53 pub inputs: Vec<RawInputData>,
54 pub outputs: Vec<RawOutputData>,
55}
56
57#[derive(Debug)]
58#[repr(C)]
59pub struct CRawOutput {
60 asset: *const c_uchar,
61 value: *const c_uchar,
62 nonce: *const c_uchar,
63 script_pubkey: CRawBuffer,
64 surjection_proof: CRawBuffer,
65 range_proof: CRawBuffer,
66}
67
68#[derive(Debug)]
69#[repr(C)]
70pub struct CRawInput {
71 annex: *const CRawBuffer,
72 prev_txid: *const c_uchar,
73 pegin: *const c_uchar,
74 blinding_nonce: *const c_uchar,
76 asset_entropy: *const c_uchar,
77 amount: *const c_uchar,
78 inflation_keys: *const c_uchar,
79 amount_range_proof: CRawBuffer,
80 inflation_keys_range_proof: CRawBuffer,
81 asset: *const c_uchar,
83 value: *const c_uchar,
84 script_pubkey: CRawBuffer,
85 script_sig: CRawBuffer,
87 prev_txout_index: u32,
88 sequence: u32,
89}
90
91#[derive(Debug)]
92#[repr(C)]
93pub struct CRawTransaction {
94 txid: *const c_uchar,
95 inputs: *const CRawInput,
96 outputs: *const CRawOutput,
97 version: u32,
98 locktime: u32,
99 n_inputs: u32,
100 n_outputs: u32,
101}
102
103#[derive(Debug)]
104#[repr(C)]
105pub struct CRawTapEnv {
106 control_block: *const c_uchar,
107 script_cmr: *const c_uchar,
108 branch_len: u8,
109}
110
111#[derive(Debug)]
112pub enum CTransaction {}
113
114#[derive(Debug)]
115#[repr(C)]
116pub struct CElementsTxEnv {
117 tx: *const CTransaction,
118 taproot: *const CTapEnv,
119 genesis_hash: CSha256Midstate,
120 sighash_all: CSha256Midstate,
121 ix: c_uint_fast32_t,
122}
123
124#[derive(Debug)]
125pub enum CTapEnv {}
126
127extern "C" {
128
129 pub static c_sizeof_rawBuffer: c_size_t;
130 pub static c_sizeof_rawOutput: c_size_t;
131 pub static c_sizeof_rawInput: c_size_t;
132 pub static c_sizeof_rawTransaction: c_size_t;
133 pub static c_sizeof_rawTapEnv: c_size_t;
134 pub static c_sizeof_txEnv: c_size_t;
135
136 pub static c_alignof_rawBuffer: c_size_t;
137 pub static c_alignof_rawOutput: c_size_t;
138 pub static c_alignof_rawInput: c_size_t;
139 pub static c_alignof_rawTransaction: c_size_t;
140 pub static c_alignof_rawTapEnv: c_size_t;
141 pub static c_alignof_txEnv: c_size_t;
142
143 pub fn c_set_rawBuffer(res: *mut CRawBuffer, buf: *const c_uchar, len: c_uint);
144 pub fn c_set_rawOutput(
145 res: *mut CRawOutput,
146 asset: *const c_uchar,
147 value: *const c_uchar,
148 nonce: *const c_uchar,
149 scriptPubKey: *const CRawBuffer,
150 surjectionProof: *const CRawBuffer,
151 rangeProof: *const CRawBuffer,
152 );
153 pub fn c_set_rawInput(
154 result: *mut CRawInput,
155 annex: *const CRawBuffer,
156 pegin: *const c_uchar,
157 scriptSig: *const CRawBuffer,
158 prevTxid: *const c_uchar,
159 prevIx: c_uint,
160 asset: *const c_uchar,
161 value: *const c_uchar,
162 scriptPubKey: *const CRawBuffer,
163 sequence: c_uint,
164 blindingNonce: *const c_uchar,
165 assetEntropy: *const c_uchar,
166 amount: *const c_uchar,
167 inflationKeys: *const c_uchar,
168 amountRangePrf: *const CRawBuffer,
169 inflationKeysRangePrf: *const CRawBuffer,
170 );
171
172 pub fn c_set_rawTransaction(
173 result: *mut CRawTransaction,
174 version: c_uint,
175 txid: *const c_uchar,
176 input: *const CRawInput,
177 numInputs: c_uint,
178 output: *const CRawOutput,
179 numOutputs: c_uint,
180 lockTime: c_uint,
181 );
182 pub fn c_set_rawTapEnv(
183 result: *mut CRawTapEnv,
184 controlBlock: *const c_uchar,
185 pathLen: c_uchar,
186 scriptCMR: *const c_uchar,
187 );
188 pub fn c_set_txEnv(
189 result: *mut CElementsTxEnv,
190 tx: *const CTransaction,
191 taproot: *const CTapEnv,
192 genesisHash: *const c_uchar,
193 ix: c_uint,
194 );
195 pub fn simplicity_elements_mallocTapEnv(rawEnv: *const CRawTapEnv) -> *mut CTapEnv;
196 pub fn simplicity_elements_mallocTransaction(
197 rawTx: *const CRawTransaction,
198 ) -> *mut CTransaction;
199 pub fn c_free_transaction(tx: *mut CTransaction);
200 pub fn c_free_tapEnv(env: *mut CTapEnv);
201}
202impl CElementsTxEnv {
203 pub fn sighash_all(&self) -> sha256::Hash {
204 let midstate: sha256::Midstate = self.sighash_all.into();
205 sha256::Hash::from_byte_array(midstate.to_byte_array())
206 }
207}
208
209impl Drop for CElementsTxEnv {
211 fn drop(&mut self) {
212 unsafe {
213 crate::alloc::rust_0_4_free(self.tx as *mut u8);
214 crate::alloc::rust_0_4_free(self.taproot as *mut u8);
215 }
216 }
217}
218
219impl CRawBuffer {
220 pub fn new(buf: &[c_uchar]) -> Self {
221 unsafe {
222 let mut raw_buffer = std::mem::MaybeUninit::<CRawBuffer>::uninit();
223 c_set_rawBuffer(raw_buffer.as_mut_ptr(), buf.as_ptr(), buf.len() as c_uint);
224 raw_buffer.assume_init()
225 }
226 }
227}
228
229#[cfg(test)]
230mod tests {
231 use std::mem::{align_of, size_of};
232
233 use crate::c_jets::{c_env::*, frame_ffi::*};
234
235 #[test]
236 fn test_sizes() {
237 unsafe {
238 assert_eq!(size_of::<CFrameItem>(), c_sizeof_frameItem);
239 assert_eq!(size_of::<CRawBuffer>(), c_sizeof_rawBuffer);
240 assert_eq!(size_of::<CRawInput>(), c_sizeof_rawInput);
241 assert_eq!(size_of::<CRawOutput>(), c_sizeof_rawOutput);
242 assert_eq!(size_of::<CRawTransaction>(), c_sizeof_rawTransaction);
243 assert_eq!(size_of::<CRawTapEnv>(), c_sizeof_rawTapEnv);
244 assert_eq!(size_of::<CElementsTxEnv>(), c_sizeof_txEnv);
245 }
246 }
247
248 #[test]
249 fn test_aligns() {
250 unsafe {
251 assert_eq!(align_of::<CFrameItem>(), c_alignof_frameItem);
252 assert_eq!(align_of::<CRawBuffer>(), c_alignof_rawBuffer);
253 assert_eq!(align_of::<CRawInput>(), c_alignof_rawInput);
254 assert_eq!(align_of::<CRawOutput>(), c_alignof_rawOutput);
255 assert_eq!(align_of::<CRawTransaction>(), c_alignof_rawTransaction);
256 assert_eq!(align_of::<CRawTapEnv>(), c_alignof_rawTapEnv);
257 assert_eq!(align_of::<CElementsTxEnv>(), c_alignof_txEnv);
258 }
259 }
260}