Transfer lamports from one wallet to two other wallets in one solana program

Hi team,
If anyone can point me guidance or example on following would be much appreciated.

Example Scenario:
Wallet X transfer

  • 0.25SOL to Wallet-Y
  • 0.5SOL to Wallet-Z

How can I achieve this within one solana program( smart contract).

Hi @sub87 and welcome to the forum! :wave:

To transfer tokens inside of a Solana program you can invoke() a transfer instruction on the system program inside your smart contract.

It would look something like this in code:

        invoke(
            &system_instruction::transfer(payer_info.key, account_info.key, required_lamports),
            &[
                payer_info.clone(),
                account_info.clone(),
                system_program_info.clone(),
            ],
        )?;
1 Like

Hi @zicklag I tried this and works great. But since my use case is there’re two receiving accounts and one payer.

Does that mean I have to do two transfers like
transfer(payer1,receiver1,1000)
transfer(payer1, receiver2,1000).

if so

  1. If by any chance one of the transfers fails for some reason, while other one successful, does this means my contract execution terminates and both will eventually fail to preserve Atomicity ?

  2. In these two transactions, I assume receiving which party should pay gas fees ? Can we choose it?

Yep that would work.

Also, me and another user just discovered recently that you might just be able to modify the lamports for the accounts directly by using something like:

payer1.lamports.borrow_mut() -= 2000);
receiver1.lamports.borrow_mut() += 1000;
receiver2.lamports.borrow_mut() += 1000;

As far as I understand, the entire transaction the user submits will execute atomically. If any section of it is unsuccessful, then the entire transaction will be reverted and it will be like it never happened.

The person submitting the transaction will be the one who pays the fees, not the receivers.

You can change who pays the fees, but whoever pays the fees needs to sign the transaction, so if the payer is the one submitting the transaction, then it would be much more work to get the receiver to also sign the same transaction so that they can authorize the transaction to spend their money to pay the fees.

Great explanation. Thank you very much for the prompt response.

So when call transfer method with some value for the amount(say x), the gas fees will be deducted from that amount correct?
Meaning receiver will get (x-gasfee) ? Or will amount 100% received to the receiver and gas fees will be deducted separately from the senders(signer) wallet ?

The gas fees are subtracted only once from the person who submitted the transaction ( the main signer ), and it is a totally separate process from all the logic in your app.

So if you do a transfer, the person will get all of what you transferred with no subtracted gas fees.

Also, contrary to Ethereum, having more operations inside of your Solana program won’t make the gas fees more expensive, so you can fit as many different operations as you want in one transaction without it costing more gas.

The caveat is that there is a limit to how much you can do in a Solana transaction, before you are forced to submit two or more transactions, because you can’t fit everything you need to do into the compute/size limits that Solana places on one transaction.

But you shouldn’t run into the limits for a simple program like you are working on now, and the person who sends the transaction will separately get a small amount of SOL subtracted for their wallet when they submit the transaction.

Awesome. Small Question related to signing.

If same above smart contract(program) executed 10 times, does the signer has to sign it 10 times when it happens ? 10 times equal 10 Calls from client side to invoke the program, and it could execute in different times. I.e 10 times in 3months.

Yes, the signer would have to sign it 10 times, and they would have to sign it withing 2 minutes of the time that the transaction is to be submitted.

Each transaction has what’s called the “recent blockhash” included in it. If a transaction is submitted with a recent blockhash that is not recent enough, then the chain won’t accept it.

This makes it not quite possible to “pre-sign” transactions you want to submit in the future.

If you wanted to do a workflow like having a wallet that would periodically transfer funds to other wallets on some schedule, you would need to deposit all the funds that are to be distributed ahead of time, into the smart contract.

The user would sign some transaction that would pledge those funds, over time, to the other wallets by some proportion.

Then, the smart contract would allow anybody, at any time to say “make pending payments”, and if there were payments that were do to happen, that hadn’t been made yet, it would pay them out.

This “make pending payments” instruction could be automated by a server, and wouldn’t need a signature, because the smart contract will know when the payments are supposed to be made, it just needs somebody to come and “turn the crank” so to speak, because transactions in Solana can only happen if somebody initiates it.