📢 Gate Square #MBG Posting Challenge# is Live— Post for MBG Rewards!
Want a share of 1,000 MBG? Get involved now—show your insights and real participation to become an MBG promoter!
💰 20 top posts will each win 50 MBG!
How to Participate:
1️⃣ Research the MBG project
Share your in-depth views on MBG’s fundamentals, community governance, development goals, and tokenomics, etc.
2️⃣ Join and share your real experience
Take part in MBG activities (CandyDrop, Launchpool, or spot trading), and post your screenshots, earnings, or step-by-step tutorials. Content can include profits, beginner-friendl
Rust smart contracts upgrade practice: Three methods and security considerations in the NEAR ecosystem
Rust smart contracts development series: Contract upgrade methods
Smart contracts, as a type of program code, inevitably have defects and areas that need improvement. Even after extensive testing and auditing, contracts may still have vulnerabilities. Once a vulnerability is exploited by an attacker, it can lead to serious consequences such as the loss of user assets. Therefore, the upgradability of contracts is very important, as it can be used to fix vulnerabilities and to add new features. This article will introduce several upgrade methods for Rust smart contracts.
NEAR Contract Upgrade Method
Taking the StatusMessage project as an example, this introduces the common upgrade methods for NEAR smart contracts.
StatusMessage smart contracts code example:
rust #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct StatusMessage { records: LookupMap<string, string="">
}
impl Default for StatusMessage { Self { Self { records: LookupMap::new(b'r'.to_vec)((, } } }
#[near_bindgen] impl StatusMessage { pub fn set_status)&mut self, message: String) { let account_id = env::signer_account_id(); self.records.insert(&account_id, &message); }
Option { return self.records.get(&account_id); } }
( 1. The upgrade without modification of the contract data structure
If only the contract logic is modified without changes to the data structure, you can directly use the near deploy command to redeploy the new code.
For example, add a new function:
rust Option { let account_id = env::signer_account_id)(; self.records.insert)&account_id, &message###; return self.records.get(&account_id); }
After redeployment, the original data can still be read normally.
( 2. Upgrade of contract data structure modification
If the data structure of the contract is modified, redeploying it directly will lead to a failure in state deserialization.
For example, modify the data structure:
rust pub struct StatusMessage { taglines: LookupMap<string, string="">, bios: LookupMap<string, string="">, }
In this case, it is necessary to use the Migrate method for the upgrade.
) 3. Use the Migrate method to upgrade
Add migrate method in the new contract:
rust #( #[init)ignore_state(] Self { let old_state: OldStatusMessage = env::state_read)###.expect###'failed'[private]; Self { taglines: old_state.records, bios: LookupMap::new(b'b'.to_vec)(), } }
Call the migrate method simultaneously during deployment:
near deploy
--wasmFile target/wasm32-unknown-unknown/release/status_message.wasm
--initFunction 'migrate'
--initArgs '{}'
--accountId statusmessage.blocksec_upgrade.testnet
This allows for the successful migration of old data to the new data structure.
Security Considerations for Contract Upgrades
Access Control - The upgrade function should be exclusive to the owner, and it is recommended to set the owner as the DAO.
Add #[init(ignore_state)] before the migration function.
Delete the migration function after the migration is complete.
The new data structure is initialized during migration.
By reasonably designing the upgrade mechanism, the upgradability of the contract can be achieved while ensuring security, laying the foundation for long-term maintenance and optimization.
![](https://img-cdn.gateio.im/webp-social/moments-af3fe22c1999da5db0e2853b8a271276.webp(</string,></string,></string,>