// CreateScriptSig signs a raw transaction with keys. func (rs *RedeemScript) createScriptSig(rawTransactionHashed []byte, signs [][]byte) ([]byte, error) { //Verify that it worked. secp256k1 := btcec.S256() count := 0 for i, signature := range signs { if signature == nil { continue } count++ sig, err := btcec.ParseSignature(signature, secp256k1) if err != nil { return nil, err } valid := sig.Verify(rawTransactionHashed, rs.PublicKeys[i].key) if !valid { return nil, fmt.Errorf("number %d of signature is invalid", i) } } if count != rs.M { return nil, fmt.Errorf("number of signatures %d must be %d", count, rs.M) } //redeemScript length. To allow redeemScript > 255 bytes, we use OP_PUSHDATA2 and use two bytes to specify length var redeemScriptLengthBytes []byte var requiredPUSHDATA byte if len(rs.Script) < 255 { requiredPUSHDATA = opPUSHDATA1 //OP_PUSHDATA1 specifies next *one byte* will be length to be pushed to stack redeemScriptLengthBytes = []byte{byte(len(rs.Script))} } else { requiredPUSHDATA = opPUSHDATA2 //OP_PUSHDATA2 specifies next *two bytes* will be length to be pushed to stack redeemScriptLengthBytes = make([]byte, 2) binary.LittleEndian.PutUint16(redeemScriptLengthBytes, uint16(len(rs.Script))) } //Create scriptSig var buffer bytes.Buffer buffer.WriteByte(op0) //OP_0 for Multisig off-by-one error for _, signature := range signs { if signature == nil { continue } buffer.WriteByte(byte(len(signature) + 1)) //PUSH each signature. Add one for hash type byte buffer.Write(signature) // Signature bytes buffer.WriteByte(0x1) //hash type } buffer.WriteByte(requiredPUSHDATA) //OP_PUSHDATA1 or OP_PUSHDATA2 depending on size of redeemScript buffer.Write(redeemScriptLengthBytes) //PUSH redeemScript buffer.Write(rs.Script) //redeemScript return buffer.Bytes(), nil }
func TestSignatures(t *testing.T) { for _, test := range signatureTests { var err error if test.der { _, err = btcec.ParseDERSignature(test.sig, btcec.S256()) } else { _, err = btcec.ParseSignature(test.sig, btcec.S256()) } if err != nil { if test.isValid { t.Errorf("%s signature failed when shouldn't %v", test.name, err) } /* else { t.Errorf("%s got error %v", test.name, err) } */ continue } if !test.isValid { t.Errorf("%s counted as valid when it should fail", test.name) } } }