I want to write a contract which enables the user to deposit the native chain token in a contract and to then later withdraw the token.

The only example I found so far, only enables the user to withdraw the balance from the smart contract but I couldn't figure out how to send token to the contract.

This is how I want it in theory to look:

    #[ink(message, payable)]
    pub fn deposit(&mut self, value: Balance) {
        // Test if caller has sufficient funds
        // deposit the balance to the contract

    #[ink(message, payable)]
    pub fn withdraw(&mut self, value: Balance) {
        ink_env::debug_println!("requested value: {}", value);
        ink_env::debug_println!("contract balance: {}", self.env().balance());

        assert!(value <= self.env().balance(), "insufficient funds!");

        if self.env().transfer(self.env().caller(), value).is_err() {
                "requested transfer failed. this can be the case if the contract does not\
                 have sufficient free funds or if the transfer would have brought the\
                 contract's balance below minimum balance."

1 Answer 1


Your pseudo-code is right. The user can call the method deposit of the contract and pass some value from the UI or the TS/JS code.

Also, other contracts can do cross-contract calls to you(they need to call the deposit method) and specify the amount to transfer.

Inside of deposit method, you can use ink_env::transferred_value method, to get the value of the sent amount(your contract already received money when the blockchain started to execute your transaction).

But expect of that method, you also can receive money by standard transfer ink_env::transfer. Or by transfer via pallet-balances.

Also, maybe it will be useful to check or reuse the code from payment_apliiter in OpenBrush.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.