VerificationScript extends NeoSerializable { public boolean isMultiSigScript() { if (script.length < 43) { return false; } try { BinaryReader reader = new BinaryReader(this.script); int n = reader.readPushInteger(); if (n < 1 || n > NeoConstants.MAX_PUBLIC_KEYS_PER_MULTISIG_ACCOUNT) { return false; } int m = 0; while (reader.readByte() == OpCode.PUSHDATA1.getCode()) { if (script.length <= reader.getPosition() + 35) { return false; } if (reader.readByte() != 33) { return false; } reader.readEncodedECPoint(); m++; reader.mark(0); } if (n > m || m > MAX_PUBLIC_KEYS_PER_MULTISIG_ACCOUNT) { return false; } reader.reset(); int alsoM = reader.readPushInteger(); if (m != alsoM) { return false; } if (reader.readByte() != OpCode.PUSHNULL.getCode()) { return false; } if (reader.readByte() != OpCode.SYSCALL.getCode()) { return false; } byte[] interopServiceCode = new byte[4]; reader.read(interopServiceCode, 0, 4); if (!Numeric.toHexStringNoPrefix(interopServiceCode) .equals(InteropServiceCode.NEO_CRYPTO_CHECKMULTISIGWITHECDSASECP256R1.getHash())) { return false; } } catch (DeserializationException | IOException e) { return false; } return true; } VerificationScript();  VerificationScript(byte[] script);  VerificationScript(ECPublicKey publicKey);  VerificationScript(List<ECPublicKey> publicKeys, int signingThreshold); byte[] getScript(); @Override byte[] toArray(); ScriptHash getScriptHash(); @Override int getSize(); int getSigningThreshold(); int getNrOfAccounts(); boolean isSingleSigScript(); boolean isMultiSigScript(); List<ECPublicKey> getPublicKeys(); @Override void deserialize(BinaryReader reader); @Override void serialize(BinaryWriter writer); @Override boolean equals(Object o); @Override int hashCode();  }
@Test public void isMultiSigScript() { byte[] scriptBytes = Numeric.hexStringToByteArray("" + OpCode.PUSH2.toString() + OpCode.PUSHDATA1.toString() + "21" + "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef" + OpCode.PUSHDATA1.toString() + "21" + "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9" + OpCode.PUSHDATA1.toString() + "21" + "03f0f9b358dfed564e74ffe242713f8bc866414226649f59859b140a130818898b" + OpCode.PUSH3.toString() + OpCode.PUSHNULL.toString() + OpCode.SYSCALL.toString() + InteropServiceCode.NEO_CRYPTO_CHECKMULTISIGWITHECDSASECP256R1.getHash()); VerificationScript s = new VerificationScript(scriptBytes); assertTrue(s.isMultiSigScript()); }
@Test public void failIsMultiSigScriptBecauseScrtipIsTooShort() { byte[] scriptBytes = Numeric.hexStringToByteArray("a89429c3be9f"); VerificationScript s = new VerificationScript(scriptBytes); assertFalse(s.isMultiSigScript()); }
@Test public void failIsMultiSigScriptBecauseNIsSmallerThanOne() { byte[] scriptBytes = Numeric.hexStringToByteArray("" + OpCode.PUSH0.toString() + OpCode.PUSHDATA1.toString() + "21" + "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef" + OpCode.PUSH1.toString() + OpCode.PUSHNULL.toString() + OpCode.SYSCALL.toString() + "3073b3bb"); VerificationScript s = new VerificationScript(scriptBytes); assertFalse(s.isMultiSigScript()); }
@Test public void failIsMultiSigScriptBecauseScriptAppruptlyEnds() { byte[] scriptBytes = Numeric.hexStringToByteArray("" + OpCode.PUSH2.toString() + OpCode.PUSHDATA1.toString() + "21" + "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef"); VerificationScript s = new VerificationScript(scriptBytes); assertFalse(s.isMultiSigScript()); }
@Test public void failIsMultiSigScriptBecauseOfWrongPushData() { byte[] scriptBytes = Numeric.hexStringToByteArray("" + OpCode.PUSH2.toString() + OpCode.PUSHDATA1.toString() + "21" + "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef" + OpCode.PUSHDATA1.toString() + "43" + "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9" + OpCode.PUSH2.toString() + OpCode.PUSHNULL.toString() + OpCode.SYSCALL.toString() + "3073b3bb"); VerificationScript s = new VerificationScript(scriptBytes); assertFalse(s.isMultiSigScript()); }
@Test public void failIsMultiSigScriptBecauseNLargerThanM() { byte[] scriptBytes = Numeric.hexStringToByteArray("" + OpCode.PUSH3.toString() + OpCode.PUSHDATA1.toString() + "21" + "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef" + OpCode.PUSHDATA1.toString() + "21" + "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9" + OpCode.PUSH2.toString() + OpCode.PUSHNULL.toString() + OpCode.SYSCALL.toString() + "3073b3bb"); VerificationScript s = new VerificationScript(scriptBytes); assertFalse(s.isMultiSigScript()); }
@Test public void failIsMultiSigScriptBecauseMIsIncorrect() { byte[] scriptBytes = Numeric.hexStringToByteArray("" + OpCode.PUSH2.toString() + OpCode.PUSHDATA1.toString() + "21" + "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef" + OpCode.PUSHDATA1.toString() + "21" + "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9" + OpCode.PUSH3.toString() + OpCode.PUSHNULL.toString() + OpCode.SYSCALL.toString() + "3073b3bb"); VerificationScript s = new VerificationScript(scriptBytes); assertFalse(s.isMultiSigScript()); }
@Test public void failIsMultiSigScriptBecauseOfMissingPUSHNULL() { byte[] scriptBytes = Numeric.hexStringToByteArray("" + OpCode.PUSH2.toString() + OpCode.PUSHDATA1.toString() + "21" + "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef" + OpCode.PUSHDATA1.toString() + "21" + "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9" + OpCode.PUSH2.toString() + OpCode.SYSCALL.toString() + "3073b3bb"); VerificationScript s = new VerificationScript(scriptBytes); assertFalse(s.isMultiSigScript()); }
@Test public void failIsMultiSigScriptBecauseOfMissingSYSCALL() { byte[] scriptBytes = Numeric.hexStringToByteArray("" + OpCode.PUSH2.toString() + OpCode.PUSHDATA1.toString() + "21" + "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef" + OpCode.PUSHDATA1.toString() + "21" + "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9" + OpCode.PUSH2.toString() + OpCode.PUSHNULL.toString() + "3073b3bb"); VerificationScript s = new VerificationScript(scriptBytes); assertFalse(s.isMultiSigScript()); }
@Test public void failIsMultiSigScriptBecauseOfWrongInteropService() { byte[] scriptBytes = Numeric.hexStringToByteArray("" + OpCode.PUSH2.toString() + OpCode.PUSHDATA1.toString() + "21" + "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef" + OpCode.PUSHDATA1.toString() + "21" + "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9" + OpCode.PUSH3.toString() + OpCode.PUSHNULL.toString() + OpCode.SYSCALL.toString() + "103ab300"); VerificationScript s = new VerificationScript(scriptBytes); assertFalse(s.isMultiSigScript()); }