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
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)
def update_password(self, password): user = session.query(User).get(self.id) user.password_hash = User.encode_password(password) session.commit() return user
def delete(self): user = session.query(User).get(self.id) session.delete(user) session.commit()
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
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)