Skip to content

Commit 9ee3576

Browse files
committed
Implement SolEncode and SolDecode for H160 and H256
1 parent 0424020 commit 9ee3576

File tree

2 files changed

+95
-5
lines changed

2 files changed

+95
-5
lines changed

crates/primitives/src/sol.rs

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ use ink_prelude::{
3232
};
3333

3434
pub use bytes::AsSolBytes;
35+
use primitive_types::{
36+
H160,
37+
H256,
38+
};
3539
pub use types::{
3640
SolTypeDecode,
3741
SolTypeEncode,
@@ -233,15 +237,14 @@ impl_refs_encode! {
233237
[] Box<T>,
234238
}
235239

236-
// AccountId
240+
// AccountId <-> bytes32
237241
impl SolDecode for AccountId {
238242
type SolType = AsSolBytes<[u8; 32]>;
239243

240244
fn from_sol_type(value: Self::SolType) -> Self {
241245
AccountId(value.0)
242246
}
243247
}
244-
245248
impl SolEncode for AccountId {
246249
type SolType = AsSolBytes<[u8; 32]>;
247250

@@ -260,15 +263,14 @@ impl SolEncode for AccountId {
260263
}
261264
}
262265

263-
// Hash
266+
// Hash <-> bytes32
264267
impl SolDecode for Hash {
265268
type SolType = AsSolBytes<[u8; 32]>;
266269

267270
fn from_sol_type(value: Self::SolType) -> Self {
268271
Hash::from(value.0)
269272
}
270273
}
271-
272274
impl SolEncode for Hash {
273275
type SolType = AsSolBytes<[u8; 32]>;
274276

@@ -286,3 +288,58 @@ impl SolEncode for Hash {
286288
Cow::Owned(AsSolBytes::<[u8; 32]>((*self).into()))
287289
}
288290
}
291+
292+
// H256 <-> bytes32
293+
impl SolDecode for H256 {
294+
type SolType = AsSolBytes<[u8; 32]>;
295+
296+
fn from_sol_type(value: Self::SolType) -> Self {
297+
H256(value.0)
298+
}
299+
}
300+
impl SolEncode for H256 {
301+
type SolType = AsSolBytes<[u8; 32]>;
302+
303+
fn encode(&self) -> Vec<u8> {
304+
// Override for better performance.
305+
sol_data::FixedBytes::abi_encode(&self.0)
306+
}
307+
308+
fn to_sol_type(&self) -> Cow<Self::SolType> {
309+
// NOTE: Not actually used for encoding because of `encode` override above (for
310+
// better performance).
311+
// Arbitrary newtype wrappers can achieve similar performance (without overriding
312+
// `encode`) by using `AsSolBytes<[u8; 32]>` as the inner type and returning
313+
// `Cow::Borrowed(&self.0)`.
314+
Cow::Owned(AsSolBytes(self.0))
315+
}
316+
}
317+
318+
// H160 <-> bytes20
319+
// TODO: (@davidsemakula) Evaluate if it's worth removing to mapping, changing it
320+
// `address` before v6 release. Rationale: while this mapping is technically correct, it
321+
// may be confusing for ink! devs, or just needless increase the cognitive load.
322+
impl SolDecode for H160 {
323+
type SolType = AsSolBytes<[u8; 20]>;
324+
325+
fn from_sol_type(value: Self::SolType) -> Self {
326+
H160(value.0)
327+
}
328+
}
329+
impl SolEncode for H160 {
330+
type SolType = AsSolBytes<[u8; 20]>;
331+
332+
fn encode(&self) -> Vec<u8> {
333+
// Override for better performance.
334+
sol_data::FixedBytes::abi_encode(&self.0)
335+
}
336+
337+
fn to_sol_type(&self) -> Cow<Self::SolType> {
338+
// NOTE: Not actually used for encoding because of `encode` override above (for
339+
// better performance).
340+
// Arbitrary newtype wrappers can achieve similar performance (without overriding
341+
// `encode`) by using `AsSolBytes<[u8; 32]>` as the inner type and returning
342+
// `Cow::Borrowed(&self.0)`.
343+
Cow::Owned(AsSolBytes(self.0))
344+
}
345+
}

crates/primitives/src/sol/tests.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ use ink_prelude::{
2929
string::String,
3030
vec::Vec,
3131
};
32-
use primitive_types::U256;
32+
use primitive_types::{
33+
H160,
34+
H256,
35+
U256,
36+
};
3337

3438
use crate::{
3539
sol::{
@@ -309,3 +313,32 @@ fn hash_works() {
309313
decoded_alloy.unwrap().0.as_slice()
310314
);
311315
}
316+
317+
#[test]
318+
fn h256_works() {
319+
let hash = H256([1; 32]);
320+
let bytes = SolFixedBytes([1; 32]);
321+
322+
let encoded = <H256 as SolEncode>::encode(&hash);
323+
let encoded_alloy = <SolFixedBytes<32> as SolValue>::abi_encode(&bytes);
324+
assert_eq!(encoded, encoded_alloy);
325+
326+
let decoded = <H256 as SolDecode>::decode(&encoded);
327+
let decoded_alloy = <SolFixedBytes<32> as SolValue>::abi_decode(&encoded, true);
328+
assert_eq!(decoded.unwrap().0, decoded_alloy.unwrap().0);
329+
}
330+
331+
#[test]
332+
fn h160_works() {
333+
// NOTE: We're currently mapping `H160` to `bytes20`.
334+
let hash = H160([1; 20]);
335+
let bytes = SolFixedBytes([1; 20]);
336+
337+
let encoded = <H160 as SolEncode>::encode(&hash);
338+
let encoded_alloy = <SolFixedBytes<20> as SolValue>::abi_encode(&bytes);
339+
assert_eq!(encoded, encoded_alloy);
340+
341+
let decoded = <H160 as SolDecode>::decode(&encoded);
342+
let decoded_alloy = <SolFixedBytes<20> as SolValue>::abi_decode(&encoded, true);
343+
assert_eq!(decoded.unwrap().0, decoded_alloy.unwrap().0);
344+
}

0 commit comments

Comments
 (0)