예제 #1
0
    def create(name, address, abi):
        contract = ContractService.find(name)
        if not contract:
            contract = Contract(name=name, address=address, abi=abi)
            session.add(contract)
            session.commit()

        return contract
예제 #2
0
    def sync(self):
        """Synchronize ORV address(wallet) on bitcoin blockchain with local database.
            Normally runs be scheduler.
            Step 1: Get wallet by address from database
            Step 2: Check wallet balance via bitcoin client
            Step 3: if balance changed - update it locally (otherwise just update updated_at field)
            Step 4: if balance changed - trigger appropriate smart contract via ETH client

        """
        addr = session.query(Address).filter_by(address=self.address).first()
        if addr:
            bclient = BitcoinClient()
            blockchain_address = BTCAddress(bclient, self.address)
            # TODO: Uncomment once on mainnet, checking mainnet address on dev-btc-node fails
            # if not blockchain_address.is_valid():
            #     raise ValueError("bitcoin address %s is not valid in the blockchain" % self.address)

            if int(os.environ['ETHEREUM_TESTRPC_ENABLED']) == 1:
                balance = blockchain_address.balance('test')
                # balance = blockchain_address.balance()
            else:
                balance = blockchain_address.balance()

            transaction = None
            if balance != addr.balance:
                persisted_contract = ContractService.find('PricingStrategy')
                if persisted_contract is None:
                    raise RuntimeError(
                        'PricingStrategy contract is not available in the database'
                    )

                contract_address = persisted_contract.address
                contract_abi = json.loads(persisted_contract.abi)

                # TODO: Remove this hack once we get rid of testrpc
                if int(os.environ['ETHEREUM_TESTRPC_ENABLED']) == 1:
                    executor_address = os.environ[
                        'ETHEREUM_TESTRPC_MASTER_ADDRESS']
                    eclient = EthereumClient('testrpc')
                else:
                    executor_address = os.environ['ETHEREUM_CONTRACT_EXECUTOR']
                    eclient = EthereumClient()

                contract = PricingStrategyContract(eclient, contract_abi,
                                                   contract_address)
                transaction = contract.set_available_satoshi(
                    balance, executor_address)

            addr.balance = balance
            session.commit()
            return transaction
        else:
            raise ValueError("bitcoin address %s not found in the database" %
                             self.address)
예제 #3
0
 def update_password(self, password):
     user = session.query(User).get(self.id)
     user.password_hash = User.encode_password(password)
     session.commit()
     return user
예제 #4
0
 def delete(self):
     user = session.query(User).get(self.id)
     session.delete(user)
     session.commit()
예제 #5
0
    def create(cls, email, password, secret_key=None):
        """Register user

        Args
            email (str): user email
            password (str): user password
            secret_key (str): secret key for ciphering/deciphering wallet passwords and private keys
        Returns
            User: created user model object
        Raises
            ValueError: if was not able to register bitcoin wallet for new user
        """
        if not secret_key:
            secret_key = os.environ['SECRET_KEY']

        user = User(
            email=email,
            password_hash=User.encode_password(password),
            # created_at=datetime.datetime.utcnow(),
            # updated_at=datetime.datetime.utcnow(),
        )
        session.add(user)

        # Create wallets for user

        # Create bitcoin wallet
        btc_client = BitcoinClient()
        btc_addr = BTCAddress(btc_client)
        if btc_addr.register():
            private_key_hash = Address.cipher_string(btc_addr.private_key,
                                                     secret_key)

            address = Address(address=btc_addr.public_key,
                              currency='bitcoin',
                              wallet_type='user',
                              password=private_key_hash,
                              user=user)
            session.add(address)
        else:
            raise ValueError("cannot register bitcoin wallet for user %s" %
                             email)

        # Create Ethereum Wallet
        eclient = EthereumClient()
        num_chars = 8
        random_passphrase = ''.join(
            random.choices(string.ascii_uppercase + string.digits,
                           k=num_chars))
        eth_addr = ETHAdress(eclient, passphrase=random_passphrase)
        if eth_addr.register():
            passphrase_hash = Address.cipher_string(eth_addr.passphrase,
                                                    secret_key)
            address = Address(address=eth_addr.address,
                              currency='ethereum',
                              wallet_type='user',
                              password=passphrase_hash,
                              user=user)
            session.add(address)
        else:
            raise ValueError("cannot register ethereum wallet for user %s" %
                             email)

        session.commit()
        return user
예제 #6
0
    def sync(self):
        """Synchronize user address(wallet) on bitcoin blockchain with local database.
            Normally runs by scheduler.
            Step 1: Step 1: get wallet by address from database
            Step 2: Check wallet balance via bitcoin client
            Step 3: if balance > 0 - transfer all funds to ORV wallet
            Step 4: if balance > 0 - trigger appropriate smart contract via ETH client

        """
        addr = session.query(Address).filter_by(address=self.address).first()
        if addr:
            bclient = BitcoinClient()
            blockchain_address = BTCAddress(bclient, self.address)
            if not blockchain_address.is_valid():
                raise ValueError(
                    "bitcoin address %s is not valid in the blockchain" %
                    self.address)

            try:
                balance = blockchain_address.balance()
                if balance > 0:
                    to_address = os.environ['BITCOIN_ORV_WALLET']
                    # Send all money to ORV wallet
                    blockchain_address.send(to_address, balance)

                    # Step 1: get user of the address
                    # Step 2: get ethereum wallet of the user
                    # Step 3: Run contract transfer_to
                    user = addr.user
                    for user_address in user.addresses:
                        # Assuming user could have just one ethereum wallet
                        if user_address.currency == 'ethereum':
                            persisted_contract = ContractService.find(
                                'PricingStrategy')
                            if persisted_contract is None:
                                raise RuntimeError(
                                    'PricingStrategy contract is not available in the database'
                                )

                            contract_address = persisted_contract.address
                            contract_abi = json.loads(persisted_contract.abi)

                            # TODO: Remove this hack once we get rid of testrpc
                            if int(os.environ['ETHEREUM_TESTRPC_ENABLED']
                                   ) == 1:
                                executor_address = os.environ[
                                    'ETHEREUM_TESTRPC_MASTER_ADDRESS']
                                eclient = EthereumClient('testrpc')
                            else:
                                executor_address = os.environ[
                                    'ETHEREUM_CONTRACT_EXECUTOR']
                                eclient = EthereumClient()

                            contract = PricingStrategyContract(
                                eclient, contract_abi, contract_address)
                            user_address = user_address.address
                            transaction = contract.transfer_to(
                                user_address, balance, executor_address)

                    # Update wallet status
                    addr.balance = 0
                    session.commit()
                    return transaction
            except RuntimeError:
                # This issue should not happen in production,
                # just in dev/test where we create local accounts, but verify them on mainnet using blockexporer
                print("bitcoin address %s does not exist, doing nothing" %
                      blockchain_address.public_key)
        else:
            raise ValueError("bitcoin address %s not found in the database" %
                             self.address)