以太坊私有链springboot-web3j

本文详细介绍如何在Java Spring Boot项目中整合Web3j库,实现区块链基础操作,包括安装配置、创建钱包、转账及查询交易等核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近研究了下区块链,东西真的挺多的,具体的资料什么的就先不赘述了,主要是说一下java整合web3j的一些常用功能;

首先本地下载geth钱包:

下载地址:Downloads | Go Ethereum,下载之后是个 .exe文件,然后安装就好了,安装之后把geth的安装目录加入到系统环境变量的path里,

验证是否安装成功,打开cmd窗口,输入 geth version 如果出来下面的内容,表示安装好了。
(如果不加任何任何参数直接运行 geth ,会自动连接到以太坊公网,此时会开始同步区块)

详细安装步骤参考:

搭建以太坊私链(单节点,多节点,windows,linux)_hantangduhey的博客-CSDN博客_以太坊私链

接下来开始搭建项目:

JDK:jdk1.8

geth: Geth/v1.4.11-stable/windows/go1.6.2

modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

IDE:IDEA

框架:springboot  2.0.5.RELEASE

首先pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>com.example</groupId>
   <artifactId>springboot-web3j</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>springboot-web3j</name>
   <description>Demo project for Spring Boot</description>

   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.0.5.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
   </properties>

   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>

      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <scope>runtime</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
      <dependency>
         <groupId>org.web3j</groupId>
         <artifactId>web3j-spring-boot-starter</artifactId>
         <version>1.6.0</version>
      </dependency>
      <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>fastjson</artifactId>
         <version>1.2.28</version>
      </dependency>
   </dependencies>


   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
         <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
               <source>1.8</source>
               <target>1.8</target>
            </configuration>
         </plugin>
      </plugins>
   </build>


</project>

接下来application.properties

web3j.client-address=http://127.0.0.1:8545/
#web3j.client-address=http://127.0.0.1:8487/
web3j.admin-client=true
web3j.http-timeout-seconds=600

