vm: add ParseSignatureContract()

This commit is contained in:
Evgeniy Stratonikov 2021-03-05 12:22:48 +03:00
parent e66d36900c
commit ded6a70335
2 changed files with 22 additions and 5 deletions

View file

@ -105,24 +105,32 @@ func ParseMultiSigContract(script []byte) (int, [][]byte, bool) {
// IsSignatureContract checks whether the passed script is a signature check // IsSignatureContract checks whether the passed script is a signature check
// contract. // contract.
func IsSignatureContract(script []byte) bool { func IsSignatureContract(script []byte) bool {
_, ok := ParseSignatureContract(script)
return ok
}
// ParseSignatureContract parses simple signature contract and returns
// public key.
func ParseSignatureContract(script []byte) ([]byte, bool) {
if len(script) != 41 { if len(script) != 41 {
return false return nil, false
} }
ctx := NewContext(script) ctx := NewContext(script)
instr, param, err := ctx.Next() instr, param, err := ctx.Next()
if err != nil || instr != opcode.PUSHDATA1 || len(param) != 33 { if err != nil || instr != opcode.PUSHDATA1 || len(param) != 33 {
return false return nil, false
} }
pub := param
instr, _, err = ctx.Next() instr, _, err = ctx.Next()
if err != nil || instr != opcode.PUSHNULL { if err != nil || instr != opcode.PUSHNULL {
return false return nil, false
} }
instr, param, err = ctx.Next() instr, param, err = ctx.Next()
if err != nil || instr != opcode.SYSCALL || binary.LittleEndian.Uint32(param) != verifyInteropID { if err != nil || instr != opcode.SYSCALL || binary.LittleEndian.Uint32(param) != verifyInteropID {
return false return nil, false
} }
return true return pub, true
} }
// IsStandardContract checks whether the passed script is a signature or // IsStandardContract checks whether the passed script is a signature or

View file

@ -25,6 +25,15 @@ func testSignatureContract() []byte {
return prog return prog
} }
func TestParseSignatureContract(t *testing.T) {
prog := testSignatureContract()
pub := randomBytes(33)
copy(prog[2:], pub)
actual, ok := ParseSignatureContract(prog)
require.True(t, ok)
require.Equal(t, pub, actual)
}
func TestIsSignatureContract(t *testing.T) { func TestIsSignatureContract(t *testing.T) {
t.Run("valid contract", func(t *testing.T) { t.Run("valid contract", func(t *testing.T) {
prog := testSignatureContract() prog := testSignatureContract()