比特币Bitcoin应用HelloWorld开发
阐明一个事:以太坊和比特币都不是区块链,它们是基于区块链的一种应用,区块链可以理解为各种技术的组合或者一直新型的“数据库”。想要了解更多,可以去度娘下载相关的白皮书蓝皮书看看,可以下载观摩。
说明:以下样例和代码操作都是基于Java版的钱包应用来描述的。
标签:比特币钱包开发,区块链钱包开发,bitcoin钱包开发,bitcoinj接口使用,比特币测试网络,获取比特币测试币
一 测试网络
比特币提供的测试网络:
a)TestNet2、TestNet3 测试网络
b)UnitTest 测试网络,针对单元测试的特殊网络
c)RegTest 私有网络,主要是个人或企业自己搭建的网络
d)MainNet、ProdNet,正式网络,生产网络,生产环境使用
二 涉及框架或模块(Java)
bitcoinj, gtihub:
bitcoinj是一个使用比特币协议的库。它可以维护钱包,发送/接收交易而无需比特币核心的本地副本,并具有许多其他高级功能。它是用Java实现的,但可以从任何JVM兼容语言中使用:包括Python和JavaScript中的示例。
它附带完整的文档,并在其上构建了许多大型,众所周知的比特币应用程序和服务。
特征
高度优化的轻量级简化支付验证(SPV)模式。在这种模式下,只下载了一小部分区块链,使比特币适合在智能手机或廉价虚拟专用服务器等受限设备上使用。 实验性完整验证模式,与比特币核心执行相同的验证工作。在此模式下,计算未使用的事务输出集(UTXO集),并且由于PostgreSQL存储,可以将其索引到数据库中,以便按地址快速查找余额。 带有加密,费用计算,多重签名,确定性密钥派生,可插入硬币选择/硬币控制,扩展支持和事件监听器的钱包类,让您及时了解余额变化。 支持微支付渠道,允许您在客户端和服务器之间建立多签名合同,然后在渠道上进行协商,允许快速小额支付,以避免矿工费用。 为网络IO 提供异步和每线程连接,允许您在可伸缩性和仅阻塞功能(如SOCKS / Tor代理)之间进行选择。 轻松实现使用比特币合约功能的应用程序。 一个简单的GUI钱包应用程序,您可以将其用作自己的应用程序的基础。观看或阅读有关如何自定义它的教程,并构建不需要Java的本机安装程序。。
js的版本:,可自行参考。
三 使用样例(部分代码)
maven依赖
<dependency> <groupId>org.bitcoinj</groupId> <artifactId>bitcoinj-core</artifactId> <version>0.14.7</version></dependency>
//# 创建钱包
WalletAppKit walletAppKit = new WalletAppKit(networkParam(), new File("."), walletName);walletAppKit.startAsync();walletAppKit.awaitRunning();Wallet wallet = walletAppKit.wallet();DeterministicSeed keyChainSeed = wallet.getKeyChainSeed();DeterministicKeyChain deterministicKeyChain = DeterministicKeyChain.builder().seed(keyChainSeed).build();BigInteger privateKey = deterministicKeyChain.getKeyByPath(parsePath("M"), true).getPrivKey();ECKey ecKey = ECKey.fromPrivate(privateKey);wallet.importKey(ecKey);Address watchedAddresses = LegacyAddress.fromKey(networkParam(), ecKey);wallet.addWatchedAddress(watchedAddresses);Address address = wallet.getWatchedAddresses().get(0);List<String> mnemonicCode = wallet.getKeyChainSeed().getMnemonicCode();String seedCode = String.join(" ", mnemonicCode);log.info("walletAddress={}", address.toString());log.info("privateKey={}", ecKey.getPrivKey());log.info("encode privateKey={}", ecKey.getPrivateKeyEncoded(networkParam()));log.info("hex privateKey={}", ecKey.getPrivateKeyAsHex());log.info("wif privateKey={}", ecKey.getPrivateKeyAsWiF(networkParam()));log.info("seedCode={}", seedCode); //# 助记词
//# 查询账户余额,address是0x开头地址
WalletAppKit walletAppKit = new WalletAppKit(networkParam(), new File("."), walletName);walletAppKit.startAsync();walletAppKit.awaitRunning();Wallet wallet = walletAppKit.wallet();Coin balance = wallet.getBalance();
//# 转账,返回交易hash
WalletAppKit kit = new WalletAppKit(params, new File("."), walletName);kit.startAsync();kit.awaitRunning();log.warn("==================================================================");log.warn("========================= update completed =========================");log.warn("==================================================================");Coin value = Coin.parseCoin("0.02");LegacyAddress to = LegacyAddress.fromBase58(params, "monEGqJ2uTNSAbHudVPCCszx7mWMH2oL3z");log.info("send money[{}] to address[{}]", value.getValue(), to.toString());System.out.println("balance= "+kit.wallet().getBalance().getValue());System.out.println("balance= "+kit.wallet().getBalance().toFriendlyString());try { SendRequest sendRequest = SendRequest.to(to, value); Wallet.SendResult result = kit.wallet().sendCoins(sendRequest);
//# 返回交易hash log.info("coins sent. transaction hash: {}", result.tx.getHashAsString());} catch (InsufficientMoneyException e) { log.error("send money[{}] to address[{}] error", value.getValue(), to.toString()); log.error("not enough coins in your wallet. Missing {} satoshis are missing (including fees)", e.missing.getValue());}ListenableFuture<Coin> balanceFuture = kit.wallet().getBalanceFuture(value, Wallet.BalanceType.AVAILABLE);FutureCallback<Coin> callback = new FutureCallback<Coin>() { @Override public void onSuccess(Coin balance) { log.info("----------- **************************************************** ----------------------"); log.info("----------- coins arrived and the wallet now has enough balance ----------------------"); log.info("----------- **************************************************** ----------------------"); } @Override public void onFailure(Throwable t) { log.error("....................................."); log.error("@ something went wrong #"); log.error("....................................."); }};Futures.addCallback(balanceFuture, callback);
四 网站查看余额及交易记录
testnet环境:
五 密钥普及
公钥和私钥成对出现
公开的密钥叫公钥,只有自己知道的叫私钥
用公钥加密的数据只有对应的私钥可以解密
用私钥加密的数据只有对应的公钥可以解密
如果可以用公钥解密,则必然是对应的私钥加的密
如果可以用私钥解密,则必然是对应的公钥加的密
Keystore+密码=银行卡号+银行卡密码
Keystore ≠ 私钥
Keystore+密码=私钥
Keystore不是私钥,常见于以太坊钱包,一般你创建以太坊钱包后,会让你备份Keystore,输入密码,会出现一串字符这就是 Keystore。Keystore的本质是加密后的私钥,Keystore必须配合你的钱包密码来使用。用途:在导入钱包的时候,选择官方钱包,输入 Keystore 和密码,就能进入钱包了。需要说明的是,这和用私钥或助记词导入钱包不一样,用私钥或助记词导入钱包,不需要知道密码。
私钥:私钥可以计算出公钥,公钥可以经过一系列数字签名生成钱包地址。所以, 私钥的持有者才是数字货币的持有者。你可以把它看成是你的银行卡密码。
公钥:它是密码学上的概念,由私钥推算出来。公开密钥的算法属于不对称加密算法,该算法拥有两个密钥:公钥和私钥。使用私钥加密的数据可以用公钥解密,反之亦可。通过公钥可以算出钱包地址。
钱包地址:地址由公钥转换而来,地址被用于接收数字货币,一个地址上收到数字货币后,只有使用该地址所对应的私钥才能花费这个地址上的钱。可以把钱包地址想象成一个银行卡号,别人可以给你的钱包地址打钱。一般地址和私钥是成对出现的,他们的关系就像银行卡号和密码。地址就像银行卡号一样用来记录你在该钱包地址上存有多少币。我们可以简单的把钱包地址理解成为银行卡号,该钱包地址的私钥理解成为所对应银行卡号的密码。只有你在知道银行密码的情况下才能使用银行卡号上的钱。所以,在使用钱包时请保存好你的地址和私钥。
六 获取测试币
除了开发过程使用,其他时候没有任何实际价值,表当真^_^, 谁认真谁输.....
这个水龙头好像呜呼哀哉了~
这个偶尔可以用,现在也不稳定了~
写的不好,不喜勿喷! 谢谢~~
如果觉得申请比特币测试币麻烦,可以加我获取,×××测试币~~~
企鹅号: 631722350
邮箱: vip_warne@163.com