Skip to content

Instantly share code, notes, and snippets.

@fivepiece
Last active September 1, 2018 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fivepiece/cd06216534002ebe00917ef417089cb4 to your computer and use it in GitHub Desktop.
Save fivepiece/cd06216534002ebe00917ef417089cb4 to your computer and use it in GitHub Desktop.
BU\ABC\SV replay protection with script
<nums pubkey> = 02EFD6CF6CE988CF11384C70CCCC8B3FE5451F2FA415E6F75A5FB3D911ECF16514
<dummy msg> = 666F726B696E67 # `echo -n "forking" | xxd -ps`
<msg header> = 426974636F696E205369676E6564204D6573736167653A0A # `echo "Bitcoin Signed Message:" | xxd -ps`
<user pubkey> = as the name suggests
The script builds on stack a typical "Bitcoin signed message" (as in sign\verifymessage), with the text "forking" and a signature (1,1), signed by the pubkey <nums pubkey>.
Depending on which path is used when redeeming the script, the transaction becomes replay protected in one of 3 ways :
path 0 : valid on BU only
path 1 : valid on ABC only
path 2 : NOT valid on SV, but valid on BU and ABC
Even though DATASIGVERIFY (on BU) and CHECKDATASIGVERIFY (on ABC) share the same opcode, 0xBB, they are not compatible.
On SV, the opcode 0xBB does not exist, and the script always fails (even if 0xBB is never executed).
It's possible to create a replay protected utxo in advance with a tiny amount of money in it, and use use it in a transaction with other non replay protected utxos.
P2SH script :
DUP DUP
0 3 WITHIN VERIFY
2 LESSTHAN
IF
<dummy msg>
<nums pubkey>
ROT
NOTIF
CODESEPARATOR
31 0 31 NUM2BIN 1 CAT DUP CAT 1 CAT CAT
SWAP HASH160
DATASIGVERIFY
DROP
ELSE
CODESEPARATOR
0x08 0x3006020101020101
ROT
SIZE SWAP CAT
<msg header> SIZE SWAP CAT
SWAP CAT SHA256
ROT
CHECKDATASIGVERIFY
ENDIF
ELSE
CODESEPARATOR
VERIFY
ENDIF
<user pubkey> CHECKSIG
Redeem with a single number between 0 and 2 and a single signature signing the desired path.
For example, if <user pubkey> is :
02F6293C985094E71FEA9785F3D7990478808E9BCACE25314D5555C967FEEEE7E9
For path 0, sign the scriptcode :
69011F00011F80517E767E517E7E7CA9BB7567AB0830060201010201017B827C7E18426974636F696E205369676E6564204D6573736167653A0A827C7E7C7EA87BBB6867AB69682102F6293C985094E71FEA9785F3D7990478808E9BCACE25314D5555C967FEEEE7E9AC
And redeem with scriptsig :
'<signature> 0'
For path 1, sign the scriptcode :
560830060201010201017B827C7E18426974636F696E205369676E6564204D6573736167653A0A827C7E7C7EA87BBB6867AB69682102F6293C985094E71FEA9785F3D7990478808E9BCACE25314D5555C967FEEEE7E9AC
And redeem with scriptsig :
'<signature> 1'
For path 2, sign the scriptcode :
2569682102F6293C985094E71FEA9785F3D7990478808E9BCACE25314D5555C967FEEEE7E9AC
And redeem with scriptsig :
'<signature> 2'
Proof that <nums pubkey> is actually a NUMS pubkey is in the script itself, but to test on regtest :
$ abc-cli decodescript 2102EFD6CF6CE988CF11384C70CCCC8B3FE5451F2FA415E6F75A5FB3D911ECF16514AC # scriptpubkey for p2pk
{
"asm": "02efd6cf6ce988cf11384c70cccc8b3fe5451f2fa415e6f75a5fb3d911ecf16514 OP_CHECKSIG",
"reqSigs": 1,
"type": "pubkey",
"addresses": [
"bchreg:qqvfvm4ngv72f83kurlved6m6gt0wr4jjswu0jz889"
],
"p2sh": "bchreg:pqv539cp530ll8l95cfj8fw9wedzq7twlq4ju74qkr"
}
$ abc-cli verifymessage bchreg:qqvfvm4ngv72f83kurlved6m6gt0wr4jjswu0jz889 HwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE= "forking"
true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment