mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-05-13 09:08:02 +08:00
Added bip38 decryption files, tested out register and activate on new DB, and added profile conversion code (v1 to v2)
This commit is contained in:
@@ -5,7 +5,7 @@ import json
|
||||
import requests
|
||||
|
||||
from time import sleep
|
||||
from coinrpc.coinrpc import namecoind_blocks, namecoind_firstupdate
|
||||
from coinrpc.namecoin.namecoind_wrapper import namecoind_blocks, namecoind_firstupdate
|
||||
|
||||
blocks = namecoind_blocks()
|
||||
|
||||
@@ -74,7 +74,6 @@ def do_name_firstupdate():
|
||||
|
||||
output = namecoind_firstupdate(entry['key'],entry['rand'],update_value,entry['longhex'])
|
||||
|
||||
#output = namecoind_firstupdate(entry['key'], entry['rand'], update_value, entry['longhex'])
|
||||
print "Transaction ID ", output
|
||||
|
||||
if 'message' in output and output['message'] == "this name is already active":
|
||||
@@ -90,7 +89,7 @@ def do_name_firstupdate():
|
||||
|
||||
#sleep(1)
|
||||
else:
|
||||
pass
|
||||
print "wait: " + str(entry['wait_till_block'] - current_blocks) + " blocks"
|
||||
|
||||
#-----------------------------------
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,28 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
SLEEP_INTERVAL = 1
|
||||
#-----------------------
|
||||
# Copyright 2014 Halfmoon Labs, Inc.
|
||||
# All Rights Reserved
|
||||
#-----------------------
|
||||
|
||||
#520 is the real limit
|
||||
VALUE_MAX_LIMIT = 512
|
||||
|
||||
from time import sleep
|
||||
|
||||
import requests
|
||||
import json
|
||||
|
||||
from coinrpc.coinrpc import namecoind_blocks, namecoind_name_new, check_registration
|
||||
from coinrpc.coinrpc import namecoind_name_update, namecoind_name_show
|
||||
from coinrpc.namecoin.namecoind_wrapper import namecoind_blocks, namecoind_name_new, check_registration
|
||||
from coinrpc.namecoin.namecoind_wrapper import namecoind_name_update, namecoind_name_show
|
||||
|
||||
from config import LOAD_BALANCER
|
||||
|
||||
#-----------------------------------
|
||||
from pymongo import MongoClient
|
||||
db = MongoClient['namecoin']
|
||||
queue = db.queue
|
||||
codes = db.codes
|
||||
client = MongoClient()
|
||||
|
||||
from config import MONGODB_URI, HEROKU_APP
|
||||
local_db = client['namecoin']
|
||||
queue = local_db.queue
|
||||
codes = local_db.codes
|
||||
|
||||
from config import MONGODB_URI
|
||||
remote_client = MongoClient(MONGODB_URI)
|
||||
users = remote_client[HEROKU_APP].user
|
||||
remote_db = remote_client.get_default_database()
|
||||
users = remote_db.user
|
||||
registrations = remote_db.user_registration
|
||||
|
||||
#-----------------------------------
|
||||
def utf8len(s):
|
||||
@@ -132,7 +138,6 @@ def register_name(key,value):
|
||||
|
||||
print reply
|
||||
print '---'
|
||||
sleep(SLEEP_INTERVAL)
|
||||
|
||||
#-----------------------------------
|
||||
def update_name(key,value):
|
||||
@@ -157,7 +162,6 @@ def update_name(key,value):
|
||||
print reply
|
||||
print info
|
||||
print '---'
|
||||
sleep(SLEEP_INTERVAL)
|
||||
|
||||
#----------------------------------
|
||||
def get_old_keys(username):
|
||||
@@ -191,7 +195,7 @@ def get_old_keys(username):
|
||||
return old_keys
|
||||
|
||||
#-----------------------------------
|
||||
def process_user(username,profile,accesscode=None):
|
||||
def process_user(username,profile):
|
||||
|
||||
old_keys = get_old_keys(username)
|
||||
|
||||
@@ -206,28 +210,8 @@ def process_user(username,profile,accesscode=None):
|
||||
if check_registration(key1):
|
||||
|
||||
#if name is registered
|
||||
check_profile = namecoind_name_show(key1)
|
||||
|
||||
try:
|
||||
check_profile = check_profile['value']
|
||||
|
||||
#if name is reserved, check code
|
||||
if 'status' in check_profile and check_profile['status'] == 'reserved':
|
||||
|
||||
print "name reserved: " + key1
|
||||
code = codes.find_one({'username':key1})
|
||||
if code['accesscode'] == accesscode:
|
||||
print "code match"
|
||||
update_name(key1,value1)
|
||||
else:
|
||||
#if registered but not reserved
|
||||
print "name update: " + key1
|
||||
update_name(key1,value1)
|
||||
|
||||
except Exception as e:
|
||||
#if registered but not reserved
|
||||
print "name update: " + key1
|
||||
update_name(key1,value1)
|
||||
print "name update: " + key1
|
||||
update_name(key1,value1)
|
||||
|
||||
else:
|
||||
#if not registered
|
||||
@@ -290,31 +274,23 @@ def set_backend_server(DISTRIBUTE=True):
|
||||
print "sending " + i['username'] + " to backend_server " + str(selected_server)
|
||||
|
||||
#-----------------------------------
|
||||
def check_new_registrations(IS_LIVE=False):
|
||||
def check_new_registrations(LIVE=True):
|
||||
|
||||
registered_counter = 0
|
||||
unregistered_counter = 0
|
||||
|
||||
print '-' * 5
|
||||
print "Checking for new users"
|
||||
for user in users.find():
|
||||
for user in registrations.find():
|
||||
|
||||
if 'dispatched' in user and user['dispatched'] is False:
|
||||
|
||||
if not IS_LIVE:
|
||||
print user['username']
|
||||
print user['email']
|
||||
print '-' * 5
|
||||
unregistered_counter += 1
|
||||
|
||||
accesscode = None
|
||||
if 'accesscode' in user:
|
||||
accesscode = user['accesscode']
|
||||
|
||||
if ('backend_server' in user) and (user['backend_server'] == int(LOAD_BALANCER)):
|
||||
if IS_LIVE:
|
||||
if LIVE:
|
||||
try:
|
||||
process_user(user['username'],json.loads(user['profile']),accesscode)
|
||||
process_user(user['username'],json.loads(user['profile']))
|
||||
print user['backend_server']
|
||||
except Exception as e:
|
||||
print e
|
||||
@@ -326,7 +302,7 @@ def check_new_registrations(IS_LIVE=False):
|
||||
local = queue.find_one({'key':username})
|
||||
if local is not None:
|
||||
print "in local DB"
|
||||
if IS_LIVE:
|
||||
if LIVE:
|
||||
user['dispatched'] = True
|
||||
user['accepted'] = True
|
||||
users.save(user)
|
||||
@@ -342,7 +318,7 @@ def check_new_registrations(IS_LIVE=False):
|
||||
#-----------------------------------
|
||||
if __name__ == '__main__':
|
||||
|
||||
IS_LIVE = True
|
||||
LIVE = True
|
||||
DISTRIBUTE = False
|
||||
set_backend_server(DISTRIBUTE)
|
||||
check_new_registrations(IS_LIVE)
|
||||
check_new_registrations(LIVE)
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#-----------------------
|
||||
# Copyright 2014 Halfmoon Labs, Inc.
|
||||
# All Rights Reserved
|
||||
@@ -17,7 +18,7 @@ except:
|
||||
DEBUG = True
|
||||
|
||||
#--------------------------------------------------
|
||||
NAMECOIND_READONLY = True
|
||||
NAMECOIND_READONLY = False
|
||||
|
||||
NAMECOIND_USE_HTTPS = True
|
||||
|
||||
@@ -29,8 +30,4 @@ except:
|
||||
#--------------------------------------------------
|
||||
|
||||
MONGODB_URI = os.environ['MONGODB_URI']
|
||||
HEROKU_APP = os.environ['HEROKU_APP']
|
||||
|
||||
LOAD_BALANCER = os.environ['LOAD_BALANCER']
|
||||
|
||||
|
||||
LOAD_BALANCER = os.environ['LOAD_BALANCER']
|
||||
83
blockstack_cli/blockstack_registrar/encrypt/bip38.py
Executable file
83
blockstack_cli/blockstack_registrar/encrypt/bip38.py
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#-----------------------
|
||||
# Copyright 2014 Halfmoon Labs, Inc.
|
||||
# All Rights Reserved
|
||||
#-----------------------
|
||||
|
||||
"""
|
||||
BIP 0038
|
||||
~~~~~
|
||||
|
||||
:copyright: (c) 2014 by Halfmoon Labs
|
||||
:license: MIT, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
import re, os, random, struct, hashlib, binascii, scrypt
|
||||
from hashlib import sha256
|
||||
from coinkit import BitcoinKeypair, b58check_encode, b58check_decode
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
def bip38_encrypt(private_key, passphrase, n=16384, r=8, p=8, compressed=False):
|
||||
# determine the flagbyte
|
||||
if compressed:
|
||||
flagbyte = '\xe0'
|
||||
else:
|
||||
flagbyte = '\xc0'
|
||||
# get the private key's address and equivalent in hex format and wif format
|
||||
k = BitcoinKeypair(private_key)
|
||||
address = k.address()
|
||||
hex_private_key = k.private_key()
|
||||
wif_private_key = k.wif_pk()
|
||||
# calculate the address's checksum
|
||||
address_checksum = sha256(sha256(address).digest()).digest()[0:4]
|
||||
# calculate the scrypt hash and split it in half
|
||||
scrypt_derived_key = scrypt.hash(passphrase, address_checksum, n, r, p)
|
||||
derived_half_1 = scrypt_derived_key[0:32]
|
||||
derived_half_2 = scrypt_derived_key[32:64]
|
||||
# combine parts of the private key and scrypt hash and AES encrypt them
|
||||
aes = AES.new(derived_half_2)
|
||||
encrypted_half_1 = aes.encrypt(
|
||||
binascii.unhexlify(
|
||||
'%0.32x' % (long(hex_private_key[0:32], 16) ^ long(binascii.hexlify(derived_half_1[0:16]), 16))
|
||||
)
|
||||
)
|
||||
encrypted_half_2 = aes.encrypt(
|
||||
binascii.unhexlify(
|
||||
'%0.32x' % (long(hex_private_key[32:64], 16) ^ long(binascii.hexlify(derived_half_1[16:32]), 16))
|
||||
)
|
||||
)
|
||||
# build the encrypted private key from the checksum and encrypted parts
|
||||
encrypted_private_key = ('\x42' + flagbyte + address_checksum + encrypted_half_1 + encrypted_half_2)
|
||||
# base 58 encode the encrypted private key
|
||||
b58check_encrypted_private_key = b58check_encode(encrypted_private_key, version_byte=1)
|
||||
# return the encrypted private key
|
||||
return b58check_encrypted_private_key
|
||||
|
||||
def bip38_decrypt(b58check_encrypted_private_key, passphrase, n=16384, r=8, p=8):
|
||||
# decode private key from base 58 check to binary
|
||||
encrypted_private_key = b58check_decode(b58check_encrypted_private_key)
|
||||
# parse the encrypted key different byte sections
|
||||
bip38_key_identification_byte = encrypted_private_key[0:1]
|
||||
flagbyte = encrypted_private_key[1:2]
|
||||
address_checksum = encrypted_private_key[2:6]
|
||||
encrypted_half_1 = encrypted_private_key[6:6+16]
|
||||
encrypted_half_2 = encrypted_private_key[6+16:6+32]
|
||||
# derive a unique key from the passphrase and the address checksum
|
||||
scrypt_derived_key = scrypt.hash(passphrase, address_checksum, n, r, p)
|
||||
derived_half_1 = scrypt_derived_key[0:32]
|
||||
derived_half_2 = scrypt_derived_key[32:64]
|
||||
# decrypt the encrypted halves
|
||||
aes = AES.new(derived_half_2)
|
||||
decrypted_half_1 = aes.decrypt(encrypted_half_1)
|
||||
decrypted_half_2 = aes.decrypt(encrypted_half_2)
|
||||
# get the original private key from the encrypted halves + the derived half
|
||||
decrypted_private_key = '%064x' % (long(binascii.hexlify(decrypted_half_1 + decrypted_half_2), 16) ^ long(binascii.hexlify(derived_half_1), 16))
|
||||
# get the address corresponding to the private key
|
||||
k = BitcoinKeypair(decrypted_private_key)
|
||||
address = k.address()
|
||||
# make sure the address matches the checksum in the original encrypted key
|
||||
if address_checksum != sha256(sha256(address).digest()).digest()[0:4]:
|
||||
raise ValueError('Invalid private key and password combo.')
|
||||
# return the decrypted private key
|
||||
return k.private_key()
|
||||
61
blockstack_cli/blockstack_registrar/tools/profile_conversion.py
Executable file
61
blockstack_cli/blockstack_registrar/tools/profile_conversion.py
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#-----------------------
|
||||
# Copyright 2014 Halfmoon Labs, Inc.
|
||||
# All Rights Reserved
|
||||
#-----------------------
|
||||
|
||||
#-----------------------------------
|
||||
def convert_v1_to_v2(profile):
|
||||
|
||||
new_profile = {}
|
||||
|
||||
if 'v' in profile:
|
||||
new_profile['v'] = '0.2'
|
||||
|
||||
if 'website' in profile:
|
||||
new_profile['website'] = profile['website']
|
||||
|
||||
if 'bio' in profile:
|
||||
new_profile['bio'] = profile['bio']
|
||||
|
||||
if 'github' in profile:
|
||||
new_profile['github'] = profile['github']
|
||||
|
||||
if 'instagram' in profile:
|
||||
new_profile['instagram'] = {"username":profile['instagram']}
|
||||
|
||||
if 'twitter' in profile:
|
||||
new_profile['twitter'] = {"username":profile['twitter']}
|
||||
|
||||
if 'cover' in profile:
|
||||
new_profile['cover'] = {"url":profile['cover']}
|
||||
|
||||
if 'avatar' in profile:
|
||||
new_profile['avatar'] = {"url":profile['avatar']}
|
||||
|
||||
if 'bitcoin' in profile:
|
||||
new_profile['bitcoin'] = {"address":profile['bitcoin']}
|
||||
|
||||
if 'linkedin' in profile:
|
||||
new_profile['linkedin'] = {"url":profile['linkedin']}
|
||||
|
||||
if 'name' in profile:
|
||||
new_profile['name'] = {"formatted":profile['name']}
|
||||
|
||||
if 'facebook' in profile:
|
||||
new_profile['facebook'] = {"username":profile['facebook']}
|
||||
|
||||
if 'location' in profile:
|
||||
new_profile['location'] = {"formatted":profile['location']}
|
||||
|
||||
if 'angellist' in profile:
|
||||
new_profile['angellist'] = {"username":profile['angellist']}
|
||||
|
||||
if 'bitmessage' in profile:
|
||||
new_profile['bitmessage'] = {"address":profile['bitmessage']}
|
||||
|
||||
if 'pgp' in profile:
|
||||
new_profile['pgp'] = profile['pgp']
|
||||
|
||||
return new_profile
|
||||
Reference in New Issue
Block a user