TARDÍGRADOS

Ciencia en español -ʟᴀ ʀᴀᴢóɴ ᴇsᴛá ᴀʜí ғᴜᴇʀᴀ-

Archive for the ‘Bitcoin’ Category

STOCHASHES: ¿Qué es un hash estocástico, y para qué sirve?

Posted by Albert Zotkin en junio 1, 2020

Hola amigos de Tardígrados. Hoy me voy a inventar un nuevo concepto de hash, que podremos aplicar en el campo de la criptografía, y en el de las criptomonedas. Se trata del concepto de hash estocástico. En el mundo de las criptodivisas, estamos acostumbrados a trabajar como todo tipo de hashes, y demás cadenas y scripts de todo tipo. Pero. creo que lo que voy a definir a continuación no existe, como tal, en el mundo de la criptografía.
Podemos definir un hash estocástico como una función tal que tiene como input una cadena constante de N bytes, y cada vez que la aplicamos, genera una cadena casi-aleatoria de N bits. Decímos, casi-aleatoria, porque en realidad lo que cada byte del input de entrada define es una probabilidad. Al ser N bytes de entrada existirán N bits de salida, y cada uno de esos bits es generado de acuerdo a la probabilidad definida por su correspondiente byte de entrada. Eso significa, que cada vez que aplicamos la función, obtenemos una cadena de N bits distinta (aunque podría darse el improbable caso de que alguna cadena se repitiera), y estadisticamente se podría comprobar cómo para cualquier muestra, se cumple siempre la distribución definida en las probabilidades codificadas en los bytes de entrada. O sea, un hash estocástico de N bytes genera hashes estándar de N bits.

Pongamos un ejemplo: Definamos una función stochash256 que tomará 256 bytes como input, y “escupirá”, 256 bits de salida, cada vez que se ejecute. Para la realización de este proyecto, usaré la librería de node.js llamada bitcore-lib, la cual posee bonitas funciones y utilidades varias. Crearé un script en node.js para que podamos ver la idea, y cómo trabaja esa función, que he llamado stochash256.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
			Stochashes
*/
const bitcore = require('bitcore-lib');
const Random = bitcore.crypto.Random;

var stochash = Random.getRandomBuffer(256);
for(var i=0;i<100;i++){
		var hash = stochash256(stochash);
		console.log(hash.toString('hex'));
}

function stochash256(buffer){
	if(buffer.length !== 256) return null;
	var pt  = 0;
	var hash = []
	while(1){
			var byte = buffer.readUInt8(pt);
	 		var repunit = getRepunit(byte);
	 		var rnd = Random.getRandomBuffer(1).readUInt8(0);
	 		hash.push(repunit[rnd]);
	 pt++;
	 if(pt == buffer.length)break;
	}
	 var result = new bitcore.crypto.BN.fromString(hash.join(''),2);
	 return result.toBuffer();
}
function getRepunit(byte){
	
	const two = new bitcore.crypto.BN(2);
	const one = new bitcore.crypto.BN(1);
	var b = new bitcore.crypto.BN(byte);
	var repunit = two.pow(b);
	repunit = repunit.sub(one);
	return repunit.toString(2,256);
	
	
}
La librería bitcore-lib nos ofrece la función const Random = bitcore.crypto.Random, con la cual podemos generar buffers aleatorios de arbitraria longitud. En nuestro caso generamos uno de 256 bytes, para empezar

