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

View File

@ -97,13 +97,19 @@ public class Wallet {
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();
AddressState addressState = rows.get(Hex.toHexString(address));
if (addressState != null){
addressState.addToBalance(new BigInteger(1, tx.getValue()));
byte[] receiveAddress = tx.getReceiveAddress();
AddressState receiverState = rows.get(Hex.toHexString(receiveAddress));
if (receiverState != null){
receiverState.addToBalance(new BigInteger(1, tx.getValue()));
walletUpdated = true;
}
}

View File

@ -294,7 +294,7 @@ public class ECKey implements Serializable {
}
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) {

View File

@ -47,7 +47,7 @@ public class TransactionTest {
// cat --> 79b08ad8787060333663d19704909ee7b1903e58
// cow --> cd2a3d9f938e13cd947ec05abc7fe734df8dd826
BigInteger value = new BigInteger("1000000000000000000000000");
BigInteger value = new BigInteger("1000000000000000000000");
byte[] privKey = HashUtil.sha3("cat".getBytes());
Address receiveAddress = new Address(privKey);
@ -57,8 +57,55 @@ public class TransactionTest {
byte[] gasPrice= Hex.decode("09184e72a000");
byte[] gas = Hex.decode("4255");
Transaction tx = new Transaction(null, value.toByteArray(),
receiveAddress.getAddress(), gasPrice, gas, null);
// Tn (nonce); Tp(pgas); Tg(gaslimi); Tt(value); Tv(value); Ti(sender); Tw; Tr; Ts
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);
@ -81,26 +128,7 @@ public class TransactionTest {
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
public void testTransactionFromRLP() {
// from RLP encoding
@ -121,7 +149,17 @@ public class TransactionTest {
assertEquals(RLP_ENCODED_TX, Hex.toHexString(tx.getEncodedSigned()));
}
@Test
@Test
public void testTransactionFromRLP2() {
byte[] encodedTxBytes = Hex.decode("f86e808609184e72a0008242559479b08ad8787060333663d19704909ee7b1903e58893635c9adc5dea00000801ba0e01349f939f41f7262e823b1ccd7306ec32b5cab6a4f539849a38b0637aee9cda0079bf1cf8dfcb1ddefa6336de34eefeebfd796afc25568a2b875fc4ff0c044c3");
Transaction tx = new Transaction(encodedTxBytes);
System.out.println(Hex.toHexString( tx.sender() ));
}
@Test
public void testTransactionFromNew() throws Exception {
byte[] privKeyBytes = Hex.decode("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4");