Java代码实现以太坊代币转账,从环境搭建到实战操作

OKX欧易app

OKX欧易app

欧易交易所app是全球排名第一的虚拟货币交易所,注册领取6万元盲盒礼包!

APP下载   官网注册

Java代码实现以太坊代币转账,从环境搭建到实战操作

Java代码实现以太坊代币转账,从环境搭建到实战操作

以太坊代币转账概述

以太坊作为全球第二大公链,其生态中充斥着基于ERC-20标准的代币(如USDT、DAI、LINK等),代币转账本质上是以太坊网络上的一个交易调用,通过调用智能合约的transfer方法,实现代币在地址间的转移,Java作为企业级开发的主流语言,可通过Web3j等库与以太坊节点交互,完成代币转账的编程实现,本文将详细介绍如何使用Java代码实现以太坊代币转账,涵盖环境搭建、核心代码编写及异常处理等关键环节。

环境准备

安装JDK与Maven

确保已安装JDK 8或更高版本,并配置好环境变量,使用Maven管理项目依赖,可通过以下命令创建Maven项目:

mvn archetype:generate -DgroupId=com.ethereum.example -DartifactId=ethereum-token-transfer -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

添加Web3j依赖

在pom.xml中添加Web3j依赖(以最新稳定版为例):

<dependencies>
    <!-- Web3j核心依赖 -->
    <dependency>
        <groupId>org.web3j</groupId>
        <artifactId>core</artifactId>
        <version>4.9.8</version>
    </dependency>
    <!-- 以太坊单位工具类(可选) -->
    <dependency>
        <groupId>org.web3j</groupId>
        <artifactId>utils</artifactId>
        <version>4.9.8</version>
    </dependency>
</dependencies>

准备以太坊节点

