Master-X
Форум | Новости | Статьи
Главная » Форум » Программинг, Скрипты, Софт, Сервисы » 
Тема: Скрипт приёма Bitcoin
цитата
01/12/13 в 19:29
 pornoNote
Ку всем.

Кто что знает?
Пока нарыл только http://bitfreak.info/bitshop/
цитата
01/12/13 в 19:48
 Pentarh
Я свой писал =)

Для прямого приема нужен bitcoind на сервере, а это 10 мбит трафика, 30 гиг свободного места и кастомные скрипты )

Для непрямого можешь подключиться к посредникам, они все предоставят.
цитата
02/12/13 в 14:45
 pornoNote
Стороннее не хочу, люблю всё контролировать.
Неужели нет уже готовых решений?

И если рассматривать как кастомные скрипты, сколько это будет стоить примерно? 1, 2к?
цитата
02/12/13 в 14:47
 Pentarh
Ты скажи, ты хочешь напрямую принимать сами bitcoin прямо на свой кошелек без всяких посредников?

Какой движок у магазина? Или еще нет магазина?
цитата
02/12/13 в 14:53
 pornoNote
Pentarh писал:
Ты скажи, ты хочешь напрямую принимать сами bitcoin прямо на свой кошелек без всяких посредников?
Какой движок у магазина? Или еще нет магазина?

Ну в идеале чтобы скрипт перекидывал человека на (допустим) Mt.Gox, да без посредников, свой дедик.
Да, магаза нет ещё icon_biggrin.gif Сначала скрипт, магаз дело не долгое,
а магаз к примеру: osCommerce, Magento, OpenCart, UberCart (Drupal)
цитата
02/12/13 в 14:57
 Pentarh
pornoNote писал:
чтобы скрипт перекидывал человека на (допустим) Mt.Gox, да без посредников

Взаимоисключающие параграфы

Ты или принимаешь биткоин сам, это сложнее. Или через посредника, MtGox, bitpay и т.д. Это легче, есть готорые скрипты у них и они снимают процент.
цитата
02/12/13 в 14:59
 pornoNote
ок. свои скрипты, без посредников. сколько это будет стоить?
ты вот например возмёшся? icon_smile.gif
цитата
02/12/13 в 15:10
 Alexandur
pornoNote писал:
а магаз к примеру: osCommerce, Magento, OpenCart, UberCart (Drupal)


Так забей название в поисковик +bitcoin и всё будет.
цитата
02/12/13 в 15:14
 Pentarh
Ну вот мои интерфейсы к bitcoind. Сам код обработки не покажу, но принцип расскажу.

1. На каждый платеж генерируется уникальный адрес в bitcoind и на него ожидается поступление средств.
2. Когда обнаружена транзакция на этот адрес, она регистрируется в базе как неподтвержденная (если 0 подтверждений).
3. Далее, bitcoind периодически опрашивается на предмет неподтвержденных транзакций в базе. Если замечено N подтверждений, транзакция помечается как законченная. N рекомендуется ставить от 1 (около 10 минут ожидания) до 6 (час ожидания). Чем больше, тем секурнее, но и неудобнее.
4. Следует учитывать что в одной странзакции может быть несколько платежей на разные адреса.
5. Вместо тяжелого bitcoind можно заюзать более легкий BitcoinJ.

<?php

class BitcoinClient {
    protected $host='localhost';
    protected $port=8332;
    protected $user='';
    protected $password='';
    protected $rpc;

    public function __construct($host,$user,$password,$port=8332) {
        $this->host=$host;
        $this->port=$port;
        $this->user=$user;
        $this->password=$password;
        $this->rpc=NULL;
    }

    function __destruct() {
        $this->disconnect();
    }

    protected function connect() {
        if (is_null($this->rpc)) {
            $this->rpc=new jsonRPCClient('http://'.$this->user.':'.$this->password.'@'.$this->host.':'.$this->port.'/');
            Yii::getLogger()->log("Connecting to $this->host",'trace','BitcoinClient');
        }
    }

    protected function disconnect() {
        $this->rpc=NULL;
    }

    /**
     * Bitcoin getinfo()
     * @return array key/value server status
     */
    public function getInfo() {
        $this->connect();
        return $this->rpc->getinfo();
    }

    public function getBlock($hash) {
        $this->connect();
        return $this->rpc->getblock($hash);
    }

    /**
     * Get new address
     * @param string $account
     * @return string new address
     */
    public function getNewAddress($account) {
        $this->connect();
        return $this->rpc->getnewaddress($account);
    }

