rustnearprotocolnearnearprotocol-validator

Which is the equivalent of "BLOCKCHAIN_INTERFACE 3.1.0" in the near-sdk 4.0.0-pre.4?


In the near-sdk 3.1.0 we use the BLOCKCHAIN_INTERFACE to make a Dao remote-upgrade with the next method:

#[cfg(target_arch = "wasm32")]
    pub fn upgrade(self) {
        // assert!(env::predecessor_account_id() == self.minter_account_id);
        //input is code:<Vec<u8> on REGISTER 0
        //log!("bytes.length {}", code.unwrap().len());
        const GAS_FOR_UPGRADE: u64 = 20 * TGAS; //gas occupied by this fn
        const BLOCKCHAIN_INTERFACE_NOT_SET_ERR: &str = "Blockchain interface not set.";
        //after upgrade we call *pub fn migrate()* on the NEW CODE
        let current_id = env::current_account_id().into_bytes();
        let migrate_method_name = "migrate".as_bytes().to_vec();
        let attached_gas = env::prepaid_gas() - env::used_gas() - GAS_FOR_UPGRADE;
        unsafe {
            BLOCKCHAIN_INTERFACE.with(|b| {
                // Load input (new contract code) into register 0
                b.borrow()
                    .as_ref()
                    .expect(BLOCKCHAIN_INTERFACE_NOT_SET_ERR)
                    .input(0);

                //prepare self-call promise
                let promise_id = b
                    .borrow()
                    .as_ref()
                    .expect(BLOCKCHAIN_INTERFACE_NOT_SET_ERR)
                    .promise_batch_create(current_id.len() as _, current_id.as_ptr() as _);

                //1st action, deploy/upgrade code (takes code from register 0)
                b.borrow()
                    .as_ref()
                    .expect(BLOCKCHAIN_INTERFACE_NOT_SET_ERR)
                    .promise_batch_action_deploy_contract(promise_id, u64::MAX as _, 0);

                // 2nd action, schedule a call to "migrate()".
                // Will execute on the **new code**
                b.borrow()
                    .as_ref()
                    .expect(BLOCKCHAIN_INTERFACE_NOT_SET_ERR)
                    .promise_batch_action_function_call(
                        promise_id,
                        migrate_method_name.len() as _,
                        migrate_method_name.as_ptr() as _,
                        0 as _,
                        0 as _,
                        0 as _,
                        attached_gas,
                    );
            });
        }
    }

To use the BLOCKCHAIN_INTERFACE I use this import: use near_sdk::env::BLOCKCHAIN_INTERFACE;

In the near-sdk 4.0.0-pre.4 I can't use this interface to make the remote-upgrade, how I can solve it? I read something about the MockedBlockchain, but I can't use it, the import doesn't exist or the methods are private and also says that it's only for #test


Solution

  • Yes, so that blockchain interface was removed completely so there is no need to go through that at all anymore. For all methods, you can just use near_sdk::sys to call each low level method. Here is the contract code migrated:

        #[cfg(target_arch = "wasm32")]
        pub fn upgrade(self) {
            use near_sdk::sys;
            // assert!(env::predecessor_account_id() == self.minter_account_id);
            //input is code:<Vec<u8> on REGISTER 0
            //log!("bytes.length {}", code.unwrap().len());
            const GAS_FOR_UPGRADE: u64 = 20 * TGAS; //gas occupied by this fn
            const BLOCKCHAIN_INTERFACE_NOT_SET_ERR: &str = "Blockchain interface not set.";
            //after upgrade we call *pub fn migrate()* on the NEW CODE
            let current_id = env::current_account_id().into_bytes();
            let migrate_method_name = "migrate".as_bytes().to_vec();
            let attached_gas = env::prepaid_gas() - env::used_gas() - GAS_FOR_UPGRADE;
            unsafe {
                // Load input (new contract code) into register 0
                sys::input(0);
    
                //prepare self-call promise
                let promise_id =
                    sys::promise_batch_create(current_id.len() as _, current_id.as_ptr() as _);
    
                //1st action, deploy/upgrade code (takes code from register 0)
                sys::promise_batch_action_deploy_contract(promise_id, u64::MAX as _, 0);
    
                // 2nd action, schedule a call to "migrate()".
                // Will execute on the **new code**
                sys::promise_batch_action_function_call(
                    promise_id,
                    migrate_method_name.len() as _,
                    migrate_method_name.as_ptr() as _,
                    0 as _,
                    0 as _,
                    0 as _,
                    attached_gas,
                );
            }
        }
    

    Let me know if this solves your problem completely or if there is anything else I can help with :)