I am currently signing with a the ECDSASignature spec in java however I noticed that getting a v value from the signature is a custom spec for ethereum.
My code:
public static void main(String[] args) throws Exception
{
byte[] offer = {
0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
};
System.out.print(getAgreementFromAdmin(offer));
}
//TODO port to android
//TODO get v value
private static JSONObject getAgreementFromAdmin(byte[] offer) throws Exception
{
//no need for address, from ecrecover you can take the token.
System.out.println("offer: " + offer.length);
// sign() returns r, s but not v
// org.web3j.crypto.ECDSASignature
ECDSASignature signature = TransactionQueue.getAdminKeyPair().sign(offer);
BigInteger r = signature.r;
BigInteger s = signature.s;
int v = 27; // minimum value of v, if not working try with 28
JSONObject agreementJSON = new JSONObject();
agreementJSON.put("offer", "0x" + bytesToHex(offer));
agreementJSON.put("v", v);
agreementJSON.put("r", r);
agreementJSON.put("s", s);
return agreementJSON;
}
The sign method is defined as:
public ECDSASignature sign(byte[] transactionHash) {
ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));
ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privateKey, Sign.CURVE);
signer.init(true, privKey);
BigInteger[] components = signer.generateSignature(transactionHash);
return new ECDSASignature(components[0], components[1]).toCanonicalised();
}
Best Answer
This is similar to this question. The calculation of v in the geth client can be found here. It's simply the combination of