Implement payment hidden address feature for subscription
This commit is contained in:
parent
6da6912e25
commit
413283f3b0
|
@ -93,10 +93,10 @@
|
|||
size: self.size
|
||||
size: dp(app.window_size[0] - 2*self.parent.parent.padding[0]) - 10 , 1
|
||||
height: dp(40)
|
||||
on_press: root.move_to_pay_option(py2.text)
|
||||
on_press: root.create_hidden_payment_address(self)
|
||||
MDLabel:
|
||||
font_style: 'H6'
|
||||
text: 'Get Monthly Credits'
|
||||
text: 'Buy 100 Credits'
|
||||
font_size: '13sp'
|
||||
color: (0,0,0,1)
|
||||
halign: 'center'
|
||||
|
@ -139,10 +139,10 @@
|
|||
size: self.size
|
||||
size: dp(app.window_size[0] - 2*self.parent.parent.padding[0]) - 10 , 1
|
||||
height: dp(40)
|
||||
on_press: root.move_to_pay_option(py3.text)
|
||||
on_press: root.create_hidden_payment_address(self)
|
||||
MDLabel:
|
||||
font_style: 'H6'
|
||||
text: 'Get Yearly Credits'
|
||||
text: 'Buy 500 Credits'
|
||||
font_size: '13sp'
|
||||
color: (0,0,0,1)
|
||||
halign: 'center'
|
|
@ -891,9 +891,19 @@ class Payment(Screen):
|
|||
state.kivyapp.root.ids.sc18.ids.cred.text = '{0}'.format(
|
||||
state.availabe_credit)
|
||||
|
||||
def move_to_pay_option(self, amount): # pylint: disable=no-self-use
|
||||
"""Option move to pay"""
|
||||
pass
|
||||
def create_hidden_payment_address(self, instance):
|
||||
if BMConfigParser().paymentaddress():
|
||||
toast('hidden payment address already exist for buying subscription...')
|
||||
else:
|
||||
streamNumberForAddress = 1
|
||||
eighteenByteRipe = False
|
||||
nonceTrialsPerByte = 1000
|
||||
payloadLengthExtraBytes = 1000
|
||||
queues.addressGeneratorQueue.put((
|
||||
'createPaymentAddress', 4, streamNumberForAddress, '', 1,
|
||||
"", eighteenByteRipe, nonceTrialsPerByte,
|
||||
payloadLengthExtraBytes))
|
||||
toast('hidden payment address Creating for buying subscription....')
|
||||
|
||||
|
||||
class Credits(Screen):
|
||||
|
|
|
@ -56,21 +56,23 @@ class BMConfigParser(configparser.ConfigParser):
|
|||
raise ValueError("Invalid value %s" % value)
|
||||
return configparser.ConfigParser.set(self, section, option, value)
|
||||
|
||||
def get(self, section, option, raw=False, variables=None):
|
||||
def get(self, section, option, raw=False, vars=None):
|
||||
# import pdb;pdb.set_trace()
|
||||
# pylint: disable=unused-argument
|
||||
# import pdb; pdb.set_trace()
|
||||
try:
|
||||
if section == "bitmessagesettings" and option == "timeformat":
|
||||
return configparser.ConfigParser.get(
|
||||
self, section, option, raw=True, vars=variables)
|
||||
self, section, option, raw=True, vars=vars)
|
||||
try:
|
||||
return self._temp[section][option]
|
||||
except KeyError:
|
||||
pass
|
||||
return configparser.ConfigParser.get(
|
||||
self, section, option, raw=True, vars=variables)
|
||||
self, section, option, raw=True, vars=vars)
|
||||
except configparser.InterpolationError:
|
||||
return configparser.ConfigParser.get(
|
||||
self, section, option, raw=True, vars=variables)
|
||||
self, section, option, raw=True, vars=vars)
|
||||
except (configparser.NoSectionError, configparser.NoOptionError) as e:
|
||||
try:
|
||||
return BMConfigDefaults[section][option]
|
||||
|
@ -86,12 +88,13 @@ class BMConfigParser(configparser.ConfigParser):
|
|||
|
||||
def safeGetBoolean(self, section, field):
|
||||
"""Return value as boolean, False on exceptions"""
|
||||
config = configparser.ConfigParser()
|
||||
try:
|
||||
# Used in the python2.7
|
||||
# return self.getboolean(section, field)
|
||||
# Used in the python3.5.2
|
||||
return config.getboolean(section, field)
|
||||
# print(config, section, field)
|
||||
return self.getboolean(section, field)
|
||||
# return config.getboolean(section, field)
|
||||
except (configparser.NoSectionError, configparser.NoOptionError,
|
||||
ValueError, AttributeError):
|
||||
return False
|
||||
|
@ -122,9 +125,14 @@ class BMConfigParser(configparser.ConfigParser):
|
|||
but override the "raw" argument to always True"""
|
||||
return configparser.ConfigParser.items(self, section, True, variables)
|
||||
|
||||
def addresses(self):
|
||||
def addresses(self, hidden=False):
|
||||
|
||||
"""Return a list of local bitmessage addresses (from section labels)"""
|
||||
return [x for x in BMConfigParser().sections() if x.startswith('BM-')]
|
||||
return [x for x in BMConfigParser().sections() if x.startswith('BM-') and (hidden or not BMConfigParser().safeGetBoolean(x, 'hidden'))]
|
||||
|
||||
def paymentaddress(self):
|
||||
"""Return a list of local payment addresses (from section labels)"""
|
||||
return ''.join([x for x in BMConfigParser().sections() if x.startswith('BM-') and BMConfigParser().safeGetBoolean(x, 'payment')])
|
||||
|
||||
def read(self, filenames):
|
||||
configparser.ConfigParser.read(self, filenames)
|
||||
|
|
|
@ -206,9 +206,98 @@ class addressGenerator(StoppableThread):
|
|||
queues.workerQueue.put((
|
||||
'sendOutOrStoreMyV4Pubkey', address))
|
||||
|
||||
# elif command == 'createDeterministicAddresses' \
|
||||
# or command == 'getDeterministicAddress' \
|
||||
# or command == 'createChan' or command == 'joinChan':
|
||||
elif command == 'createPaymentAddress':
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar', ""
|
||||
))
|
||||
# This next section is a little bit strange. We're going
|
||||
# to generate keys over and over until we find one
|
||||
# that starts with either \x00 or \x00\x00. Then when
|
||||
# we pack them into a Bitmessage address, we won't store
|
||||
# the \x00 or \x00\x00 bytes thus making the address shorter.
|
||||
startTime = time.time()
|
||||
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
|
||||
potentialPrivSigningKey = OpenSSL.rand(32)
|
||||
potentialPubSigningKey = highlevelcrypto.pointMult(
|
||||
potentialPrivSigningKey)
|
||||
while True:
|
||||
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
|
||||
potentialPrivEncryptionKey = OpenSSL.rand(32)
|
||||
potentialPubEncryptionKey = highlevelcrypto.pointMult(
|
||||
potentialPrivEncryptionKey)
|
||||
sha = hashlib.new('sha512')
|
||||
sha.update(
|
||||
potentialPubSigningKey + potentialPubEncryptionKey)
|
||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
||||
if (
|
||||
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash] ==
|
||||
'\x00'.encode('utf-8') * numberOfNullBytesDemandedOnFrontOfRipeHash
|
||||
):
|
||||
break
|
||||
self.logger.info(
|
||||
'Generated address with ripe digest: %s', hexlify(ripe))
|
||||
try:
|
||||
self.logger.info(
|
||||
'Address generator calculated %s addresses at %s'
|
||||
' addresses per second before finding one with'
|
||||
' the correct ripe-prefix.',
|
||||
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix,
|
||||
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix
|
||||
/ (time.time() - startTime))
|
||||
except ZeroDivisionError:
|
||||
# The user must have a pretty fast computer.
|
||||
# time.time() - startTime equaled zero.
|
||||
pass
|
||||
|
||||
address = encodeAddress(
|
||||
addressVersionNumber, streamNumber, ripe)
|
||||
|
||||
# An excellent way for us to store our keys
|
||||
# is in Wallet Import Format. Let us convert now.
|
||||
# https://en.bitcoin.it/wiki/Wallet_import_format
|
||||
privSigningKey = '\x80'.encode('utf-8')[1:] + potentialPrivSigningKey
|
||||
checksum = hashlib.sha256(hashlib.sha256(
|
||||
privSigningKey).digest()).digest()[0:4]
|
||||
privSigningKeyWIF = arithmetic.changebase(
|
||||
privSigningKey + checksum, 256, 58)
|
||||
|
||||
privEncryptionKey = '\x80'.encode('utf-8')[1:] + potentialPrivEncryptionKey
|
||||
checksum = hashlib.sha256(hashlib.sha256(
|
||||
privEncryptionKey).digest()).digest()[0:4]
|
||||
privEncryptionKeyWIF = arithmetic.changebase(
|
||||
privEncryptionKey + checksum, 256, 58)
|
||||
BMConfigParser().add_section(address)
|
||||
# BMConfigParser().set(address, 'label', label)
|
||||
BMConfigParser().set(address, 'enabled', 'true')
|
||||
BMConfigParser().set(address, 'decoy', 'false')
|
||||
BMConfigParser().set(address, 'noncetrialsperbyte', str(
|
||||
nonceTrialsPerByte))
|
||||
BMConfigParser().set(address, 'payloadlengthextrabytes', str(
|
||||
payloadLengthExtraBytes))
|
||||
BMConfigParser().set(
|
||||
address, 'privsigningkey', privSigningKeyWIF)
|
||||
BMConfigParser().set(
|
||||
address, 'privencryptionkey', privEncryptionKeyWIF)
|
||||
BMConfigParser().set(address, 'hidden', 'true')
|
||||
BMConfigParser().set(address, 'payment', 'true')
|
||||
BMConfigParser().save()
|
||||
|
||||
# The API and the join and create Chan functionality
|
||||
# both need information back from the address generator.
|
||||
queues.apiAddressGeneratorReturnQueue.put(address)
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar', ""
|
||||
))
|
||||
queues.UISignalQueue.put(('writeNewAddressToTable', (
|
||||
label, address, streamNumber)))
|
||||
shared.reloadMyAddressHashes()
|
||||
if addressVersionNumber == 3:
|
||||
queues.workerQueue.put((
|
||||
'sendOutOrStoreMyV3Pubkey', ripe))
|
||||
elif addressVersionNumber == 4:
|
||||
queues.workerQueue.put((
|
||||
'sendOutOrStoreMyV4Pubkey', address))
|
||||
|
||||
elif command in (
|
||||
'createDeterministicAddresses',
|
||||
'getDeterministicAddress',
|
||||
|
|
|
@ -215,7 +215,7 @@ def updateConfig():
|
|||
# Adjust the required POW values for each of this user's addresses
|
||||
# to conform to protocol v3 norms.
|
||||
if settingsversion == 9:
|
||||
for addressInKeysFile in config.addresses():
|
||||
for addressInKeysFile in config.addresses(hidden=True):
|
||||
try:
|
||||
previousTotalDifficulty = float(
|
||||
config.getint(
|
||||
|
|
|
@ -142,7 +142,7 @@ def reloadMyAddressHashes():
|
|||
keyfileSecure = checkSensitiveFilePermissions(os.path.join(
|
||||
state.appdata, 'keys.dat'))
|
||||
hasEnabledKeys = False
|
||||
for addressInKeysFile in BMConfigParser().addresses():
|
||||
for addressInKeysFile in BMConfigParser().addresses(hidden=True):
|
||||
isEnabled = BMConfigParser().safeGet(addressInKeysFile, 'enabled')
|
||||
if isEnabled:
|
||||
hasEnabledKeys = True
|
||||
|
|
Reference in New Issue
Block a user