La idea de este post surgió a raíz de la creación de nuestra primera red blockchain para pruebas.
Cuando nos planteamos su instalación no teníamos muy claro qué implicaba ni cuánto trabajo suponía, y, como casi todo lo que rodea a esta tecnología, parecía algo difuso y complejo. ¡Nada más lejos de la realidad! Por ello hemos pensado que podría ser de interés mostrar las distintas alternativas para la creación de una red blockchain basada en tecnología Ethereum, en este caso sobre infraestructura AWS.
Comencemos
Durante nuestro proyecto descubrimos que los servicios de AWS ofrecían 3 alternativas para el despliegue de redes blockchain:
- Templates
- BaaS (Blockchain as a service)
- Implantación a medida
- Templates
AWS dispone de unos templates o plantillas que permiten desplegar una red blockchain, bien basada en Ethereum o bien en Hyperledger Fabric, mediante CloudFormation en una instancia EC2 o en un clúster de ECS.
La parte negativa de esta solución era que estos templates no nos daban la flexibilidad que queríamos, puesto que no podíamos modificar algunos valores de configuración. Además, a día de hoy estas templates únicamente permiten el despliegue en USA, en las regiones de:
- Región EE.UU. Este (Norte de Virginia) (us-east-1)
- Región EE.UU. Este (Ohio) (us-east-2)
- Región EE.UU. Oeste (Oregón) (us-west-2)
Veámos qué podemos configurar a la hora de desplegar una red Ethereum siguiendo este template:
En primer lugar aparece una sección en la que podemos definir los parámetros que definirán el funcionamiento de nuestra red blockchain Ethereum, como el ID de la red, el precio del gas, el límite de gas en un bloque, dificultad de minado, la cuenta inicial con la que crearemos la red, etc.
Como hemos comentado anteriormente, podemos desplegar la red, bien en EC2 (VM) o ECS (Contenedores) y seleccionar el tipo de las instancias sobre las que desplegaremos, así como la configuración de la red privada virtual (crearemos una red virtual que constituya una sección aislada del resto de la nube de AWS):
Seguimos con configuraciones de seguridad para acceso a las máquina y configuraciones de nuestro clúster ECS:
Por último, podemos elegir si queremos desplegar un explorador de la red blockchain y un explorador de bloques.
En el caso de Hyperledger Fabric la configuración es similar:
Configuramos el nombre de red, el dominio, los subdominios de cada organización y la configuración de la red privada virtual sobre la que vamos a desplegar la red blockchain:
Como podéis ver no hay posibilidad de seleccionar o modificar muchos de los parámetros intrínsecos de este tipo de redes, por lo que aunque nos permite tener una red de pruebas en apenas unos minutos no nos aportan ni posibilidad de configurarla a nuestro gusto (si queremos algo distinto de los establecido por defecto en los templates) ni conocimiento sobre los procesos necesarios para configurar una red o un nodo.
- SaaS (BaaS)
Como segunda opción tenemos disponible una AMI de Kaleido para desplegar una blockchain bajo el modelo SaaS (o BaaS, blockchain as a service).
El problema de esta solución es que, a parte de tener un coste indeterminado por el empleo de la AMI, ya que va asociado al número de unidades (e inicialmente desconocíamos cuántas emplearíamos), no tenemos ni control sobre la instalación ni conocimiento del proceso de instalación de software ni despliegue / configuración de la red.
Nota: También existen AMIs para Hyperledger Sawtoothy R3 Corda pero en nuestro caso teníamos claro que queríamos empezar por desplegar una red Ethereum.
- Implantación a medida
Llegados a este punto estaba claro que ésta tenía que ser nuestra opción: crear una red desde cero que nos permitiera aprender y entender el proceso de instalación, y poder realizar la configuración que quisiéramos.
Aunque es la más manual de todas las alternativas, conlleva tener un mayor conocimiento técnico sobre conceptos de blockchain.
Por supuesto, en esta alternativa tenemos control total sobre la operaciones realizadas:
Es precisamente en este punto en el que vamos a centrar este artículo.
Como vamos a crear nuestra red con fines didácticos vamos a crear una red de únicamente 3 nodos. Estos nodos tendrán diferentes roles:
- bootnode.
- minero.
- nodo de trabajo.
Configuraremos un nodo como bootnode, que actuará como Discovery Service, y que permitirá al resto de nodos que creemos en la red agregarse automáticamente. Normalmente tendrá una IP fija y supone el punto al que el resto de nodos van a ir a preguntar por los demás nodos de la red.
El minero es un concepto asociado al protocolo PoW (Proof of Work), y que en nuestro caso no vamos a implementar ... Pero, ahora os preguntaréis, ¿y por qué no? ¿Entonces cómo va a funcionar?
La respuesta es sencilla: al ser una red privada, exclusivamente de test, y que va a estar bajo nuestro control, no tiene sentido emplear un algoritmo "pesado" (como PoW) y que requiera mucho trabajo de computación para generar cada bloque, que consuma más energía y cuya creación de bloques sea más lenta... En su lugar vamos a emplear PoA (Proof of Authority), y por tanto, siendo estrictos con la nomenclatura, nuestro nodo no será un minero sino que será un sealer o sellador.
Por último, crearemos un tercer nodo que usaremos como nodo de trabajo, y que será el nodo al que nos conectaremos para interactuar con el Smart Contract.
Bien, ¡empecemos!
El proceso es el siguiente:
Creamos las 3 máquinas (EC2) a la vez y con las mismas características. En nuestro caso máquinas t2.micro con volúmenes de 8Gb y SO Linux Amazon.
Lo más importante son las reglas de Inbound del Security Group que crearemos, ya que definen las conexiones entrantes que vamos a permitir a la red.
Generaremos reglas para:
Permitir acceso SSH desde una máquina para la administración de los nodos:
- Type: SSH
- Protocol: TCP
- Port Range: 22
- Source: XXX.XXX.XXX.XXX (IP de la máquina desde la que nos vamos a conectar)
- Description: SSH Administración
Permitir acceso RPC a los nodos:
- Type: Custom TCP Rule
- Protocol: TCP
- Port Range: 8545
- Source- Custom: XXX.XXX.XXX.XXX (IP desde la que nos vamos a conectar mediante una DApp o 0.0.0.0/0 si lo queremos abrir para que nos podamos conectar desde cualquier IP)
- Description: Comunicacion RPC desde clientes
Permitir comunicación entre los nodos:
- Type: Custom TCP Rule
- Protocol : TCP
- Port Range: 30303
- Source-Custom: XXX.XXX.XXX.XXX/XX (Máscara de red de la VPC donde se encuentran los nodos o 0.0.0.0/0 para probar)
- Description: Comunicación entre nodos
- Type: Custom UDP Rule
- Protocol : UDP
- Port Range: 30301-30303
- Source-Custom: XXX.XXX.XXX.XXX/XX (Máscara de red de la VPC donde se encuentran los nodos o 0.0.0.0/0 para probar)
- Description: Discovery
Y las etiquetamos como:
- Nodo1: bootnode
- Nodo2: worker
- Nodo3: sealer
Instalamos el mismo software en las 3 máquinas:
$ sudo yum install golang $ sudo yum install gmp-devel $ sudo yum install git $ git clone https://github.com/ethereum/go-ethereum $ cd go-ethereum/ $ make all
(En lugar de hacer un make geth, que instala únicamente el geth, hacemos un make all para tener disponibles todas las herramientas y poder ejecutar el bootnode. Podríamos hacer el make all solo en la máquina que actuará como bootnode, pero instalaremos a futuro otros servicios (fuera del ámbito de este artículo) para los que necesitamos otras herramientas)
Una vez instaladas las 3 máquinas, vamos al nodo sealer para crear una cuenta:
ls -al build/bin/get sudo ./build/bin/geth --datadir /var/data account new
Introducimos la password que queramos para la cuenta (por ejemplo demoATBlockchain) y se generará una cuenta con una dirección tipo {0cc43b47df98220ccc41e7f99038c34ce7af53d8}
Una vez creada la primera cuenta, vamos a crear el fichero Genesis de nuestra red. Para ello, ejecutamos el puppeth:
./build/bin/puppeth
Y rellenamos los parámetros que nos va pidiendo.
- Nombre de la red: atsistemaspoa (identificamos que es la red privada corporativa y que emplea el algoritmo PoA)
- Opción 2. Configure new genesis
- Opción 2. Consensus Engine: 2 PoA (Clique)
- Definimos el intervalo de creación de bloques: 2 sg.
- Añadimos la cuenta permitida para autorizar bloques (la creada al inicio).
- A continuación ponemos todas las cuentas creadas para definirlas con fondos establecidos. Al menos ponemos la creada al inicio y que es también ‘sealer’.
- Identificador de la red, por ejemplo 28231 (en nuestro caso usaremos el código postal)
Ahora exportamos el Genesis recién creado:
- Opción 2. Manage existing genesis
- Opción 2. Export genesis configuration
- Introducimos un nombre para el fichero json. En nuestro caso vamos a llamarlo atsistemaspoa.json para indicar que corresponde a nuestra red atsistemaspoa
Inicializamos la red:
sudo ./build/bin/geth --datadir /var/data init ./atsistemaspoa.json
A continuación copiamos el fichero Genesis de nuestra red (éste atsistemaspoa.json) a las otras dos máquinas (el bootnode y el worker).
Vamos a la máquina del bootnode e inicializamos el nodo usando este fichero Genesis:
sudo ./build/bin/geth --datadir /var/data init ./atsistemaspoa.json
Una vez inicializado el nodo, vamos a generar una key y a ponerle a trabajar como bootnode: ./build/bin/bootnode --genkey=boot.key ./build/bin/bootnode --nodekey=boot.key
En este paso obtendremos un enode, que nos servirá para identificar únivocamente el nodo en la red, y que usaremos para el arranque del resto de nodos:
Volvemos de nuevo al sealer y lo arrancamos como:
sudo ./build/bin/geth --cache=512 --datadir=/var/data --rpc --mine --unlock "0x6f8e48e12dc9de9d10d66767da323fae5e3991ef" --password "pass.txt" --bootnodes enode://b7240fede7b986b7bb72e0277c2a9f35621d3dfc1ba2897fdbdd220ef67a28440f035100f77b17dc43b332cbd0e68a8c867e8bffcfb375636c6a41b1723fa628@10.16.10.77:30301
(hemos colocado la password de la cuenta en el fichero pass.txt para evitar que la cuenta se bloquee periódicamente)
--cache: Tamaño de la memoria reservada para el proceso geth
--datadir: Directorio donde se almacenará toda la información publicada en la blockchain privada.
--rpc: Habilita el servidor HTTP-RPC para poder ejecutar comandos de manera remota en la blockchain.
--bootnode: Indica el nodo que actuará como discovery service, identificado a través del enode
Ahora vamos a la máquina del worker y arrancamos como:
sudo ./build/bin/geth --cache=512 --datadir=/var/data --rpc --bootnodes enode://b7240fede7b986b7bb72e0277c2a9f35621d3dfc1ba2897fdbdd220ef67a28440f035100f77b17dc43b332cbd0e68a8c867e8bffcfb375636c6a41b1723fa628@10.16.10.77:30301
Volvemos al nodo 1 (sealer) e inicializamos el nodo (para que se conecte al bootnode).
Metemos la pass de la cuenta en un fichero pass.txt:
sudo ./build/bin/geth --cache=512 --datadir=/var/data --rpc --mine --unlock "0x6f8e48e12dc9de9d10d66767da323fae5e3991ef" --password "pass.txt" --bootnodes enode://b7240fede7b986b7bb72e0277c2a9f35621d3dfc1ba2897fdbdd220ef67a28440f035100f77b17dc43b332cbd0e68a8c867e8bffcfb375636c6a41b1723fa628@10.16.10.77:30301
--mine: Activa el minado en el nodo
--unlock: Lista de cuentas (separadas por comas) a desbloquear
Por último, vamos a crear unos scripts para arrancar y parar los procesos de cada nodo. Os dejo un link a los scripts que ha generado mi compañero Ángel Martínez :
Por último arrancamos los servicios y podremos comprobar como nuestra red va minando:
Con esto ya tendríamos nuestra red de tres nodos creada y lista para empezar a trabajar, es decir, para desplegar Smart Contracts e interactuar con ellos.
Espero que el proceso os haya resultado tan interesante como nos resultó a nosotros y que hayamos podido aclarar algunos conceptos sobre las tan de moda redes blockchain.
¡Esto es todo amigos!
Si te ha gustado, ¡síguenos en Twitter!