class GetMultisigScriptHash extends NativeMethod {

    @Override
    public Object execute(Object[] arguments) {
        if (arguments == null || arguments[0] == null) {
            throw new NativeContractIllegalArgumentException(REQUIRED_SIGNATURE_NULL_OR_ZERO);
        }
        int minimumSignatures = ((BigInteger) arguments[0]).intValueExact();
        Object[] publicKeys = (Object[]) arguments[1];

        if (minimumSignatures <= 0) {
            throw new NativeContractIllegalArgumentException(REQUIRED_SIGNATURE_NULL_OR_ZERO);
        }

        if (publicKeys == null || publicKeys.length < MINIMUM_REQUIRED_KEYS) {
            throw new NativeContractIllegalArgumentException(PUBLIC_KEYS_NULL_OR_ONE);
        }

        if (publicKeys.length < minimumSignatures) {
            throw new NativeContractIllegalArgumentException(String.format(
                    INVALID_REQUIRED_SIGNATURE_AND_PUBLIC_KEYS_PAIR,
                    publicKeys.length, minimumSignatures
            ));
        }

        if (publicKeys.length > MAXIMUM_ALLOWED_KEYS) {
            throw new NativeContractIllegalArgumentException(String.format(
                    "Given public keys (%d) are more than the maximum allowed signatures (%d)",
                    publicKeys.length, MAXIMUM_ALLOWED_KEYS
            ));
        }

        List<BtcECKey> btcPublicKeys = new ArrayList<>();
        Arrays.stream(publicKeys).forEach(o -> {
            byte[] publicKey = (byte[]) o;
            if (publicKey.length != COMPRESSED_PUBLIC_KEY_LENGTH && publicKey.length != UNCOMPRESSED_PUBLIC_KEY_LENGTH) {
                throw new NativeContractIllegalArgumentException(String.format(
                        "Invalid public key length: %d", publicKey.length
                ));
            }

            // Avoid extra work by not recalculating compressed keys on already compressed keys
            try {
                BtcECKey btcPublicKey = BtcECKey.fromPublicOnly(publicKey);
                if (publicKey.length == UNCOMPRESSED_PUBLIC_KEY_LENGTH) {
                    btcPublicKey = BtcECKey.fromPublicOnly(btcPublicKey.getPubKeyPoint().getEncoded(true));
                }
                btcPublicKeys.add(btcPublicKey);
            } catch (IllegalArgumentException e) {
                throw new NativeContractIllegalArgumentException(String.format(
                        "Invalid public key format: %s", ByteUtil.toHexString(publicKey)
                ), e);
            }
        });

        Script multisigScript = ScriptBuilder.createP2SHOutputScript(minimumSignatures, btcPublicKeys);

        return multisigScript.getPubKeyHash();
    }

    public  GetMultisigScriptHash(ExecutionEnvironment executionEnvironment);

}