var stochash = Random.getRandomBuffer(256);
Una vez que tenemos ese buffer de 256 bytes aleatorios, con cada byte definiendo una probabilidad que será aplicada a su correspondiente bit de salida, generamos una muestra de 100 hashes estándar, aplicando la función stochash256 con el mismo buffer constante stochash. En seguida vemos, que uso una función auxiliar llamada getRepunit. ¿qué hace?. Crea un número repunit en base 2 según el valor del byte con el que estamos trabjando. Es decir, esa función getRepunit nos da un numero en base 2 (ceros y unos), que contiene tantos unos seguidos como especifica el valor del byte. rellenamos con ceros a la izquierda para completar hasta 256. Una vez que tenemos nuestro número repunit, solo hay que escoger al azar uno cualquiera de sus ceros y unos, para obtener así nuestro bit casi-aleatorio (estocástico). la idea de usar números repunit en base 2 como recurso para realizar la probabilidad definida en el valor del byte, se me ocurrió ayer mientras echaba una siestecilla de 2 horas 😛
Apliquemos nuestra función stochash256 para obtener una muestra de 100 hashes estándar de 256 bits cada uno, que expresaremos en base hexadecimal:
1. Primero generamos el buffer aleatorio de 256 bytes de entrada stochash. Y después aplicamos 100 veces stochash256, con ese stochash constante:
{
        "stochash": 
"4f92bc84fd5126a6a65f31bf33b5ad112644e7a55f22e134a4ccba1800323  						 fb1b2ac0d9c31c0b8001cd4edfb9447be44e9cf04987d0f5a26936b9463e1					 96ba76b38aa35068a1e960447d1850a20d8a10d9b723b9ba7178551f19988
3bcd41ec6f9c813135d585b173b1047dc98a23f83a84a3ce8fde269ed9f7d
bb2f5fa6a9f8f9395b8a4cb96961d50a752069800eb5ee75435138210d724						 20b751be5480042997f42c2966ffdfa117e68bc746fd98f27665853aff3cd						 081d9a1c2dd702e74982f50255c9afbfefe7e8a6158d1ed75258afd772e03  						 00cba1c8d3c76d7a969e90f7f3a8b61eb3cd649114e346a923ad32fe4b354
9d8f2e15d47d6ef8fed69570",
        "hashes": [
                "1b343045ce7898ea771ad17dcc1f9d23379190083f560403cdc3ea5d0c274cfd",
                "38d63263c67fdabeae5cda15cc121f21a4acf1289f13060bd5f3381745096bdc",
                "69142ae56c72d1a3d29a326d823d18bfa4b1a02ca35b4e4ac7c0290d0d311cff",
                "29b4ba65d4f9ce9cf242fc2dcc10dfe3a409c10cd766ac684fe3791b65076c7d",
                "78c232c0ce7489fd5609dd3d80bd9debff85c28ceba70c8acfe04989348348dc",
                "6a8682614e7280afc648cc1dc23e992d9ca8899d17413e49dd6a783b1500e0f8",
                "fb0833219e74c0bab2da982dc095dfe786a1f129db316c6ac5ead97f4fad783f",
                "7982e2c2b47b48b39a4acf1ec095996fb4a18c288b1a9e7a5fe9790d4d7954be",
                "f9542e21d07fc32b9beb9b76ce1dfbc78c88f52c975b460adee36d5f758d4cdc",
                "d89222e1f67ad26fd6d09db7cc11cfa7838081199f4b1e6a6fe37869192c509f",
                "ec927641c678506fa70ace2dc82cff83b2a18128db3724cacbcbb91d0d0574da",
                "ebbeb263c65ec068a6888c05c7979ffb848cf8809f22246ac9e269cd1d0de4be",
                "19d6bbc1d67ad828b30a413dc2159f639105b0e83f1a5e4259cafd2d410460be",
                "6d9c7ac5d052dba7d68a989de21ecd23b4a1400cfb72ae0acfe9e8431580745d",
                "fb5e7ae196b390fbf212de14c892cc67b590c0288f1f060aceea28491501689f",
                "e99073609e7ad0dff7628831843abfebb7809129d3610e4ad5e1394954206c9d",
                "6d1422e19672c01a86c8df2dc0559feb96a94088df3b2e08cfe6690d7d1554dd",
                "ecf602e3d272ca2eeb4ac82dc8349bbf90048008571f0e4a57eae95d0f055cde",
                "a99e32819e73d8b8a748d73dcc1e5dc3950890259b707e2a47c2fc5d5c8c443f",
                "edc26280b47bc09f2688fb258535dd8392a9800897274e4a5dc2f0ff49806afe",
                "39127a619e5bdaebb3d0f41d8018ddcfa6af8c08db3a66c3cbe370ed1d2be27e",
                "b8d62022d072cb8bc45ad325c1169fe134b4fc2893af3e4247eb615d150864df",
                "69567a6150628aadb61ad80fca0dfda7d5a5e08877758e0bddeacd5d718a7cfe",
                "edd7baf0c23b92fd8a2cd81dc02d1d25c0a9d98817be6e8a49e2f00d548c62fe",
                "39ac72e1e472c2eb7618de3dc087de6f9ce1c1b8bbc17c4a47e3391dd50d488f",
                "bb943ee4d678d29e2fdad82dd01f1da7e599880d1b081c0b4fca790f5c0154fe",
                "699a3a7144761b3e6e48de8dc6399de5d6acc029931d2e5ac3c2e90b0db56cfe",
                "5a903260d4fac84af740f219c01f1de5b4b5c0016f16dec2c9e6e84f5509ccde",
                "2f823ac38670d1cf0642940dcb591ca5b60d81a8ff5d2e3b4fc2691d0b016c9a",
                "580622e15673d37e339ce4bcc0341d6b8ca1a0091b0f4e62c08a044c2d356cba",
                "399732e31672da9ae748f83dc011dd659581c12893443e2a4feae94916356e5b",
                "7c96fa40d678ca5b63dac7358e1cbda790a0c1089b171e9bc5caed7d1d05629a",
                "2b9678e1f67ad8defec8982988959d4fa9e1b8289b5a5e4a5bca391c678d60de",
                "385e3b66de7ad02f2658c125c0523d239ca5c129db8c1e41dfa2e1cd6c04acbd",
                "ef9738e74077c9ee965a8885c895dda394a08518c3260c7adff3e94d1681d85d",
                "789622a0543adc0cf6cac3b8c29d9d27bca9e4083f6f170b47faf97d45246e1e",
                "28163ac5027bda3e1648dc34d891bd7b9e81a808bb53064acfe6397957847cde",
                "d91e62c1d6d39064b282c96340188d8f848c91285f1e0e0a5de2ecdd25814c9c",
                "29dc76c21676d0583750c016ca2cbda5d388e908936ac65acfe9785d0d21e81e",
                "29b27a60c67e92ff3e52c51ec01d9d87ada1812cf7557e4bdbcb71090f916cde",
                "7e843aa18072d0decb0acb19c28e1dbff68dc23053262e5acbc2f95d1555709e",
                "3e0620831672c0ae8e42de05c2961e83d4819029df7746cac9eaf94b5fc57a9f",
                "3f9432c144b7daeffa48d82542149daf878ca080df5f1e4acfa23949661168ac",
                "2c8422f0d67ec0acdf48d02fc4f29ba3dc8488295f4e2e0ac9c2694317056cde",
                "8f323f61c672c0b6be68c044c4119f27d18dd00c97364c4ad9ee294b4d11629e",
                "58d63aa14e72c0a8ae50f83dca3d1b2fd381a1688f424e1aceea3de74723c499",
                "f9572ee0de7ad0edee62db2dcb141b6f84bda0889b124ecadfe3d8ff07a17c99",
                "7dd67ae1c6b896cfc64a9034c19d9dc79425d108db380e5b41ca797d050cc8df",
                "98fa2241867a0a3e2f4ab635c0144dcb8181810891507e4ac8e25d4d1d4d2cd5",
                "7814b6e5c6509299d7125b0dc02d3d579f899008db37064bc3c76959472652fe",
                "791836e3567eda6a8688dd68c0113de39e80882903121e5a4fe2d9595f27649a",
                "79d023a6ce77d88ce740e20dc817defba089842c9b740e0acdea7d6f3510619e",
                "78da32a2de70d29c265a9a7dca15dde5db88a519d7350f424bc8291c07216c7e",
                "382236e0447bc00cea98f805d4159ee7b08991a0b3d94a1a4ffab90d5d17469f",
                "ac987bc16670d2eca2884a25c33eff8b97240128fb6f0e9b57c21f1d450468dd",
                "f91263014c72c2a38652de3d821c9f6f8089e90147070e1a45cbb90fd50102df",
                "39c61aa0d21281387682d1adc81d7f25e3a581a8c17a4e1acde2694d0d04629a",
                "e9d622e3c67458bdc298d90ce0913de39e85e808df4e0e237be3793d260548ad",
                "6d9262e09673ca492a185919c5989d0df62dc0a94f1bae4b4fe039791f05609c",
                "49866260e47cc028ab51ce0bc2189fa19c8de1b997eb4e4acbc67859450d401b",
                "399e2ee6dc7b9820e742c811d9359da9b49508081f9f2e4a4fe3e967d7217cbc",
                "5db773e5de7b99ea8321dc1cc21fddabe48c942093c72e0a5de3b84d75016cbe",
                "79f2b220d27a407aa6b8da0cc035dd75bca49b085f5a4e8adfebc84914897cde",
                "1d0632679672c04e2c01c83dd91cd90586b0802cd6680e2ac6c0a12b070164fc",
                "7987326544f0d14d9218170dc0101daf920bb1259357c44a4be0195915096d5d",
                "191e7061e4fd90ac7b18da2dc4159ca1a084b0b843579e4ac9c0690d1c03089f",
                "e99232e4c47cd8ecc648ca04cc059d2385a909195717764ad9ea7c5b0b0165ff",
                "bc9c92c1467ad00fea1a8804848c9fe79d29c8281b3aa608dd8b780f6d3c6c9e",
                "7cba70c1d673d08f6e48c13482309be399a5c90d9f0e8e4b4f6b698d1d25609c",
                "6d123aa3d6f9c0ab060ad5a3c69c99e5a4808038533a641bd3ee617904014cde",
                "991e30e18679d00e645afa95d714fbaf960989807b560e4bcbf0795d0715681f",
                "798623c20e72dcb0bf42da1dc89c9fc39ea58019937f0e4b4fe3b81d5d016a9e",
                "9e162a4100f8c82e56089b7dc81e9fefad359689d37f064bcfe9294445017c5e",
                "49c630c2c270d2db6e08d929c65fdfebbda0900c0b5f8e434fc2e81d160061dd",
                "883637e1063fda18ea02d61de019df8f9f8f99a89f04ce025fc1213e0c2d68b8",
                "c9163ac1d67bc2bba75288bdc6139f39900984b95f5aae43dfea294f3d1d7c8d",
                "28dc3ae1d673c0673a5ad83dc0a11f2794a589a87f38cc0adfc261099f03749d",
                "089c6af1867ac85bef009c0fc0019fe39b84c4e9e3324e4b4f4a785d412de09f",
                "19de32e1107fc83512489315ce1ddd879081c0008f135e8a8fda617b5d85e8de",
                "e8902a83c673d00ae6085035828e3ba39e81f008335b444ac7e2b95d922964dd",
                "98bc6ae1527288b8c248d83bc21359cf80098c04975f3e0ac7ffe84e95036edc",
                "2d5216f55672d8fec20adaacc61fbc3185a0a0189b557c0addc27f3b778de29d",
                "588f3660d472c82e7a88d23dc841dd87b68580a83f0b5e4b43a9ed1f441d60df",
                "399032f3de72c8dbe702882dc890ddef99a9a82c97388e0bcb68f95f5d0f69d1",
                "79537ae1467adb9aae9ad4b5c21d1f7f9589c00c93222e4a57e2fb7975cde0de",
                "65de0ae18233c0e1aac9d20dcc151def9480a048d3124e4acfcb295d55c47ebe",
                "5d36ba255e72d08bd658ec0dc01c1dff34a9c108137b2e4a4bea7919040d54fe",
                "48c062a4d6b2c2be8512a00f881f9fe58724a0089b3a0ecacfcbb91f050d3edd",
                "691712c1dcba01ab034c4e3d865cdf859b8991b89f3b2e4ac9e2282f4d0d7cbe",
                "2dd63082c672d186ee40d829c41abf85d921d128bf071ec9c9c968015d217edf",
                "799232e1f47fc05db6c8d63dca149de185e5c1a9475deec05be9b899c505fc9c",
                "0bb036a41e7bd83af60a98bdc094c9a5a72dc02c5b3b0b4a0fe6790b4391681f",
                "7b1402e5c27b88ae7b0ad84cc71b5d9786a48000933a1e624fc8285f5d8776b4",
                "b93612c11276d89f9418583cc4599d27dc818128bb32ee4bcda2211f578178dc",
                "39166a41467cd2aeffe8d93dc00e5fefa9888118935a6614cdc8e04d54a94898",
                "387130e1d67b90e72208de2cc03fbfcf86bdc02c53530e085fe0391b15305e1f",
                "3d1632c154729abf83c8d82d881b1dc78ea5a0091f1e960ac7ec611e151564dd",
                "4f467600c21bc2ce890a5c2dc21d5fafa5a1c1a99b5a66db5bea79df45206cdd",
                "5c963a62c470d8ce4e00d62dc61e0f2e8635082853364e4a5fe2780f4565e4fd",
                "599632e1d67298bf4a1adc1082959d2da6ad802dd75a460a4deadd0c5516409f"
        ]
}

