Example #1
0
// 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
}
Example #2
0
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)
		}
	}
}