Search code examples
substrate

In srml_support::storage::StorageMap, what is the difference between get() and take()


In srml_support::storage::StorageMap, what is the difference between fn get() and fn take()?


Solution

  • get() simply returns the value in storage:

    /// Load the bytes of a key from storage. Can panic if the type is incorrect.
    fn get<T: codec::Decode>(&self, key: &[u8]) -> Option<T>;
    

    take() performs both get() to return the value, but also kill() which deletes the key from storage:

    /// Take a value from storage, deleting it after reading.
    fn take<T: codec::Decode>(&mut self, key: &[u8]) -> Option<T> {
        let value = self.get(key);
        self.kill(key);
        value
    }
    

    This means after a take() operation, you can call exists() and it will return false.

    A common pattern where take() is used is some kind of pot payout. Let's say at the end of some game, a winner gets all the funds in a pot. You would call take() on the pot value to both get how much should be transferred to the user, and to reset the pot to "zero".

    Note that this operation DOES write to storage, so when called in your runtime, storage is permanently modified.