Allureluoli 二月FEBRUARY

区块链国赛笔记 13|Spring Boot 通过 Web3j 调用本地合约

后端服务需要把 RPC、合约地址和签名账户配置连接起来。这份记录使用本地以太坊开发链,是理解调用链路的独立练习。

本文由个人备赛旧笔记整理,整理日期为 2026-11-03。命令、输出和测试记录属于当时的实验环境;本文未重新搭建整套环境验证。

阅读前先确认

Web3j 的 Ethereum RPC 示例不能直接替代 FISCO BCOS Java SDK。Bank Java 包装类需要根据实际 ABI 和字节码生成。私钥配置已改为环境变量占位。

后端与智能合约

后端地址配置

application.properties

1
2
3
4
5
6
7
8
# 合约地址
contract.address=0x5FbDB2315678afecb367f032d93F642f64180aa3

# 私钥
private.key=${WEB3_PRIVATE_KEY}

# Web3j 配置
web3j.client-address=http://localhost:8545

后端合约服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.myproject.demo.controller;

import com.myproject.demo.contract.Bank;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.tx.gas.DefaultGasProvider;

import java.math.BigInteger;

@Service
public class ContractService {
@Autowired
private Web3j web3j;

@Value("${contract.address}")
private String contractAddress;

@Value("${private.key}")
private String privateKey;

private Bank contract;

@PostConstruct
public void init() throws Exception {
// 加载钱包私钥
var credentials = Credentials.create(privateKey);

// 加载已部署的合约
contract = Bank.load(contractAddress, web3j, credentials, new DefaultGasProvider());
}

// 存款
public String deposit(BigInteger amount) throws Exception {
return contract.deposit(amount).send().getTransactionHash();
}

// 取款
public String withdraw(BigInteger amount) throws Exception {
return contract.withdraw(amount).send().getTransactionHash();
}

// 查询余额
public BigInteger getBalance() throws Exception {
return contract.checkBalance().send();
}
}

后端路由接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.myproject.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigInteger;

@RestController
@RequestMapping("/api/bank")
public class BankController {

@Autowired
private ContractService contractService;

@PostMapping("/deposit")
public String deposit(@RequestParam BigInteger amount) throws Exception {
return contractService.deposit(amount);
}

@PostMapping("/withdraw")
public String withdraw(@RequestParam BigInteger amount) throws Exception {
return contractService.withdraw(amount);
}

@GetMapping("/balance")
public BigInteger getBalance() throws Exception {
return contractService.getBalance();
}
}

复现时的自查

  • 记录自己实际使用的版本、配置和缺失依赖。
  • 对照本篇关键步骤,保存命令或调用结果,并解释结果代表什么。
  • 对失败或与原记录不一致的情况保留错误信息,不把历史输出当成自己的验证结果。

返回系列导读 · 上一篇 · 下一篇

评论COMMENTS