    /**
     * Get recent transactions list
     * @param string $account account or * for all
     * @param int $num limit number of transactions
     * @return array - Array of assoc arrays with transactions
     *
     * Example:
Array
(
    [0] => Array
        (
            [account] => u5
            [address] => 16WNVA297DTgoZ9Lskh2u9Nk2SvBKLZVwH
            [category] => receive
            [amount] => 0.01
            [confirmations] => 80
            [blockhash] => 00000000000001e41863fc702b86ddf0d7f7a75be739635463c52eb7560b8202
            [blockindex] => 45
            [blocktime] => 1361926729
            [txid] => 956efd7e65b9aaef1c422b327355c4d19aa21f10b6c6bc934c494b25601a27fe
            [time] => 1361926249
            [timereceived] => 1361926249
        )

    [1] => Array
        (
            [account] => u1
            [address] => 1K7u377faB6gAtrYV5XgQZWBGrm241qYLV
            [category] => receive
            [amount] => 0.02
            [confirmations] => 80
            [blockhash] => 00000000000001e41863fc702b86ddf0d7f7a75be739635463c52eb7560b8202
            [blockindex] => 22
            [blocktime] => 1361926729
            [txid] => a31bdd8168d130e4eac9c5fd19079a258c14dda22c278dc8a1e30ec1f18aa244
            [time] => 1361926368
            [timereceived] => 1361926368
        )
)
     */
    public function listTransactions($account,$num) {
        $this->connect();
        return $this->rpc->listtransactions($account,$num);
    }

    /**
     * Get local transaction details
     * @param string $txid - TXID
     * @return array - TX info
     *
     * Example:
Array
(
    [amount] => 0.03
    [confirmations] => 82
    [blockhash] => 00000000000001e41863fc702b86ddf0d7f7a75be739635463c52eb7560b8202
    [blockindex] => 22
    [blocktime] => 1361926729
    [txid] => a31bdd8168d130e4eac9c5fd19079a258c14dda22c278dc8a1e30ec1f18aa244
    [time] => 1361926368
    [timereceived] => 1361926368
    [details] => Array
        (
            [0] => Array
                (
                    [account] => u5
                    [address] => 16WNVA297DTgoZ9Lskh2u9Nk2SvBKLZVwH
                    [category] => receive
                    [amount] => 0.01
                )

            [1] => Array
                (
                    [account] => u1
                    [address] => 1K7u377faB6gAtrYV5XgQZWBGrm241qYLV
                    [category] => receive
                    [amount] => 0.02
                )

        )

)

     */
    public function getTransaction($txid) {
        $this->connect();
        return $this->rpc->gettransaction($txid);
    }

    public function validateAddress($address) {
        $this->connect();
        $result=$this->rpc->validateaddress($address);
        if (is_array($result) && isset ($result['isvalid']) && $result['isvalid']==1) {
            return true;
        }
        return false;
    }

    /**
     * Send many payments in 1 transaction
     * @param string $account - Account. * DO NOT WORKS
     * @param array $payments Key/valua array of destination address/amount
     * @param integer $minconf
     * @param string $comment
     * @return string transaction ID
     */
    public function sendMany($account,&$payments,$minconf=1,$comment='') {
        $this->connect();
        if (is_array($payments)) {
            // Need to cast explicitly to float
            foreach($payments as $addr=>$amount) {
                $payments[$addr]=floatval($amount);
            }
        } else {
            throw new Exception("BitcoinClient::sendMany(): \$payments expected to be an array");
        }
        if ($comment) {
            return $this->rpc->sendmany($account,$payments,$minconf,$comment);
        }
        return $this->rpc->sendmany($account,$payments,$minconf);
    }

    /**
     * Send coins to one address in single transaction
     * @param string $toaddress Destination
     * @param float $amount Amount
     * @param string $comment comment
     */
    public function send($toaddress,$amount,$comment=null) {
        $this->connect();
        if (!$this->validateAddress($toaddress)) {
            throw new Exception("Invalid address: $toaddress");
        }
        if (!is_numeric($amount) || $amount<=0) {
            throw new Exception("Invalid amount: $amount");
        }
        $amount=floatval($amount);
        if ($comment) {
            return $this->rpc->sendtoaddress($toaddress,$amount,$comment);
        }
        return $this->rpc->sendtoaddress($toaddress,$amount);
    }

    public function getBalanceAccount($account) {
        $this->connect();
        return $this->rpc->getbalance($account);
    }

    public function getBalance() {
        $this->connect();
        $info=$this->getInfo();
        return $info['balance'];
    }
}


