diff --git a/src/hash.rs b/src/hash.rs index ad918ef3d..5662d713c 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -9,6 +9,7 @@ use rand::Rng; use rand::os::OsRng; use bytes::BytesConvertable; use math::log2; +use uint::U256; /// types implementing FixedHash must be also BytesConvertable pub trait FixedHash: Sized + BytesConvertable { @@ -307,6 +308,16 @@ macro_rules! impl_hash { } } +impl<'a> From<&'a U256> for H256 { + fn from(value: &'a U256) -> H256 { + unsafe { + let mut ret: H256 = ::std::mem::uninitialized(); + value.to_bytes(&mut ret); + ret + } + } +} + impl_hash!(H32, 4); impl_hash!(H64, 8); impl_hash!(H128, 16); @@ -350,7 +361,7 @@ mod tests { #[test] fn shift_bloom() { use sha3::Hashable; - + let bloom = H2048::from_str("00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(); let address = Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap(); let topic = H256::from_str("02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap(); @@ -362,7 +373,7 @@ mod tests { my_bloom.shift_bloom(&address.sha3()); assert!(my_bloom.contains_bloom(&address.sha3())); assert!(!my_bloom.contains_bloom(&topic.sha3())); - + my_bloom.shift_bloom(&topic.sha3()); assert_eq!(my_bloom, bloom); assert!(my_bloom.contains_bloom(&address.sha3())); diff --git a/src/uint.rs b/src/uint.rs index c8e9d84de..693b9f471 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -186,6 +186,15 @@ macro_rules! construct_uint { (arr[index / 8] >> ((index % 8)) * 8) as u8 } + pub fn to_bytes(&self, bytes: &mut[u8]) { + assert!($n_words * 8 == bytes.len()); + let &$name(ref arr) = self; + for i in 0..bytes.len() { + let rev = bytes.len() - 1 - i; + let pos = rev / 8; + bytes[i] = (arr[pos] >> ((rev % 8) * 8)) as u8; + } + } /// Multiplication by u32 fn mul_u32(self, other: u32) -> $name { let $name(ref arr) = self; @@ -287,7 +296,7 @@ macro_rules! construct_uint { let mut sub_copy = self; let mut shift_copy = other; let mut ret = [0u64; $n_words]; - + let my_bits = self.bits(); let your_bits = other.bits(); @@ -453,7 +462,7 @@ construct_uint!(U128, 2); impl From for U256 { fn from(value: U128) -> U256 { - let U128(ref arr) = value; + let U128(ref arr) = value; let mut ret = [0; 4]; ret[0] = arr[0]; ret[1] = arr[1]; @@ -483,7 +492,7 @@ mod tests { assert_eq!(e, ub); assert_eq!(e, uc); assert_eq!(e, ud); - + // test initialization from bytes let va = U256::from(&[10u8][..]); assert_eq!(e, va); @@ -497,7 +506,7 @@ mod tests { assert_eq!(U256([0x12f0, 1 , 0x0910203040506077, 0x8090a0b0c0d0e0f0]), U256::from(&[ 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0x09, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x77, - 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x12u8, 0xf0][..])); assert_eq!(U256([0x00192437100019fa, 0x243710, 0, 0]), U256::from(&[ 0x24u8, 0x37, 0x10, @@ -514,6 +523,16 @@ mod tests { assert_eq!(U256([0x12f0, 1 , 0x0910203040506077, 0x8090a0b0c0d0e0f0]), U256::from_str("8090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0").unwrap()); } + #[test] + pub fn uint256_to() { + let hex = "8090a0b0c0d0e0f00910203040506077583a2cf8264910e1436bda32571012f0"; + let uint = U256::from_str(hex).unwrap(); + let mut bytes = [0u8; 32]; + uint.to_bytes(&mut bytes); + let uint2 = U256::from(&bytes[..]); + assert_eq!(uint, uint2); + } + #[test] pub fn uint256_bits_test() { assert_eq!(U256::from(0u64).bits(), 0); @@ -522,7 +541,7 @@ mod tests { assert_eq!(U256::from(300u64).bits(), 9); assert_eq!(U256::from(60000u64).bits(), 16); assert_eq!(U256::from(70000u64).bits(), 17); - + //// Try to read the following lines out loud quickly let mut shl = U256::from(70000u64); shl = shl << 100;