Get to the point with Solidity

As I explained in my previous post about coding for Ethereum, there are a lot of ways to learn Solidity. However, most of them are really humdrum if you already know how to code, almost if you know javascript. So, let’s get to the point with Solidity looking the simplest structures you need to start coding.

ethereum photo

Solidity is based on javascript, but it also owns structures from other functional languages like Haskell and from object-oriented languages like Java. To do Dapps you need more than knowing the language because you need to know about patterns, security, how to compile and publish, and what actions cost more gas than others. Also, Solidity owns more reserved words than the explained below and more complex structures like inserting assembly inline, but with a little base of javascript and reading the following script (just 242 lines) you will be ready to start the backend of your very own distributed application over the Ethereum Virtual Machine.

pragma solidity ^0.4.19; //Version of the compiler

import "./otherContractsFile.sol";

contract ContractName { //Declaration of the basic unit of code
   /***Variables and funtions***/
   bool boolVariable;
   uint unsignedIntVariable;
   int intVariable;
   int intVariableWithValue = 10;
   uint16 unsigned16BitInt;
   uint256 unsignedIntVariable2;
   ufixed unsignedFixedVariable;
   fixed128x19 fixedVariableWith128bitsAnd19DecimalPoints;
   string stringVariable = "It can store any UTF-8 encoded string";
   address addressVariable; //addresses are used to store user accounts and contracts identifiers
   var aVariable = intVariableWithValue; //aVariable is defined as an int variable
   uint constant lustrum = 5 years;

   /*State variables are permanently stored in the EVM
    *between external function calls for this contract. 
    */
   uint stateVariable;

   function doSomething(uint uintParam) {
      /*Variables declared inside functions
       *are stored in memory and they are reset 
       *between different calls to the function.
       */
      uint functionVariable;
      
      functionVariable++;
      stateVariable = stateVariable + functionVariable;
      /*functionVariable = 1
       *stateVariable = 1 the first time this function is executed,
       *2 the second time this functions is executed, 3 the third, ...
       */
   }

   /***Collections and your own types***/
   uint[2] fixedArray;
   uint[] dynamicArray;
   mapping (address => uint) mapFromAddressToUint;

   enum EnumType {
      FirstValue,
      SecondValue,
      ThirdValue
   }

   struct StructType {
      uint uintField;
      string stringField;
   }
   StructType structVariable;
   StructType structVariableWithValue = StructType(10, "something");
   StructType[] structArray;

   function manageStructArrayByValue() {
      /*This variable is asigned by value (a copy is done)*/
      StructType memory myStruct = structArray[0]; 
      myStruct.uintField = 10; //structArray[0].uintField = 0;
   }

   function manageStructArrayByReference() {
      /*This variable is asigned by reference (a pointer is created)*/
      StructType storage myStruct = structArray[0]; 
      myStruct.uintField = 10; //structArray[0].uintField = 10;
   }

   uint[] public publicArray; //A public array is read-only publicly accessible by other contracts
   mapping (uint => string) public publicMap;

   function workWithArrays() private {
      uint[] myArray;
      myArray.push(1); //myArray = [1]
      myArray.push(2); //myArray = [1,2]
      uint newLenth = myArray.push(1); //newLenth = 3, myArray = [1,2,1] 
   }

   /*Functions are public by default, so you need to set them private
    *in order to keep your contract secure. In other case, functions
    *can be called (and executed) by other contracts.
    */
   function doSomethingPrivate(uint uintParam) private {
      //some code
   }

   /*Internal functions are functions that can be called from
    *contracts that inherit from this one.
    */
   function doSomethingInternal(uint uintParam) internal {
       //some code
   }

   /*Public functions can be called from anywhere.*/
   function do(uint param) public {
      //some code
      doSomethingPrivate(param);
      doSomethingInternal(unsignedIntVariable);
      doSomethingPrivate(10); //Can't call to doSomethingExternal
   }

   /*External functions can be called from external contracts
    *but not from inside this contract.
    */
   function doSomethingExternal(uint param) external {
      //some code
   }

   function ContractName() public { //this is a constructor but be carefull using them, they are not executed in some special cases
      //do something
   }

   function return10() returns (uint) {
      return 10;
   }

   function returnMultipleValues() returns (uint value1, uint value2) {
      value1 = 10;
      value2 = 20;
   }

   function returnMultipleValues2() returns (uint, uint) {
      return(10, 20);
   }

   function useMultipleValues() {
      uint value1;
      uint value2;
      (value1, value2) = returnMultipleValues();

      uint value4;
      (,value4) = returnMultpleValues2();
   }

   /*function throwsAnError(int a) private returns (int8) {
    *   return a + 1;
    *}
    */

   function addAndConvert(int a) private returns (int8) {
      return int8(a) + 1; //uses the 8 less significant bits of a
   }

   function addAndConvertIfIsInt8(uint a) private returns (uint8) {
      require(a <= 2 ** 8); //Throws an error if false
      return uint8(a) + 1;
   }

   /***Events***/
   event sthOccurred(uint param);

   function throwEvent() private {
      sthOcurred(10);
   }

   /***Modifiers***/
   //"view" can be used to identify functions that are not changing any data
   function returnInt() public view returns (int) {
      return intVariable;
   }

   //"pure" can be used to identify functions that do not access any data in the contract
   function add(int a, int b) public pure returns (int) {
      return a + b;
   }

   //"payable" is needed in order to receive Ether with a call
   function aFunctionThatCost() public payable {
      //this contract will own the ether sended at the end of the execution
   }

   modifier myModifier() {
      //some code to be executed before the function
      _; //this is a placeholder that indicates the point where the code of the function will be executed
      //some code to be executed after the function
   }

   function functionWithModifier() public myModifier {
      //some code to be executed in the place where the placeholder is set inside modifier's code
   }

   function otherFunctionsAndValues() private {
      keccak256("qwerty"); //returns a 256-bit hexadecimal with a SHA3 hash of the param
      //"qwerty" == "QWERTY"; Solidity can't compare strings. Instead you can do
      keccak256("qwerty") != keccak256("QWERTY");

      uint currentUnixTimestamp = now;
      1 minutes == 60;
      1 hours == 3600;
      //you also have available "days", "weeks" and "years" units

      address currentBlocMiner = block.coinbase;
      uint currentBlockDifficulty = block.difficulty;
      uint currentBlockGasLimit = block.gaslimit;
      uint currentBlockNumber = block.number; 
      uint currentBlockUnixTimestamp = block.timestamp;
      bytes32 theHash = block.blockhash(block.number); //only works for 256 most recent blocks excluding current
      bytes completeCallData = msg.data;
      uint remainingGas = msg.gas;
      address callerWhoInitiatesThisExecution = msg.sender;
      bytes4 firstFourBytesOfMsgData = msg.sig;
      uint numberOfWei = msg.value;
      uint gasPriceOfTheTransaction = tx.gasprice;
      uint senderOfTheTransaction = tx.origin;

      assert(1==2); //like require but for internal errors
      revert(); //abort and revert changes
   }

}

