Licenças de ExpertAdivisor

 

Boa noite pessoal, tenho uma dúvida que acredito que muitos devem ter aqui.

Existe  algum tutorial ou artigo que ensine a criar alguma função para podemos limitar o acesso ou copia do nosso expert


Eu tenho esse simples codigo que verifica se uma conta é permitida para usar o EA, mas para cada novo usuário eu tenho que recompilar o codigo com a conta permitida

entretanto gostaria de saber se tem alguma forma de fazer isso Online, por banco de dados ou até mesmo a leitura

de um arquivo txt que esteja hospedado na web.

bool verificarContas(long &cpermitidas[],long login)
  {
   bool liberado = false;
   for(int i=0; i<ArraySize(cpermitidas); i++)
     {
      if(cpermitidas[i] == login)
        {
         Print("Acesso Liberado");
         liberado = true;
         break;
        }
     }
   return liberado;
  }
int OnInit()
  {
   long conta = AccountInfoInteger(ACCOUNT_LOGIN);
   long contas_permitidas[] = {conta};

   if(!verificarContas(contas_permitidas,conta))
     {
      Alert("Acesso Negado!");
      return(INIT_FAILED);
     }
   return(INIT_SUCCEEDED);
}
 
JhonyTygasBoa noite pessoal, tenho uma dúvida que acredito que muitos devem ter aqui. Existe  algum tutorial ou artigo que ensine a criar alguma função para podemos limitar o acesso ou copia do nosso expert Eu tenho esse simples codigo que verifica se uma conta é permitida para usar o EA, mas para cada novo usuário eu tenho que recompilar o codigo com a conta permitida entretanto gostaria de saber se tem alguma forma de fazer isso Online, por banco de dados ou até mesmo a leitura de um arquivo txt que esteja hospedado na web.


Bom dia!!

Artigos

Código MQL5 de segurança: proteção de senha, geradores de chaves, limites de tempo, licenças remotas e técnicas de codificação de chave de licença de EA avançadas

investeo, 2014.02.20 15:12

A maioria dos desenvolvedores precisa ter seu código protegido. Este artigo apresentará alguns meios diferentes para proteger o software MQL5 - ele apresenta métodos para fornecer recursos de licenciamento para Scripts do MQL5, Exper Advisors e Indicadores. Ele cobre a proteção de senha, geradores de chave, licença de conta, avaliação de limite de tempo e proteção remota usando chamadas MQL5-RPC.

 
Vinicius de Oliveira #:


Bom dia!!


Obrigado cara, vou ler esse artigo e estudar como posso implementar
 

Veja também o seguinte antigo post do forum em Inglês ...

Forum on trading, automated trading systems and testing trading strategies

EA limit code

Fernando Carreiro, 2017.09.10 22:17

Here is a sample of my own code that I use, but it is up to you to implement properly. I'm not offering any support on it. It is up to you to do the necessary research and learning.

