Contract Call Dialog:
+ Play button to call already saved contracts
This commit is contained in:
parent
a9b890a86d
commit
9ae78521a6
|
@ -1,8 +1,10 @@
|
|||
package org.ethereum.gui;
|
||||
|
||||
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.ethereum.util.ByteUtil;
|
||||
import org.ethereum.util.Utils;
|
||||
|
@ -32,7 +34,7 @@ import java.util.Collection;
|
|||
*/
|
||||
class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(getClass());
|
||||
Logger logger = LoggerFactory.getLogger("ui");
|
||||
|
||||
|
||||
ContractCallDialog dialog;
|
||||
|
@ -79,6 +81,24 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
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.setToolTipText("Play Drafted");
|
||||
playLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
|
||||
playLabel.addMouseListener(
|
||||
new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
|
||||
ContractCallDialog.this.playContractCall();
|
||||
}}
|
||||
);
|
||||
|
||||
playLabel.setBounds(438, 100, 42, 42);
|
||||
this.getContentPane().add(playLabel);
|
||||
|
||||
|
||||
JLabel statusMessage = new JLabel("");
|
||||
statusMessage.setBounds(50, 360, 400, 50);
|
||||
statusMessage.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
|
@ -178,6 +198,29 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
this.setResizable(false);
|
||||
}
|
||||
|
||||
|
||||
private void playContractCall() {
|
||||
|
||||
byte[] contractAddress = Hex.decode( contractAddrInput.getText());
|
||||
byte[] contractStateB = WorldManager.instance.worldState.get(contractAddress);
|
||||
if (contractStateB == null || contractStateB.length == 0){
|
||||
alertStatusMsg("No contract for that address");
|
||||
return;
|
||||
}
|
||||
|
||||
AccountState contractState = new AccountState(contractStateB);
|
||||
byte[] programCode = WorldManager.instance.chainDB.get(contractState.getCodeHash());
|
||||
if (programCode == null || programCode.length == 0){
|
||||
alertStatusMsg("Such account exist but no code in the db");
|
||||
return;
|
||||
}
|
||||
|
||||
Transaction tx = createTransaction();
|
||||
if (tx == null) return;
|
||||
|
||||
ProgramPlayDialog.createAndShowGUI(programCode, tx, MainData.instance.getBlockchain().getLastBlock());
|
||||
}
|
||||
|
||||
protected JRootPane createRootPane() {
|
||||
|
||||
Container parent = this.getParent();
|
||||
|
@ -223,9 +266,28 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
return;
|
||||
}
|
||||
|
||||
// todo: check up how the HEX value is encoded
|
||||
Transaction tx = createTransaction();
|
||||
if (tx == null) return;
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("tx.hash: {}", (new BigInteger(tx.getHash()).toString(16)));
|
||||
}
|
||||
|
||||
|
||||
// SwingWorker
|
||||
DialogWorker worker = new DialogWorker(tx, this);
|
||||
worker.execute();
|
||||
}
|
||||
|
||||
private Transaction createTransaction(){
|
||||
|
||||
byte[] data;
|
||||
if (!msgDataTA.getText().trim().equals("")){
|
||||
Object[] lexaList = msgDataTA.getText().split(",");
|
||||
byte[] data = ByteUtil.encodeDataList(lexaList);
|
||||
data = ByteUtil.encodeDataList(lexaList);
|
||||
} else {
|
||||
data = new byte[]{};
|
||||
}
|
||||
|
||||
byte[] contractAddress = Hex.decode( contractAddrInput.getText());
|
||||
|
||||
|
@ -252,23 +314,18 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{
|
|||
Transaction tx = new Transaction(nonce, gasPrice, gasValue,
|
||||
contractAddress, endowment, data);
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("tx.hash: {}", (new BigInteger(tx.getHash()).toString(16)));
|
||||
}
|
||||
|
||||
try {
|
||||
tx.sign(senderPrivKey);
|
||||
} catch (Exception e1) {
|
||||
|
||||
dialog.alertStatusMsg("Failed to sign the transaction");
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
// SwingWorker
|
||||
DialogWorker worker = new DialogWorker(tx, this);
|
||||
worker.execute();
|
||||
return tx;
|
||||
}
|
||||
|
||||
|
||||
public class AccountWrapper {
|
||||
|
||||
private Account account;
|
||||
|
|
|
@ -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.ethereum.util.Utils;
|
||||
import org.spongycastle.util.BigIntegers;
|
||||
|
@ -107,7 +108,7 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
|
|||
}
|
||||
contractAddrInput.setText(Hex.toHexString(tx.getContractAddress()));
|
||||
|
||||
ProgramPlayDialog.createAndShowGUI(tx);
|
||||
ProgramPlayDialog.createAndShowGUI(tx.getData(), tx, MainData.instance.getBlockchain().getLastBlock());
|
||||
}}
|
||||
);
|
||||
|
||||
|
@ -312,7 +313,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(MainData.instance.getBlockchain().getGasPrice());
|
||||
BigInteger gasInput = new BigInteger( this.gasInput.getText());
|
||||
|
||||
boolean canAfford = currentBalance.compareTo(gasPrice.multiply(gasInput)) >= 0;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.ethereum.gui;
|
||||
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.vm.Program;
|
||||
import org.ethereum.vm.ProgramInvokeFactory;
|
||||
|
@ -31,7 +32,7 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
|
|||
|
||||
private Transaction tx;
|
||||
|
||||
public ProgramPlayDialog(Transaction tx) {
|
||||
public ProgramPlayDialog(byte[] code, Transaction tx, Block lastBlock) {
|
||||
|
||||
this.tx = tx;
|
||||
|
||||
|
@ -46,8 +47,8 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
|
|||
// byte[] codeBytes =
|
||||
// Hex.decode(code);
|
||||
|
||||
Program program = new Program(tx.getData() ,
|
||||
ProgramInvokeFactory.createProgramInvoke(tx, null));
|
||||
Program program = new Program(code ,
|
||||
ProgramInvokeFactory.createProgramInvoke(tx, lastBlock));
|
||||
|
||||
program.addListener(this);
|
||||
program.fullTrace();
|
||||
|
@ -128,9 +129,9 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
|
|||
* this method should be invoked from the
|
||||
* event-dispatching thread.
|
||||
*/
|
||||
public static void createAndShowGUI(Transaction tx) {
|
||||
public static void createAndShowGUI(byte[] runCode, Transaction tx, Block lastBlock) {
|
||||
|
||||
ProgramPlayDialog ppd = new ProgramPlayDialog(tx);
|
||||
ProgramPlayDialog ppd = new ProgramPlayDialog(runCode, tx, lastBlock);
|
||||
|
||||
//Create and set up the window.
|
||||
JFrame frame = new JFrame("Program Draft Play");
|
||||
|
|
|
@ -72,7 +72,11 @@ public class Program {
|
|||
|
||||
if (this.pc > ops.length) {
|
||||
stop();
|
||||
throw new RuntimeException("pc overflow pc: " + pc);
|
||||
throw new RuntimeException("pc overflow pc= " + pc);
|
||||
}
|
||||
|
||||
if (this.pc == ops.length) {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,8 +390,16 @@ public class Program {
|
|||
globalOutput.append("\n HReturn: ").append(Hex.toHexString(result.gethReturn().array()));
|
||||
}
|
||||
|
||||
// soffisticated assumption that msg.data != codedata
|
||||
// means we are calling the contract not creating it
|
||||
byte[] txData = invokeData.getDataCopy(DataWord.ZERO, getDataSize());
|
||||
if (!Arrays.equals(txData, ops)){
|
||||
globalOutput.append("\n msg.data: ").append(Hex.toHexString( txData ));
|
||||
}
|
||||
|
||||
globalOutput.append("\n\n Spent Gas: ").append(result.getGasUsed());
|
||||
|
||||
|
||||
if (listener != null){
|
||||
listener.output(globalOutput.toString());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue