Загрузка...

BILLING bitcoin+PYTHON FOR YOU

Thread in Python created by Luucifer Apr 5, 2020. 258 views

  1. Luucifer
    Luucifer Topic starter Apr 5, 2020 Banned 104 Oct 15, 2018
    В данном топике хочу рассказать о своих потугах написать на питоне биллинг для практически любого проекта на основе bitcoin.

    Материал сырой, кодер я не супер, поэтому критика принимается.
    Поехали...

    Первое что нам понадобится - сервер. Я использовал debian linux (свой любимый) 64 bit.

    Нам для старта понадобится скачать оффициальный клиент bitcoin. Download page

    Скачиваем клиент, распаковываем в произвольную папку пользователя.
    В моем случае используется /home/usr/bitcoind
    Переходим в папку bin/64/
    Запускаем ./bitcoind

    Все что необходимо он уже создал. Далее нам предстоит настроить данный софт.
    Пишем в консоль killall bitcoind

    Идем по адресу /home/usr/.bitcoin
    И создаем тут файл конфигурации. mcedit bitcoin.conf
    Я использовал следующие настройки:
    Code
    daemon=1
    gen=0
    #proxy=127.0.0.1:9050
    dns=1
    upnp=1
    noirc=1
    server=1
    rpcuser=usr
    rpcpassword=fake_passwords
    rpcport=8455
    rpctimeout=30
    paytxfee=0.0002
    addnode=69.207.126.238:8333
    addnode=73.189.41.65:8333
    addnode=69.65.67.66:8333
    connect=69.207.126.238:8333
    connect=73.189.41.65:8333
    connect=69.65.67.66:8333
    Возвращаемся в папку /home/usr/bitcoind/bin/64
    Стартуем демон снова ./bitcoind

    Все. Наш клиент стал демоном и начал синхронизировать блоки.
    Для любопытных - вторая строка - это настройка работы биткоин через сеть тор. У меня на сервере он установлен, но для ускорения синхронизации не используется.

    Далее примем за аксиому тот момент, что я сам пишу софт и отталкиваюсь от того что мне в голову стукнет. А мои клиенты все определяются по jabber аккаунту.

    Я создаю следующие папки:
    /home/usr/bitcoind/src/
    /home/usr/bitcoind/src/db/
    Выставляю права 777 на папку db. Это важно.
    И создаем следующие файлы:
    cat>btc.log
    chmod 777 btc.log
    mcedit btc.py

    Code
    #!/usr/bin/env python
    #-*- coding: utf-8 -*-

    # ----------------------------------------------------------
    # coded by ar3s
    # How to use: python btc-e.py
    # Profit!
    # ----------------------------------------------------------

    import os
    import sys
    import time
    import json
    import base64
    import hashlib
    import urllib2
    import datetime
    import socket
    import sqlite3
    import subprocess
    from Crypto.Cipher import AES # encryption library

    #system
    os.system('clear')
    #sqlite
    conn = sqlite3.connect('db/base.db')
    conn.isolation_level = None
    conn.text_factory = str
    #crypt
    BLOCK_SIZE = 32
    PADDING = '{'
    pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
    cipher = AES.new('Jns70wJnc92LmaTw')

    def log(log):
    if (len(log) != 0):
    now = datetime.datetime.now()
    f = open('btc.log', 'a')
    f.write(str(now.day)+"."+str(now.month)+"."+str(now.year)+" "+str(now.hour)+":"+str(now.minute)+":"+str(now.second)+" - "+log+"\n")
    f.close()
    else:
    print "enter a log data"

    def rate():
    response = urllib2.urlopen(urllib2.Request(url='https://btc-e.com/api/2/btc_usd/ticker'))
    objFromJSON = json.loads(response.read())
    ticker = objFromJSON['ticker']
    return format(ticker['last'])

    def bitcoin(cmd, jid):
    if (cmd == "bal"):
    try:
    cmd = './bitcoind getbalance'
    PIPE = subprocess.PIPE
    p = subprocess.Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=subprocess.STDOUT, close_fds=True, cwd='/home/usr/bitcoind/bin/64/')
    bal = p.stdout.read()
    bal = float(bal.replace('\n',''))
    return bal
    except:
    print "bitcoind not respond a ballance"


    if (cmd == "add"):
    try:
    cmd = './bitcoind getnewaddress '+jid
    PIPE = subprocess.PIPE
    p = subprocess.Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=subprocess.STDOUT, close_fds=True, cwd='/home/usr/bitcoind/bin/64/')
    btc = p.stdout.read()
    btc = btc.replace('\n','')
    except:
    print "bitcoind not respond a BTC address"
    return btc

    if (cmd == "pars"):
    ball = 0.0
    account = ""
    try:
    cmd = './bitcoind listaccounts'
    PIPE = subprocess.PIPE
    p = subprocess.Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=subprocess.STDOUT, close_fds=True, cwd='/home/usr/bitcoind/bin/64/')
    btc = p.stdout.read()
    # сделать парсинг не нулевых баллансов и возврат имени и суммы в запрос
    except:
    log("bitcoind send not finished")
    return account, ball

    def sql(query):
    #--------------------------
    # Коннектимся к Базе данных
    #--------------------------
    connection = 0
    try:
    #conn = sqlite3.connect(":memory:")

    cur = conn.cursor()
    connection = 1
    except sqlite3.Error:
    connection = 0
    log("Соединение с БД НЕ установлено!!!")

    if ((query=='def') and (connection == 1)):
    #print "Исполняем def запрос"
    try:
    cur.execute("Select * from user")
    conn.commit()
    #print "DEF запрос прошел успешно"
    except:
    print 'db not issue. Creating.'
    cur.execute('''CREATE TABLE [user] ([id] INTEGER NOT NULL ON CONFLICT ABORT PRIMARY KEY ON CONFLICT ABORT AUTOINCREMENT, [jid] CHAR NOT NULL ON CONFLICT ABORT, [btc] CHAR NOT NULL ON CONFLICT ABORT, [ballance] FLOAT NOT NULL ON CONFLICT ABORT DEFAULT 0)''')
    cur.execute("insert into user values (null,'ar3s@dlab.im','FakeAddress','0')")
    conn.commit()

    if ((query != 'def') and (connection == 1)):
    #print "Исполняем запрос на пользователя"
    # Тут проверяем имеется ли такой пользователь
    btc = ""
    jid = query
    #print "Проверка по БД"
    try:
    cur.execute("select btc from user where jid=?",(jid,))
    conn.commit()
    except:
    print "BAD sql query in section select BTC from DB"

    #print "Парсим результат"
    data = cur.fetchall()
    if (len(data) != 0):
    #print "Вошли в проверку"
    adr = str(data[0])
    adr = adr.split("'")
    btc = adr[1]
    #print btc
    #print "Распарсили"
    else:
    # если ответ нулевой - то создаем пользователя
    btc = bitcoin("add", jid)
    print "Добавляем пользователя "+jid+":"+btc+"\n"
    try:
    cur.execute("insert into user values (null,?,?,'0')",(jid,btc,))
    conn.commit()
    except:
    print "Error in sql query for add user in DB"
    return btc

    def crypt(msg):
    EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
    encoded = EncodeAES(cipher, msg)
    return encoded

    def decrypt(msg):
    DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
    decoded = DecodeAES(cipher, msg)
    return decoded

    def main():
    #-------------------------------
    # Тест записи в лог
    log("start")

    #-------------------------------
    # Читаем курс
    kurs = rate()
    print "Текущий курс BTC=>USD:"+kurs
    log("Текущий курс BTC=>USD:"+kurs)

    #-------------------------------
    # читаем наш балланс из демона
    bal = bitcoin("bal", "")
    print "Текущий балланс кошельков:"+str(bal)
    log("Текущий балланс кошельков:"+str(bal))
    if (bal > 0):
    account, ball = bitcoint("pars", "")
    # тут сделать зачисление на балланс и отправку мне на кош

    #-------------------------------
    # Инициализируем БД
    sql("def")
    log("Инициализируем БД")

    #-------------------------------
    # инициализируем чтение сокета
    try:
    sock = socket.socket()
    sock.bind(('', 4563))
    sock.listen(1)

    except Exception as e:
    log("Не могу открыть сокет: %s" % e)
    sys.exit()

    while True:
    srv, addr = sock.accept()
    log("Socket opened: %s" % str(addr))

    data = srv.recv(1024)
    data = decrypt(data)
    if data == 'PPDvtmw1POWFSkwmNH61WF0Vlhvhq5Gc':
    log("Проверка ключа прошла успешно")
    srv.send(crypt('true'))
    data = '' # обнуляем данные от прошлого запроса
    while 1: # ждем запрос от клиента
    data = srv.recv(1024)
    if data:
    break

    jid = decrypt(data)
    if jid:
    print jid
    btc = sql(jid)
    print "user "+jid+" : "+ btc
    srv.send(crypt(btc))
    log("Answer sendet")
    else:
    srv.send("error!")
    log("!!! Проверка ключа НЕ прошла")
    srv.close()


    # start main function
    if __name__ == '__main__':
    main()

    #--------------------------------------------------------------------------------------------------------------
    # Happy end!
    #--------------------------------------------------------------------------------------------------------------
    Протокол запросов идет у нас шифрованным. Ключ один, но можно использовать два. Один от клиента второй от сервера.

    Принцип работы прост. Есть демон и есть бд. Что бы не дергать демон каждый раз я записываю данные в БД. Сделал специально на sqlite для большей портабельности.

    Код клиента:
    Code
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    #http://stackoverflow.com/questions/2490334/simple-way-to-encode-a-string-according-to-a-password

    import socket
    import base64
    import hashlib
    from Crypto.Cipher import AES # encryption library

    BLOCK_SIZE = 32
    PADDING = '{'
    pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
    cipher = AES.new('Jns70wJnc92LmaTw')

    def crypt(msg):
    EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
    encoded = EncodeAES(cipher, msg)
    return encoded

    def decrypt(msg):
    DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
    decoded = DecodeAES(cipher, msg)
    return decoded

    sock = socket.socket()
    sock.connect(('127.0.0.1', 4563))
    sock.send(crypt('PPDvtmw1POWFSkwmNH61WF0Vlhvhq5Gc'))
    data = sock.recv(1024)
    data = decrypt(data)
    print data
    if (data == 'true'):
    sock.send(crypt('new_user@server.im'))
    data = sock.recv(1024)
    data = decrypt(data)

    print data
    sock.close()
    Клиент первым делом шифрует ключевую фразу и шлет серверу. Если все ок - сервер отвечает шифрованным true. Ну и дальше идет запрос на клиента (отправляем жабу или мыло), ответ BTC адрес.

    В данный момент чего не доделал:
    1. определение у кого какой балланс
    2. отправку комманды на пополнение балланса в панель клиента
    3. перекидывание денег с сервака биллинга мне на кош.

    Написано данное чудо просто от балды. От большого нехер делать и может быть кому-то полезно. Жду реакции и критики кода. А так же желающих доработать данное творчество.
     
  2. Rblndik
    Rblndik Apr 5, 2020 Актуальных контактов нет 538 Jul 17, 2019
    я запутался уже на словах питоне биллинг
     
  3. sesu
    sesu Apr 5, 2020 Ты не умеешь писать код 114 Nov 17, 2019
    Код твой?
     
  4. Dibb
    Dibb Apr 6, 2020 Здесь могла быть ваша реклама 25 May 30, 2017
    Курс берется с btc-e, судьба которой известна - вспомнил, прослезился:press_f:
     
Loading...
Top