//+------------------------------------------------------------------------------------+
// Initialisation Event Function
//+------------------------------------------------------------------------------------+
int OnInit()
{
   // Check Licensing Restrictions
   if( boolRestrictOnInit() ) return( INIT_FAILED );

   // ...

   return( INIT_SUCCEEDED );  // Initialisation complete
}
//+------------------------------------------------------------------------------------+
// Tick Event Function
//+------------------------------------------------------------------------------------+
void OnTick()
{
   // Check Licensing Restrictions
   if( boolRestrictOnTick() ) return;
   
   /// ...
}
//+------------------------------------------------------------------------------------+
// Function to Test Restrictions during Initialisation
//+------------------------------------------------------------------------------------+
bool boolRestrictOnInit()
{
   boolRestrictions =
      boolRestrictExpiration     ||
      boolRestrictAccountNumber  ||
      boolRestrictAccountName    ||
      boolRestrictAccountServer  ||
      boolRestrictAccountCompany ||
      boolRestrictDemoAccount    ||
      boolRestrictSymbols;

   if( boolRestrictions )
   {
      boolRestrictionsUnverified = true;

      if( (bool) TerminalInfoInteger( TERMINAL_CONNECTED ) )
      {
         long longAccountNumber = AccountInfoInteger( ACCOUNT_LOGIN );
         if( longAccountNumber > 0 )
         {
            if( boolRestrictAccountNumber )
               { if( longAccountNumber                        != longRestrictAccountNumber )
                  { return( boolRestrictAlert() ); } }
            if( boolRestrictAccountName )
               { if( AccountInfoString( ACCOUNT_NAME )        != strRestrictAccountName    )
                  { return( boolRestrictAlert() ); } }
            if( boolRestrictAccountServer )
               { if( AccountInfoString( ACCOUNT_SERVER )      != strRestrictAccountServer  )
                  { return( boolRestrictAlert() ); } }
            if( boolRestrictAccountCompany )
               { if( AccountInfoString( ACCOUNT_COMPANY )     != strRestrictAccountCompany )
                  { return( boolRestrictAlert() ); } }
            if( boolRestrictDemoAccount )
               { if( AccountInfoInteger( ACCOUNT_TRADE_MODE ) != ACCOUNT_TRADE_MODE_DEMO   )
                  { return( boolRestrictAlert() ); } }
            if( boolRestrictSymbols() )
               { return( boolRestrictAlert() ); }

            boolRestrictionsUnverified = false;
         }
      }
   }
   return( false );
}
//+------------------------------------------------------------------------------------+
// Function to Test Variations of Restricted Symbols
//+------------------------------------------------------------------------------------+
bool boolRestrictSymbols()
{
   if( boolRestrictSymbols )
   {
      int intSymbolCount = ArraySize( strRestrictSymbols );
      if( intSymbolCount == 0 ) return( false );
      for( int i = 0; i < intSymbolCount; i++ )
      {
         if( StringFind( _Symbol, strRestrictSymbols[i] ) != WRONG_VALUE ) return( false );
         int
            intLen  = StringLen( strRestrictSymbols[i] ),
            intHalf = intLen / 2;
         string
            strLeft  = StringSubstr( strRestrictSymbols[i], 0, intHalf ),
            strRight = StringSubstr( strRestrictSymbols[i], intHalf, intLen - intHalf );
         if( ( StringFind( _Symbol, strLeft  ) != WRONG_VALUE ) &&
             ( StringFind( _Symbol, strRight ) != WRONG_VALUE )    )
            return( false );
      }
      return( true );
   }
   return( false );
}
//+------------------------------------------------------------------------------------+
// Function to Test Expiration during Tick Events
//+------------------------------------------------------------------------------------+
bool boolRestrictOnTick()
{
   if( boolRestrictions )
   {
      if( boolRestrictionsUnverified )
         return( boolRestrictOnInit() );
      if( boolRestrictExpiration && ( TimeCurrent() >= dtRestrictExpiration ) )
         return( boolRestrictAlert()  );
   }
   return( false );
}
// Function to Alert User of Licensing Restrictions and Remove Code from Execution
bool boolRestrictAlert()
{
   if( boolRestrictAlert )
      MessageBox( strRestrictAlertMessage, strRestrictAlertCaption, MB_ICONERROR );
   ExpertRemove();
   return( true );
}
//+------------------------------------------------------------------------------------+
//      Variables for Handling of Licensing Restrictions
//+------------------------------------------------------------------------------------+
bool
   boolRestrictExpiration     = false, // Set to true, to use an Experation Date
   boolRestrictAccountNumber  = false, // Set to true for Restricting by Account Number
   boolRestrictAccountName    = false, // Set to true for Restricting by Account Name
   boolRestrictAccountServer  = false, // Set to true for Restricting by Account Server
   boolRestrictAccountCompany = false, // Set to true for Restricting by Account Company
   boolRestrictDemoAccount    = false, // Set to true, to only allow Demo Accounts
   boolRestrictSymbols        = false, // Set to true, to only allow certain Symbols
   boolRestrictAlert          = true,  // Display Alert Message when Restrictions apply
   boolRestrictionsUnverified = false, // DO NOT CHANGE. For internal use only!
   boolRestrictions           = false; // DO NOT CHANGE. For internal use only!
datetime
   dtRestrictExpiration       = D'2017.03.31';  // Restricted by Expration Date
long
   longRestrictAccountNumber  = 123456789;      // Restricted by Account Number
string
   strRestrictAccountName     = "Client Name",  // Restricted by Account Name
   strRestrictAccountServer   = "Server Name",  // Restricted by Account Server
   strRestrictAccountCompany  = "Company Name", // Restricted by Account Company
   strRestrictSymbols[]       = { "EURUSD", "GBPJPY", "NZDCAD" }, // Restricted Symbols
   strRestrictAlertCaption    = "Restrictions", // Alert Message Box Caption
   strRestrictAlertMessage    =
      "ATTENTION! Due to Licensing Restrictions, code execution has been blocked!";
      // Message to be used when Restrictions have been detected
//+------------------------------------------------------------------------------------+
 

Tem várias formas de fazer isso online, sem por a venda no marketplace daqui (que tambem é uma forma). Uma bem simples é um gerador de serial, baseado no nome registrado na conta e no login, que você passaria ao cliente.

Uma solução online é a leitura de uma pagina pelo EA (não serve com indicadores) você pode colocar o login na pagina e a EA ler e dar acesso, entre outras soluções dessa forma. E existe ainda as mais elabolaradas, como acesso pelo telegram ou mesmo por banco de dados via metodo post

 
Cesar Afif rezende Oaquim #:

