<?php require "../vendor/autoload.php"; use BitWasp\Buffertools\Buffer; use BitWasp\Bitcoin\Key\PrivateKeyFactory; use BitWasp\Bitcoin\Script\ScriptFactory; use BitWasp\Bitcoin\Transaction\OutPoint; use BitWasp\Bitcoin\Transaction\TransactionFactory; use BitWasp\Bitcoin\Script\WitnessProgram; use BitWasp\Bitcoin\Bitcoin; $wif = 'QP3p9tRpTGTefG4a8jKoktSWC7Um8qzvt8wGKMxwWyW3KTNxMxN7'; $s = \BitWasp\Bitcoin\Network\NetworkFactory::bitcoinSegnet(); Bitcoin::setNetwork($s); $ec = \BitWasp\Bitcoin\Bitcoin::getEcAdapter(); $key = PrivateKeyFactory::fromWif($wif); echo $key->getPublicKey()->getAddress()->getAddress() . PHP_EOL; $outpoint = new OutPoint(Buffer::hex('874381bb431eaaae16e94f8b88e4ea7baf2ebf541b2ae11ec10d54c8e03a237f', 32), 0); $scriptPubKey = ScriptFactory::scriptPubKey()->payToPubKeyHash($key->getPublicKey()); $value = 100000000; $txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($value, $scriptPubKey); $destination = new WitnessProgram(0, $key->getPubKeyHash()); $tx = TransactionFactory::build()->spendOutPoint($outpoint)->output(99900000, $destination->getScript())->get(); $signed = new \BitWasp\Bitcoin\Transaction\Factory\Signer($tx, $ec); $signed->sign(0, $key, $txOut); $ss = $signed->get(); echo $ss->getHex() . PHP_EOL;
<?php require "../vendor/autoload.php"; use BitWasp\Buffertools\Buffer; use BitWasp\Bitcoin\Key\PrivateKeyFactory; use BitWasp\Bitcoin\Script\ScriptFactory; use BitWasp\Bitcoin\Transaction\OutPoint; use BitWasp\Bitcoin\Transaction\TransactionFactory; use BitWasp\Bitcoin\Script\WitnessProgram; use BitWasp\Bitcoin\Bitcoin; $wif = 'QP3p9tRpTGTefG4a8jKoktSWC7Um8qzvt8wGKMxwWyW3KTNxMxN7'; $s = \BitWasp\Bitcoin\Network\NetworkFactory::bitcoinSegnet(); Bitcoin::setNetwork($s); $ec = \BitWasp\Bitcoin\Bitcoin::getEcAdapter(); $key = PrivateKeyFactory::fromWif($wif); echo $key->getPublicKey()->getAddress()->getAddress() . PHP_EOL; $outpoint = new OutPoint(Buffer::hex('703f50920bff10e1622117af81b622d8bbd625460e61909cc3f8b8ee78a59c0d', 32), 0); $scriptPubKey = ScriptFactory::scriptPubKey()->payToPubKeyHash($key->getPublicKey()); $value = 100000000; $txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($value, $scriptPubKey); $destination = new WitnessProgram(0, $key->getPubKeyHash()); $p2sh = new \BitWasp\Bitcoin\Script\P2shScript($destination->getScript()); $tx = TransactionFactory::build()->spendOutPoint($outpoint)->output(95590000, $p2sh->getOutputScript())->get(); $signed = new \BitWasp\Bitcoin\Transaction\Factory\Signer($tx, $ec); $signed->sign(0, $key, $txOut); $ss = $signed->get(); echo $ss->getHex() . PHP_EOL;
/** * @param WitnessProgram $program * @param ScriptWitnessInterface $scriptWitness * @return int */ private function witnessSigOps(WitnessProgram $program, ScriptWitnessInterface $scriptWitness) { if ($program->getVersion() == 0) { $size = $program->getProgram()->getSize(); if ($size === 32 && count($scriptWitness) > 0) { $script = new Script($scriptWitness->bottom()); return $script->countSigOps(true); } if ($size === 20) { return 1; } } return 0; }
use BitWasp\Buffertools\Buffer; use BitWasp\Bitcoin\Key\PrivateKeyFactory; use BitWasp\Bitcoin\Script\ScriptFactory; use BitWasp\Bitcoin\Script\Script; use BitWasp\Bitcoin\Transaction\OutPoint; use BitWasp\Bitcoin\Transaction\TransactionFactory; use BitWasp\Bitcoin\Script\WitnessProgram; use BitWasp\Bitcoin\Script\P2shScript; use BitWasp\Bitcoin\Crypto\Hash; use BitWasp\Bitcoin\Script\Opcodes; use BitWasp\Bitcoin\Bitcoin; $wif = 'QP3p9tRpTGTefG4a8jKoktSWC7Um8qzvt8wGKMxwWyW3KTNxMxN7'; $s = \BitWasp\Bitcoin\Network\NetworkFactory::bitcoinSegnet(); Bitcoin::setNetwork($s); $ec = \BitWasp\Bitcoin\Bitcoin::getEcAdapter(); $key = PrivateKeyFactory::fromWif($wif); echo "Bitcoin address: " . $key->getPublicKey()->getAddress()->getAddress() . PHP_EOL; $outpoint = new OutPoint(Buffer::hex('23d6640c3f3383ffc8233fbd830ee49162c720389bbba1c313a43b06a235ae13', 32), 0); $destination = new WitnessProgram(0, $key->getPubKeyHash()); $p2sh = new \BitWasp\Bitcoin\Script\P2shScript($destination->getScript()); $value = 95590000; $txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($value, $p2sh->getOutputScript()); $tx = TransactionFactory::build()->spendOutPoint($outpoint)->payToAddress(94550000, $key->getPublicKey()->getAddress())->get(); $signed = new \BitWasp\Bitcoin\Transaction\Factory\Signer($tx, $ec); $signed->sign(0, $key, $txOut, $destination->getScript()); $ss = $signed->get(); $consensus = ScriptFactory::consensus(\BitWasp\Bitcoin\Script\Interpreter\InterpreterInterface::VERIFY_P2SH | \BitWasp\Bitcoin\Script\Interpreter\InterpreterInterface::VERIFY_WITNESS); echo "Script validation result: " . ($ss->validator()->checkSignature($consensus, 0, 95590000, $p2sh->getOutputScript()) ? "yay\n" : "nay\n"); echo PHP_EOL; echo $ss->getWitnessBuffer()->getHex() . PHP_EOL . PHP_EOL; echo $ss->getHex() . PHP_EOL;
use BitWasp\Buffertools\Buffer; use BitWasp\Bitcoin\Key\PrivateKeyFactory; use BitWasp\Bitcoin\Script\ScriptFactory; use BitWasp\Bitcoin\Script\Script; use BitWasp\Bitcoin\Transaction\OutPoint; use BitWasp\Bitcoin\Transaction\TransactionFactory; use BitWasp\Bitcoin\Script\WitnessProgram; use BitWasp\Bitcoin\Script\P2shScript; use BitWasp\Bitcoin\Crypto\Hash; use BitWasp\Bitcoin\Script\Opcodes; use BitWasp\Bitcoin\Bitcoin; $wif = 'QP3p9tRpTGTefG4a8jKoktSWC7Um8qzvt8wGKMxwWyW3KTNxMxN7'; $s = \BitWasp\Bitcoin\Network\NetworkFactory::bitcoinSegnet(); Bitcoin::setNetwork($s); $ec = \BitWasp\Bitcoin\Bitcoin::getEcAdapter(); $key = PrivateKeyFactory::fromWif($wif); echo "Bitcoin address: " . $key->getPublicKey()->getAddress()->getAddress() . PHP_EOL; $outpoint = new OutPoint(Buffer::hex('3382460d9b226a620c22a5ec435d4e0d2e698ee82c184f0331ea438db6ad3bad', 32), 0); $program = new WitnessProgram(0, $key->getPubKeyHash()); $scriptPubKey = $program->getScript(); $value = 99900000; $txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($value, $scriptPubKey); $tx = TransactionFactory::build()->spendOutPoint($outpoint)->payToAddress(99850000, $key->getPublicKey()->getAddress())->get(); $signed = new \BitWasp\Bitcoin\Transaction\Factory\Signer($tx, $ec); $signed->sign(0, $key, $txOut); $ss = $signed->get(); $consensus = ScriptFactory::consensus(\BitWasp\Bitcoin\Script\Interpreter\InterpreterInterface::VERIFY_P2SH | \BitWasp\Bitcoin\Script\Interpreter\InterpreterInterface::VERIFY_WITNESS); echo "Script validation result: " . ($ss->validator()->checkSignature($consensus, 0, 99900000, $scriptPubKey) ? "yay\n" : "nay\n"); echo PHP_EOL; echo $ss->getWitnessBuffer()->getHex() . PHP_EOL . PHP_EOL; echo $ss->getHex() . PHP_EOL;
require "../vendor/autoload.php"; use BitWasp\Buffertools\Buffer; use BitWasp\Bitcoin\Key\PrivateKeyFactory; use BitWasp\Bitcoin\Script\ScriptFactory; use BitWasp\Bitcoin\Script\Script; use BitWasp\Bitcoin\Transaction\OutPoint; use BitWasp\Bitcoin\Transaction\TransactionFactory; use BitWasp\Bitcoin\Script\WitnessProgram; use BitWasp\Bitcoin\Script\P2shScript; use BitWasp\Bitcoin\Crypto\Hash; use BitWasp\Bitcoin\Script\Opcodes; use BitWasp\Bitcoin\Bitcoin; $wif = 'QP3p9tRpTGTefG4a8jKoktSWC7Um8qzvt8wGKMxwWyW3KTNxMxN7'; $s = \BitWasp\Bitcoin\Network\NetworkFactory::bitcoinSegnet(); Bitcoin::setNetwork($s); $ec = \BitWasp\Bitcoin\Bitcoin::getEcAdapter(); $key = PrivateKeyFactory::fromWif($wif); echo "Bitcoin address: " . $key->getPublicKey()->getAddress()->getAddress() . PHP_EOL; $destScript = ScriptFactory::scriptPubKey()->payToPubKeyHash($key->getPublicKey()); $program = new WitnessProgram(0, Hash::sha256($destScript->getBuffer())); $outpoint = new OutPoint(Buffer::hex('c2197f15d510304f1463230c0e61566bfb8dcadb7e1c510d3c0470bcfbca2194', 32), 0); $txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput(99990000, $program->getScript()); $tx = TransactionFactory::build()->spendOutPoint($outpoint)->payToAddress(97900000, $key->getPublicKey()->getAddress())->get(); $signed = new \BitWasp\Bitcoin\Transaction\Factory\Signer($tx, $ec); $signed->sign(0, $key, $txOut, null, $destScript); $ss = $signed->get(); $consensus = ScriptFactory::consensus(\BitWasp\Bitcoin\Script\Interpreter\InterpreterInterface::VERIFY_P2SH | \BitWasp\Bitcoin\Script\Interpreter\InterpreterInterface::VERIFY_WITNESS); echo "Script validation result: " . ($ss->validator()->checkSignature($consensus, 0, 99990000, $txOut->getScript()) ? "yay\n" : "nay\n"); echo PHP_EOL; echo $ss->getWitnessBuffer()->getHex() . PHP_EOL . PHP_EOL; //echo $ss->getHex() . PHP_EOL;
/** * @param WitnessProgram $witnessProgram * @param ScriptWitness $scriptWitness * @param int $flags * @param Checker $checker * @return bool */ private function verifyWitnessProgram(WitnessProgram $witnessProgram, ScriptWitness $scriptWitness, $flags, Checker $checker) { $witnessCount = count($scriptWitness); if ($witnessProgram->getVersion() == 0) { $buffer = $witnessProgram->getProgram(); if ($buffer->getSize() === 32) { // Version 0 segregated witness program: SHA256(Script) in program, Script + inputs in witness if ($witnessCount === 0) { // Must contain script at least return false; } $scriptPubKey = new Script($scriptWitness[$witnessCount - 1]); $stackValues = $scriptWitness->slice(0, -1); $hashScriptPubKey = Hash::sha256($scriptPubKey->getBuffer()); if ($hashScriptPubKey == $buffer) { return false; } } elseif ($buffer->getSize() === 20) { // Version 0 special case for pay-to-pubkeyhash if ($witnessCount !== 2) { // 2 items in witness - <signature> <pubkey> return false; } $scriptPubKey = ScriptFactory::create()->sequence([Opcodes::OP_DUP, Opcodes::OP_HASH160, $buffer, Opcodes::OP_EQUALVERIFY, Opcodes::OP_CHECKSIG])->getScript(); $stackValues = $scriptWitness; } else { return false; } } elseif ($flags & self::VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM) { return false; } else { return false; } $mainStack = new Stack(); foreach ($stackValues as $value) { $mainStack->push($value); } if (!$this->evaluate($scriptPubKey, $mainStack, 1, $flags, $checker)) { return false; } if ($mainStack->count() !== 1) { return false; } if (!$this->castToBool($mainStack->bottom())) { return false; } return true; }