se puede comprobar fácilmente como la muestra de hashes cae toda dentro de una distribución normal, según las probabilidades definidas en cada byte de stochash. Los stochashes nos servirán para optimizar la velocidad de resolución de bloques en minería de bitcoins u otras criptodivisas. Pero, ese es otro capítulo.

Saludos estocásticos a todos.

Posted in Bitcoin, criptografía, Criptomonedas | Etiquetado: , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment »

Iconos para bloques en la blockchain de bitcoin

Posted by Albert Zotkin en febrero 27, 2020

Ayer, mientras ganaba algunos miles de euros minando bitcoins, se me ocurrió una idea gráfica, para identificar mediante una imagen a cada uno de los bloques en la blockchain.
Como cada bloque posee tres hashes principales de 32 bytes cada uno: el hash propio del bloque, el del bloque inmediato anterior, y el de la raíz del árbol Merkle de las transacciones., se me ocurrió lo siguiente: cada dígito de cada uno de esos tres hashes podría ser un código de color de una terna RGB, rojo, verde y azul, para cada pixel de la imagen. Pongamos un ejemplo. Elijamos el Bloque Génesis, es decir, el primer bloque de bitcoin que fue minado por el propio Satoshi Nakamoto. El objeto JSON de este histórico bloque es:

{
        "0": {
                "hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
                "version": 1,
                "previous_block": "0000000000000000000000000000000000000000000000000000000000000000",
                "merkle_root": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
                "time": 1231006505,
                "bits": 486604799,
                "fee": "0.00000000",
                "nonce": 2083236893,
                "n_tx": 1,
                "size": 285,
                "block_index": 0,
                "main_chain": true,
                "height": 0,
                "received_time": null,
                "relayed_by": null,
                "transactions": [
                        {
                                "double_spend": false,
                                "block_height": null,
                                "time": 1231006505,
                                "lock_time": 0,
                                "relayed_by": "0.0.0.0",
                                "hash": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
                                "tx_index": 0,
                                "version": 1,
                                "size": 204,
                                "inputs": [
                                        {
                                                "sequence": 4294967295,
                                                "script_sig": "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73",
                                                "coinbase": true
                                        }
                                ],
                                "outputs": [
                                        {
                                                "n": 0,
                                                "value": "50.00000000",
                                                "address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
                                                "tx_index": 0,
                                                "script": "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac",
                                                "spent": false
                                        }
                                ]
                        }
                ]
        }
}
Por lo tanto vemos que los tres hashes principales son:

                "hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
                "previous_block": "0000000000000000000000000000000000000000000000000000000000000000",
                "merkle_root": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
