diff --git a/ethereumj-core/pom.xml b/ethereumj-core/pom.xml
index 0a052b9b..82b7acf4 100644
--- a/ethereumj-core/pom.xml
+++ b/ethereumj-core/pom.xml
@@ -7,6 +7,12 @@
0.1-SNAPSHOT
EthereumJ
http://www.ethereumj.org
+
+
+
UTF-8
@@ -114,6 +120,20 @@
1.7
+
+
+ maven-assembly-plugin
+
+
+
+ org.ethereum.gui.ToolBar
+
+
+
+ jar-with-dependencies
+
+
+
\ No newline at end of file
diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Address.java b/ethereumj-core/src/main/java/org/ethereum/core/Address.java
index 727261af..fc4c9df7 100644
--- a/ethereumj-core/src/main/java/org/ethereum/core/Address.java
+++ b/ethereumj-core/src/main/java/org/ethereum/core/Address.java
@@ -1,7 +1,6 @@
package org.ethereum.core;
import org.ethereum.crypto.ECKey;
-import org.ethereum.crypto.HashUtil;
import org.ethereum.util.Utils;
import org.spongycastle.util.encoders.Hex;
@@ -16,34 +15,34 @@ import java.util.Arrays;
public class Address {
byte[] privKey;
- byte[] pubKey;
+ byte[] address;
public Address(){
privKey = new BigInteger(130, Utils.getRandom()).toString(32).getBytes();
- this.pubKey = ECKey.fromPrivate(privKey).getAddress();
+ this.address = ECKey.fromPrivate(privKey).getAddress();
}
public Address(byte[] privKey) {
this.privKey = privKey;
- this.pubKey = ECKey.fromPrivate(privKey).getAddress();
+ this.address = ECKey.fromPrivate(privKey).getAddress();
}
- public Address(byte[] privKey, byte[] pubKey) {
+ public Address(byte[] privKey, byte[] address) {
this.privKey = privKey;
- this.pubKey = pubKey;
+ this.address = address;
}
public byte[] getPrivKey() {
return privKey;
}
- public byte[] getPubKey() {
- return pubKey;
+ public byte[] getAddress() {
+ return address;
}
@Override
public String toString() {
- return Hex.toHexString(pubKey);
+ return Hex.toHexString(address);
}
@Override
@@ -53,13 +52,13 @@ public class Address {
Address address = (Address) o;
- if (!Arrays.equals(pubKey, address.pubKey)) return false;
+ if (!Arrays.equals(this.address, address.address)) return false;
return true;
}
@Override
public int hashCode() {
- return Arrays.hashCode(pubKey);
+ return Arrays.hashCode(address);
}
}
diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Transaction.java b/ethereumj-core/src/main/java/org/ethereum/core/Transaction.java
index 7da18715..9b4eb362 100644
--- a/ethereumj-core/src/main/java/org/ethereum/core/Transaction.java
+++ b/ethereumj-core/src/main/java/org/ethereum/core/Transaction.java
@@ -9,6 +9,7 @@ import org.ethereum.util.RLP;
import org.ethereum.util.RLPItem;
import org.ethereum.util.RLPList;
import org.ethereum.util.Utils;
+import org.spongycastle.util.BigIntegers;
import org.spongycastle.util.encoders.Hex;
import edu.emory.mathcs.backport.java.util.Arrays;
@@ -24,6 +25,8 @@ import edu.emory.mathcs.backport.java.util.Arrays;
public class Transaction {
private byte[] rlpEncoded;
+ private byte[] unsignedRLPEncoded;
+
private boolean parsed = false;
/* creation contract tx
@@ -129,8 +132,11 @@ public class Transaction {
}
public byte[] getHash() {
+
if (!parsed) rlpParse();
- return HashUtil.sha3(this.getEncoded(false));
+ byte[] plainMsg = this.getRlpUnsigned();
+
+ return HashUtil.sha3(plainMsg);
}
public byte[] getNonce() {
@@ -218,71 +224,77 @@ public class Transaction {
", signatureS=" + Utils.toHexString(signature.s.toByteArray()) +
']';
}
-
- public byte[] getEncoded(boolean signed) {
- if(rlpEncoded == null) {
- // TODO: Alternative clean way to encode, using RLP.encode() after it's optimized
- // return new Object[] { nonce, value, receiveAddress, gasPrice,
- // gasLimit, data, init, signature };
+ /**
+ * For signature games you have to keep also
+ * rlp of the transaction without any signature data
+ */
+ public byte[] getRlpUnsigned(){
- /* Temporary order for an RLP encoded transaction in cpp client */
- byte[] nonce = RLP.encodeElement(this.nonce);
- byte[] gasPrice = RLP.encodeElement(this.gasPrice);
- byte[] gasLimit = RLP.encodeElement(this.gasLimit);
- byte[] receiveAddress = RLP.encodeElement(this.receiveAddress);
- byte[] value = RLP.encodeElement(this.value);
- byte[] data = RLP.encodeElement(this.data);
+ if (unsignedRLPEncoded != null) return unsignedRLPEncoded;
- byte[] v = null;
- byte[] r = null;
- byte[] s = null;
+ byte[] nonce = RLP.encodeElement(this.nonce);
+ byte[] gasPrice = RLP.encodeElement(this.gasPrice);
+ byte[] gasLimit = RLP.encodeElement(this.gasLimit);
+ byte[] receiveAddress = RLP.encodeElement(this.receiveAddress);
+ byte[] value = RLP.encodeElement(this.value);
+ byte[] data = RLP.encodeElement(this.data);
- if(signed && signature != null) {
-// byte[] signature = RLP.encodeElement(this.signature);
+ if(Arrays.equals(this.receiveAddress, new byte[0])) {
+ byte[] init = RLP.encodeElement(this.init);
+ this.unsignedRLPEncoded = RLP.encodeList(nonce, gasPrice, gasLimit, value, receiveAddress,
+ data, init);
+ } else {
+ this.unsignedRLPEncoded = RLP.encodeList(nonce, gasPrice, gasLimit, value, receiveAddress,
+ data);
+ }
- v = RLP.encodeByte( signature.v );
- r = RLP.encodeElement(signature.r.toByteArray());
- s = RLP.encodeElement(signature.s.toByteArray());
+ return unsignedRLPEncoded;
+ }
- if(Arrays.equals(this.receiveAddress, new byte[0])) {
- byte[] init = RLP.encodeElement(this.init);
- this.rlpEncoded = RLP.encodeList(nonce, gasPrice, gasLimit, value, receiveAddress,
- data, init, v, r, s);
- } else {
- this.rlpEncoded = RLP.encodeList(nonce, gasPrice, gasLimit, value, receiveAddress,
- data, v, r, s);
- }
+ public byte[] getEncoded() {
- } else {
+ if(rlpEncoded != null) return rlpEncoded;
- byte[] result;
+ /* Temporary order for an RLP encoded transaction in cpp client */
+ byte[] nonce = RLP.encodeElement(this.nonce);
+ byte[] gasPrice = RLP.encodeElement(this.gasPrice);
+ byte[] gasLimit = RLP.encodeElement(this.gasLimit);
+ byte[] receiveAddress = RLP.encodeElement(this.receiveAddress);
+ byte[] value = RLP.encodeElement(this.value);
+ byte[] data = RLP.encodeElement(this.data);
- if(Arrays.equals(this.receiveAddress, new byte[0])) {
- byte[] init = RLP.encodeElement(this.init);
- result = RLP.encodeList(nonce, gasPrice, gasLimit, value, receiveAddress,
- data, init);
- } else {
- result = RLP.encodeList(nonce, gasPrice, gasLimit, value, receiveAddress,
- data);
- }
-
- return result;
- }
+ byte[] v = null;
+ byte[] r = null;
+ byte[] s = null;
- /* Order of the Yellow Paper / eth-go & pyethereum clients
- byte[] nonce = RLP.encodeElement(this.nonce);
- byte[] value = RLP.encodeElement(this.value);
- byte[] receiveAddress = RLP.encodeElement(this.receiveAddress);
- byte[] gasPrice = RLP.encodeElement(this.gasPrice);
- byte[] gasLimit = RLP.encodeElement(this.gasLimit);
- byte[] data = RLP.encodeElement(this.data);
- byte[] init = RLP.encodeElement(this.init);
- */
-
-
- }
- return rlpEncoded;
+ v = RLP.encodeByte( signature.v );
+ r = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.r));
+ s = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.s));
+
+ if(Arrays.equals(this.receiveAddress, new byte[0])) {
+ byte[] init = RLP.encodeElement(this.init);
+ this.rlpEncoded = RLP.encodeList(nonce, gasPrice, gasLimit, value, receiveAddress,
+ data, init, v, r, s);
+ } else {
+ this.rlpEncoded = RLP.encodeList(nonce, gasPrice, gasLimit, value, receiveAddress,
+ data, v, r, s);
+ }
+
+
+
+
+ /* Order of the Yellow Paper / eth-go & pyethereum clients
+ byte[] nonce = RLP.encodeElement(this.nonce);
+ byte[] value = RLP.encodeElement(this.value);
+ byte[] receiveAddress = RLP.encodeElement(this.receiveAddress);
+ byte[] gasPrice = RLP.encodeElement(this.gasPrice);
+ byte[] gasLimit = RLP.encodeElement(this.gasLimit);
+ byte[] data = RLP.encodeElement(this.data);
+ byte[] init = RLP.encodeElement(this.init);
+ */
+
+ return rlpEncoded;
}
}
diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java b/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java
index aea3d900..f07d09d3 100644
--- a/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java
+++ b/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java
@@ -8,7 +8,6 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
@@ -197,7 +196,7 @@ public class Wallet {
raw.setAttributeNode(id);
Element addressE = doc.createElement("address");
- addressE.setTextContent(Hex.toHexString(address.getPubKey()));
+ addressE.setTextContent(Hex.toHexString(address.getAddress()));
Attr nonce = doc.createAttribute("nonce");
nonce.setValue("0");
diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/ConnectionConsoleWindow.java b/ethereumj-core/src/main/java/org/ethereum/gui/ConnectionConsoleWindow.java
index a64c97af..46289d48 100644
--- a/ethereumj-core/src/main/java/org/ethereum/gui/ConnectionConsoleWindow.java
+++ b/ethereumj-core/src/main/java/org/ethereum/gui/ConnectionConsoleWindow.java
@@ -69,11 +69,11 @@ public class ConnectionConsoleWindow extends JFrame implements PeerListener{
Thread t = new Thread() {
public void run() {
-// new ClientPeer(thisConsole).connect("82.217.72.169", 30303);
-// new ClientPeer(thisConsole).connect("54.201.28.117", 30303);
+// new ClientPeer(thisConsole).connect("54.201.28.117", 30303); // peer discovery
// new ClientPeer(thisConsole).connect("82.217.72.169", 30303); // Nick
- new ClientPeer(thisConsole).connect("54.204.10.41", 30303);
+// new ClientPeer(thisConsole).connect("54.204.10.41", 30303);
+ new ClientPeer(thisConsole).connect("54.211.14.10", 30303);
// new ClientPeer(thisConsole).connect("192.168.1.102", 30303);
}
};
diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java b/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java
index d7a63ff9..e41e3931 100644
--- a/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java
+++ b/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java
@@ -5,18 +5,14 @@ import org.ethereum.core.Transaction;
import org.ethereum.crypto.HashUtil;
import org.ethereum.manager.MainData;
import org.ethereum.net.client.ClientPeer;
-import org.ethereum.net.message.TransactionsMessage;
import org.spongycastle.util.encoders.Hex;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
import java.math.BigInteger;
-import java.util.*;
import javax.swing.*;
-import javax.swing.text.DefaultEditorKit;
/**
* www.ethereumJ.com
@@ -75,7 +71,7 @@ class PayOutDialog extends JDialog {
byte[] gas = Hex.decode("4255");
Transaction tx = new Transaction(null, value.toByteArray(),
- receiveAddress.getPubKey(), gasPrice, gas, null);
+ receiveAddress.getAddress(), gasPrice, gas, null);
try {
tx.sign(senderPrivKey);
diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/WalletAddressPanel.java b/ethereumj-core/src/main/java/org/ethereum/gui/WalletAddressPanel.java
index 2f27fe9e..6c22f006 100644
--- a/ethereumj-core/src/main/java/org/ethereum/gui/WalletAddressPanel.java
+++ b/ethereumj-core/src/main/java/org/ethereum/gui/WalletAddressPanel.java
@@ -35,7 +35,7 @@ public class WalletAddressPanel extends JPanel{
addressField.setBorder(border);
addressField.setEnabled(true);
addressField.setEditable(false);
- addressField.setText(Hex.toHexString(address.getPubKey()).toUpperCase());
+ addressField.setText(Hex.toHexString(address.getAddress()).toUpperCase());
addressField.setForeground(new Color(143, 170, 220));
addressField.setFont(new Font("Monospaced", 0, 12));
addressField.setPreferredSize(new Dimension(300, 35));
diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java b/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java
index 0ec1b9ae..bcac38d4 100644
--- a/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java
+++ b/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java
@@ -57,8 +57,7 @@ public class MainData {
// if it is the first block to add
// check that the parent is the genesis
if (blockChainDB.isEmpty() &&
- !"69a7356a245f9dc5b865475ada5ee4e89b18f93c06503a9db3b3630e88e9fb4e".
- equals(Hex.toHexString(firstBlockToAdd.getParentHash()))){
+ !Arrays.equals(StaticMessages.GENESSIS_HASH, firstBlockToAdd.getParentHash())){
return;
}
diff --git a/ethereumj-core/src/main/java/org/ethereum/net/client/ClientPeer.java b/ethereumj-core/src/main/java/org/ethereum/net/client/ClientPeer.java
index 9d9cb1b5..1d6ade64 100644
--- a/ethereumj-core/src/main/java/org/ethereum/net/client/ClientPeer.java
+++ b/ethereumj-core/src/main/java/org/ethereum/net/client/ClientPeer.java
@@ -95,7 +95,7 @@ public class ClientPeer {
*/
public void sendTransaction(Transaction transaction){
- transaction.getEncoded(true);
+ transaction.getEncoded();
java.util.List txList = new ArrayList();
txList.add(transaction);
TransactionsMessage transactionsMessage = new TransactionsMessage(txList);
diff --git a/ethereumj-core/src/main/java/org/ethereum/net/message/StaticMessages.java b/ethereumj-core/src/main/java/org/ethereum/net/message/StaticMessages.java
index 9b9a261e..08631659 100644
--- a/ethereumj-core/src/main/java/org/ethereum/net/message/StaticMessages.java
+++ b/ethereumj-core/src/main/java/org/ethereum/net/message/StaticMessages.java
@@ -50,14 +50,14 @@ public class StaticMessages {
public static final byte[] GET_CHAIN = Hex.decode("2240089100000027F82514A069A7356A245F9DC5B865475ADA5EE4E89B18F93C06503A9DB3B3630E88E9FB4E820100");
- public static final byte[] GENESSIS_HASH = Hex.decode("69a7356a245f9dc5b865475ada5ee4e89b18f93c06503a9db3b3630e88e9fb4e");
+ public static final byte[] GENESSIS_HASH = Hex.decode("f5232afe32aba6b366f8aa86a6939437c5e13d1fd71a0f51e77735d3456eb1a6");
public static final byte[] MAGIC_PACKET = Hex.decode("22400891");
static {
byte[] peerIdBytes = HashUtil.randomPeerId();
- HELLO_MESSAGE = new HelloMessage((byte)0x0F, (byte)0x00, "EthereumJ [v0.0.1] pure java [by Roman Mandeleil]",
+ HELLO_MESSAGE = new HelloMessage((byte)0x10, (byte)0x00, "EthereumJ [v0.5.1] pure java by RomanJ",
(byte)0b00000111, (short)30303, peerIdBytes);
/*
diff --git a/ethereumj-core/src/main/java/org/ethereum/net/message/TransactionsMessage.java b/ethereumj-core/src/main/java/org/ethereum/net/message/TransactionsMessage.java
index 4b8dc829..b881b5c1 100644
--- a/ethereumj-core/src/main/java/org/ethereum/net/message/TransactionsMessage.java
+++ b/ethereumj-core/src/main/java/org/ethereum/net/message/TransactionsMessage.java
@@ -32,7 +32,7 @@ public class TransactionsMessage extends Message {
for (Transaction tx : transactionList){
- byte[] txPayload = tx.getEncoded(true);
+ byte[] txPayload = tx.getEncoded();
try {
baos.write(txPayload);
} catch (IOException e) {
@@ -43,7 +43,7 @@ public class TransactionsMessage extends Message {
byte[][] elements = new byte[transactionList.size() + 1][];
elements[0] = new byte[]{Command.TRANSACTIONS.asByte()};
for (int i = 0; i < transactionList.size(); ++i){
- elements[i + 1] = transactionList.get(i).getEncoded(true);
+ elements[i + 1] = transactionList.get(i).getEncoded();
}
payload = RLP.encodeList(elements);
diff --git a/ethereumj-core/src/main/java/org/ethereum/util/RLP.java b/ethereumj-core/src/main/java/org/ethereum/util/RLP.java
index 08a2566a..fe5569c5 100644
--- a/ethereumj-core/src/main/java/org/ethereum/util/RLP.java
+++ b/ethereumj-core/src/main/java/org/ethereum/util/RLP.java
@@ -98,7 +98,7 @@ public class RLP {
* followed by the concatenation of the RLP encodings of the items. The
* range of the first byte is thus [0xf8, 0xff].
*/
- private static int OFFSET_LONG_LIST = 0xf8;
+ private static int OFFSET_LONG_LIST = 0xf7;
/* ******************************************************
diff --git a/ethereumj-core/src/test/java/org/ethereum/core/TransactionTest.java b/ethereumj-core/src/test/java/org/ethereum/core/TransactionTest.java
index d7810b92..c79c1779 100644
--- a/ethereumj-core/src/test/java/org/ethereum/core/TransactionTest.java
+++ b/ethereumj-core/src/test/java/org/ethereum/core/TransactionTest.java
@@ -31,7 +31,7 @@ public class TransactionTest {
assertEquals("c2604bd6eeca76afce4e7775d87960e3d4ed3b69235a3f94d6f1497c9831b50c", tx.getSignature().r);
assertEquals("664124a6b323350dd57a650434dc6bf8ddf37cd1a2686fee377e512aa12f1214", tx.getSignature().s);
- assertEquals(RLP_ENCODED_TX2, Hex.toHexString(tx.getEncoded(false)));
+ assertEquals(RLP_ENCODED_TX2, Hex.toHexString(tx.getEncoded()));
}
@Test
@@ -55,7 +55,7 @@ public class TransactionTest {
byte[] data = Hex.decode("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
Transaction tx = new Transaction(nonce, value, recieveAddress, gasPrice, gas, data);
- byte[] encoded = tx.getEncoded(false);
+ byte[] encoded = tx.getEncoded();
String test = Hex.toHexString(encoded);
System.out.println(RLP_ENCODED_TX2);
diff --git a/ethereumj-core/src/test/java/org/ethereum/net/MessagesTest.java b/ethereumj-core/src/test/java/org/ethereum/net/MessagesTest.java
index d77ad737..86cec0ab 100644
--- a/ethereumj-core/src/test/java/org/ethereum/net/MessagesTest.java
+++ b/ethereumj-core/src/test/java/org/ethereum/net/MessagesTest.java
@@ -7,7 +7,6 @@ import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
-import junit.framework.Assert;
import org.ethereum.core.Address;
import org.ethereum.core.Block;
import org.ethereum.core.Transaction;
@@ -536,10 +535,10 @@ public class MessagesTest {
byte[] gas = Hex.decode("4255");
Transaction tx = new Transaction(null, value.toByteArray(),
- receiveAddress.getPubKey(), gasPrice, gas, null);
+ receiveAddress.getAddress(), gasPrice, gas, null);
tx.sign(privKey);
- tx.getEncoded(true);
+ tx.getEncoded();
List txList = new ArrayList();
txList.add(tx);
diff --git a/ethereumj-core/src/test/java/org/ethereum/transaction/TransactionTest.java b/ethereumj-core/src/test/java/org/ethereum/transaction/TransactionTest.java
index 88e0f1f8..3f9f28c7 100644
--- a/ethereumj-core/src/test/java/org/ethereum/transaction/TransactionTest.java
+++ b/ethereumj-core/src/test/java/org/ethereum/transaction/TransactionTest.java
@@ -5,13 +5,14 @@ import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
-import java.security.SignatureException;
import org.ethereum.core.Address;
import org.ethereum.core.Transaction;
import org.ethereum.crypto.ECKey;
import org.ethereum.crypto.HashUtil;
+import org.junit.Assert;
import org.junit.Test;
+import org.spongycastle.util.BigIntegers;
import org.spongycastle.util.encoders.Hex;
public class TransactionTest {
@@ -53,16 +54,28 @@ public class TransactionTest {
byte[] gas = Hex.decode("4255");
Transaction tx = new Transaction(null, value.toByteArray(),
- receiveAddress.getPubKey(), gasPrice, gas, null);
+ receiveAddress.getAddress(), gasPrice, gas, null);
tx.sign(senderPrivKey);
- System.out.println(tx.toString());
- ECKey key = ECKey.signatureToKey(HashUtil.sha3(tx.getEncoded(true)), tx.getSignature().toBase64());
+
+ System.out.println("r: " + Hex.toHexString(tx.getSignature().r.toByteArray()));
+ System.out.println("s: " + Hex.toHexString(tx.getSignature().s.toByteArray()));
+
+ System.out.println(Hex.toHexString( tx.getEncoded() ));
+
+ // retrieve the signer/sender of the transaction
+ ECKey key = ECKey.signatureToKey(tx.getHash(), tx.getSignature().toBase64());
+
+ System.out.println("Tx unsigned RLP: " + Hex.toHexString( tx.getRlpUnsigned() ));
+ System.out.println("Tx signed RLP: " + Hex.toHexString( tx.getEncoded() ));
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
+
+ Assert.assertEquals("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826",
+ Hex.toHexString(key.getAddress()).toUpperCase());
}
@@ -78,10 +91,10 @@ public class TransactionTest {
byte[] gas = Hex.decode("4255");
Transaction tx = new Transaction(null, value.toByteArray(),
- receiveAddress.getPubKey(), gasPrice, gas, null);
+ receiveAddress.getAddress(), gasPrice, gas, null);
tx.sign(privKey);
- byte[] payload = tx.getEncoded(true);
+ byte[] payload = tx.getEncoded();
System.out.println(Hex.toHexString( payload ));
}