/***Inheritance and rehusability***/
contract A {
   function aFunction {}
}

contract B is A {
   function bFunction {
      aFunction();
   }
}

/*If you want to use an external contract, you need to define an
 *interface with the definition of the methods that you want to
 *use.
 */
contract InterfaceOfExternalContract {
   function functionExternalDefinition(uint param) external return (uint);

   function functionPublicDefinition(uint param) public return (uint);
}

contract ContractWichUsesTheExternalContract {
   address externalContractAddress = 0x...;
   InterfaceOfExternalContract externalContract = InterfaceOfExternalContract(externalContractAddress);

   function aFunction() {
      uint value = externalContract.functionExternalDefinition(1);
   }
}

And now, what are you starting to code?

Como empezar a programar apps distribuidas en Solidity para Ethereum

Podría parecer que para programar Dapps, las aplicaciones que corren sobre la máquina virtual de Ethereum, es necesario ser un experto en blockchain, saber de criptografía, entender cómo se calculan los hash de los bloques, entender cómo está implementado el Proof of Work, o incluso saber cómo se mina. Sin embargo, no hace falta profundizar tanto para echar a andar una aplicación distribuida, veamos por dónde se puede empezar.

learn photo

Para desarrollar Dapps, basta con conocer cómo funciona la Ethereum Virutal Machine, conocer las arquitecturas y patrones que se emplean y manejarse con alguno de los lenguajes pensados para tal fin. El más popular es Solidity, que está basado en javascript, aunque hay otros como LLL (que está basado en Lisp) o Serpent (basado en Python).

