txtx_core/std/functions/
hash.rs1use ripemd::{Digest, Ripemd160 as LibRipemd160};
2use txtx_addon_kit::keccak_hash::keccak;
3use txtx_addon_kit::sha2::Sha256 as LibSha256;
4use txtx_addon_kit::types::AuthorizationContext;
5
6use txtx_addon_kit::{
7 define_function, indoc,
8 types::{
9 diagnostics::Diagnostic,
10 functions::{FunctionImplementation, FunctionSpecification},
11 types::{Type, Value},
12 },
13};
14
15use super::arg_checker;
16use crate::std::typing::StdValue;
17
18lazy_static! {
19 pub static ref FUNCTIONS: Vec<FunctionSpecification> = vec![
20 define_function! {
21 Ripemd160 => {
22 name: "ripemd160",
23 documentation: "`ripemd160` computes the Ripemd160 hash of a value.",
24 example: indoc!{r#"
25 output "hashed_data" {
26 value = ripemd160(encode_hex("hello, world"))
27 }
28 // > hashed_data: 0XA3201F82FCA034E46D10CD7B27E174976E241DA2
29 "#},
30 inputs: [
31 value: {
32 documentation: "The hex-encoded value to hash.",
33 typing: vec![Type::buffer(), Type::array(Type::buffer())]
34 }
35 ],
36 output: {
37 documentation: "The hashed result.",
38 typing: Type::string()
39 },
40 }
41 },
42 define_function! {
43 Sha256 => {
44 name: "sha256",
45 documentation: "`sha256` computes the sha256 hash of a value.",
46 example: indoc!{r#"
47 output "hashed_data" {
48 value = sha256(encode_hex("hello, world"))
49 }
50 // > hashed_data: 0x09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b
51 "#},
52 inputs: [
53 value: {
54 documentation: "The hex-encoded value to hash.",
55 typing: vec![Type::buffer(), Type::array(Type::buffer())]
56 }
57 ],
58 output: {
59 documentation: "The hashed result.",
60 typing: Type::string()
61 },
62 }
63 },
64 define_function! {
65 Keccak256 => {
66 name: "keccak256",
67 documentation: "`std::keccak256` computes the keccak256 hash of a value.",
68 example: indoc!{r#"
69 output "hashed_data" {
70 value = keccak256("hello, world")
71 }
72 // > hashed_data: 0x09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b
73 "#},
74 inputs: [
75 value: {
76 documentation: "The string value to hash.",
77 typing: vec![Type::string()]
78 }
79 ],
80 output: {
81 documentation: "The hashed result.",
82 typing: Type::string()
83 },
84 }
85 }
86 ];
87}
88
89pub struct Ripemd160;
90impl FunctionImplementation for Ripemd160 {
91 fn check_instantiability(
92 _fn_spec: &FunctionSpecification,
93 _auth_ctx: &AuthorizationContext,
94 _args: &Vec<Type>,
95 ) -> Result<Type, Diagnostic> {
96 unimplemented!()
97 }
98
99 fn run(
100 fn_spec: &FunctionSpecification,
101 _auth_ctx: &AuthorizationContext,
102 args: &Vec<Value>,
103 ) -> Result<Value, Diagnostic> {
104 let Some(value) = args.get(0) else {
105 return Err(diagnosed_error!("{}: expected 1 argument, got 0", fn_spec.name));
106 };
107
108 let mut hasher = LibRipemd160::new();
109 hasher.update(value.to_be_bytes());
110 let result = hasher.finalize();
111 Ok(StdValue::hash(result[..].to_vec()))
112 }
113}
114
115pub struct Sha256;
116impl FunctionImplementation for Sha256 {
117 fn check_instantiability(
118 _fn_spec: &FunctionSpecification,
119 _auth_ctx: &AuthorizationContext,
120 _args: &Vec<Type>,
121 ) -> Result<Type, Diagnostic> {
122 unimplemented!()
123 }
124
125 fn run(
126 fn_spec: &FunctionSpecification,
127 _auth_ctx: &AuthorizationContext,
128 args: &Vec<Value>,
129 ) -> Result<Value, Diagnostic> {
130 let Some(value) = args.get(0) else {
131 return Err(diagnosed_error!("{}: expected 1 argument, got 0", fn_spec.name));
132 };
133
134 let mut hasher = LibSha256::new();
135 hasher.update(value.to_be_bytes());
136 let result = hasher.finalize();
137 Ok(StdValue::hash(result[..].to_vec()))
138 }
139}
140
141pub struct Keccak256;
142impl FunctionImplementation for Keccak256 {
143 fn check_instantiability(
144 _fn_spec: &FunctionSpecification,
145 _auth_ctx: &AuthorizationContext,
146 _args: &Vec<Type>,
147 ) -> Result<Type, Diagnostic> {
148 unimplemented!()
149 }
150
151 fn run(
152 fn_spec: &FunctionSpecification,
153 _auth_ctx: &AuthorizationContext,
154 args: &Vec<Value>,
155 ) -> Result<Value, Diagnostic> {
156 arg_checker(fn_spec, args)?;
157 let value = args.get(0).unwrap().as_string().unwrap().to_string();
158 let hash = keccak(value.as_bytes());
159 Ok(StdValue::hash(hash.0.to_vec()))
160 }
161}