波场钱包-android篇

1:使用Protocol Buffers

 首先根目录gradle中添加依赖:

 classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.3"

 然后项目文件中添加plugin,添加依赖包:

apply plugin: 'com.google.protobuf'

protobuf {
    protoc {
        artifact = 'com.google.protobuf:protoc:3.6.1'
    }
    plugins {
        javalite {
            artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
        }
        grpc {
            artifact = 'io.grpc:protoc-gen-grpc-java:1.17.1'
        }
    }
    generateProtoTasks {
        all().each { task ->
            task.plugins {
                javalite {}
                grpc {
                    // Options added to --grpc_out
                    option 'lite'
                }
            }
        }
    }
    configurations {
        all*.exclude group: 'com.android.support', module: 'support-v13'
    }
}


dependencies {
    api 'io.grpc:grpc-okhttp:1.17.1'
    api 'io.grpc:grpc-protobuf-lite:1.17.1'
    api 'io.grpc:grpc-stub:1.17.1'
  }

 最后main下添加proto路径,添加proto文件;

 

2:tron基础类

       关于tron的基础类,我整理了个lib,使用时直接导入lib即可。

       主要包括wallet钱包类,管理类等内容。

       

 这里我主要贴出wallet的代码

package org.tron.walletserver;


import android.os.Build;
import android.support.annotation.RequiresApi;

import org.tron.common.crypto.ECKey;
import org.tron.common.utils.Utils;

import java.math.BigInteger;

public class Wallet {
    private ECKey mECKey = null;

    private boolean isWatchOnly = false;
    private boolean isColdWallet = false;
    private String walletName = "";
    private String encPassword = "";
    private String address = "";
    private byte[] encPrivateKey;
    private byte[] publicKey;


    public Wallet() {
    }

