-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add ripemd160 to hash module * add bech32 module * fmt * fix names * fix test to use simple hex macro --------- Co-authored-by: beer-1 <[email protected]>
- Loading branch information
Showing
14 changed files
with
271 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
use bech32::{Bech32, Hrp}; | ||
use move_core_types::gas_algebra::NumBytes; | ||
use move_vm_runtime::native_functions::NativeFunction; | ||
use move_vm_types::{ | ||
loaded_data::runtime_types::Type, | ||
values::{Struct, Value}, | ||
}; | ||
use smallvec::{smallvec, SmallVec}; | ||
use std::collections::VecDeque; | ||
|
||
use crate::{ | ||
helpers::get_string, | ||
interface::{ | ||
RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeError, SafeNativeResult, | ||
}, | ||
safely_pop_arg, | ||
}; | ||
|
||
// See stdlib/error.move | ||
const ECATEGORY_INVALID_ARGUMENT: u64 = 0x1; | ||
|
||
// native errors always start from 100 | ||
const EUNABLE_TO_ENCODE: u64 = (ECATEGORY_INVALID_ARGUMENT << 16) + 100; | ||
const EUNABLE_TO_DECODE: u64 = (ECATEGORY_INVALID_ARGUMENT << 16) + 101; | ||
const EINVALID_PREFIX: u64 = (ECATEGORY_INVALID_ARGUMENT << 16) + 102; | ||
const EINVALID_ADDRESS: u64 = (ECATEGORY_INVALID_ARGUMENT << 16) + 103; | ||
|
||
/* | ||
native public fun encode(prefix: String, data: vector<u8>): String; | ||
native public fun decode(addr: String): (String, vector<u8>); | ||
*/ | ||
|
||
/*************************************************************************************************** | ||
* native fun encode | ||
* | ||
* gas cost: base_cost + unit_cost * (prefix_len + data_len) | ||
* | ||
**************************************************************************************************/ | ||
fn native_encode( | ||
context: &mut SafeNativeContext, | ||
ty_args: Vec<Type>, | ||
mut arguments: VecDeque<Value>, | ||
) -> SafeNativeResult<SmallVec<[Value; 1]>> { | ||
let gas_params = &context.native_gas_params.initia_stdlib; | ||
|
||
debug_assert!(ty_args.is_empty()); | ||
debug_assert_eq!(arguments.len(), 2); | ||
|
||
let data = safely_pop_arg!(arguments, Vec<u8>); | ||
let raw_prefix = get_string(safely_pop_arg!(arguments, Struct))?; | ||
let prefix = String::from_utf8(raw_prefix).map_err(|_| SafeNativeError::Abort { | ||
abort_code: EINVALID_PREFIX, | ||
})?; | ||
context.charge( | ||
gas_params.bech32_encode_base | ||
+ gas_params.bech32_encode_unit * NumBytes::new((prefix.len() + data.len()) as u64), | ||
)?; | ||
|
||
let encoded_string = bech32::encode::<Bech32>( | ||
Hrp::parse(prefix.as_str()).map_err(|_| SafeNativeError::Abort { | ||
abort_code: EINVALID_PREFIX, | ||
})?, | ||
data.as_slice(), | ||
) | ||
.map_err(|_| SafeNativeError::Abort { | ||
abort_code: EUNABLE_TO_ENCODE, | ||
})?; | ||
|
||
Ok(smallvec![Value::struct_(Struct::pack(vec![ | ||
Value::vector_u8(encoded_string.as_bytes().to_vec()), | ||
]))]) | ||
} | ||
|
||
/*************************************************************************************************** | ||
* native fun decode | ||
* | ||
* gas cost: base_cost + unit_cost * address_len | ||
* | ||
**************************************************************************************************/ | ||
fn native_decode( | ||
context: &mut SafeNativeContext, | ||
ty_args: Vec<Type>, | ||
mut arguments: VecDeque<Value>, | ||
) -> SafeNativeResult<SmallVec<[Value; 1]>> { | ||
let gas_params = &context.native_gas_params.initia_stdlib; | ||
|
||
debug_assert!(ty_args.is_empty()); | ||
debug_assert_eq!(arguments.len(), 1); | ||
|
||
let raw_addr = get_string(safely_pop_arg!(arguments, Struct))?; | ||
let addr = String::from_utf8(raw_addr).map_err(|_| SafeNativeError::Abort { | ||
abort_code: EINVALID_ADDRESS, | ||
})?; | ||
|
||
context.charge( | ||
gas_params.bech32_decode_base | ||
+ gas_params.bech32_decode_unit * NumBytes::new(addr.len() as u64), | ||
)?; | ||
|
||
let (prefix, words) = bech32::decode(addr.as_str()).map_err(|_| SafeNativeError::Abort { | ||
abort_code: EUNABLE_TO_DECODE, | ||
})?; | ||
|
||
Ok(smallvec![ | ||
Value::struct_(Struct::pack(vec![Value::vector_u8( | ||
prefix.as_bytes().to_vec() | ||
)])), | ||
Value::vector_u8(words) | ||
]) | ||
} | ||
|
||
/*************************************************************************************************** | ||
* module | ||
* | ||
**************************************************************************************************/ | ||
pub fn make_all( | ||
builder: &SafeNativeBuilder, | ||
) -> impl Iterator<Item = (String, NativeFunction)> + '_ { | ||
let natives = [ | ||
("encode", native_encode as RawSafeNative), | ||
("decode", native_decode), | ||
]; | ||
|
||
builder.make_named_natives(natives) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
module initia_std::bech32 { | ||
use initia_std::string::String; | ||
|
||
native public fun encode(prefix: String, data: vector<u8>): String; | ||
native public fun decode(addr: String): (String, vector<u8>); | ||
|
||
#[test_only] | ||
use initia_std::string; | ||
|
||
#[test] | ||
fun test_bech32_encode() { | ||
let prefix = string::utf8(b"init"); | ||
let data = x"12eafdba79c3dd7b90e3712ee475423153a722c7"; | ||
let got = encode(prefix, data); | ||
let expected = string::utf8(b"init1zt40mwnec0whhy8rwyhwga2zx9f6wgk8p3x098"); | ||
assert!(got == expected, 0); | ||
|
||
let prefix = string::utf8(b"celestia"); | ||
let data = x"12eafdba79c3dd7b90e3712ee475423153a722c7"; | ||
let got = encode(prefix, data); | ||
let expected = string::utf8(b"celestia1zt40mwnec0whhy8rwyhwga2zx9f6wgk87dhv5g"); | ||
assert!(got == expected, 1); | ||
} | ||
|
||
#[test] | ||
fun test_bech32_decode() { | ||
let addr = string::utf8(b"init1zt40mwnec0whhy8rwyhwga2zx9f6wgk8p3x098"); | ||
let (prefix, data) = decode(addr); | ||
assert!(prefix == string::utf8(b"init"), 0); | ||
assert!(data == x"12eafdba79c3dd7b90e3712ee475423153a722c7", 1); | ||
|
||
let addr = string::utf8(b"celestia1zt40mwnec0whhy8rwyhwga2zx9f6wgk87dhv5g"); | ||
let (prefix, data) = decode(addr); | ||
assert!(prefix == string::utf8(b"celestia"), 2); | ||
assert!(data == x"12eafdba79c3dd7b90e3712ee475423153a722c7", 3); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
module minitia_std::bech32 { | ||
use minitia_std::string::String; | ||
|
||
native public fun encode(prefix: String, data: vector<u8>): String; | ||
native public fun decode(addr: String): (String, vector<u8>); | ||
|
||
#[test_only] | ||
use minitia_std::string; | ||
|
||
#[test] | ||
fun test_bech32_encode() { | ||
let prefix = string::utf8(b"init"); | ||
let data = x"12eafdba79c3dd7b90e3712ee475423153a722c7"; | ||
let got = encode(prefix, data); | ||
let expected = string::utf8(b"init1zt40mwnec0whhy8rwyhwga2zx9f6wgk8p3x098"); | ||
assert!(got == expected, 0); | ||
|
||
let prefix = string::utf8(b"celestia"); | ||
let data = x"12eafdba79c3dd7b90e3712ee475423153a722c7"; | ||
let got = encode(prefix, data); | ||
let expected = string::utf8(b"celestia1zt40mwnec0whhy8rwyhwga2zx9f6wgk87dhv5g"); | ||
assert!(got == expected, 1); | ||
} | ||
|
||
#[test] | ||
fun test_bech32_decode() { | ||
let addr = string::utf8(b"init1zt40mwnec0whhy8rwyhwga2zx9f6wgk8p3x098"); | ||
let (prefix, data) = decode(addr); | ||
assert!(prefix == string::utf8(b"init"), 0); | ||
assert!(data == x"12eafdba79c3dd7b90e3712ee475423153a722c7", 1); | ||
|
||
let addr = string::utf8(b"celestia1zt40mwnec0whhy8rwyhwga2zx9f6wgk87dhv5g"); | ||
let (prefix, data) = decode(addr); | ||
assert!(prefix == string::utf8(b"celestia"), 2); | ||
assert!(data == x"12eafdba79c3dd7b90e3712ee475423153a722c7", 3); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters