# Ejemplo para Decodificar una transacción a mano
###### tags: `bitcoin` `cli` `ejercicio`
_Ya usaste bitcoin core para ver transacciones, ahora haz una radiografía de como funcionan_
[TOC]
## Autor
**EntrePlanctonyBallenas**.
Twitter para correcciones, comentarios o sugerencias: [@entreplanctony1](https://twitter.com/Entreplanctony1)
El presente ejercicio fue elaborado por **[@niftynei](https://twitter.com/niftynei)**, como parte del curso
[Bitcoin Protocol Deep Dive: Transactions
](https://www.udemy.com/course/base58-bitcoin-transactions-one/) en Udemy, si consideras útil este material te sugiero que tomes todo su curso, te será muy útil si quieres adentrarte en el rabbit hole de las transacciones de bitcoin.
## Cheat Sheet de PYTHON
:::info
Usamos python desde la línea de comandos para decodificar más rápido. Aquí una lista de comandos que te harán más fácil el ejercicio.
:::
PARA CONVERTIR UN VALOR DE HEXADECIMAL A ENTERO
```
int('<CADENA>',16)
```
PARA CONVERTIR UN VALOR HEXADECIMAL A BIG ENDIAN
```
bytes.fromhex('<CADENA>')[::-1].hex()
```
PARA CONVERTIR UN VALOR HEXADECIMAL A BIG ENDIAN Y A ENTERO
```
int(bytes.fromhex('<CADENA>')[::-1].hex(),16)
```
PARA MEDIR LA LONGITUD DE UNA CADENA HEXADECIMAL EN BYTES
```
len ('<CADENA>')/2
```
## Ejemplo para Legacy
Tomamos la siguiente transacción:
**txid** = 'f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16'
:::warning
**Valor Hexadecimal de la transacción**
0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000
:::
### Formulario para identificar los campos de una transacción.
:::success
Todos los campos de tamaño fijo están codificados en **little endian**, mientras que los campos que tienen longitud variable usan **Big Endian**
:::
Versión de la transacción - 4 bytes - little endian y convertir a Entero
numero de inputs - 1 byte - little endian y convertir a Entero
**VINs (vectores de entrada)**
txid - 32 bytes - little endian
vout - 4 bytes - little endian y convertir a Entero
scriptsize - 1 byte - little endian y convertir a Entero
scriptsig - variable - BIG endian
sequence - 8 bytes - little endian
**VOUTs (Vectores de salida)**
Numero de outputs - 1 byte - little endian
amount - 8 bytes - little endian y convertir a Entero
scriptsize - 1 byte - little endian y convertir a Entero
scriptsig - variable - BIG endian
LOCKTIME
### Aplicamos el formulario y el cheat cheat sobre la transacción
:::info
**Versión de la transacción** *- 4 bytes - little endian y convertir a Entero*
01000000
**numero de inputs** *- 1 byte - little endian y convertir a Entero*
01
**VINs (vectores de entrada)**
**txid** *- 32 bytes - little endian*
c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704
```
bytes.fromhex('<CADENA>')[::-1].hex()
Resultado: 0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9
```
**vout** *- 4 bytes - little endian y convertir a Entero*
00000000
**scriptsize** *- 1 byte - little endian y convertir a Entero*
48
```
int(bytes.fromhex('<CADENA>')[::-1].hex(),16)
Resultado:72
```
**scriptsig** *- variable - BIG endian*
47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901
**sequence** *- 8 bytes - little endian*
ffffffff
**VOUTs (Vectores de salida)**
**Numero de outputs** *- 1 byte - little endian*
02
**amount** *- 8 bytes - little endian y convertir a Entero*
00ca9a3b00000000
```
int(bytes.fromhex('<CADENA>')[::-1].hex(),16)
Resultado: 10 0000 0000
```
**scriptsize** *- 1 byte - little endian y convertir a Entero*
43
```
int(bytes.fromhex('<CADENA>')[::-1].hex(),16)
Resultado: 67
```
**scriptsig** *- variable - BIG endian*
4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac
**amount** *- 8 bytes - little endian y convertir a Entero*
00286bee00000000
```
int(bytes.fromhex('<CADENA>')[::-1].hex(),16)
Resultado: 40 0000 0000
```
**scriptsize** *- 1 byte - little endian y convertir a Entero*
43
```
int(bytes.fromhex('<CADENA>')[::-1].hex(),16)
Resultado: 67
```
**scriptsig** *- variable - BIG endian*
410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac
**LOCKTIME** *- little endian*
00000000
:::
## Ejemplo para SegWit
### Diferencias en los campos entre Legacy y SegWit
|**Legacy**| **Segwit**|
|:-------- |:--------:|
|Versión de la transacción | Versión de la transacción |
|Número de inputs | Segwit marker + Flag
|Txid |Número de inputs|
|Índice de Vout|Txid |
|Scriptsize|Índice de Vout|
|Scriptsig |Scriptsize|
|Sequence|Sequence|
|Número de outputs|Número de outputs|
|Amount|Amount|
|Scriptsize|Scriptsize|
|ScriptLock|ScriptLock|
|LOCKTIME|Witness Stacks|
| |Scriptsig|
| |LOCKTIME|
### Vamos a convertir la misma transacción Legacy a SegWit
Tomamos el mismo formulario, solo queremos saber los valores originales, no nos importa convertir a entero o a Big Endian.
Y hay que modificar la información tomando en cuenta los campos nuevos. Así mismo los scripts de desbloqueo se mueven al final de los VOUTs.
:::info
**Versión de la transacción**
01000000
**segwit marker + flag**
00 01
**numero de inputs**
01
**VINs (vectores de entrada)**
**txid**
c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704
**vout**
00000000
**scriptsize**
00
**sequence**
ffffffff
**VOUTs (Vectores de salida)**
**Numero de outputs**
02
**amount**
00ca9a3b00000000
**scriptsize**
43
**scriptsig**
4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac
**amount**
00286bee00000000
**scriptsize**
43
**scriptsig**
410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac
**witness stacks**
01
**scriptsig**
47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901
**LOCKTIME**
00000000
:::
**Resultado:**
01000000000101c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd37040000000000ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac0147304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d090100000000
## Obtener el txid de una transacción en hexadecimal
### Comandos para obtener el hash de una transaccion
Importar librerias necesarias
```
from hashlib import sha256
```
Obtenemos los bytes del valor hexadecimal de la transacción:
```
b = bytes.fromhex('<TXHEX>')
```
Aplicamos 2 veces el sha256 y volvemos a convertir a hexadecimal y BIG endian:
```
sha256(sha256(b).digest()).digest()[::-1].hex()
```
### TXID Legacy
Es el hash de toda la información de una transacción
```
from hashlib import sha256
TXHEX = '0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000'
b = bytes.fromhex(TXHEX)
sha256(sha256(b).digest()).digest()[::-1].hex()
```
Resultado
```
f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16
```
### TXID SegWit
Es el hash de toda la información "Legacy de una transacción", hay que remover todos los datos hexadecimales que se usen en SegWit.
```
from hashlib import sha256
TXHEX = '0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd37040000000000ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000'
b = bytes.fromhex(TXHEX)
sha256(sha256(b).digest()).digest()[::-1].hex()
```
Resultado
```
f4999544bfc6aad5c629a8eaa015f7df32d3498569073db7f2cebdf4cf13c1e4
```
## Como calcular el peso de una transacción.
### Legacy
El peso de la transacción, se obtiene de la longitud de la transacción en bytes multiplicado por 4, en terminal correr
```
len ('<CADENA>')/2 *4
Resultado: 1100
```
### SegWit
El peso de la transacción se calcula de manera distinta, cada campo tiene un peso distinto de acuerdo a su longitud y de acuerdo a si es un campo **Legacy (se multiplica la longitud del campo x 4)** o **SegWit (se multiplica la longitud del campo x 1)**. Por lo que hay que aplicar los valores como los encontramos en la transacción:
|**Versión de la transacción**|4 bytes * 4 = |**16**|
|:-------- |:--------:|:--------:|
|01000000| | |
|**Segwit marker + flag**|1byte + 1byte = 2 bytes * 1 = |**2**|
|00 01| | |
|**numero de inputs**| 1 byte * 4 = |**4**|
|01| | |
|**VINs (vectores de entrada)**| | |
|**txid**| 32 bytes * 4 = |**128**|
|c997a5e56e104102fa209c6a852dd90660
a20b2d9c352423edce25857fcd3704| | |
|**vout**| 4 bytes * 4 = |**16**|
|00000000| | |
|**scriptsize**| 1 byte * 4 = |**4**|
|00|
|**sequence**| 4 bytes * 4 = |**16**|
|ffffffff|
|**VOUTs (Vectores de salida)**| | |
|**Numero de outputs**| 1 byte * 4 = |**4**|
02|
|**amount**| 8 bytes * 4 = |**32**|
|00ca9a3b00000000| | |
|**scriptsize**| 1 byte * 4 = |**4**|
|43|
|**scriptsig**| 67 bytes * 4 = |**268**|
|4104ae1a62fe09c5f51b13905f07f06b99a2| | |
|f7159b2225f374cd378d71302fa28414e7aa| | |
|b37397f554a7df5f142c21c1b7303b8a0626| | |
|f1baded5c72a704f7e6cd84cac| | |
|**amount**| 8 bytes * 4 = |**32**|
|00286bee00000000|
|**scriptsize** |1 byte * 4 = |**4**|
|43|
|**scriptsig** |67 bytes * 4 = |**268**|
410411db93e1dcdb8a016b49840f8c53bc1eb
68a382e97b1482ecad7b148a6909a5cb2e0ea
ddfb84ccf9744464f82e160bfa9b8b64f9d4c
03f999b8643f656b412a3ac
|**witness stacks** |1 byte * 1 = |**1**|
|01|
|**scriptsig** |72 bytes * 1 = |**72**|
47304402204e45e16932b8af514961a1d3a1a
25fdf3f4f7732e9d624c6c61548ab5fb8cd41
0220181522ec8eca07de4860a4acdd12909d8
31cc56cbbac4622082221a8768d1d0901
|**LOCKTIME**| 4 bytes * 4 = |**16**|
|00000000|
::: success
Por lo que el peso de esta transacción SegWit sería:
16 + 2 + 4 + 128 + 16 + 4 + 16 + 4 + 32 + 4 + 268 + 32 + 4 + 268 + 1 + 72 + 16 = **887**
:::