1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
use bitcoin::blockdata::script::Script;
use bitcoin::blockdata::transaction::Transaction;
use c_fixed_string::CFixedStr;
use cashaccount_sys::{
cashacc_account_destroy, cashacc_account_init, cashacc_parse_opreturn,
CASHACC_ERR_MALLOC_FAILED,
};
use std::ffi::CStr;
pub fn get_cashaccount_name(tx: &Transaction) -> Option<String> {
let mut opreturn_found = false;
let mut cashaccount_found = false;
let account = unsafe { cashacc_account_init() };
let _clean = scopeguard::guard((), |_| {
unsafe { cashacc_account_destroy(account) };
});
for out in tx.output.iter() {
if !out.script_pubkey.is_op_return() {
continue;
}
if opreturn_found {
return None;
}
opreturn_found = true;
let script: &Script = &out.script_pubkey;
let bytes = CFixedStr::from_bytes(script.as_bytes());
let rc =
unsafe { cashacc_parse_opreturn(bytes.as_ptr(), script.len() as u32, false, account) };
assert!(rc != CASHACC_ERR_MALLOC_FAILED);
if rc < 1 {
return None;
}
cashaccount_found = true;
}
if !cashaccount_found {
return None;
}
let name = unsafe { CStr::from_ptr((*account).name).to_str().unwrap() };
Some(name.to_string())
}