Repository: CosmWasm/cosmwasm (rust)

Issue:
Change `CodeInfoResponse::checksum` from `HexBinary` to `cosmwasm_std::Checksum`
1. Move `cosmwasm_vm::Checksum` to `cosmwasm-std`.
 2. Change `CodeInfoResponse::checksum` from `HexBinary` to `cosmwasm_std::Checksum`.
 3. Change go-gen type mapping to:
    ```rust
    // both hex strings in JSON
    "HexBinary" => Some("string"),
    "Checksum" => Some("Checksum"),
    ```

_Originally posted by @webmaster128 in https://github.com/CosmWasm/cosmwasm/pull/1805#discussion_r1301837578_

Pull request:
Use `Checksum` for `CodeInfoResponse`
closes #1835 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 27c7b85a9..e922810d5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -53,6 +53,8 @@ and this project adheres to
   nested msg struct like in other messages. ([#1926])
 - cosmwasm-vm: Add `AnalysisReport::entrypoints` and make
   `AnalysisReport::required_capabilities` a `BTreeSet`. ([#1949])
+- cosmwasm-std: Add `Checksum` type and change type of
+  `CodeInfoResponse::checksum` to that. ([#1944])
 
 [#1874]: https://github.com/CosmWasm/cosmwasm/pull/1874
 [#1876]: https://github.com/CosmWasm/cosmwasm/pull/1876
@@ -66,6 +68,7 @@ and this project adheres to
 [#1939]: https://github.com/CosmWasm/cosmwasm/pull/1939
 [#1940]: https://github.com/CosmWasm/cosmwasm/pull/1940
 [#1941]: https://github.com/CosmWasm/cosmwasm/pull/1941
+[#1944]: https://github.com/CosmWasm/cosmwasm/pull/1944
 [#1949]: https://github.com/CosmWasm/cosmwasm/pull/1949
 
 ### Removed
@@ -83,6 +86,8 @@ and this project adheres to
   using `Instance::set_debug_handler`. ([#1953])
 - cosmwasm-vm: Remove `allow_interface_version_7` feature and all related
   functionality. ([#1952])
+- cosmwasm-vm: Remove `Checksum`. Use `cosmwasm_std::Checksum` instead.
+  ([#1944])
 
 [cw-storage-plus]: https://github.com/CosmWasm/cw-storage-plus
 [#1875]: https://github.com/CosmWasm/cosmwasm/pull/1875
diff --git a/contracts/virus/src/contract.rs b/contracts/virus/src/contract.rs
index 0a1235751..38b06f346 100644
--- a/contracts/virus/src/contract.rs
+++ b/contracts/virus/src/contract.rs
@@ -60,9 +60,9 @@ pub fn execute_spread(
 
         attributes.push(Attribute::new(format!("path{i}"), path.clone()));
 
-        let address = deps
-            .api
-            .addr_humanize(&instantiate2_address(&checksum, &creator, &salt)?)?;
+        let address =
+            deps.api
+                .addr_humanize(&instantiate2_address(checksum.as_ref(), &creator, &salt)?)?;
         attributes.push(Attribute::new(
             format!("predicted_address{i}"),
             address.clone(),
diff --git a/packages/go-gen/src/main.rs b/packages/go-gen/src/main.rs
index 7dd00d383..20779a289 100644
--- a/packages/go-gen/src/main.rs
+++ b/packages/go-gen/src/main.rs
@@ -198,7 +198,7 @@ pub fn build_enum_variant(
 #[cfg(test)]
 mod tests {
     use cosmwasm_schema::cw_serde;
-    use cosmwasm_std::{Binary, Empty, HexBinary, Uint128};
+    use cosmwasm_std::{Binary, Checksum, Empty, HexBinary, Uint128};
 
     use super::*;
 
@@ -241,6 +241,7 @@ mod tests {
             binary: Binary,
             nested_binary: Vec<Option<Binary>>,
             hex_binary: HexBinary,
+            checksum: Checksum,
             uint128: Uint128,
         }
 
@@ -252,7 +253,8 @@ mod tests {
             r#"
             type SpecialTypes struct {
                 Binary []byte `json:"binary"`
-                HexBinary Checksum `json:"hex_binary"`
+                Checksum Checksum `json:"checksum"`
+                HexBinary string `json:"hex_binary"`
                 NestedBinary []*[]byte `json:"nested_binary"`
                 Uint128 string `json:"uint128"`
             }"#,
@@ -357,7 +359,7 @@ mod tests {
         compare_codes!(cosmwasm_std::DelegatorValidatorsResponse);
         // wasm
         compare_codes!(cosmwasm_std::ContractInfoResponse);
-        // compare_codes!(cosmwasm_std::CodeInfoResponse); // TODO: Checksum type and "omitempty"
+        compare_codes!(cosmwasm_std::CodeInfoResponse);
     }
 
     #[test]
diff --git a/packages/go-gen/src/schema.rs b/packages/go-gen/src/schema.rs
index 496d0954c..346bc2989 100644
--- a/packages/go-gen/src/schema.rs
+++ b/packages/go-gen/src/schema.rs
@@ -261,7 +261,8 @@ pub fn custom_type_of(ty: &str) -> Option<&str> {
     match ty {
         "Uint128" => Some("string"),
         "Binary" => Some("[]byte"),
-        "HexBinary" => Some("Checksum"),
+        "HexBinary" => Some("string"),
+        "Checksum" => Some("Checksum"),
         "Addr" => Some("string"),
         "Decimal" => Some("string"),
         "Decimal256" => Some("string"),
diff --git a/packages/schema/src/idl.rs b/packages/schema/src/idl.rs
index e1390fa1b..dc47b239e 100644
--- a/packages/schema/src/idl.rs
+++ b/packages/schema/src/idl.rs
@@ -146,10 +146,55 @@ pub enum EncodeError {
 
 #[cfg(test)]
 mod tests {
+    use crate::schema_for;
+
     use super::*;
 
     #[test]
     fn version_is_semver() {
         semver::Version::parse(IDL_VERSION).unwrap();
     }
+
+    #[test]
+    fn to_schema_files_works() {
+        let empty = Api {
+            contract_name: "my_contract".to_string(),
+            contract_version: "1.2.3".to_string(),
+            instantiate: None,
+            execute: None,
+            query: None,
+            migrate: None,
+            sudo: None,
+            responses: None,
+        };
+
+        let files = empty.render().to_schema_files().unwrap();
+        assert_eq!(files, []);
+
+        #[derive(schemars::JsonSchema)]
+        struct TestMsg {}
+
+        let full = Api {
+            contract_name: "my_contract".to_string(),
+            contract_version: "1.2.3".to_string(),
+            instantiate: Some(schema_for!(TestMsg)),
+            execute: Some(schema_for!(TestMsg)),
+            query: Some(schema_for!(TestMsg)),
+            migrate: Some(schema_for!(TestMsg)),
+            sudo: Some(schema_for!(TestMsg)),
+            responses: Some(BTreeMap::from([(
+                "TestMsg".to_string(),
+                schema_for!(TestMsg),
+            )])),
+        };
+
+        let files = full.render().to_schema_files().unwrap();
+        assert_eq!(files.len(), 6);
+        assert_eq!(files[0].0, "instantiate.json");
+        assert_eq!(files[1].0, "execute.json");
+        assert_eq!(files[2].0, "query.json");
+        assert_eq!(files[3].0, "migrate.json");
+        assert_eq!(files[4].0, "sudo.json");
+        assert_eq!(files[5].0, "response_to_TestMsg.json");
+    }
 }
diff --git a/packages/std/src/checksum.rs b/packages/std/src/checksum.rs
new file mode 100644
index 000000000..1a6cfff04
--- /dev/null
+++ b/packages/std/src/checksum.rs
@@ -0,0 +1,229 @@
+use core::fmt;
+
+use schemars::JsonSchema;
+use serde::{de, ser, Deserialize, Deserializer, Serialize};
+use sha2::{Digest, Sha256};
+use thiserror::Error;
+
+use crate::{StdError, StdResult};
+
+/// A SHA-256 checksum of a Wasm blob, used to identify a Wasm code.
+/// This must remain stable since this checksum is stored in the blockchain state.
+///
+/// This is often referred to as "code ID" in go-cosmwasm, even if code ID
+/// usually refers to an auto-incrementing number.
+#[derive(JsonSchema, Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct Checksum(#[schemars(with = "String")] [u8; 32]);
+
+impl Checksum {
+    pub fn generate(wasm: &[u8]) -> Self {
+        Checksum(Sha256::digest(wasm).into())
+    }
+
+    /// Tries to parse the given hex string into a checksum.
+    /// Errors if the string contains non-hex characters or does not contain 32 bytes.
+    pub fn from_hex(input: &str) -> StdResult<Self> {
+        let mut binary = [0u8; 32];
+        hex::decode_to_slice(input, &mut binary).map_err(StdError::invalid_hex)?;
+
+        Ok(Self(binary))
+    }
+
+    /// Creates a lowercase hex encoded copy of this checksum.
+    ///
+    /// This takes an owned `self` instead of a reference because `Checksum` is cheap to `Copy`.
+    pub fn to_hex(self) -> String {
+        self.to_string()
+    }
+
+    /// Returns a reference to the inner bytes of this checksum as a slice.
+    /// If you need a reference to the array, use [`AsRef::as_ref`].
+    pub fn as_slice(&self) -> &[u8] {
+        &self.0
+    }
+}
+
+impl fmt::Display for Checksum {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        for byte in self.0.iter() {
+            write!(f, "{byte:02x}")?;
+        }
+        Ok(())
+    }
+}
+
+impl From<[u8; 32]> for Checksum {
+    fn from(data: [u8; 32]) -> Self {
+        Checksum(data)
+    }
+}
+
+impl AsRef<[u8; 32]> for Checksum {
+    fn as_ref(&self) -> &[u8; 32] {
+        &self.0
+    }
+}
+
+/// Serializes as a hex string
+impl Serialize for Checksum {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: ser::Serializer,
+    {
+        serializer.serialize_str(&self.to_hex())
+    }
+}
+
+/// Deserializes as a hex string
+impl<'de> Deserialize<'de> for Checksum {
+    fn deserialize<D>(deserializer: D) -> Result<Checksum, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        deserializer.deserialize_str(ChecksumVisitor)
+    }
+}
+
+struct ChecksumVisitor;
+
+impl<'de> de::Visitor<'de> for ChecksumVisitor {
+    type Value = Checksum;
+
+    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        formatter.write_str("valid hex encoded 32 byte checksum")
+    }
+
+    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+    where
+        E: de::Error,
+    {
+        match Checksum::from_hex(v) {
+            Ok(data) => Ok(data),
+            Err(_) => Err(E::custom(format!("invalid checksum: {v}"))),
+        }
+    }
+}
+
+#[derive(Error, Debug)]
+#[error("Checksum not of length 32")]
+pub struct ChecksumError;
+
+impl TryFrom<&[u8]> for Checksum {
+    type Error = ChecksumError;
+
+    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
+        if value.len() != 32 {
+            return Err(ChecksumError);
+        }
+        let mut data = [0u8; 32];
+        data.copy_from_slice(value);
+        Ok(Checksum(data))
+    }
+}
+
+impl From<Checksum> for Vec<u8> {
+    fn from(original: Checksum) -> Vec<u8> {
+        original.0.into()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    use crate::to_json_string;
+
+    #[test]
+    fn generate_works() {
+        let wasm = vec![0x68, 0x69, 0x6a];
+        let checksum = Checksum::generate(&wasm);
+
+        // echo -n "hij" | sha256sum
+        let expected = [
+            0x72, 0x2c, 0x8c, 0x99, 0x3f, 0xd7, 0x5a, 0x76, 0x27, 0xd6, 0x9e, 0xd9, 0x41, 0x34,
+            0x4f, 0xe2, 0xa1, 0x42, 0x3a, 0x3e, 0x75, 0xef, 0xd3, 0xe6, 0x77, 0x8a, 0x14, 0x28,
+            0x84, 0x22, 0x71, 0x04,
+        ];
+        assert_eq!(checksum.0, expected);
+    }
+
+    #[test]
+    fn implemented_display() {
+        let wasm = vec![0x68, 0x69, 0x6a];
+        let checksum = Checksum::generate(&wasm);
+        // echo -n "hij" | sha256sum
+        let embedded = format!("Check: {checksum}");
+        assert_eq!(
+            embedded,
+            "Check: 722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a142884227104"
+        );
+        assert_eq!(
+            checksum.to_string(),
+            "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a142884227104"
+        );
+    }
+
+    #[test]
+    fn from_hex_works() {
+        // echo -n "hij" | sha256sum
+        let checksum = "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a142884227104";
+        let parsed = Checksum::from_hex(checksum).unwrap();
+        assert_eq!(parsed, Checksum::generate(b"hij"));
+        // should be inverse of `to_hex`
+        assert_eq!(parsed.to_hex(), checksum);
+
+        // invalid hex
+        let too_short = "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a1428842271";
+        assert!(Checksum::from_hex(too_short).is_err());
+        let invalid_char = "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a1428842271g4";
+        assert!(Checksum::from_hex(invalid_char).is_err());
+        let too_long = "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a14288422710400";
+        assert!(Checksum::from_hex(too_long).is_err());
+    }
+
+    #[test]
+    fn to_hex_works() {
+        let wasm = vec![0x68, 0x69, 0x6a];
+        let checksum = Checksum::generate(&wasm);
+        // echo -n "hij" | sha256sum
+        assert_eq!(
+            checksum.to_hex(),
+            "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a142884227104"
+        );
+    }
+
+    #[test]
+    fn into_vec_works() {
+        let checksum = Checksum::generate(&[12u8; 17]);
+        let as_vec: Vec<u8> = checksum.into();
+        assert_eq!(as_vec, checksum.0);
+    }
+
+    #[test]
+    fn ref_conversions_work() {
+        let checksum = Checksum::generate(&[12u8; 17]);
+        // as_ref
+        let _: &[u8; 32] = checksum.as_ref();
+        let _: &[u8] = checksum.as_ref();
+        // as_slice
+        let _: &[u8; 32] = checksum.as_ref();
+        let _: &[u8] = checksum.as_ref();
+    }
+
+    #[test]
+    fn serde_works() {
+        // echo -n "hij" | sha256sum
+        let checksum =
+            Checksum::from_hex("722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a142884227104")
+                .unwrap();
+
+        let serialized = to_json_string(&checksum).unwrap();
+        assert_eq!(
+            serialized,
+            "\"722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a142884227104\""
+        );
+
+        let deserialized: Checksum = serde_json::from_str(&serialized).unwrap();
+        assert_eq!(deserialized, checksum);
+    }
+}
diff --git a/packages/std/src/lib.rs b/packages/std/src/lib.rs
index 559e9852f..b6536c28e 100644
--- a/packages/std/src/lib.rs
+++ b/packages/std/src/lib.rs
@@ -8,6 +8,7 @@ extern crate alloc;
 mod addresses;
 mod assertions;
 mod binary;
+mod checksum;
 mod coin;
 mod coins;
 mod conversion;
@@ -41,6 +42,7 @@ pub mod storage_keys;
 
 pub use crate::addresses::{instantiate2_address, Addr, CanonicalAddr, Instantiate2AddressError};
 pub use crate::binary::Binary;
+pub use crate::checksum::{Checksum, ChecksumError};
 pub use crate::coin::{coin, coins, has_coins, Coin};
 pub use crate::coins::Coins;
 pub use crate::deps::{Deps, DepsMut, OwnedDeps};
diff --git a/packages/std/src/query/wasm.rs b/packages/std/src/query/wasm.rs
index 91a36cac4..7c01040ee 100644
--- a/packages/std/src/query/wasm.rs
+++ b/packages/std/src/query/wasm.rs
@@ -1,7 +1,7 @@
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
 
-use crate::{Addr, Binary, HexBinary};
+use crate::{Addr, Binary, Checksum};
 
 use super::query_response::QueryResponseType;
 
@@ -70,14 +70,14 @@ pub struct CodeInfoResponse {
     /// The address that initially stored the code
     pub creator: Addr,
     /// The hash of the Wasm blob
-    pub checksum: HexBinary,
+    pub checksum: Checksum,
 }
 
 impl_response_constructor!(
     CodeInfoResponse,
     code_id: u64,
     creator: Addr,
-    checksum: HexBinary
+    checksum: Checksum
 );
 
 impl QueryResponseType for CodeInfoResponse {}
@@ -129,12 +129,12 @@ mod tests {
     #[test]
     #[cfg(feature = "cosmwasm_1_2")]
     fn code_info_response_serialization() {
-        use crate::HexBinary;
+        use crate::Checksum;
 
         let response = CodeInfoResponse {
             code_id: 67,
             creator: Addr::unchecked("jane"),
-            checksum: HexBinary::from_hex(
+            checksum: Checksum::from_hex(
                 "f7bb7b18fb01bbf425cf4ed2cd4b7fb26a019a7fc75a4dc87e8a0b768c501f00",
             )
             .unwrap(),
diff --git a/packages/vm/benches/main.rs b/packages/vm/benches/main.rs
index f171c7bec..5b014617a 100644
--- a/packages/vm/benches/main.rs
+++ b/packages/vm/benches/main.rs
@@ -6,12 +6,12 @@ use std::thread;
 use std::time::{Duration, SystemTime};
 use tempfile::TempDir;
 
-use cosmwasm_std::{coins, Empty};
+use cosmwasm_std::{coins, Checksum, Empty};
 use cosmwasm_vm::testing::{
     mock_backend, mock_env, mock_info, mock_instance_options, MockApi, MockQuerier, MockStorage,
 };
 use cosmwasm_vm::{
-    call_execute, call_instantiate, capabilities_from_csv, Cache, CacheOptions, Checksum, Instance,
+    call_execute, call_instantiate, capabilities_from_csv, Cache, CacheOptions, Instance,
     InstanceOptions, Size,
 };
 
diff --git a/packages/vm/src/cache.rs b/packages/vm/src/cache.rs
index 7ff54ebfe..5ba9291a2 100644
--- a/packages/vm/src/cache.rs
+++ b/packages/vm/src/cache.rs
@@ -7,9 +7,10 @@ use std::str::FromStr;
 use std::sync::Mutex;
 use wasmer::{Engine, Store};
 
+use cosmwasm_std::Checksum;
+
 use crate::backend::{Backend, BackendApi, Querier, Storage};
 use crate::capabilities::required_capabilities_from_module;
-use crate::checksum::Checksum;
 use crate::compatibility::check_wasm;
 use crate::errors::{VmError, VmResult};
 use crate::filesystem::mkdir_p;
diff --git a/packages/vm/src/checksum.rs b/packages/vm/src/checksum.rs
deleted file mode 100644
index c6aefc3fa..000000000
--- a/packages/vm/src/checksum.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-use std::fmt;
-
-use sha2::{Digest, Sha256};
-
-use crate::errors::VmError;
-
-/// A SHA-256 checksum of a Wasm blob, used to identify a Wasm code.
-/// This must remain stable since this checksum is stored in the blockchain state.
-///
-/// This is often referred to as "code ID" in go-cosmwasm, even if code ID
-/// usually refers to an auto-incrementing number.
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub struct Checksum([u8; 32]);
-
-impl Checksum {
-    pub fn generate(wasm: &[u8]) -> Self {
-        Checksum(Sha256::digest(wasm).into())
-    }
-
-    /// Creates a lowercase hex encoded copy of this checksum.
-    ///
-    /// This takes an owned `self` instead of a reference because `Checksum` is cheap to `Copy`.
-    pub fn to_hex(self) -> String {
-        self.to_string()
-    }
-}
-
-impl fmt::Display for Checksum {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        for byte in self.0.iter() {
-            write!(f, "{byte:02x}")?;
-        }
-        Ok(())
-    }
-}
-
-impl From<[u8; 32]> for Checksum {
-    fn from(data: [u8; 32]) -> Self {
-        Checksum(data)
-    }
-}
-
-impl TryFrom<&[u8]> for Checksum {
-    type Error = VmError;
-
-    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
-        if value.len() != 32 {
-            return Err(VmError::cache_err("Checksum not of length 32"));
-        }
-        let mut data = [0u8; 32];
-        data.copy_from_slice(value);
-        Ok(Checksum(data))
-    }
-}
-
-impl From<Checksum> for Vec<u8> {
-    fn from(original: Checksum) -> Vec<u8> {
-        original.0.into()
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn generate_works() {
-        let wasm = vec![0x68, 0x69, 0x6a];
-        let checksum = Checksum::generate(&wasm);
-
-        // echo -n "hij" | sha256sum
-        let expected = [
-            0x72, 0x2c, 0x8c, 0x99, 0x3f, 0xd7, 0x5a, 0x76, 0x27, 0xd6, 0x9e, 0xd9, 0x41, 0x34,
-            0x4f, 0xe2, 0xa1, 0x42, 0x3a, 0x3e, 0x75, 0xef, 0xd3, 0xe6, 0x77, 0x8a, 0x14, 0x28,
-            0x84, 0x22, 0x71, 0x04,
-        ];
-        assert_eq!(checksum.0, expected);
-    }
-
-    #[test]
-    fn implemented_display() {
-        let wasm = vec![0x68, 0x69, 0x6a];
-        let checksum = Checksum::generate(&wasm);
-        // echo -n "hij" | sha256sum
-        let embedded = format!("Check: {checksum}");
-        assert_eq!(
-            embedded,
-            "Check: 722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a142884227104"
-        );
-        assert_eq!(
-            checksum.to_string(),
-            "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a142884227104"
-        );
-    }
-
-    #[test]
-    fn to_hex_works() {
-        let wasm = vec![0x68, 0x69, 0x6a];
-        let checksum = Checksum::generate(&wasm);
-        // echo -n "hij" | sha256sum
-        assert_eq!(
-            checksum.to_hex(),
-            "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a142884227104"
-        );
-    }
-
-    #[test]
-    fn into_vec_works() {
-        let checksum = Checksum::generate(&[12u8; 17]);
-        let as_vec: Vec<u8> = checksum.into();
-        assert_eq!(as_vec, checksum.0);
-    }
-}
diff --git a/packages/vm/src/lib.rs b/packages/vm/src/lib.rs
index 05987bac7..5a858ed56 100644
--- a/packages/vm/src/lib.rs
+++ b/packages/vm/src/lib.rs
@@ -5,7 +5,6 @@ mod backend;
 mod cache;
 mod calls;
 mod capabilities;
-mod checksum;
 mod compatibility;
 mod conversion;
 mod environment;
@@ -41,7 +40,6 @@ pub use crate::calls::{
     call_ibc_packet_receive_raw, call_ibc_packet_timeout, call_ibc_packet_timeout_raw,
 };
 pub use crate::capabilities::capabilities_from_csv;
-pub use crate::checksum::Checksum;
 pub use crate::errors::{
     CommunicationError, CommunicationResult, RegionValidationError, RegionValidationResult,
     VmError, VmResult,
diff --git a/packages/vm/src/modules/file_system_cache.rs b/packages/vm/src/modules/file_system_cache.rs
index 58cac91b7..fd87d9cd4 100644
--- a/packages/vm/src/modules/file_system_cache.rs
+++ b/packages/vm/src/modules/file_system_cache.rs
@@ -6,9 +6,9 @@ use thiserror::Error;
 
 use wasmer::{AsEngineRef, DeserializeError, Module, Target};
 
-use crate::checksum::Checksum;
-use crate::errors::{VmError, VmResult};
+use cosmwasm_std::Checksum;
 
+use crate::errors::{VmError, VmResult};
 use crate::filesystem::mkdir_p;
 use crate::modules::current_wasmer_module_version;
 
diff --git a/packages/vm/src/modules/in_memory_cache.rs b/packages/vm/src/modules/in_memory_cache.rs
index 5b2eec52d..670816839 100644
--- a/packages/vm/src/modules/in_memory_cache.rs
+++ b/packages/vm/src/modules/in_memory_cache.rs
@@ -3,8 +3,10 @@ use std::collections::hash_map::RandomState;
 use std::num::NonZeroUsize;
 use wasmer::Module;
 
+use cosmwasm_std::Checksum;
+
 use super::cached_module::CachedModule;
-use crate::{Checksum, Size, VmError, VmResult};
+use crate::{Size, VmError, VmResult};
 
 // Minimum module size.
 // Based on `examples/module_size.sh`, and the cosmwasm-plus contracts.
diff --git a/packages/vm/src/modules/pinned_memory_cache.rs b/packages/vm/src/modules/pinned_memory_cache.rs
index 6177013b9..b003bed21 100644
--- a/packages/vm/src/modules/pinned_memory_cache.rs
+++ b/packages/vm/src/modules/pinned_memory_cache.rs
@@ -1,8 +1,9 @@
+use cosmwasm_std::Checksum;
 use std::collections::HashMap;
 use wasmer::Module;
 
 use super::cached_module::CachedModule;
-use crate::{Checksum, VmResult};
+use crate::VmResult;
 
 /// An pinned in memory module cache
 pub struct PinnedMemoryCache {


Test patch:
diff --git a/packages/go-gen/tests/cosmwasm_std__CodeInfoResponse.go b/packages/go-gen/tests/cosmwasm_std__CodeInfoResponse.go
index 1173e9e7f..54520073a 100644
--- a/packages/go-gen/tests/cosmwasm_std__CodeInfoResponse.go
+++ b/packages/go-gen/tests/cosmwasm_std__CodeInfoResponse.go
@@ -1,5 +1,5 @@
 type CodeInfoResponse struct {
-	Checksum Checksum `json:"checksum,omitempty"`
+	Checksum Checksum `json:"checksum"` // before wasmvm 2.0.0, this was `omitempty` (https://github.com/CosmWasm/wasmvm/issues/471)
 	CodeID   uint64   `json:"code_id"`
 	Creator  string   `json:"creator"`
 }
diff --git a/packages/std/src/testing/mock.rs b/packages/std/src/testing/mock.rs
index dcd52214a..0a90e98d1 100644
--- a/packages/std/src/testing/mock.rs
+++ b/packages/std/src/testing/mock.rs
@@ -2234,13 +2234,13 @@ mod tests {
                 }
                 #[cfg(feature = "cosmwasm_1_2")]
                 WasmQuery::CodeInfo { code_id } => {
-                    use crate::{CodeInfoResponse, HexBinary};
+                    use crate::{Checksum, CodeInfoResponse};
                     let code_id = *code_id;
                     if code_id == 4 {
                         let response = CodeInfoResponse {
                             code_id,
                             creator: Addr::unchecked("lalala"),
-                            checksum: HexBinary::from_hex(
+                            checksum: Checksum::from_hex(
                                 "84cf20810fd429caf58898c3210fcb71759a27becddae08dbde8668ea2f4725d",
                             )
                             .unwrap(),