Implement payment hidden address feature for subscription
This commit is contained in:
parent
6da6912e25
commit
413283f3b0
|
@ -93,10 +93,10 @@
|
||||||
size: self.size
|
size: self.size
|
||||||
size: dp(app.window_size[0] - 2*self.parent.parent.padding[0]) - 10 , 1
|
size: dp(app.window_size[0] - 2*self.parent.parent.padding[0]) - 10 , 1
|
||||||
height: dp(40)
|
height: dp(40)
|
||||||
on_press: root.move_to_pay_option(py2.text)
|
on_press: root.create_hidden_payment_address(self)
|
||||||
MDLabel:
|
MDLabel:
|
||||||
font_style: 'H6'
|
font_style: 'H6'
|
||||||
text: 'Get Monthly Credits'
|
text: 'Buy 100 Credits'
|
||||||
font_size: '13sp'
|
font_size: '13sp'
|
||||||
color: (0,0,0,1)
|
color: (0,0,0,1)
|
||||||
halign: 'center'
|
halign: 'center'
|
||||||
|
@ -139,10 +139,10 @@
|
||||||
size: self.size
|
size: self.size
|
||||||
size: dp(app.window_size[0] - 2*self.parent.parent.padding[0]) - 10 , 1
|
size: dp(app.window_size[0] - 2*self.parent.parent.padding[0]) - 10 , 1
|
||||||
height: dp(40)
|
height: dp(40)
|
||||||
on_press: root.move_to_pay_option(py3.text)
|
on_press: root.create_hidden_payment_address(self)
|
||||||
MDLabel:
|
MDLabel:
|
||||||
font_style: 'H6'
|
font_style: 'H6'
|
||||||
text: 'Get Yearly Credits'
|
text: 'Buy 500 Credits'
|
||||||
font_size: '13sp'
|
font_size: '13sp'
|
||||||
color: (0,0,0,1)
|
color: (0,0,0,1)
|
||||||
halign: 'center'
|
halign: 'center'
|
|
@ -891,9 +891,19 @@ class Payment(Screen):
|
||||||
state.kivyapp.root.ids.sc18.ids.cred.text = '{0}'.format(
|
state.kivyapp.root.ids.sc18.ids.cred.text = '{0}'.format(
|
||||||
state.availabe_credit)
|
state.availabe_credit)
|
||||||
|
|
||||||
def move_to_pay_option(self, amount): # pylint: disable=no-self-use
|
def create_hidden_payment_address(self, instance):
|
||||||
"""Option move to pay"""
|
if BMConfigParser().paymentaddress():
|
||||||
pass
|
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):
|
class Credits(Screen):
|
||||||
|
|
|
@ -56,21 +56,23 @@ class BMConfigParser(configparser.ConfigParser):
|
||||||
raise ValueError("Invalid value %s" % value)
|
raise ValueError("Invalid value %s" % value)
|
||||||
return configparser.ConfigParser.set(self, section, option, 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
|
# pylint: disable=unused-argument
|
||||||
|
# import pdb; pdb.set_trace()
|
||||||
try:
|
try:
|
||||||
if section == "bitmessagesettings" and option == "timeformat":
|
if section == "bitmessagesettings" and option == "timeformat":
|
||||||
return configparser.ConfigParser.get(
|
return configparser.ConfigParser.get(
|
||||||
self, section, option, raw=True, vars=variables)
|
self, section, option, raw=True, vars=vars)
|
||||||
try:
|
try:
|
||||||
return self._temp[section][option]
|
return self._temp[section][option]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
return configparser.ConfigParser.get(
|
return configparser.ConfigParser.get(
|
||||||
self, section, option, raw=True, vars=variables)
|
self, section, option, raw=True, vars=vars)
|
||||||
except configparser.InterpolationError:
|
except configparser.InterpolationError:
|
||||||
return configparser.ConfigParser.get(
|
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:
|
except (configparser.NoSectionError, configparser.NoOptionError) as e:
|
||||||
try:
|
try:
|
||||||
return BMConfigDefaults[section][option]
|
return BMConfigDefaults[section][option]
|
||||||
|
@ -86,12 +88,13 @@ class BMConfigParser(configparser.ConfigParser):
|
||||||
|
|
||||||
def safeGetBoolean(self, section, field):
|
def safeGetBoolean(self, section, field):
|
||||||
"""Return value as boolean, False on exceptions"""
|
"""Return value as boolean, False on exceptions"""
|
||||||
config = configparser.ConfigParser()
|
|
||||||
try:
|
try:
|
||||||
# Used in the python2.7
|
# Used in the python2.7
|
||||||
# return self.getboolean(section, field)
|
# return self.getboolean(section, field)
|
||||||
# Used in the python3.5.2
|
# 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,
|
except (configparser.NoSectionError, configparser.NoOptionError,
|
||||||
ValueError, AttributeError):
|
ValueError, AttributeError):
|
||||||
return False
|
return False
|
||||||
|
@ -122,9 +125,14 @@ class BMConfigParser(configparser.ConfigParser):
|
||||||
but override the "raw" argument to always True"""
|
but override the "raw" argument to always True"""
|
||||||
return configparser.ConfigParser.items(self, section, True, variables)
|
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 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):
|
def read(self, filenames):
|
||||||
configparser.ConfigParser.read(self, filenames)
|
configparser.ConfigParser.read(self, filenames)
|
||||||
|
|
|
@ -206,9 +206,98 @@ class addressGenerator(StoppableThread):
|
||||||
queues.workerQueue.put((
|
queues.workerQueue.put((
|
||||||
'sendOutOrStoreMyV4Pubkey', address))
|
'sendOutOrStoreMyV4Pubkey', address))
|
||||||
|
|
||||||
# elif command == 'createDeterministicAddresses' \
|
elif command == 'createPaymentAddress':
|
||||||
# or command == 'getDeterministicAddress' \
|
queues.UISignalQueue.put((
|
||||||
# or command == 'createChan' or command == 'joinChan':
|
'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 (
|
elif command in (
|
||||||
'createDeterministicAddresses',
|
'createDeterministicAddresses',
|
||||||
'getDeterministicAddress',
|
'getDeterministicAddress',
|
||||||
|
|
|
@ -215,7 +215,7 @@ def updateConfig():
|
||||||
# Adjust the required POW values for each of this user's addresses
|
# Adjust the required POW values for each of this user's addresses
|
||||||
# to conform to protocol v3 norms.
|
# to conform to protocol v3 norms.
|
||||||
if settingsversion == 9:
|
if settingsversion == 9:
|
||||||
for addressInKeysFile in config.addresses():
|
for addressInKeysFile in config.addresses(hidden=True):
|
||||||
try:
|
try:
|
||||||
previousTotalDifficulty = float(
|
previousTotalDifficulty = float(
|
||||||
config.getint(
|
config.getint(
|
||||||
|
|
|
@ -142,7 +142,7 @@ def reloadMyAddressHashes():
|
||||||
keyfileSecure = checkSensitiveFilePermissions(os.path.join(
|
keyfileSecure = checkSensitiveFilePermissions(os.path.join(
|
||||||
state.appdata, 'keys.dat'))
|
state.appdata, 'keys.dat'))
|
||||||
hasEnabledKeys = False
|
hasEnabledKeys = False
|
||||||
for addressInKeysFile in BMConfigParser().addresses():
|
for addressInKeysFile in BMConfigParser().addresses(hidden=True):
|
||||||
isEnabled = BMConfigParser().safeGet(addressInKeysFile, 'enabled')
|
isEnabled = BMConfigParser().safeGet(addressInKeysFile, 'enabled')
|
||||||
if isEnabled:
|
if isEnabled:
|
||||||
hasEnabledKeys = True
|
hasEnabledKeys = True
|
||||||
|
|
Reference in New Issue
Block a user