Загрузка...

БИЛЛИНГ bitcoin+ПИТОН ДЛЯ ВАС

Тема в разделе Python создана пользователем Luucifer 5 апр 2020. 259 просмотров

  1. Luucifer
    Luucifer Автор темы 5 апр 2020 Заблокирован(а) 104 15 окт 2018
    В данном топике хочу рассказать о своих потугах написать на питоне биллинг для практически любого проекта на основе bitcoin.

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

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

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

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

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

    Идем по адресу /home/usr/.bitcoin
    И создаем тут файл конфигурации. mcedit bitcoin.conf
    Я использовал следующие настройки:
    Код
    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

    Код
    #!/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 для большей портабельности.

    Код клиента:
    Код
    #!/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 5 апр 2020 Актуальных контактов нет 538 17 июл 2019
    я запутался уже на словах питоне биллинг
     
  3. sesu
    sesu 5 апр 2020 Ты не умеешь писать код 114 17 ноя 2019
    Код твой?
     
  4. Dibb
    Dibb 6 апр 2020 Здесь могла быть ваша реклама 25 30 май 2017
    Курс берется с btc-e, судьба которой известна - вспомнил, прослезился:press_f:
     
Top
Загрузка...