Search code examples
smartcontractssubstraterust-ink

How to deposit into an Ink! Smart Contract


I have a few ideas for smart contracts that I will be implementing using Ink! on Substrate.

Most of these ideas involve callers making deposits into the smart contract which will be held indefinitely, and then the caller may be able to withdraw at some future point, depending on other factors.

I have found an example that allows callers to withdraw from a smart contract:

https://github.com/paritytech/ink/blob/master/examples/contract-transfer/lib.rs

This hints at an approach to the caller making a deposit - the self.env().transferred_value() method suggests the caller can/has send/sent value.

I am struggling to find an example that deposits funds into a smart contract. Perhaps I am missing something fundamental here?

Ideally I want to avoid implementing a function that takes 2 addresses and transfers from one to the other (the contract already having & knowing its own address!), instead favouring the caller sending an amount, and it being deposited into the smart contract.

I think this may be possible with a smart contract method that takes no parameters but not certain and not at all clear on how the contract would then receive & hold the funds.

Looking for a concrete code example to show how this works in full, but also appreciate any comments to clarify or correct my (quite possibly incorrect) understanding.

Thanks in advance!


Solution

  • The method of your contract, that expects the payments should be marked with #[ink(message, payable)] for example like here. During the call of that method the user should specify that amount to send in the native currency(in the case of polkadot-js it is value field of payable method).

    In the method, you can use let amount = Self::env().transferred_value(); to get a sent amount. If your transaction is not rejected your contract will hold amount tokens on its balance. It works the same way as in Solidity.

    To get the current balance of the contract Self::env().balance(). To send a native currency Self::env().transfer(to, amount).

    Maybe it will be useful to check that example.