NEXUS

What is gas abstraction?

Overview

gasabs (Gas Abstraction Interface) is a Go-based service that abstracts gas handling for CROSS chain network transactions and provides a fee delegation feature. This solution enables gas fee sponsorship (Fee Delegation) for transactions that meet specific conditions.

Key Features

1. Transaction Fee Delegation

The core functionality of gasabs is to pay gas fees on behalf of transactions that meet certain criteria. This process involves the following steps:

  1. User creates and signs a transaction (DynamicFeeTx EIP1559)
  2. Transaction is sent to the gasabs API
  3. gasabs validates the transaction:
    • Checks if the target address is an approved contract
      • Verifies if the transaction format is eligible for fee delegation
        • Validates transaction execution through simulation
  4. If validation passes, FeePayer adds its signature and converts it to a FeeDelegatedDynamicFeeTx
  5. Returns the final transaction

2) Transaction Filtering

gasabs processes only transactions that meet specific filter rules.
Detailed fee delegation policies will be provided on a separate page.

API Specification

gasabs provides its services through RPC API:

1. Fee Delegated Transaction Signing

Item

Description

Method

gasabs_signFeeDelegateTransaction

Parameters

raw transaction of dynamic Fee Tx

Return Value

Transaction data with fee delegation signature (hexadecimal string)

Errors

ErrorDisapprovedAddress: Unapproved address ErrorNondelegableTx: Non-delegable transaction ErrorRevertExpected: Error during transaction execution ErrorInvalidTransactionType: Invalid transaction type ErrorNotFoundMethodSig: Missing method signature

2. Address Approval Check

ItemDescription
Methodgasabs_isApproved
ParametersContract address to check
Return Valueboolean (approval status)

Client Usage Examples

Example 1: Direct Transaction Submission to Node

package main

import (
	"context"
	"crypto/ecdsa"
	"fmt"
	"log"
	"math/big"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
)

func main() {
	// Connect to Ethereum node
	client, err := ethclient.Dial("http://localhost:8545")
	if err != nil {
		log.Fatalf("Failed to connect to Ethereum node: %v", err)
	}

	// Generate a new private key
	privateKey, err := crypto.GenerateKey()
	if err != nil {
		log.Fatalf("Failed to generate private key: %v", err)
	}

	// Get the public address from the private key
	publicKey := privateKey.Public()
	publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
	if !ok {
		log.Fatal("Failed to cast public key to ECDSA")
	}
	fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
	fmt.Printf("From address: %s\n", fromAddress.Hex())

	// Get chain ID
	chainID, err := client.NetworkID(context.Background())
	if err != nil {
		log.Fatalf("Failed to get chain ID: %v", err)
	}

	// Get the latest nonce for the from address
	nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
	if err != nil {
		log.Fatalf("Failed to get nonce: %v", err)
	}

	// Get gas price estimates
	tipCap, err := client.SuggestGasTipCap(context.Background())
	if err != nil {
		log.Fatalf("Failed to suggest gas tip cap: %v", err)
	}

	baseFee, err := client.SuggestGasPrice(context.Background())
	if err != nil {
		log.Fatalf("Failed to suggest gas price: %v", err)
	}

	maxFeePerGas := new(big.Int).Add(baseFee, big.NewInt(2000000000)) // Base fee + 2 Gwei buffer

	// Target contract address
	toAddress := common.HexToAddress("0x1234567890123456789012345678901234567890")
	
	// Transaction parameters
	value := big.NewInt(0)      // 0 ETH
	gasLimit := uint64(100000)  // Gas limit
	data := []byte{0x1, 0x2, 0x3, 0x4} // Method call data (example)

	// Create an EIP-1559 transaction
	tx := types.NewTx(&types.DynamicFeeTx{
		ChainID:   chainID,
		Nonce:     nonce,
		To:        &toAddress,
		Value:     value,
		Gas:       gasLimit,
		GasFeeCap: maxFeePerGas,
		GasTipCap: tipCap,
		Data:      data,
	})

	// Sign the transaction
	signer := types.LatestSignerForChainID(chainID)
	signedTx, err := types.SignTx(tx, signer, privateKey)
	if err != nil {
		log.Fatalf("Failed to sign transaction: %v", err)
	}

	// Send the transaction
	err = client.SendTransaction(context.Background(), signedTx)
	if err != nil {
		log.Fatalf("Failed to send transaction: %v", err)
	}

	fmt.Printf("Transaction sent: %s\n", signedTx.Hash().Hex())
}



Example 2: Using gasabs for Fee Delegated Transactions


package main

import (
	"context"
	"crypto/ecdsa"
	"fmt"
	"log"
	"math/big"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/ethereum/go-ethereum/node"
	"github.com/to-nexus/gasabs"
)

func main() {
	// Connect to CROSS chain node for transaction preparation
	ethClient, err := ethclient.Dial("http://localhost:8545")
	if err != nil {
		log.Fatalf("Failed to connect to Cross chain node: %v", err)
	}

	// Connect to gasabs service
	gasabsClient, err := gasabs.Dial(node.GasAbstraction{
		GasAbsURL: "http://localhost:8090",
	})
	if err != nil {
		log.Fatalf("Failed to connect to gasabs: %v", err)
	}
	defer gasabsClient.Close()

	// Generate a new private key for the transaction sender
	privateKey, err := crypto.GenerateKey()
	if err != nil {
		log.Fatalf("Failed to generate private key: %v", err)
	}

	// Get the sender's address
	publicKey := privateKey.Public()
	publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
	if !ok {
		log.Fatal("Failed to cast public key to ECDSA")
	}
	fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
	fmt.Printf("From address: %s\n", fromAddress.Hex())

	// Get chain ID
	chainID, err := ethClient.NetworkID(context.Background())
	if err != nil {
		log.Fatalf("Failed to get chain ID: %v", err)
	}

	// Get the latest nonce for the from address
	nonce, err := ethClient.PendingNonceAt(context.Background(), fromAddress)
	if err != nil {
		log.Fatalf("Failed to get nonce: %v", err)
	}

	// Get gas price estimates
	tipCap, err := ethClient.SuggestGasTipCap(context.Background())
	if err != nil {
		log.Fatalf("Failed to suggest gas tip cap: %v", err)
	}

	baseFee, err := ethClient.SuggestGasPrice(context.Background())
	if err != nil {
		log.Fatalf("Failed to suggest gas price: %v", err)
	}

	maxFeePerGas := new(big.Int).Add(baseFee, big.NewInt(2000000000)) // Base fee + 2 Gwei buffer

	// Target contract address - make sure this is an approved contract in gasabs
	contractAddr := common.HexToAddress("0x1234567890123456789012345678901234567890")
	
	// Check if the contract is approved for fee delegation
	approved, err := gasabsClient.IsApproved(context.Background(), contractAddr)
	if err != nil {
		log.Fatalf("Failed to check approval: %v", err)
	}
	
	if !approved {
		log.Fatalf("Contract address not approved for fee delegation")
	}
	
	// Transaction parameters
	value := big.NewInt(0)      // 0 ETH
	gasLimit := uint64(100000)  // Gas limit
	data := []byte{0x1, 0x2, 0x3, 0x4} // Method signature + parameters (at least 4 bytes)

	// Create an EIP-1559 transaction
	tx := types.NewTx(&types.DynamicFeeTx{
		ChainID:   chainID,
		Nonce:     nonce,
		To:        &contractAddr,
		Value:     value,
		Gas:       gasLimit,
		GasFeeCap: maxFeePerGas,
		GasTipCap: tipCap,
		Data:      data,
	})

	// Sign the transaction with sender's private key
	signer := types.LatestSignerForChainID(chainID)
	signedTx, err := types.SignTx(tx, signer, privateKey)
	if err != nil {
		log.Fatalf("Failed to sign transaction: %v", err)
	}

	// Request fee delegation from gasabs
	feeDelegatedTx, err := gasabsClient.SignFeeDelegateTransaction(context.Background(), signedTx)
	if err != nil {
		log.Fatalf("Failed to get fee delegated transaction: %v", err)
	}

	// Send the fee delegated transaction to the network
	err = ethClient.SendTransaction(context.Background(), feeDelegatedTx)
	if err != nil {
		log.Fatalf("Failed to send fee delegated transaction: %v", err)
	}

	fmt.Printf("Original transaction hash: %s\n", signedTx.Hash().Hex())
	fmt.Printf("Fee delegated transaction hash: %s\n", feeDelegatedTx.Hash().Hex())
	fmt.Println("Fee delegated transaction successfully sent!")
} 

© 2025 NEXUS Co., Ltd. All Rights Reserved.