One of the real world applications for crypto is that it is much easier and faster to make payments to multiple wallets at once. This could be very useful when you want to airdrop or have a payroll with several employees. Depending on how you set it up though, it may not always be cheaper. This is actually where I think Solana shines in comparison to Ethereum and EVM chains, since it doesn’t require a smart contract to carry out multiple transfers at once. You could attempt to make transfers to multiple wallets in Ethereum without a smart contract, but it won’t be very efficient or time-saving.
In this tutorial, I will show you how to set up a multi-transfer system for tokens that is fast and gas-efficient, first in Ethereum, and then, without a smart contract, in Solana.
Ethereum Multi-Transfer
If you’ve been in crypto for awhile, you likely have heard or participated in airdrops. There are two types of airdrops which can be classed as “push” or “pull” airdrops. Push airdrops or multi-transfers, are where the token owner transfers tokens to multiple addresses at once. Pull airdrops, or claim contracts, put the onus on the recipient to call the function to receive the tokens. Both have their pros and cons. Pull airdrops can help the token owner to avoid waste by only sending tokens to recipients who will actually use the token. However, depending on the size of the list of addresses, where the token owner saves in the cost of transferring themselves, they end up losing in the cost of storage. For example, if Ethereum is your chain of choice, it could end up costing hundreds of dollars just to store the addresses on chain. Add that on top of that the cost of deployment and it may not even be worth it anymore.
Push airdrops, on the other hand, do not require storage of the wallet addresses it sends to, but you will have to pay the gas for the transaction. Ultimately, you will have to choose which kind of airdrop works best for your operation, but in this tutorial, we will create a push airdrop.
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.9;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract MoneyTransfer {
address private owner;
constructor(){
owner = msg.sender;
}
function tokenTransfer(address _payToken, address[] calldata _wallets, uint256[] calldata _amounts) external {
require(msg.sender == owner, "Not authorized");
IERC20 payToken = IERC20(_payToken);
for(uint8 i = 0; i < _wallets.length; i++) {
payToken.transferFrom(msg.sender, _wallets[i], _amounts[i]);
}
}
We have written a function called tokenTransfer which will take three arguments: the address of the token we want to send, an array of wallets, and an array of amounts. The arrays of wallets and amounts must be equal in length. The tokenTransfer function calls a for loop and makes the transfer in seconds.
Solana Multi-Transfer
Solana distinguishes itself from Ethereum in that instead of a user having to deploy his or her own version of an ERC-20, there is instead one program that acts like a token factory, and without deployment and a significantly smaller expenditure of SOL, one can create a child of that token program which inherits its methods and properties. What I like most about doing a multi-transfer with Solana is that I can create the same for-loop in javascript, without the need to deploy a separate contract:
import { Program, AnchorProvider, BN, web3 } from "@project-serum/anchor";
import {
getOrCreateAssociatedTokenAccount,
createTransferInstruction,
getAssociatedTokenAddress,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID,
createAssociatedTokenAccountInstruction,
} from "@solana/spl-token";
async function airdrop() {
//make sure a wallet is connected - phantom is a good choice
const wallet = window.solana;
//establish connection
const connection = new web3.Connection(
web3.clusterApiUrl("devnet"),
"confirmed"
);
//get provider
const provider = new AnchorProvider(
connection,
wallet,
opts.preflightCommitment
);
...
The first step involves some basic setup: importing the necessary dependencies and establishing a connection between the wallet and provider. Next, we have to get the actual account that holds the tokens. To read more about how associated token accounts work in Solana, go here.
...
// Get the token account of the fromWallet Solana address, if it does not exist, create it
const fromTokenAccount = await getOrCreateAssociatedTokenAccount(
connection,
provider.wallet,
new PublicKey("YOUR_TOKEN_ADDRESS"),
provider.wallet.publicKey
);
console.log(fromTokenAccount)
Next, we must create an array that will contain the recipient address and the corresponding amount:
const transfers = [
{
recipientPublicKey: "RECIPIENT_ADDRESS_1",
tokens: 2* 10 ** 9,
},
{
recipientPublicKey: "RECIPIENT_ADDRESS_2",
tokens: (1.5 * 10 ** 9) ,
},
];
The 10**9 represents the number of decimals. You can modify this to match the number of decimals of the token you use. Here, recipient 1 receives 2 tokens, and recipient 2 receives 1.5. Now, we have to set up our for-loop:
let transferTransaction = new Transaction();
transferTransaction.feePayer = provider.wallet.publicKey;
for (let { recipientPublicKey, tokens } of transfers) {
//get the token account of the toWallet Solana address, if it does not exist, create it
try {
const toTokenAccount = await getOrCreateAssociatedTokenAccount(
connection,
provider.wallet,
new PublicKey("YOUR_TOKEN_ADDRESS"),
new PublicKey(recipientPublicKey),
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
);
console.log(toTokenAccount);
transferTransaction.add(
createTransferInstruction(
fromTokenAccount.address,
toTokenAccount.address,
provider.wallet.publicKey,
tokens
)
);
And then lastly, we send the transaction:
// Sign transaction, broadcast, and confirm
const signature = await provider.sendAndConfirm(transferTransaction);
console.log("Transaction signature", signature);
}
And that’s it! This is how to setup a multi-transfer in Ethereum and Solana!
If you found this article helpful and enjoy learning about all sorts of cool tricks with Solidity and DeFi hacks, star our CryptoCadet Academy repo on GitHub for more!
TechJD is the Founder of Ascendant.Finance, which assists web2 businesses to transition to web3, consulting on all facets including SEC compliance, tokenomics, development, and connecting with angel investors. For more information check out ascendant.finance or join the Discord.
https://twitter.com/ascendantfi