Transaction.sender() fix

This commit is contained in:
romanman 2014-05-21 18:14:29 +03:00
parent a16fa04e59
commit 0e239b58ef
4 changed files with 96 additions and 45 deletions

View File

@ -10,6 +10,7 @@ import org.ethereum.util.Utils;
import org.spongycastle.util.BigIntegers; import org.spongycastle.util.BigIntegers;
import org.spongycastle.util.encoders.Hex; import org.spongycastle.util.encoders.Hex;
import java.security.SignatureException;
import java.util.Arrays; import java.util.Arrays;
/** /**
@ -91,12 +92,14 @@ public class Transaction {
parsed = true; parsed = true;
} }
// YP {Tn (nonce); Tp(pgas); Tg(gaslimi); Tt(reciver); Tv(value); Ti(init); Tw; Tr; Ts}
public void rlpParse(){ public void rlpParse(){
RLPList decodedTxList = RLP.decode2(rlpEncodedSigned); RLPList decodedTxList = RLP.decode2(rlpEncodedSigned);
RLPList transaction = (RLPList) decodedTxList.get(0); RLPList transaction = (RLPList) decodedTxList.get(0);
this.hash = HashUtil.sha3(rlpEncodedSigned);
this.nonce = ((RLPItem) transaction.get(0)).getRLPData(); this.nonce = ((RLPItem) transaction.get(0)).getRLPData();
this.gasPrice = ((RLPItem) transaction.get(1)).getRLPData(); this.gasPrice = ((RLPItem) transaction.get(1)).getRLPData();
@ -186,13 +189,15 @@ public class Transaction {
} }
public byte[] sender() { public byte[] sender() {
ECKey eckey = this.getKey();
// Validate the returned key. ECKey key = null;
// Return null if public key isn't in a correct format try {
if (!eckey.isPubKeyCanonical()) { key = ECKey.signatureToKey(getHash(), getSignature().toBase64());
return null; } catch (SignatureException e) {
e.printStackTrace();
} }
return eckey.getAddress();
return key.getAddress();
} }
public void sign(byte[] privKeyBytes) throws Exception { public void sign(byte[] privKeyBytes) throws Exception {
@ -206,15 +211,15 @@ public class Transaction {
if (!parsed) rlpParse(); if (!parsed) rlpParse();
return "TransactionData [" + " hash=" + Utils.toHexString(hash) + return "TransactionData [" + " hash=" + Utils.toHexString(hash) +
" nonce=" + Utils.toHexString(nonce) + " nonce=" + Utils.toHexString(nonce) +
", value=" + Utils.toHexString(value) +
", receiveAddress=" + Utils.toHexString(receiveAddress) +
", gasPrice=" + Utils.toHexString(gasPrice) + ", gasPrice=" + Utils.toHexString(gasPrice) +
", gas=" + Utils.toHexString(gasLimit) + ", gas=" + Utils.toHexString(gasLimit) +
", receiveAddress=" + Utils.toHexString(receiveAddress) +
", value=" + Utils.toHexString(value) +
", data=" + Utils.toHexString(data) + ", data=" + Utils.toHexString(data) +
", init=" + Utils.toHexString(init) + ", init=" + Utils.toHexString(init) +
", signatureV=" + signature.v + ", signatureV=" + signature.v +
", signatureR=" + Utils.toHexString(signature.r.toByteArray()) + ", signatureR=" + Utils.toHexString(BigIntegers.asUnsignedByteArray(signature.r)) +
", signatureS=" + Utils.toHexString(signature.s.toByteArray()) + ", signatureS=" + Utils.toHexString(BigIntegers.asUnsignedByteArray(signature.s)) +
']'; ']';
} }
@ -224,6 +229,8 @@ public class Transaction {
*/ */
public byte[] getEncoded(){ public byte[] getEncoded(){
// YP {Tn (nonce); Tp(pgas); Tg(gaslimi); Tt(reciver); Tv(value); Ti(init); Tw; Tr; Ts}
if (rlpEncoded != null) return rlpEncoded; if (rlpEncoded != null) return rlpEncoded;
byte[] nonce = RLP.encodeElement(this.nonce); byte[] nonce = RLP.encodeElement(this.nonce);
@ -256,7 +263,7 @@ public class Transaction {
byte[] value = RLP.encodeElement(this.value); byte[] value = RLP.encodeElement(this.value);
byte[] data = RLP.encodeElement(this.data); byte[] data = RLP.encodeElement(this.data);
byte[] v = RLP.encodeByte( signature.v ); byte[] v = RLP.encodeByte(signature.v);
byte[] rBytes = BigIntegers.asUnsignedByteArray(signature.r); byte[] rBytes = BigIntegers.asUnsignedByteArray(signature.r);
System.out.println(Hex.toHexString(rBytes)); System.out.println(Hex.toHexString(rBytes));
byte[] r = RLP.encodeElement(rBytes); byte[] r = RLP.encodeElement(rBytes);

View File

@ -97,13 +97,19 @@ public class Wallet {
for (Transaction tx : transactions){ for (Transaction tx : transactions){
// todo: validate the transaction and decrypt the sender // byte[] senderAddress = tx.sender();
// AddressState senderState = rows.get(Hex.toHexString(senderAddress));
// if (senderState != null){
// BigInteger value = new BigInteger(0, tx.getValue());
//
// senderState.addToBalance(value.negate());
// walletUpdated = true;
// }
byte[] address = tx.getReceiveAddress(); byte[] receiveAddress = tx.getReceiveAddress();
AddressState receiverState = rows.get(Hex.toHexString(receiveAddress));
AddressState addressState = rows.get(Hex.toHexString(address)); if (receiverState != null){
if (addressState != null){ receiverState.addToBalance(new BigInteger(1, tx.getValue()));
addressState.addToBalance(new BigInteger(1, tx.getValue()));
walletUpdated = true; walletUpdated = true;
} }
} }

View File

@ -294,7 +294,7 @@ public class ECKey implements Serializable {
} }
private static ECDSASignature fromComponents(byte[] r, byte[] s) { private static ECDSASignature fromComponents(byte[] r, byte[] s) {
return new ECDSASignature(new BigInteger(r), new BigInteger(s)); return new ECDSASignature(new BigInteger(1, r), new BigInteger(1, s));
} }
public static ECDSASignature fromComponents(byte[] r, byte[] s, byte v) { public static ECDSASignature fromComponents(byte[] r, byte[] s, byte v) {

View File

@ -47,7 +47,7 @@ public class TransactionTest {
// cat --> 79b08ad8787060333663d19704909ee7b1903e58 // cat --> 79b08ad8787060333663d19704909ee7b1903e58
// cow --> cd2a3d9f938e13cd947ec05abc7fe734df8dd826 // cow --> cd2a3d9f938e13cd947ec05abc7fe734df8dd826
BigInteger value = new BigInteger("1000000000000000000000000"); BigInteger value = new BigInteger("1000000000000000000000");
byte[] privKey = HashUtil.sha3("cat".getBytes()); byte[] privKey = HashUtil.sha3("cat".getBytes());
Address receiveAddress = new Address(privKey); Address receiveAddress = new Address(privKey);
@ -57,8 +57,55 @@ public class TransactionTest {
byte[] gasPrice= Hex.decode("09184e72a000"); byte[] gasPrice= Hex.decode("09184e72a000");
byte[] gas = Hex.decode("4255"); byte[] gas = Hex.decode("4255");
Transaction tx = new Transaction(null, value.toByteArray(), // Tn (nonce); Tp(pgas); Tg(gaslimi); Tt(value); Tv(value); Ti(sender); Tw; Tr; Ts
receiveAddress.getAddress(), gasPrice, gas, null); Transaction tx = new Transaction(null, gasPrice, gas, receiveAddress.getAddress(),
value.toByteArray(),
null);
tx.sign(senderPrivKey);
System.out.println("v\t\t\t: " + Hex.toHexString(new byte[] { tx.getSignature().v }));
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() ));
// 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("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()));
System.out.println(tx.toString());
}
@Test /* achieve public key of the sender nonce: 01 */
public void test3() throws Exception {
// cat --> 79b08ad8787060333663d19704909ee7b1903e58
// cow --> cd2a3d9f938e13cd947ec05abc7fe734df8dd826
BigInteger value = new BigInteger("1000000000000000000000000");
byte[] nonce = {01};
byte[] privKey = HashUtil.sha3("cat".getBytes());
Address receiveAddress = new Address(privKey);
byte[] senderPrivKey = HashUtil.sha3("cow".getBytes());
byte[] gasPrice= Hex.decode("09184e72a000");
byte[] gas = Hex.decode("4255");
Transaction tx = new Transaction(null, gasPrice, gas,
receiveAddress.getAddress(), value.toByteArray(), null);
tx.sign(senderPrivKey); tx.sign(senderPrivKey);
@ -81,25 +128,6 @@ public class TransactionTest {
Hex.toHexString(key.getAddress())); Hex.toHexString(key.getAddress()));
} }
@Test /* encode transaction */
public void test3() throws Exception {
BigInteger value = new BigInteger("1000000000000000000000000");
byte[] privKey = HashUtil.sha3("cat".getBytes());
Address receiveAddress = new Address(privKey);
byte[] gasPrice= Hex.decode("09184e72a000");
byte[] gas = Hex.decode("4255");
Transaction tx = new Transaction(null, value.toByteArray(),
receiveAddress.getAddress(), gasPrice, gas, null);
tx.sign(privKey);
byte[] payload = tx.getEncodedSigned();
System.out.println(Hex.toHexString( payload ));
}
@Test @Test
public void testTransactionFromRLP() { public void testTransactionFromRLP() {
@ -121,6 +149,16 @@ public class TransactionTest {
assertEquals(RLP_ENCODED_TX, Hex.toHexString(tx.getEncodedSigned())); assertEquals(RLP_ENCODED_TX, Hex.toHexString(tx.getEncodedSigned()));
} }
@Test
public void testTransactionFromRLP2() {
byte[] encodedTxBytes = Hex.decode("f86e808609184e72a0008242559479b08ad8787060333663d19704909ee7b1903e58893635c9adc5dea00000801ba0e01349f939f41f7262e823b1ccd7306ec32b5cab6a4f539849a38b0637aee9cda0079bf1cf8dfcb1ddefa6336de34eefeebfd796afc25568a2b875fc4ff0c044c3");
Transaction tx = new Transaction(encodedTxBytes);
System.out.println(Hex.toHexString( tx.sender() ));
}
@Test @Test
public void testTransactionFromNew() throws Exception { public void testTransactionFromNew() throws Exception {
byte[] privKeyBytes = Hex.decode("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4"); byte[] privKeyBytes = Hex.decode("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4");