/ *
|
* 2011年谷歌公司
|
*
|
*许可下在Apache许可证2.0版(以下简称“许可证”);
|
*您不得使用除符合许可文件。
|
*您可能获得执照副本
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
*除非适用法律要求或书面同意,软件
|
*根据许可证分发,分发“AS IS”基础上,
|
*没有任何形式的担保或条件,明示或暗示。
|
*请参阅许可和管辖权限的具体语言
|
*根据许可证的限制。
|
* /
|
|
封装COM 。谷歌。bitcoin 。例子。toywallet ;
|
|
进口COM 。谷歌。bitcoin 。核心;
|
进口COM bitcoin 。发现。DnsDiscovery ;
|
进口COM 谷歌 。bitcoin 。商店。BoundedOverheadBlockStore ;
|
进口COM 。谷歌。bitcoin 。utils的。BriefLogFormatter ;
|
进口。BouncyCastle的。UTIL 。编码器。六角;
|
|
进口javax 。摆动*。;
|
进口的Java AWT *。
|
导入的Java 。io的文件;
|
进口的Java IO 。IOException异常;
|
进口的Java 。数学。
|
进口的Java 。净。的InetAddress ;
|
进口的Java 。util的。ArrayList的;
|
导入的Java 。util的日期;
|
导入的Java 。util的名单;
|
进口的Java 。util的设置;
|
|
/ **
|
* GUI演示,让你看收到的交易,因为他们积累信心。
|
* /
|
公共 类 ToyWallet {
|
私人的 最后 TxListModel txListModel =的 新 TxListModel ();
|
私人 txList ;
|
私人 NetworkParameters 的params ;
|
私人 钱包钱包;
|
私营 等组等组;
|
私人 BlockChain 链;
|
私人 的JLabel networkStats ;
|
私人 文件walletFile ;
|
私人 的JScrollPane txScrollPane ;
|
|
公共 静态 无效的主要(字符串[] ARGS ) 抛出 异常 {
|
BriefLogFormatter 。的init ();
|
新 ToyWallet (假,参数);
|
}
|
|
:公共 ToyWallet (布尔testnet , 的String [] ARGS ) 抛出 异常 {
|
/ /设置1 Bitcoin连接+空的钱包。TODO:在这个用例的简化的设置。
|
如果 (testnet ) {
|
的params的= NetworkParameters 。testNet ();
|
} 否则 {
|
的params的= NetworkParameters 。prodNet ();
|
}
|
|
/ /尝试读取存储钱包,创建一个新的,如果没有可能。
|
布尔freshWallet = FALSE ;
|
walletFile = 新的 文件(“toy.wallet” );
|
尝试 {
|
钱包= 钱包。loadFromFile (walletFile );
|
} 赶上 (IOException异常e )条 {
|
钱包 (的params );
|
|
/ /允许用户在命令行上指定的第一个关键:
|
/ /十六进制编码的关键:创建时间秒
|
ECKey 的关键;
|
(参数长度> 0 ) {
|
尝试 {
|
的String [] 部分= ARGS [ 0 ]。分裂(“:” );
|
字节] pubKey = 六角。解码(部分[ 0 ]);
|
关键= 新 ECKey (空pubKey )的;
|
长creationTimeSeconds = 长。parseLong (部分[ 1 ]);
|
关键。setCreationTimeSeconds (creationTimeSeconds );
|
系统。出来。的println (字符串格式(“使用命令行%s的地址,在%s上创建”
|
关键,。toAddress (的params )。的toString (), 新的 日期(creationTimeSeconds * 1000 )。的toString ()));
|
} 渔获 (例外E2 ) {
|
系统。犯错。 +
|
“在与冒号之间的附加 秒的时间:” + E2 。的toString ());
|
返回;
|
}
|
} 否则 {
|
键= 新 ECKey (); / /生成一个新的关键。
|
}
|
钱包,钥匙扣。添加(键);
|
|
钱包的SaveToFile (walletFile );
|
freshWallet = 真;
|
}
|
系统。出来。的println (“发送到:” + 钱包。钥匙扣(0 )。toAddress (的params ));
|
系统。出来。的println (钱包);
|
|
文件blockChainFile = 新 文件(“toy.blockchain” );
|
(!blockChainFile 。EXISTS () && !freshWallet ) {
|
/ /块链,但我们有一个钱包。所以空了钱包的交易,所以,当我们重新扫描
|
/ /块有没有问题(钱包不支持没有被掏空的重播)。
|
钱包。clearTransactions (0 );
|
}
|
链=, 新 BlockChain (的params ,钱包,: 新 BoundedOverheadBlockStore (的params ,blockChainFile ));
|
|
等组 (的params ,链);
|
等组。setUserAgent (“ToyWallet” , “1.0” );
|
如果 (testnet ) {
|
等组。addAddress (新 PeerAddress (InetAddress的。 );
|
等组。addAddress (新 PeerAddress (InetAddress的。 );
|
} 否则 {
|
等组。addPeerDiscovery (新 DnsDiscovery (的params ));
|
}
|
等组。addWallet (钱包);
|
等组。setFastCatchupTimeSecs (钱包。getEarliestKeyCreationTime ());
|
|
/ /手表的同龄人来来去去,所以我们可以更新UI。
|
等组。的addEventListener (新 AbstractPeerEventListener () {
|
@覆盖
|
公共 无效onPeerConnected (同行同行, peerCount ) {
|
超。onPeerConnected的(同侪,peerCount );
|
triggerNetworkStatsUpdate ();
|
}
|
|
@覆盖
|
公共 无效onPeerDisconnected (同行同行, peerCount ) {
|
超。onPeerDisconnected的(同侪,peerCount );
|
triggerNetworkStatsUpdate ();
|
}
|
|
@覆盖
|
公共 无效onBlocksDownloaded (同伴同行, 座块, blocksLeft ) {
|
超级onBlocksDownloaded (同行,块,blocksLeft );
|
triggerNetworkStatsUpdate ();
|
handleNewBlock ();
|
}
|
});
|
|
钱包。的addEventListener (新 AbstractWalletEventListener () {
|
@覆盖
|
公共 无效onCoinsReceived (钱包钱包, BigInteger的prevBalance , BigInteger的newBalance ) {
|
超级onCoinsReceived (newBalance );
|
handleNewTransaction (TX );
|
}
|
|
@覆盖
|
公共 无效onCoinsSent (钱包钱包, 交易TX , 的BigInteger , BigInteger的newBalance ) {
|
超级。onCoinsSent (钱包,prevBalance ,newBalance );
|
handleNewTransaction (TX );
|
}
|
|
@覆盖
|
公共 无效的onChange () {
|
尝试 {
|
系统。出来。的println (“钱包变” );
|
钱包的SaveToFile (walletFile );
|
} 赶上 (IOException异常e )条 {
|
抛出 新 的RuntimeException ( e )条;
|
}
|
}
|
});
|
|
/ /创建GUI。
|
JFrame的窗口, 新 的JFrame (“玩具钱包” );
|
窗口。setDefaultCloseOperation (JFrame的。EXIT_ON_CLOSE );
|
setupWindow (窗口);
|
窗口。包();
|
窗口。setSize (640 , 480 );
|
|
/ /把钱包中的交易,进入GUI。
|
最终 集< 交易> walletTransactions = 钱包。getTransactions (真实的, 真实的);
|
SwingUtilities类。invokeAndWait (新 的Runnable () {
|
公共 无效的run () {
|
(最后 交易TX :walletTransactions ) {
|
txListModel, 。monitorTx (TX );
|
}
|
}
|
});
|
|
|
/ /去!
|
窗口。setVisible (真);
|
等组。开始();
|
等组。downloadBlockChain ();
|
}
|
|
私人 无效handleNewBlock的() {
|
SwingUtilities类。的invokeLater (新 的Runnable () {
|
公共 无效的run () {
|
txListModel 。newBlock ();
|
}
|
});
|
}
|
|
“私人的 无效handleNewTransaction (最后 交易T ) {
|
/ /同行线程运行,切换到Swing前添加和更新UI线程。
|
SwingUtilities类。的invokeLater (新 的Runnable () {
|
公共 无效的run () {
|
txListModel, 。monitorTx ( T );
|
}
|
});
|
}
|
|
私人 无效triggerNetworkStatsUpdate的() {
|
SwingUtilities类。的invokeLater (新 的Runnable () {
|
公共 无效的run () {
|
INT numPeers 等组。numConnectedPeers ();
|
StoredBlock chainHead = 链。getChainHead ();
|
字符串日期= chainHead 。getHeader ()。getTime ()。的toString ();
|
字符串复数= numPeers > 1 ? “同行” : “同行” ;
|
字符串状态= 字符串格式,
|
numPeers ,复数,chainHead getHeight (),日期等);
|
networkStats 。的setText (状态);
|
}
|
});
|
}
|
|
私人的 无效setupWindow (JFrame的窗口) {
|
JLabel的指示 新 JLabel的(
|
“<HTML>广播事务出现在下面。观看他们获得信心。参考” +
|
“寄硬币:<B>” + 钱包。钥匙扣。(0 )。toAddress (的params ) + “</ B>” );
|
窗口的getContentPane 。() (指令, BorderLayout的。华北);
|
|
/ /交易清单。
|
txList = 新 JList的(txListModel );
|
txList 。setCellRenderer (新 TxListLabel ());
|
txList, 。setSelectionMode (ListSelectionModel 。SINGLE_INTERVAL_SELECTION );
|
txList 。setLayoutOrientation (JList的垂直);
|
txScrollPane = 新 的JScrollPane (txList );
|
窗口的getContentPane 。() (txScrollPane , BorderLayout的中心);
|
|
networkStats = 新 的JLabel (“连接到Bitcoin网络...” );
|
窗口的getContentPane 。() (networkStats , BorderLayout的。华南);
|
}
|
|
/ /对象管理列表视图中的内容。
|
私有 类 TxListModel 延伸 AbstractListModel {
|
私人 名单< 交易> 交易= 新的ArrayList < 交易>();
|
|
公共的 无效monitorTx (交易TX ) {
|
断言SwingUtilities类。isEventDispatchThread ();
|
交易。(TX );
|
/ /设置了TX信心,改变事件监听器,所以我们知道什么时候才能更新列表。
|
TX 。getConfidence ()。的addEventListener (新 TransactionConfidence 。监听器() {
|
公共 无效onConfidenceChanged (交易TX ) {
|
/ /注意,这不收到的每块调用,只是当我们过渡
|
/ /之间的信任状态。
|
txIndex = 交易。的indexOf (TX );
|
fireContentsChanged (txIndex ,txIndex );
|
}
|
});
|
fireIntervalAdded (此,事务的大小() - 1 ,交易的大小() - 1 );
|
}
|
|
公众 诠释的getSize () {
|
回报的交易。大小();
|
}
|
|
公共 对象getElementAt (INT ) {
|
交易TX = 交易。(一 );
|
返回TX 。的toString () + “\ N” + TX的。getConfidence ()。的toString ();
|
}
|
|
“公共的 无效newBlock () {
|
fireContentsChanged ( 0 ,的getSize () - 1 );
|
}
|
}
|
|
私家 类 TxListLabel 扩展 JLabel的 实现 ListCellRenderer中 {
|
公共, 组件getListCellRendererComponent (JList的列表, 对象内容,
|
INT 指数, 布尔isSelected
|
布尔cellHasFocus ) {
|
字符串值= (字符串)内容;
|
最终 String 键= 钱包。钥匙扣。(0 )。toAddress (的params )。的toString ();
|
值= “<HTML>” + 价值。的replaceAll (“\ N” ,“参考” )。的replaceAll (“参考” , “参考” )
|
。的replaceAll (键 + 键+ “</ I>” );
|
的setText (值);
|
setOpaque (真);
|
setBackground (索引% 2 == 1 ? 新的Color (230 , 230 , 230 ) : 颜色白);
|
返回 本;
|
}
|
}
|
} |