Skip to content

Latest commit

 

History

History
587 lines (504 loc) · 33 KB

v0.9_to_v1.0.0_near_sdk_rs.md

File metadata and controls

587 lines (504 loc) · 33 KB

v0.9 -> v1.0.0 near-sdk-rs upgrade migration guide

The link to near-sdk-rs pr is chore: borsh version update

Steps:

1. update dependencies in near-sdk/Cargo.toml.

First we update to 1.0.0-alpha.5 version, which contains deprecation of BorshSerialize::try_to_vec method.

We enable derive feature by default, and make unstable__schema feature optional, enabled depending on whether abi feature of near-sdk package is enabled or not.

diff --git a/near-sdk/Cargo.toml b/near-sdk/Cargo.toml
index a015a64..e6099d4 100644
--- a/near-sdk/Cargo.toml
+++ b/near-sdk/Cargo.toml
@@ -26,3 +26,3 @@ near-sys = { path = "../near-sys", version = "0.2" }
 base64 = "0.13"
-borsh = { version = "0.9", features = ["const-generics"] }
+borsh = { version = "=1.0.0-alpha.5", features = ["derive"] }
 bs58 = "0.4"
@@ -35,3 +35,4 @@ once_cell = { version = "1.17", default-features = false }
@@ -58,3 +59,3 @@ unstable = []
 legacy = []
-abi = ["near-abi", "schemars", "near-sdk-macros/abi"]
+abi = ["borsh/unstable__schema", "near-abi", "schemars", "near-sdk-macros/abi"]
 unit-testing = ["near-vm-logic", "near-primitives-core", "near-primitives", "near-crypto"]

2. We receive a great number of deprecation warnings of borsh::BorshSerialize::try_to_vec method (near-sdk package):

 2  warning: use of deprecated method `borsh::BorshSerialize::try_to_vec`: use `borsh::to_vec(&object)` instead                                                                                                                                                          
   --> near-sdk/src/store/lazy/mod.rs:43:28                                                                                                                                                                                                                              
    |                                                                                                                                                                                                                                                                    
 43 |     let serialized = value.try_to_vec().unwrap_or_else(|_| env::panic_str(ERR_VALUE_SERIALIZATION));                                                                                                                                                               
    |                            ^^^^^^^^^^                                                                                                                                                                                                                              
    |                                                                                                                                                                                                                                                                    
    = note: `#[warn(deprecated)]` on by default                                                                                                                                                                                                                          

We choose to fix it at once, as this method is removed in 1.0.0-alpha.5 -> 1.0.0 transition completely with following diff:

diff --git a/near-sdk/src/store/lazy/mod.rs b/near-sdk/src/store/lazy/mod.rs
index 7df7ee4..42112ea 100644
--- a/near-sdk/src/store/lazy/mod.rs
+++ b/near-sdk/src/store/lazy/mod.rs
@@ -8,3 +8,3 @@ mod impls;
 
-use borsh::{BorshDeserialize, BorshSerialize};
+use borsh::{BorshDeserialize, BorshSerialize, to_vec};
 use once_cell::unsync::OnceCell;