Para aprender a programar con Solidity se puede empezar por muchos sitios. Puedes empezar a dar vueltas por el Wiki de Ethereum, o ir directamente a la documentación oficial, aunque personalmente creo que es un poco tediosa y no va demasiado al grano. Otra opción es buscar un buen tutorial en el que te enseñen paso a paso, como Cryptozombies que te enseña a hacer desde cero un juego como el popular Cryptokitties.

Para aprender el lenguaje cualquiera de esas vías es válida. Sin embargo,  por desgracia, creo que es necesario pasar por todas esas documentaciones para tener conocimiento de los patrones más habituales y estar preparado para hacer cualquier tipo de aplicación, ya que si por ejemplo te quedas en ver cómo está hecho Cryptokitties, sólo conocerás aquellos que sirven para hacer un sistema de compraventa de bienes únicos.

Es cierto que esto puede llevar mucho tiempo, y si tienes prisa por empezar a programar, puedes buscar un curso para que alguien te guíe y te dé información concisa y bien estructurada. Recientemente he empezado a colaborar con DevAcademy, una academia que ofrece cursos de alto nivel para las tecnologías más punteras (DevOps, Machine Learning, Big Data, …) y, cómo no, entre ellos tiene un curso de Solidity. Es una buena alternativa para que te lo den todo mascado, y además, le puedes pedir a tu empresa que te lo pague ya que le saldrá gratis por ser formación bonificada. Si quieres saber más sobre este u otro de sus cursos, no dudes en ponerte en contacto conmigo y que podamos ver tus necesidades o las de tu empresa.

Intelgate: ¿qué ha pasado? ¿Cómo te afecta?

Hace unos días que nos encontramos con una sobredosis de noticias sobre el «caso de Intel», con gritos de alarma sobre lo malo que es y todo lo que nos va a perjudicar. Vamos a ver de un modo sencillo qué es lo que ha pasado y cómo nos afectará.

Meltdown photo
Photo by Kenneth Dagenais

¿Qué ha pasado?

Se han hecho públicos unos bugs que afectan a los procesadores (los chips principales de los ordenadores). En concreto, estos bugs se aprovechan del funcionamiento de los procesadores que como son muy rápidos, muy rápidos, a veces se inventan el código a ejecutar para ganar tiempo. Una aplicacion que se aprovechase de estos bugs, podría «incitar» al procesador a leer partes de memoria a la que no debería tener acceso.

Uno de ellos (Meltdown) afecta casi exclusivamente a procesadores Intel, y afecta a casi todos los procesadores de Intel de la última década. Este bug es una feature de estos procesadores, que resulta que es un poco insegura y que cuando se implementó, nadie se paró a pensar que se podría usar así. Este bug ya tiene un sistema que permite corregirlo, pero que afecta al rendimiento del procesador.

Los otros dos (Spectre) afectan a la mayoría de procesadores habituales, y al parecer va a ser más difícil de corregir.

