Skip to content

Payments on SKALE

Payments and tokenization is currently one of the most common usecases within the blockchain space. It’s important to recognize that with zero gas fees on SKALE, the way you handle payments and tokenization may require a small change compared to other networks.

There are two types of tokens that are generally used for “payments” or “fungible value transfer” on most blockchains:

  1. Native Token: the native token of the blockchain (e.g. ETH on Ethereum, etc.)
  2. ERC-20 Tokens: tokens that are built on top of the blockchain (e.g. DAI, USDC, etc.)

When you’re building an application that faciliates payments on Ethereum and other chains that have gas fees, many developers utilize the native gas token as a primary form of payment. This is because the gas token is generally the most liquid asset and easiest to attain for users since they need it to execute transactions.

However, on SKALE, with zero gas fees or gasless transactions; you cannot use the native token as form of payment at all as it has 0 monetary value. Therefore, you should use other forms of value such as ERC-20 tokens or other tokens that have value on the network.

The following is how to transfer assets into a smart contract as a payment using the native gas token. In Solidity, this is msg.value. This should not be done on SKALE as the native token has no value.

NativePayment.sol
/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
/// @title NativePayment
/// @author TheGreatAxios
/// @notice A simple contract that allows users to make payments with native ETH
/// @dev This contract demonstrates handling of native ETH transfers
contract NativePayment {
/// @notice Allows a user to make a purchase by sending ETH
/// @dev Transfers the sent ETH amount to the contract's balance
/// @dev Uses low-level call to transfer ETH value within the contract
/// @dev Reverts if the internal transfer fails
function purchase() external payable {
(bool sent,) = payable(address(this)).call{value: msg.value}("");
require(sent, "Failed to send Ether");
}
}

The following is how to use an ERC-20 token for payments. This is the recommended way to handle payments on SKALE.

ERC20Payment.sol
/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/// @title ERC20Payment
/// @author TheGreatAxios
/// @notice A simple contract that allows users to make payments with ERC20 tokens
/// @dev This contract leverages OpenZeppelin's SafeERC20 library for secure token transfers
contract ERC20Payment {
using SafeERC20 for IERC20;
/// @notice The ERC20 token used for payments
IERC20 public token;
/// @notice Initializes the contract with a specific ERC20 token
/// @dev Sets the token that will be used for all payment operations
/// @param _token The address of the ERC20 token contract
constructor(address _token) {
token = IERC20(_token);
}
/// @notice Allows a user to make a purchase by sending 100 tokens
/// @dev Transfers 100 tokens from the sender to this contract using safeTransferFrom
/// @dev The amount is hardcoded to 100e18 (100 tokens with 18 decimals)
function purchase() external {
token.safeTransferFrom(msg.sender, address(this), 100e18);
}
}