<?php
/*
               COPYRIGHT

Copyright 2007 Sergio Vaccaro <sergio@inservibile.org>

This file is part of JSON-RPC PHP.

JSON-RPC PHP is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

JSON-RPC PHP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with JSON-RPC PHP; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/**
* The object of this class are generic jsonRPC 1.0 clients
* http://json-rpc.org/wiki/specification
*
* @author sergio <jsonrpcphp@inservibile.org>
*/
class jsonRPCClient {

   /**
    * Debug state
    *
    * @var boolean
    */
   private $debug;

   /**
    * The server URL
    *
    * @var string
    */
   private $url;
   /**
    * The request id
    *
    * @var integer
    */
   private $id;
   /**
    * If true, notifications are performed instead of requests
    *
    * @var boolean
    */
   private $notification = false;

   /**
    * Takes the connection parameters
    *
    * @param string $url
    * @param boolean $debug
    */
   public function __construct($url,$debug = false) {
      // server URL
      $this->url = $url;
      // proxy
      empty($proxy) ? $this->proxy = '' : $this->proxy = $proxy;
      // debug state
      empty($debug) ? $this->debug = false : $this->debug = true;
      // message id
      $this->id = 1;
   }

   /**
    * Sets the notification state of the object. In this state, notifications are performed, instead of requests.
    *
    * @param boolean $notification
    */
   public function setRPCNotification($notification) {
      empty($notification) ?
                     $this->notification = false
                     :
                     $this->notification = true;
   }

   /**
    * Performs a jsonRCP request and gets the results as an array
    *
    * @param string $method
    * @param array $params
    * @return array
    */
   public function __call($method,$params) {

      // check
      if (!is_scalar($method)) {
         throw new Exception('Method name has no scalar value');
      }

      // check
      if (is_array($params)) {
         // no keys
         $params = array_values($params);
      } else {
         throw new Exception('Params must be given as array');
      }

      // sets notification or request task
      if ($this->notification) {
         $currentId = NULL;
      } else {
         $currentId = $this->id;
      }

      // prepares the request
      $request = array(
                  'method' => $method,
                  'params' => $params,
                  'id' => $currentId
                  );
      //var_dump($request);
                $request = json_encode($request);
                //print($request);
      $this->debug && $this->debug.='***** Request *****'."\n".$request."\n".'***** End Of request *****'."\n\n";

      // performs the HTTP POST
      $opts = array ('http' => array (
                     'method'  => 'POST',
                     'header'  => 'Content-type: application/json',
                     'content' => $request,
                                                        'ignore_errors' => true,
                     ));
      $context  = stream_context_create($opts);
      if ($fp = @fopen($this->url, 'r', false, $context)) {
         $response = '';
         while($row = fgets($fp)) {
            $response.= trim($row)."\n";
         }
         $this->debug && $this->debug.='***** Server response *****'."\n".$response.'***** End of server response *****'."\n";
         $response = json_decode($response,true);
      } else {
         throw new Exception('Unable to connect to '.$this->url);
      }

      // debug output
      if ($this->debug) {
         echo nl2br($this->debug);
      }

      // final checks and return
      if (!$this->notification) {
         // check
         if ($response['id'] != $currentId) {
            throw new Exception('Incorrect response id (request id: '.$currentId.', response id: '.$response['id'].')');
         }
         if (!is_null($response['error'])) {
                                $error=is_array($response['error'])?$response['error']['message']:$response['error'];
            throw new Exception('Got error: '.$error);
         }

         return $response['result'];

      } else {
         return true;
      }
   }
}
цитата
02/12/13 в 15:18
 Pentarh
gimcnuk писал:
Так забей название в поисковик +bitcoin и всё будет.

Ну да, это тоже вариант. Вот например

https://en.bitcoin.it/wiki/OsCommerce_Bitcoin_Payment_Module
цитата
02/12/13 в 15:20
 Stek
Так у биткойна же подтверждение транзакции долгое. Как вы это в скрипте решать то будете ? Там по пол часа перевод идти может.
цитата
02/12/13 в 15:22
 Pentarh


Есть нюансы. Например, помечать неподтвержденные транзакции как условно оплаченные, отпускать клиента. Но отгрузку делать только когда они реально подтвердятся.

Или в казино вот. Принимать неподтвержденные транзакции для пополнения баланса и разрешать играть, но вывод средств разрешать только после подтверждения.
цитата
02/12/13 в 15:24
 pornoNote
Pentarh писал:
помечать неподтвержденные транзакции как условно оплаченные, отпускать клиента.

Именно это и предполагалось. Спс за инфу, буду рыть.


Эта страница в полной версии