Esto no es todo. La polémica, y el motivo de que se comparase con el caso de los diesel de Volkswagen, es la actitud de Intel en su tratamiento. Lo sabían desde hace tiempo y lo mantenían oculto. Además han seguido vendiendo y sacando nuevos modelos afectados por dichos bugs. El CEO vendió todas las acciones que pudo, aprovechándose de su conocimiento privilegiado. Además, tras hacerse público, se han dedicado a tirar balones fuera negando lo evidente y señalando a otras empresas con el dedo.

¿Cómo te afecta?

Suponiendo que eres un usuario normal, te afecta poco.

El parche que se empezó a distribuir, efectivamente afecta al rendimiento del procesador, pero afecta sólo en un caso muy concreto en el que las aplicaciones necesitan hacer llamadas especiales que controla el sistema operativo como por ejemplo leer un archivo. La mayoría de aplicaciones hacen esto de manera ocasional y esto, sumado a que casi todos los sistemas domésticos suelen tener el procesador infrautilizado, conlleva que apenas vayas a notar ningún cambio en el ordenador de tu casa.

Por tanto, los sistemas que se van a ver más penalizados son los dedicados a virtualización, bases de datos, etc. Principalmente los sistemas corporativos y entornos cloud, que suelen tener cargas más altas y sufren mayores cambios de contexto, serán los que se vean más afectados. Dicen que estos sistemas se harán entre un 5% y un 30% más lentos, y las pruebas que se han realizado con sistemas de este estilo así lo avalan.

Además de esto, Google anunció un modo de parchear los sistemas, que reduciría sustancialmente los problemas derivados de su aplicación, haciendo que lo que se ralenticen sea practicamente insignificante, pero habrá que ir viendo a medida que se vaya aplicando.

Resumen:

Se ha encontrado un problema histórico, que si se hubiese tratado con normalidad y explicado con sinceridad, no habría supuesto tanta alarma. Sin embargo, la negativa de Intel a afrontarlo, ha provocado un caos y una desinformación que les pasará factura más pronto que tarde.

 

APIs públicas para tus proyectos

Año nuevo: proyecto nuevo. Estoy seguro de que sois muchos los que estáis empezando un sideproject como propósito para el nuevo año. A la hora de elegir la mejor idea, si no queréis picar un montón de código, os vendrá bien saber que APIs tenéis disponibles para juntarlas, remezclarlas y sacar alguna funcionalidad chula.

API photo
Photo by abraham.williams

Es muy importante saber qué herramientas tienes disponibles, y es un conocimiento que además os puede venir muy bien para enfocar mejor esos momentos de desorden en el que vienen un montón de ideas a la cabeza.

Pero, no corráis a poneros a buscar en Google «API pública», por favor. Hay maneras de optimizar el tiempo para que todo lo que dediquéis sea de experimentación y absorción de conocimiento. Además, si optáis por la primera opción, es muy posible que os encontréis que cada una está definida y documentada como su padre y su madre han creído oportuno: puede ser una auténtica locura.

Hay gente que ya se ha encargado de juntar un montón de definiciones de APIs públicas, de tal modo que tu las tengas a mano y ordenadas. Además, así puedes acceder a todas de una misma forma y tener la documentación de una forma más estandarizada.

Para cacharrear con ellas puedes hacerlo como prefieras: desde la web; con un sdk para tu plataforma preferida; o incluso desde la línea de comandos. Sin embargo, si me pedís la recomendación más cómoda (aunque por el momento es la que menos APIs tiene disponibles) yo optaría por una colección para el postman, que es una extensión de Chrome que me tiene enamoradito desde hace años.

Ánimo, elegid vuestro sabor preferido y dadle vida a ese nuevo proyecto.

Minado de Ether: ¿Qué es? ¿Cómo se hace? ¿Es rentable?

Estamos viviendo un boom (o burbuja) de las cryptomonedas comparable a la de la fiebre del oro. Tiene algunas similitudes, ya que cualquiera se puede poner a minar y conseguir cryptomonedas «gratis». Veremos todos los detalles de esta práctica centrándonos en conseguir Ether, la cryptomoneda de Ethereum.