Tem várias formas de fazer isso online, sem por a venda no marketplace daqui (que tambem é uma forma). Uma bem simples é um gerador de serial, baseado no nome registrado na conta e no login, que você passaria ao cliente.

Uma solução online é a leitura de uma pagina pelo EA (não serve com indicadores) você pode colocar o login na pagina e a EA ler e dar acesso, entre outras soluções dessa forma. E existe ainda as mais elabolaradas, como acesso pelo telegram ou mesmo por banco de dados via metodo post

Ops, o pessoal respondeu enquanto eu escrevia. Otimo artigo, por sinal. Boa solução.

 
Fernando Carreiro #:

Veja também o seguinte antigo post do forum em Inglês ...

Show de bola, muito bom esse artigo
 
Cesar Afif rezende Oaquim #:

Tem várias formas de fazer isso online, sem por a venda no marketplace daqui (que tambem é uma forma). Uma bem simples é um gerador de serial, baseado no nome registrado na conta e no login, que você passaria ao cliente.

Uma solução online é a leitura de uma pagina pelo EA (não serve com indicadores) você pode colocar o login na pagina e a EA ler e dar acesso, entre outras soluções dessa forma. E existe ainda as mais elabolaradas, como acesso pelo telegram ou mesmo por banco de dados via metodo post

Boa ideia também, obrigado


Erro na criação da Licença Remota

Boa tarde, há um tempo atrás eu estava com dúvidas de como implementar o código de licensa remota para o meu EA, me indicaram o seguinte artigo

https://www.mql5.com/pt/articles/359

Implementei o seguinte código abaixo de acordo com o artigo, codigo para Criar um servidor Localmente, se vocês testarem o código abaixo em Python funciona perfeitamente cria o servidor e adiciona as 2 licenças fictícia

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler

class RequestHandler( SimpleXMLRPCRequestHandler ):
    rpc_path = ( '/RPC2', )
    

class RemoteLicenseExample(SimpleXMLRPCServer):

    def __init__(self):
        SimpleXMLRPCServer.__init__( self, (localhost:8000), requestHandler=RequestHandler, logRequests = False)
        
        self.register_introspection_functions()
        self.register_function( self.xmlrpc_isValid, "isValid" )        
        
        self.licenses = {} 
        
    def addLicense(self, ea_name, broker_name, account_number):
        if ea_name in self.licenses:
            self.licenses[ea_name].append({ 'broker_name': broker_name, 'account_number' : account_number })
        else:
            self.licenses[ea_name] = [ { 'broker_name': broker_name, 'account_number' : account_number } ]
             
    def listLicenses(self):
        print (self.licenses)
        
    def xmlrpc_isValid(self, ea_name, broker_name, account_number):
        isValidLicense = False
        
        ea_name = str(ea_name)
        broker_name = str(broker_name)
        
        print ("Request for license", ea_name, broker_name, account_number)
        
        try:
            account_number = int(account_number)
        except ValueError as error:
            return isValidLicense
    
        if ea_name in self.licenses:
            for license in self.licenses[ea_name]:
                if license['broker_name'] == broker_name and license['account_number'] == account_number:
                    isValidLicense = True
                    break
                
        print ("License valid:", isValidLicense)
        
        return isValidLicense
    
if __name__ == '__main__':
    server = RemoteLicenseExample()
    server.addLicense("RemoteProtectedEA", "MetaQuotes Software Corp.", 1024221)
    server.addLicense("RemoteProtectedEA", "MetaQuotes Software Corp.", 1024223)
    
    server.listLicenses()
    server.serve_forever() 

Até aqui tudo bem, executei o código MQL5 abaixo para testar a licensa

Código que cria o EA para fazer o teste das licensas(CODIGO DO ARTIGO)

//+------------------------------------------------------------------+
//|                                            RemoteProtectedEA.mq5 |
//|                                      Copyright 2012, Investeo.pl |
//|                                           http://www.investeo.pl |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, Investeo.pl"
#property link      "http://www.investeo.pl"
#property version   "1.00"

#include <MQL5-RPC.mqh>
#include <Arrays\ArrayObj.mqh>
#include <Arrays\ArrayInt.mqh>
#include <Arrays\ArrayString.mqh>
#include <Arrays\ArrayBool.mqh>

