コード例 #1
0
ファイル: V1Hasher.php プロジェクト: nmarley/bitcoin-php
 /**
  * @param int $sighashType
  * @param int $inputToSign
  * @return Buffer|BufferInterface
  */
 public function hashOutputs($sighashType, $inputToSign)
 {
     if (($sighashType & 0x1f) !== SigHash::SINGLE && ($sighashType & 0x1f) != SigHash::NONE) {
         $binary = '';
         foreach ($this->transaction->getOutputs() as $output) {
             $binary .= $output->getBinary();
         }
         return Hash::sha256d(new Buffer($binary));
     } elseif (($sighashType & 0x1f) == SigHash::SINGLE && $inputToSign < count($this->transaction->getOutputs())) {
         return Hash::sha256($this->transaction->getOutput($inputToSign)->getBuffer());
     }
     return new Buffer('', 32);
 }
コード例 #2
0
 /**
  * Create an input for this transaction spending $tx's output, $outputToSpend.
  *
  * @param TransactionInterface $tx
  * @param $outputToSpend
  * @return $this
  */
 public function spendOutput(TransactionInterface $tx, $outputToSpend)
 {
     // Check TransactionOutput exists in $tx
     $tx->getOutputs()->getOutput($outputToSpend);
     $this->addInput(new TransactionInput($tx->getTransactionId(), $outputToSpend));
     return $this;
 }
コード例 #3
0
ファイル: UtxoSet.php プロジェクト: rubensayshi/bitcoin-php
 /**
  * @param TransactionInterface $tx
  */
 private function saveOutputs(TransactionInterface $tx)
 {
     $txid = $tx->getTransactionId();
     $vout = 0;
     foreach ($tx->getOutputs()->getOutputs() as $output) {
         $this->contents->save($this->cacheIndex($txid, $vout), new Utxo($txid, $vout++, $output));
     }
     $this->size += $vout;
 }
コード例 #4
0
 /**
  * @param TransactionInterface $transaction
  */
 private function processTransaction(TransactionInterface $transaction)
 {
     $results = [];
     $nOut = count($transaction->getOutputs());
     for ($i = 0; $i < $nOut; $i++) {
         $output = $transaction->getOutput($i);
         $script = $output->getScript()->getBinary();
         if (!isset($results[$script])) {
             $results[$script] = $output->getValue();
         } else {
             $results[$script] += $output->getValue();
         }
     }
     // Compare results to known contracts
     foreach ($this->contracts as $contract) {
         $requirements = $contract['requirements'];
         $rCount = count($requirements);
         $have = 0;
         foreach ($requirements as $script => $value) {
             if (isset($results[$script])) {
                 echo 'pmt';
                 if ($results[$script] >= $value) {
                     $have++;
                 }
             }
         }
         if ($have > 0) {
             if ($have < $rCount) {
                 $command = 'tx.partial';
             } else {
                 $command = 'tx.complete';
             }
             $this->listener->send(json_encode(['slug' => $contract['slug'], 'command' => $command, 'tx' => $transaction->getHex()]));
         }
     }
 }
コード例 #5
0
 /**
  * @param TransactionInterface $transaction
  * @return string
  */
 public function serialize(TransactionInterface $transaction)
 {
     return $this->getTemplate()->write([$transaction->getVersion(), $transaction->getInputs()->getInputs(), $transaction->getOutputs()->getOutputs(), $transaction->getLockTime()]);
 }
コード例 #6
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);
 }
コード例 #7
0
ファイル: Command.php プロジェクト: Bit-Wasp/node-php
 /**
  * @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)];
 }
コード例 #8
0
ファイル: Hasher.php プロジェクト: nmarley/bitcoin-php
 /**
  * @param TransactionInterface $transaction
  */
 public function __construct(TransactionInterface $transaction)
 {
     $this->transaction = $transaction;
     $this->nInputs = count($this->transaction->getInputs());
     $this->nOutputs = count($this->transaction->getOutputs());
 }
