Transaction.sender() fix
This commit is contained in:
parent
a16fa04e59
commit
0e239b58ef
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
Loading…
Reference in New Issue