Пример #1
0
 /**
  * Calculate the hash of the current transaction, when you are looking to
  * spend $txOut, and are signing $inputToSign. The SigHashType defaults to
  * SIGHASH_ALL, though SIGHASH_SINGLE, SIGHASH_NONE, SIGHASH_ANYONECANPAY
  * can be used.
  *
  * @param ScriptInterface $txOutScript
  * @param int $inputToSign
  * @param int $sighashType
  * @return BufferInterface
  * @throws \Exception
  */
 public function calculate(ScriptInterface $txOutScript, $inputToSign, $sighashType = SigHash::ALL)
 {
     $sighashType = (int) $sighashType;
     $hashPrevOuts = $this->hashPrevOuts($sighashType);
     $hashSequence = $this->hashSequences($sighashType);
     $hashOutputs = $this->hashOutputs($sighashType, $inputToSign);
     $input = $this->transaction->getInput($inputToSign);
     return Hash::sha256d(new Buffer(pack("V", $this->transaction->getVersion()) . $hashPrevOuts->getBinary() . $hashSequence->getBinary() . $input->getOutPoint()->getBinary() . ScriptFactory::create()->push($txOutScript->getBuffer())->getScript()->getBinary() . Buffer::int($this->amount, 8)->flip()->getBinary() . pack("V", $input->getSequence()) . $hashOutputs->getBinary() . pack("V", $this->transaction->getLockTime()) . pack("V", $sighashType)));
 }
Пример #2
0
 /**
  * @param \BitWasp\Bitcoin\Script\Interpreter\Number $sequence
  * @return bool
  */
 private function checkSequence(Number $sequence)
 {
     $txSequence = $this->transaction->getInput($this->inputToSign)->getSequence();
     if ($this->transaction->getVersion() < 2) {
         return false;
     }
     if ($this->math->cmp($this->math->bitwiseAnd($txSequence, TransactionInputInterface::SEQUENCE_LOCKTIME_DISABLE_FLAG), 0) !== 0) {
         return 0;
     }
     $mask = $this->math->bitwiseOr(TransactionInputInterface::SEQUENCE_LOCKTIME_TYPE_FLAG, TransactionInputInterface::SEQUENCE_LOCKTIME_MASK);
     return $this->verifyLockTime($this->math->bitwiseAnd($txSequence, $mask), TransactionInputInterface::SEQUENCE_LOCKTIME_TYPE_FLAG, Number::int($this->math->bitwiseAnd($sequence->getInt(), $mask)));
 }
Пример #3
0
 /**
  * @param \BitWasp\Bitcoin\Script\Interpreter\Number $sequence
  * @return bool
  */
 public function checkSequence(\BitWasp\Bitcoin\Script\Interpreter\Number $sequence)
 {
     $math = $this->adapter->getMath();
     $txSequence = $this->transaction->getInput($this->nInput)->getSequence();
     if ($this->transaction->getVersion() < 2) {
         return false;
     }
     if ($math->cmp($math->bitwiseAnd($txSequence, TransactionInputInterface::SEQUENCE_LOCKTIME_DISABLE_FLAG), 0) !== 0) {
         return 0;
     }
     $mask = $math->bitwiseOr(TransactionInputInterface::SEQUENCE_LOCKTIME_TYPE_FLAG, TransactionInputInterface::SEQUENCE_LOCKTIME_MASK);
     return $this->verifyLockTime($math->bitwiseAnd($txSequence, $mask), TransactionInputInterface::SEQUENCE_LOCKTIME_TYPE_FLAG, Number::int($math->bitwiseAnd($sequence->getInt(), $mask)));
 }
 /**
  * @param TransactionInterface $transaction
  * @return string
  */
 public function serialize(TransactionInterface $transaction)
 {
     return $this->getTemplate()->write([$transaction->getVersion(), $transaction->getInputs()->getInputs(), $transaction->getOutputs()->getOutputs(), $transaction->getLockTime()]);
 }
Пример #5
0
 /**
  * @param TransactionInterface $transaction
  * @return BufferInterface
  */
 public function serialize(TransactionInterface $transaction)
 {
     $math = Bitcoin::getMath();
     $int8le = new Int8($math, ByteOrder::LE);
     $int32le = new Int32($math, ByteOrder::LE);
     $uint32le = new Uint32($math, ByteOrder::LE);
     $varint = new VarInt($math, ByteOrder::LE);
     $vector = new Vector($varint, function () {
     });
     $binary = $int32le->write($transaction->getVersion());
     $flags = 0;
     if (!$transaction->getWitnesses()->isNull()) {
         $flags |= 1;
     }
     if ($flags) {
         $binary .= $int8le->write(0);
         $binary .= $int8le->write($flags);
     }
     $binary .= $vector->write($transaction->getInputs()->all());
     $binary .= $vector->write($transaction->getOutputs()->all());
     if ($flags & 1) {
         foreach ($transaction->getWitnesses() as $witness) {
             $binary .= $witness->getBuffer()->getBinary();
         }
     }
     $binary .= $uint32le->write($transaction->getLockTime());
     return new Buffer($binary);
 }
Пример #6
0
 /**
  * @param TransactionInterface $transaction
  * @return array
  */
 public function convertTransactionToArray(TransactionInterface $transaction)
 {
     $inputs = [];
     foreach ($transaction->getInputs() as $input) {
         $inputs[] = $this->convertTxinToArray($input);
     }
     $outputs = [];
     foreach ($transaction->getOutputs() as $output) {
         $outputs[] = $this->convertTxoutToArray($output);
     }
     $buf = $transaction->getBuffer()->getBinary();
     return ['hash' => $transaction->getTxId()->getHex(), 'version' => $transaction->getVersion(), 'inputs' => $inputs, 'outputs' => $outputs, 'locktime' => $transaction->getLockTime(), 'raw' => bin2hex($buf), 'size' => strlen($buf)];
 }
 /**
  * @param TransactionInterface $tx
  * @return Transaction
  */
 public function fixTransaction(Peer $sender, TransactionInterface $tx, &$wasMalleated = false)
 {
     $c = count($tx->getInputs());
     $new = new TransactionInputCollection();
     for ($i = 0; $i < $c; $i++) {
         $input = $tx->getInput($i);
         $script = $input->getScript();
         $classify = ScriptFactory::scriptSig()->classify($input->getScript());
         $this->inputs++;
         if ($classify->isPayToPublicKeyHash()) {
             $parsed = $input->getScript()->getScriptParser()->parse();
             $txSig = TransactionSignatureFactory::fromHex($parsed[0]);
             $txSig = $this->fixSig($sender, $txSig, $wasMalleated);
             $script = ScriptFactory::create()->push($txSig->getBuffer())->push($parsed[1])->getScript();
         }
         $new->addInput(new TransactionInput($input->getTransactionId(), $input->getVout(), $script, $input->getSequence()));
     }
     return new Transaction($tx->getVersion(), $new, $tx->getOutputs(), $tx->getLockTime());
 }
Пример #8
0
 /**
  * @param array $array
  * @return $this
  */
 private function replace(array $array = [])
 {
     $this->transaction = new Transaction(array_key_exists('version', $array) ? $array['version'] : $this->transaction->getVersion(), array_key_exists('inputs', $array) ? $array['inputs'] : $this->transaction->getInputs(), array_key_exists('outputs', $array) ? $array['outputs'] : $this->transaction->getOutputs(), array_key_exists('witness', $array) ? $array['witness'] : $this->transaction->getWitnesses(), array_key_exists('nLockTime', $array) ? $array['nLockTime'] : $this->transaction->getLockTime());
     return $this;
 }