I know this question has been asked and answered, but while trying to get everything to work, I've come across some problems. This is what I'm trying to do:
1. take a target string 'Schoolbus'
2. use JSON with geth to eth_sign it
3. obtain v,r,s of signature
4. attempt to verify with a solidity contract, need the hash of 'Schoolbus'
So here's what I got. First of all, we can't all use the same private key, so if someone can verify my work and get a gist of my problem, that would be great.
Pretending that my priv key is '0xd1ade25ccd3d550a7eb532ac759cac7be09c2719', to sign 'Schoolbus', I use
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sign","params":["0xd1ade25ccd3d550a7eb532ac759cac7be09c2719", "Schoolbus"],"id":1}'
Where I get the result
0x2ac19db245478a06032e69cdbd2b54e648b78431d0a47bd1fbab18f79f820ba407466e37adbe9e84541cab97ab7d290f4a64a5825c876d22109f3bf813254e8601
I'm using (I might be wrong here)
v=2a
r=c19db245478a06032e69cdbd2b54e648b78431d0a47bd1fbab18f79f820ba407
s=466e37adbe9e84541cab97ab7d290f4a64a5825c876d22109f3bf813254e8601
Then I whipped up my contract, which is a variation of an answer in a related thread:
contract Auth {
function verify( bytes32 hash, uint8 v, bytes32 r, bytes32 s) constant returns(address retAddr) {
retAddr= ecrecover(hash, v, r, s);
}
}
Because I never got the hash of 'Schoolbus', I tried a couple of things in web3.js (the UTF8 one confused me, I was expecting that {encoding:'hex'} version to be the correct one):
console.log('1 '+ web3.sha3(web3.toHex('Schoolbus'))); //05ab39621b81764697fcfb6ae4fcf6b023cd644721c67c13a49fbd769c75671c
console.log('2 '+ web3.sha3(web3.toHex('Schoolbus'),{encoding:'hex'}));//d030d9a04df643f62a1502b017f51c41a659268091abbd20e2de97b935724d7c
console.log('3 '+ web3.sha3('Schoolbus'));//d030d9a04df643f62a1502b017f51c41a659268091abbd20e2de97b935724d7c
console.log('4 '+ web3.sha3( unescape(encodeURIComponent('Schoolbus')) ) ); //to UTF8 //d030d9a04df643f62a1502b017f51c41a659268091abbd20e2de97b935724d7c
console.log('5 '+ web3.sha3( unescape(encodeURIComponent('Schoolbus')), {encoding:'hex'} ) ); //to UTF8 //8f1cbe7efcf383ffeb1aeaf1e826c778a087153344cbeba144fbe967ad3ab11a
I ended up using this, but don't know why:
0xd030d9a04df643f62a1502b017f51c41a659268091abbd20e2de97b935724d7c
Then I called the contract:
var contDep=web3.eth.contract( [abi def] ).at( contractAddress);
console.log(
contDep.verify('d030d9a04df643f62a1502b017f51c41a659268091abbd20e2de97b935724d7c', 2a,'c19db245478a06032e69cdbd2b54e648b78431d0a47bd1fbab18f79f820ba407', '466e37adbe9e84541cab97ab7d290f4a64a5825c876d22109f3bf813254e8601')
);
Here's my problem. I keep getting this weird address back. It starts with 0x, it's 20 bytes, but it doesn't have [a-f] in it:
0x3433663632613135303262303137663531633431
If I swapped r and s, I get almost the same result back.
I was wondering if someone can verify my experience, or point out what I was doing wrong. I feel like a crazy person here.
Thanks for all your help.
web3.eth.sign(...)is the address of the account whose private key you want to sign with. So, the value that you are sending, which is 40 hex chars (i.e. 20 bytes) is the correct length for an address. From your comment, it seems that you really are sending the address. Just do not call it a "private key". An address is very much a public piece of information. (It is usually generated in some manner from the public key. – Ajoy Bhatia Apr 10 '17 at 21:43