接下来服务层:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.web3j.crypto.*;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.DefaultBlockParameterNumber;
import org.web3j.protocol.core.methods.response.EthBlock;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class Web3JService {

    private static final Logger LOGGER = LoggerFactory.getLogger(Web3JService.class);

    @Autowired
    Web3j web3j;

    //设置需要的矿工费
    private final BigInteger GAS_PRICE = BigInteger.valueOf(1);
    private final BigInteger GAS_LIMIT = BigInteger.valueOf(21000L);

    /**
     * 获取版本号
     * @return
     */
    public String getVersion(){
        try {
            String version = web3j.web3ClientVersion().send().getWeb3ClientVersion();
            return version;
        }catch (Exception e){
            e.printStackTrace();
        }
        return "";
    }
/**
 * 获取账号列表
 * @return
 */
public List<String> getAccounts(){
    List<String> result = new ArrayList<>();
    try {
        result = web3j.ethAccounts().send().getAccounts();
    }catch (Exception e){
        e.printStackTrace();
    }
    return result;
}
/**
 * 获取账户余额
 * @return
 */
public BigDecimal getBalanceById(String id) {
    try {
        DefaultBlockParameterNumber defaultBlockParameterNumber = new DefaultBlockParameterNumber(web3j.ethBlockNumber().send().getBlockNumber());
        EthGetBalance ethGetBalance = web3j.ethGetBalance(id, defaultBlockParameterNumber).send();
        if (ethGetBalance != null ) {
            BigDecimal banlance = Convert.fromWei(ethGetBalance.getBalance().toString(), Convert.Unit.ETHER);
            return banlance;
        }
    }catch (Exception e){
        e.printStackTrace();
    }
    return null;
}
/**
     * 创建钱包
     */
    public Map<String,Object> createWallet(String password,HttpServletRequest request){
        Bip39Wallet wallet;
        Map<String, Object> result = new HashMap<>();
        try {
//            String filePath = request.getSession().getServletContext().getRealPath("/data/wallet/");
            String filePath = "E:/pictures";
            File file = new File(filePath); //指定一个目录
            String fileName = WalletUtils.generateNewWalletFile(password, file, false);//方法返回创建的钱包文件名
            Credentials credentials = WalletUtils.loadCredentials(password,filePath +"/" +fileName );
            String returnAddress = credentials.getAddress();
            //公钥16进制字符串表示:
            String publicKey = credentials.getEcKeyPair().getPublicKey().toString(16);
            //私钥16进制字符串表示:
            String privateKey = credentials.getEcKeyPair().getPrivateKey().toString(16);
            result.put("address",returnAddress);
            result.put("publicKey",publicKey);
            result.put("privateKey",privateKey);
            result.put("fileName",fileName);
        }catch (Exception e){
            e.printStackTrace();
            System.out.printf("创建以太坊钱包失败");
        }
        return result;
    }
     /**
     * 转账
     * @param pwd  密码
     * @param file 账号文件
     * @param toAddress 转到的地址
     * @param amount    数量
     * @return  tx
     */
    @SuppressWarnings("Since15")
    public String transferAccount(String pwd ,File file,String toAddress,String amount){
        //交易的哈希值
        String transactionHash = new String();

        try {
            Credentials credentials = WalletUtils.loadCredentials(pwd, file);
            //获取发送的地址
            String fromAddress = credentials.getAddress();
            //获得nonce 从0开始,每笔交易加1,获取最后的nonce
            BigInteger nonce = getNonceByFromAddress(fromAddress);
            //发送的数量
            BigDecimal bigDecimal = Convert.toWei(amount, Convert.Unit.ETHER);
           
            /**
             * 正式使用--开始
             */
            //创建交易
            RawTransaction rawTransaction = RawTransaction.createEtherTransaction(nonce, GAS_PRICE,GAS_LIMIT, toAddress,BigInteger.valueOf(bigDecimal.longValue()));//nonce  gasprice  gas toAddress
            //签名Transaction,这里要对交易做签名
            byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
            //获取交易订单号
            String hexValue = Numeric.toHexString(signedMessage);
            EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();
            transactionHash = ethSendTransaction.getTransactionHash();
        }catch (Exception e){
            e.printStackTrace();
        }
        return transactionHash;

    }
/**
     * 根据tx值查询交易信息
     * @param tx 0xb6bfc5374a62cbad558eb16a209b43b9a3b0f9dd55cd26349d9682cf4fb2af2a
     */
    @SuppressWarnings("Since15")
    public Map<String, Object> getTxInfo(String tx){
        org.web3j.protocol.core.methods.response.Transaction transaction = null;
        Map<String, Object> result = new HashMap<>();
        try {
            if(web3j.ethGetTransactionByHash(tx).sendAsync() != null){
                if(web3j.ethGetTransactionByHash(tx).sendAsync().get().getTransaction() != null){
                    org.web3j.protocol.core.methods.response.Transaction transaction1 =                                web3j.ethGetTransactionByHash(tx).sendAsync().get().getTransaction().get();
                    if(transaction1 !=null){
                    transaction =transaction1;
                    }
                }
            }
            if(transaction != null){
                String to = transaction.getTo();
                String from = transaction.getFrom();
                BigInteger value = transaction.getValue();
                int v = transaction.getV();
                String creates = transaction.getCreates();
                BigInteger gas = transaction.getGas();
                BigInteger gasPrice = transaction.getGasPrice();
                BigInteger nonce = transaction.getNonce();
                String blockNumber = transaction.getBlockNumber().toString();
                String s = transaction.getS();
                String blockNumberRaw = transaction.getBlockNumberRaw();
                String hash = transaction.getHash();
                String input = transaction.getInput();
                byte[] bytes = Numeric.hexStringToByteArray(input);
                String inputStr = new String(bytes);
                result.put("to",to);
                result.put("from",from);
                result.put("value",value);
                result.put("v",v);
                result.put("nonce",nonce);
                result.put("creates",creates);
                result.put("blockNumber",blockNumber);
                result.put("gas",gas);
                result.put("gasPrice",gasPrice);
                result.put("s",s);
                result.put("blockNumberRaw",blockNumberRaw);
                result.put("hash",hash);
                result.put("input",inputStr);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return result ;
    }
/**
 * 获取nonce
 * @param address
 * @return
 */
public BigInteger getNonceByFromAddress(String address){
    try{
        EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(address,DefaultBlockParameterName.LATEST).sendAsync().get();
        return ethGetTransactionCount.getTransactionCount();
    }catch (Exception e){
        e.printStackTrace();
    }
    return null;
}
}


后续发布基于nodejs的web3开发
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值