BTC转账功能开发

BTC转账功能开发

一、准备工作

1、下载metamask钱包插件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uQgfiZ6B-1660126639658)(/Users/wanping/Desktop/博文/btc/00001.png)]

根据提示使用助记词生成账户,这里可以看到用户可以保留助记词,但是不保留私钥,或者keystore的json文件。可以生成一个账户

2、创建账户

针对于java和以太坊之间操作,一般有两种生成账户的方法:

  • 使用metamask插件运用助记词创建账户的方法

  • 用代码生成账户的方法,该方法有一个好处就是我们能够掌握账户的私钥(keystore的json文件)

    • maven配置

      <dependency>
                  <groupId>org.bitcoinj</groupId>
                  <artifactId>bitcoinj-core</artifactId>
                  <version>0.14.7</version>
              </dependency>
      
              <dependency>
                  <groupId>org.web3j</groupId>
                  <artifactId>core</artifactId>
                  <version>3.6.0</version>
              </dependency>
      
    • 代码实现

      /**
           * 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);
      
      
      
          /**
           * 创建钱包
           * @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.nextBytes(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));
          }
      
          public static void main(String[] args) throws Exception {
              //创建钱包
              createWallet();
          }
      
    • 导入钱包

      • 保存上述打印东西
      • 打开小狐狸钱包,导入私钥

3、领取测试币

领取测试币地址5ETH:https://faucet.dimensions.network/

二、ETH转账交易

1、创建自己的以太坊节点地址

参考区块链同学给我的地址:https://docs.infura.io/infura/networks/ethereum/json-rpc-methods/eth_sendtransaction

先注册=》创建项目=〉进入自己的项目

选择项目属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mbD4FyXM-1660126639660)(/Users/wanping/Desktop/博文/btc/00002.png)]

复制自己的测试网节点地址(下拉到自己的测试网地址)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xvd326d9-1660126639660)(/Users/wanping/Desktop/博文/btc/00003.png)]

2、代码编写

实现ETH转账
/**
     * 连接web3 节点
     */
    private final static Web3j web3j = Web3j.build(new HttpService("https://rinkeby.infura.io/v3/第一步的那个项目编号"));

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

        //发送方地址
        String from = "0xe12A0E286C94747E9D8a67e18FBDF35D6B58C5B6";
        //转账数量
        String amount = "0.05";
        //接收者地址
        String to = "0x336185cc47e81422d8ff26fb9a7a9c4138ce3d2a";
        //发送方私钥
        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);

    }

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4PrNQVlh-1660126639661)(/Users/wanping/Desktop/博文/btc/00006.png)]

转账结果
转账之前:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W4tP8shx-1660126639662)(/Users/wanping/Desktop/博文/btc/00004.png)]

转账后:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5u9wJs4Z-1660126639663)(/Users/wanping/Desktop/博文/btc/00005.png)]

3、代币查询

由于没有ETH的代币,所以找区块链的同学转了点币安测试网的代币

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wiV6cRKI-1660126639663)(/Users/wanping/Desktop/博文/btc/00007.png)]

代币余额查询
/**
     * 连接web3 节点
     */
    private final static Web3j web3j = Web3j.build(new HttpService("https://data-seed-prebsc-2-s2.binance.org:8545/项目编号"));
private static final BigDecimal WEI = new BigDecimal(10000);
/**
* 获取ERC-20 token指定地址余额
*/
public static void getbscGetBalance() throws ExecutionException, InterruptedException {
        String methodName = "balanceOf";
        List<Type> inputParameters = new ArrayList<>();
        List<TypeReference<?>> outputParameters = new ArrayList<>();
        Address fromAddress = new Address("发送方地址");
        inputParameters.add(fromAddress);

        TypeReference<Uint256> typeReference = new TypeReference<Uint256>() {};
        outputParameters.add(typeReference);
        Function function = new Function(methodName, inputParameters, outputParameters);
        String data = FunctionEncoder.encode(function);
        Transaction transaction = Transaction.createEthCallTransaction("发送方地址", "合约地址", data);

        EthCall ethCall;
        BigDecimal balanceValue = BigDecimal.ZERO;
        try {
            ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
            List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
            BigInteger value = BigInteger.valueOf(0);
            if(results != null && results.size()>0){
                value = (BigInteger)results.get(0).getValue();
            }
            balanceValue = new BigDecimal(value).divide(WEI, 6, RoundingMode.HALF_DOWN);
            System.out.println(balanceValue.toBigInteger());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
查询余额结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lxATEKRB-1660126639664)(/Users/wanping/Desktop/博文/btc/00008.png)]

4、代币转账

转账代码实现:

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

        //发送方地址
        String from = "0xe12A0E286C94747E9D8a67e18FBDF35D6B58C5B6";
        //转账数量
        String amount = "5";
        //接收者地址
        String to = "0x336185cC47e81422D8fF26fB9A7a9c4138Ce3D2A";
        //发送方私钥
        String privateKey = "****";
        //代币合约地址
        String coinAddress = "合约地址";
        //查询地址交易编号
        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);
    }

执行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qfIp4W2v-1660126639665)(/Users/wanping/Desktop/博文/btc/00009.png)]

转账结果
转账之前

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lvNO4Y2i-1660126639666)(/Users/wanping/Desktop/博文/btc/00010.png)]

转账之后:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tjzUY7YE-1660126639666)(/Users/wanping/Desktop/博文/btc/00011.png)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值