| 35 | } |
| 36 | |
| 37 | func ParseBlockMultiSigProgram(script []byte) ([]ed25519.PublicKey, int, error) { |
| 38 | pops, err := vm.ParseProgram(script) |
| 39 | if err != nil { |
| 40 | return nil, 0, err |
| 41 | } |
| 42 | if len(pops) < 4 { |
| 43 | return nil, 0, vm.ErrShortProgram |
| 44 | } |
| 45 | if pops[len(pops)-1].Op != vm.OP_CHECKMULTISIG { |
| 46 | return nil, 0, errors.Wrap(ErrMultisigFormat, "no OP_CHECKMULTISIG") |
| 47 | } |
| 48 | npubkeys, err := vm.AsInt64(pops[len(pops)-2].Data) |
| 49 | if err != nil { |
| 50 | return nil, 0, errors.Wrap(ErrMultisigFormat, "parsing npubkeys") |
| 51 | } |
| 52 | if int(npubkeys) != len(pops)-4 { |
| 53 | return nil, 0, vm.ErrShortProgram |
| 54 | } |
| 55 | nrequired, err := vm.AsInt64(pops[len(pops)-3].Data) |
| 56 | if err != nil { |
| 57 | return nil, 0, errors.Wrap(ErrMultisigFormat, "parsing nrequired") |
| 58 | } |
| 59 | err = checkMultiSigParams(nrequired, npubkeys) |
| 60 | if err != nil { |
| 61 | return nil, 0, err |
| 62 | } |
| 63 | |
| 64 | firstPubkeyIndex := len(pops) - 3 - int(npubkeys) |
| 65 | |
| 66 | pubkeys := make([]ed25519.PublicKey, 0, npubkeys) |
| 67 | for i := firstPubkeyIndex; i < firstPubkeyIndex+int(npubkeys); i++ { |
| 68 | if len(pops[i].Data) != ed25519.PublicKeySize { |
| 69 | return nil, 0, err |
| 70 | } |
| 71 | pubkeys = append(pubkeys, ed25519.PublicKey(pops[i].Data)) |
| 72 | } |
| 73 | return pubkeys, int(nrequired), nil |
| 74 | } |
| 75 | |
| 76 | func P2SPMultiSigProgram(pubkeys []ed25519.PublicKey, nrequired int) ([]byte, error) { |
| 77 | err := checkMultiSigParams(int64(nrequired), int64(len(pubkeys))) |