VM integration go on:
+ ProgramInvoke addapted to work with env vars (no Block data yet) + ProgramPlayDialog, can play real code generated from the editor + Successfully got the production chain even that CALL doesn't work yet.
This commit is contained in:
parent
c6dd4f31f9
commit
30459202c1
|
@ -97,7 +97,17 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
|
|||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
|
||||
ProgramPlayDialog.createAndShowGUI();
|
||||
Transaction tx = null;
|
||||
try {
|
||||
tx = createTransaction();
|
||||
} catch (Exception e1) {
|
||||
|
||||
dialog.alertStatusMsg("Failed to sign the transaction");
|
||||
return;
|
||||
}
|
||||
contractAddrInput.setText(Hex.toHexString(tx.getContractAddress()));
|
||||
|
||||
ProgramPlayDialog.createAndShowGUI(tx);
|
||||
}}
|
||||
);
|
||||
|
||||
|
@ -248,9 +258,32 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
|
|||
this.statusMsg.setText(text);
|
||||
}
|
||||
|
||||
|
||||
public void submitContract(){
|
||||
|
||||
Transaction tx = null;
|
||||
try {
|
||||
tx = createTransaction();
|
||||
} catch (Exception e1) {
|
||||
|
||||
dialog.alertStatusMsg("Failed to sign the transaction");
|
||||
return;
|
||||
}
|
||||
contractAddrInput.setText(Hex.toHexString(tx.getContractAddress()));
|
||||
|
||||
ClientPeer peer = MainData.instance.getActivePeer();
|
||||
if (peer == null) {
|
||||
dialog.alertStatusMsg("Not connected to any peer");
|
||||
return;
|
||||
}
|
||||
|
||||
// SwingWorker
|
||||
DialogWorker worker = new DialogWorker(tx, this);
|
||||
worker.execute();
|
||||
|
||||
}
|
||||
|
||||
private Transaction createTransaction(){
|
||||
|
||||
Account account = ((AccountWrapper)creatorAddressCombo.getSelectedItem()).getAccount();
|
||||
|
||||
byte[] senderPrivKey = account.getEcKey().getPrivKeyBytes();
|
||||
|
@ -266,27 +299,9 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
|
|||
Transaction tx = new Transaction(nonce, gasPrice, gasValue,
|
||||
zeroAddress, endowment, initByteCode);
|
||||
|
||||
try {
|
||||
tx.sign(senderPrivKey);
|
||||
} catch (Exception e1) {
|
||||
|
||||
dialog.alertStatusMsg("Failed to sign the transaction");
|
||||
return;
|
||||
}
|
||||
|
||||
contractAddrInput.setText(Hex.toHexString(tx.getContractAddress()));
|
||||
|
||||
|
||||
ClientPeer peer = MainData.instance.getActivePeer();
|
||||
if (peer == null) {
|
||||
dialog.alertStatusMsg("Not connected to any peer");
|
||||
return;
|
||||
}
|
||||
|
||||
// SwingWorker
|
||||
DialogWorker worker = new DialogWorker(tx, this);
|
||||
worker.execute();
|
||||
tx.sign(senderPrivKey);
|
||||
|
||||
return tx;
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package org.ethereum.gui;
|
||||
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.vm.Program;
|
||||
import org.ethereum.vm.ProgramInvokeFactory;
|
||||
import org.ethereum.vm.ProgramInvokeImpl;
|
||||
import org.ethereum.vm.VM;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
@ -27,20 +29,25 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
|
|||
public JTextArea console;
|
||||
public JSlider stepSlider;
|
||||
|
||||
public ProgramPlayDialog() {
|
||||
private Transaction tx;
|
||||
|
||||
public ProgramPlayDialog(Transaction tx) {
|
||||
|
||||
this.tx = tx;
|
||||
|
||||
outputList = new ArrayList<String>();
|
||||
VM vm = new VM();
|
||||
// Program program = new Program(Hex.decode("630000000060445960CC60DD611234600054615566602054630000000060445960CC60DD611234600054615566602054630000000060445960CC60DD611234600054615566602054"));
|
||||
// Program program = new Program(Hex.decode("60016023576000605f556014600054601e60205463abcddcba6040545b51602001600a5254516040016014525451606001601e5254516080016028525460a052546016604860003960166000f26000603f556103e75660005460005360200235602054"), null);
|
||||
|
||||
String code = "60016000546006601160003960066000f261778e600054";
|
||||
// String code = "60016000546006601160003960066000f261778e600054";
|
||||
// String code = "620f424073cd2a3d9f938e13cd947ec05abc7fe734df8dd826576086602660003960866000f26001602036040e0f630000002159600060200235600054600053565b525b54602052f263000000765833602054602053566040546000602002356060546001602002356080546080536040530a0f0f630000006c59608053604053036020535760805360605356016060535760015b525b54602052f263000000765860005b525b54602052f2";
|
||||
|
||||
byte[] codeBytes =
|
||||
Hex.decode(code);
|
||||
Program program = new Program(codeBytes ,
|
||||
new ProgramInvokeImpl(codeBytes));
|
||||
// byte[] codeBytes =
|
||||
// Hex.decode(code);
|
||||
|
||||
Program program = new Program(tx.getData() ,
|
||||
ProgramInvokeFactory.createProgramInvoke(tx));
|
||||
|
||||
program.addListener(this);
|
||||
program.fullTrace();
|
||||
|
@ -121,9 +128,9 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
|
|||
* this method should be invoked from the
|
||||
* event-dispatching thread.
|
||||
*/
|
||||
public static void createAndShowGUI() {
|
||||
public static void createAndShowGUI(Transaction tx) {
|
||||
|
||||
ProgramPlayDialog ppd = new ProgramPlayDialog();
|
||||
ProgramPlayDialog ppd = new ProgramPlayDialog(tx);
|
||||
|
||||
//Create and set up the window.
|
||||
JFrame frame = new JFrame("Program Draft Play");
|
||||
|
@ -159,11 +166,14 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
|
|||
|
||||
//Schedule a job for the event-dispatching thread:
|
||||
//creating and showing this application's GUI.
|
||||
|
||||
/* todo: make dummy tx for dialog single invokation
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
createAndShowGUI();
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,7 @@ import org.ethereum.core.Transaction;
|
|||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.Database;
|
||||
import org.ethereum.trie.Trie;
|
||||
import org.ethereum.vm.Program;
|
||||
import org.ethereum.vm.ProgramResult;
|
||||
import org.ethereum.vm.VM;
|
||||
import org.ethereum.vm.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
@ -107,23 +105,34 @@ public class WorldManager {
|
|||
|
||||
byte[] initCode = tx.getData();
|
||||
|
||||
ProgramInvoke programInvoke =
|
||||
ProgramInvokeFactory.createProgramInvoke(tx);
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(initCode, null);
|
||||
Program program = new Program(initCode, programInvoke);
|
||||
vm.play(program);
|
||||
|
||||
ProgramResult result = program.getResult();
|
||||
byte[] bodyCode = result.gethReturn().array();
|
||||
byte[] bodyCode = null;
|
||||
if (result.gethReturn() != null){
|
||||
|
||||
result.gethReturn().array();
|
||||
}
|
||||
// TODO: what if the body code is null , still submit ?
|
||||
|
||||
// TODO: (!!!!!) ALL THE CHECKS FOR THE PROGRAM RESULT
|
||||
|
||||
byte[] key = HashUtil.sha3(bodyCode);
|
||||
chainDB.put(key, bodyCode);
|
||||
if (bodyCode != null){
|
||||
|
||||
byte[] key = HashUtil.sha3(bodyCode);
|
||||
chainDB.put(key, bodyCode);
|
||||
|
||||
if (stateLogger.isInfoEnabled())
|
||||
stateLogger.info("saving code of the contract to the db: sha3(code)={} code={}",
|
||||
Hex.toHexString(key),
|
||||
Hex.toHexString(bodyCode));
|
||||
}
|
||||
|
||||
if (stateLogger.isInfoEnabled())
|
||||
stateLogger.info("saving code of the contract to the db: sha3(code)={} code={}",
|
||||
Hex.toHexString(key),
|
||||
Hex.toHexString(bodyCode));
|
||||
} else {
|
||||
// TODO: 2. check if the address is a contract, if it is perform contract call
|
||||
}
|
||||
|
|
|
@ -32,8 +32,14 @@ public class DataWord {
|
|||
}
|
||||
|
||||
public DataWord(byte[] data) {
|
||||
if (data == null || data.length > 32)
|
||||
throw new RuntimeException("bad push data: " + data);
|
||||
|
||||
if (data == null){
|
||||
this.data = new byte[]{};
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.length > 32)
|
||||
throw new RuntimeException("Data word can't exit 32 bytes: " + data);
|
||||
System.arraycopy(data, 0, this.data, 32 - data.length, data.length);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,14 @@ import org.spongycastle.util.encoders.Hex;
|
|||
|
||||
public class ProgramInvokeImpl implements ProgramInvoke {
|
||||
|
||||
DataWord address;
|
||||
DataWord origin;
|
||||
DataWord caller;
|
||||
DataWord balance;
|
||||
DataWord gas;
|
||||
DataWord gasPrice;
|
||||
DataWord callValue;
|
||||
|
||||
byte[] msgData;
|
||||
|
||||
|
||||
|
@ -19,56 +27,50 @@ public class ProgramInvokeImpl implements ProgramInvoke {
|
|||
this.msgData = msgDataRaw;
|
||||
}
|
||||
|
||||
public ProgramInvokeImpl() {
|
||||
public ProgramInvokeImpl(byte[] address, byte[] origin, byte[] caller, byte[] balance,
|
||||
byte[] gasPrice, byte[] gas, byte[] callValue, byte[] msgData) {
|
||||
|
||||
this.address = new DataWord(address);
|
||||
this.origin = new DataWord(origin);
|
||||
this.caller = new DataWord(caller);
|
||||
this.balance = new DataWord(balance);
|
||||
this.gasPrice = new DataWord(gasPrice);
|
||||
this.gas = new DataWord(gas);
|
||||
this.callValue = new DataWord(callValue);
|
||||
|
||||
this.msgData = msgData;
|
||||
}
|
||||
|
||||
/* ADDRESS op */
|
||||
public DataWord getOwnerAddress(){
|
||||
|
||||
byte[] cowPrivKey = HashUtil.sha3("cow".getBytes());
|
||||
byte[] addr = ECKey.fromPrivate(cowPrivKey).getAddress();
|
||||
|
||||
return new DataWord(addr);
|
||||
return address;
|
||||
}
|
||||
|
||||
/* BALANCE op */
|
||||
public DataWord getBalance(){
|
||||
byte[] balance = Hex.decode("0DE0B6B3A7640000");
|
||||
return new DataWord(balance);
|
||||
return balance;
|
||||
}
|
||||
|
||||
|
||||
/* ORIGIN op */
|
||||
public DataWord getOriginAddress(){
|
||||
|
||||
byte[] cowPrivKey = HashUtil.sha3("horse".getBytes());
|
||||
byte[] addr = ECKey.fromPrivate(cowPrivKey).getAddress();
|
||||
|
||||
return new DataWord(addr);
|
||||
return origin;
|
||||
}
|
||||
|
||||
/* CALLER op */
|
||||
public DataWord getCallerAddress(){
|
||||
|
||||
byte[] cowPrivKey = HashUtil.sha3("monkey".getBytes());
|
||||
byte[] addr = ECKey.fromPrivate(cowPrivKey).getAddress();
|
||||
|
||||
return new DataWord(addr);
|
||||
return caller;
|
||||
}
|
||||
|
||||
|
||||
/* GASPRICE op */
|
||||
public DataWord getMinGasPrice(){
|
||||
|
||||
byte[] minGasPrice = Hex.decode("09184e72a000");
|
||||
return new DataWord(minGasPrice);
|
||||
return gasPrice;
|
||||
}
|
||||
|
||||
|
||||
/* CALLVALUE op */
|
||||
public DataWord getCallValue(){
|
||||
byte[] balance = Hex.decode("0DE0B6B3A7640000");
|
||||
return new DataWord(balance);
|
||||
return callValue;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -371,6 +371,9 @@ public class VM {
|
|||
program.step();
|
||||
} break;
|
||||
case GASPRICE:
|
||||
|
||||
|
||||
program.step();
|
||||
break;
|
||||
|
||||
/**
|
||||
|
@ -378,16 +381,22 @@ public class VM {
|
|||
*/
|
||||
|
||||
case PREVHASH:
|
||||
program.step();
|
||||
break;
|
||||
case COINBASE:
|
||||
program.step();
|
||||
break;
|
||||
case TIMESTAMP:
|
||||
program.step();
|
||||
break;
|
||||
case NUMBER:
|
||||
program.step();
|
||||
break;
|
||||
case DIFFICULTY:
|
||||
program.step();
|
||||
break;
|
||||
case GASLIMIT:
|
||||
program.step();
|
||||
break;
|
||||
case POP:{
|
||||
program.stackPop();
|
||||
|
@ -477,6 +486,7 @@ public class VM {
|
|||
program.step();
|
||||
} break;
|
||||
case GAS:
|
||||
program.step();
|
||||
break;
|
||||
|
||||
case PUSH1: case PUSH2: case PUSH3: case PUSH4: case PUSH5: case PUSH6: case PUSH7: case PUSH8:
|
||||
|
|
|
@ -13,8 +13,8 @@ log4j.logger.org.ethereum.net.peerdiscovery = WARN
|
|||
log4j.logger.java.nio = WARN
|
||||
log4j.logger.io.netty = FATAL
|
||||
log4j.logger.org.ethereum.core = FATAL
|
||||
log4j.logger.wire = FATAL
|
||||
log4j.logger.wire = INFO
|
||||
log4j.logger.VM = DEBUG
|
||||
log4j.logger.main = FATAL
|
||||
log4j.logger.state = FATAL
|
||||
log4j.logger.blockchain = FATAL
|
||||
log4j.logger.main = DEBUG
|
||||
log4j.logger.state = DEBUG
|
||||
log4j.logger.blockchain = INFO
|
||||
|
|
|
@ -16,8 +16,8 @@ peer.discovery.port = 30303
|
|||
# that is the peer through
|
||||
# we get the chain: [54.201.28.117] port: [30303]
|
||||
# ZeroGox
|
||||
#peer.active.ip = 54.204.10.41
|
||||
#peer.active.port = 30303
|
||||
peer.active.ip = 54.204.10.41
|
||||
peer.active.port = 30303
|
||||
|
||||
# Some dude in Canada
|
||||
#peer.active.ip = 131.104.247.135
|
||||
|
@ -29,8 +29,8 @@ peer.discovery.port = 30303
|
|||
|
||||
|
||||
# RomanJ general
|
||||
peer.active.ip = 54.211.14.10
|
||||
peer.active.port = 50505
|
||||
#peer.active.ip = 54.211.14.10
|
||||
#peer.active.port = 50505
|
||||
|
||||
#peer.active.ip = 151.64.223.120
|
||||
#peer.active.port = 30304
|
||||
|
|
Loading…
Reference in New Issue