ContractCallDialong:
+ enhanced with the option to see contract details: storage/code + refactored Block Chain into a WorldManager
This commit is contained in:
parent
1e6835f71d
commit
f3e57269bd
|
@ -48,7 +48,6 @@ public class Blockchain {
|
|||
public Blockchain(Wallet wallet) {
|
||||
this.db = WorldManager.instance.chainDB;
|
||||
this.wallet = wallet;
|
||||
this.loadChain();
|
||||
}
|
||||
|
||||
public Block getLastBlock() {
|
||||
|
@ -162,24 +161,31 @@ public class Blockchain {
|
|||
public void loadChain() {
|
||||
DBIterator iterator = db.iterator();
|
||||
try {
|
||||
if (!iterator.hasNext()) {
|
||||
if (index.size() == 0) {
|
||||
logger.info("DB is empty - adding Genesis");
|
||||
Block genesis = Genesis.getInstance();
|
||||
this.addBlock(genesis);
|
||||
logger.debug("Block: " + genesis.getNumber() + " ---> " + genesis.toFlatString());
|
||||
db.put(genesis.getParentHash(), genesis.getEncoded());
|
||||
} else {
|
||||
}
|
||||
|
||||
logger.debug("Displaying blocks stored in DB sorted on blocknumber");
|
||||
byte[] parentHash = Genesis.PARENT_HASH; // get Genesis block by parentHash
|
||||
for (iterator.seekToFirst(); iterator.hasNext(); iterator.next()) {
|
||||
|
||||
byte[] parentRLP = db.get(parentHash);
|
||||
if (parentRLP == null) return;
|
||||
|
||||
this.addBlock(new Block(parentRLP));
|
||||
Block block = new Block(parentRLP);
|
||||
this.addBlock(block);
|
||||
|
||||
// in case of cold load play the contracts
|
||||
WorldManager.instance.applyBlock(block);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Block: " + getLastBlock().getNumber() + " ---> " + getLastBlock().toFlatString());
|
||||
parentHash = getLastBlock().getHash();
|
||||
}
|
||||
|
||||
}
|
||||
} finally {
|
||||
// Make sure you close the iterator to avoid resource leaks.
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.ethereum.gui;
|
|||
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.manager.MainData;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
@ -74,9 +75,9 @@ public class BlockChainTable extends JFrame {
|
|||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
if (MainData.instance.getBlockchain().getSize() - 1 < lastFindIndex) return;
|
||||
if (WorldManager.instance.getBlockChain().getSize() - 1 < lastFindIndex) return;
|
||||
|
||||
Block block = MainData.instance.getBlockchain().getByNumber(lastFindIndex);
|
||||
Block block = WorldManager.instance.getBlockChain().getByNumber(lastFindIndex);
|
||||
StringSelection stsel = new StringSelection(block.toString());
|
||||
Clipboard system = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
system.setContents(stsel,stsel);
|
||||
|
@ -96,10 +97,10 @@ public class BlockChainTable extends JFrame {
|
|||
return;
|
||||
}
|
||||
|
||||
for (int i = lastFindIndex + 1; i < MainData.instance.getBlockchain().getSize(); ++i) {
|
||||
for (int i = lastFindIndex + 1; i < WorldManager.instance.getBlockChain().getSize(); ++i) {
|
||||
|
||||
if (MainData.instance.getBlockchain().getSize() - 1 < i) return;
|
||||
Block block = MainData.instance.getBlockchain().getByNumber(i);
|
||||
if (WorldManager.instance.getBlockChain().getSize() - 1 < i) return;
|
||||
Block block = WorldManager.instance.getBlockChain().getByNumber(i);
|
||||
boolean found = block.toString().toLowerCase().contains(toFind.toLowerCase());
|
||||
if (found) {
|
||||
// todo: now we find the first occur
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.ethereum.gui;
|
|||
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.manager.MainData;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
|
@ -16,7 +17,7 @@ public class BlockTableModel extends AbstractTableModel {
|
|||
public int getRowCount() {
|
||||
|
||||
fireTableDataChanged();
|
||||
int rowCount = MainData.instance.getBlockchain().getSize();
|
||||
int rowCount = WorldManager.instance.getBlockChain().getSize();
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
@ -31,7 +32,7 @@ public class BlockTableModel extends AbstractTableModel {
|
|||
// byte[] hash = MainData.instance.getAllBlocks().get(rowIndex).getHash();
|
||||
// return Hex.toHexString(hash);
|
||||
|
||||
Block block = MainData.instance.getBlockchain().getByNumber(rowIndex);
|
||||
Block block = WorldManager.instance.getBlockChain().getByNumber(rowIndex);
|
||||
if (block == null) return "";
|
||||
|
||||
return block.toString();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.ethereum.gui;
|
||||
|
||||
import com.sun.javafx.binding.StringFormatter;
|
||||
import org.ethereum.core.Account;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.ContractDetails;
|
||||
|
@ -9,6 +10,7 @@ import org.ethereum.manager.WorldManager;
|
|||
import org.ethereum.net.client.ClientPeer;
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.ethereum.util.Utils;
|
||||
import org.ethereum.vm.DataWord;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.util.BigIntegers;
|
||||
|
@ -16,17 +18,22 @@ import org.spongycastle.util.encoders.Hex;
|
|||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EtchedBorder;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.plaf.ComboBoxUI;
|
||||
import javax.swing.plaf.basic.BasicComboBoxUI;
|
||||
import javax.swing.plaf.basic.BasicComboPopup;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.*;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
|
@ -42,8 +49,14 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
JComboBox<AccountWrapper> creatorAddressCombo;
|
||||
final JTextField gasInput;
|
||||
final JTextField contractAddrInput;
|
||||
|
||||
JScrollPane contractDataInput;
|
||||
JTextArea msgDataTA;
|
||||
|
||||
JLabel statusMsg = null;
|
||||
JLabel playLabel = null;
|
||||
JLabel rejectLabel = null;
|
||||
JLabel approveLabel = null;
|
||||
|
||||
public ContractCallDialog(Frame parent) {
|
||||
super(parent, "Call Contract: ", false);
|
||||
|
@ -51,6 +64,20 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
|
||||
contractAddrInput = new JTextField(5);
|
||||
GUIUtils.addStyle(contractAddrInput, "Contract Address: ");
|
||||
contractAddrInput.addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
populateContractDetails();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
contractAddrInput.setBounds(70, 30, 350, 45);
|
||||
this.getContentPane().add(contractAddrInput);
|
||||
|
@ -60,9 +87,9 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
|
||||
msgDataTA = new JTextArea();
|
||||
msgDataTA.setLineWrap(true);
|
||||
JScrollPane contractDataInput = new JScrollPane(msgDataTA);
|
||||
contractDataInput = new JScrollPane(msgDataTA);
|
||||
GUIUtils.addStyle(msgDataTA, null, false);
|
||||
GUIUtils.addStyle(contractDataInput, "Data:");
|
||||
GUIUtils.addStyle(contractDataInput, "Input:");
|
||||
|
||||
msgDataTA.setText("");
|
||||
msgDataTA.setCaretPosition(0);
|
||||
|
@ -78,20 +105,19 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
|
||||
URL rejectIconURL = ClassLoader.getSystemResource("buttons/reject.png");
|
||||
ImageIcon rejectIcon = new ImageIcon(rejectIconURL);
|
||||
JLabel rejectLabel = new JLabel(rejectIcon);
|
||||
rejectLabel = new JLabel(rejectIcon);
|
||||
rejectLabel.setToolTipText("Cancel");
|
||||
rejectLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
|
||||
|
||||
URL playIconURL = ClassLoader.getSystemResource("buttons/play.png");
|
||||
ImageIcon playIcon = new ImageIcon(playIconURL);
|
||||
JLabel playLabel = new JLabel(playIcon);
|
||||
playLabel = new JLabel(playIcon);
|
||||
playLabel.setToolTipText("Play Drafted");
|
||||
playLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
|
||||
playLabel.addMouseListener(
|
||||
new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
|
||||
ContractCallDialog.this.playContractCall();
|
||||
}}
|
||||
);
|
||||
|
@ -118,7 +144,7 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
|
||||
URL approveIconURL = ClassLoader.getSystemResource("buttons/approve.png");
|
||||
ImageIcon approveIcon = new ImageIcon(approveIconURL);
|
||||
JLabel approveLabel = new JLabel(approveIcon);
|
||||
approveLabel = new JLabel(approveIcon);
|
||||
approveLabel.setToolTipText("Submit the transaction");
|
||||
approveLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
|
||||
|
||||
|
@ -157,7 +183,7 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
editor.setForeground(Color.RED);
|
||||
|
||||
Collection<Account> accounts =
|
||||
MainData.instance.getWallet().getAccountCollection();
|
||||
WorldManager.instance.getWallet().getAccountCollection();
|
||||
|
||||
for (Account account : accounts){
|
||||
creatorAddressCombo.addItem(new AccountWrapper(account));
|
||||
|
@ -191,7 +217,7 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
((AbstractButton) creatorAddressCombo.getComponent(i)).setBorder(line);
|
||||
}
|
||||
}
|
||||
creatorAddressCombo.setBounds(73, 267, 230, 36);
|
||||
creatorAddressCombo.setBounds(70, 267, 230, 36);
|
||||
this.getContentPane().add(creatorAddressCombo);
|
||||
|
||||
this.getContentPane().revalidate();
|
||||
|
@ -199,6 +225,117 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
this.setResizable(false);
|
||||
}
|
||||
|
||||
private void populateContractDetails() {
|
||||
|
||||
String contractAddr = contractAddrInput.getText();
|
||||
if (!Pattern.matches("[0-9a-fA-F]+", contractAddr) || (contractAddr.length() != 40)){
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] contractAddress = Hex.decode( contractAddr );
|
||||
byte[] contractStateB = WorldManager.instance.worldState.get(contractAddress);
|
||||
if (contractStateB == null || contractStateB.length == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
AccountState contractState = new AccountState(contractStateB);
|
||||
final byte[] programCode = WorldManager.instance.chainDB.get(contractState.getCodeHash());
|
||||
if (programCode == null || programCode.length == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] contractDetailsB =
|
||||
WorldManager.instance.detaildDB.get(contractAddress);
|
||||
|
||||
ContractDetails contractDetails = null;
|
||||
final Map storageMap = new HashMap();
|
||||
|
||||
if (contractDetailsB != null){
|
||||
|
||||
contractDetails = new ContractDetails(contractDetailsB);
|
||||
Map<DataWord, DataWord> tmpStorage = contractDetails.getStorage();
|
||||
if (tmpStorage != null){
|
||||
for (DataWord key : tmpStorage.keySet()){
|
||||
String keyToSave = Hex.toHexString (key.getNoLeadZeroesData());
|
||||
String valueToSave = Hex.toHexString (tmpStorage.get(key).getNoLeadZeroesData());
|
||||
storageMap.put(keyToSave, valueToSave);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contractDataInput.setBounds(70, 80, 350, 145);
|
||||
contractDataInput.setViewportView(msgDataTA);
|
||||
|
||||
URL expandIconURL = ClassLoader.getSystemResource("buttons/add-23x23.png");
|
||||
ImageIcon expandIcon = new ImageIcon(expandIconURL);
|
||||
final JLabel expandLabel = new JLabel(expandIcon);
|
||||
expandLabel.setToolTipText("Cancel");
|
||||
expandLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
|
||||
expandLabel.setBounds(235, 232, 23, 23);
|
||||
this.getContentPane().add(expandLabel);
|
||||
expandLabel.setVisible(true);
|
||||
|
||||
final Border border = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
|
||||
final JPanel detailPanel = new JPanel();
|
||||
detailPanel.setBorder(border);
|
||||
detailPanel.setBounds(135, 242, 230, 2);
|
||||
|
||||
final JPanel spacer = new JPanel();
|
||||
spacer.setForeground(Color.white);
|
||||
spacer.setBackground(Color.white);
|
||||
spacer.setBorder(null);
|
||||
spacer.setBounds(225, 232, 40, 20);
|
||||
|
||||
this.getContentPane().add(spacer);
|
||||
this.getContentPane().add(detailPanel);
|
||||
|
||||
|
||||
expandLabel.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
ContractCallDialog.this.setSize(500, 530);
|
||||
|
||||
ContractCallDialog.this.creatorAddressCombo.setBounds(70, 367, 230, 36);
|
||||
ContractCallDialog.this.gasInput.setBounds(330, 360, 90, 45);
|
||||
ContractCallDialog.this.rejectLabel.setBounds(260, 425, 45, 45);
|
||||
ContractCallDialog.this.approveLabel.setBounds(200, 425, 45, 45);
|
||||
ContractCallDialog.this.statusMsg.setBounds(50, 460, 400, 50);
|
||||
|
||||
spacer.setVisible(false);
|
||||
expandLabel.setVisible(false);
|
||||
detailPanel.setVisible(false);
|
||||
|
||||
|
||||
JTextField contractCode = new JTextField(15);
|
||||
contractCode.setText(Hex.toHexString( programCode ));
|
||||
GUIUtils.addStyle(contractCode, "Code: ");
|
||||
contractCode.setBounds(70, 230, 350, 45);
|
||||
|
||||
JTable storage = new JTable(2, 2);
|
||||
storage.setTableHeader(null);
|
||||
storage.setShowGrid(false);
|
||||
storage.setIntercellSpacing(new Dimension(15, 0));
|
||||
storage.setCellSelectionEnabled(false);
|
||||
GUIUtils.addStyle(storage);
|
||||
|
||||
JTableStorageModel tableModel = new JTableStorageModel(storageMap);
|
||||
storage.setModel(tableModel);
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane(storage);
|
||||
scrollPane.setBorder(null);
|
||||
scrollPane.getViewport().setBackground(Color.WHITE);
|
||||
scrollPane.setBounds(70, 290, 350, 50);
|
||||
|
||||
|
||||
ContractCallDialog.this.getContentPane().add(contractCode);
|
||||
ContractCallDialog.this.getContentPane().add(scrollPane);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
|
||||
private void playContractCall() {
|
||||
|
||||
|
@ -226,7 +363,7 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
Transaction tx = createTransaction();
|
||||
if (tx == null) return;
|
||||
|
||||
ProgramPlayDialog.createAndShowGUI(programCode, tx, MainData.instance.getBlockchain().getLastBlock(), contractDetails);
|
||||
ProgramPlayDialog.createAndShowGUI(programCode, tx, WorldManager.instance.getBlockChain().getLastBlock(), contractDetails);
|
||||
}
|
||||
|
||||
protected JRootPane createRootPane() {
|
||||
|
@ -355,5 +492,38 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private class JTableStorageModel extends DefaultTableModel {
|
||||
private JTableStorageModel(Map<String, String> data) {
|
||||
|
||||
if (data != null){
|
||||
|
||||
this.setColumnCount(2);
|
||||
this.setRowCount(data.size());
|
||||
|
||||
int i = 0;
|
||||
for (String key : data.keySet()){
|
||||
this.setValueAt(key, i, 0);
|
||||
this.setValueAt(data.get(key), i, 1);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String args[]){
|
||||
WorldManager.instance.getWallet();
|
||||
WorldManager.instance.loadChain();
|
||||
ContractCallDialog ccd = new ContractCallDialog(null);
|
||||
ccd.setVisible(true);
|
||||
ccd.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
ccd.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
WorldManager.instance.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
|
|||
contractAddrInput.setText(Hex.toHexString(tx.getContractAddress()));
|
||||
|
||||
ProgramPlayDialog.createAndShowGUI(tx.getData(), tx,
|
||||
MainData.instance.getBlockchain().getLastBlock(), null);
|
||||
WorldManager.instance.getBlockChain().getLastBlock(), null);
|
||||
}}
|
||||
);
|
||||
|
||||
|
@ -174,7 +174,7 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
|
|||
editor.setForeground(Color.RED);
|
||||
|
||||
Collection<Account> accounts =
|
||||
MainData.instance.getWallet().getAccountCollection();
|
||||
WorldManager.instance.getWallet().getAccountCollection();
|
||||
|
||||
for (Account account : accounts){
|
||||
creatorAddressCombo.addItem(new AccountWrapper(account));
|
||||
|
@ -314,7 +314,7 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
|
|||
|
||||
Account account = ((AccountWrapper)creatorAddressCombo.getSelectedItem()).getAccount();
|
||||
BigInteger currentBalance = account.getState().getBalance();
|
||||
BigInteger gasPrice = BigInteger.valueOf(MainData.instance.getBlockchain().getGasPrice());
|
||||
BigInteger gasPrice = BigInteger.valueOf(WorldManager.instance.getBlockChain().getGasPrice());
|
||||
BigInteger gasInput = new BigInteger( this.gasInput.getText());
|
||||
|
||||
boolean canAfford = currentBalance.compareTo(gasPrice.multiply(gasInput)) >= 0;
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.ethereum.gui;
|
|||
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.manager.MainData;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.net.submit.TransactionExecutor;
|
||||
import org.ethereum.net.submit.TransactionTask;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -58,7 +59,7 @@ public class DialogWorker extends SwingWorker {
|
|||
}
|
||||
|
||||
dialog.infoStatusMsg("Transaction got approved");
|
||||
MainData.instance.getWallet().applyTransaction(tx);
|
||||
WorldManager.instance.getWallet().applyTransaction(tx);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,11 @@ public class GUIUtils {
|
|||
jScrollPane.setHorizontalScrollBar(null);
|
||||
}
|
||||
|
||||
public static void addStyle(JTable jTable){
|
||||
jTable.setForeground(new Color(143, 170, 220));
|
||||
jTable.setBackground(Color.WHITE);
|
||||
jTable.setFont(new Font("Monospaced", 0, 13));
|
||||
}
|
||||
|
||||
public static String getHexStyledText(byte[] data){
|
||||
String[] dataHex = Hex.toHexString(data).split("(?<=\\G.{2})");
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.ethereum.core.Account;
|
|||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.manager.MainData;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.net.client.ClientPeer;
|
||||
import org.spongycastle.util.BigIntegers;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
@ -118,7 +119,7 @@ class PayOutDialog extends JDialog implements MessageAwareDialog {
|
|||
byte[] senderPrivKey = account.getEcKey().getPrivKeyBytes();
|
||||
byte[] nonce = addressState.getNonce() == BigInteger.ZERO ? null : addressState.getNonce().toByteArray();
|
||||
|
||||
byte[] gasPrice = BigInteger.valueOf( MainData.instance.getBlockchain().getGasPrice()).toByteArray();
|
||||
byte[] gasPrice = BigInteger.valueOf( WorldManager.instance.getBlockChain().getGasPrice()).toByteArray();
|
||||
|
||||
Transaction tx = new Transaction(nonce, gasPrice, BigIntegers
|
||||
.asUnsignedByteArray(fee), address, BigIntegers
|
||||
|
@ -193,7 +194,7 @@ class PayOutDialog extends JDialog implements MessageAwareDialog {
|
|||
// check if the tx is affordable
|
||||
BigInteger ammountValue = new BigInteger(amountText);
|
||||
BigInteger feeValue = new BigInteger(feeText);
|
||||
BigInteger gasPrice = BigInteger.valueOf(MainData.instance.getBlockchain().getGasPrice());
|
||||
BigInteger gasPrice = BigInteger.valueOf(WorldManager.instance.getBlockChain().getGasPrice());
|
||||
BigInteger currentBalance = addressState.getBalance();
|
||||
|
||||
boolean canAfford = gasPrice.multiply(feeValue).add(ammountValue).compareTo(currentBalance) != 1;
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.ethereum.gui;
|
|||
import org.ethereum.core.Account;
|
||||
import org.ethereum.core.Wallet;
|
||||
import org.ethereum.manager.MainData;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
@ -41,7 +42,7 @@ public class WalletWindow extends JFrame implements Wallet.WalletListener{
|
|||
Container contentPane = this.getContentPane();
|
||||
contentPane.setBackground(new Color(255, 255, 255));
|
||||
|
||||
Wallet wallet = MainData.instance.getWallet();
|
||||
Wallet wallet = WorldManager.instance.getWallet();
|
||||
wallet.addListener(this);
|
||||
loadWallet();
|
||||
|
||||
|
@ -54,7 +55,7 @@ public class WalletWindow extends JFrame implements Wallet.WalletListener{
|
|||
contentPane.removeAll();
|
||||
contentPane.setLayout(new FlowLayout());
|
||||
|
||||
Wallet wallet = MainData.instance.getWallet();
|
||||
Wallet wallet = WorldManager.instance.getWallet();
|
||||
|
||||
for (Account account : wallet.getAccountCollection()){
|
||||
|
||||
|
@ -76,7 +77,7 @@ public class WalletWindow extends JFrame implements Wallet.WalletListener{
|
|||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
|
||||
Wallet wallet = MainData.instance.getWallet();
|
||||
Wallet wallet = WorldManager.instance.getWallet();
|
||||
if (wallet.getAccountCollection().size() >=5){
|
||||
JOptionPane.showMessageDialog(walletWindow,
|
||||
"Hey do you really need more than 5 address for a demo wallet");
|
||||
|
|
|
@ -33,8 +33,6 @@ public class MainData {
|
|||
Logger logger = LoggerFactory.getLogger(getClass().getName());
|
||||
|
||||
private List<PeerData> peers = Collections.synchronizedList(new ArrayList<PeerData>());
|
||||
private Blockchain blockChain;
|
||||
private Wallet wallet = new Wallet();
|
||||
private ClientPeer activePeer;
|
||||
|
||||
PeerDiscovery peerDiscovery;
|
||||
|
@ -42,23 +40,6 @@ public class MainData {
|
|||
public static MainData instance = new MainData();
|
||||
|
||||
public MainData() {
|
||||
// Initialize Wallet
|
||||
byte[] cowAddr = HashUtil.sha3("cow".getBytes());
|
||||
ECKey key = ECKey.fromPrivate(cowAddr);
|
||||
wallet.importKey(cowAddr);
|
||||
|
||||
AccountState state = wallet.getAccountState(key.getAddress());
|
||||
state.addToBalance(BigInteger.valueOf(2).pow(200));
|
||||
|
||||
// wallet.importKey(HashUtil.sha3("cat".getBytes()));
|
||||
|
||||
String secret = CONFIG.coinbaseSecret();
|
||||
byte[] cbAddr = HashUtil.sha3(secret.getBytes());
|
||||
wallet.importKey(cbAddr);
|
||||
|
||||
|
||||
// Initialize Blockchain
|
||||
blockChain = new Blockchain(wallet);
|
||||
|
||||
// Initialize PeerData
|
||||
try {
|
||||
|
@ -73,13 +54,6 @@ public class MainData {
|
|||
}
|
||||
}
|
||||
|
||||
public Blockchain getBlockchain() {
|
||||
return blockChain;
|
||||
}
|
||||
|
||||
public Wallet getWallet() {
|
||||
return wallet;
|
||||
}
|
||||
|
||||
public void setActivePeer(ClientPeer peer){
|
||||
this.activePeer = peer;
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package org.ethereum.manager;
|
||||
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.ContractDetails;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.core.*;
|
||||
import org.ethereum.crypto.ECKey;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.DatabaseImpl;
|
||||
import org.ethereum.db.TrackDatabase;
|
||||
|
@ -20,6 +18,8 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.ethereum.config.SystemProperties.CONFIG;
|
||||
|
||||
/**
|
||||
*
|
||||
* WorldManager is the main class to handle the processing of transactions and managing the world state.
|
||||
|
@ -34,7 +34,10 @@ public class WorldManager {
|
|||
private Logger logger = LoggerFactory.getLogger("main");
|
||||
private Logger stateLogger = LoggerFactory.getLogger("state");
|
||||
|
||||
public static WorldManager instance = new WorldManager();
|
||||
|
||||
private Blockchain blockChain;
|
||||
private Wallet wallet = new Wallet();
|
||||
|
||||
|
||||
private Map<String, Transaction> pendingTransactions =
|
||||
Collections.synchronizedMap(new HashMap<String, Transaction>());
|
||||
|
@ -45,10 +48,37 @@ public class WorldManager {
|
|||
|
||||
public Trie worldState = new Trie(stateDB.getDb());
|
||||
|
||||
public static WorldManager instance = new WorldManager();
|
||||
public WorldManager() {
|
||||
}
|
||||
|
||||
public void loadChain(){
|
||||
|
||||
// Initialize Wallet
|
||||
byte[] cowAddr = HashUtil.sha3("cow".getBytes());
|
||||
ECKey key = ECKey.fromPrivate(cowAddr);
|
||||
wallet.importKey(cowAddr);
|
||||
|
||||
AccountState state = wallet.getAccountState(key.getAddress());
|
||||
state.addToBalance(BigInteger.valueOf(2).pow(200));
|
||||
|
||||
// wallet.importKey(HashUtil.sha3("cat".getBytes()));
|
||||
|
||||
String secret = CONFIG.coinbaseSecret();
|
||||
byte[] cbAddr = HashUtil.sha3(secret.getBytes());
|
||||
wallet.importKey(cbAddr);
|
||||
|
||||
|
||||
// Initialize Blockchain
|
||||
blockChain = new Blockchain(wallet);
|
||||
blockChain.loadChain();
|
||||
}
|
||||
|
||||
public void applyTransaction(Transaction tx) {
|
||||
|
||||
// TODO: refactor the wallet transactions to the world manager
|
||||
MainData.instance.getBlockchain().addWalletTransaction(tx);
|
||||
if (blockChain != null)
|
||||
blockChain.addWalletTransaction(tx);
|
||||
|
||||
// TODO: what is going on with simple wallet transfer
|
||||
|
||||
|
@ -167,7 +197,7 @@ public class WorldManager {
|
|||
byte[] initCode = tx.getData();
|
||||
|
||||
Block lastBlock =
|
||||
MainData.instance.getBlockchain().getLastBlock();
|
||||
blockChain.getLastBlock();
|
||||
|
||||
ProgramInvoke programInvoke =
|
||||
ProgramInvokeFactory.createProgramInvoke(tx, lastBlock, null, trackDetailDB, trackChainDb, trackStateDB);
|
||||
|
@ -191,7 +221,7 @@ public class WorldManager {
|
|||
if (programCode != null && programCode.length != 0){
|
||||
|
||||
Block lastBlock =
|
||||
MainData.instance.getBlockchain().getLastBlock();
|
||||
blockChain.getLastBlock();
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("calling for existing contract: addres={}" , Hex.toHexString(tx.getReceiveAddress()));
|
||||
|
@ -262,7 +292,7 @@ public class WorldManager {
|
|||
}
|
||||
|
||||
BigInteger gasPrice =
|
||||
BigInteger.valueOf( MainData.instance.getBlockchain().getGasPrice());
|
||||
BigInteger.valueOf( blockChain.getGasPrice());
|
||||
BigInteger refund =
|
||||
gasDebit.subtract(BigInteger.valueOf( result.getGasUsed()).multiply(gasPrice));
|
||||
|
||||
|
@ -306,6 +336,14 @@ public class WorldManager {
|
|||
}
|
||||
}
|
||||
|
||||
public Blockchain getBlockChain() {
|
||||
return blockChain;
|
||||
}
|
||||
|
||||
public Wallet getWallet() {
|
||||
return wallet;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
chainDB.close();
|
||||
stateDB.close();
|
||||
|
|
|
@ -254,7 +254,7 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
|||
}, 3000, secToAskForChain * 1000);
|
||||
}
|
||||
|
||||
MainData.instance.getBlockchain().addBlocks(blockList);
|
||||
WorldManager.instance.getBlockChain().addBlocks(blockList);
|
||||
WorldManager.instance.applyBlockList(blockList);
|
||||
if (peerListener != null) peerListener.console(blocksMessage.toString());
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
|||
|
||||
private void sendGetChain(ChannelHandlerContext ctx){
|
||||
|
||||
byte[] hash = MainData.instance.getBlockchain().getLatestBlockHash();
|
||||
byte[] hash = WorldManager.instance.getBlockChain().getLatestBlockHash();
|
||||
GetChainMessage chainMessage = new GetChainMessage((byte)100, hash);
|
||||
chainMessage.toString();
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.ethereum.net.submit;
|
|||
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.manager.MainData;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.net.client.ClientPeer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -34,8 +35,8 @@ public class TransactionTask implements Callable<Transaction> {
|
|||
|
||||
ClientPeer peer = MainData.instance.getActivePeer();
|
||||
|
||||
WalletTransaction walletTransaction = MainData.instance
|
||||
.getBlockchain().addWalletTransaction(tx);
|
||||
WalletTransaction walletTransaction = WorldManager.instance
|
||||
.getBlockChain().addWalletTransaction(tx);
|
||||
peer.sendTransaction(tx);
|
||||
|
||||
while(walletTransaction.getApproved() < 1 ){
|
||||
|
@ -45,7 +46,7 @@ public class TransactionTask implements Callable<Transaction> {
|
|||
logger.info("return approved: {}", walletTransaction.getApproved());
|
||||
} catch (Throwable th) {
|
||||
logger.info("exception caugh: {}", th.getCause());
|
||||
MainData.instance.getBlockchain().removeWalletTransaction(tx);
|
||||
WorldManager.instance.getBlockChain().removeWalletTransaction(tx);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
Loading…
Reference in New Issue