From c93d4c558588b715a8954afa5f14292625fbf398 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Tue, 12 Sep 2023 13:10:22 +0300 Subject: [PATCH 1/3] ethereum encodeParams now works for hex number formats --- crates/utils/Cargo.toml | 1 + crates/utils/src/encode.rs | 9 +++++++++ wraps/utils/tests/e2e.spec.ts | 3 +-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index 5c548e2..d1a12e3 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -17,3 +17,4 @@ serde = { version = "1.0.152", features = ["derive"] } serde_json = { version = "1.0.93", default-features = false, features = ["raw_value"] } ethers-core = { version="=2.0.2", features = [] } hex = { version = "0.4.3", default-features = false, features = ["alloc"] } +num-traits = { version = "0.2", default-features = false } diff --git a/crates/utils/src/encode.rs b/crates/utils/src/encode.rs index 12b9700..165a37c 100644 --- a/crates/utils/src/encode.rs +++ b/crates/utils/src/encode.rs @@ -9,6 +9,8 @@ use ethers_core::{ use crate::error::EncodeError; use std::str::FromStr; +use polywrap_wasm_rs::BigInt; +use num_traits::Num; pub fn encode_params(types: Vec, values: Vec) -> Vec { let tokens: Vec = values.iter() @@ -23,6 +25,13 @@ pub fn encode_params(types: Vec, values: Vec) -> Vec { if arg.starts_with("\"") && arg.ends_with("\"") { return LenientTokenizer::tokenize(&kind, arg.replace("\"", "").as_str()).unwrap(); } + if let ParamType::Uint(_) = &kind { + if arg.chars().any(char::is_alphabetic) { + let hex = if arg.starts_with("0x") { arg.strip_prefix("0x").unwrap() } else { arg.as_str() }; + let decimal = BigInt::from_str_radix(hex, 16).unwrap().to_string(); + return LenientTokenizer::tokenize(&kind, &decimal).unwrap() + } + } LenientTokenizer::tokenize(&kind, arg).unwrap() }) .collect(); diff --git a/wraps/utils/tests/e2e.spec.ts b/wraps/utils/tests/e2e.spec.ts index bda62cd..7c8f1d0 100644 --- a/wraps/utils/tests/e2e.spec.ts +++ b/wraps/utils/tests/e2e.spec.ts @@ -153,7 +153,7 @@ describe("Ethereum Wrapper", () => { expect(response.value).toBe(expected); }); - it.only("encodeParams", async () => { + it("encodeParams uint256", async () => { const response = await client.invoke({ uri, method: "encodeParams", @@ -163,7 +163,6 @@ describe("Ethereum Wrapper", () => { }, }); - console.log(response) if (!response.ok) throw response.error; const expected = ethers.utils.defaultAbiCoder.encode( From ab151dc08a2bb71713ac15f3b95e7f7b5e748ff2 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Tue, 12 Sep 2023 13:12:12 +0300 Subject: [PATCH 2/3] added hex number tokenization logic to tokenize_values in utils crate --- crates/utils/src/encode.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/utils/src/encode.rs b/crates/utils/src/encode.rs index 165a37c..5cadb43 100644 --- a/crates/utils/src/encode.rs +++ b/crates/utils/src/encode.rs @@ -76,6 +76,13 @@ pub fn tokenize_values(values: &Vec, params: &Vec) -> Vec if arg.starts_with("\"") && arg.ends_with("\"") { return LenientTokenizer::tokenize(¶m.kind, arg.replace("\"", "").as_str()).unwrap(); } + if let ParamType::Uint(_) = ¶m.kind { + if arg.chars().any(char::is_alphabetic) { + let hex = if arg.starts_with("0x") { arg.strip_prefix("0x").unwrap() } else { arg.as_str() }; + let decimal = BigInt::from_str_radix(hex, 16).unwrap().to_string(); + return LenientTokenizer::tokenize(¶m.kind, &decimal).unwrap() + } + } LenientTokenizer::tokenize(¶m.kind, arg).unwrap() }) .collect() From 786f57f23214ad30fdbecf68d0b820f0e8601b08 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Tue, 12 Sep 2023 13:19:52 +0300 Subject: [PATCH 3/3] refactored tokenization logic into private method --- crates/utils/src/encode.rs | 54 ++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/crates/utils/src/encode.rs b/crates/utils/src/encode.rs index 5cadb43..88c3809 100644 --- a/crates/utils/src/encode.rs +++ b/crates/utils/src/encode.rs @@ -9,6 +9,7 @@ use ethers_core::{ use crate::error::EncodeError; use std::str::FromStr; +use ethers_core::abi::Error; use polywrap_wasm_rs::BigInt; use num_traits::Num; @@ -17,22 +18,7 @@ pub fn encode_params(types: Vec, values: Vec) -> Vec { .zip(types.iter()) .map(|(arg, t)| { let kind = HumanReadableParser::parse_type(&t).unwrap(); - if let ParamType::Array(items) = &kind { - if let ParamType::Address = items.as_ref() { - return LenientTokenizer::tokenize(&kind, arg.replace("\"", "").as_str()).unwrap(); - } - } - if arg.starts_with("\"") && arg.ends_with("\"") { - return LenientTokenizer::tokenize(&kind, arg.replace("\"", "").as_str()).unwrap(); - } - if let ParamType::Uint(_) = &kind { - if arg.chars().any(char::is_alphabetic) { - let hex = if arg.starts_with("0x") { arg.strip_prefix("0x").unwrap() } else { arg.as_str() }; - let decimal = BigInt::from_str_radix(hex, 16).unwrap().to_string(); - return LenientTokenizer::tokenize(&kind, &decimal).unwrap() - } - } - LenientTokenizer::tokenize(&kind, arg).unwrap() + tokenize(&kind, arg).unwrap() }) .collect(); let bytes = encode(&tokens); @@ -68,22 +54,7 @@ pub fn tokenize_values(values: &Vec, params: &Vec) -> Vec .iter() .zip(values.iter()) .map(|(param, arg)| { - if let ParamType::Array(items) = ¶m.kind { - if let ParamType::Address = items.as_ref() { - return LenientTokenizer::tokenize(¶m.kind, arg.replace("\"", "").as_str()).unwrap(); - } - } - if arg.starts_with("\"") && arg.ends_with("\"") { - return LenientTokenizer::tokenize(¶m.kind, arg.replace("\"", "").as_str()).unwrap(); - } - if let ParamType::Uint(_) = ¶m.kind { - if arg.chars().any(char::is_alphabetic) { - let hex = if arg.starts_with("0x") { arg.strip_prefix("0x").unwrap() } else { arg.as_str() }; - let decimal = BigInt::from_str_radix(hex, 16).unwrap().to_string(); - return LenientTokenizer::tokenize(¶m.kind, &decimal).unwrap() - } - } - LenientTokenizer::tokenize(¶m.kind, arg).unwrap() + tokenize(¶m.kind, arg).unwrap() }) .collect() } @@ -117,3 +88,22 @@ pub fn encode_packed_bytes(bytes: String) -> String { let encoded = encode_packed(&[token]).unwrap(); format!("{}", Bytes::from(encoded)) } + +fn tokenize(kind: &ParamType, arg: &String) -> Result { + if let ParamType::Array(items) = &kind { + if let ParamType::Address = items.as_ref() { + return LenientTokenizer::tokenize(&kind, arg.replace("\"", "").as_str()); + } + } + if arg.starts_with("\"") && arg.ends_with("\"") { + return LenientTokenizer::tokenize(&kind, arg.replace("\"", "").as_str()); + } + if let ParamType::Uint(_) = &kind { + if arg.chars().any(char::is_alphabetic) { + let hex = if arg.starts_with("0x") { arg.strip_prefix("0x").unwrap() } else { arg.as_str() }; + let decimal = BigInt::from_str_radix(hex, 16).unwrap().to_string(); + return LenientTokenizer::tokenize(&kind, &decimal); + } + } + LenientTokenizer::tokenize(&kind, arg) +} \ No newline at end of file