Ethereum es una plataforma que utiliza una arquitectura blockchain. En estas, como ya explicamos cuando hablamos de cryptojacking y de las diferencias entre Prueba de trabajo y Prueba de confianza (o interés), cada bloque guarda el hash del anterior como identificador único, y que al estar encadenados todos los bloques sea, en la práctica, imposible alterar los datos pasados. Para obtener ese hash hay que realizar muchos cálculos, por eso al propietario de la máquina que consigue obtenerlo en primer lugar, la plataforma le da una recompensa (actualmente 5 ETH).

Por tanto, es fácil, si tu quieres obtener Ether sin aflojar la cartera, tan sólo tienes que convertirte en minero poniendo tu ordenador a trabajar por ti. ¡Fa-ci-lí-si-mo!

Veamos, ¿cómo podemos poner a nuestro equipo a trabajar en ello?

Lo primero es obtener geth (Go Ethereum). Es la consola/aplicación de consola oficial. Si tienes instalado el Wallet de Ethereum o Mist, ya la tendrás instalada y configurada, ya que es por ejemplo la encargada de sincronizar tu sistema con toda la red de Ethereum para que tengas los mismos bloques que el resto.

Una vez montado sólo tienes que ejecutar el siguiente comando:


geth --etherbase '0xHashDeTuWallet' --mine

Ten en cuenta que si ya tenías geth configurado por tener el Wallet, te bastará solo con usar el argumento «–mine» porque ya tendrás establecido tu coinbase.

Otra opción que tienes es iniciarlo en modo consola y luego arrancar el miner:


geth console
...
>miner.start()

Yo prefiero esta modalidad ya que nos permite consultar nuestro hashrate y la dificultad de lo que ha costado conseguir el último bloque, con lo que podremos echar una estimación de cuanto tiempo tardaremos (estadísticamente) en conseguir cerrar uno de los bloques y llevarnos nosotros la recompensa:

Comprobación de tiempo para obtener un hash
Comprobación de tiempo para obtener un hash

Como se puede comprobar en la imagen, en mi máquina se tardarían más de 87.000 días en obtener un hash.

¿Está eso bien? ¿Qué ocurre aquí?

El comando geth no está preparado para usar GPUs, por lo que usa la CPU y por mucho que mi máquina sea un maquinón, mis 8 cores no están a la altura de ninguna GPU.

Para solucionarlo hay dos opciones sencillas: una es usar una implementación en C++ de la definición de Ethereum, la cual sí está preparada para usar GPUs pero que oficialmente no ha sido lanzada; la otra opción (y mi preferida por seguir usando el software verificado) es usar otra aplicación para las operaciones que se conecte a geth para que se encargue del resto.

Para esta última opción hay que poner a geth a escuchar:

geth --rpc --rpccorsdomain localhost

Y luego arrancar ethminer con la opción que queramos:

  • G usa las tarjetas que estén habilitadas para funcionar con OpenCL.

  • U usa las tarjetas que estén habilitadas para funcionar con CUDA.

  • X usa todas las tarjetas.

No vamos a entrar en grandes detalles, pero os contaré que en mi caso tengo dos tarjetas. La NVIDIA dedicada es CUDA y la Intel que usa memoria compartida es OpenCL. Podría parecer que lo mejor es usar la opción «-X» y poner todas a funcionar, pero es un error ya que los recursos del sistema son limitados y entonces se pelearán por ellos… este es un caso de en los que menos es más.

En mi equipo usando una tarjeta dedicada con 4GB se obtiene que estadísticamente tardaría aproximádamente 1500 días en obtener esos 5ETH. Seguro que algún ludópata ya está echando las cuentas, pero la verdad es que con el cambio de 626€ actual, esto supone que se estarían ganando unos 2€ al día. No está mal sin hacer nada ¿verdad? Pero hay que contar que el consumo eléctrico de la máquina (en mi caso) se duplica, que probablemente dentro de 1500 días no se pueda minar con la máquina que estés minando hoy, o que puede que 1ETH dentro de 4 años valga mucho más o mucho menos… Echad vuestras propias cuentas y decidid si vais a jugar o no, porque esto es una lotería y aunque puede que tengáis suerte, las probabilidades están en vuestra contra.

