Let us take "pizza transaction"
https://blockchain.info/tx/cca7507897abc89628f450e8b1e0c6fca4ec3f7b34cccf55f3f531c659ff4d79
01000000018dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d415db55d07a1000000008b4830450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e0141042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabbffffffff0200719a81860000001976a914df1bd49a6c9e34dfa8631f2c54cf39986027501b88ac009f0a5362000000434104cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455dac00000000
// decoded by https://blockchain.info/decode-tx
{
"lock_time":0,
"size":300,
"inputs":[
{
"prev_out":{
"index":0,
"hash":"a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d"
},
"script":"4830450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e0141042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabb"
}
],
"version":1,
"vin_sz":1,
"hash":"cca7507897abc89628f450e8b1e0c6fca4ec3f7b34cccf55f3f531c659ff4d79",
"vout_sz":2,
"out":[
{
"script_string":"OP_DUP OP_HASH160 df1bd49a6c9e34dfa8631f2c54cf39986027501b OP_EQUALVERIFY OP_CHECKSIG",
"address":"1MLh2UVHgonJY4ZtsakoXtkcXDJ2EPU6RY",
"value":577700000000,
"script":"76a914df1bd49a6c9e34dfa8631f2c54cf39986027501b88ac"
},
{
"script_string":"04cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455d OP_CHECKSIG",
"address":"13TETb2WMr58mexBaNq1jmXV1J7Abk2tE2",
"value":422300000000,
"script":"4104cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455dac"
}
]
}
Look and decode at the input=0 script:
48 // push next 0x48 bytes
30450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e01
41 // push next 0x41 bytes
042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabb
First push is signature concatenated with hashtype=01 (SIGHASH_ALL)
Second push is public key for address 17SkEw2md5avVNyYgj6RiXuQKNwkXaxFyQ
How do we check - is this transaction valid? Is it correctly signed?
1) Remove input script from transaction. We should remove bytes (do not forget about script len)
8b4830450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d
075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59
290d2fddf25269ee0e0141042e930f39ba62c6534ee98ed20ca98959d34aa9e0
57cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8
526e59667ce9c4e9dcebcabb
2) Replace it with the funding script to 17SkEw2md5avVNyYgj6RiXuQKNwkXaxFyQ
OP_DUP OP_HASH160 46af3fb481837fadbb421727f9959c2d32a36829 OP_EQUALVERIFY OP_CHECKSIG
1976a91446af3fb481837fadbb421727f9959c2d32a3682988ac
(Do not forget about script length again!)
3) Append SIGHASH_ALL as 32-bit low-endian value. The result will be
01000000018dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d41
5db55d07a1000000001976a91446af3fb481837fadbb421727f9959c2d32a368
2988acffffffff0200719a81860000001976a914df1bd49a6c9e34dfa8631f2c
54cf39986027501b88ac009f0a5362000000434104cd5e9726e6afeae357b180
6be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce33
88fa1abd0fa88b06c44ce81e2234aa70fe578d455dac0000000001000000
4) Hash it twice by SHA256. The digest will be
692678553d1b85ccf87d4d4443095f276cdf600f2bb7dd44f6effbd7458fd4c2
5) OK, we have now three items:
- a) public key 042e930f39ba62c6[...cut...]6e59667ce9c4e9dcebcabb
- b) signature 304502210099081[...cut...]d59290d2fddf25269ee0e
- c) digest 692678553d1b85ccf87d4d4443095f276cdf600f2bb7dd44f6effbd7458fd4c2
Pass these values to standard ECDSA verify method and you will receive the result: true or false. Here is a small piece of my quick-and-dirty check whith hardcoded values:
const QByteArray xx ( QByteArray::fromHex ( "01000000018dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d41"
"5db55d07a1000000001976a91446af3fb481837fadbb421727f9959c2d32a368"
"2988acffffffff0200719a81860000001976a914df1bd49a6c9e34dfa8631f2c"
"54cf39986027501b88ac009f0a5362000000434104cd5e9726e6afeae357b180"
"6be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce33"
"88fa1abd0fa88b06c44ce81e2234aa70fe578d455dac0000000001000000" ) );
const MyKey32 digest ( xx.constData ( ), xx.size ( ) ); // construct object of sha256 (sha256 ( xx ) )
_trace ( digest.toString ( ) ); // print result
const QByteArray pubkey ( QByteArray::fromHex ( "042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabb" ) );
const QByteArray signature ( QByteArray::fromHex ( "30450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e" ) );
_trace ( QString ( "verify=%1" ).arg ( digest.verify ( pubkey, signature ) ) );
The output is
"692678553d1b85ccf87d4d4443095f276cdf600f2bb7dd44f6effbd7458fd4c2"
"verify=1"
The brief run through is very useful , there are a few more minor questions regarding to it. I might be still confused, but I'll try to make sense of it .After the input script removal (Step1) , Replace with funding scrip(Step2) Append SIGHASH_ALL(Step3), which is the new transaction. According to the other answer , for the signiture s= (H(x)dr)n^-1 mod q,where H(x) is everything in raw tx , I'd assume that is exactly like the digest(?) So the Signature (304502...ee0e)is generated by using the digest (692678...d4c2) ,tempkey(random)and the private key ? – Kuriz – 2014-11-04T18:40:32.803
If so , I see that your ECDSA varification only takes in 2 inputs , which is pubkey and signiture. Out put was the digest. Since the basic concept utilizes u1, and u2. It was matching u1(G)+u2(B) , which B= pulic key , G= generation point , u1 = H(x)s^-1 , u2 = rds-1n, where the cancellation occurs leaves n*G's x-coordinate = r = varify. But since our key.verify doesn't include the digest, is it using a different method ? by regenerating the digest with the publickey and signature? – Kuriz – 2014-11-04T18:46:31.253
I have my own lib. Class MyKey32 is a class for performing some actions. So, the last line can be written as "digest.verify ( pubkey, signature )" where digest - is 32-byte object – amaclin – 2014-11-05T05:20:33.230
I've edited my post. – amaclin – 2014-11-05T05:28:00.227
1>So the Signature (304502...ee0e)is generated by using the digest (692678...d4c2) ,tempkey(random)and the private key?<<< Yes! The owner of private key created in 2010 the same array of bytes, calculated digest (the same as mine, or to be correct: mine is the same as his) and created signature with privkey and digest. For creating signature he need privkey and digest. For verifying signature we need pubkey and digest. – amaclin – 2014-11-05T10:48:21.260