logoAcademy

Transfers and Smart Contract

Transfer native tokens to smart contracts

Now that you know how to transfer native assets between accounts, let's see how to to transfer those funds to the control of an smart contract. Payable smart contract functions are essential for this process, as they allow the contract to receive Native Tokens. A function marked as payable in Solidity signifies that the function can accept and process incoming funds. This is particularly useful for contracts that need to handle funds for instance any financial dApps, such as decentralized applications (dApps), automated market makers (AMMs), or transfering funds from one chain to another, like we do with Avalanche Interchain Token Transfer.

Payable functions

The payable keyword in Solidity is used to designate functions that are capable of receiving native blockchain tokens. When a function is marked as payable, it allows the contract to accept incoming funds and execute specific logic based on the amount received. Without the payable modifier, any attempt to send native tokens to a contract would result in an error, preventing the transaction from being processed.

A function defined as payable serves multiple purposes. First, it signals to users and other contracts that the function is intended to handle incoming payments. This adds a layer of transparency and ensures that the contract’s behavior is clear and predictable. Second, it allows the function to access special variables such as msg.value, which holds the amount of Ether sent with the call. This can be used within the function to implement various logic, such as recording payments, issuing tokens in return, or triggering other contract behaviors.

Here's an example of a simple payable function in Solidity:

pragma solidity ^0.8.0;
 
contract PayableExample {
    uint public amountReceived = 0 ;
 
    function receiveNative() public payable {
        amountReceived += msg.value;
    }
}

In this example, the receiveNative function is marked as payable, enabling it to accept the Native Token. The msg.value variable is used to add the amount of native token sent to the amountReceived state variable. This is a basic illustration, but it underscores how the payable keyword facilitates the handling of native token transfers within smart contracts.

Create the working directory to store new contracts

mkdir -p src/my-contracts

Deploy Contract with Payable Function

forge create --rpc-url myblockchain --private-key $PK src/my-contracts/PayableExample.sol:PayableExample

Save the Contract Address

export PAYABLE_CONTRACT=0X..
 

Check amountReceived

cast call --rpc-url myblockchain $PAYABLE_CONTRACT "amountReceived()(uint)"

Transfer Native Token to the Contract

Now let's use solidity to transfer funds to our PayableExample contract

cast send --rpc-url myblockchain --private-key $PK $PAYABLE_CONTRACT "receiveNative()" --value 100000

Check amountReceived

cast call --rpc-url myblockchain $PAYABLE_CONTRACT "amountReceived()(uint)"

Well done! You transferred native tokens to a Smart Contract.

It's important to understand the distinction between Native Tokens and ERC-20 tokens. Native tokens, such as AVAX or ETH, are transferred directly to payable functions within the smart contract. This process is straightforward and involves sending the tokens to the contract's address, invoking the payable function.

On the other hand, ERC-20 tokens require a different approach due to their standardized interface. We will cover that in the following sections.

On this page