由于我们做的区块链钱包是只传用用户私匙签名后的hex字符串到服务端, 然后服务端再进行统一的交易处理, 所以客户端就需要做到离线签名的功能, 那么在以太坊的如何签名转账hex呢? 以太坊有ETH和基于以太坊上面的代币, 比如EOS, QUN等, 这种是基于智能合约的, 签名也就不一样了.

ETH转账签名

这里需要用web3j的方法, 所以需要先添加web3j依赖

1
implementation 'org.web3j:core:3.3.1-android'

那么现在来试试如何做离线签名吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fun signedEthTransactionData(to: String, //转账的钱包地址
nonce: BigInteger,//获取到的交易次数
gasPrice: BigInteger, //
gasLimit: BigInteger, //
value: Double, //转账的值
tianWallet: TianWallet): String {
//把十进制的转换成ETH的Wei, 1ETH = 10^18 Wei
val realValue = Convert.toWei(value.toString(), Convert.Unit.ETHER)
val rawTransaction = RawTransaction.createEtherTransaction(
nonce,
gasPrice,
gasLimit,
to,
realValue.toBigIntegerExact())
//手续费= (gasPrice * gasLimit ) / 10^18 ether
val credentials = loadBip39Credentials(tianWallet.words)
//使用TransactionEncoder对RawTransaction进行签名操作
val signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials)
//转换成0x开头的字符串
return Numeric.toHexString(signedMessage)
}

基于以太坊的代币转账签名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
fun signedContractTransactionData(contractAddress: String,//代币的智能合约地址
toAdress: String,//对方的地址
nonce: BigInteger,//获取到交易数量
gasPrice: BigInteger,
gasLimit: BigInteger,
value: Double, decimal: Double,
tianWallet: TianWallet): String {
//因为每个代币可以规定自己的小数位, 所以实际的转账值=数值 * 10^小数位
val realValue = BigDecimal.valueOf(value * Math.pow(10.0, decimal))
//0xa9059cbb代表某个代币的转账方法hex(transfer) + 对方的转账地址hex + 转账的值的hex
val data = "0xa9059cbb" + Numeric.toHexStringNoPrefixZeroPadded(Numeric.toBigInt(toAdress), 64) + toHexStringNoPrefixZeroPadded(realValue.toBigInteger(), 64)
val rawTransaction = RawTransaction.createTransaction(
nonce,
gasPrice,
gasLimit,
contractAddress,
data)

val credentials = loadBip39Credentials(tianWallet.words)
//使用TransactionEncoder对RawTransaction进行签名操作
val signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials)
//转换成0x开头的字符串
return Numeric.toHexString(signedMessage)
}

区块链安卓开发群:区块链安卓开发 431969409