Fix tx encoding without signature, Add txTests, Fix Message tests

This commit is contained in:
nicksavers 2014-05-24 19:36:50 +02:00
parent eba6a048b6
commit c61569bf69
10 changed files with 278 additions and 210 deletions

View File

@ -4,10 +4,14 @@ import java.math.BigInteger;
import org.ethereum.crypto.HashUtil;
import org.ethereum.util.RLP;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
public class Genesis extends Block {
Logger logger = LoggerFactory.getLogger(this.getClass());
private static byte[] zeroHash256 = new byte[32];
private static byte[] zeroHash160 = new byte[20];
private static byte[] sha3EmptyList = HashUtil.sha3(RLP.encodeList());
@ -31,5 +35,6 @@ public class Genesis extends Block {
super(parentHash, unclesHash, coinbase, stateRoot,
txTrieRoot, difficulty, number, minGasPrice, gasLimit, gasUsed,
timestamp, extraData, nonce, null, null);
logger.info("Genesis-hash: " + Hex.toHexString(this.getHash()));
}
}

View File

@ -2,6 +2,7 @@ package org.ethereum.core;
import org.ethereum.crypto.ECKey.ECDSASignature;
import org.ethereum.crypto.ECKey;
import org.ethereum.crypto.ECKey.MissingPrivateKeyException;
import org.ethereum.crypto.HashUtil;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.RLP;
@ -70,21 +71,21 @@ public class Transaction {
private ECDSASignature signature;
/* Tx in encoded form */
private byte[] rlpEncodedSigned;
private byte[] rlpEncoded;
private byte[] rlpRaw;
/* Indicates if this transaction has been parsed
* from the rlp-encoded data */
private boolean parsed = false;
public Transaction(byte[] rawData) {
this.rlpEncodedSigned = rawData;
this.rlpEncoded = rawData;
parsed = false;
}
public Transaction(byte[] nonce, byte[] gasPrice, byte[] gas, byte[] recieveAddress, byte[] value, byte[] data) {
public Transaction(byte[] nonce, byte[] gasPrice, byte[] gasLimit, byte[] recieveAddress, byte[] value, byte[] data) {
this.nonce = nonce;
this.gasPrice = gasPrice;
this.gasLimit = gas;
this.gasLimit = gasLimit;
this.receiveAddress = recieveAddress;
this.value = value;
if(recieveAddress == null || receiveAddress.length == 0) {
@ -97,7 +98,7 @@ public class Transaction {
public void rlpParse(){
RLPList decodedTxList = RLP.decode2(rlpEncodedSigned);
RLPList decodedTxList = RLP.decode2(rlpEncoded);
RLPList transaction = (RLPList) decodedTxList.get(0);
this.nonce = ((RLPItem) transaction.get(0)).getRLPData();
@ -108,16 +109,26 @@ public class Transaction {
this.data = ((RLPItem) transaction.get(5)).getRLPData();
if (transaction.size() == CALL_SIZE){ // Simple transaction
byte v = ((RLPItem) transaction.get(6)).getRLPData()[0];
byte[] r = ((RLPItem) transaction.get(7)).getRLPData();
byte[] s = ((RLPItem) transaction.get(8)).getRLPData();
this.signature = ECDSASignature.fromComponents(r, s, v);
// only parse signature in case tx is signed
if(((RLPItem) transaction.get(6)).getRLPData() != null) {
byte v = ((RLPItem) transaction.get(6)).getRLPData()[0];
byte[] r = ((RLPItem) transaction.get(7)).getRLPData();
byte[] s = ((RLPItem) transaction.get(8)).getRLPData();
this.signature = ECDSASignature.fromComponents(r, s, v);
} else {
logger.debug("RLP encoded tx is not signed!");
}
} else if (transaction.size() == CONTRACT_SIZE){ // Contract creation transaction
this.init = ((RLPItem) transaction.get(6)).getRLPData();
byte v = ((RLPItem) transaction.get(7)).getRLPData()[0];
byte[] r = ((RLPItem) transaction.get(8)).getRLPData();
byte[] s = ((RLPItem) transaction.get(9)).getRLPData();
this.signature = ECDSASignature.fromComponents(r, s, v);
// only parse signature in case tx is signed
if(((RLPItem) transaction.get(6)).getRLPData() != null) {
byte v = ((RLPItem) transaction.get(7)).getRLPData()[0];
byte[] r = ((RLPItem) transaction.get(8)).getRLPData();
byte[] s = ((RLPItem) transaction.get(9)).getRLPData();
this.signature = ECDSASignature.fromComponents(r, s, v);
} else {
logger.debug("RLP encoded tx is not signed!");
}
} else throw new RuntimeException("Wrong tx data element list size");
this.parsed = true;
this.hash = this.getHash();
@ -130,7 +141,7 @@ public class Transaction {
public byte[] getHash() {
if (!parsed) rlpParse();
byte[] plainMsg = this.getEncoded();
byte[] plainMsg = this.getEncodedRaw();
return HashUtil.sha3(plainMsg);
}
@ -197,10 +208,11 @@ public class Transaction {
return null;
}
public void sign(byte[] privKeyBytes) throws Exception {
public void sign(byte[] privKeyBytes) throws MissingPrivateKeyException {
byte[] hash = this.getHash();
ECKey key = ECKey.fromPrivate(privKeyBytes).decompress();
this.signature = key.sign(hash);
this.rlpEncoded = null;
}
@Override
@ -208,15 +220,15 @@ public class Transaction {
if (!parsed) rlpParse();
return "TransactionData [" + " hash=" + ByteUtil.toHexString(hash) +
" nonce=" + ByteUtil.toHexString(nonce) +
", value=" + ByteUtil.toHexString(value) +
", receiveAddress=" + ByteUtil.toHexString(receiveAddress) +
", gasPrice=" + ByteUtil.toHexString(gasPrice) +
", gas=" + ByteUtil.toHexString(gasLimit) +
", receiveAddress=" + ByteUtil.toHexString(receiveAddress) +
", value=" + ByteUtil.toHexString(value) +
", data=" + ByteUtil.toHexString(data) +
", init=" + ByteUtil.toHexString(init) +
", signatureV=" + signature.v +
", signatureR=" + ByteUtil.toHexString(signature.r.toByteArray()) +
", signatureS=" + ByteUtil.toHexString(signature.s.toByteArray()) +
", signatureR=" + ByteUtil.toHexString(BigIntegers.asUnsignedByteArray(signature.r)) +
", signatureS=" + ByteUtil.toHexString(BigIntegers.asUnsignedByteArray(signature.s)) +
']';
}
@ -224,9 +236,9 @@ public class Transaction {
* For signature games you have to keep also
* rlp of the transaction without any signature data
*/
public byte[] getEncoded(){
public byte[] getEncodedRaw(){
if (rlpEncoded != null) return rlpEncoded;
if (rlpRaw != null) return rlpRaw;
byte[] nonce = RLP.encodeElement(this.nonce);
byte[] gasPrice = RLP.encodeElement(this.gasPrice);
@ -237,38 +249,46 @@ public class Transaction {
if(Arrays.equals(this.receiveAddress, new byte[0])) {
byte[] init = RLP.encodeElement(this.init);
this.rlpEncoded = RLP.encodeList(nonce, gasPrice, gasLimit, receiveAddress, value,
this.rlpRaw = RLP.encodeList(nonce, gasPrice, gasLimit, receiveAddress, value,
data, init);
} else {
this.rlpEncoded = RLP.encodeList(nonce, gasPrice, gasLimit, receiveAddress, value,
this.rlpRaw = RLP.encodeList(nonce, gasPrice, gasLimit, receiveAddress, value,
data);
}
return rlpRaw;
}
public byte[] getEncoded() {
if(rlpEncoded != null) return rlpEncoded;
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);
byte[] v, r, s;
if(signature != null) {
v = RLP.encodeByte( signature.v );
r = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.r));
s = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.s));
} else {
v = RLP.encodeElement(new byte[0]);
r = RLP.encodeElement(new byte[0]);
s = RLP.encodeElement(new byte[0]);
}
if(Arrays.equals(this.receiveAddress, new byte[0])) {
byte[] init = RLP.encodeElement(this.init);
this.rlpEncoded = RLP.encodeList(nonce, gasPrice, gasLimit, receiveAddress, value,
data, init, v, r, s);
} else {
this.rlpEncoded = RLP.encodeList(nonce, gasPrice, gasLimit, receiveAddress, value,
data, v, r, s);
}
return rlpEncoded;
}
public byte[] getEncodedSigned() {
if(rlpEncodedSigned != null) return rlpEncodedSigned;
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);
byte[] v = RLP.encodeByte( signature.v );
byte[] r = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.r));
byte[] s = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.s));
if(Arrays.equals(this.receiveAddress, new byte[0])) {
byte[] init = RLP.encodeElement(this.init);
this.rlpEncodedSigned = RLP.encodeList(nonce, gasPrice, gasLimit, receiveAddress, value,
data, init, v, r, s);
} else {
this.rlpEncodedSigned = RLP.encodeList(nonce, gasPrice, gasLimit, receiveAddress, value,
data, v, r, s);
}
return rlpEncodedSigned;
}
}

View File

@ -69,13 +69,23 @@ public class ConnectionConsoleWindow extends JFrame implements PeerListener{
Thread t = new Thread() {
public void run() {
// new ClientPeer(thisConsole).connect("54.201.28.117", 30303); // peer discovery
// new ClientPeer(thisConsole).connect("54.204.10.41", 30303);
// new ClientPeer(thisConsole).connect("131.104.247.135", 30303); // Some dude in Canada
// new ClientPeer(thisConsole).connect("82.217.72.169", 30303); // Nick
// new ClientPeer(thisConsole).connect("54.204.10.41", 30303); // CPP: ZeroGox Poc5
new ClientPeer(thisConsole).connect("54.211.14.10", 40404); // RomanJ
// new ClientPeer(thisConsole).connect("192.168.1.102", 30303);
// Peer Server Zero: peer discovery
// new ClientPeer(thisConsole).connect("54.201.28.117", 30303);
// Peer Server One: peer discovery
new ClientPeer(thisConsole).connect("54.204.10.41", 30303);
// Some dude in Canada
// new ClientPeer(thisConsole).connect("131.104.247.135", 30303);
// Nick
// new ClientPeer(thisConsole).connect("82.217.72.169", 30303);
// c++: ZeroGox
// new ClientPeer(thisConsole).connect("54.204.10.41", 30303);
// RomanJ
// new ClientPeer(thisConsole).connect("54.211.14.10", 40404);
}
};
t.start();

View File

@ -91,7 +91,7 @@ public class MainData {
public byte[] getLatestBlockHash(){
if (blockChainDB.isEmpty())
return (new Genesis()).getHash();
return StaticMessages.GENESIS_HASH;
else
return blockChainDB.get(blockChainDB.size() - 1).getHash();
}

View File

@ -89,7 +89,7 @@ public class ClientPeer {
*/
public void sendTransaction(Transaction transaction){
transaction.getEncodedSigned();
transaction.getEncoded();
java.util.List<Transaction> txList = new ArrayList<Transaction>();
txList.add(transaction);
TransactionsMessage transactionsMessage = new TransactionsMessage(txList);

View File

@ -78,4 +78,4 @@ public class PeersMessage extends Message {
}
return "Peers Message [\n " + sb.toString() + "]";
}
}
}

View File

@ -1,5 +1,6 @@
package org.ethereum.net.message;
import org.ethereum.core.Genesis;
import org.ethereum.crypto.HashUtil;
import org.spongycastle.util.encoders.Hex;
@ -16,16 +17,15 @@ public class StaticMessages {
public static final byte[] GET_TRANSACTIONS = Hex.decode("2240089100000002C116");
public static final byte[] DISCONNECT_08 = Hex.decode("2240089100000003C20108");
public static final byte[] GENESIS_HASH = Hex.decode("c305511e7cb9b33767e50f5e94ecd7b1c51359a04f45183860ec6808d80b0d3f");
public static final byte[] GENESIS_HASH = (new Genesis()).getHash();
public static final byte[] MAGIC_PACKET = Hex.decode("22400891");
static {
byte[] peerIdBytes = HashUtil.randomPeerId();
HELLO_MESSAGE = new HelloMessage((byte)0x11, (byte)0x00, "EthereumJ [v0.5.1] by RomanJ",
(byte)0b00000111, (short)30303, peerIdBytes);
HELLO_MESSAGE = new HelloMessage((byte) 0x11, (byte) 0x00,
"EthereumJ [v0.5.1] by RomanJ", (byte) 0b00000111,
(short) 30303, peerIdBytes);
}
public static final HelloMessage HELLO_MESSAGE;
}

View File

@ -32,7 +32,7 @@ public class TransactionsMessage extends Message {
for (Transaction tx : transactionList){
byte[] txPayload = tx.getEncodedSigned();
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).getEncodedSigned();
elements[i + 1] = transactionList.get(i).getEncoded();
}
payload = RLP.encodeList(elements);
@ -84,8 +84,8 @@ public class TransactionsMessage extends Message {
public String toString() {
if(!parsed) parseRLP();
StringBuffer sb = new StringBuffer();
for (Transaction transactionData : transactions){
sb.append(" ").append(transactionData).append("\n");
for (Transaction transaction : transactions){
sb.append(" ").append(transaction).append("\n");
}
return "Transactions Message [\n" + sb.toString() + " ]";
}

View File

@ -9,8 +9,8 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import org.ethereum.crypto.ECKey;
import org.ethereum.crypto.ECKey.MissingPrivateKeyException;
import org.ethereum.crypto.HashUtil;
import org.ethereum.util.ByteUtil;
import org.junit.Assert;
import org.junit.Test;
import org.spongycastle.util.BigIntegers;
@ -18,10 +18,6 @@ import org.spongycastle.util.encoders.Hex;
public class TransactionTest {
private static String RLP_ENCODED_RAW_TX = "ed808b00d3c21bcecceda10000009479b08ad8787060333663d19704909ee7b1903e588609184e72a00082425580";
private static String HASH_RAW_TX = "c957fce141839221403b51d26a5de186db2dabe0de4ac48f3f6718bfeb7c5f47";
private static String RLP_ENCODED_SIGNED_TX = "f870808b00d3c21bcecceda10000009479b08ad8787060333663d19704909ee7b1903e588609184e72a000824255801ca08e7dfa371b0acde61f894f1969f1f17696b86492a8572c60154e85d7801a4a08a0229807de94c4cfa63d978ff22f764cd9e6abd1bae1bcdba4aa4ae299ad0a8a9f";
@Test /* sign transaction https://tools.ietf.org/html/rfc6979 */
public void test1() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, IOException {
@ -69,13 +65,13 @@ public class TransactionTest {
System.out.println("r\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().r)));
System.out.println("s\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().s)));
System.out.println("RLP encoded tx\t\t: " + Hex.toHexString( tx.getEncodedSigned() ));
System.out.println("RLP encoded tx\t\t: " + 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\t\t: " + Hex.toHexString( tx.getEncoded()));
System.out.println("Tx signed RLP\t\t: " + Hex.toHexString( tx.getEncodedSigned() ));
System.out.println("Tx unsigned RLP\t\t: " + Hex.toHexString( tx.getEncodedRaw()));
System.out.println("Tx signed RLP\t\t: " + 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()));
@ -93,20 +89,16 @@ public class TransactionTest {
// cat --> 79b08ad8787060333663d19704909ee7b1903e58
// cow --> cd2a3d9f938e13cd947ec05abc7fe734df8dd826
ECKey ecKey = ECKey.fromPrivate(HashUtil.sha3("cat".getBytes()));
byte[] senderPrivKey = HashUtil.sha3("cow".getBytes());
byte[] nonce = { 0x01 };
byte[] gasPrice = Hex.decode("09184e72a000");
byte[] gasLimit = Hex.decode("4255");
BigInteger value = new BigInteger("1000000000000000000000000");
byte[] nonce = {01};
byte[] privKey = HashUtil.sha3("cat".getBytes());
ECKey ecKey = ECKey.fromPrivate(privKey);
byte[] senderPrivKey = HashUtil.sha3("cow".getBytes());
byte[] gasPrice= Hex.decode("09184e72a000");
byte[] gas = Hex.decode("4255");
Transaction tx = new Transaction(null, gasPrice, gas,
ecKey.getAddress(), value.toByteArray(), null);
Transaction tx = new Transaction(nonce, gasPrice, gasLimit,
ecKey.getAddress(), value.toByteArray(), null);
tx.sign(senderPrivKey);
@ -114,13 +106,13 @@ public class TransactionTest {
System.out.println("r\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().r)));
System.out.println("s\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().s)));
System.out.println("RLP encoded tx\t\t: " + Hex.toHexString( tx.getEncodedSigned() ));
System.out.println("RLP encoded tx\t\t: " + 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\t\t: " + Hex.toHexString( tx.getEncoded()));
System.out.println("Tx signed RLP\t\t: " + Hex.toHexString( tx.getEncodedSigned() ));
System.out.println("Tx unsigned RLP\t\t: " + Hex.toHexString( tx.getEncodedRaw()));
System.out.println("Tx signed RLP\t\t: " + 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()));
@ -129,46 +121,89 @@ public class TransactionTest {
Hex.toHexString(key.getAddress()));
}
// Testdata from: https://github.com/ethereum/tests/blob/master/txtest.json
String RLP_ENCODED_RAW_TX = "e88085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc1000080";
String RLP_ENCODED_UNSIGNED_TX = "eb8085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc1000080808080";
String HASH_TX = "328ea6d24659dec48adea1aced9a136e5ebdf40258db30d1b1d97ed2b74be34e";
String RLP_ENCODED_SIGNED_TX = "f86b8085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc10000801ba0eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4a014a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1";
String KEY = "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4";
byte[] testNonce = Hex.decode("");
byte[] testGasPrice = BigIntegers.asUnsignedByteArray(BigInteger.valueOf(1000000000000L));;
byte[] testGasLimit = BigIntegers.asUnsignedByteArray(BigInteger.valueOf(10000));;
byte[] testReceiveAddress = Hex.decode("13978aee95f38490e9769c39b2773ed763d9cd5f");
byte[] testValue = BigIntegers.asUnsignedByteArray(BigInteger.valueOf(10000000000000000L));
byte[] testData = Hex.decode("");
byte[] testInit = Hex.decode("");
@Test
public void testTransactionFromRLP() {
// from RLP encoding
fail("Double check the expected values, they don't seem to be parsed in the right order.");
byte[] encodedTxBytes = Hex.decode(RLP_ENCODED_SIGNED_TX);
Transaction tx = new Transaction(encodedTxBytes);
assertNull(tx.getNonce());
assertEquals(BigInteger.valueOf(16981), new BigInteger(tx.getValue()));
assertEquals("09184e72a000", ByteUtil.toHexString(tx.getReceiveAddress()));
assertEquals("00d3c21bcecceda1000000", ByteUtil.toHexString(tx.getGasPrice()));
assertEquals("79b08ad8787060333663d19704909ee7b1903e58", ByteUtil.toHexString(tx.getGasLimit()));
assertNull(tx.getData());
assertNull(tx.getInit());
assertEquals(28, tx.getSignature().v);
assertEquals("8e7dfa371b0acde61f894f1969f1f17696b86492a8572c60154e85d7801a4a08", Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().r)));
assertEquals("229807de94c4cfa63d978ff22f764cd9e6abd1bae1bcdba4aa4ae299ad0a8a9f", Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().s)));
public void testTransactionFromSignedRLP() throws Exception {
Transaction txSigned = new Transaction(Hex.decode(RLP_ENCODED_SIGNED_TX));
assertEquals(HASH_RAW_TX, ByteUtil.toHexString(tx.getHash()));
assertEquals(RLP_ENCODED_RAW_TX, ByteUtil.toHexString(tx.getEncoded()));
assertEquals(RLP_ENCODED_SIGNED_TX, ByteUtil.toHexString(tx.getEncodedSigned()));
assertEquals(HASH_TX, Hex.toHexString(txSigned.getHash()));
assertEquals(RLP_ENCODED_SIGNED_TX, Hex.toHexString(txSigned.getEncoded()));
assertNull(txSigned.getNonce());
assertEquals(new BigInteger(1, testGasPrice), new BigInteger(1, txSigned.getGasPrice()));
assertEquals(new BigInteger(1, testGasLimit), new BigInteger(1, txSigned.getGasLimit()));
assertEquals(Hex.toHexString(testReceiveAddress), Hex.toHexString(txSigned.getReceiveAddress()));
assertEquals(new BigInteger(1, testValue), new BigInteger(1, txSigned.getValue()));
assertNull(txSigned.getData());
assertNull(txSigned.getInit());
assertEquals(27, txSigned.getSignature().v);
assertEquals("eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4", Hex.toHexString(BigIntegers.asUnsignedByteArray(txSigned.getSignature().r)));
assertEquals("14a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1", Hex.toHexString(BigIntegers.asUnsignedByteArray(txSigned.getSignature().s)));
}
@Test
public void testTransactionFromUnsignedRLP() throws Exception {
Transaction txUnsigned = new Transaction(Hex.decode(RLP_ENCODED_UNSIGNED_TX));
assertEquals(HASH_TX, Hex.toHexString(txUnsigned.getHash()));
assertEquals(RLP_ENCODED_UNSIGNED_TX, Hex.toHexString(txUnsigned.getEncoded()));
txUnsigned.sign(Hex.decode(KEY));
assertEquals(RLP_ENCODED_SIGNED_TX, Hex.toHexString(txUnsigned.getEncoded()));
assertNull(txUnsigned.getNonce());
assertEquals(new BigInteger(1, testGasPrice), new BigInteger(1, txUnsigned.getGasPrice()));
assertEquals(new BigInteger(1, testGasLimit), new BigInteger(1, txUnsigned.getGasLimit()));
assertEquals(Hex.toHexString(testReceiveAddress), Hex.toHexString(txUnsigned.getReceiveAddress()));
assertEquals(new BigInteger(1, testValue), new BigInteger(1, txUnsigned.getValue()));
assertNull(txUnsigned.getData());
assertNull(txUnsigned.getInit());
assertEquals(27, txUnsigned.getSignature().v);
assertEquals("eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4", Hex.toHexString(BigIntegers.asUnsignedByteArray(txUnsigned.getSignature().r)));
assertEquals("14a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1", Hex.toHexString(BigIntegers.asUnsignedByteArray(txUnsigned.getSignature().s)));
}
@Test
public void testTransactionFromNew1() throws MissingPrivateKeyException {
Transaction txNew = new Transaction(testNonce, testGasPrice, testGasLimit, testReceiveAddress, testValue, testData);
assertEquals("", Hex.toHexString(txNew.getNonce()));
assertEquals(new BigInteger(1, testGasPrice), new BigInteger(1, txNew.getGasPrice()));
assertEquals(new BigInteger(1, testGasLimit), new BigInteger(1, txNew.getGasLimit()));
assertEquals(Hex.toHexString(testReceiveAddress), Hex.toHexString(txNew.getReceiveAddress()));
assertEquals(new BigInteger(1, testValue), new BigInteger(1, txNew.getValue()));
assertEquals("", Hex.toHexString(txNew.getData()));
assertNull(txNew.getInit());
assertNull(txNew.getSignature());
assertEquals(RLP_ENCODED_RAW_TX, Hex.toHexString(txNew.getEncodedRaw()));
assertEquals(HASH_TX, Hex.toHexString(txNew.getHash()));
assertEquals(RLP_ENCODED_UNSIGNED_TX, Hex.toHexString(txNew.getEncoded()));
txNew.sign(Hex.decode(KEY));
assertEquals(RLP_ENCODED_SIGNED_TX, Hex.toHexString(txNew.getEncoded()));
assertEquals(27, txNew.getSignature().v);
assertEquals("eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4", Hex.toHexString(BigIntegers.asUnsignedByteArray(txNew.getSignature().r)));
assertEquals("14a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1", Hex.toHexString(BigIntegers.asUnsignedByteArray(txNew.getSignature().s)));
}
@Test
public void testTransactionFromRLP2() {
byte[] encodedTxBytes = Hex.decode("f86f81018609184e72a0008242559479b08ad8787060333663d19704909ee7b1903e58893635c9adc5dea00000801ba056f49cb76f7daadd0e7eb523a8c942a2b510f450185c93a3e2e51a749642f0efa03374f71fa8855212d8c369be6ced2801a8a7b6d7cea3a578623ad34feceef12f");
Transaction tx = new Transaction(encodedTxBytes);
System.out.println(Hex.toHexString( tx.getSender() ));
System.out.println(Hex.toHexString( tx.getHash() ));
System.out.println(Hex.toHexString( tx.getEncoded() ));
}
@Test
public void testTransactionFromNew() throws Exception {
public void testTransactionFromNew2() throws MissingPrivateKeyException {
byte[] privKeyBytes = Hex.decode("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4");
String RLP_TX_UNSIGNED = "e88085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc1000080";
String RLP_TX_UNSIGNED = "eb8085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc1000080808080";
String RLP_TX_SIGNED = "f86b8085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc10000801ba0eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4a014a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1";
String HASH_TX_UNSIGNED = "328ea6d24659dec48adea1aced9a136e5ebdf40258db30d1b1d97ed2b74be34e";
@ -188,7 +223,7 @@ public class TransactionTest {
// Testing signed
tx.sign(privKeyBytes);
String encodedSigned = Hex.toHexString(tx.getEncodedSigned());
String encodedSigned = Hex.toHexString(tx.getEncoded());
assertEquals(RLP_TX_SIGNED, encodedSigned);
assertEquals(HASH_TX_UNSIGNED, Hex.toHexString(tx.getHash()));
}

View File

@ -48,7 +48,6 @@ public class MessagesTest {
helloMessage.parseRLP();
System.out.println(helloMessage);
assertEquals(12, helloMessage.getProtocolVersion());
assertEquals(0, helloMessage.getNetworkId());
assertEquals("Ethereum(++)/ZeroGox/v0.5.1/ncurses/Linux/g++", helloMessage.getClientId());
@ -60,7 +59,7 @@ public class MessagesTest {
}
@Test /* HelloMessage 2 */
public void test_2(){
public void test_2() {
String helloMessageRaw = "F87F800B80B5457468657265756D282B2B292F76302E342E332F4554485F4255494C445F545950452F4554485F4255494C445F504C4154464F524D0782765FB840E02B18FBA6B887FB9258469C3AF8E445CC9AE2B5386CAC5F60C4170F822086224E3876555C745A7EC8AC181C7F9701776D94A779604EA12651DE5F4A748D29E1";
byte[] payload = Hex.decode(helloMessageRaw);
@ -179,11 +178,14 @@ public class MessagesTest {
/* TRANSACTIONS */
@Test /* Transactions message 1 */
public void test_8(){
public void test_8() {
String transactionsPacketRaw = "F86E12F86B04881BC16D674EC8000094CD2A3D9F938E13CD947EC05ABC7FE734DF8DD8268609184E72A00064801BA05E3868194605F1647593B842725818CCFA6A38651A728715133A8E97CDCFAC54A00FF91628D04B215EBCCFD5F4FC34CC1B45DF32F6B4609FBB0DE42E8522264467";
byte[] payload = Hex.decode(transactionsPacketRaw);
String txsPacketRaw = "f86e12f86b04648609184e72a00094cd2a3d9f938e13cd947ec05abc7fe734df8dd826"
+ "881bc16d674ec80000801ba05c89ebf2b77eeab88251e553f6f9d53badc1d800"
+ "bbac02d830801c2aa94a4c9fa00b7907532b1f29c79942b75fff98822293bf5f"
+ "daa3653a8d9f424c6a3265f06c";
byte[] payload = Hex.decode(txsPacketRaw);
RLPList rlpList = RLP.decode2(payload);
TransactionsMessage transactionsMessage = new TransactionsMessage(rlpList);
@ -191,49 +193,45 @@ public class MessagesTest {
assertEquals(1, transactionsMessage.getTransactions().size());
Transaction tx =
transactionsMessage.getTransactions().get(0);
Transaction tx = transactionsMessage.getTransactions().get(0);
assertEquals("558A3797E0DD3FBFAF761F1ADD6749C7D5DB313FDAC5CBA59F40E28AF7BBACD1",
Hex.toHexString( tx.getHash() ).toUpperCase());
assertEquals("04",
Hex.toHexString( tx.getNonce() ).toUpperCase());
assertEquals("1BC16D674EC80000",
Hex.toHexString( tx.getValue() ).toUpperCase());
assertEquals("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826",
Hex.toHexString( tx.getReceiveAddress() ).toUpperCase());
assertEquals("09184E72A000",
Hex.toHexString( tx.getGasPrice() ).toUpperCase());
assertEquals("64",
Hex.toHexString( tx.getGasLimit() ).toUpperCase());
assertEquals("NULL",
Hex.toHexString( tx.getData() ).toUpperCase());
assertEquals("NULL",
Hex.toHexString( tx.getInit() ).toUpperCase());
assertEquals("1B",
Hex.toHexString( new byte[] {tx.getSignature().v} ).toUpperCase());
assertEquals("5E3868194605F1647593B842725818CCFA6A38651A728715133A8E97CDCFAC54",
Hex.toHexString( tx.getSignature().r.toByteArray() ).toUpperCase());
assertEquals("0FF91628D04B215EBCCFD5F4FC34CC1B45DF32F6B4609FBB0DE42E8522264467",
Hex.toHexString( tx.getSignature().s.toByteArray() ).toUpperCase());
assertEquals("5d2aee0490a9228024158433d650335116b4af5a30b8abb10e9b7f9f7e090fd8", Hex.toHexString(tx.getHash()));
assertEquals("04", Hex.toHexString(tx.getNonce()));
assertEquals("1bc16d674ec80000", Hex.toHexString(tx.getValue()));
assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826", Hex.toHexString(tx.getReceiveAddress()));
assertEquals("64", Hex.toHexString(tx.getGasPrice()));
assertEquals("09184e72a000", Hex.toHexString(tx.getGasLimit()));
assertEquals("null", ByteUtil.toHexString(tx.getData()));
assertEquals("null", ByteUtil.toHexString(tx.getInit()));
assertEquals("1b", Hex.toHexString(new byte[] { tx.getSignature().v }));
assertEquals("5c89ebf2b77eeab88251e553f6f9d53badc1d800bbac02d830801c2aa94a4c9f", Hex.toHexString(tx.getSignature().r.toByteArray()));
assertEquals("0b7907532b1f29c79942b75fff98822293bf5fdaa3653a8d9f424c6a3265f06c", Hex.toHexString(tx.getSignature().s.toByteArray()));
}
@Test /* Transactions message 2 */
public void test_9(){
String transactionsPacketRaw = "F9025012F89D80809400000000000000000000000000000000000000008609184E72A000822710B3606956330C0D630000003359366000530A0D630000003359602060005301356000533557604060005301600054630000000C5884336069571CA07F6EB94576346488C6253197BDE6A7E59DDC36F2773672C849402AA9C402C3C4A06D254E662BF7450DD8D835160CBB053463FED0B53F2CDD7F3EA8731919C8E8CCF9010501809400000000000000000000000000000000000000008609184E72A000822710B85336630000002E59606956330C0D63000000155933FF33560D63000000275960003356576000335700630000005358600035560D630000003A590033560D63000000485960003356573360003557600035335700B84A7F4E616D65526567000000000000000000000000000000000000000000000000003057307F4E616D655265670000000000000000000000000000000000000000000000000057336069571BA04AF15A0EC494AEAC5B243C8A2690833FAA74C0F73DB1F439D521C49C381513E9A05802E64939BE5A1F9D4D614038FBD5479538C48795614EF9C551477ECBDB49D2F8A6028094CCDEAC59D35627B7DE09332E819D5159E7BB72508609184E72A000822710B84000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D0ACEEE7E5AB874E22CCF8D1A649F59106D74E81BA0D05887574456C6DE8F7A0D172342C2CBDD4CF7AFE15D9DBB8B75B748BA6791C9A01E87172A861F6C37B5A9E3A5D0D7393152A7FBE41530E5BB8AC8F35433E5931B";
String txsPacketRaw = "f9025012f89d8080940000000000000000000000000000000000000000860918"
+ "4e72a000822710b3606956330c0d630000003359366000530a0d630000003359"
+ "602060005301356000533557604060005301600054630000000c588433606957"
+ "1ca07f6eb94576346488c6253197bde6a7e59ddc36f2773672c849402aa9c402"
+ "c3c4a06d254e662bf7450dd8d835160cbb053463fed0b53f2cdd7f3ea8731919"
+ "c8e8ccf901050180940000000000000000000000000000000000000000860918"
+ "4e72a000822710b85336630000002e59606956330c0d63000000155933ff3356"
+ "0d63000000275960003356576000335700630000005358600035560d63000000"
+ "3a590033560d63000000485960003356573360003557600035335700b84a7f4e"
+ "616d655265670000000000000000000000000000000000000000000000000030"
+ "57307f4e616d6552656700000000000000000000000000000000000000000000"
+ "00000057336069571ba04af15a0ec494aeac5b243c8a2690833faa74c0f73db1"
+ "f439d521c49c381513e9a05802e64939be5a1f9d4d614038fbd5479538c48795"
+ "614ef9c551477ecbdb49d2f8a6028094ccdeac59d35627b7de09332e819d5159"
+ "e7bb72508609184e72a000822710b84000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000002d0aceee"
+ "7e5ab874e22ccf8d1a649f59106d74e81ba0d05887574456c6de8f7a0d172342"
+ "c2cbdd4cf7afe15d9dbb8b75b748ba6791c9a01e87172a861f6c37b5a9e3a5d0"
+ "d7393152a7fbe41530e5bb8ac8f35433e5931b";
byte[] payload = Hex.decode(transactionsPacketRaw);
byte[] payload = Hex.decode(txsPacketRaw);
RLPList rlpList = RLP.decode2(payload);
TransactionsMessage transactionsMessage = new TransactionsMessage(rlpList);
@ -244,73 +242,73 @@ public class MessagesTest {
Transaction tx =
transactionsMessage.getTransactions().get(0);
assertEquals("4B7D9670A92BF120D5B43400543B69304A14D767CF836A7F6ABFF4EDDE092895",
Hex.toHexString( tx.getHash() ).toUpperCase());
assertEquals("4b7d9670a92bf120d5b43400543b69304a14d767cf836a7f6abff4edde092895",
Hex.toHexString( tx.getHash() ));
assertEquals("null",
Hex.toHexString( tx.getNonce() ));
assertEquals("NULL",
Hex.toHexString( tx.getNonce() ).toUpperCase());
assertEquals("NULL",
Hex.toHexString( tx.getValue() ).toUpperCase());
Hex.toHexString( tx.getValue() ));
assertEquals("0000000000000000000000000000000000000000",
Hex.toHexString( tx.getReceiveAddress() ).toUpperCase());
Hex.toHexString( tx.getReceiveAddress() ));
assertEquals("09184E72A000",
Hex.toHexString( tx.getGasPrice() ).toUpperCase());
assertEquals("09184e72a000",
Hex.toHexString( tx.getGasPrice() ));
assertEquals("2710",
Hex.toHexString( tx.getGasLimit() ).toUpperCase());
Hex.toHexString( tx.getGasLimit() ));
assertEquals("606956330C0D630000003359366000530A0D630000003359602060005301356000533557604060005301600054630000000C58",
Hex.toHexString( tx.getData() ).toUpperCase());
assertEquals("606956330c0d630000003359366000530a0d630000003359602060005301356000533557604060005301600054630000000c58",
Hex.toHexString( tx.getData() ));
assertEquals("33606957",
Hex.toHexString( tx.getInit() ).toUpperCase());
Hex.toHexString( tx.getInit() ));
assertEquals("1C",
Hex.toHexString( new byte[] {tx.getSignature().v} ).toUpperCase());
assertEquals("1c",
Hex.toHexString( new byte[] {tx.getSignature().v} ));
assertEquals("7F6EB94576346488C6253197BDE6A7E59DDC36F2773672C849402AA9C402C3C4",
Hex.toHexString( tx.getSignature().r.toByteArray() ).toUpperCase());
assertEquals("7f6eb94576346488c6253197bde6a7e59ddc36f2773672c849402aa9c402c3c4",
Hex.toHexString( tx.getSignature().r.toByteArray() ));
assertEquals("6D254E662BF7450DD8D835160CBB053463FED0B53F2CDD7F3EA8731919C8E8CC",
Hex.toHexString( tx.getSignature().s.toByteArray() ).toUpperCase());
assertEquals("6d254e662bf7450dd8d835160cbb053463fed0b53f2cdd7f3ea8731919c8e8cc",
Hex.toHexString( tx.getSignature().s.toByteArray() ));
tx = transactionsMessage.getTransactions().get(2);
assertEquals("B0251A1BB20B44459DB5B5444AB53EDD9E12C46D0BA07FA401A797BEB967D53C",
Hex.toHexString( tx.getHash() ).toUpperCase());
assertEquals("b0251a1bb20b44459db5b5444ab53edd9e12c46d0ba07fa401a797beb967d53c",
Hex.toHexString( tx.getHash() ));
assertEquals("02",
Hex.toHexString( tx.getNonce() ).toUpperCase());
Hex.toHexString( tx.getNonce() ));
assertEquals("NULL",
Hex.toHexString( tx.getValue() ).toUpperCase());
assertEquals("null",
Hex.toHexString( tx.getValue() ));
assertEquals("CCDEAC59D35627B7DE09332E819D5159E7BB7250",
Hex.toHexString( tx.getReceiveAddress() ).toUpperCase());
assertEquals("ccdeac59d35627b7de09332e819d5159e7bb7250",
Hex.toHexString( tx.getReceiveAddress() ));
assertEquals("09184E72A000",
Hex.toHexString( tx.getGasPrice() ).toUpperCase());
assertEquals("09184e72a000",
Hex.toHexString( tx.getGasPrice() ));
assertEquals("2710",
Hex.toHexString( tx.getGasLimit() ).toUpperCase());
Hex.toHexString( tx.getGasLimit() ));
assertEquals("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D0ACEEE7E5AB874E22CCF8D1A649F59106D74E8",
Hex.toHexString( tx.getData() ).toUpperCase());
assertEquals("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d0aceee7e5ab874e22ccf8d1a649f59106d74e8",
Hex.toHexString( tx.getData() ));
assertEquals("NULL",
Hex.toHexString( tx.getInit() ).toUpperCase());
assertEquals("null",
Hex.toHexString( tx.getInit() ));
assertEquals("1B",
Hex.toHexString( new byte[] {tx.getSignature().v} ).toUpperCase());
assertEquals("1b",
Hex.toHexString( new byte[] {tx.getSignature().v} ));
assertEquals("D05887574456C6DE8F7A0D172342C2CBDD4CF7AFE15D9DBB8B75B748BA6791C9",
Hex.toHexString( tx.getSignature().r.toByteArray() ).toUpperCase());
assertEquals("d05887574456c6de8f7a0d172342c2cbdd4cf7afe15d9dbb8b75b748ba6791c9",
Hex.toHexString( tx.getSignature().r.toByteArray() ));
assertEquals("1E87172A861F6C37B5A9E3A5D0D7393152A7FBE41530E5BB8AC8F35433E5931B",
Hex.toHexString(tx.getSignature().s.toByteArray()).toUpperCase());
assertEquals("1e87172a861f6c37b5a9e3a5d0d7393152a7fbe41530e5bb8ac8f35433e5931b",
Hex.toHexString(tx.getSignature().s.toByteArray()));
}
/* BLOCKS */
@ -534,7 +532,7 @@ public class MessagesTest {
ecKey.getAddress(), gasPrice, gas, null);
tx.sign(privKey);
tx.getEncodedSigned();
tx.getEncoded();
List<Transaction> txList = new ArrayList<Transaction>();
txList.add(tx);