6 ProgramingBitcoin (1) .En - Es
6 ProgramingBitcoin (1) .En - Es
6 ProgramingBitcoin (1) .En - Es
Guión
103
Por qué Bitcoin no se está completando
La integridad de Turing en un lenguaje de programación
esencialmente significa que el programa tiene la capacidad de
bucle. Los bucles son una estafa útil- estructura en la programación,
por lo que puede que se pregunte en este momento por qué Script
no tiene la capacidad de bucle.
Hay muchas razones para esto, pero comencemos con el programa
exe-precaución Cualquiera puede crear un programa Script que
ejecute cada nodo completo de la red. Si el script se completara con
Turing, sería posible que el ciclo continuara ejecutándose para
siempre. Esto provocaría que los nodos de validación ingresen y
nunca salgan de ese bucle. Esta sería una manera fácil de atacar la
red a través de lo que se llamaría un ataque de denegación de
servicio (DoS). ¡Un solo programa de Script con un bucle infinito
podría eliminar Bitcoin! Este sería un gran sistema-vulnerabilidad
temática, y la protección contra esta vulnerabilidad es una de las
principales razones por las cuales se evita la integridad de Turing.
Ethereum, que tiene la integridad de Turing en su lenguaje de
contrato inteligente, Solidity, maneja este problema al obligar a los
contratos a pagar la ejecución del programa con algo llamado "gas".
Un bucle infinito agotará cualquier gas que haya en el contrato
porque, por definición- Además, se ejecutará un número infinito de
veces.
Otra razón para evitar la integridad de Turing es porque los
contratos inteligentes con la integridad de Turing son muy difíciles
de analizar. Las condiciones de ejecución de un contrato inteligente
completo de Turing son muy diferentes- es difícil de enumerar y,
por lo tanto, es fácil crear comportamientos no deseados-ior,
causando errores. Los errores en un contrato inteligente significan
que las monedas son vulnerables a ser gastadas involuntariamente,
lo que significa que la estafa-Los participantes del tracto podrían
perder dinero. Tales errores no son solo teóricos- cal: este fue el
principal problema en la DAO (Organización Autónoma
Descentralizada), un contrato inteligente completo de Turing que
terminó con la bifurcación dura Ethereum Classic.
Las operaciones hacen algo a los datos (Figura 6-2.) Consumen cero o más ele-
Ments de la pila de procesamiento y empujar cero o más elementos de nuevo a la
pila.
Una operación típica es OP_DUP (Figura 6-3), que duplicará el elemento superior
(con- sumando 0) y empuje el nuevo elemento a la pila (empujando 1).
Después de evaluar todos los comandos, el elemento superior de la pila debe ser
distinto de cero para que el script se resuelva como válido. No tener elementos en la
pila o el elemento superior siendo 0 se resolvería como no válido. Resolver como
inválido significa que la transacción que incluye el script de desbloqueo no se acepta
en la red.
Operaciones de ejemplo
Hay muchas otras operaciones además de OP_DUP. OP_HASH160 (Figura 6-4) hace
un sha256 seguido de un ripemd160 (también conocido como hash160) al elemento
superior de la pila (con-sumando 1) y empuja un nuevo elemento a la pila
(empujando 1). Tenga en cuenta en el diagrama quey = hash160 (x).
Cómo funciona el script
El |
105
Figura 6-4. OP_HASH160 hace un sha256 seguido de ripemd160 al elemento
superior
Ejercicio 1
Escribe el op_hash160 función.
• 0x00 - OP_0
• 0x51 - OP_1
• 0x60 - OP_16
• 0x76 - OP_DUP
• 0x93 - OP_ADD
• 0xa9 - OP_HASH160
• 0xac - OP_CHECKSIG
Hay muchos más códigos de operación, que están codificados en op.py, y la lista
completa se puede encontrar en https://en.bitcoin.it/wiki/Script.
La serialización del script siempre comienza con la longitud del script completo.
Para un número entre 1 y 75 inclusive, sabemos el próximo norte Los bytes son
un elemento.
76 es OP_PUSHDATA1, por lo que el siguiente byte nos dice cuántos bytes leer.
77 es OP_PUSHDATA2, por lo que los siguientes dos bytes nos dicen cuántos
bytes leer.
resultado + =
int_to_little_endian(77, 1) resultado + =
int_to_little_endian(longitud, 2)
más:
aumento ValueError('demasiado largo un cmd')
resultado + = cmd
regreso resultado
Guiones estándar
Hay muchos tipos de scripts estándar en Bitcoin, incluidos los siguientes:
Combinando los campos de script
El |
111
p2pk
Pay-to-pubkey
p2pkh
Pay-to-pubkey-hash
p2sh
Pago a hash de script
p2wpkh
Pagar-a-testigo-pubkey-hash
p2wsh
Pagar-a-testigo-script-hash
Las direcciones son plantillas de script conocidas como estas. Las carteras saben
interpretar vari-ous tipos de direcciones (p2pkh, p2sh, p2wpkh) y cree los
ScriptPubKeys apropiados. Todos los ejemplos aquí tienen un tipo particular de
formato de dirección (Base58, Bech32) para que las billeteras puedan pagarles.
Para mostrar exactamente cómo funciona todo esto, comenzaremos con uno de los
scripts originales, pay-to-pubkey.
p2pk
Pay-to-pubkey (p2pk) se usó principalmente durante los primeros días de Bitcoin. La
mayoría de las monedas que se cree que pertenecen a Satoshi están en UTXO p2pk,
es decir, salidas de transacciones cuyas ScriptPubKeys tienen la forma p2pk. Hay
algunas limitaciones que discutiremos en“Problemas con p2pk” en la página 118,
pero primero, veamos cómo funciona p2pk.
De nuevo en Capítulo 3, aprendimos sobre la firma y verificación de ECDSA. Para
verificar una firma ECDSA, necesitamos el mensaje, z, la clave pública, P, y la
firma, r y s. En p2pk, los bitcoins se envían a una clave pública, y el propietario de la
clave privada puede desbloquear o gastar los bitcoins creando una firma. El
ScriptPubKey de una transacción- ción pone los bitcoins asignados bajo el control
del propietario de la clave privada.
Especificar adónde van los bitcoins es el trabajo de ScriptPubKey: esta es la caja de
seguridad que recibe los bitcoins. El p2pk ScriptPubKey se parece aFigura 6-7.
El primer comando es la firma, que es un elemento. Estos son datos que se envían a
la pila (Figura 6-11.)
p2pk El |
113
Figura 6-11. p2pk paso 1
Hemos terminado de procesar todos los comandos de Script y hemos terminado con
un solo elemento en la pila. Dado que el elemento superior no es cero (1
definitivamente no es 0), este script es válido.
Si esta transacción tenía una firma no válida, el resultado de OP_CHECKSIG sería 0,
finalizando el procesamiento de nuestro script (como se muestra en Figura 6-14.)
p2pk El |
115
Este es el método que usaremos para el conjunto de comandos combinados
(combinación de ScriptPubKey de la transacción anterior y ScriptSig de la
transacción actual):
desde op importar OP_CODE_FUNCTIONS, OP_CODE_NAMES
...
clase Guión:
...
def evaluar(yo, z):
cmds = yo.cmds[:]
apilar = []
altstack = []
mientras Len(cmds) > 0 0:
cmd = cmds.popular(0 0)
Si tipo(cmd) == En t:
operación = OP_CODE_FUNCTIONS[cmd]
Si cmd en (99, 100):
Si no operación(apilar, cmds):
LOGGER.informacion('mala operación:
{}'.formato(OP_CODE_NAMES[cmd]))
regreso Falso
elif cmd en (107, 108):
Si no operación(apilar, altstack):
LOGGER.informacion('mala operación:
{}'.formato(OP_CODE_NAMES[cmd]))
regreso Falso
elif cmd en (172, 173, 174, 175):
Si no operación(apilar, z):
LOGGER.informacion('mala operación:
{}'.formato(OP_CODE_NAMES[cmd]))
regreso Falso
más:
Si no operación(apilar):
LOGGER.informacion('mala operación:
{}'.formato(OP_CODE_NAMES[cmd]))
regreso Falso
más:
apilar.adjuntar(cmd)
Si Len(apilar) == 0 0:
regreso Falso
Si apilar.popular() == si'':
regreso Falso
regreso Cierto
Si la pila está vacía al final del procesamiento de todos los comandos, fallamos el
script al devolver Falso.
def decode_num(elemento):
Si elemento == si'':
regreso 0 0
big_endian = elemento[::-1]
Si big_endian[0 0] Y 0x80:
negativo = Cierto
resultado = big_endian[0 0] Y 0x7f
más:
negativo = Falso
resultado = big_endian[0 0]
para C en big_endian[1:]:
resultado << = 8
resultado + = C
Si negativo:
regreso -resultado
más:
regreso resultado
def op_0(apilar):
apilar.adjuntar(encode_num(0 0))
regreso Cierto
Ejercicio 2
Escribe el op_checksig funcionar en op.py.
En segundo lugar, la longitud de las claves públicas causa un problema más sutil:
dado que deben mantenerse e indexarse para ver si las salidas son gastables, el
conjunto UTXO se hace más grande. Esto requiere más recursos por parte de los
nodos completos.
Tercero, debido a que estamos almacenando las claves públicas en el campo
ScriptPubKey, todos las conocen. Eso significa que si algún día se rompe el ECDSA,
estos resultados podrían ser robados. Por ejemplo, la computación cuántica tiene el
potencial de reducir significativamente los tiempos de cálculo para RSA y ECDSA,
por lo que tener algo más además de pro-Proteger estos resultados sería más seguro.
Sin embargo, esta no es una amenaza muy grande ya que ECDSA se usa en muchas
aplicaciones además de Bitcoin y romperlo también afectaría todas esas cosas.
Problemas con p2pk El
| 119
Resolviendo los problemas con p2pkh
Pay-to-pubkey-hash (p2pkh) es un formato de script alternativo que tiene dos claves
avanzadas- tages sobre p2pk:
Las direcciones son más cortas porque usa el algoritmo hash sha256 y ripemd160-
Ritmos Hacemos ambos sucesivamente y lo llamamos hash160. El resultado de
hash160 es 160 bits o 20 bytes, que se codifican en una dirección.
El resultado es lo que puede haber visto en la red Bitcoin y codificado en Capítulo 4:
1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs
Estos 20 bytes son el resultado de realizar una operación hash160 en esta clave
pública SEC (comprimida):
0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352
Dado que p2pkh es más corto y más seguro, el uso de p2pk disminuyó
significativamente después de 2010, aunque todavía es totalmente compatible hoy en
día.
p2pkh
Pay-to-pubkey-hash se usó durante los primeros días de Bitcoin, aunque no tanto
como p2pk.
El p2pkh ScriptPubKey, o script de bloqueo, se ve como Figura 6-15.
Los dos primeros comandos son elementos, por lo que se envían a la pila (Figura 6-
19.)
OP_DUP duplica el elemento superior, por lo que la clave pública se duplica (Figura
6-20.)
Hay dos formas en que este script puede fallar. Si ScriptSig proporciona una clave
pública que no tiene hash160 al hash de 20 bytes en ScriptPubKey, el script fallará
enOP_EQUAL VERIFICAR (Figura 6-22.) La otra condición de falla es si el ScriptSig
tiene una clave pública ese hash160s al hash de 20 bytes en ScriptPubKey, pero tiene
una firma no válida. Eso terminaría la evaluación combinada del script con un 0,
terminando en falla.
Es por eso que llamamos a este tipo de script pay-to-pubkey-hash. ScriptPubKey
tiene el hash160 de 20 bytes de la clave pública y no la clave pública en sí. Estamos
bloqueando poco- monedas a un hash de la clave pública, y el gastador es
responsable de revelar el pub- clave clave como parte de la construcción de
ScriptSig.
Las principales ventajas son que ScriptPubKey es más corto (solo 25 bytes) y un
ladrón no solo tendría que resolver el problema de registro discreto en ECDSA, sino
también encontrar una forma de encontrar imágenes previas de ripemd160 y sha256.
OP_ADD consumirá los dos elementos superiores de la pila, los agregará y empujará
la suma de la pila (Figura 6-31)
Ejercicio 3
Cree un ScriptSig que pueda desbloquear este ScriptPubKey:
767695935687
Tenga en cuenta que OP_MUL multiplica los dos elementos superiores de la pila.
• 56 = OP_6
• 76 = OP_DUP
• 87 = OP_EQUAL
• 93 = OP_ADD
• 95 = OP_MUL
Utilidad de scripts
El ejercicio anterior fue un poco tramposo, ya que OP_MUL ya no está permitido en Bit-
red de monedas. La versión 0.3.5 de Bitcoin deshabilitó muchos códigos de operación
diferentes (cualquier cosa que tuviera incluso un poco de potencial para crear
vulnerabilidades en la red).
Esto es igual de bueno, ya que la mayor parte de la funcionalidad en Script no se usa
mucho. Desde el punto de vista del mantenimiento del software, esta no es una gran
situación ya que el código debe mantenerse a pesar de su falta de uso. Simplificando
y deshaciéndose de cierta capa- Las capacidades pueden verse como una forma de
hacer que Bitcoin sea más seguro.
Esto está en marcado contraste con otros proyectos, que intentan expandir sus
lenguajes de contratos inteligentes, a menudo aumentando la superficie de ataque
junto con nuevas características.
Ejercicio 4
Descubre qué está haciendo este script:
6e879169a77ca787
Las secuencias de comandos se pueden
construir arbitrariamente El |
127
• 69 = OP_VERIFY
• 6e = OP_2DUP
• 7c = OP_SWAP
• 87 = OP_EQUAL
• 91 = OP_NOT
• a7 = OP_SHA1
Piñata SHA-1
En 2013, Peter Todd creó un guión muy similar al del Ejercicio 4 y puso algunos
bitcoins para crear un incentivo económico para que las personas encuentren hash
colli-Sions. Las donaciones alcanzaron 2.49153717 BTC, y cuando Google
realmente encontró uncolisión de hash para SHA-1 en febrero de 2017, Este script
fue redimido rápidamente. los La salida de la transacción fue de 2.48 BTC, que era
de 2,848.88 USD en ese momento.
Peter creó más piñatas para sha256, hash256 y hash160, que agregan incentivos
económicos para encontrar colisiones para estas funciones de hash.
Conclusión
Hemos cubierto Script y cómo funciona. Ahora podemos proceder a la creación y
vali- fecha de las transacciones.