Desenvolvimento de contrato sCrypt e habilidades de depuração: localizar e resolver exceções checkSig / checkPreimage

Durante o desenvolvimento e depuração do contrato sCrypt, os dois problemas mais comuns e mais problemáticos são as exceções checkSig e checkPreimage. Embora possamos localizar o local específico do erro no código-fonte durante a depuração, sempre nos sentimos confusos sobre o motivo da falha e como corrigi-lo. Hoje vamos falar sobre algumas dicas de como localizar e reparar rapidamente esses dois tipos de problemas, na esperança de ser útil a todos.

O projeto padrão sCrypt contém alguns códigos de amostra específicos do contrato sCrypt e está em constante atualização, portanto, às vezes você pode encontrar uma situação em que a configuração falha e a depuração não pode ser concluída normalmente. Vamos tomar o contrato tokenUtxo neste projeto como um exemplo para ver como localizar e resolver esses dois tipos de problemas.

Observação: a versão do plug-in sCrypt usado neste artigo é 0.4.3 .

exceção checkPreimage

Primeiro, observe tokenUtxo.scrypta configuração de inicialização de depuração (localizada .vscode / launch.json para conveniência, visualize os 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
            }
        }

A configuração de depuração acima especifica a função inicial splite entryMethodParamsos parâmetros especificam o número inicial; o mesmo txContextparâmetro de contexto especificado de tempo relacionado a tx. Quando iniciamos essa configuração em vscode para nos prepararmos para a depuração, descobrimos que a seguinte exceção foi gerada no Console de depuração:

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

A localização anormal mostrada aqui está na linha 14, e o código é require(Tx.checkPreimage(txPreimage));. A partir disso, pode-se inferir que há um problema com txPreimage, mas qual é o motivo específico?

No artigo anterior , apresentamos Sighash Preiamge, que é chamado de pré-imagem da transação e pode ser calculado pela transação tx. Aqui Tx.checkPreimagefalha, os parâmetros de configuração de inicialização entryMethodParamspassados ​​no valor e usam txContextos parâmetros calculados do resultado são inconsistentes.

sighashPreimage

Conforme mostrado na figura acima, a pré-imagem de Sighash é composta de várias partes. Se as duas pré-imagens forem inconsistentes, alguns dos campos devem ser diferentes. Qual campo é o problema? Vejamos o seguinte log novamente:

----- 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 -----

Este diário nos fornece checkPreimagemais detalhes sobre anormalidades, principalmente comparando as diferenças específicas entre as duas imagens originais mencionadas anteriormente. Aqui, ambos os scriptCodevalores MD5 são diferentes, ou seja, a descrição em si scriptCode(correspondente ao script de entrada de bloqueio) é inconsistente.

O ponto básico encontrado onde está o problema, dadas algumas das mudanças recentes, presumivelmente entryMethodParams, e txContextalguns dos parâmetros de configuração podem ser ineficazes. Então recalculados e atualizados preimage, txContext.hex, txContext.opReturnos outros parâmetros, Debug finalmente os resultados corretos.

exceção checkSig

Existe um tipo de erro comum é checkSiganormal, muitas vezes devido a problemas de assinatura causados. Aqui, podemos ser modificados livremente senderSigpara simular o valor do parâmetro de erro de um problema de assinatura. Depois de reiniciar o Debug, você pode ver as seguintes informações:

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...

As informações de prompt acima abrangem os principais pontos de verificação ao resolver erros de assinatura, a saber:

1. Determine se a chave privada usada para gerar a assinatura está correta;

2. Confirme se a pré-imagem do tx a ser assinado (calculado automaticamente de acordo com txContext) é consistente com os parâmetros de entrada.

Para comparar se duas pré-imagem são iguais, pode ser usado SigHashPreimageem toJSON()um método para visualizar seus detalhes internos, para obter resultados semelhantes aos seguintes:

{
  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'
}

O truque aqui é: insira um pedaço de código onde o parâmetro de entrada preimage é gerado, compare-o com a saída de preimage no prompt de exceção acima e descubra as possíveis diferenças entre os dois. Conforme mostrado no seguinte 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())

Devo lembrar mais uma vez que a configuração de inicialização txContextafetará o campo sob os preimagecálculos dos atributos , e assim um a um para confirmar se a mesma comparação quando um problema exige.

Acho que você gosta

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