vm: implement ParseMultisigContract()
When creating witness for a multisig contract, it is needed to extract the order of public keys from it.
This commit is contained in:
parent
acea3867b2
commit
8819d4f970
1 changed files with 19 additions and 10 deletions
|
@ -31,49 +31,58 @@ func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) {
|
|||
// IsMultiSigContract checks whether the passed script is a multi-signature
|
||||
// contract.
|
||||
func IsMultiSigContract(script []byte) bool {
|
||||
_, ok := ParseMultiSigContract(script)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ParseMultiSigContract returns list of public keys from the verification
|
||||
// script of the contract.
|
||||
func ParseMultiSigContract(script []byte) ([][]byte, bool) {
|
||||
var nsigs, nkeys int
|
||||
|
||||
ctx := NewContext(script)
|
||||
instr, param, err := ctx.Next()
|
||||
if err != nil {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
nsigs, ok := getNumOfThingsFromInstr(instr, param)
|
||||
if !ok {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
var pubs [][]byte
|
||||
for {
|
||||
instr, param, err = ctx.Next()
|
||||
if err != nil {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
if instr != opcode.PUSHBYTES33 {
|
||||
break
|
||||
}
|
||||
pubs = append(pubs, param)
|
||||
nkeys++
|
||||
if nkeys > MaxArraySize {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
if nkeys < nsigs {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
nkeys2, ok := getNumOfThingsFromInstr(instr, param)
|
||||
if !ok {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
if nkeys2 != nkeys {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
instr, _, err = ctx.Next()
|
||||
if err != nil || instr != opcode.CHECKMULTISIG {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
instr, _, err = ctx.Next()
|
||||
if err != nil || instr != opcode.RET || ctx.ip != len(script) {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
return true
|
||||
return pubs, true
|
||||
}
|
||||
|
||||
// IsSignatureContract checks whether the passed script is a signature check
|
||||
|
|
Loading…
Reference in a new issue