los cuales son números de 64 dígitos en base hexadecimal, es decir, 32 bytes cada uno. Podemos diseñar una imagen en formato PNG de 64 x 64 pixels. Para ello vamos seleccionado ternas de dígitos para componer el RGB de cada pixel. Así tendremos que el primer pixel de nuestra imagen (posición superior izquierda será el RGB(4,0,0), porque 4 es el primer dígito en el hash de la Merkle root, y 0 para los otros dos. El siguiente pixel sería RGB(a,0,0), y los cuatro siguientes son RGB(5,0,0), RGB(e,0,0), RGB(1,0,0). Pero como esos dígitos son hexadecimales, sólo van desde el 0 al 15, en lugar de ir del 0 al 255, lo cual produciría un color bastante oscuro. Por lo tanto, le vamos a dar brillo a cada pixel duplicando cada componente RGB hasta completar el byte, es decir, sería como multiplicar por 17 cada componente (dígito hexadecimal). Así nuestros pixeles, con brillo serían: RGB(44,0,0), RGB(aa,0,0), RGB(55,0,0), RGB(ee,0,0), RGB(11,0,0), y el ultimo pixel de la imagen PNG sería el RGB(bb, 0, ff). Es decir, nuestra imagen PNG para el Bloque Génesis sería esta:

ID imagen del Bloque Génesis de Satoshi Nakamoto

O sea, podemos crear la imagen dinámicamente mediante lenguaje PHP, creando una función que tome como argumentos esos tres hashes del bloque en un array. Yo escribí el código para una función que haga eso. Esa función es la siguiente:

function ImageFromHash3($hash){
if(strlen($hash[0])!=64 && strlen($hash[1])!=64 && strlen($hash[2])!=64) return '';
// Create a 64 x 64 image
$image = imagecreatetruecolor(64, 64);
$n=0;
$r = str_split($hash[0],1);
$g = str_split($hash[1],1);
$b = str_split($hash[2],1);
				
for ($y = 0; $y < 64; $y+=8){
for ($x = 0; $x < 64; $x+=8) {						
imagefilledrectangle($image, $x, $y, $x+8, $y+8, 
imagecolorallocate($image, hexdec($r[$n])*17, hexdec($g[$n])*17, hexdec($b[$n])*17 ));			   		
$n ++;			
}				 
ob_start();
imagepng($image);
$im = ob_get_contents();
ob_end_clean();
imagedestroy($image);
return '<img src="data:image/png;base64,'.base64_encode($im).'" />';					
}
Y así, la podemos presentar en nuestra página web. Pongamos un ejemplo más. El ultimo bloque validado por la minería de bitcoin, hasta la fecha, tiene una altura de 619122 (la altura n de un bloque significa el orden, o sea, que existen n bloques antes que él en la blockchain). Este bloque de fecha 26/2/2020 22:16:32, posee los siguientes tres hashes:

                "hash": "0000000000000000001159ec899185ec8f056b7655bf7898fef186454efde94f",
                "previous_block": "00000000000000000008e901529a41ef9350ff42166c8abeea80f6e708a46463",
                "merkle_root": "1adeb8334f75e32a335b19005871b2be3ac5555c661ce17b81131b0c43579a61",

y ha sido minado por la pool ViaBTC. La imagen generada con nuestra función sería esta:

ID imagen del bloque con altura = 619122

Como vemos la imagen ha sido creada dinámicamente en formato PNG con el lenguaje de programación PHP, y los bytes del rawdata de la imagen están codificados en base64, mediante la función base64_encode. Y el rawdata está en la variable $im. Es decir:

data:image/png;base64,iVBORw0KGg
oAAAANSUhEUgAAAEAAAABACAIAAAAlC+
aJAAAACXBIWXMAAA7EAAAOxAGVKw4bAA
ABWklEQVRoge2awY2DMBRE8SoNeEvwlk
ALUAKUACUkJUAJSwlQApSwtOASQgnZBm
YOOU0szTsOlqOnL32bH0KsML8kr0nO9j
nfzDeSM77eXP9xWECNBdRYQE1oyIOd5A
+SZ5Kz86Ql+UXyieTFV8ACaiygxgJqAr
vfMxK5+Q+kUfcDPmmmDefj2OGNIj5piq
+ABdRYQI0F1NxShxt4feJ+f93xRn3Ebw
prj0+a8Txgvj/xOVCTwVPxFbCAGguosY
CaWyaDoS4PME9HgHnecP9eXvgeX1d4/6
WdYX7PeGJUfAUsoMYCaiygJgyRzGFIvJ
H+vZP5Tzrwe8JPIvOliPOm9jnwmVhAjQ
XUFC8QpucLPpgP8o9txn06Pb7x8hceJK
0jfk9oJ5z/zfh3i6+ABdRYQI0F1ISmwv
f4a1phnsg9Pi24f7P1MeMvRI+E8+3EXz
AVXwELqLGAGguo+Qen00MzJKmE8gAAAA
BJRU5ErkJggg==
Saludos, me siento como bloqueado ya 😛

Posted in Bitcoin, Criptomonedas, informática, Matemáticas | Etiquetado: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment »

Minería de bitcoins explicada con lápiz y papel

Posted by Albert Zotkin en enero 30, 2020

Hola amigos de tardígrados. Hoy vamos a aprender a hacernos ricos en poco tiempo 🙂 En este pequeño tutorial aprenderemos cómo minar bitcoins desde cero, burlando así a las grandes granjas chinas de minería de criptomonedas.

Quizás yo no sea muy bueno en muchas cosas, pero con los años aprendí a conocerme a mi mismo bien, y descubrí que tengo ciertos talentos ocultos. Una de esas destrezas, que tenía oculta, es que soy capaz de adivinar cualquier contraseña en menos de un minuto sólo con el poder de mi mente 😛 ¿No te lo crees?. Mándame una dirección de correo electrónico tuya, y verás en tu sección de correos enviados, cómo, en poco tiempo (dependiendo del número de solicitudes de incrédulos), “me habrás enviado” un correo electrónico a albertzotkin@yahoo.com, en el que me dirás lo siguiente: “Esto prueba que sé tu contraseña y usé tu dirección de correo para enviarme esto”. Sí, amigo de Tardígrados, yo soy un superhéroe los días pares, y los impares un villano. A parte de esa destreza de adivinar mentalmente contraseñas, la cual resulta bastante sorprendente, teniendo en cuanto que soy un humano, también tengo otras cualidades ocultas, más sorprendentes aún que esa, si cabe, pero no te las voy a decir de momento, para que sigan siendo ocultas.

Hoy en día existen muchas criptomonedas, la mayoria están basadas en la tecnología del blockchain. Hasta la tostadora IoT que tengo en mi casa sería capaz de crear una criptomoneda. Sólo hay que ver que hasta Nicolás Maduro fue capaz de crear la criptomoneda Petro, con eso está dicho todo.

En este pequeño artículo que estoy escribiendo, me voy a centrar solo en el bitcoin. Hoy en día es posible comprar y vender bitcoins fácilmente, con lo que tú solito puedes llegar a enriquecerte, o a arruinarte a placer, especulando con esa moneda electrónica tan volátil. Las ventajas que tiene el bitcoin y otras monedas electrónicas, son que es un sistema descentralizado, y puede escapar fácilmente del fisco, pero a cambio, estás a expensas de fraudes, robos, y demás actividades encaminadas por terceros a dejarte sin dinero en tu billetera a cambio de nada más que disgustos. Pero, como vamos a partir de cero, es decir, de cero euros, nuestro disgusto de que nos roben cero euros sería menos del que sufriríamos si partiéramos de nuestros ahorros de toda la vida, o del dinero de la cesta de la compra.

Pero vayamos ya sin más tardar, al ajo. Para poder hacernos ricos con el bitcoin, lo primero que tenemos que hacer es conseguir una billetera (no digo monedero, porque hay ciertas personas con ciertos apellidos que me caen mal). Para ganar nuestro primer bitcoin, que a día de hoy esta a 8212.96 € en el mercado cambiario, tendremos nuestra billetera preparada para recibir moneditas calenticas recién minadas. La mejor billetera que puedes conseguir es la electrum. Una vez que hayas creado tu billetera de bitcoin electrum, guardarás tus claves offline, fuera del sistema, para que nadie que no seas tú, pueda hacerse con ellas y desplumarte. La electrum crea una clave muy peculiar, desde la que puedes acceder a tu billetera desde cualquier parte que posea conexión a internet, o con una única contraseña si la usas localmente desde tu dispositivo habitual. Dicha clave consiste en una secuencia ordenada de 12 palabras. Esa secuencia ordenada la puede memorizar, o la puedes guardar donde te plazca, pero siempre fuera del alcance de curiosos. Yo, por ejemplo, la clave de mi billetera electrum la tengo memorizada, pero también me hice un pictograma con esas 12 palabras de mi clave, porque a veces mi memoria me falla. El pictograma mnemotécnico de mi clave electrum, donde guardo algunos bitcoins, es este:

Si sientes el deseo que robarme mis criptomonedas, sólo tienes que adivinar a qué palabra corresponde cada uno de esos iconos, y voila!. Pero, si lo que deseas es enviarme algunos Satoshis, puedes hacerlo a mi clave publica:

un Satoshi es la cien millonésima parte de un bitcoin = 0.00000001 BTC. O sea que si un bitcoin se cambia actualmente por 8212.96 €, entonces 1 euro serían 12175.87 Satoshis. Lo de comprar y vender bitcoins, o con bitcoins, no tiene mayor misterio. Como habrás comprobado ya, incluso a la hora de recibir o enviar bitcoins con electrum, lo podemos hacer mediante los famosos códigos QR desde nuestros teléfonos móviles. Entonces, te estarás preguntando, cómo y cuándo vamos a empezar ya de una vez a ganar nuestros miles de Satoshis. La respuesta está en la minería de bitcoins.

La minería de bitcoins es una actividad mediante la cual van agrupando las nuevas transacciones en bloques, y estos bloques se unen a la gran cadena de bloques o blockchain. Los mineros usan potentes maquinaria de hardware a gran escala, para conseguir algún provecho, de lo contrario, esa actividad no sería rentable. Los mineros se comunican unos con otros mediante una red de nodos P2P, peer-to-peer. Usualmente lo hacen con el protocolo TCP estándar, el de los servidores web, pero no por el puerto 80 habitual, sino por los puertos 8333 o el 8332. Estos mineros de criptomonedas usan factorías llenas de cientos de procesadores fabricados y dedicados expresamente a realizar una única y sencilla operación matemática, pero han de hacerlo a gran velocidad para tener algo de probabilidad de encontrar la solución en un tiempo razonable para la rentabilidad económica. El problema con esos dispositivos es que, cada uno de ellos, es un monstruito muy ruidoso, bastante tragón de energía eléctrica, y se calienta bastante. Si juntamos en una nave industrial cientos de esos monstruitos computando a la vez sin parar las 24 horas del día, lo que obtenemos es una actividad super contaminante de ruido y calor, con energía desaprovechada por un tubo. La factura de la luz de un sólo día puede llegar a alcanzar miles de euros. La recompensa por resolver un bloque de transacciones de bitcoins es de algunas monedas, suficiente para conseguir rentabilidad.

¿En qué consiste esa sencilla operación matemática que tienen que realizar a toda velocidad esos procesadores para conseguir hacer negocio?. La solución de esa rutina operacional se llama Prueba de Trabajo. Los mineros, recolectan un conjunto de últimas transacciones del día, que están por ser confirmadas (validadas), y con ese conjunto de transacciones construyen un proyecto de bloque para ser añadido e integrado en la cadena blockchain. Junto a esas transacciones redactan la suya propia (transacción coinbase) para ganar la recompensa en el momento de dar con la solución, y todo irá incluido en el mismo proyecto de bloque. Pongamos un ejemplo concreto. Hace unos momentos, a las 17:55 de la tarde (hora de Benidorm 🙂 ), unos mineros chinos del pool AntPool han conseguido cuadrar (resolver) un nuevo bloque. Exactamente uno con el hash = 000000000000000000044b6c80648ead63c9ab7cad89f7841d6c1a420d34ba43. ¿Que qué es un hash?. Un hash es simplemente algo muy parecido a la huella de una cadena de caracteres. Existe una función hash256 que se aplica, para nuestro caso concreto, dos veces (iteración) sobre una cadena de 80 caracteres, correspondiente a la cabecera del bloque proyecto que proponen los mineros. Este bloque hallado es el número 614930 dentro del blockchain. Estos mineros chinos, en su granja con sus miles de “gallinas cibernéticas”, cacareando calientes sin parar, han puesto un huevo, por el que se están llevando al bolsillo 12.5 bitcoins, más una comisión de 0.2, es decir, un total de 12.7 bitcoins = 104304.6 euros (y eso lo hacen cada día, unas cuantas veces). La cabecera de 80 bytes, codificada en binario, de ese bloque es la siguiente:

0000000h : 00 00 00 20 9d 88 e1 40 67 f7 f0 10 db 58 5a 2f ; ... ...@g....XZ/ 0000010h : d7 28 bb c2 d8 1e e3 09 64 b7 0b 00 00 00 00 00 ; .(......d....... 0000020h : 00 00 00 00 82 e4 1c d2 3e c9 9f 27 d0 66 27 99 ; ........>..'.f'. 0000030h : c0 cc 88 11 35 1e 33 ed d0 33 6c bd 3c b5 11 79 ; ....5.3..3l.<..y 0000040h : 68 a5 e4 5e 9b 67 30 5e ff 32 12 17 74 c7 f9 01 ; h..^.g0^.2..t...
Si desglosamos la estructura de esa cabecera de 80 bytes, veremos qué parámetros la forman:

$version = 536870912
$previous_block = 0000000000000000000bb76409e31ed8c2bb28d72f5a58db10f0f76740e1889d
$merkle_root = 5ee4a5687911b53cbd6c33d0ed331e351188ccc0992766d0279fc93ed21ce482
$time = 1580230555
$nbits = 387068671
$nonce = 33146740

Si ahora aplicamos la función hash256 dos veces sobre la cadena en binario de esos 80 bytes de la cabecera, obtenemos lo siguiente:
hash256(hash256(cabecera))= 000000000000000000044b6c80648ead63c9ab7cad89f7841d6c1a420d34ba43
que coincide exactamente con el hash del bloque encontrado por los mineros del Antpool. Esto significa que hemos comprobado por nosotros mismos que ese block es válido. Ya de entrada, notamos algo raro en el hash de ese bloque. Los hash256 son todos cadenas alfanuméricas (aparentemente aleatorias, porque no hay manera de saber a qué cadena de caracteres corresponde un hash determinado) de exactamente 64 caracteres, o lo que es lo mismo, de 32 bytes (independientemente del número de caracteres de la cadena sobre la que se aplica). En realidad, vemos que todo hash es un número expresado en base hexadecimal. Lo raro que notamos, es pues que existan tantos ceros seguidos a la izquierda de ese hash, de hecho es muy raro que un hash256 empiece siquiera por un único cero. En realidad, esa rareza de muchos ceros al inicio del hash es precisamente lo que se busca con tanta codicia por los mineros. Los dos parámetros clave para los mineros son el nbits y el nonce. Este ultimo es un valor que el minero está autorizado a cambiar, para ir probando hasta hallar un hash que tenga muchos ceros al inicio y que cumpla una condición. La condición la dicta el parámetro nbits. Mediante una sencilla operación el nbits se transforma en un número en base hexadecimal llamado target. Para el caso concreto del ejemplo de bloque que estamos analizando, como nbits = 387068671, el target, con esa sencilla operación, resultará ser

target=1232ff0000000000000000000000000000000000000000
Como tanto el hash del bloque como el target son números enteros (expresados en base hexadecimal, pero números), la condición, que exige Prueba de Trabajo es una simple pregunta: ¿Es el hash del bloque menor que el target?. Para contestar afirmativamente a esa pregunta los mineros empiezan a calcular el doble hash256 de la cabecera, desde nonce = 0. Y la palabra Bingo! suena bien alto en la sala cuando se halla un hash que es menor que el target.

En nuestro caso, para un nonce = 0, obtendríamos un doble hash256 de:
hash256(hash256(cabecera))= a625bbfaf77163b53d1e30c30e8d01a7b0e00fb396b08f475d1c3eda7ecaf133
Es fácil ver que ese hash es mayor que el target. Por lo tanto, un bloque con ese nonce = 0 no sería un bloque válido. Es imposible saber qué valor de nonce cumpliría la condición. En nuestro ejemplo el nonce = 33146740 hace que se cumpla la condición, y por la tanto el bloque queda validado.Todo es puro azar, una lotería, vamos. Cuanto más juegues a la lotería más probabilidad tienes de que te toque. En eso consiste la minería de criptomonedas, con trastos ASIC, tragando hashes a velocidades endiabladas. Ludopatía pura y dura.

La velocidad de los procesadores mineros debe ser muy alta si quieren conseguir rentabilidad. Actualmente se usan en las granjas de minería de bitcoins esos chips tipo ASIC. En cada granja puede haber instalados cientos de esos ruidosos aparatos. Compremos uno de esos aparatos y pongámonos a minar bitcoins por nuestra cuenta. Podemos adquirir uno baratito por 100 euros, el AntMiner S7

Este aparatito tiene una velocidad de cálculo de 4.73 TH/s, es decir, 4.73 x 1012 hashes por segundo, pero chupa electricidad por un tubo, ya que consume con una potencia eléctrica de 1210 vatios. Teniendo en cuenta que en España el precio del kilovatio-hora es aproximadamente de unos 0.13 euros, ese aparatito, por sí solo, durante 1 día consume 29040 kilovatios-hora, es decir, un coste por día de 3.7 euros.

¿Cuál es la probabilidad de que a la primera obtengamos un doble hash256 que cumpla esa condición de ser menor que el parámetro target?. Es como tirar un dado y ver si obtenemos un 6 a la primera tirada, pero en el caso de los hashes existirían muchos más lados que los seis de un dado normal. ¿Cuántos exactamente?. El máximo número entero de 64 cifras en representación de base hexadecimal es este:

\displaystyle  m = \text{ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff},

y si lo expresamos en base decimal obtendremos el número de 81 cifras

\displaystyle  n = 115792089237316195423570985008687907853269984665640564039457584007913129639935.

Esto significa que el número de caras de ese supuesto dado gigantesto sería de n+1. El target que se usó en el hallazgo de la solución para ese bloque era, como he dicho antes,

\displaystyle  \text{target}=1232\text{ff}0000000000000000000000000000000000000000,

que expresado en base decimal es

\displaystyle  \text{target}_{10}= 1743137387349479903250289511035208906392689711805104128,

Esto significa que la probabilidad de que un hash256 sea menor o igual a ese target es precisamente

\displaystyle  p = \frac{\text{target}_{10}}{n+1} = 1.5054028291837063 \; \times  \; 10^{-23}

Nuestro aparatito para minar (el AntMiner S7) tiene una velocidad de v = 4.73 TH/s, por lo tanto, en un día, la probabilidad de resolver ese bloque sería de

\displaystyle  p_d = p \times v \times 24  \times 60 \times 60 = 6.15216 \; \times  \; 10^{-6}

Si no me he equivocado en los cálculos, resulta ser una probabilidad demasiado baja, se necesitaría un promedio de 445 años para hallar la solución. ¿Entonces, cómo podemos ganar dinero nosotros si no nos unimos a uno de esos pool de minería?. Parece obvio que, por nuestra cuenta, las probabilidades de obtener ganancias están muy próximas a cero. De hecho los mineros en pools incluso, a veces, agotan todos los nonces, y necesitan incluir extra nonces en los proyectos de bloque para seguir probando suerte.

Y hasta aquí puedo escribir … 😛 … de momento.

Posted in Bitcoin, Criptomonedas, informática, Matemáticas | Etiquetado: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment »

 
A %d blogueros les gusta esto: