区块链钱包系统开发应用难点解析(附源码示例)

747 阅读4分钟

在日常生活中,大家都会买个钱包用于存放我们日常使用发行的纸币,那数字资产世界的钱包是怎么样的呢? 对于数字资产世界里而言,钱包就是一个密钥 (包含私钥和公钥) 的管理容器。用户用私钥来签名交易, 从而证明该用户拥有交易的输出权限,其交易信息并不是存储在该钱包内,而是储存在区块链中。

区块链数字钱包系统能对比特币、以太坊等多种主流的数字货币进行统一的管理与存储,也就是说所有货币都能装到一个钱包来进行管理,这样大大的降低了数字货币的使用门槛和管理负担,使用起来也更加灵活方便。 一个钱包通常主要包含的功能有: 账号管理(主要是私钥的管理):创建账号、账号导入导出 账号信息展示:如以太币余额、Token(代币)余额。 转账功能:发送以太币及发送Token(代币)

区块链钱包开发源码示例:

钱包文件

保存私钥和转账记录

Wallet containing 0.01 BTC (spendable: 0.01 BTC) in:

0 pending transactions

1 unspent transactions

0 spent transactions

0 dead transactionsLast seen best block: 1384907 (2018-08-22T03:38:42Z): 0000000000000030fe01a48a7cd6b0c52909a7d019084d195ae3ebd2889c82ec

Keys:Earliest creation time: 2018-08-20T07:51:29ZSeed birthday: 1534751489 [2018-08-20T07:51:29Z]Key to watch: tpubD92y4mcSrbcSxANfCgiWx7h7sGquSF4ogNPcUxC2GECSwgWBMNPMo2C8nxez2ngvSS4UfaGhSunemWoqZ6aAAzLb4WLsmQxDirfFgE9tG5J

addr:mq5gdvJDuDEmNKFPbgMn8pGm3pyJvkSsHv hash160:68e9c9e06890527cd0f0b59d83333502ac127bef (M/0H/0/0)

>>> UNSPENT:0.01 BTC total value (sends 0.00 BTC and receives 0.01 BTC)

confidence: Seen by 7 peers (most recently: 2018-08-22T03:33:33Z). Appeared in best chain at height 1384907, depth 1. Source: NETWORK

a82c35c2133bd357bfa462f82d75b28787afcdcd20c8b89cd2b78f48138d6e9f

updated: 2018-08-22T03:31:53Z

in PUSHDATA(71)[304402205d3e0974b4604b92e09f83950b183100bd47243c9cb548f2213a9ca26e83bdd3022018278c7ce9b65982e6c67ba9acf8e6e3898f1dad80702bb1e32c4a0b61195e0f01] PUSHDATA(33)[02f8769ecddd821cc9b75c554978b4a674df28c098e640fd0188b88bf019bc31fa]

outpoint:8294b8dcf6513ab13321d4dd1642bf1c19600a313bf1ebe8511521dcd4dd0277:0

out DUP HASH160 PUSHDATA(20)[8843beff2291c5a00aa00fbd8a541f800c83b86d] EQUALVERIFY CHECKSIG 1.1899548 BTC

out DUP HASH160 PUSHDATA(20)[68e9c9e06890527cd0f0b59d83333502ac127bef] EQUALVERIFY CHECKSIG 0.01 BTC

prps UNKNOWN

## ##

获取钱包地址

//Utils.java

public static byte[] sha256hash160(byte[] input) {

byte[] sha256 = Sha256Hash.hash(input);

RIPEMD160Digest digest = new RIPEMD160Digest();

digest.update(sha256, 0, sha256.length);

byte[] out = new byte[20];

digest.doFinal(out, 0);

return out;

}

从文件中加载钱包

//

读取钱包文件

File walletFile = activity.getFileStreamPath("wallet-protobuf");

if (walletFile.exists()) {

InputStream inputStream = new FileInputStream(walletFile);

//

反序列化

wallet = new WalletProtobufSerializer().readWallet(inputStream);

//

设置自动保存

wallet.autosaveToFile(walletFile, 3 * 1000, TimeUnit.MILLISECONDS, null);

//

清理钱包

wallet.cleanup();

}

通过助记词创建钱包

File destination = new File(walletDir, walletFileName);

objectMapper.writeValue(destination, wallet);

//

创建助记词

public List createMnemonics() throws MnemonicException.MnemonicLengthException {

SecureRandom secureRandom = new SecureRandom();

byte[] entropy = new byte[DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8];

secureRandom.nextBytes(entropy);

return MnemonicCode.INSTANCE.toMnemonic(entropy);

}

//m / 44' / 60' / 0' / 0

//Hardened

意思就是派生加固,防止获取到一个子私钥之后可以派生出后面的子私钥

//

必须还有上一级的父私钥才能派生

public static final ImmutableList BIP44_ETH_ACCOUNT_ZERO_PATH =

ImmutableList.of(new ChildNumber(44, true), new ChildNumber(60, true),

ChildNumber.ZERO_HARDENED, ChildNumber.ZERO);

//

通过助记词生成

HD

钱包

public void onCreateWallet(View view) {

byte[] seed = MnemonicCode.toSeed(words, "");

DeterministicKey masterPrivateKey = HDKeyDerivation.createMasterPrivateKey(seed);

DeterministicHierarchy deterministicHierarchy = new DeterministicHierarchy(masterPrivateKey);

// m / 44' / 60' / 0' / 0 / 0

DeterministicKey deterministicKey = deterministicHierarchy

.deriveChild(BIP44_ETH_ACCOUNT_ZERO_PATH, false, true, new ChildNumber(0));

byte[] bytes = deterministicKey.getPrivKeyBytes();

ECKeyPair keyPair = ECKeyPair.create(bytes);

try {

WalletFile walletFile = Wallet.createLight(PASSWORD, keyPair);

String address = walletFile.getAddress();

mAddress.setText("0x" + address);

} catch (CipherException e) {

e.printStackTrace();

}

}