コード例 #9
0
ファイル: BlockCheck.php プロジェクト: sbwdlihao/node-php
 /**
  * @param UtxoView $view
  * @param TransactionInterface $tx
  * @param $spendHeight
  * @return bool
  */
 public function checkContextualInputs(UtxoView $view, TransactionInterface $tx, $spendHeight)
 {
     $valueIn = 0;
     for ($i = 0; $i < count($tx->getInputs()); $i++) {
         $utxo = $view->fetchByInput($tx->getInput($i));
         /*if ($out->isCoinbase()) {
               // todo: cb / height
               if ($spendHeight - $out->getHeight() < $this->params->coinbaseMaturityAge()) {
                   return false;
               }
           }*/
         $value = $utxo->getOutput()->getValue();
         $valueIn = $this->math->add($value, $valueIn);
         if (!$this->consensus->checkAmount($valueIn) || !$this->consensus->checkAmount($value)) {
             throw new \RuntimeException('CheckAmount failed for inputs value');
         }
     }
     $valueOut = 0;
     foreach ($tx->getOutputs() as $output) {
         $valueOut = $this->math->add($output->getValue(), $valueOut);
         if (!$this->consensus->checkAmount($valueOut) || !$this->consensus->checkAmount($output->getValue())) {
             throw new \RuntimeException('CheckAmount failed for outputs value');
         }
     }
     if ($this->math->cmp($valueIn, $valueOut) < 0) {
         throw new \RuntimeException('Value-in is less than value out');
     }
     $fee = $this->math->sub($valueIn, $valueOut);
     if ($this->math->cmp($fee, 0) < 0) {
         throw new \RuntimeException('Fee is less than zero');
     }
     if (!$this->consensus->checkAmount($fee)) {
         throw new \RuntimeException('CheckAmount failed for fee');
     }
     return true;
 }
コード例 #10
0
 /**
  * @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());
 }
コード例 #11
0
ファイル: BloomFilter.php プロジェクト: nmarley/bitcoin-php
 /**
  * @param TransactionInterface $tx
  * @return bool
  */
 public function isRelevantAndUpdate(TransactionInterface $tx)
 {
     $this->updateEmptyFull();
     $found = false;
     if ($this->isFull()) {
         return true;
     }
     if ($this->isEmpty()) {
         return false;
     }
     // Check if the txid hash is in the filter
     $txHash = $tx->getTxId();
     if ($this->containsData($txHash)) {
         $found = true;
     }
     // Check for relevant output scripts. We add the outpoint to the filter if found.
     foreach ($tx->getOutputs() as $vout => $output) {
         $script = $output->getScript();
         $parser = $script->getScriptParser();
         foreach ($parser as $exec) {
             if ($exec->isPush() && $this->containsData($exec->getData())) {
                 $found = true;
                 if ($this->isUpdateAll()) {
                     $this->insertOutPoint($tx->makeOutPoint($vout));
                 } else {
                     if ($this->isUpdatePubKeyOnly()) {
                         $type = ScriptFactory::scriptPubKey()->classify($script);
                         if ($type->isMultisig() || $type->isPayToPublicKey()) {
                             $this->insertOutPoint($tx->makeOutPoint($vout));
                         }
                     }
                 }
             }
         }
     }
     if ($found) {
         return true;
     }
     foreach ($tx->getInputs() as $txIn) {
         if ($this->containsOutPoint($txIn->getOutPoint())) {
             return true;
         }
         $parser = $txIn->getScript()->getScriptParser();
         foreach ($parser as $exec) {
             if ($exec->isPush() > 0 && $this->containsData($exec->getData())) {
                 return true;
             }
         }
     }
     return false;
 }
コード例 #12
0
ファイル: BlockCheck.php プロジェクト: Bit-Wasp/node-php
 /**
  * @param UtxoView $view
  * @param TransactionInterface $tx
  * @param int $spendHeight
  * @return $this
  */
 public function checkContextualInputs(UtxoView $view, TransactionInterface $tx, $spendHeight)
 {
     $valueIn = gmp_init(0);
     for ($i = 0, $nInputs = count($tx->getInputs()); $i < $nInputs; $i++) {
         /*if ($out->isCoinbase()) {
               // todo: cb / height
               if ($spendHeight - $out->getHeight() < $this->params->coinbaseMaturityAge()) {
                   return false;
               }
           }*/
         $value = gmp_init($view->fetchByInput($tx->getInput($i))->getOutput()->getValue(), 10);
         $valueIn = $this->math->add($valueIn, $value);
         $this->consensus->checkAmount($valueIn);
     }
     $valueOut = gmp_init(0);
     foreach ($tx->getOutputs() as $output) {
         $valueOut = $this->math->add($valueOut, gmp_init($output->getValue(), 10));
         $this->consensus->checkAmount($valueOut);
     }
     if ($this->math->cmp($valueIn, $valueOut) < 0) {
         throw new \RuntimeException('Value-in is less than value-out');
     }
     $fee = $this->math->sub($valueIn, $valueOut);
     $this->consensus->checkAmount($fee);
     return $this;
 }
コード例 #13
0
ファイル: TxMutator.php プロジェクト: nmarley/bitcoin-php
 /**
  * @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;
 }