diff --git a/Poppins/local_settings_dev.py b/Poppins/local_settings_dev.py index 8625b098d52288b13356dec2b03ea667e485874e..9830555cbba422db7ded74a28c6183f3f31c9a72 100644 --- a/Poppins/local_settings_dev.py +++ b/Poppins/local_settings_dev.py @@ -96,4 +96,4 @@ DISTILLERY_ABI = '[ { "anonymous": false, "inputs": [ { "indexed": false, "name" RAVEN_CONFIG = { 'dsn': 'http://5c7db71f422f4f6c90f0e424691ac8c5:6d461c37c9ee4335817f42406a8ef34a@172.17.30.21:9000/63', -} \ No newline at end of file +} diff --git a/Poppins/local_settings_preprod.py b/Poppins/local_settings_preprod.py index fa1aeabcac1bc8a7c4c64d7b3c9ef6abae5058f7..e311bfcb8d527a1a7a6c7fe5553b7e38ab718f5f 100644 --- a/Poppins/local_settings_preprod.py +++ b/Poppins/local_settings_preprod.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Copyright 2019 de la Dirección General de Sistemas Informáticos – SecretarÃa Legal y Técnica - Nación. @@ -10,7 +11,7 @@ You should have received a copy of the GNU General Public License along with thi # DEBUG DEBUG = False -APP_ROOT = '/var/www/poppins.bc.local/app/Poppins/' +APP_ROOT = '/var/www/poppins.bc.local/' STATIC_ROOT = '/var/www/poppins.bc.local/html' # MAIL DATA diff --git a/Poppins/local_settings_prod.py b/Poppins/local_settings_prod.py index 4f360b9895082f765ed8009683dea133ebfdccab..58488d5fca5b352388a2c2e794d1131db45db9ae 100644 --- a/Poppins/local_settings_prod.py +++ b/Poppins/local_settings_prod.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Copyright 2019 de la Dirección General de Sistemas Informáticos – SecretarÃa Legal y Técnica - Nación. @@ -10,12 +11,26 @@ You should have received a copy of the GNU General Public License along with thi #DEBUG DEBUG = False -APP_ROOT = '/var/www/poppins.bc.local/app/Poppins/' +import os +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +APP_ROOT = BASE_DIR+'/../../' STATIC_ROOT = '/var/www/poppins.bc.local/html' +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'poppins', + 'USER': 'poppinsuser', + 'PASSWORD': '1234', + 'HOST': '127.0.0.1', + 'PORT': '5432', + } +} + #MAIL DATA EMAIL_USE_TLS = False -EMAIL_HOST = '172.16.1.106' +EMAIL_HOST = 'localhost' EMAIL_PORT = 25 EMAIL_HOST_USER = '' EMAIL_HOST_PASSWORD = '' @@ -24,40 +39,80 @@ DEFAULT_FROM_EMAIL = 'no-reply@bfa.ar' ADMIN_EMAIL = 'no-reply@bfa.ar' #NODO DE BLOACJAJEICHAIN -NODE_URL = 'http://10.23.10.71:54450' # salberchain +NODE_URL = 'http://10.24.10.14:8545' # mainnet (bootnode) #CFG BLOCKCHANGE -DISTILLERY_ADDRESS = '0x67d6e2887638cb6F4D55FCe4f4122635E4B27531' # distillery -DISTRIBUTOR_ACCOUNT = '0x25c185DcaeD065BAC30a0a1cd0688A7aA02896d7' # cuenta con mucho ether -DISTILLERY_ABI = '[ { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", ' \ - '"type": "uint256" } ], "name": "addBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], ' \ - '"payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, ' \ - '"inputs": [ { "name": "acc", "type": "address" }, { "name": "top", "type": "uint256" } ], ' \ - '"name": "addDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, ' \ +DISTILLERY_ADDRESS = '0xc3cF96aF51d3c41DfBE428dE75a8E5597d4D7A7B' # distillery +DISTRIBUTOR_ACCOUNT = '0xBF1ce9Cca7dedea3FDB22d169B49643664602eE1' # cuenta con mucho ether +DISTILLERY_ABI = '[ { "anonymous": false, "inputs": [ { "indexed": false, "name": "amount", "type": "uint256" } ], ' \ + '"name": "proofOfControlWeiAmountChanged", "type": "event" }, { "constant": false, "inputs": [ { ' \ + '"name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], ' \ + '"name": "addBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, ' \ '"stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": ' \ - '"acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "changeLimit", ' \ + '"add", "type": "address" }, { "name": "password", "type": "bytes32" } ], "name": "addSuitor", ' \ + '"outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", ' \ + '"type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, ' \ + '{ "name": "limit", "type": "uint256" } ], "name": "changeLimit", "outputs": [ { "name": "", ' \ + '"type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, ' \ + '{ "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickBeneficiary", ' \ '"outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", ' \ '"type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], ' \ - '"name": "kickBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, ' \ + '"name": "kickDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, ' \ + '"stateMutability": "nonpayable", "type": "function" }, { "anonymous": false, "inputs": [ { ' \ + '"indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "ben", ' \ + '"type": "address" }, { "indexed": false, "name": "newLimit", "type": "uint256" } ], ' \ + '"name": "limitChanged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, ' \ + '"name": "suitor", "type": "address" } ], "name": "suitorApproved", "type": "event" }, ' \ + '{ "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], ' \ + '"name": "suitorNotApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": ' \ + 'true, "name": "kicked", "type": "address" } ], "name": "kickedDistributor", "type": "event" }, ' \ + '{ "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" }, ' \ + '{ "indexed": true, "name": "distr", "type": "address" } ], "name": "suitorAdded", "type": "event" ' \ + '}, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, ' \ + '{ "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "limit", ' \ + '"type": "uint256" } ], "name": "addedBeneficiary", "type": "event" }, { "anonymous": false, ' \ + '"inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, ' \ + '"name": "kicked", "type": "address" } ], "name": "kickedBeneficiary", "type": "event" }, ' \ + '{ "anonymous": false, "inputs": [ { "indexed": true, "name": "added", "type": "address" }, ' \ + '{ "indexed": false, "name": "top", "type": "uint256" } ], "name": "addedDistributor", ' \ + '"type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", ' \ + '"type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" } ], ' \ + '"name": "replenished", "type": "event" }, { "constant": false, "inputs": [ { "name": "acc", ' \ + '"type": "address" }, { "name": "top", "type": "uint256" } ], "name": "addDistributor", "outputs": [ ' \ + '{ "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", ' \ + '"type": "function" }, { "constant": false, "inputs": [ { "name": "key", "type": "string" } ], ' \ + '"name": "proveControl", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, ' \ '"stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": ' \ - '"acc", "type": "address" } ], "name": "kickDistributor", "outputs": [ { "name": "", "type": "bool" ' \ - '} ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, ' \ - '"inputs": [ { "name": "acc", "type": "address" }, { "name": "amount", "type": "uint256" } ], ' \ - '"name": "replenish", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, ' \ - '"stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [], ' \ - '"name": "replenishAll", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, ' \ + '"acc", "type": "address" }, { "name": "amount", "type": "uint256" } ], "name": "replenish", ' \ + '"outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", ' \ + '"type": "function" }, { "constant": false, "inputs": [], "name": "replenishAll", "outputs": [ { ' \ + '"name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" ' \ + '}, { "constant": false, "inputs": [ { "name": "accs", "type": "address[]" }, { "name": "amounts", ' \ + '"type": "uint256[]" } ], "name": "replenishList", "outputs": [], "payable": true, ' \ '"stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": ' \ - '"accs", "type": "address[]" }, { "name": "amounts", "type": "uint256[]" } ], ' \ - '"name": "replenishList", "outputs": [], "payable": true, "stateMutability": "payable", ' \ - '"type": "function" }, { "inputs": [], "payable": true, "stateMutability": "payable", ' \ - '"type": "constructor" }, { "constant": true, "inputs": [], "name": "getBeneficiariesCount", ' \ - '"outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", ' \ - '"type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], ' \ + '"amount", "type": "uint256" } ], "name": "setProofOfControlWeiAmount", "outputs": [ { "name": "", ' \ + '"type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, ' \ + '{ "inputs": [], "payable": true, "stateMutability": "payable", "type": "constructor" }, ' \ + '{ "constant": true, "inputs": [], "name": "getBeneficiariesCount", "outputs": [ { "name": "", ' \ + '"type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, ' \ + '{ "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], ' \ '"name": "getBeneficiaryLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, ' \ '"stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", ' \ '"type": "address" } ], "name": "getDistributorLimit", "outputs": [ { "name": "", "type": "uint256" ' \ - '} ], "payable": false, "stateMutability": "view", "type": "function" } ] ' + '} ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, ' \ + '"inputs": [], "name": "getProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "uint256" } ' \ + '], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, ' \ + '"inputs": [ { "name": "key", "type": "string" } ], "name": "hash", "outputs": [ { "name": "", ' \ + '"type": "bytes32" } ], "payable": false, "stateMutability": "pure", "type": "function" }, ' \ + '{ "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isBeneficiary", ' \ + '"outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", ' \ + '"type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], ' \ + '"name": "isDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, ' \ + '"stateMutability": "view", "type": "function" } ] ' + +GOOGLE_RECAPTCHA_SECRET_KEY = '6LdIsXoUAAAAAM2CK9KUohWWFZTjpwo-Z2CP_Ndp' +DATA_SITEKEY = '6LdIsXoUAAAAAFQfkzQWPpJ5ERGdxmY8YT4bFLmt' RAVEN_CONFIG = { - 'dsn': 'http://5c7db71f422f4f6c90f0e424691ac8c5:6d461c37c9ee4335817f42406a8ef34a@172.17.30.21:9000/63', + 'dsn': 'http://0f6b7e857c31436badd6f5a33b6795e4:21003d12f52b4e2cb4efba1f27fd1780@10.1.100.118:9000/81', } \ No newline at end of file diff --git a/Poppins/local_settings_tst.py b/Poppins/local_settings_tst.py index 42d3f1efd289847a1cbe649dff4382f063b62904..946fb50f1e7d7c4befa155bb728cb537dd3b0502 100644 --- a/Poppins/local_settings_tst.py +++ b/Poppins/local_settings_tst.py @@ -1,8 +1,9 @@ # DEBUG -DEBUG = False +DEBUG = True +import os +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -APP_ROOT = '/var/www/poppins.bc.local/app/Poppins/' -STATIC_ROOT = '/var/www/poppins.bc.local/html' +APP_ROOT = BASE_DIR+'/' DATABASES = { 'default': { @@ -10,7 +11,7 @@ DATABASES = { 'NAME': 'poppins', 'USER': 'poppinsuser', 'PASSWORD': '1234', - 'HOST': 'localhost', + 'HOST': '10.14.2.198', 'PORT': '5432', } } @@ -26,7 +27,7 @@ DEFAULT_FROM_EMAIL = 'no-reply@bfa.ar' ADMIN_EMAIL = 'no-reply@bfa.ar' # NODO DE BLOACJAJEICHAIN -NODE_URL = 'http://10.23.10.73:54450' # salberchain +NODE_URL = 'http://10.23.10.71:54450' # salberchain # CFG BLOCKCHANGE DISTILLERY_ADDRESS = '0x822c2b518dCfEE69d435E0C5F2e6d196FcC8320E' # distillery @@ -102,9 +103,6 @@ DISTILLERY_ABI = '[ { "anonymous": false, "inputs": [ { "indexed": false, "name" '"name": "isDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, ' \ '"stateMutability": "view", "type": "function" } ] ' -GOOGLE_RECAPTCHA_SECRET_KEY = '6LdIsXoUAAAAAM2CK9KUohWWFZTjpwo-Z2CP_Ndp' -DATA_SITEKEY = '6LdIsXoUAAAAAFQfkzQWPpJ5ERGdxmY8YT4bFLmt' - RAVEN_CONFIG = { 'dsn': 'http://af8a61a068af431eb80d8ee277f84364:887b38e0b1594fabb844b75309bdaab7@10.1.100.118:9000/79', } diff --git a/README.md b/README.md index 597db7dec32321db57e5c3a5f0d58585ceb69e8c..698b82992a9c9c7b5d32de80fc78146ff0775ab3 100644 --- a/README.md +++ b/README.md @@ -22,5 +22,27 @@ Ejecutar dentro del virtual environment - python manage.py agregar_estados_cuenta_usuario - service apache2 restart -- Cronear el comando pyhton manage.py pedir_ether cada 1 minuto +- Cronear el comando pyhton manage.py pedir_ether cada 1 minuto o menos +- Cronear el comando pyhton manage.py actualizar_estado cada 1 minuto o menos +### Comandos + +Existen varios comandos para ayudar con el deploy, el estado, o la verificación de consistencia de la aplicación + +- python manage.py deployar_smart_contract : deploya smart contract + +- python manage.py verificar_admin_distribuidor : verifica que el distribuidor en los settings está cargado en el smart contract y el tope que tiene + +- python manage.py verificar_balance_distribuidor: devuelve el balance de la cuenta del distribuidor en los settings + +- python manage.py cargar_distribuidor: carga en el smart contract el distribuidor en los settings con el tope en los settings + +- python manage.py ver_bytecode_contrato : devuelve el bytecode del smart contract, para verificar que está bien deployado + +- python manage.py settear_cantidad_prueba_control : settea en el smart contract la cantidad de saldo para hacer la verificación de control + +- python manage.py cantidad_prueba_control : getter de la cantidad de saldo en el smart contract para verificacion de control + +- python manage.py sincronizar_cuentas_beneficiario : levanta los beneficiarios cargados en el smart contract y los carga en base + +- python manage.py verificar_consistencia : verifica las cuentas que no estan relacionadas con usuarios y si están en smart contract y las borra o desvincula diff --git a/api/admin.py b/api/admin.py index 5d0fd82d8236a60dc2f1f7a084065a2e7622ff63..a411bfd8a8a19c73bc79e3e3675f9b253a205717 100644 --- a/api/admin.py +++ b/api/admin.py @@ -8,8 +8,29 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ """ from django.contrib import admin -from api.models import CustomUser, Institution, Section +from api.models import CustomUser, Institution, Section, Service +from dapp.models import Account + + +class ServiceAdmin(admin.ModelAdmin): + list_display = ('name', 'address', 'status', ) + + def address(self, service): + qs = Account.objects.filter(service=service) + if qs.exists(): + return qs.first().address + else: + return "" + + def status(self, service): + qs = Account.objects.filter(service=service) + if qs.exists(): + return qs.first().status + else: + return "" + admin.site.register(CustomUser) admin.site.register(Institution) admin.site.register(Section) +admin.site.register(Service, ServiceAdmin) diff --git a/api/models.py b/api/models.py index 0e37c5e75c433e9b62f0eb555699dc239fc67fb6..4741ced578b6e27995c40b4afe9c08e34a71209a 100644 --- a/api/models.py +++ b/api/models.py @@ -61,6 +61,7 @@ class CustomUser(models.Model): cuit = models.CharField(max_length=20, null=True, blank=True) user = models.ForeignKey(User, on_delete=models.PROTECT, ) enabled_institutions = models.ManyToManyField(Institution, verbose_name='Instituciones habilitadas', blank=True) + accepted_terms = models.BooleanField(default=True) class Meta: db_table = 'custom_user' diff --git a/dapp/gateway.py b/dapp/gateway.py index b9719c5770009d306728c6b09ba82d70a7270a49..8bc37c8bf7df5a110497d0541400f6b4737215ac 100644 --- a/dapp/gateway.py +++ b/dapp/gateway.py @@ -55,9 +55,6 @@ class EthereumGateway: event_filter = event.createFilter(**params) return event_filter.get_all_entries() - def calcular_gas(self, action): - return action.estimateGas() - class InvalidTransactionException(Exception): pass @@ -68,7 +65,7 @@ class Distillery: def execute_transaction(self, contract, transaction_data, exception_message=""): es_valido = contract.call(transaction_data) - gas_estimate = self.gateway.calcular_gas(contract) + if es_valido: # transaction_data['gasLimit'] = 1000000000000 tx_hash = contract.transact(transaction_data) @@ -91,19 +88,18 @@ class Distillery: abi = settings.DISTILLERY_ABI return self.gateway.get_contract_events(abi, self.contract_account) - def beneficiarios(self): - cant_cuentas = self.contrato.numberOfBeneficiaries().call() + def beneficiarios(self, from_block_number): + event_ben = self.eventos.addedBeneficiary + event_filter_ben = event_ben.createFilter(fromBlock=int(from_block_number), toBlock='latest') + results = event_filter_ben.get_all_entries() - cuentas = [] + bens = [] - if cant_cuentas > 0: - i = 0 - while i < cant_cuentas: - par = self.contrato.atPosition(i).call() - cuentas.append(par[0]) - i += 1 + for r in results: + if self.es_beneficiario(r['args']['added']): + bens.append((r['args']['added'], r['args']['limit'])) - return cuentas + return bens def distribuir(self, from_account): distribute = self.contrato.replenishAll() @@ -111,11 +107,12 @@ class Distillery: return tx_hash def agregar_beneficiario(self, from_account, address, tope): - agregar = self.contrato.addBeneficiary(self.gateway.to_checksum_address(address), tope) - tx_hash = self.execute_transaction(agregar, {'from': self.gateway.to_checksum_address(from_account)}, - "Transaction is invalid, " + from_account + " has no permissions or top " - + str(tope) + "is higher than allowed") - return tx_hash + if not self.es_beneficiario(address): + agregar = self.contrato.addBeneficiary(self.gateway.to_checksum_address(address), tope) + tx_hash = self.execute_transaction(agregar, {'from': self.gateway.to_checksum_address(from_account)}, + "Transaction is invalid, " + from_account + " has no permissions or top " + + str(tope) + " is higher than allowed") + return tx_hash def agregar_distribuidor(self, from_account, address, tope): agregar = self.contrato.addDistributor(self.gateway.to_checksum_address(address), tope) @@ -131,7 +128,9 @@ class Distillery: def abastecer(self, from_account, cuenta, cantidad): abastecer = self.contrato.replenish(self.gateway.to_checksum_address(cuenta), int(cantidad)) - tx_hash = self.execute_transaction(abastecer, {'from': self.gateway.to_checksum_address(from_account)}, + tx_hash = self.execute_transaction(abastecer, { + 'from': self.gateway.to_checksum_address(from_account), + 'value': int(cantidad) + 1}, # para pasar validacion "Transaction is invalid " + from_account + " is not allowed or amount is too high, contract balance: " + str(self.gateway.get_balance(self.contract_account)) + " amount " @@ -143,7 +142,9 @@ class Distillery: for c in cuentas: checksumed.append(self.gateway.to_checksum_address(c)) abastecer = self.contrato.replenish(checksumed, cantidades) - tx_hash = self.execute_transaction(abastecer, {'from': self.gateway.to_checksum_address(from_account)}, + tx_hash = self.execute_transaction(abastecer, { + 'from': self.gateway.to_checksum_address(from_account), + 'value': sum(cantidades)}, "Transaction is invalid" + from_account + " is not allowed or amount is too high") return tx_hash @@ -152,10 +153,11 @@ class Distillery: return self.contrato.getBeneficiaryLimit(self.gateway.to_checksum_address(cuenta)).call() def sacar_beneficiario(self, from_account, address): - patear = self.contrato.kickBeneficiary(self.gateway.to_checksum_address(address)) - tx_hash = self.execute_transaction(patear, {'from': self.gateway.to_checksum_address(from_account)}, - 'Transaction is invalid ' + from_account + " has no permissions") - return tx_hash + if self.es_beneficiario(address): + patear = self.contrato.kickBeneficiary(self.gateway.to_checksum_address(address)) + tx_hash = self.execute_transaction(patear, {'from': self.gateway.to_checksum_address(from_account)}, + 'Transaction is invalid ' + from_account + " has no permissions") + return tx_hash def ya_fue_eliminado(self, from_account, address): args = { @@ -170,6 +172,9 @@ class Distillery: entradas = self.gateway.buscar_entradas(evento, args) return len(entradas) > 0 + def es_beneficiario(self, address): + return self.contrato.isBeneficiary(self.gateway.to_checksum_address(address)).call() + def es_distribuidor(self, address): return self.contrato.isDistributor(self.gateway.to_checksum_address(address)).call() @@ -216,3 +221,6 @@ class Distillery: } entradas = self.gateway.buscar_entradas(suitor_approved_evento, params) return len(entradas) > 0 + + def tope_distribuidor(self, address): + return self.contrato.getDistributorLimit(self.gateway.to_checksum_address(address)).call() diff --git a/dapp/managers.py b/dapp/managers.py index 4b8c0124b2a5c274d90377fd90e9d4768b9f255a..0f7b89369b2353b62a8233304aa09d922608a0ba 100644 --- a/dapp/managers.py +++ b/dapp/managers.py @@ -23,7 +23,7 @@ class StatusManager(models.Manager): def get_esperando_transaccion(self): try: - return self.filter(descripcion="Esperando transaccion").first() + return self.filter(descripcion="Esperando transaccion de alta beneficiario").first() except Exception as e: pass except OperationalError as oe: @@ -61,6 +61,14 @@ class StatusManager(models.Manager): except OperationalError as oe: return None + def get_esperando_transaccion_abastecimiento(self): + try: + return self.filter(descripcion="Esperando transaccion de abastecimiento").first() + except Exception as e: + pass + except OperationalError as oe: + return None + class AccountManager(models.Manager): gateway = EthereumGateway() diff --git a/dapp/models.py b/dapp/models.py index eb7e4da97e74eea6e54d3f426416a15b3e53a91c..997a8fbf9f6262f81e6d7e94849e769a55ceeb9c 100644 --- a/dapp/models.py +++ b/dapp/models.py @@ -33,7 +33,6 @@ class Account(models.Model): institution = models.ForeignKey(Institution, on_delete=models.PROTECT, null=True, blank=True) service = models.ForeignKey(Service, on_delete=models.PROTECT, null=True) clave = models.CharField(max_length=255, null=True, default='', blank=True) - owner = models.ForeignKey(CustomUser, on_delete=models.PROTECT, null=False) objects = AccountManager() def __str__(self): diff --git a/dapp/services.py b/dapp/services.py index 894cea5b4304a47c0f90b4da7fe714fdeefd3898..8da26117737dbca91fa936b07c8e5de572e17f9e 100644 --- a/dapp/services.py +++ b/dapp/services.py @@ -10,6 +10,7 @@ You should have received a copy of the GNU General Public License along with thi import logging from Poppins import settings +from api.models import Service from dapp.gateway import Distillery, EthereumGateway from dapp.models import Account, Status, TopeEsperado from django.db import transaction @@ -27,15 +28,15 @@ class AccountBeingKicked(Exception): class PetitorioEtherCuenta: logger = logging.getLogger('logger') - pendiente = Status.objects.get_pendiente_distribucion() - desvinculando = Status.objects.get_esperando_desvinculado() + pendiente = Status.objects.get_pendiente_distribucion + desvinculando = Status.objects.get_esperando_desvinculado def pedir_ether(self, account): """ :type account: Account """ - if account.status != self.desvinculando: - account.status = self.pendiente + if account.status is not self.desvinculando(): + account.status = self.pendiente() self.logger.info('Pedido de ether para cuenta :' + str(account)) account.save() else: @@ -120,7 +121,7 @@ class Abastecimiento: account = settings.DISTRIBUTOR_ACCOUNT logger = logging.getLogger('logger') account_manager = Account.objects - esperando_transaccion = Status.objects.get_esperando_transaccion() + esperando_transaccion = Status.objects.get_esperando_transaccion_abastecimiento() def abastecer(self, account, cantidad): self.logger.info("Abasteciendo {} con {} wei".format(account.address, cantidad)) @@ -143,9 +144,11 @@ class ActualizacionEstados: pendiente_distribucion = Status.objects.get_pendiente_distribucion esperando_desvinculacion = Status.objects.get_esperando_desvinculado esperando_transaccion = Status.objects.get_esperando_transaccion + esperando_transaccion_abastecimiento = Status.objects.get_esperando_transaccion_abastecimiento lista_para_gestion = Status.objects.get_lista_para_gestion distillery = Distillery() asociacion_beneficiario = AsociacionCuenta() + servicios_manager = Service.objects def actualizar_cuentas(self, cuentas): # no me odies pato, cuando vuelva corrijo esta bola de nieve, mi peor codigo cuentas_a_actualizar = [] @@ -153,44 +156,48 @@ class ActualizacionEstados: cuentas_a_eliminar = [] cuentas_a_listo = [] topes_a_eliminar = [] - satisfecho = self.satisfecho() - verificado = self.verificado() - sin_verificar = self.sin_verificar() - pendiente_distribucion = self.pendiente_distribucion() - esperando_desvinculacion = self.esperando_desvinculacion() - esperando_transaccion = self.esperando_transaccion() - lista_para_gestion = self.lista_para_gestion() + servicios_a_eliminar = [] for i in cuentas: - if i.status == pendiente_distribucion and i.balance() >= i.tope(): + if (i.status == self.pendiente_distribucion() or i.status == self.esperando_transaccion_abastecimiento())\ + and i.balance() >= i.tope(): cuentas_a_actualizar.append(i.pk) - elif i.status == esperando_desvinculacion and\ + elif i.status == self.esperando_desvinculacion() and\ self.distillery.ya_fue_eliminado(settings.DISTRIBUTOR_ACCOUNT, i.address): cuentas_a_eliminar.append(i.pk) - elif i.status == sin_verificar and self.distillery.ya_fue_verificado(i.address): + servicios_a_eliminar.append(i.service.id) + elif i.status == self.sin_verificar() and self.distillery.ya_fue_verificado(i.address): cuentas_a_verificar.append(i.pk) - elif i.status == verificado: + elif i.status == self.verificado(): tope_esperado = self.tope_manager.get(account=i) try: self.asociacion_beneficiario.asociar_cuenta(i, tope_esperado.valor) except Exception as e: self.logger.error(e) - elif i.status == esperando_transaccion and self.distillery.ya_fue_agregado(i.address): + elif i.status == self.esperando_transaccion() and self.distillery.ya_fue_agregado(i.address): cuentas_a_listo.append(i.pk) topes_a_eliminar.append(i.pk) - self.account_manager.filter(pk__in=cuentas_a_actualizar).update(status=satisfecho) - self.account_manager.filter(pk__in=cuentas_a_verificar).update(status=verificado) - self.account_manager.filter(pk__in=cuentas_a_listo).update(status=lista_para_gestion) + self.account_manager.filter(pk__in=cuentas_a_actualizar).update(status=self.satisfecho()) + self.account_manager.filter(pk__in=cuentas_a_verificar).update(status=self.verificado()) + self.account_manager.filter(pk__in=cuentas_a_listo).update(status=self.lista_para_gestion()) self.account_manager.filter(pk__in=cuentas_a_eliminar).delete() self.tope_manager.filter(account__id__in=topes_a_eliminar).delete() + self.servicios_manager.filter(pk__in=servicios_a_eliminar).delete() class DesvinculacionCuenta: distillery = Distillery() account_manager = Account.objects - desvinculando = Status.objects.get_esperando_desvinculado() + desvinculando = Status.objects.get_esperando_desvinculado + sin_verificar = Status.objects.get_sin_verificar def desvincular_cuenta(self, account): - self.distillery.sacar_beneficiario(settings.DISTRIBUTOR_ACCOUNT, account.address) - account.status = self.desvinculando - account.save() + if account.status != self.sin_verificar(): + self.distillery.sacar_beneficiario(settings.DISTRIBUTOR_ACCOUNT, account.address) + account.status = self.desvinculando() + account.save() + else: + service = account.service + account.delete() + service.delete() + diff --git a/dapp/tests.py b/dapp/tests.py index 33efbc5b8c32cfb76d985cfefbb0d65dad75b4f5..0e312c46b2752d7f5522fc9dac3514b615577cce 100644 --- a/dapp/tests.py +++ b/dapp/tests.py @@ -9,9 +9,10 @@ You should have received a copy of the GNU General Public License along with thi """ from django.test import TestCase -from api.models import CustomUser, Institution, Service +from api.models import CustomUser, Institution, Service, Section from dapp.services import PetitorioEtherCuenta, AsociacionCuenta, \ - NotValidAddressException, DesvinculacionCuenta, VerificacionCuenta, NotVerifiedAccountException + NotValidAddressException, DesvinculacionCuenta, VerificacionCuenta, NotVerifiedAccountException, \ + ActualizacionEstados from dapp.models import Account, Status, TopeEsperado from django.contrib.auth.models import User @@ -19,30 +20,38 @@ from django.contrib.auth.models import User class GeneradorPruebas: def generar_pruebas(self): - Account.objects.create(address="address") - self.account = Account.objects.filter(address="address").first() - user = User.objects.create(first_name="Algun", last_name="Usuario", ) - self.user = CustomUser.objects.create(user=user, cuit="123456789", section=1) + Section.objects.create(name="Seccion") + self.seccion = Section.objects.filter(name='Seccion').first() + user = User.objects.create(first_name="Algun", last_name="Usuario", username="username") + self.user = CustomUser.objects.create(user=user, cuit="123456789", section=self.seccion) Status.objects.create(descripcion="Pendiente de distribucion") self.pendiente_status = Status.objects.filter(descripcion="Pendiente de distribucion").first() - Status.objects.create(descripcion="Esperando transaccion") - self.esperando_transaccion = Status.objects.filter(descripcion="Esperando transaccion").first() + Status.objects.create(descripcion="Esperando transaccion de alta beneficiario") + self.esperando_transaccion = Status.objects.filter( + descripcion="Esperando transaccion de alta beneficiario").first() Status.objects.create(descripcion="Esperando desvinculacion") self.esperando_desvinculador = Status.objects.filter(descripcion="Esperando desvinculacion").first() Status.objects.create(descripcion="Sin verificar") self.sin_verificar = Status.objects.filter(descripcion="Sin verificar").first() Status.objects.create(descripcion="Verificada") self.verificada = Status.objects.filter(descripcion="Verificada").first() + Status.objects.create(descripcion="Satisfecho") + self.satisfecho = Status.objects.filter(descripcion="Satisfecho").first() + Status.objects.create(descripcion="Esperando transaccion de abastecimiento") + self.esperando_transaccion_abastecimiento = Status.objects.filter( + descripcion="Esperando transaccion de abastecimiento").first() Institution.objects.create(name="Institucion loca") self.institucion = Institution.objects.filter(name='Institucion loca').first() Service.objects.create(name="Servicio loco") self.service = Service.objects.filter(name="Servicio loco").first() + Account.objects.create(address="address", status=self.sin_verificar) + self.account = Account.objects.filter(address="address").first() def generar_cuentas(self): - Account.objects.create(address="address1") - Account.objects.create(address="address2") - Account.objects.create(address="address3") - Account.objects.create(address="address4") + Account.objects.create(address="address1", status=self.sin_verificar) + Account.objects.create(address="address2", status=self.sin_verificar) + Account.objects.create(address="address3", status=self.sin_verificar) + Account.objects.create(address="address4", status=self.sin_verificar) self.accounts = Account.objects.filter(address__in=["address1", "address2", "address3", @@ -92,6 +101,9 @@ class DistilleryMock: def iniciar_verificacion(self, from_account, address, password): pass + def ya_fue_eliminado(self, dist, target): + return True + class TestAsociacionCuenta(TestCase, GeneradorPruebas): class ValidadorSiempreTrueMock: @@ -127,8 +139,7 @@ class TestAsociacionCuenta(TestCase, GeneradorPruebas): self.asociador.gateway = self.ValidadorSiempreTrueMock() Account.objects.create(address="cuenta no verificada", status=self.sin_verificar) cuenta = Account.objects.filter(address="cuenta no verificada").first() - self.assertRaises(NotVerifiedAccountException, self.asociador.asociar_cuenta, account=cuenta, - tope=10) + self.assertRaises(NotVerifiedAccountException, self.asociador.asociar_cuenta, account=cuenta, tope=10) class TestDesvincularCuenta(TestCase, GeneradorPruebas): @@ -139,13 +150,22 @@ class TestDesvincularCuenta(TestCase, GeneradorPruebas): self.desvinculador.distillery = DistilleryMock() def test_desvincular_cuenta(self): - self.desvinculador.desvincular_cuenta(self.account) - self.assertEqual(self.esperando_desvinculador.descripcion, self.account.status.descripcion, + account_desvinculando = Account.objects.create(address='address_desvincular', status=self.satisfecho, + institution=self.institucion, service=self.service) + self.desvinculador.desvincular_cuenta(account_desvinculando) + self.assertEqual(self.esperando_desvinculador, + Account.objects.get(address=account_desvinculando.address).status, "Deberia estar esperando desvinculado") + def test_borrar_cuenta(self): + account_a_borrar = Account.objects.create(address='address_borrar', status=self.sin_verificar, + institution=self.institucion, service=self.service) + self.assertEqual(Account.objects.filter(address='address_borrar').count(), 1) + self.desvinculador.desvincular_cuenta(account_a_borrar) + self.assertEqual(Account.objects.filter(address='address_borrar').count(), 0) -class TestVerificacionCuenta(TestCase, GeneradorPruebas): +class TestVerificacionCuenta(TestCase, GeneradorPruebas): class GeneradorClaveMock: def generar_clave(self): return "clave mock" @@ -181,3 +201,33 @@ class TestVerificacionCuenta(TestCase, GeneradorPruebas): def test_verificar_cuenta_invalida(self): self.verificacion.gateway = self.ValidadorSiempreFalseMock() self.assertRaises(NotValidAddressException, self.verificacion.iniciar_verificacion, account=self.account, ) + + +class TestActualizarEstados(TestCase, GeneradorPruebas): + + def setUp(self): + self.actualizador = ActualizacionEstados() + self.generar_pruebas() + + def test_actualizar_desvinculacion(self): + self.actualizador.distillery = DistilleryMock() + Account.objects.distillery = DistilleryMock() + Account.objects.gateway = MockGateway() + account = Account.objects.create(address="address_random", status=self.esperando_desvinculador, + service=self.service, institution=self.institucion) + self.assertEqual(Account.objects.filter(address="address_random").count(), 1) + self.actualizador.actualizar_cuentas([account]) + self.assertEqual(Account.objects.filter(address="address_random").count(), 0) + + def test_ya_esta_satisfecho(self): + Account.objects.gateway = MockGateway() + Account.objects.distillery = DistilleryMock() + account_pendiente = Account.objects.create(address="address_random", status=self.pendiente_status, + service=self.service, institution=self.institucion) + + account_esperando = Account.objects.create(address="address_random_2", status=self.esperando_transaccion_abastecimiento, + service=self.service, institution=self.institucion) + self.actualizador.actualizar_cuentas([account_pendiente, account_esperando]) + self.assertEqual(self.satisfecho, Account.objects.get(address="address_random").status) + self.assertEqual(self.satisfecho, Account.objects.get(address="address_random_2").status) + diff --git a/frontend/templates/dapp/account_list.html b/frontend/templates/dapp/account_list.html index 014e266799d3a1b83497d41215001ffe63bff724..4def32540767d91bb5f3b2c47987e0e1742e7ea5 100644 --- a/frontend/templates/dapp/account_list.html +++ b/frontend/templates/dapp/account_list.html @@ -128,7 +128,7 @@ <pre>var estimate = contractInstance.proveControl.estimateGas("<label id="label-clave1"></label>")</pre> </li> <li>Generá una transacción - <pre>var tx = contractInstance.proveControl.sendTransaction("<label id="label-clave2"></label>", {gas:estimate, gasPrice:1})</pre> + <pre>var tx = contractInstance.proveControl.sendTransaction("<label id="label-clave2"></label>", {gas:estimate, gasPrice:eth.gasPrice})</pre> </li> <li>Obtené el recibo. Esto puede devolver <i>undefined</i> porque depende de si se selló el bloque con la transacción <pre>eth.getTransactionReceipt(tx)</pre> diff --git a/frontend/templates/django_registration/registration_form.html b/frontend/templates/django_registration/registration_form.html index 8e49617cbb0bb1fcec098ab400ee69952609f708..a38b61bf334322895b7a2fb679fc3ae151ae6cbd 100644 --- a/frontend/templates/django_registration/registration_form.html +++ b/frontend/templates/django_registration/registration_form.html @@ -72,6 +72,16 @@ You should have received a copy of the GNU General Public License along with thi <p>Utilizá ocho caracteres como mÃnimo con una combinación de letras, números y sÃmbolos.</p> </div> + <div class="form-group form-group-lg col-sm-12"> + <div> + <label class="control-label" for="terms">PolÃtica de Uso</label> + </div> + <div> + <input type="checkbox" name="terms" id="terms" placeholder="PolÃtica de Uso" required style="float: left; margin-top: 8px;"> + <label class="font_small" for="terms" style="font-weight: 100">He leÃdo y acepto la <a style="cursor: pointer" data-toggle="modal" data-target="#terms-modal">polÃtica de uso</a></label> + </div> + </div> + <script src='https://www.google.com/recaptcha/api.js'></script> <div class="g-recaptcha col-sm-12" data-sitekey="{{ data_sitekey }}"></div> @@ -84,6 +94,34 @@ You should have received a copy of the GNU General Public License along with thi </form> </section> </div> + <div class="modal" tabindex="-1" role="dialog" id="terms-modal"> + <div class="modal-dialog" role="document" style="width: 80%;"> + <div class="modal-content"> + <div class="modal-header"> + <h4 class="modal-title">PolÃtica de uso</h4> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + <p>What is Lorem Ipsum? +Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + +Why do we use it? +It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like). + + +Where does it come from? +Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. + + </p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" data-dismiss="modal" >Cerrar</button> + </div> + </div> + </div> + </div> </main> {% include 'footer.html' %} @@ -139,13 +177,15 @@ You should have received a copy of the GNU General Public License along with thi password: { required: "Ingresá una contraseña", minlength: "La contraseña debe tener al menos 8 caracteres" - } + }, + terms: "Debes aceptar la polÃtica de uso" }, rules:{ first_name: "required", last_name: "required", username: "required", + terms: "required", password: { required: true, atLeastOneLowercaseLetter: true, diff --git a/frontend/templates/header.html b/frontend/templates/header.html index dd8ffc605518fac508a9dfb8e4c282648e1825f3..c9c919432fd3664f2d417aeb4c39ffe7c8979e91 100644 --- a/frontend/templates/header.html +++ b/frontend/templates/header.html @@ -28,4 +28,13 @@ You should have received a copy of the GNU General Public License along with thi <body> {% block content %}{% endblock %} </body> + <script> + $(window).unload(function() { + $.ajax({ + url: '/accounts/logout/', + method: 'GET', + + }); + }); + </script> </html> \ No newline at end of file diff --git a/logica_cuentas/admin.py b/logica_cuentas/admin.py index 540903acc3d9db6edf98d04fb903be1919b66af9..c48ca114ab391c6f4fa40cfb7ca9ee093af59193 100644 --- a/logica_cuentas/admin.py +++ b/logica_cuentas/admin.py @@ -10,3 +10,19 @@ You should have received a copy of the GNU General Public License along with thi from django.contrib import admin # Register your models here. +from logica_cuentas.forms import RelacionUsuarioAccountForm +from logica_cuentas.models import RelacionUsuarioAccountStatus, RelacionUsuarioAccount + + +class RelacionUsuarioAccountAdmin(admin.ModelAdmin): + form = RelacionUsuarioAccountForm + list_filter = ('status',) + # actions = [pedir_ether, abastecer_inmediatamente, desvincular] + + +class RelacionUsuarioAccountStatusAdmin(admin.ModelAdmin): + exclude = ('id',) + + +admin.site.register(RelacionUsuarioAccount, RelacionUsuarioAccountAdmin) +admin.site.register(RelacionUsuarioAccountStatus, RelacionUsuarioAccountStatusAdmin) diff --git a/logica_cuentas/apps.py b/logica_cuentas/apps.py index b36ee8508906448d29933b40e5227b58f68090cb..c558f2dec3c7fc5a4c0af27bd39d12495d733172 100644 --- a/logica_cuentas/apps.py +++ b/logica_cuentas/apps.py @@ -12,3 +12,4 @@ from django.apps import AppConfig class LogicaCuentasConfig(AppConfig): name = 'logica_cuentas' + verbose_name = 'Relacion Cuenta BFA - EOAs' diff --git a/logica_cuentas/management/commands/agregar_estados_cuenta_usuario.py b/logica_cuentas/management/commands/agregar_estados_cuenta_usuario.py index 615ad1ee091b0d149a4077a8a01f2d98d6bfa6b2..499816c536f9814314b8b2b29de76f3dfece9055 100644 --- a/logica_cuentas/management/commands/agregar_estados_cuenta_usuario.py +++ b/logica_cuentas/management/commands/agregar_estados_cuenta_usuario.py @@ -10,21 +10,25 @@ You should have received a copy of the GNU General Public License along with thi from django.core.management.base import BaseCommand from logica_cuentas.models import RelacionUsuarioAccountStatus import logging + logger = logging.getLogger('logger') class Command(BaseCommand): def handle(self, *args, **options): try: - logger.info("Estado 'Sin verificar' no existe, creandose") - res = RelacionUsuarioAccountStatus.objects.create(descripcion="Sin verificar") - logger.info("Hecho " + str(res)) - - - logger.info("Estado 'Verificada' no existe, creandose") - res = RelacionUsuarioAccountStatus.objects.create(descripcion="Verificada") - logger.info("Hecho " + str(res)) - + sin_verificar = RelacionUsuarioAccountStatus.objects.filter(descripcion="Sin verificar") + verificada = RelacionUsuarioAccountStatus.objects.filter(descripcion="Verificada") + + if not sin_verificar.exists(): + logger.info("Estado 'Sin verificar' no existe, creandose") + res = RelacionUsuarioAccountStatus.objects.create(descripcion="Sin verificar") + logger.info("Hecho " + str(res)) + + if not verificada.exists(): + logger.info("Estado 'Verificada' no existe, creandose") + res = RelacionUsuarioAccountStatus.objects.create(descripcion="Verificada") + logger.info("Hecho " + str(res)) except Exception as e: logger.exception(e) diff --git a/logica_cuentas/managers.py b/logica_cuentas/managers.py index fe359c8533cf745e9fd95825a8f32a48868251bf..5a48b77a69c205973b6ccca2d99c9736b5a04c79 100644 --- a/logica_cuentas/managers.py +++ b/logica_cuentas/managers.py @@ -27,7 +27,6 @@ class RelacionUsuarioAccountStatusManager(models.Manager): class RelacionUsuarioAccountManager(models.Manager): - account_status_manager = Status.objects account_manager = Account.objects @@ -40,8 +39,23 @@ class RelacionUsuarioAccountManager(models.Manager): def cant_cuentas_sin_verificar_por_user(self, user): return self.get_accounts_sin_verificar_por_user(user).count() + def get_users_por_account(self, account): + users = [] + for u in self.filter(account=account): + users.append(u.user) + return users + def get_accounts_por_user(self, user): accounts = [] for a in self.filter(user=user): accounts.append(a.account) return accounts + + def existe_relacion(self, user, account): + return self.filter(user=user, account=account).exists() + + def tiene_owner(self, account): + return self.filter(account=account, is_owner=True).exists() + + def owner(self, account): + return self.filter(account=account, is_owner=True).first().user.user \ No newline at end of file diff --git a/logica_cuentas/models.py b/logica_cuentas/models.py index f01ed2e939d76cd913004ffa4345fde27fca1b0e..123831a38b544536b122aeb277b4fff76b72e413 100644 --- a/logica_cuentas/models.py +++ b/logica_cuentas/models.py @@ -18,16 +18,27 @@ class RelacionUsuarioAccountStatus(models.Model): descripcion = models.CharField(max_length=60) objects = RelacionUsuarioAccountStatusManager() + def __str__(self): + return self.descripcion + class Meta: db_table = 'customuser_account_status' + verbose_name = 'Estado de la relacion usuario - EOA' + verbose_name_plural = 'Estados de la relacion usuario - EOA' class RelacionUsuarioAccount(models.Model): account = models.ForeignKey(Account, on_delete=models.PROTECT) user = models.ForeignKey(CustomUser, on_delete=models.PROTECT) status = models.ForeignKey(RelacionUsuarioAccountStatus, on_delete=models.PROTECT, ) + is_owner = models.BooleanField(default=False) objects = RelacionUsuarioAccountManager() + def __str__(self): + return "Account: {} ; user : {}".format(self.account, self.user) + class Meta: db_table = 'customuser_account' unique_together = (("account", "user"),) + verbose_name = 'Relacion usuario BFA - EOA' + verbose_name_plural = 'Relaciones usuario BFA - EOA' diff --git a/logica_cuentas/services.py b/logica_cuentas/services.py index 8855c2a78a351f78ec87d53b4c1e3e25de2db146..a4e1a66615757958efbeef96ed6984ae04454321 100644 --- a/logica_cuentas/services.py +++ b/logica_cuentas/services.py @@ -11,8 +11,8 @@ import logging from django.db import transaction -from dapp.models import Account, TopeEsperado -from dapp.services import VerificacionCuenta, PetitorioEtherCuenta, AccountBeingKicked +from dapp.models import Account, TopeEsperado, Status +from dapp.services import VerificacionCuenta, PetitorioEtherCuenta, AccountBeingKicked, DesvinculacionCuenta from logica_cuentas.models import RelacionUsuarioAccount, RelacionUsuarioAccountStatus @@ -27,19 +27,21 @@ class AltaCuentaEthereum: verificador_cuenta = VerificacionCuenta() relacion_sin_verificar = RelacionUsuarioAccountStatus.objects.get_sin_verificar_relacion relacion_verificada = RelacionUsuarioAccountStatus.objects.get_relacion_verificada + sin_verificar = Status.objects.get_sin_verificar def alta_cuenta_ethereum(self, address, institution, service, user, tope=0): if self.relacion_manager.cant_cuentas_sin_verificar_por_user(user) > 4: raise TooMuchUnverifiedAccountsException with transaction.atomic(): - self.account_manager.create(address=address, institution=institution, - service=service, owner=user) + funcion_status = self.sin_verificar + self.account_manager.create(address=address, institution=institution, service=service, + status=funcion_status()) account = self.account_manager.filter(address=address).first() self.tope_manager.create(valor=tope, account=account) clave = self.verificador_cuenta.iniciar_verificacion(account) funcion = self.relacion_verificada - self.relacion_manager.create(user=user, account=account, status=funcion()) + self.relacion_manager.create(user=user, account=account, status=funcion(), is_owner=True) return account, clave @@ -58,3 +60,62 @@ class PetitorioEtherUsuario: self.petitorio_ether.pedir_ether(c) except AccountBeingKicked as ack: self.logger.info(ack.msg) + + +class NoOwnerException(Exception): + pass + + +class AlreadyBoundException(Exception): + pass + + +class CreacionRelacionCuentaUsuario: + manager = RelacionUsuarioAccount.objects + sin_verificar = RelacionUsuarioAccountStatus.objects.get_sin_verificar_relacion + + def vincular(self, user, account): + if self.manager.existe_relacion(user, account): + raise AlreadyBoundException("Account {} ya esta relacionada a user {}".format(str(account), str(user))) + if not self.manager.tiene_owner(account): + raise NoOwnerException("Account {} no tiene dueño".format(str(account))) + sin_verificar_funcion = self.sin_verificar + relacion = self.manager.create(user=user, account=account, is_owner=False, status=sin_verificar_funcion()) + return relacion + + +class DesvinculacionDefinitiva: + desvinculador = DesvinculacionCuenta() + relacion_manager = RelacionUsuarioAccount.objects + + def desvincular(self, relacion): + with transaction.atomic(): + + if relacion.is_owner: + + accounts = self.relacion_manager.get_users_por_account(relacion.account) + + if accounts.count() > 1: + error_message = 'Los siguientes usuarios tienen vinculada la cuenta, deben desvincularla para poder ser borrada: <br/><ul>' + for a in accounts: + if a.user.user.id != relacion.user.user.id: + error_message = error_message + '<li>' + a.user.user.username + ' - ' + a.user.user.email + '</li>' + + error_message = error_message + '</ul>' + + messages.error(request, error_message, extra_tags='danger') + else: + account = Account.objects.get(pk=relacion.account_id) + + account_address = relacion.account.address + + relacion.delete() + account.delete() + service = Service.objects.get(pk=account.service_id) + service.delete() + + messages.success(request, _('cuenta_borrada') % account_address) + + else: + relacion.delete() + messages.success(request, _('cuenta_desvinculada') % relacion.account.address) diff --git a/logica_cuentas/tests.py b/logica_cuentas/tests.py index 21097c7a21f0aef9c7c142909f00587ddcf13624..731504c598f1b0c08c28a16e8d363d4b9be4c5d5 100644 --- a/logica_cuentas/tests.py +++ b/logica_cuentas/tests.py @@ -11,12 +11,15 @@ from django.test import TestCase # Create your tests here. import dapp +from api.models import CustomUser from dapp.models import Account, Status, TopeEsperado from dapp.services import Distribucion, NotValidAddressException from dapp.tests import DistilleryMock from logica_cuentas.models import RelacionUsuarioAccountStatus, RelacionUsuarioAccount -from logica_cuentas.services import PetitorioEtherUsuario, AltaCuentaEthereum, TooMuchUnverifiedAccountsException +from logica_cuentas.services import PetitorioEtherUsuario, AltaCuentaEthereum, TooMuchUnverifiedAccountsException, \ + NoOwnerException, AlreadyBoundException, CreacionRelacionCuentaUsuario from django.db import models +from django.contrib.auth.models import User class GeneradorPruebas: @@ -26,6 +29,28 @@ class GeneradorPruebas: RelacionUsuarioAccountStatus.objects.create(descripcion="Verificada") self.relacion_verificada = RelacionUsuarioAccountStatus.objects.filter(descripcion="Verificada").first() + class ValidadorSiempreTrueMock: + def is_valid_address(self, address): + return True + + class ValidadorSiempreFalseMock: + def is_valid_address(self, address): + return False + + class ManagerMock(models.Manager): + def cant_cuentas_sin_verificar_por_user(self, user): + return 4 + + def tiene_owner(self, account): + return True + + class ManagerMockCuentasSinVerificar(models.Manager): + def cant_cuentas_sin_verificar_por_user(self, user): + return 10 + + def tiene_owner(self, account): + return False + class TestDistribucion(TestCase, dapp.tests.GeneradorPruebas): @@ -69,21 +94,6 @@ class VerificacionInvalidaMock(object): class TestAltaCuentaEthereum(TestCase, GeneradorPruebas, dapp.tests.GeneradorPruebas): - class ValidadorSiempreTrueMock: - def is_valid_address(self, address): - return True - - class ValidadorSiempreFalseMock: - def is_valid_address(self, address): - return False - - class ManagerMock(models.Manager): - def cant_cuentas_sin_verificar_por_user(self, user): - return 4 - - class ManagerMockCuentasSinVerificar(models.Manager): - def cant_cuentas_sin_verificar_por_user(self, user): - return 10 def setUp(self): self.alta_cuenta = AltaCuentaEthereum() @@ -99,12 +109,14 @@ class TestAltaCuentaEthereum(TestCase, GeneradorPruebas, dapp.tests.GeneradorPru self.managerMock.cant_cuentas_sin_verificar_por_user (cuenta, clave) = self.alta_cuenta.alta_cuenta_ethereum("cuenta poronga", self.institucion, self.service, self.user, 1000) + relacion = RelacionUsuarioAccount.objects.filter(user=self.user, account=cuenta).first() self.assertEqual("cuenta poronga", cuenta.address, "DeberÃan ser iguales las direcciones") self.assertEqual(self.institucion, cuenta.institution, "DeberÃan ser las mismas instituciones") self.assertEqual("clave mock", clave, "Las claves deberÃan ser iguales") tope_esperado = TopeEsperado.objects.filter(account=cuenta).first().valor self.assertEqual(1000, tope_esperado, "Los montos deberÃan ser iguales") self.assertEqual(self.sin_verificar.descripcion, cuenta.status.descripcion, "DeberÃa estar sin verificar") + self.assertTrue(relacion.is_owner, "El usuario deberÃa ser owner de esta cuenta") def test_verificar_cuenta_invalida(self): self.alta_cuenta.verificador_cuenta = VerificacionInvalidaMock() @@ -121,3 +133,50 @@ class TestAltaCuentaEthereum(TestCase, GeneradorPruebas, dapp.tests.GeneradorPru self.assertRaises(TooMuchUnverifiedAccountsException, self.alta_cuenta.alta_cuenta_ethereum, address="cuenta poronga", user=self.user, institution=self.institucion, service=self.service) self.assertFalse(Account.objects.filter(address="cuenta poronga").exists()) + + +class TestCreacionRelacionCuentaUsuario(TestCase, GeneradorPruebas, dapp.tests.GeneradorPruebas): + + def setUp(self): + self.creador = CreacionRelacionCuentaUsuario() + self.generar_estados() + self.generar_pruebas() + self.generar_cuentas() + user = User.objects.create(first_name="Otro", last_name="Usuarito", username="sarlanga") + self.otro_user = CustomUser.objects.create(user=user, cuit="12345678910", section=self.seccion) + self.managerMock = self.ManagerMock() + self.managerMockInvalido = self.ManagerMockCuentasSinVerificar() + pass + + def test_creacion_vinculacion(self): + manager_original = self.creador.manager + self.creador.manager.tiene_owner = self.managerMock.tiene_owner + self.assertEqual(RelacionUsuarioAccount.objects.filter(user=self.user, account=self.account).count(), 0) + relacion = self.creador.vincular(self.user, self.account) + self.assertEqual(RelacionUsuarioAccount.objects.filter(user=self.user, account=self.account).count(), 1) + self.assertFalse(relacion.is_owner) + self.assertEqual(self.sin_verificar_relacion, relacion.status) + self.creador.manager = manager_original + + def test_creacion_vinculacion_ya_existia(self): + self.creador.vincular(self.user, self.account) + self.assertRaises(AlreadyBoundException, self.creador.vincular, + user=self.user, account=self.account) + + def test_alta_y_vinculacion(self): + alta_cuenta = AltaCuentaEthereum() + alta_cuenta.verificador_cuenta = VerificacionValidaMock() + alta_cuenta.relacion_manager.cant_cuentas_sin_verificar_por_user = \ + self.managerMock.cant_cuentas_sin_verificar_por_user + (cuenta, clave) = alta_cuenta.alta_cuenta_ethereum("cuenta poronga", self.institucion, self.service, + self.user, 1000) + relacion = self.creador.vincular(self.otro_user, cuenta) + self.assertFalse(relacion.is_owner) + self.assertEqual(RelacionUsuarioAccount.objects.filter(account=cuenta).count(), 2) + self.assertEqual(self.sin_verificar_relacion, relacion.status) + + def test_vinculacion_sin_owner(self): + manager_original = self.creador.manager + self.creador.manager.tiene_owner = self.managerMockInvalido.tiene_owner + self.assertRaises(NoOwnerException, self.creador.vincular, user=self.user, account=self.account) + self.creador.manager = manager_original diff --git a/requirements.txt b/requirements.txt index d504a15ce870e8388cb4e8a51a1d955f9f043a50..697def662741029bcf6868e60da3361caffa7022 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,6 @@ hexbytes==0.1.0 idna==2.7 lru-dict==1.1.6 parsimonious==0.8.0 -pkg-resources==0.0.0 psycopg2==2.7.6.1 psycopg2-binary==2.7.6.1 pycryptodome==3.6.6 diff --git a/scripts_utiles/PoAdeploy.py b/scripts_utiles/PoAdeploy.py index 6462f5ae95d842813233b38d79e465bea48f6601..99dca836c963ac80374f28b7109274327e35d1aa 100644 --- a/scripts_utiles/PoAdeploy.py +++ b/scripts_utiles/PoAdeploy.py @@ -19,9 +19,9 @@ from web3.middleware import geth_poa_middleware w3 = Web3(Web3.HTTPProvider('http://10.23.10.71:8501')) w3.middleware_stack.inject(geth_poa_middleware, layer=0) -abi = '[ { "anonymous": false, "inputs": [ { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "proofOfControlWeiAmountChanged", "type": "event" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "addBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "add", "type": "address" }, { "name": "password", "type": "bytes32" } ], "name": "addSuitor", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "changeLimit", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "ben", "type": "address" }, { "indexed": false, "name": "newLimit", "type": "uint256" } ], "name": "limitChanged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorNotApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" }, { "indexed": true, "name": "distr", "type": "address" } ], "name": "suitorAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "limit", "type": "uint256" } ], "name": "addedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "top", "type": "uint256" } ], "name": "addedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "replenished", "type": "event" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "top", "type": "uint256" } ], "name": "addDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "key", "type": "string" } ], "name": "proveControl", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "amount", "type": "uint256" } ], "name": "replenish", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [], "name": "replenishAll", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "accs", "type": "address[]" }, { "name": "amounts", "type": "uint256[]" } ], "name": "replenishList", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "amount", "type": "uint256" } ], "name": "setProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "payable": true, "stateMutability": "payable", "type": "constructor" }, { "constant": true, "inputs": [], "name": "getBeneficiariesCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getBeneficiaryLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getDistributorLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "key", "type": "string" } ], "name": "hash", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "pure", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ]' +abi = '[ { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getBeneficiaryLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "accs", "type": "address[]" }, { "name": "amounts", "type": "uint256[]" } ], "name": "replenishList", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "key", "type": "string" } ], "name": "proveControl", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "getProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "amount", "type": "uint256" } ], "name": "setProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "amount", "type": "uint256" } ], "name": "replenish", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": true, "inputs": [], "name": "getBeneficiariesCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "addBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "add", "type": "address" }, { "name": "password", "type": "bytes32" } ], "name": "addSuitor", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "top", "type": "uint256" } ], "name": "addDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "changeLimit", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "key", "type": "string" } ], "name": "hash", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "pure", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getDistributorLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "replenishAll", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "payable": true, "stateMutability": "payable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "limit", "type": "uint256" } ], "name": "addedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "top", "type": "uint256" } ], "name": "addedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "ben", "type": "address" }, { "indexed": false, "name": "newLimit", "type": "uint256" } ], "name": "limitChanged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "replenished", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" }, { "indexed": true, "name": "distr", "type": "address" } ], "name": "suitorAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorNotApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "proofOfControlWeiAmountChanged", "type": "event" } ]' -bytecode = "6080604052336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611ce0806100536000396000f3006080604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630146dfef14610101578063118b43d41461015857806312777df8146101f4578063141ff2a11461027557806352417497146102a057806356407455146102e5578063669be7011461033d5780637bde190c146103685780638f0c86fa146103c357806396074e701461041e5780639b5dca5a146104835780639d19b226146104df578063a7ade36f1461053a578063b20f3f371461059f578063b411ee9414610604578063cf1eb1c214610689578063d2030a37146106e0578063d9ec42f814610702575b600080fd5b34801561010d57600080fd5b50610142600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061075d565b6040518082815260200191505060405180910390f35b6101f26004803603810190808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919291929080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290505050610771565b005b34801561020057600080fd5b5061025b600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610861565b604051808215151515815260200191505060405180910390f35b34801561028157600080fd5b5061028a610aa9565b6040518082815260200191505060405180910390f35b3480156102ac57600080fd5b506102cb60048036038101908080359060200190929190505050610ab3565b604051808215151515815260200191505060405180910390f35b610323600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b53565b604051808215151515815260200191505060405180910390f35b34801561034957600080fd5b50610352610cc9565b6040518082815260200191505060405180910390f35b34801561037457600080fd5b506103a9600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cd6565b604051808215151515815260200191505060405180910390f35b3480156103cf57600080fd5b50610404600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610db9565b604051808215151515815260200191505060405180910390f35b34801561042a57600080fd5b50610469600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610dcd565b604051808215151515815260200191505060405180910390f35b6104c5600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035600019169060200190929190505050610ee6565b604051808215151515815260200191505060405180910390f35b3480156104eb57600080fd5b50610520600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611076565b604051808215151515815260200191505060405180910390f35b34801561054657600080fd5b50610585600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061108a565b604051808215151515815260200191505060405180910390f35b3480156105ab57600080fd5b506105ea600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611165565b604051808215151515815260200191505060405180910390f35b34801561061057600080fd5b5061066b600480360381019080803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061127f565b60405180826000191660001916815260200191505060405180910390f35b34801561069557600080fd5b506106ca600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611357565b6040518082815260200191505060405180910390f35b6106e861136b565b604051808215151515815260200191505060405180910390f35b34801561070e57600080fd5b50610743600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114bd565b604051808215151515815260200191505060405180910390f35b600061076a600183611589565b9050919050565b60008151835114151561078357600080fd5b60009050610790836115d8565b1561085c575b825181101561085b5782818151811015156107ad57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff166108fc84838151811015156107de57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16316108216001878681518110151561081257fe5b90602001906020020151611589565b039081150290604051600060405180830381858888f1935050505015801561084d573d6000803e3d6000fd5b508080600101915050610796565b5b505050565b6000806008541180156109c85750600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600019163073ffffffffffffffffffffffffffffffffffffffff1663b411ee94846040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561093b578082015181840152602081019050610920565b50505050905090810190601f1680156109685780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15801561098757600080fd5b505af115801561099b573d6000803e3d6000fd5b505050506040513d60208110156109b157600080fd5b810190808051906020019092919050505060001916145b15610a5c573373ffffffffffffffffffffffffffffffffffffffff167f27331d2f70895590002d07861712460d31f950e1b18f7658f3a40441149d54b260405160405180910390a2600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000905560019050610aa4565b3373ffffffffffffffffffffffffffffffffffffffff167f0bd7a7206a3474c66723618e72cc804f3b3db8c5440ad272f4032a517b663ce060405160405180910390a2600090505b919050565b6000600854905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b1057600080fd5b816008819055507fb922369845d41aae76bb07b70450bc5603d4a0959b47db440c0c8491165a10e9826040518082815260200191505060405180910390a1919050565b6000610b606004336116b1565b80610bb757506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1515610bc257600080fd5b610bcd6001846116b1565b8015610bf95750610bdf600184611589565b8373ffffffffffffffffffffffffffffffffffffffff1631105b8015610c1b5750813073ffffffffffffffffffffffffffffffffffffffff1631115b15610cbe578273ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610c66573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff167f67aa7cb8cf4d3427fea2605f3073936075334185ea817ad4a3e3ffe6612ef830836040518082815260200191505060405180910390a260019050610cc3565b600090505b92915050565b6000600160020154905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d3357600080fd5b610d3e6004836116b1565b15610daf578173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fee9dbfa1f0856d9dc7e726f2a84489bf9ceb44e65761440471e0cf07024ec2fb60405160405180910390a3610da8600483611702565b9050610db4565b600090505b919050565b6000610dc66004836116b1565b9050919050565b6000610dda6004336116b1565b80610e3157506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1515610e3c57600080fd5b610e476004846116b1565b158015610e5d5750610e5a600433611589565b82105b15610edb578273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167facb9534d8c7cff5af1fe1ee56d258412e52005019c12a868daf35fcf6ebfdd9c846040518082815260200191505060405180910390a3610ed36001848461180d565b159050610ee0565b600090505b92915050565b6000610ef36004336116b1565b80610f4a57506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1515610f5557600080fd5b6008543073ffffffffffffffffffffffffffffffffffffffff163110151561106b5781600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081600019169055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fbfdc4f9f1c1e9c255c4aa6abd73a2a2cb4f599e3fc15f8b58d55483cb4ada82460405160405180910390a38273ffffffffffffffffffffffffffffffffffffffff166108fc6008549081150290604051600060405180830381858888f19350505050158015611061573d6000803e3d6000fd5b5060019050611070565b600090505b92915050565b60006110836001836116b1565b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156110e757600080fd5b6110f26001846116b1565b151561115a578273ffffffffffffffffffffffffffffffffffffffff167f0644aa13d0ac1766bc91d62a757486dc5f7f5dec6e40d3fec281ece9d2d3de2d836040518082815260200191505060405180910390a26111526004848461180d565b15905061115f565b600090505b92915050565b60006111726004336116b1565b806111c957506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156111d457600080fd5b6111df6001846116b1565b80156111f45750816111f2600433611589565b115b156112745761120560018484611994565b508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f861f6b2bc31fb94186e291e6e9b393d17d621075c758cb77330d8be25f57c6ee846040518082815260200191505060405180910390a360019050611279565b600090505b92915050565b6000816040516020018082805190602001908083835b6020831015156112ba5780518252602082019150602081019050602083039250611295565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310151561132357805182526020820191506020810190506020830392506112fe565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209050919050565b6000611364600483611589565b9050919050565b60008060008061137c6004336116b1565b806113d357506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156113de57600080fd5b6113e6611a46565b156114b2576113f56001611af1565b92505b611403600184611b24565b156114a957611413600184611b38565b915091508173ffffffffffffffffffffffffffffffffffffffff1631811115611497578173ffffffffffffffffffffffffffffffffffffffff166108fc8373ffffffffffffffffffffffffffffffffffffffff163183039081150290604051600060405180830381858888f19350505050158015611495573d6000803e3d6000fd5b505b6114a2600184611bca565b92506113f8565b600193506114b7565b600093505b50505090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561151a57600080fd5b6115256004836116b1565b1561157f578173ffffffffffffffffffffffffffffffffffffffff167f53ae61629b1cf76adc0f9eb0b6e7fcdf1271040d7a0df25ac23671ed6ecc191760405160405180910390a2611578600483611702565b9050611584565b600090505b919050565b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905092915050565b60008060008060009250600091505b845183101561168d576116126001868581518110151561160357fe5b90602001906020020151611589565b9050848381518110151561162257fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff163181111561168057848381518110151561165857fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16318103820191505b82806001019350506115e7565b3073ffffffffffffffffffffffffffffffffffffffff163182109350505050919050565b6000808360000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015411905092915050565b6000808360000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001549050600081141561175e5760009150611806565b8360000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090555050600184600101600183038154811015156117c857fe5b9060005260206000200160000160146101000a81548160ff021916908315150217905550836002016000815480929190600190039190505550600191505b5092915050565b6000808460000160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001549050828560000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555060008111156118b2576001915061198c565b8460010180548091906001016118c89190611c2e565b9050600181018560000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555083856001018281548110151561192857fe5b9060005260206000200160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508460020160008154809291906001019190505550600091505b509392505050565b6000808460000160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154905060008114156119f05760009150611a3e565b828560000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550600191505b509392505050565b6000806000806000611a586001611af1565b9350600092505b611a6a600185611b24565b15611ace57611a7a600185611b38565b915091508173ffffffffffffffffffffffffffffffffffffffff1631811115611abc578173ffffffffffffffffffffffffffffffffffffffff16318103830192505b611ac7600185611bca565b9350611a5f565b3073ffffffffffffffffffffffffffffffffffffffff1631831094505050505090565b6000611b1d827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611bca565b9050919050565b600082600101805490508210905092915050565b6000808360010183815481101515611b4c57fe5b9060005260206000200160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508360000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490509250929050565b600081806001019250505b826001018054905082108015611c1357508260010182815481101515611bf757fe5b9060005260206000200160000160149054906101000a900460ff165b15611c25578180600101925050611bd5565b81905092915050565b815481835581811115611c5557818360005260206000209182019101611c549190611c5a565b5b505050565b611cb191905b80821115611cad57600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a81549060ff021916905550600101611c60565b5090565b905600a165627a7a72305820682a03d4645be868cf5284f41444500a7c502d082820e40ed844358bc8ec69c40029" +bytecode = "6080604052336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611ce0806100536000396000f3006080604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630146dfef14610101578063118b43d41461015857806312777df8146101f4578063141ff2a11461027557806352417497146102a057806356407455146102e5578063669be7011461033d5780637bde190c146103685780638f0c86fa146103c357806396074e701461041e5780639b5dca5a146104835780639d19b226146104df578063a7ade36f1461053a578063b20f3f371461059f578063b411ee9414610604578063cf1eb1c214610689578063d2030a37146106e0578063d9ec42f814610702575b600080fd5b34801561010d57600080fd5b50610142600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061075d565b6040518082815260200191505060405180910390f35b6101f26004803603810190808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919291929080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290505050610771565b005b34801561020057600080fd5b5061025b600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610861565b604051808215151515815260200191505060405180910390f35b34801561028157600080fd5b5061028a610aa9565b6040518082815260200191505060405180910390f35b3480156102ac57600080fd5b506102cb60048036038101908080359060200190929190505050610ab3565b604051808215151515815260200191505060405180910390f35b610323600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b53565b604051808215151515815260200191505060405180910390f35b34801561034957600080fd5b50610352610cc9565b6040518082815260200191505060405180910390f35b34801561037457600080fd5b506103a9600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cd6565b604051808215151515815260200191505060405180910390f35b3480156103cf57600080fd5b50610404600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610db9565b604051808215151515815260200191505060405180910390f35b34801561042a57600080fd5b50610469600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610dcd565b604051808215151515815260200191505060405180910390f35b6104c5600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035600019169060200190929190505050610ee6565b604051808215151515815260200191505060405180910390f35b3480156104eb57600080fd5b50610520600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611076565b604051808215151515815260200191505060405180910390f35b34801561054657600080fd5b50610585600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061108a565b604051808215151515815260200191505060405180910390f35b3480156105ab57600080fd5b506105ea600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611165565b604051808215151515815260200191505060405180910390f35b34801561061057600080fd5b5061066b600480360381019080803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061127f565b60405180826000191660001916815260200191505060405180910390f35b34801561069557600080fd5b506106ca600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611357565b6040518082815260200191505060405180910390f35b6106e861136b565b604051808215151515815260200191505060405180910390f35b34801561070e57600080fd5b50610743600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114bd565b604051808215151515815260200191505060405180910390f35b600061076a600183611589565b9050919050565b60008151835114151561078357600080fd5b60009050610790836115d8565b1561085c575b825181101561085b5782818151811015156107ad57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff166108fc84838151811015156107de57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16316108216001878681518110151561081257fe5b90602001906020020151611589565b039081150290604051600060405180830381858888f1935050505015801561084d573d6000803e3d6000fd5b508080600101915050610796565b5b505050565b6000806008541180156109c85750600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600019163073ffffffffffffffffffffffffffffffffffffffff1663b411ee94846040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561093b578082015181840152602081019050610920565b50505050905090810190601f1680156109685780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15801561098757600080fd5b505af115801561099b573d6000803e3d6000fd5b505050506040513d60208110156109b157600080fd5b810190808051906020019092919050505060001916145b15610a5c573373ffffffffffffffffffffffffffffffffffffffff167f27331d2f70895590002d07861712460d31f950e1b18f7658f3a40441149d54b260405160405180910390a2600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000905560019050610aa4565b3373ffffffffffffffffffffffffffffffffffffffff167f0bd7a7206a3474c66723618e72cc804f3b3db8c5440ad272f4032a517b663ce060405160405180910390a2600090505b919050565b6000600854905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b1057600080fd5b816008819055507fb922369845d41aae76bb07b70450bc5603d4a0959b47db440c0c8491165a10e9826040518082815260200191505060405180910390a1919050565b6000610b606004336116b1565b80610bb757506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1515610bc257600080fd5b610bcd6001846116b1565b8015610bf95750610bdf600184611589565b8373ffffffffffffffffffffffffffffffffffffffff1631105b8015610c1b5750813073ffffffffffffffffffffffffffffffffffffffff1631115b15610cbe578273ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610c66573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff167f67aa7cb8cf4d3427fea2605f3073936075334185ea817ad4a3e3ffe6612ef830836040518082815260200191505060405180910390a260019050610cc3565b600090505b92915050565b6000600160020154905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d3357600080fd5b610d3e6004836116b1565b15610daf578173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fee9dbfa1f0856d9dc7e726f2a84489bf9ceb44e65761440471e0cf07024ec2fb60405160405180910390a3610da8600483611702565b9050610db4565b600090505b919050565b6000610dc66004836116b1565b9050919050565b6000610dda6004336116b1565b80610e3157506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1515610e3c57600080fd5b610e476004846116b1565b158015610e5d5750610e5a600433611589565b82105b15610edb578273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167facb9534d8c7cff5af1fe1ee56d258412e52005019c12a868daf35fcf6ebfdd9c846040518082815260200191505060405180910390a3610ed36001848461180d565b159050610ee0565b600090505b92915050565b6000610ef36004336116b1565b80610f4a57506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1515610f5557600080fd5b6008543073ffffffffffffffffffffffffffffffffffffffff163110151561106b5781600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081600019169055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fbfdc4f9f1c1e9c255c4aa6abd73a2a2cb4f599e3fc15f8b58d55483cb4ada82460405160405180910390a38273ffffffffffffffffffffffffffffffffffffffff166108fc6008549081150290604051600060405180830381858888f19350505050158015611061573d6000803e3d6000fd5b5060019050611070565b600090505b92915050565b60006110836001836116b1565b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156110e757600080fd5b6110f26001846116b1565b151561115a578273ffffffffffffffffffffffffffffffffffffffff167f0644aa13d0ac1766bc91d62a757486dc5f7f5dec6e40d3fec281ece9d2d3de2d836040518082815260200191505060405180910390a26111526004848461180d565b15905061115f565b600090505b92915050565b60006111726004336116b1565b806111c957506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156111d457600080fd5b6111df6001846116b1565b80156111f45750816111f2600433611589565b115b156112745761120560018484611994565b508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f861f6b2bc31fb94186e291e6e9b393d17d621075c758cb77330d8be25f57c6ee846040518082815260200191505060405180910390a360019050611279565b600090505b92915050565b6000816040516020018082805190602001908083835b6020831015156112ba5780518252602082019150602081019050602083039250611295565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310151561132357805182526020820191506020810190506020830392506112fe565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209050919050565b6000611364600483611589565b9050919050565b60008060008061137c6004336116b1565b806113d357506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156113de57600080fd5b6113e6611a46565b156114b2576113f56001611af1565b92505b611403600184611b24565b156114a957611413600184611b38565b915091508173ffffffffffffffffffffffffffffffffffffffff1631811115611497578173ffffffffffffffffffffffffffffffffffffffff166108fc8373ffffffffffffffffffffffffffffffffffffffff163183039081150290604051600060405180830381858888f19350505050158015611495573d6000803e3d6000fd5b505b6114a2600184611bca565b92506113f8565b600193506114b7565b600093505b50505090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561151a57600080fd5b6115256004836116b1565b1561157f578173ffffffffffffffffffffffffffffffffffffffff167f53ae61629b1cf76adc0f9eb0b6e7fcdf1271040d7a0df25ac23671ed6ecc191760405160405180910390a2611578600483611702565b9050611584565b600090505b919050565b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905092915050565b60008060008060009250600091505b845183101561168d576116126001868581518110151561160357fe5b90602001906020020151611589565b9050848381518110151561162257fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff163181111561168057848381518110151561165857fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16318103820191505b82806001019350506115e7565b3073ffffffffffffffffffffffffffffffffffffffff163182109350505050919050565b6000808360000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015411905092915050565b6000808360000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001549050600081141561175e5760009150611806565b8360000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090555050600184600101600183038154811015156117c857fe5b9060005260206000200160000160146101000a81548160ff021916908315150217905550836002016000815480929190600190039190505550600191505b5092915050565b6000808460000160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001549050828560000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555060008111156118b2576001915061198c565b8460010180548091906001016118c89190611c2e565b9050600181018560000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555083856001018281548110151561192857fe5b9060005260206000200160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508460020160008154809291906001019190505550600091505b509392505050565b6000808460000160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154905060008114156119f05760009150611a3e565b828560000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550600191505b509392505050565b6000806000806000611a586001611af1565b9350600092505b611a6a600185611b24565b15611ace57611a7a600185611b38565b915091508173ffffffffffffffffffffffffffffffffffffffff1631811115611abc578173ffffffffffffffffffffffffffffffffffffffff16318103830192505b611ac7600185611bca565b9350611a5f565b3073ffffffffffffffffffffffffffffffffffffffff1631831094505050505090565b6000611b1d827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611bca565b9050919050565b600082600101805490508210905092915050565b6000808360010183815481101515611b4c57fe5b9060005260206000200160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508360000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490509250929050565b600081806001019250505b826001018054905082108015611c1357508260010182815481101515611bf757fe5b9060005260206000200160000160149054906101000a900460ff165b15611c25578180600101925050611bd5565b81905092915050565b815481835581811115611c5557818360005260206000209182019101611c549190611c5a565b5b505050565b611cb191905b80821115611cad57600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a81549060ff021916905550600101611c60565b5090565b905600a165627a7a72305820e32f918d7b59986f9e898dc7dbf279e11c82a273dec1b2d416b96fd919d6c8780029" print (str(w3.eth.accounts)) # set pre-funded account as sender diff --git a/scripts_utiles/cambiarCantidad.py b/scripts_utiles/cambiarCantidad.py index 8e24fe0feaad1b3424b6f62074954445b462d582..8341f5952db92be8bcd5848cb2a64b211a747d88 100644 --- a/scripts_utiles/cambiarCantidad.py +++ b/scripts_utiles/cambiarCantidad.py @@ -10,29 +10,28 @@ You should have received a copy of the GNU General Public License along with thi from web3 import Web3 from web3.middleware import geth_poa_middleware from uuid import uuid1 +from django.conf import settings - -w3 = Web3(Web3.HTTPProvider('http://10.23.10.71:8501')) +w3 = Web3(Web3.HTTPProvider(settings.NODE_URL)) w3.middleware_stack.inject(geth_poa_middleware, layer=0) -abi = '[ { "anonymous": false, "inputs": [ { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "proofOfControlWeiAmountChanged", "type": "event" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "addBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "add", "type": "address" }, { "name": "password", "type": "bytes32" } ], "name": "addSuitor", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "changeLimit", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "ben", "type": "address" }, { "indexed": false, "name": "newLimit", "type": "uint256" } ], "name": "limitChanged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorNotApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" }, { "indexed": true, "name": "distr", "type": "address" } ], "name": "suitorAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "limit", "type": "uint256" } ], "name": "addedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "top", "type": "uint256" } ], "name": "addedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "replenished", "type": "event" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "top", "type": "uint256" } ], "name": "addDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "key", "type": "string" } ], "name": "proveControl", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "amount", "type": "uint256" } ], "name": "replenish", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [], "name": "replenishAll", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "accs", "type": "address[]" }, { "name": "amounts", "type": "uint256[]" } ], "name": "replenishList", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "amount", "type": "uint256" } ], "name": "setProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "payable": true, "stateMutability": "payable", "type": "constructor" }, { "constant": true, "inputs": [], "name": "getBeneficiariesCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getBeneficiaryLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getDistributorLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "key", "type": "string" } ], "name": "hash", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "pure", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ]' -contract_address = "0xBCE634B5cd8ba22A66A5CDedFb1bC56EFFb8a525" +abi = settings.DISTILLERY_ABI +contract_address = settings.DISTILLERY_ADDRESS + +distributor_address = settings.DISTRIBUTOR_ACCOUNT contract = w3.eth.contract(abi=abi, address=contract_address) -w3.eth.defaultAccount = w3.eth.accounts[0] +w3.eth.defaultAccount = w3.eth.accounts[3] + +gasPrice = w3.eth.gasPrice clave = str(uuid1()) -estimate = contract.functions.proveControl(clave).estimateGas() +estimate = (contract.functions.proveControl(clave).estimateGas() + 10000) * gasPrice print("Gas estimado para probar control: {}".format(estimate)) tx_hash = contract.functions.setProofOfControlWeiAmount(estimate).transact() -tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash) - -print("\n") -print("Block {0}".format(w3.eth.blockNumber)) -print("Data {0}".format(str(w3.eth.getBlock(w3.eth.blockNumber)))) -print("Funciono: {0}".format(str(contract.functions.getProofOfControlWeiAmount().call()))) \ No newline at end of file +tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash) \ No newline at end of file diff --git a/scripts_utiles/cargarDistribuidor.py b/scripts_utiles/cargarDistribuidor.py index 7ff1477bb6e2b910e71631e3d9ea611be56cc1c5..ac20533c428509c7a9f2afba8c5d46020f4dcbe9 100644 --- a/scripts_utiles/cargarDistribuidor.py +++ b/scripts_utiles/cargarDistribuidor.py @@ -9,20 +9,23 @@ You should have received a copy of the GNU General Public License along with thi """ from web3 import Web3 from web3.middleware import geth_poa_middleware +from django.conf import settings -w3 = Web3(Web3.HTTPProvider('http://10.23.10.71:8501')) +w3 = Web3(Web3.HTTPProvider(settings.NODE_URL)) w3.middleware_stack.inject(geth_poa_middleware, layer=0) -abi = '[ { "anonymous": false, "inputs": [ { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "proofOfControlWeiAmountChanged", "type": "event" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "addBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "add", "type": "address" }, { "name": "password", "type": "bytes32" } ], "name": "addSuitor", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "changeLimit", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "ben", "type": "address" }, { "indexed": false, "name": "newLimit", "type": "uint256" } ], "name": "limitChanged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorNotApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" }, { "indexed": true, "name": "distr", "type": "address" } ], "name": "suitorAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "limit", "type": "uint256" } ], "name": "addedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "top", "type": "uint256" } ], "name": "addedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "replenished", "type": "event" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "top", "type": "uint256" } ], "name": "addDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "key", "type": "string" } ], "name": "proveControl", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "amount", "type": "uint256" } ], "name": "replenish", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [], "name": "replenishAll", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "accs", "type": "address[]" }, { "name": "amounts", "type": "uint256[]" } ], "name": "replenishList", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "amount", "type": "uint256" } ], "name": "setProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "payable": true, "stateMutability": "payable", "type": "constructor" }, { "constant": true, "inputs": [], "name": "getBeneficiariesCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getBeneficiaryLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getDistributorLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "key", "type": "string" } ], "name": "hash", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "pure", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ]' -contract_address = "0xBCE634B5cd8ba22A66A5CDedFb1bC56EFFb8a525" +abi = settings.DISTILLERY_ABI +contract_address = settings.DISTILLERY_ADDRESS -distributor_address = "0x25c185DcaeD065BAC30a0a1cd0688A7aA02896d7" # salberchain distributor +distributor_address = settings.DISTRIBUTOR_ACCOUNT contract = w3.eth.contract(abi=abi, address=contract_address) -w3.eth.defaultAccount = w3.eth.accounts[0] +w3.eth.defaultAccount = "PepitaLaPistolera" # TODO Pedir por prompt (es el dueño del contrato -tx_hash = contract.functions.addDistributor(distributor_address, 100000000).transact() +w3.personal.unlockAccount(w3.eth.defaultAccount,"") # TODO Pedir por prompt + +tx_hash = contract.functions.addDistributor(distributor_address, 60000).transact({"gas":900000}) tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)