以太坊离线签名转账交易-Java版

  • Chain哥
  • 更新于 2022-11-16 09:19
  • 阅读 3477

以太坊离线签名转账交易-Java版

一、在之前创建的spring boot 项目中的 pom.xml文件中加入需要的依赖

<dependency>
    <groupId>org.web3j</groupId>
    <artifactId>core</artifactId>
    <version>3.6.0</version>
</dependency>

链接区块链节点

  /**
     * 连接web3 节点
     */
    private final static Web3j web3j = Web3j.build(new HttpService("https://ropsten.infura.io"));

二、创建ETH转账方法

/**
     * ETH转账
     * @throws IOException
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void signETHTransaction() throws IOException, ExecutionException, InterruptedException {

        //发送方地址
        String from = "";
        //转账数量
        String amount = "1";
        //接收者地址
        String to = "";
        //发送方私钥
        String privateKey = "";
        //查询地址交易编号
        BigInteger nonce = web3j.ethGetTransactionCount(from, DefaultBlockParameterName.PENDING).send().getTransactionCount();
        //支付的矿工费
        BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice();
        BigInteger gasLimit = new BigInteger("210000");

        BigInteger amountWei = Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger();
        //签名交易
        RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, to, amountWei, "");
        Credentials credentials = Credentials.create(privateKey);
        byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        //广播交易
        String hash =  web3j.ethSendRawTransaction(Numeric.toHexString(signMessage)).sendAsync().get().getTransactionHash();

        System.out.println("hash:"+hash);

    }

在main方法中执行:把输出的 Hash值 拿到区块链浏览器校验:

image.png

image.png

三、创建ETH 代币转账方法

/**
     * ETH代币转账
     * @throws IOException
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void signTokenTransaction() throws IOException, ExecutionException, InterruptedException {

        //发送方地址
        String from = "";
        //转账数量
        String amount = "1";
        //接收者地址
        String to = "";
        //发送方私钥
        String privateKey = "";
        //代币合约地址
        String coinAddress = "";
        //查询地址交易编号
        BigInteger nonce = web3j.ethGetTransactionCount(from, DefaultBlockParameterName.PENDING).send().getTransactionCount();
        //支付的矿工费
        BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice();
        BigInteger gasLimit = new BigInteger("90000");

        Credentials credentials = Credentials.create(privateKey);
        BigInteger amountWei = Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger();

        //封装转账交易
        Function function = new Function(
                "transfer",
                Arrays.<Type>asList(new org.web3j.abi.datatypes.Address(to),
                        new org.web3j.abi.datatypes.generated.Uint256(amountWei)),
                Collections.<TypeReference<?>>emptyList());
        String data = FunctionEncoder.encode(function);
        //签名交易
        RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, coinAddress, data);
        byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        //广播交易
        String hash = web3j.ethSendRawTransaction(Numeric.toHexString(signMessage)).sendAsync().get().getTransactionHash();
        System.out.println("hash:"+hash);
    }

同样在main方法中执行:把输出的 Hash值 难道区块链浏览器校验:

image.png

image.png

完整代码

package com.example.demo.eth;

import com.google.common.collect.ImmutableList;
import org.bitcoinj.crypto.*;
import org.bitcoinj.wallet.DeterministicSeed;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.crypto.*;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.http.HttpService;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;
import sun.security.provider.SecureRandom;

import java.io.IOException;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;

public class Wallet {

    /**
     * path路径
     */
    private final static ImmutableList<ChildNumber> BIP44_ETH_ACCOUNT_ZERO_PATH =
            ImmutableList.of(new ChildNumber(44, true), new ChildNumber(60, true),
                    ChildNumber.ZERO_HARDENED, ChildNumber.ZERO);

    /**
     * 连接web3 节点
     */
    private final static Web3j web3j = Web3j.build(new HttpService("https://ropsten.infura.io"));

    public static void main(String[] args) throws Exception {
        //创建钱包
        //createWallet();

        //ETH转账交易
        //signETHTransaction();

        //ETH代币转账交易
        signTokenTransaction();
    }

    /**
     * 创建钱包
     * @throws MnemonicException.MnemonicLengthException
     */
    private static void createWallet()  throws MnemonicException.MnemonicLengthException {
        SecureRandom secureRandom = new SecureRandom();
        byte[] entropy = new byte[DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8];
        secureRandom.engineNextBytes(entropy);

        //生成12位助记词
        List<String>  str = MnemonicCode.INSTANCE.toMnemonic(entropy);

        //使用助记词生成钱包种子
        byte[] seed = MnemonicCode.toSeed(str, "");
        DeterministicKey masterPrivateKey = HDKeyDerivation.createMasterPrivateKey(seed);
        DeterministicHierarchy deterministicHierarchy = new DeterministicHierarchy(masterPrivateKey);
        DeterministicKey deterministicKey = deterministicHierarchy
                .deriveChild(BIP44_ETH_ACCOUNT_ZERO_PATH, false, true, new ChildNumber(0));
        byte[] bytes = deterministicKey.getPrivKeyBytes();
        ECKeyPair keyPair = ECKeyPair.create(bytes);
        //通过公钥生成钱包地址
        String address = Keys.getAddress(keyPair.getPublicKey());

        System.out.println();
        System.out.println("助记词:");
        System.out.println(str);
        System.out.println();
        System.out.println("地址:");
        System.out.println("0x"+address);
        System.out.println();
        System.out.println("私钥:");
        System.out.println("0x"+keyPair.getPrivateKey().toString(16));
        System.out.println();
        System.out.println("公钥:");
        System.out.println(keyPair.getPublicKey().toString(16));
    }

    /**
     * ETH转账
     * @throws IOException
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void signETHTransaction() throws IOException, ExecutionException, InterruptedException {

        //发送方地址
        String from = "";
        //转账数量
        String amount = "1";
        //接收者地址
        String to = "";
        //发送方私钥
        String privateKey = "";
        //查询地址交易编号
        BigInteger nonce = web3j.ethGetTransactionCount(from, DefaultBlockParameterName.PENDING).send().getTransactionCount();
        //支付的矿工费
        BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice();
        BigInteger gasLimit = new BigInteger("210000");

        BigInteger amountWei = Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger();
        //签名交易
        RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, to, amountWei, "");
        Credentials credentials = Credentials.create(privateKey);
        byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        //广播交易
        String hash =  web3j.ethSendRawTransaction(Numeric.toHexString(signMessage)).sendAsync().get().getTransactionHash();

        System.out.println("hash:"+hash);

    }

    /**
     * ETH代币转账
     * @throws IOException
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void signTokenTransaction() throws IOException, ExecutionException, InterruptedException {

        //发送方地址
        String from = "";
        //转账数量
        String amount = "1";
        //接收者地址
        String to = "";
        //发送方私钥
        String privateKey = "";
        //代币合约地址
        String coinAddress = "0x96a02A09EFcb1c0f9deEa33B01FFb991B77Db1eA";
        //查询地址交易编号
        BigInteger nonce = web3j.ethGetTransactionCount(from, DefaultBlockParameterName.PENDING).send().getTransactionCount();
        //支付的矿工费
        BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice();
        BigInteger gasLimit = new BigInteger("210000");

        Credentials credentials = Credentials.create(privateKey);
        BigInteger amountWei = Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger();

        //封装转账交易
        Function function = new Function(
                "transfer",
                Arrays.<Type>asList(new org.web3j.abi.datatypes.Address(to),
                        new org.web3j.abi.datatypes.generated.Uint256(amountWei)),
                Collections.<TypeReference<?>>emptyList());
        String data = FunctionEncoder.encode(function);
        //签名交易
        RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, coinAddress, data);
        byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        //广播交易
        String hash = web3j.ethSendRawTransaction(Numeric.toHexString(signMessage)).sendAsync().get().getTransactionHash();
        System.out.println("hash:"+hash);
    }
}

image.png

学如逆水行舟,不进则退。心似平原跑马,易放难收。全栈工程师是指掌握多种技能,并能利用多种技能独立完成产品的人。 也叫全端工程师(同时具备前端和后台能力),英文Full Stack engineer。【人工智能】【区块链】【系统/网络/运维】【云计算/大数据】【数据库】【移动开发】【后端开发】【游戏开发】【UI设计】【微服务】【爬虫】【Java】【Go】【C++】【PHP】【Python】【Android/IOS】【HTML/CSS】【JavaScript】【Node】。。。

欢迎各位大神萌新一起专研分享各行各业技术!

Chain区块链开发社区:593674370

点赞 0
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Chain哥
Chain哥
个人简介:学如逆水行舟,不进则退。心似平原跑马,易放难收!