use prost::Message;
use crate::fabric::protos::{
ChaincodeId, ChaincodeInput, ChaincodeInvocationSpec, ChaincodeProposalPayload, ChaincodeSpec,
};
pub(crate) const NONCE_LENGTH: usize = 24;
pub(crate) fn generate_transaction_id(nonce: &[u8], creator: &[u8]) -> String {
let salted_creator = [nonce, creator].concat();
let hash = openssl::sha::sha256(salted_creator.as_slice());
hex::encode(hash)
}
pub(crate) fn generate_nonce() -> [u8; 24] {
let mut nonce = [0u8; NONCE_LENGTH];
openssl::rand::rand_bytes(&mut nonce).expect("Unable to generate random bytes");
nonce
}
pub(crate) fn generate_sha256_hash(bytes: &[u8]) -> Vec<u8> {
let mut hasher = openssl::hash::Hasher::new(openssl::hash::MessageDigest::sha256()).unwrap();
hasher.update(bytes).unwrap();
hasher.finish().expect("Couldn't finalize hash").to_vec()
}
pub(crate) fn generate_chaincode_definition(
chaincode_id: ChaincodeId,
contract_id: Option<String>,
function_name: String,
function_args: Vec<Vec<u8>>,
) -> ChaincodeProposalPayload {
let mut args = if let Some(contract_id) = contract_id {
vec![
format!("{}:{}", contract_id, function_name)
.as_bytes()
.to_vec(),
]
} else {
vec![function_name.as_bytes().to_vec()]
};
for function_arg in function_args {
args.push(function_arg);
}
let chaincode_input = ChaincodeInput {
args,
decorations: std::collections::HashMap::default(), is_init: false,
};
let chaincode_spec = ChaincodeSpec {
r#type: crate::fabric::protos::chaincode_spec::Type::Golang.into(),
chaincode_id: Some(chaincode_id),
input: Some(chaincode_input),
timeout: 10,
};
let chaincode_invokation_spec = ChaincodeInvocationSpec {
chaincode_spec: Some(chaincode_spec),
};
ChaincodeProposalPayload {
input: chaincode_invokation_spec.encode_to_vec(),
transient_map: std::collections::HashMap::default(),
}
}