¿No hay ninguna opción de empezar a ganar dinero desde ya?

Sí, claro que la hay. Te puedes unir a un pool que en cierto modo te paga por cada hash prometedor que le mandas independientemente de que sea exitoso o no. Es como si repartiese las ganancias que se generan entre todos los que están trabajando con él.

Podéis estudiar que pool os da más. Yo usé ethermine.org y ponerlo en marcha es muy sencillo. Sólo tenéis que bajaros un programa, modificar el start.bat para establecer el servidor que os quede más cerca y vuestra cartera y echarlo a andar:

setx GPU_FORCE_64BIT_PTR 0
setx GPU_MAX_HEAP_SIZE 100
setx GPU_USE_SYNC_OBJECTS 1
setx GPU_MAX_ALLOC_PERCENT 100
setx GPU_SINGLE_ALLOC_PERCENT 100
EthDcrMiner64.exe -epool eu1.ethermine.org:4444 -ewal 0x4bf644b03a83a4e3f5534f81a3dd1e8b28b32076.Rig001 -epsw x

Mi primera experiencia con esto fue que tras tres horas había conseguido ganar 0.00026ETH que al cambio del momento eran unos 0.10€. Habrá quien diga que el valor en euros no vale, ya que mientras escribo estas líneas esa misma cantidad de Ether vale aproximadamente 0.16€, pero podemos verlo de otro modo: cuando pasé Ether que había comprado en Coinbase a mi cartera, el fee de la transacción fue de casi el doble de lo que saqué minando durante 3 horas.

Esto es lo que pasa con el Ether, pero con Bitcoin y otras cryptomonedas populares pasa más de lo mismo. Cada uno puede sacar sus propias conclusiones y sus propias cuentas, pero creo que a día de hoy, por mucha burbuja que haya, no vale la pena ponerse a minar cryptomoneda, a no ser que salga una nueva y os aventuréis a ser uno de los primeros mineros igual que aquellos que corrían de un lado a otro de California buscando la próxima veta.

Utilidades para trabajar en remoto

Por estas fechas, algunas empresas que tradicionalmente son más reacias a permitir el trabajo en remoto, reducen la presión y son más laxas con sus trabajadores. Si es vuestro caso y queréis demostrar que se puede trabajar igual o mejor, aquí tenéis unas herramientas que os pueden facilitar la vida:

Tool photo

Conferencias

En las empresas grandes se suelen usar los míticos Skype y Webex, aunque personalmente creo que Hangouts funciona muy bien de un modo muy sencillo. Sin embargo, no siempre vamos a tratar con gente que sepamos lo que tiene instalado, ni siquiera desde qué dispositivo se conectará. Para estos casos, mi recomendación es Appear.in la cual es de una sencillez brutal.

Grabación de vídeo

A veces una demo vale más que mil palabras. Si quieres grabar tu pantalla mientras explicas algo y no quieres estar pegándote con softwares complicados, mi recomendación es que uses Loom.

Control de tiempos

Medir lo que se tarda en hacer las cosas es una de mis obsesiones, como pueden dar fe las personas que han trabajado a mi cargo. Lo que no se mide no se puede mejorar y hay que intentar ser siempre mejores. Cómo medirlo es un tema complicado, puede que te valga simplemente una Google Sheet o puede que necesites algo más avanzado. En estos momentos yo estoy usando dos herramientas distintas: una que mide lo que hago de un modo pasivo (no tengo que interaccionar con ella para que mida), llamada ManicTime; y otra activa que sirve además para control de proyectos y clientes de un modo básico pero efectivo y se llama Toggl.

Con estas herramientas, estoy seguro de que vuestras jornadas de trabajo en remoto serán mucho más sencillas y productivas, y quién sabe, tal vez convenzáis a vuestros responsables para que os dejen ponerlo en práctica más a menudo.

