sCrypt desarrollo de contratos y habilidades de depuración: localizar y resolver excepciones checkSig / checkPreimage

Durante el desarrollo y la depuración del contrato sCrypt, los dos problemas más comunes y problemáticos son las excepciones checkSig y checkPreimage. Aunque podemos localizar la ubicación específica del error en el código fuente durante la depuración, siempre nos sentimos confundidos acerca de por qué falló y cómo solucionarlo. Hoy vamos a hablar sobre algunos consejos sobre cómo localizar y reparar rápidamente estos dos tipos de problemas, con la esperanza de que sean de utilidad para todos.

El proyecto modelo sCrypt contiene algunos códigos de muestra específicos del contrato sCrypt y se actualiza constantemente, por lo que a veces puede encontrar una situación en la que la configuración falla y la depuración no se puede completar normalmente. Tomemos el contrato tokenUtxo de este proyecto como ejemplo para ver cómo localizar y resolver estos dos tipos de problemas.

Nota: La versión del complemento sCrypt utilizada en este artículo es 0.4.3 .

checkPreimage excepción

Primero, mire tokenUtxo.scryptla configuración de inicio de depuración (ubicada .vscode / launch.json para mayor comodidad, vea los valores parcialmente omitidos):

{
            "type": "scrypt",
            "request": "launch",
            "name": "Debug tokenUtxo",
            "program": "${workspaceFolder}/contracts/tokenUtxo.scrypt",
            "constructorParams": "",
            "entryMethod": "split",
            "entryMethodParams": "Sig(b'304402200...'), PubKey(b'0251c866a29a93b6eb51197be1e9ccdcc5e822caa69c7593905347e3ec310bebad'), 60, 22222, PubKey(b'0291e61f25a92c94103f0f4ef1f70bf3582f44cff95d497ceb3efdb945f4ce3cbe'), 40, 22222, SigHashPreimage(b'0100000028bc...')",
            "txContext": {
                "hex": "01000000015884e5...",
                "inputSatoshis": 100000,
                "opReturn": "029a77564154c6ed13ffcc387342692480e7e15f2e3ad832cf2ac6de1c3ccf28230a5a",
                "inputIndex": 0
            }
        }

La configuración de depuración anterior especifica la función de inicio splity entryMethodParamslos parámetros especifican el número de inicio; el mismo txContextparámetro de contexto especificado de tiempo relacionado con tx. Cuando comenzamos esta configuración en vscode para prepararnos para la depuración, encontramos que la siguiente excepción se mostraba en la Consola de depuración:

Execution failed with error SCRIPT_ERR_NULLFAIL.
Stacktrace:
  /Users/hero/work/boilerplate/contracts/tokenUtxo.scrypt:14:in 'Token.split'

La ubicación anormal que se muestra aquí está en la línea 14, y el código es require(Tx.checkPreimage(txPreimage));A partir de esto, se puede inferir que hay un problema con txPreimage, pero ¿cuál es la razón específica?

En el artículo anterior , presentamos Sighash Preiamge, que se denomina imagen previa de la transacción y se puede calcular mediante la transacción tx. Aquí Tx.checkPreimagefalla, los parámetros de configuración de arranque entryMethodParamspasados ​​en el valor y el uso de txContextlos parámetros calculados del resultado son inconsistentes.

sighashPreimagen

Como se muestra en la figura anterior, Sighash Preimage se compone de varias partes. Si las dos preimágenes son inconsistentes, algunos de los campos deben ser diferentes. ¿Qué campo es el problema? Veamos nuevamente el siguiente registro:

----- CheckPreimage Fail Hints Begin -----
You should check the differences in detail listed below:

Fields with difference | From preimage in entry method params | From preimage calculated with tx
md5(scriptCode) | 148dd2b3fcc09d6baf15c9fcf5d961d3 | 6393778445f442466414464ee3be7cc7

Preimage calculated with tx:
0100000028bce...

----- CheckPreimage Fail Hints End -----

Esta revista nos proporciona checkPreimagemás detalles sobre las anomalías, principalmente comparó las diferencias específicas entre las dos imágenes originales mencionadas anteriormente. Aquí scriptCodese muestran ambos valores MD5 son diferentes, es decir, la descripción en sí scriptCode(correspondiente al script de entrada de bloqueo) es inconsistente.

El punto básico encontró dónde está el problema, dados algunos de los cambios recientes, presumiblemente entryMethodParams, y txContextalgunos de los parámetros de configuración pueden ser ineficaces. Así recalculado y actualizado preimage, txContext.hex, txContext.opReturnlos otros parámetros, depuración finalmente consiguieron los resultados correctos.

checkSig excepción

Existe una especie de error común que es checkSiganormal, a menudo debido a problemas provocados por la firma. A continuación, podemos modificar libremente senderSigpara simular el valor del parámetro de error de un problema de firma; después de reiniciar Debug, puede ver la siguiente información:

Execution failed with error SCRIPT_ERR_NULLFAIL.
Stacktrace:
  /Users/hero/work/boilerplate/contracts/tokenUtxo.scrypt:25:in 'Token.split'
 
----- CheckSig Fail Hints Begin -----
You should make sure the following check points all passed:
1. private key used to sign should be corresponding to the public key 028f46cb8ec957dcda049ac549fc46d451e0095a5b6f95950bc58830a7dc21167c
2. the preimage of the tx to be signed should be 0100000028bcef7e73248aa273...

La información de solicitud anterior cubre los principales puntos de control al resolver errores de firma, a saber:

1. Determine si la clave privada utilizada para generar la firma es correcta;

2. Confirme si la preimagen del tx a firmar (calculada automáticamente según txContext) es consistente con los parámetros entrantes.

Para comparar si dos preimágenes iguales, pueden usarse SigHashPreimageen toJSON()un método para ver sus detalles internos, para obtener resultados similares a los siguientes:

{
  nVersion: 1,
  hashPrevouts: '1029c58f269f3a1f0165149921e7a726d13bf29883f80ec3bb08c75fabaa06ad',
  hashSequence: '3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044',
  outpoint: {
    hash: '5884e5db9de218238671572340b207ee85b628074e7e467096c267266baf77a4',
    index: 0
  },
  scriptCode: 'fd860f5101400...',
  amount: 100000,
  nSequence: 4294967295,
  hashOutputs: '1029c58f269f3a1f0165149921e7a726d13bf29883f80ec3bb08c75fabaa06ad',
  nLocktime: 0,
  sighashType: 'SigHash.ALL | SigHash.FORKID'
}

El truco aquí es: inserte un fragmento de código donde se genera la preimagen del parámetro de entrada, compárelo con la salida de la preimagen en el indicador de excepción anterior y descubra las posibles diferencias entre los dos. Como se muestra en el siguiente código:

const {
    
     getPreimage, SigHashPreimage, signTx } = require('scryptlib');

...

const preimage = getPreimage(tx_, token.lockingScript.toASM(), inputSatoshis, inputIndex)
const sig = signTx(tx_, privKey, token.lockingScript.toASM(), inputSatoshis)

// compare two preimages for debugging purpose
const preimage2 = new SigHashPreimage('fd860f51014001760...'); // use hex from checkSig fail hints
console.log(preimage2.toString() === preimage.toString())
console.log(preimage.toJSON())
console.log(preimage2.toJSON())

Debo recordarles una vez más que la configuración de inicio txContextafectará el campo bajo los preimagecálculos de atributos , y así uno por uno para confirmar si la misma comparación cuando un problema lo requiera.

Supongo que te gusta

Origin blog.csdn.net/freedomhero/article/details/108917575
Recomendado
Clasificación