bool license_status=false;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
/* License proxy server */
   CXMLRPCServerProxy s("localhost:8000");
   if(s.isConnected()==true)
     {

      CXMLRPCResult *result;

/* Get account data */
      string broker= AccountInfoString(ACCOUNT_COMPANY);
      long account = AccountInfoInteger(ACCOUNT_LOGIN);

      printf("The name of the broker = %s",broker);
      printf("Account number =  %d",account);

/* Get remote license status */
      CArrayObj* params= new CArrayObj;
      CArrayString* ea = new CArrayString;
      CArrayString* br = new CArrayString;
      CArrayInt *ac=new CArrayInt;

      ea.Add("RemoteProtectedEA");
      br.Add(broker);
      ac.Add((int)account);

      params.Add(ea); params.Add(br); params.Add(ac);

      CXMLRPCQuery query("isValid",params);

      result=s.execute(query);

      CArrayObj *resultArray=result.getResults();
      if(resultArray!=NULL && resultArray.At(0).Type()==TYPE_BOOL)
        {
         CArrayBool *stats=resultArray.At(0);

         license_status=stats.At(0);
        }
      else license_status=false;

      if(license_status==true) printf("License valid.");
      else printf("License invalid.");

      delete params;
      delete result;
     }
   else Print("License server not connected.");
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(license_status==true)
     {
      // license valid
     }
  }
//+------------------------------------------------------------------+

Após a execução do código acima acontece o seguinte erro

'INT_MAX' - expression not boolean      ArrayBool.mqh   357     46

Abrir o arquivo ArrayBool.mqh na linha informada

bool CArrayBool::At(int index) const 
  {
//--- checking
   if(index<0 || index>=m_data_total) return(INT_MAX);
//---
   return(m_data[index]);
  }

Modifiquei o return(INT_MAX); para return(0); o codigo parou de acontecer o erro. Voltei a executar o código do MQL5(EA) que verifica a licensa ativa mas ele sempre cai no ELSE

Print("License server not connected.");

Como se não encontra-se o servidor, mas quando eu executo o codigo do servidor ele conectar e adiciona as licensas normalmente Por fim não sei como resolve, Novamente deixo o link do artigo, se alguem tiver alguma luz ou ideia diferente compartilhe por favor. Observação: Só tenho interesse em licensa online, não quero recompilar codigo, não quero colocar no mercado do MQL5. https://www.mql5.com/pt/articles/359

Código MQL5 de segurança: proteção de senha, geradores de chaves, limites de tempo, licenças remotas e técnicas de codificação de chave de licença de EA avançadas
Código MQL5 de segurança: proteção de senha, geradores de chaves, limites de tempo, licenças remotas e técnicas de codificação de chave de licença de EA avançadas
  • www.mql5.com
A maioria dos desenvolvedores precisa ter seu código protegido. Este artigo apresentará alguns meios diferentes para proteger o software MQL5 - ele apresenta métodos para fornecer recursos de licenciamento para Scripts do MQL5, Exper Advisors e Indicadores. Ele cobre a proteção de senha, geradores de chave, licença de conta, avaliação de limite de tempo e proteção remota usando chamadas MQL5-RPC.
 

@JhonyTygas, por favor não incluir texto livre dentro de secções de código. Torna-se difícil de ler em dispositivos móveis. Já editei o seu comentário para corrigir a situação.

 
JhonyTygas #:

Boa ideia também, obrigado


Erro na criação da Licença Remota

Boa tarde, há um tempo atrás eu estava com dúvidas de como implementar o código de licensa remota para o meu EA, me indicaram o seguinte artigo

https://www.mql5.com/pt/articles/359

Implementei o seguinte código abaixo de acordo com o artigo, codigo para Criar um servidor Localmente, se vocês testarem o código abaixo em Python funciona perfeitamente cria o servidor e adiciona as 2 licenças fictícia

Até aqui tudo bem, executei o código MQL5 abaixo para testar a licensa

Código que cria o EA para fazer o teste das licensas(CODIGO DO ARTIGO)

Após a execução do código acima acontece o seguinte erro

Abrir o arquivo ArrayBool.mqh na linha informada

Modifiquei o return(INT_MAX); para return(0); o codigo parou de acontecer o erro. Voltei a executar o código do MQL5(EA) que verifica a licensa ativa mas ele sempre cai no ELSE

Como se não encontra-se o servidor, mas quando eu executo o codigo do servidor ele conectar e adiciona as licensas normalmente Por fim não sei como resolve, Novamente deixo o link do artigo, se alguem tiver alguma luz ou ideia diferente compartilhe por favor. Observação: Só tenho interesse em licensa online, não quero recompilar codigo, não quero colocar no mercado do MQL5. https://www.mql5.com/pt/articles/359

Falaria pra voltar a modificação do ArrayBool.mqh e corrigir seu codigo pra suportar essa informação, INT_MAX tá lhe dizendo que é invalido porque o array veio vazio ou foi pedido um valor negativo no indice. Fora isso, verifica se o valor indo pros parametros é os mesmo que voce inseriu na hora de criar a licença, se for pode ser erro na classe CXMLRPCQuery que pode estar fazendo o envio errado dos dados por exemplo na hora de converter para envio colocou um byte a mais (mesmo zerado).