    public Wallet(boolean generateECKey) {
        if(generateECKey) {
            mECKey = new ECKey(Utils.getRandom());
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public Wallet(String privateKey) {
        setPrivateKey(privateKey);
    }

    public boolean isOpen() {
        return mECKey != null && mECKey.getPrivKeyBytes() != null;
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public boolean open(String password) {
        if(encPrivateKey != null) {
            setPrivateKey(AddressUtils.decryptPrivateKey(encPrivateKey, password));
            return isOpen();
        } else {
            return false;
        }
    }

    public byte[] getPublicKey() {
        return mECKey != null ? mECKey.getPubKey() : publicKey;
    }

    public void setPublicKey(byte[] publicKey) {
        this.publicKey = publicKey;
    }

    public byte[] getPrivateKey() {
        return mECKey != null ? mECKey.getPrivKeyBytes() : null;
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public void setPrivateKey(String privateKey) {
        if(privateKey != null && !privateKey.isEmpty()) {
            ECKey tempKey = null;
            try {
                BigInteger priK = new BigInteger(privateKey, 16);
                tempKey = ECKey.fromPrivate(priK);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            mECKey = tempKey;
        } else {
            mECKey = null;
        }
    }


    public boolean isWatchOnly() {
        return isWatchOnly;
    }

    public void setWatchOnly(boolean watchOnly) {
        isWatchOnly = watchOnly;
    }

    public boolean isColdWallet() {
        return isColdWallet;
    }

    public void setColdWallet(boolean coldWallet) {
        isColdWallet = coldWallet;
    }

    public String getWalletName() {
        return walletName;
    }

    public void setWalletName(String walletName) {
        this.walletName = walletName;
    }

    public String getEncryptedPassword() {
        return encPassword;
    }

    public void setEncryptedPassword(String password) {
        this.encPassword = password;
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public String getAddress() {
        if(mECKey != null) {
            return AddressUtils.encode58Check(mECKey.getAddress());
        }
        else if (publicKey != null){
            return AddressUtils.encode58Check(ECKey.fromPublicOnly(publicKey).getAddress());
        } else {
            return address;
        }
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public ECKey getECKey() {
        return mECKey;
    }

    public byte[] getEncryptedPrivateKey() {
        return encPrivateKey;
    }

    public void setEncryptedPrivateKey(byte[] encPrivateKey) {
        this.encPrivateKey = encPrivateKey;
    }

}

3:导入钱包

     

     其实就一步操作,就是根据私钥 创建wallet对象。

//根据私钥创建钱包
 Wallet wallet = new Wallet(privateKey);
//设置钱包名称,我这里不需要就设置成钱包地址了。
 wallet.setWalletName(wallet.getAddress());
//项目存储导入的钱包
 TronManager.storeTron(wallet);
 
                

4:创建钱包

       创建钱包需要两个参数,一个是钱包名称,一个是设置的密码,钱包名称还好,重要的是密码,因为转账,导出私钥助记词等信息时,都是需要密码验证的。

Wallet wallet = new Wallet(true);
wallet.setWalletName(name);
WalletManager.store(this,wallet, pwd);

store方法是使用SharedPreferences存储当前钱包的信息,其中我们可以通过密码来获取wallet的eckey从而得到钱包的公钥和私钥。

5:钱包信息

      这里主要用到项目中grpcClient类和walletmanager类。

      这个类主要封装了对应的网络请求以及钱包管理

       grpcClient类的initGrpc需要传入对应的fullnode和soliditynode,这个可以去下面的地址去选择,

   https://github.com/tronprotocol/Documentation/blob/master/TRX_CN/Official_Public_Node.md

 查询账户需要用到账户的地址:

Protocol.Account account = WalletManager.queryAccount(address, false);
GrpcAPI.AccountNetMessage accountNetMessage = WalletManager.getAccountNet(address);
GrpcAPI.AccountResourceMessage accountResMessage = WalletManager.getAccountRes(address);

  account可以查询balance和FrozenList;

  accountNetMessage 可以查询账户的带宽信息。

具体代码如下:

   double balance=mAccount.getBalance()/1000000.0d;
            binding.tvWalletAccount.setText(balance+"");

            long frozenTotal = 0;
            for(Protocol.Account.Frozen frozen : mAccount.getFrozenList()) {
                frozenTotal += frozen.getFrozenBalance();
            }
            binding.tvWalletTronWeight.setText((frozenTotal/1000000)+"");

            GrpcAPI.AccountNetMessage accountNetMessage = TronUtil.getAccountNet(getActivity(), wallet.getWalletName());

            long bandwidth = accountNetMessage.getNetLimit() + accountNetMessage.getFreeNetLimit();
            long bandwidthUsed = accountNetMessage.getNetUsed()+accountNetMessage.getFreeNetUsed();
            long bandwidthLeft = bandwidth - bandwidthUsed;

            binding.tvWalletBandwidth.setText(bandwidthLeft+"");

 

6:转账

          

  byte[] toRaw;
        try {
            toRaw = WalletManager.decodeFromBase58Check(sendAddress);
        } catch (IllegalArgumentException ignored) {
            Toast.makeText(this,"请输入一个有效地址",Toast.LENGTH_SHORT).show();
            return;
        }

        double amount=Double.parseDouble(sendAmount);
        Contract.TransferContract contract = WalletManager.createTransferContract(toRaw, WalletManager.decodeFromBase58Check(mWallet.getAddress()), (long) (amount * 1000000.0d));
        Protocol.Transaction transaction = WalletManager.createTransaction4Transfer(contract);
        byte[]  mTransactionBytes = transaction.toByteArray();
        try {
            mTransactionUnsigned = Protocol.Transaction.parseFrom(mTransactionBytes);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }

根据上面的代码,获取到mTransactionUnsigned ,然后输入密码校验密码并获取到wallet的eckey。

设置时间戳,交易签名。

mTransactionSigned = TransactionUtils.setTimestamp(mTransactionUnsigned);
mTransactionSigned = TransactionUtils.sign(mTransactionSigned, mWallet.getECKey());
WalletManager.broadcastTransaction(mTransactionSigned);

最后一步是广播交易。

具体操作可查看源代码。

git地址

猜你喜欢

转载自blog.csdn.net/qq_23025319/article/details/86310625
今日推荐