Skip to content

Commit 6f96f21

Browse files
committed
add TaprootTest file that was forgotten
1 parent 68f354c commit 6f96f21

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

tests/Script/TaprootTest.php

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace BitWasp\Bitcoin\Tests\Script;
4+
5+
use BitWasp\Bitcoin\Crypto\EcAdapter\Adapter\EcAdapterInterface;
6+
use BitWasp\Bitcoin\Script\Consensus\NativeConsensus;
7+
use BitWasp\Bitcoin\Script\Opcodes;
8+
use BitWasp\Bitcoin\Script\Script;
9+
use BitWasp\Bitcoin\Script\Interpreter\Interpreter as I;
10+
use BitWasp\Bitcoin\Script\ScriptFactory;
11+
use BitWasp\Bitcoin\Script\ScriptWitness;
12+
use BitWasp\Bitcoin\Transaction\TransactionOutput;
13+
use BitWasp\Buffertools\Buffer;
14+
use const BitWasp\Bitcoin\Script\Interpreter\TAPROOT_LEAF_TAPSCRIPT;
15+
16+
class TaprootTest extends ConsensusTest
17+
{
18+
public function prepareTestData(): array
19+
{
20+
$opcodes = new Opcodes();
21+
$mapOpNames = $this->calcMapOpNames($opcodes);
22+
return [
23+
//[$flags, $returns, $scriptWitness, $scriptSig, $scriptPubKey, $amount, $strTest],
24+
[0, true, new ScriptWitness(), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0xabcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'), 0, 'should return true when segwit & taproot not active'],
25+
[I::VERIFY_WITNESS, true, new ScriptWitness(), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0xabcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'), 0, 'should return true when taproot not active'],
26+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, false, new ScriptWitness(), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0xabcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'), 0, 'should return false if scriptWitness empty'],
27+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT|I::VERIFY_DISCOURAGE_UPGRADABLE_ANNEX, false, new ScriptWitness(new Buffer(), new Buffer(), new Buffer("\x50")), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0xabcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'), 0, 'VERIFY_DISCOURAGE_UPGRADABLE_ANNEX rejects annex if present'],
28+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, false, new ScriptWitness(new Buffer(), new Buffer(), new Buffer(str_repeat("A", 32))), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0xabcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'), 0, 'control size wrong: (under minimum)'],
29+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, false, new ScriptWitness(new Buffer(), new Buffer(), new Buffer(str_repeat("A", 33+32*128+1))), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0xabcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'), 0, 'control size wrong: (over maximum)'],
30+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, false, new ScriptWitness(new Buffer(), new Buffer(), new Buffer(str_repeat("A", 33+16))), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0xabcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'), 0, 'control size wrong: ((len-33)%32!=0)'],
31+
32+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, true, new ScriptWitness(Buffer::hex('b2ecb4b1957d495d55c72e3deabb3d76ed8d33c2496ffdbdc8577b9605ceec84732f6eb3d90c89931f42d0a76499aa2b493f44e53c2c9d74a3565fd8fecc4bbd')), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0x1dcf456c1195e3bd19fe33e52309859253ddc9b95996b0896e36fd3df34eb66a'), 1, 'keypath signature ok', [new TransactionOutput(1, new Script(Buffer::hex("51201dcf456c1195e3bd19fe33e52309859253ddc9b95996b0896e36fd3df34eb66a")))]],
33+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, false, new ScriptWitness(Buffer::hex('11ecb4b1957d495d55c72e3deabb3d76ed8d33c2496ffdbdc8577b9605ceec84732f6eb3d90c89931f42d0a76499aa2b493f44e53c2c9d74a3565fd8fecc4bbd')), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0x1dcf456c1195e3bd19fe33e52309859253ddc9b95996b0896e36fd3df34eb66a'), 1, 'keypath signature r first byte wrong', [new TransactionOutput(1, new Script(Buffer::hex("51201dcf456c1195e3bd19fe33e52309859253ddc9b95996b0896e36fd3df34eb66a")))]],
34+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, false, new ScriptWitness(Buffer::hex('b2ecb4b1957d495d55c72e3deabb3d76ed8d33c2496ffdbdc8577b9605ceec84112f6eb3d90c89931f42d0a76499aa2b493f44e53c2c9d74a3565fd8fecc4bbd')), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0x1dcf456c1195e3bd19fe33e52309859253ddc9b95996b0896e36fd3df34eb66a'), 1, 'keypath signature s first byte wrong', [new TransactionOutput(1, new Script(Buffer::hex("51201dcf456c1195e3bd19fe33e52309859253ddc9b95996b0896e36fd3df34eb66a")))]],
35+
36+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, true, new ScriptWitness(Buffer::hex('613f2d05989a9b82d407663c96d9f599428f5e4a3cb450d49c8292ebc2a44fc877b90d2273cc54911b5ae466b1ac10b6e7c8c972f31253eba12c14073ef957e901'),
37+
Buffer::hex('0020b24dbf3e21d269c0da6e5c1da77c8b4041b9ae85aa1747d2db7f9653aa93ed99ba519c'),
38+
Buffer::hex('c0b24dbf3e21d269c0da6e5c1da77c8b4041b9ae85aa1747d2db7f9653aa93ed99')
39+
), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0x070af82161cbd04c96cd86e7f8c600a9370092b02c3cef2fbd9dcb639b1b84b7'), 1, 'tapscript 1of1 checksigadd', [new TransactionOutput(1, new Script(Buffer::hex("5120070af82161cbd04c96cd86e7f8c600a9370092b02c3cef2fbd9dcb639b1b84b7")))]],
40+
41+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, false, new ScriptWitness(Buffer::hex('613f2d05989a9b82d407663c96d9f599428f5e4a3cb450d49c8292ebc2a44fc877b90d2273cc54911b5ae466b1ac10b6e7c8c972f31253eba12c14073ef957e901'),
42+
Buffer::hex('0020b24dbf3e21d269c0da6e5c1da77c8b4041b9ae85aa1747d2db7f9653aa93ed99ba519c'),
43+
Buffer::hex('c0b24dbf3e21d269c0da6e5c1da77c8b4041b9ae85aa1747d2db7f9653aa93ed99')
44+
), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0xfffff82161cbd04c96cd86e7f8c600a9370092b02c3cef2fbd9dcb639b1b84b7'), 1, 'first 2 bytes spk wrong', [new TransactionOutput(1, new Script(Buffer::hex("5120070af82161cbd04c96cd86e7f8c600a9370092b02c3cef2fbd9dcb639b1b84b7")))]],
45+
46+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, false, new ScriptWitness(Buffer::hex('613f2d05989a9b82d407663c96d9f599428f5e4a3cb450d49c8292ebc2a44fc877b90d2273cc54911b5ae466b1ac10b6e7c8c972f31253eba12c14073ef957e901'),
47+
Buffer::hex('ff20b24dbf3e21d269c0da6e5c1da77c8b4041b9ae85aa1747d2db7f9653aa93ed99ba519c'),
48+
Buffer::hex('c0b24dbf3e21d269c0da6e5c1da77c8b4041b9ae85aa1747d2db7f9653aa93ed99')
49+
), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0x070af82161cbd04c96cd86e7f8c600a9370092b02c3cef2fbd9dcb639b1b84b7'), 1, '1st byte script element incorrect', [new TransactionOutput(1, new Script(Buffer::hex("5120070af82161cbd04c96cd86e7f8c600a9370092b02c3cef2fbd9dcb639b1b84b7")))]],
50+
51+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, false, new ScriptWitness(Buffer::hex('613f2d05989a9b82d407663c96d9f599428f5e4a3cb450d49c8292ebc2a44fc877b90d2273cc54911b5ae466b1ac10b6e7c8c972f31253eba12c14073ef957e901'),
52+
Buffer::hex('0020b24dbf3e21d269c0da6e5c1da77c8b4041b9ae85aa1747d2db7f9653aa93ed99ba519c'),
53+
Buffer::hex('c1b24dbf3e21d269c0da6e5c1da77c8b4041b9ae85aa1747d2db7f9653aa93ed99')
54+
), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0x070af82161cbd04c96cd86e7f8c600a9370092b02c3cef2fbd9dcb639b1b84b7'), 1, 'is_square_y bit incorrect', [new TransactionOutput(1, new Script(Buffer::hex("5120070af82161cbd04c96cd86e7f8c600a9370092b02c3cef2fbd9dcb639b1b84b7")))]],
55+
56+
[I::VERIFY_WITNESS|I::VERIFY_TAPROOT, false, new ScriptWitness(Buffer::hex('613f2d05989a9b82d407663c96d9f599428f5e4a3cb450d49c8292ebc2a44fc877b90d2273cc54911b5ae466b1ac10b6e7c8c972f31253eba12c14073ef957e901'),
57+
Buffer::hex('0020b24dbf3e21d269c0da6e5c1da77c8b4041b9ae85aa1747d2db7f9653aa93ed99ba519c'),
58+
Buffer::hex('c0ffffbf3e21d269c0da6e5c1da77c8b4041b9ae85aa1747d2db7f9653aa93ed99')
59+
), new Script(), $this->calcScriptFromString($mapOpNames, '0x51 0x20 0x070af82161cbd04c96cd86e7f8c600a9370092b02c3cef2fbd9dcb639b1b84b7'), 1, '1st 2 bytes control hash incorrect', [new TransactionOutput(1, new Script(Buffer::hex("5120070af82161cbd04c96cd86e7f8c600a9370092b02c3cef2fbd9dcb639b1b84b7")))]],
60+
];
61+
}
62+
63+
/**
64+
* @dataProvider getEcAdapters
65+
* @throws \Exception
66+
*/
67+
public function testTweakTestCase(EcAdapterInterface $ec)
68+
{
69+
$privFactory = new \BitWasp\Bitcoin\Key\Factory\PrivateKeyFactory($ec);
70+
71+
$privHex = "f698076154c545857fe7072ecb8df962c965b798b1d2b7640da20db3a6fcdb7d";
72+
$privKey = $privFactory->fromHexUncompressed($privHex);
73+
$pub = $privKey->getPublicKey();
74+
$xonly = $pub->asXOnlyPublicKey();
75+
$multisig1of1 = ScriptFactory::create()
76+
->opcode(Opcodes::OP_0)
77+
->data($xonly->getBuffer())
78+
->opcode(Opcodes::OP_CHECKSIGADD, Opcodes::OP_1, Opcodes::OP_NUMEQUAL)
79+
->getScript();
80+
81+
$tree = [
82+
[TAPROOT_LEAF_TAPSCRIPT, $multisig1of1]
83+
];
84+
$ret = \BitWasp\Bitcoin\Script\Taproot\taprootConstruct($xonly, $tree);
85+
list ($scriptPubKey, $tweak, $scripts, $control) = $ret;
86+
87+
$this->assertEquals(
88+
"5120070af82161cbd04c96cd86e7f8c600a9370092b02c3cef2fbd9dcb639b1b84b7",
89+
$scriptPubKey->getHex()
90+
);
91+
$this->assertEquals(
92+
"85a4787be0566335143ad2d60f72b4db97044236515db7ffd733b8f6e10efe64",
93+
$tweak->getHex()
94+
);
95+
$this->assertEquals(
96+
$multisig1of1->getHex(),
97+
$scripts[0]->getHex()
98+
);
99+
$this->assertEquals(
100+
$multisig1of1->getHex(),
101+
$scripts[0]->getHex()
102+
);
103+
$this->assertEquals(
104+
"c0b24dbf3e21d269c0da6e5c1da77c8b4041b9ae85aa1747d2db7f9653aa93ed99",
105+
bin2hex($control[0])
106+
);
107+
}
108+
109+
/**
110+
* @param array $ecAdapterFixtures - array<array<EcAdapterInterface>>
111+
* @return array - array<array<ConsensusInterface,EcAdapterInterface>>
112+
*/
113+
public function getConsensusAdapters(array $ecAdapterFixtures): array
114+
{
115+
$adapters = [];
116+
foreach ($ecAdapterFixtures as $ecAdapterFixture) {
117+
list ($ecAdapter) = $ecAdapterFixture;
118+
$adapters[] = [new NativeConsensus($ecAdapter)];
119+
}
120+
121+
return $adapters;
122+
}
123+
}

0 commit comments

Comments
 (0)