代币转账需要连接以太坊节点,可通过以下方式获取:

  • 本地节点:搭建Geth或OpenEthereum节点(需同步区块数据,资源消耗大)。
  • Infura等第三方服务:注册Infura账号,创建项目获取节点URL(如https://mainnet.infura.io/v3/YOUR_PROJECT_ID)。
  • Alchemy等类似服务:提供稳定可靠的节点接口。

创建以太坊钱包

转账需要发送方账户的私钥,可通过MyEtherWallet(MEW)、MetaMask等工具生成,并妥善保存私钥(切勿泄露)。

核心代码实现

初始化Web3j客户端

首先创建Web3j客户端,连接到以太坊节点:

import org.web3j.protocol.Web3j;
import org.web3j.protocol.http.HttpService;
public class EthereumClient {
    private static final String INFURA_URL = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID";
    public static Web3j buildWeb3j() {
        return Web3j.build(new HttpService(INFURA_URL));
    }
}

加载代币合约

ERC-20代币需通过智能合约地址加载,获取合约实例,以USDT(主网合约地址:0xdAC17F958D2ee523a2206206994597C13D831ec7)为例:

import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Uint256;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tx.Contract;
import org.web3j.tx.gas.ContractGasProvider;
import org.web3j.tx.gas.StaticGasProvider;
import java.math.BigInteger;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
public class TokenTransfer {
    // 代币合约地址(以USDT为例)
    private static final String TOKEN_CONTRACT_ADDRESS = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
    // 代币ABI(简化版,实际需完整ABI)
    private static final String TOKEN_ABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"standard\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"type\":\"function\"}]";
    private final Web3j web3j;
    private final Credentials credentials;
    public TokenTransfer(Web3j web3j, String privateKey) {
        this.web3j = web3j;
        this.credentials = Credentials.create(privateKey);
    }
    /**
     * 转账代币
     * @param toAddress 接收方地址
     * @param amount 转账数量(注意:需乘以decimals)
     * @return 交易哈希
     */
    public String transferToken(String toAddress, BigInteger amount) throws Exception {
        // 1. 构建transfer函数调用
        Function function = new Function(
            "transfer",
            Collections.singletonList(new Address(toAddress)),
            Collections.singletonList(new TypeReference<Uint256>() {})
        );
        // 2. 编码函数调用数据
        String data = FunctionEncoder.encode(function);
        // 3. 获取代币合约的nonce
        BigInteger nonce = web3j.ethGetTransactionCount(credentials.getAddress(), DefaultBlockParameterName.LATEST)
            .send()
            .getTransactionCount();
        // 4. 估算gas费用(简化版,实际可调用ethEstimateGas)
        BigInteger gasLimit = BigInteger.valueOf(300000); // 代币转账通常需要200k-300k gas
        BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice();
        // 5. 构建交易
        Transaction transaction = Transaction.createFunctionCallTransaction(
            TOKEN_CONTRACT_ADDRESS,
            nonce,
            gasPrice,
            gasLimit,
            BigInteger.ZERO, // 转ETH时value不为0,代币转账为0
            data
        );
        // 6. 签名并发送交易
        EthSendTransaction transactionResponse = web3j.ethSendTransaction(transaction)
            .sendAsync()
            .get();
        if (transactionResponse.hasError()) {
            throw new Exception("交易失败: " + transactionResponse.getError().getMessage());
        }
        return transactionResponse.getTransactionHash();
    }
}

完整调用示例

public class Main {
    public static void main(String[] args) {
        try {
            // 1. 初始化Web3j客户端
            Web3j web3j = EthereumClient.buildWeb3j();
            // 2. 创建TokenTransfer实例(替换为实际私钥)
            String privateKey = "YOUR_PRIVATE_KEY"; // 发送方账户私钥
            TokenTransfer tokenTransfer = new TokenTransfer(web3j, privateKey);
            // 3. 设置接收方地址和转账数量(USDT的decimals=6,所以1 USDT = 1000000)
            String toAddress = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e";
            BigInteger amount = new BigInteger("1000000"); // 1 USDT
            // 4. 执行转账
            String transactionHash = tokenTransfer.transferToken(toAddress, amount);
            System.out.println("交易哈希: " + transactionHash);
            // 5. 等待交易确认(可选)
            Thread.sleep(15000); // 等待15秒
            TransactionReceipt receipt = web3j.ethGetTransactionReceipt(transactionHash).send().getTransactionReceipt().orElse(null);
            if (receipt != null && receipt.getStatus().equals(BigInteger.ONE)) {
                System.out.println("转账成功!");
            } else {
                System.out.println("转账失败或未

本文来自用户投稿,不代表币大大立场,如若转载,请注明出处:https://czxurui.com/jys/248361.html

上一篇 2026年07月03日
下一篇 2026年07月03日

相关推荐

  • 数字世界的佳酿,当以太坊遇上53度酒,一份价格表背后的价值探索

    数字世界的佳酿,当以太坊遇上53度酒,一份价格表背后的价值探索 当您在搜索框中输入“以太坊53度酒价格表”时,您可能会期待一份类似茅台飞天那样的、清晰明了的官方报价单,这个关键词组合本身就充满了奇妙的化学反应,它将代表前沿科技的“以太坊”与承载传统酿造工艺的“

    2026-11-14 08:10:01
    3 0
  • 揭开神秘面纱,以太坊原始股东名单公示及其深远影响

    揭开神秘面纱,以太坊原始股东名单公示及其深远影响 备受关注的“以太坊原始股东名单公示”话题再次引发业界热议,这份名单不仅关乎以太坊早期生态的财富分配,更因其背后涉及的核心团队、投资机构以及项目发展历程,成为理解以太坊从概念到庞然巨物演变的关键线索,尽管“原

    2026-11-14 08:10:01
    3 0
  • 以太坊价格今日行情,非号波动,市场情绪复杂

    以太坊价格今日行情,非号波动,市场情绪复杂 今日以太坊价格行情呈现出一种典型的“非号”走势,即未能延续单边上涨或下跌的强势行情,而是进入了多空力量交织、区间震荡的复杂阶段,投资者在经历了一段时间的剧烈波动后,情绪趋于谨慎,市场缺乏明确的催化剂来打破当前的僵局

    2026-11-14 08:10:01
    3 0
  • 以太坊的绿色革命,从PoW到PoS,一场关乎未来的共识升级

    以太坊的绿色革命,从PoW到PoS,一场关乎未来的共识升级 在区块链的世界里,共识机制是维系其安全与运转的基石,比特币采用的“工作量证明”(Proof of Work, PoW)以其去中心化和安全性著称,但也因其巨大的能源消耗而备受争议,作为全球第二大加密货币平台,以太坊长期以来也

    2026-11-14 04:10:02
    5 0
  • 以太坊交易卡了一天未到账?别慌!可能的原因与解决方法

    以太坊交易卡了一天未到账?别慌!可能的原因与解决方法 在加密货币的世界里,以太坊(Ethereum)作为领先的智能合约平台,其交易活动日益频繁,许多用户都曾遇到过这样的困扰:明明已经提交了以太坊转账交易,但账面上却迟迟没有显示到账,甚至一等就是一整天,这种“以太坊

    2026-11-14 04:10:02
    4 0
  • 深度解析以太坊走势,当前市值几何,未来又将走向何方?

    深度解析以太坊走势,当前市值几何,未来又将走向何方? 在波澜壮阔的数字货币世界中,如果说比特币是当之无愧的“数字黄金”,那么以太坊(Ethereum, ETH)就是构建整个智能合约生态的“世界计算机”,它的每一次价格波动,都牵动着全球数亿投资者的神经,也深刻影响着去中心

    2026-11-14 02:10:01
    3 0

发表回复

8206

评论列表(0条)

    暂无评论

binance币安交易所
已有2000万用户加入币安交易所

立即下载