@@ -42,3 +42,3 @@ where
 {
-    let serialized = value.try_to_vec().unwrap_or_else(|_| env::panic_str(ERR_VALUE_SERIALIZATION));
+    let serialized = to_vec(value).unwrap_or_else(|_| env::panic_str(ERR_VALUE_SERIALIZATION));
     env::storage_write(key, &serialized);
...
...

where value is &T, where T: BorshSerialize.

3. We replace the usage of BorshSchema::schema_container method (near-sdk-macros package)

To prevent compilation errors in the future, we grep for schema_container string. schema_container was changed from being a BorshSchema trait method to being a function, external to the trait in chore!: make BorshSchema::{add_definition,schema_container} free-standing funcs

We fix code, generated with near_bindgen procedural macro, with following diff:

diff --git a/near-sdk-macros/src/core_impl/abi/abi_generator.rs b/near-sdk-macros/src/core_impl/abi/abi_generator.rs
index cbe659a..994e63c 100644
--- a/near-sdk-macros/src/core_impl/abi/abi_generator.rs
+++ b/near-sdk-macros/src/core_impl/abi/abi_generator.rs
@@ -239,21 +239,21 @@ impl ImplItemMethodInfo {
         }
     }
 }
 
 fn generate_schema(ty: &Type, serializer_type: &SerializerType) -> TokenStream2 {
     match serializer_type {
         SerializerType::JSON => quote! {
             gen.subschema_for::<#ty>()
         },
         SerializerType::Borsh => quote! {
-            <#ty as ::near_sdk::borsh::BorshSchema>::schema_container()
+            ::near_sdk::borsh::schema_container_of::<#ty>()
         },
     }
 }
 
 fn generate_abi_type(ty: &Type, serializer_type: &SerializerType) -> TokenStream2 {
     let schema = generate_schema(ty, serializer_type);
     match serializer_type {
         SerializerType::JSON => quote! {
             ::near_sdk::__private::AbiType::Json {
                 type_schema: #schema,

4. next we encounter error with #[borsh(use_discriminant=<bool>)] (near-sdk package):

 1  error: You have to specify `#[borsh(use_discriminant=true)]` or `#[borsh(use_discriminant=false)]` for all enums with explicit discriminant                                                                  
  --> near-sdk/src/types/public_key.rs:8:10                                                              
   |                                                                                                     
 8 | pub enum CurveType {                                                                                
   |          ^^^^^^^^^                                                                                  
                                                                                                         

on

/// PublicKey curve
#[derive(Debug, Clone, Copy, PartialOrd, Ord, Eq, PartialEq, BorshDeserialize, BorshSerialize)]
#[repr(u8)]
pub enum CurveType {
    ED25519 = 0,
    SECP256K1 = 1,
}

We fix it with #[borsh(use_discriminant=true)], which will behave the same as #[borsh(use_discriminant=false)]
in this particular case, where false preserves the behaviour of borsh before 1.0 release (borsh 0.10 and older ignored explicit discriminant values in enum definitions):

diff --git a/near-sdk/src/types/public_key.rs b/near-sdk/src/types/public_key.rs
index 30ebd43..b539ddd 100644
--- a/near-sdk/src/types/public_key.rs
+++ b/near-sdk/src/types/public_key.rs
@@ -7,2 +7,3 @@ use std::convert::TryFrom;
 #[repr(u8)]
+#[borsh(use_discriminant=true)]
 pub enum CurveType {
@@ -144,4 +145,4 @@ impl serde::Serialize for PublicKey {

5. next we encounter errors with borsh::maybestd imports (near-sdk package):

 1  error[E0432]: unresolved import `borsh::maybestd`                                                                                                                                                                                                                      
  --> near-sdk/src/types/public_key.rs:1:13                                                                                                                                                                                                                                
   |                                                                                                                                                                                                                                                                       
 1 | use borsh::{maybestd::io, BorshDeserialize, BorshSerialize};                                                                                                                                                                                                          
   |             ^^^^^^^^ could not find `maybestd` in `borsh`                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                           
 2  error[E0432]: unresolved import `borsh::maybestd`                                                                                                                                                                                                                      
  --> near-sdk/src/types/account_id.rs:1:13                                                                                                                                                                                                                                
   |                                                                                                                                                                                                                                                                       
 1 | use borsh::{maybestd::io, BorshDeserialize, BorshSchema, BorshSerialize};                                                                                                                                                                                             
   |             ^^^^^^^^ could not find `maybestd` in `borsh`                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                           
// near-sdk/src/types/public_key.rs
impl BorshDeserialize for PublicKey {
    fn deserialize(buf: &mut &[u8]) -> io::Result<Self> {
        <Vec<u8> as BorshDeserialize>::deserialize(buf).and_then(|s| {
            Self::try_from(s).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
        })
    }
}

maybestd has moved to a __private package in borsh, and is not supposed to be accessed directly now besides from within code, derived in borsh traits implementations.

As near-sdk crate is not supposed to be used in no_std context, we can replace imports with std::io:

diff --git a/near-sdk/src/types/account_id.rs b/near-sdk/src/types/account_id.rs
index a338b5c..7876d77 100644
--- a/near-sdk/src/types/account_id.rs
+++ b/near-sdk/src/types/account_id.rs
@@ -1,5 +1,5 @@
-use borsh::{maybestd::io, BorshDeserialize, BorshSchema, BorshSerialize};
+use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
 use serde::{de, Deserialize, Serialize};
 use std::convert::TryFrom;
-use std::fmt;
+use std::{fmt, io};
 
diff --git a/near-sdk/src/types/public_key.rs b/near-sdk/src/types/public_key.rs
index 10175a0..4280f70 100644
--- a/near-sdk/src/types/public_key.rs
+++ b/near-sdk/src/types/public_key.rs
@@ -1,4 +1,4 @@
-use borsh::{maybestd::io, BorshDeserialize, BorshSerialize};
+use borsh::{BorshDeserialize, BorshSerialize};
 use bs58::decode::Error as B58Error;
-use std::convert::TryFrom;
+use std::{convert::TryFrom, io};

Otherwise, if we intended to support both std and no_std, we would've imported from borsh::io:

-use borsh::{maybestd::io, BorshDeserialize, BorshSerialize};
+use borsh::{BorshDeserialize, BorshSerialize};
+use borsh::io;

6. next we encounter a large number of similar syntax errors with borsh_skip (near-sdk package):

 1  error: cannot find attribute `borsh_skip` in this scope                                                                                                                                                                                                                
   --> near-sdk/src/store/lookup_map/mod.rs:89:7                                                                                                                                                                                                                           
    |                                                                                                                                                                                                                                                                      
 89 |     #[borsh_skip]                                                                                                                                                                                                                                                    
    |       ^^^^^^^^^^                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                           

We change all of these occurencies according to new #[borsh(skip)] syntax. The following diff is shortened to first and last occurencies:

diff --git a/near-sdk/src/collections/lazy_option.rs b/near-sdk/src/collections/lazy_option.rs
index 04e79fb..f4ea0dc 100644
--- a/near-sdk/src/collections/lazy_option.rs
+++ b/near-sdk/src/collections/lazy_option.rs
@@ -19,3 +19,3 @@ pub struct LazyOption<T> {
     storage_key: Vec<u8>,
-    #[borsh_skip]
+    #[borsh(skip)]
     el: PhantomData<T>,
...
diff --git a/near-sdk/src/store/lookup_set/mod.rs b/near-sdk/src/store/lookup_set/mod.rs
index 762956a..b2d1ac0 100644
--- a/near-sdk/src/store/lookup_set/mod.rs
+++ b/near-sdk/src/store/lookup_set/mod.rs
@@ -54,3 +54,3 @@ where
 
-    #[borsh_skip]
+    #[borsh(skip)]
     hasher: PhantomData<fn() -> (T, H)>,

7. next there's a bunch of similar errors with borsh::maybestd::io imports (near-sdk package):

They're fixed in a similar way as in 5.

8. next there's a bunch of similar errors due to BorshDeserialize trait signature change (near-sdk package):

 1  error[E0046]: not all trait items implemented, missing: `deserialize_reader`                                                                                                                                                                                           
    --> near-sdk/src/store/vec/mod.rs:138:1                                                                                                                                                                                                                                
     |                                                                                                                                                                                                                                                                     
 138 | impl<T> BorshDeserialize for Vector<T>                                                                                                                                                                                                                              
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `deserialize_reader` in implementation                                                                                                                                                                               
     
     = help: implement the missing item: `fn deserialize_reader<R>(_: &mut R) -> std::result::Result<Self, std::io::Error> where R: std::io::Read { todo!() }

The signature of trait has changed on 0.9.3 -> 0.10.0 transition in implement deserialize_reader. We fix it the following way:

diff --git a/near-sdk/src/store/free_list/mod.rs b/near-sdk/src/store/free_list/mod.rs
index 43d8908..20a1cc7 100644
--- a/near-sdk/src/store/free_list/mod.rs
+++ b/near-sdk/src/store/free_list/mod.rs
@@ -47,7 +47,7 @@ where
 {
-    fn deserialize(buf: &mut &[u8]) -> Result<Self, std::io::Error> {
+    fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> Result<Self, std::io::Error> {
         Ok(Self {
-            first_free: BorshDeserialize::deserialize(buf)?,
-            occupied_count: BorshDeserialize::deserialize(buf)?,
-            elements: BorshDeserialize::deserialize(buf)?,
+            first_free: BorshDeserialize::deserialize_reader(reader)?,
+            occupied_count: BorshDeserialize::deserialize_reader(reader)?,
+            elements: BorshDeserialize::deserialize_reader(reader)?,
         })
diff --git a/near-sdk/src/store/unordered_map/mod.rs b/near-sdk/src/store/unordered_map/mod.rs
index 5decc60..d82a8aa 100644
--- a/near-sdk/src/store/unordered_map/mod.rs
+++ b/near-sdk/src/store/unordered_map/mod.rs
@@ -117,6 +117,6 @@ where
 {
-    fn deserialize(buf: &mut &[u8]) -> Result<Self, std::io::Error> {
+    fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> Result<Self, std::io::Error> {
         Ok(Self {
-            keys: BorshDeserialize::deserialize(buf)?,
-            values: BorshDeserialize::deserialize(buf)?,
+            keys: BorshDeserialize::deserialize_reader(reader)?,
+            values: BorshDeserialize::deserialize_reader(reader)?,
         })
diff --git a/near-sdk/src/store/vec/mod.rs b/near-sdk/src/store/vec/mod.rs
index 9d19614..94127ba 100644
--- a/near-sdk/src/store/vec/mod.rs
+++ b/near-sdk/src/store/vec/mod.rs
@@ -141,6 +141,6 @@ where
 {
-    fn deserialize(buf: &mut &[u8]) -> Result<Self, std::io::Error> {
+    fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> Result<Self, std::io::Error> {
         Ok(Self {
-            len: BorshDeserialize::deserialize(buf)?,
-            values: BorshDeserialize::deserialize(buf)?,
+            len: BorshDeserialize::deserialize_reader(reader)?,
+            values: BorshDeserialize::deserialize_reader(reader)?,
         })
diff --git a/near-sdk/src/types/account_id.rs b/near-sdk/src/types/account_id.rs
index 7876d77..3da417a 100644
--- a/near-sdk/src/types/account_id.rs
+++ b/near-sdk/src/types/account_id.rs
@@ -88,4 +88,4 @@ impl<'de> Deserialize<'de> for AccountId {
 impl BorshDeserialize for AccountId {
-    fn deserialize(buf: &mut &[u8]) -> io::Result<Self> {
-        <String as BorshDeserialize>::deserialize(buf).and_then(|s| {
+    fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
+        <String as BorshDeserialize>::deserialize_reader(reader).and_then(|s| {
             Self::try_from(s).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
diff --git a/near-sdk/src/types/public_key.rs b/near-sdk/src/types/public_key.rs
index 4280f70..b539ddd 100644
--- a/near-sdk/src/types/public_key.rs
+++ b/near-sdk/src/types/public_key.rs
@@ -145,4 +145,4 @@ impl serde::Serialize for PublicKey {
 impl BorshDeserialize for PublicKey {
-    fn deserialize(buf: &mut &[u8]) -> io::Result<Self> {
-        <Vec<u8> as BorshDeserialize>::deserialize(buf).and_then(|s| {
+    fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
+        <Vec<u8> as BorshDeserialize>::deserialize_reader(reader).and_then(|s| {
             Self::try_from(s).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
diff --git a/near-sdk/src/collections/unordered_map/mod.rs b/near-sdk/src/collections/unordered_map/mod.rs
index d3ba8d5..aab31a4 100644
--- a/near-sdk/src/collections/unordered_map/mod.rs
+++ b/near-sdk/src/collections/unordered_map/mod.rs
@@ -512,5 +512,5 @@ mod tests {
         impl BorshDeserialize for DeserializeCounter {
-            fn deserialize(buf: &mut &[u8]) -> std::io::Result<Self> {
+            fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
                 DES_COUNT.fetch_add(1, Ordering::SeqCst);
-                u64::deserialize(buf).map(DeserializeCounter)
+                u64::deserialize_reader(reader).map(DeserializeCounter)
             }

9. next we encounter an error with BorshDeserialize trait derivation (near-sdk package):

 6  error[E0277]: the trait bound `T: Default` is not satisfied
    --> near-sdk/src/store/vec/mod.rs:145:21
     |
 145 |             values: BorshDeserialize::deserialize_reader(reader)?,
     |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `T`
     |
 note: required for `IndexMap<T>` to implement `BorshDeserialize`
    --> near-sdk/src/store/index_map.rs:12:26
     |
 12  | #[derive(BorshSerialize, BorshDeserialize)]
     |                          ^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
 13  | pub(crate) struct IndexMap<T>
     |                   ^^^^^^^^^^^
     = note: this error originates in the derive macro `BorshDeserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider further restricting this bound
     |
 140 |     T: BorshSerialize + std::default::Default,
     |                       +++++++++++++++++++++++

where IndexMap<T> looks like the following:

#[derive(BorshSerialize, BorshDeserialize)]
pub(crate) struct IndexMap<T>
where
    T: BorshSerialize,
{
    pub(crate) prefix: Box<[u8]>,
    /// Cache for loads and intermediate changes to the underlying index map.
    /// The cached entries are wrapped in a [`Box`] to avoid existing pointers from being
    /// invalidated.
    ///
    /// Note: u32 indices are used over usize to have consistent functionality across architectures.
    /// Some functionality would be different from tests to Wasm if exceeding 32-bit length.
    #[borsh(skip)]
    pub(crate) cache: StableMap<u32, OnceCell<CacheEntry<T>>>,
}

On version change v0.9 -> v1.0.0-alpha.5 bounds derivation in borsh has changed:

From bounds on the types of the fields:

// cd near-sdk; cargo expand ::store::index_map 
impl<T> borsh::de::BorshDeserialize for IndexMap<T>
where
    T: BorshSerialize,
    Box<[u8]>: borsh::BorshDeserialize,
{
    fn deserialize(
        buf: &mut &[u8],
    ) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
        Ok(Self {
            prefix: borsh::BorshDeserialize::deserialize(buf)?,
            cache: Default::default(),
        })
    }
}

to bounds on type parameters, encountered in fields. borsh::de::BorshDeserialize bound for parameters in non-skipped fields, core::default::Default bound - otherwise:

impl<T> borsh::de::BorshDeserialize for IndexMap<T>
where
    T: BorshSerialize,
    T: core::default::Default,
{
    fn deserialize_reader<R: borsh::__private::maybestd::io::Read>(
        reader: &mut R,
    ) -> ::core::result::Result<Self, borsh::__private::maybestd::io::Error> {
        Ok(Self {
            prefix: borsh::BorshDeserialize::deserialize_reader(reader)?,
            cache: core::default::Default::default(),
        })
    }
}

We can instruct borsh to replace automatically derived bound with nothing, as StableMap has a impl<K: Ord, V> Default for StableMap<K, V> implementation of its own, as it will be used when deserializing skipped field, irrelevant of bounds on V:

diff --git a/near-sdk/src/store/index_map.rs b/near-sdk/src/store/index_map.rs
index 834fc98..7d1df75 100644
--- a/near-sdk/src/store/index_map.rs
+++ b/near-sdk/src/store/index_map.rs
@@ -23,3 +23,3 @@ where
     /// Some functionality would be different from tests to Wasm if exceeding 32-bit length.
-    #[borsh(skip)]
+    #[borsh(skip, bound(deserialize = ""))]
     pub(crate) cache: StableMap<u32, OnceCell<CacheEntry<T>>>,

which would transform into following bound on trait's implementation:

// line with `T: core::default::Default,` disappeared
impl<T> borsh::de::BorshDeserialize for IndexMap<T>
where
    T: BorshSerialize,
{
...

Similar diffs were also applied here:

diff --git a/near-sdk/src/store/lookup_map/mod.rs b/near-sdk/src/store/lookup_map/mod.rs
index 0b20345..927b2d6 100644
--- a/near-sdk/src/store/lookup_map/mod.rs
+++ b/near-sdk/src/store/lookup_map/mod.rs
@@ -88,3 +88,3 @@ where
     /// invalidated.
-    #[borsh(skip)]
+    #[borsh(skip, bound(deserialize = ""))]
     cache: StableMap<K, EntryAndHash<V, H::KeyType>>,
diff --git a/near-sdk/src/store/unordered_set/mod.rs b/near-sdk/src/store/unordered_set/mod.rs
index 4504580..77621b9 100644
--- a/near-sdk/src/store/unordered_set/mod.rs
+++ b/near-sdk/src/store/unordered_set/mod.rs
@@ -83,9 +83,11 @@ pub struct UnorderedSet<T, H = Sha256>
 where
     T: BorshSerialize + Ord,
     H: ToKey,
 {
+    #[borsh(bound(serialize = "", deserialize = ""))]
     elements: FreeList<T>,
+    #[borsh(bound(serialize = "", deserialize = ""))]
     index: LookupMap<T, FreeListIndex, H>,
 }

10. next we encounter an error with BorshSchema trait derivation (near-sdk package):

 4  error[E0053]: method `add_definitions_recursively` has an incompatible type for trait
    --> near-sdk/src/promise.rs:232:22
     |
 232 |         definitions: &mut HashMap<borsh::schema::Declaration, borsh::schema::Definition>,
     |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |                      |
     |                      expected `BTreeMap<String, Definition>`, found `HashMap<String, Definition>`
     |                      help: change the parameter type to match the trait: `&mut BTreeMap<std::string::String, Definition>`
     |
     = note: expected signature `fn(&mut BTreeMap<std::string::String, Definition>)`
                found signature `fn(&mut HashMap<std::string::String, Definition>)`

Signature in trait's method has changed:

diff --git a/near-sdk/src/promise.rs b/near-sdk/src/promise.rs
index f8afe56..a430568 100644
--- a/near-sdk/src/promise.rs
+++ b/near-sdk/src/promise.rs
@@ -2,3 +2,3 @@ use borsh::BorshSchema;
 use std::cell::RefCell;
-use std::collections::HashMap;
+use std::collections::BTreeMap;
 use std::io::{Error, Write};
@@ -231,3 +231,3 @@ impl BorshSchema for Promise {
     fn add_definitions_recursively(
-        definitions: &mut HashMap<borsh::schema::Declaration, borsh::schema::Definition>,
+        definitions: &mut BTreeMap<borsh::schema::Declaration, borsh::schema::Definition>,
     ) {
@@ -576,3 +576,3 @@ where
     fn add_definitions_recursively(
-        definitions: &mut HashMap<borsh::schema::Declaration, borsh::schema::Definition>,
+        definitions: &mut BTreeMap<borsh::schema::Declaration, borsh::schema::Definition>,
     ) {

11. next we encounter an error with both BorshSerialize and BorshDeserialize traits' derivation (near-contract-standards package):

 1  error: proc-macro derive panicked                                                                                                                                                                                                                                      
   --> near-contract-standards/src/fungible_token/core_impl.rs:27:10                                                                                                                                                                                                       
    |                                                                                                                                                                                                                                                                      
 27 | #[derive(BorshDeserialize, BorshSerialize)]                                                                                                                                                                                                                          
    |          ^^^^^^^^^^^^^^^^                                                                                                                                                                                                                                            
    |                                                                                                                                                                                                                                                                      
    = help: message: called `Result::unwrap()` on an `Err` value: CrateNotFound { crate_name: "borsh", path: "/home/user/Documents/code/near-sdk-rs/near-contract-standards/Cargo.toml" }                                                                           
                                                                                                                                                                                                                                                                           
 2  error: proc-macro derive panicked                                                                                                                                                                                                                                      
   --> near-contract-standards/src/fungible_token/core_impl.rs:27:28                                                                                                                                                                                                       
    |                                                                                                                                                                                                                                                                      
 27 | #[derive(BorshDeserialize, BorshSerialize)]                                                                                                                                                                                                                          
    |                            ^^^^^^^^^^^^^^                                                                                                                                                                                                                            
    |                                                                                                                                                                                                                                                                      
    = help: message: called `Result::unwrap()` on an `Err` value: CrateNotFound { crate_name: "borsh", path: "/home/user/Documents/code/near-sdk-rs/near-contract-standards/Cargo.toml" }                                                                           

Thing is, borsh has started getting into a panic when using proc-macro-crate dependency for derives, in the cases when borsh is not imported as direct dependency in the crate, which attempts to use its derive macros. near-contract-standards wasn't importing borsh directly, just using near-sdk's reexports.

We may instruct BorshSerialize and BorshDeserialize derives to skip this check of direct import and to use a reexported version of borsh via following diff:

diff --git a/near-contract-standards/src/fungible_token/core_impl.rs b/near-contract-standards/src/fungible_token/core_impl.rs
index d61ee8e..cae776c 100644
--- a/near-contract-standards/src/fungible_token/core_impl.rs
+++ b/near-contract-standards/src/fungible_token/core_impl.rs
@@ -27,2 +27,3 @@ const ERR_TOTAL_SUPPLY_OVERFLOW: &str = "Total supply overflow";
 #[derive(BorshDeserialize, BorshSerialize)]
+#[borsh(crate = "::near_sdk::borsh")]
 pub struct FungibleToken {

12. finally, we update borsh version to 1.0.0:

diff --git a/near-sdk/Cargo.toml b/near-sdk/Cargo.toml
index a015a64..e6099d4 100644
--- a/near-sdk/Cargo.toml
+++ b/near-sdk/Cargo.toml
@@ -26,3 +26,3 @@ near-sys = { path = "../near-sys", version = "0.2" }
 base64 = "0.13"
-borsh = { version = "=1.0.0-alpha.5", features = ["derive"] }
+borsh = { version = "1.0.0", features = ["derive"] }
 bs58 = "0.4"