How to find Z value of multisig transaction?

for example this transaction: http://2coin.org/txinfo.aspx?txid=6c3dc603da32bba3f56f2b33053aaf0f0f17322386c0c6846786bffe49f6ef22&cur=BTC

Script not of right size to be a scriptSig, expecting 2 but got 4

• I think we are going to need a little more info to be able to help you out. Which "Z" value are you talking about? Jan 29, 2015 at 16:54
• I mean hash of the outputs to be signed. also this question is close to what i`m asking however it asks about single-sig transaction: bitcoin.stackexchange.com/questions/25387/… Jan 29, 2015 at 17:03
• I would phrase the question as something like "How do I figure out what to sign for a multisig transaction?" That will probably be more useful and searchable than saying Z value. Jan 29, 2015 at 21:51

What you're asking for is how to figure out what to sign for a multisig transaction.

Multisig is actually very close to this answer. There are a few subtle differences, however, so let me try to summarize step-by-step using the transaction as seen on the blockchain

Note that for each input, the actual hash to be signed is going to be different. Namely, you will need to fill in the redeem script for that input only and nulls for every other input. To illustrate, let's figure out what you need to sign for the very first input.

1. Transaction version: `01000000`
2. Number of inputs: `03`
3. Tx input #1 hash: `fdb1fe0b4506f8d412f8498a0d747701bc5ed8c009e779ee670c82361c1d1dd5`
4. Tx input #1 index: `01000000`
5. Tx input #1 redeem script length: `47` (71 bytes)
6. Tx input #1 redeem script: `522102cebf6ab580948d146b7cc771d8e646974349d3d7b11f3e03287d0997a477d3b921037ba651485b7a2cb222191eb64a55926e62bbabfe9b5ed2a9488aad547b20428252ae`
7. Tx input #1 sequence: `ffffffff`
8. Tx input #2 hash: `a614d26f1878078a00a3c296085576cd7e6361234ea82c865681041fcfdacea8`
9. Tx input #2 index: `01000000`
10. Tx input #2 redeem script length: `00` (nothing)
11. Tx input #2 sequence: `ffffffff`
12. Tx input #3 hash: `d064d2f9cf9e5196a9d81dd87718c9cfbec97f3ccac7164946d956421597c7f1`
13. Tx input #3 index: `01000000`
14. Tx input #3 redeem script length: `00` (nothing)
15. Tx input #3 sequence: `ffffffff`
16. Number of outputs: `01000000`
17. Amount being sent to the first (and only) output: `e068704600000000`
18. Output script length: `19`
19. Output script: `76a9142c76e6fdd1a81c902afa62e78ec71435708d9d9d88ac`
20. Lock time field: `00000000`
21. SIGHASH_ALL: `01000000`

Now, if you double-sha256 these bytes you get:

`9c4b551f37f4b383af9216045d80b2fcd4ed57bddca8df388ec29601cbd2a4f1`

And indeed when you check against the embedded signature of that transaction, you can see that that is indeed the hash that was signed. Here's a code sample to verify using the excellent btcd library written in go:

``````package main

import (
"encoding/hex"
"fmt"
"hash"

"github.com/btcsuite/btcec"
"github.com/btcsuite/fastsha256"
)

// Calculate the hash of hasher over buf.
func calcHash(buf []byte, hasher hash.Hash) []byte {
hasher.Write(buf)
return hasher.Sum(nil)
}

// Hash160 calculates the hash ripemd160(sha256(b)).
func Hash256(buf []byte) []byte {
return calcHash(calcHash(buf, fastsha256.New()), fastsha256.New())
}

func main() {

b, _ := hex.DecodeString(x)

hash := Hash256(b)
fmt.Printf("hash of thing to sign: %x\n", hash)

pubkeyStr := "02cebf6ab580948d146b7cc771d8e646974349d3d7b11f3e03287d0997a477d3b9"
pubkeyBytes, _ := hex.DecodeString(pubkeyStr)
pubkeyBytes2, _ := hex.DecodeString(pubkeyStr2)

p, _ := btcec.ParsePubKey(pubkeyBytes, btcec.S256())
p2, _ := btcec.ParsePubKey(pubkeyBytes2, btcec.S256())

fmt.Printf("pubkeys: %s, %s\n", p, p2)

sigStr := "3044022025332b6dabf11e493fbc62c93e7302c48666512e1cf88157c26176f4af6d064702201ee7ec25d0917244e514c402e8751f112dfd1bef2b22ec5e496fbafabb52bf010148"

sigStr2 := "3045022100fa1f17bf59bee0ac33ae5f682711c5471c73a4aeb898aee218478289a4c7aa6e02207b40dfeae3fa4a50dc147bd42be40370d76a35d72c0b27b27c4ba2439a565fb901"

sigBytes, _ := hex.DecodeString(sigStr)
sigBytes2, _ := hex.DecodeString(sigStr2)

s, _ := btcec.ParseDERSignature(sigBytes, btcec.S256())
s2, _ := btcec.ParseDERSignature(sigBytes2, btcec.S256())

fmt.Printf("sig: %s\n", s)

fmt.Printf("signature valid: %v\n", s.Verify(hash, p))
fmt.Printf("signature valid: %v\n", s2.Verify(hash, p2))

}
``````

You can do the same thing with input #2 and input #3 to get the hash that gets signed by changing #5 and #6 (combined) to be `00` and #10 or #14 in the steps above to be `47522102cebf6ab580948d146b7cc771d8e646974349d3d7b11f3e03287d0997a477d3b921037ba651485b7a2cb222191eb64a55926e62bbabfe9b5ed2a9488aad547b20428252ae`

• I re-assembled everything from step 1 to step 21 manually, at the shell level, and didn't get the dsha256 value, until I discovered, that step 16 (number of TX-OUT) should be "01" instead of "01000000". It is a var_int (or also called compact size in the wiki). Nov 22, 2017 at 17:43