Esempio n. 1
0
 /**
  * @param ScriptInterface $script
  * @param Buffer $sigBuf
  * @param Buffer $keyBuf
  * @return bool
  * @throws ScriptRuntimeException
  * @throws \Exception
  */
 private function checkSig(ScriptInterface $script, Buffer $sigBuf, Buffer $keyBuf)
 {
     $this->checkSignatureEncoding($sigBuf)->checkPublicKeyEncoding($keyBuf);
     try {
         $txSignature = TransactionSignatureFactory::fromHex($sigBuf->getHex());
         $publicKey = PublicKeyFactory::fromHex($keyBuf->getHex());
         return $this->ecAdapter->verify($this->transaction->getSignatureHash()->calculate($script, $this->inputToSign, $txSignature->getHashType()), $publicKey, $txSignature->getSignature());
     } catch (\Exception $e) {
         return false;
     }
 }
 /**
  * @param PrivateKeyInterface $privateKey
  * @param ScriptInterface $outputScript
  * @param $inputToSign
  * @param int $sigHashType
  * @param RedeemScript $redeemScript
  * @return $this
  * @throws \Exception
  */
 public function signInputWithKey(PrivateKeyInterface $privateKey, ScriptInterface $outputScript, $inputToSign, RedeemScript $redeemScript = null, $sigHashType = SignatureHashInterface::SIGHASH_ALL)
 {
     // If the input state hasn't been set up, do so now.
     try {
         $inputState = $this->getInputState($inputToSign);
     } catch (BuilderNoInputState $e) {
         $inputState = $this->createInputState($inputToSign, $outputScript, $redeemScript);
     }
     // If it's PayToPubkey / PayToPubkeyHash, TransactionBuilderInputState needs to know the public key.
     if (in_array($inputState->getPrevOutType(), [OutputClassifier::PAYTOPUBKEYHASH])) {
         $inputState->setPublicKeys([$privateKey->getPublicKey()]);
     }
     // loop over the publicKeys to find the key to sign with
     foreach ($inputState->getPublicKeys() as $idx => $publicKey) {
         if ($privateKey->getPublicKey()->getBinary() === $publicKey->getBinary()) {
             $inputState->setSignature($idx, $this->sign($privateKey, $this->transaction->getSignatureHash()->calculate($redeemScript ?: $outputScript, $inputToSign, $sigHashType), $sigHashType));
         }
     }
     return $this;
 }
Esempio n. 3
0
 /**
  * @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;
 }
Esempio n. 4
0
 /**
  * @param EcAdapterInterface $ecAdapter
  * @param TransactionInterface $tx
  */
 public function __construct(EcAdapterInterface $ecAdapter, TransactionInterface $tx)
 {
     $this->transaction = $tx;
     $this->signatureHash = $tx->getSignatureHash();
     $this->ecAdapter = $ecAdapter;
 }