想快速用 Java 部署区块链转账?本教程从核心依赖、Gas 预算到实战代码,全面拆解 Web3j 转账 与 ERC-20 Token 转账 操作,兼顾 SEO 高频关键词:智能合约调用、以太坊、gasPrice、nonce 管理、链上交易哈希,确保你搜索即可找到答案。
一、准备开发环境
1.1 新建 Maven 项目
新建一个 maven-archetype-quickstart 项目即可。接下来在 pom.xml 中添加:
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>3.4.0</version>
</dependency>提示:若你使用 Java 11+,可升级至 4.x 最新版以兼容更多网络;版本越高,支持 Layer2 网络越友好。
1.2 获取可靠节点 RPC
建议在 src/main/resources/application.yml 中维护节点配置,便于后续多网切换:
ethereum:
rpc:
mainnet: https://mainnet.infura.io/v3/YOUR_PROJECT_ID
goerli: https://goerli.infura.io/v3/YOUR_PROJECT_ID这样本地、测试网、主网都能一键切换。
二、用 Web3j 发送基础 ETH 转账
基础转账仅涉及 钱包私钥、目标地址、金额、Gas 参数 四要素,核心流程如下图所示:
- 连接以太坊节点
- 生成 Credentials
- 调用
Transfer.sendFunds - 等待链回执
TransactionReceipt
示例代码:
public static TransactionReceipt transferETH(BigDecimal amountInEther, String toAddress) throws Exception {
// 初始化 Web3j
Web3j web3j = Web3j.build(new HttpService("https://mainnet.infura.io/v3/YOUR_PROJECT_ID"));
// 导入私钥(示例:64 位 Hex)
BigInteger privateKey = new BigInteger("aabbccdd...其他64位", 16);
Credentials credentials = Credentials.create(ECKeyPair.create(privateKey));
// 发送 0.001 ETH
return Transfer.sendFunds(
web3j,
credentials,
toAddress,
amountInEther,
Convert.Unit.ETHER
).send();
}注意主题:
- Gas 默认由
Transfer工具自动估算;若想节省手续费,可 自定义 gasPrice。 - 链上拥堵时,先获取当前平均 gasPrice,然后再调大 10-20%。
三、用 Web3j 发送 ERC-20 Token 转账
Token 转账比 ETH 多一步:与智能合约交互。你需先构造 Function,再手动管理 nonce 与 gasLimit。下面逐一拆解:
3.1 步骤详解
| 步骤 | 关键 API | 备注 |
|---|---|---|
| 查询 nonce | ethGetTransactionCount | 防止交易碰撞 |
| 构造 transfer | FunctionEncoder.encode | 参数为目标地址 + 金额(单位 wei) |
| 拼装 RawTx | RawTransaction.createTransaction | 填入合约地址而非接收者地址 |
| 签名 & 发送 | TransactionEncoder.signMessage | 链下签名,减少私钥泄露风险 |
3.2 Token 转账示例
public static String transferToken(String contractAddress, String toAddress, BigInteger amountWei) throws Exception {
Web3j web3j = Web3j.build(new HttpService("https://mainnet.infura.io/v3/YOUR_PROJECT_ID"));
Credentials credentials = Credentials.create("yourPrivateKey");
String fromAddress = credentials.getAddress();
EthGetTransactionCount txCount = web3j.ethGetTransactionCount(
fromAddress, DefaultBlockParameterName.LATEST).sendAsync().get();
BigInteger nonce = txCount.getTransactionCount();
// 构造 transfer function
Function function = new Function(
"transfer",
Arrays.<Type>asList(new Address(toAddress), new Uint256(amountWei)),
Collections.<TypeReference<?>>emptyList()
);
String encodedFunction = FunctionEncoder.encode(function);
// 手动设定的 gas,90% 场景 210k 足够
BigInteger gasLimit = new BigInteger("210000");
RawTransaction rawTx = RawTransaction.createTransaction(
nonce,
DefaultGasProvider.GAS_PRICE,
gasLimit,
contractAddress,
encodedFunction
);
// 签名并广播
String hexValue = Numeric.toHexString(TransactionEncoder.signMessage(rawTx, credentials));
EthSendTransaction sendTx = web3j.ethSendRawTransaction(hexValue).sendAsync().get();
return sendTx.getTransactionHash();
}四、FAQ:Web3j 转账常见疑问
- Q:一次转账需要等多久?
A:主网 12–15 秒一个区块。如果你设置的 gasPrice 高,矿工优先打包,最快 15 秒即可完成。 - Q:如何查看交易状态?
A:用web3j.ethGetTransactionReceipt(txHash).send().getTransactionReceipt();当receipt.getStatus()等于0x1即成功。 - Q:为什么总是遇到 “nonce too low”?
A:说明你传入的 nonce 小于链上已消耗值。务必通过ethGetTransactionCount动态采集。 - Q:怎样降低手续费?
A:优先选择 Layer2(Arbitrum、Optimism)或等待 gasPrice 低谷期。提前查询 Gas Now 一目了然,眼瞅骤降再签名,立省 30-50%。 - Q:私钥以明文配置好危险?
A:绝对禁止!建议使用 Keystore + 密码 或 助记词 + BIP-44 加密存储,线上私钥加 AES 二次加密解密。 - Q:Token precision 如何转换?
A:ERC-20 常见 decimals 为 18。前端填写 1 个 USDT,后端需amountWei = new BigInteger("1000000000000000000")。
五、生产环境注意清单
- 节点故障自动重试:引入 RetryableHttpService 库。
- gasPrice 动态:用
EthGasPrice+ 120% 上浮策略,平均 bin 淘汰高价。 - 连发多笔交易:nonce 缓存队列,防止并发覆盖。
- 日志埋点:使用 MDC 透传
txHash,链路追踪一次到位。
六、综合示例:一键签名并换回执
CompletableFuture<TransactionReceipt> receiptFuture = Transfer.sendFunds(
web3j,
credentials,
"0xAbC...123",
BigDecimal.valueOf(0.01),
Convert.Unit.ETHER
).sendAsync();
receiptFuture.thenAccept(receipt -> {
if ("0x1".equalsIgnoreCase(receipt.getStatus())) {
System.out.println("链上确认成功:" + receipt.getTransactionHash());
}
});七、结语
从 基础转账 到 ERC-20 Token 转账,Web3j 让 Java 工程师在链路层与以太坊全面对接。牢记:
- gasPrice 决定速度与成本;
- nonce 决定交易顺序;
- 智能合约 ABI 决定交互协议。
实践一遍代码,遇到问题先查 nonce → 再查 gas → 最后确认合约地址,就能稳住 99% 的场景。