Soy freelance, estos son mis servicios

Proyectos a medida, selección de personal IT, formación especializada, y horas sueltas para ayudarte con tus productos y la transformación digital de tu empresa.

Rubber

Como algunos ya os habéis percatado, ha habido cambios y no me refiero a los de la nueva portada de esta web o al cambio de mascotas quitando a Shi y a Sampi y poniendo a Rubberr, no. Me he hecho autónomo (otra vez) y toca explicaros qué servicios os ofrezco.

Los servicios principales son tres:

  1. Proyectos a medida. Cuéntame tus problemas y yo te diré como los podemos resolver con tecnología. Mi dilatada experiencia resolviendo problemas juntando unos y ceros durante la que he hecho aplicaciones de escritorio, web, móvil y otros dispositivos; diseñado grandes sistemas distribuidos; gestionado proyectos de principio a fin y mucho más en una gran variedad de negocios, me habilita para enfrentarme a cualquier cosa que esté complicando el trabajo en tu empresa. Todo tiene solución y yo la encontraré. No sólo te haré un presupuesto acorde a lo que necesitas, sino que me encargaré  de todo para que los imprevistos no supongan un fracaso y se resuelvan cuanto antes. De este modo podrás tener tu solución implantada en el tiempo que necesitas sin preocupaciones que te hagan perder el norte.
  2. Selección de personal técnico. A la mayoría de las PYMES les cuesta encontrar a personal técnico, y más si no son tecnológicas. Además las condiciones que ofrecen las consultoras de RRHH no suelen estar adaptadas a las necesidades de las PYMES. Por mi parte, he liderado el proceso de contratación de decenas de personas y he colaborado en la contratación de otras tantas. Si necesitas contratar algún perfil técnico y no encuentras a nadie o no sabes por dónde empezar, yo me encargaré de todo para darte a elegir entre algunos candidatos que se amolden a tu empresa. El coste de este servicio no es un porcentaje de su sueldo, ni algo que tengas que pagar a toca-teja, son 300€/mes durante 18 meses siempre y cuando esa persona siga siendo parte de tu plantilla.
  3. Formación. Es muy difícil mantener a tu equipo al día, que sepan de los últimos avances en inteligencia artificial, blockchain, frameworks, tecnologías cloud, arquitecturas distribuidas, o métodos de gestión (lean, scrum, kanban, …). Además los proyectos surgen cuando menos te lo esperas, por lo que necesitas que alguien que ya esté al día les ponga las pilas. Plantéame qué necesitas que aprendan, para que yo pueda montarte un programa de formación especializada a medida.

Pero esto no es todo, en el desarrollo de los productos de tu empresa o en el proceso de transformación digital que tu empresa está llevando a cabo (y si no es así, debería), necesitarás apoyo de alguien que sepa de tecnología para que colabore en labores muy diversas de asesoramiento y ejecución. Por esto puedes contratarme por horas a un precio que va desde los 75€ la hora suelta, hasta los 52.5€ (30% de descuento) cuando compras packs de más de 60h.

Si no estás seguro de que sea la persona adecuada te sugiero que le eches un vistazo a las recomendaciones que antiguos compañeros, subordinados, jefes y clientes me han dejado en LinkedIn y que puedes ver en el bocadillo que tendrás en la esquina inferior derecha de esta página; o, si lo prefieres puedes ponerte directamente en contacto conmigo para que charlemos un poco de lo que necesitas.

Así como Shi y Sampi tenían un significado para mi (que me guardaré para cuando tomemos una caña celebrando el éxito de alguna de nuestras colaboraciones), Rubber también tiene un significado, y es que en el mundo tecnológico los patos de goma siempre han estado ahí para ayudarnos a resolver los problemas. No lo pienses más, y déjame ayudar a tu empresa hasta que podáis volar sólo con la ayuda de unos patos.