/**
  * @param TransactionInterface $tx
  * @param int $inputToExtract
  * @return $this
  */
 public function extractSigs(TransactionInterface $tx, $inputToExtract)
 {
     $parsed = $tx->getInput($inputToExtract)->getScript()->getScriptParser()->decode();
     $size = count($parsed);
     switch ($this->getScriptType()) {
         case OutputClassifier::PAYTOPUBKEYHASH:
             // Supply signature and public key in scriptSig
             if ($size === 2) {
                 $this->signatures = [TransactionSignatureFactory::fromHex($parsed[0]->getData(), $this->ecAdapter)];
                 $this->publicKeys = [PublicKeyFactory::fromHex($parsed[1]->getData(), $this->ecAdapter)];
             }
             break;
         case OutputClassifier::PAYTOPUBKEY:
             // Only has a signature in the scriptSig
             if ($size === 1) {
                 $this->signatures = [TransactionSignatureFactory::fromHex($parsed[0]->getData(), $this->ecAdapter)];
             }
             break;
         case OutputClassifier::MULTISIG:
             $redeemScript = $this->getRedeemScript();
             $this->signatures = array_fill(0, count($this->publicKeys), null);
             if ($size > 2 && $size <= $this->scriptInfo->getKeyCount() + 2) {
                 $sigHash = $tx->getSignatureHash();
                 $sigSort = new SignatureSort($this->ecAdapter);
                 $sigs = new \SplObjectStorage();
                 foreach (array_slice($parsed, 1, -1) as $item) {
                     /** @var \BitWasp\Bitcoin\Script\Parser\Operation $item */
                     if ($item->isPush()) {
                         $txSig = TransactionSignatureFactory::fromHex($item->getData(), $this->ecAdapter);
                         $hash = $sigHash->calculate($redeemScript, $inputToExtract, $txSig->getHashType());
                         $linked = $sigSort->link([$txSig->getSignature()], $this->publicKeys, $hash);
                         foreach ($this->publicKeys as $key) {
                             if ($linked->contains($key)) {
                                 $sigs[$key] = $txSig;
                             }
                         }
                     }
                 }
                 // We have all the signatures from the input now. array_shift the sigs for a public key, as it's encountered.
                 foreach ($this->publicKeys as $idx => $key) {
                     $this->signatures[$idx] = isset($sigs[$key]) ? $sigs[$key] : null;
                 }
             }
             break;
     }
     return $this;
 }
Exemple #2
0
 /**
  * @param int $sigVersion
  * @param $stack
  * @param ScriptInterface $scriptCode
  * @return \SplObjectStorage
  */
 private function sortMultiSigs($sigVersion, $stack, ScriptInterface $scriptCode)
 {
     if ($sigVersion === 1) {
         $hasher = new V1Hasher($this->tx, $this->txOut->getValue());
     } else {
         $hasher = new Hasher($this->tx);
     }
     $sigSort = new SignatureSort($this->ecAdapter);
     $sigs = new \SplObjectStorage();
     foreach ($stack as $txSig) {
         $hash = $hasher->calculate($scriptCode, $this->nInput, $txSig->getHashType());
         $linked = $sigSort->link([$txSig->getSignature()], $this->publicKeys, $hash);
         foreach ($this->publicKeys as $key) {
             if ($linked->contains($key)) {
                 $sigs[$key] = $txSig;
             }
         }
     }
     return $sigs;
 }