def initialize_datatrust(self): """ Confirm or create role as datatrust backend in protocol """ log.info('Getting current datatrust address from network') self.datatrust = Datatrust(self.datatrust_wallet) self.datatrust.at(self.w3, self.datatrust_contract) self.voting = Voting(self.datatrust_wallet) self.voting.at(self.w3, self.voting_contract) backend = call(self.datatrust.get_backend_address()) datatrust_hash = self.w3.sha3(text=self.datatrust_host) if backend == self.datatrust_wallet: log.info('This server is the datatrust host. Resolving registration') resolve = send( self.w3, self.datatrust_key, self.datatrust.resolve_registration( self.w3.sha3(text=self.datatrust_host) ) ) log.info(f'Resolved, transaction id: {resolve}') else: # backend not set, or is set to a different host datatrust_url = call(self.datatrust.get_backend_url()) is_candidate = call(self.voting.is_candidate(datatrust_hash)) candidate_is = call(self.voting.candidate_is(datatrust_hash, constants.PROTOCOL_REGISTRATION)) if datatrust_url == self.datatrust_host: log.info('Server has been registered as datatrust, but not voted in') elif is_candidate and candidate_is: log.info('This datatrust is a candidate but has not been voted in') poll_status = call(self.voting.poll_closed(datatrust_hash)) if poll_status: log.info('This datatrust was a candidate, but was not voted in before the poll closed') resolve = send( self.w3, self.datatrust_key, self.datatrust.resolve_registration(datatrust_hash) ) log.info(f'Resolved any prior registration, transaction id: {resolve.hex()}') self.wait_for_mining(resolve) register = self.register_host() log.info(f'Datatrust has been registered.') else: log.info('This datatrust is a candidate. Voting polls are still open.') else: log.info('No backend or different host set. Resolving prior registrations and Submitting this one for voting') resolve = send( self.w3, self.datatrust_key, self.datatrust.resolve_registration(datatrust_hash) ) log.info(f'Resolved any prior registration, transaction id: {resolve.hex()}') self.wait_for_mining(resolve) register = self.register_host()
def datatrust_pre(w3, ether_token, voting_pre, parameterizer, reserve): contract_path = os.path.join(os.path.dirname(__file__), os.pardir, 'contracts') with open(os.path.join(contract_path, 'datatrust', 'datatrust.abi')) as f: abi = json.loads(f.read()) with open(os.path.join(contract_path, 'datatrust', 'datatrust.bin')) as f: bc = f.read() deployed = w3.eth.contract(abi=abi, bytecode=bc.rstrip('\n')) tx_hash = deployed.constructor(ether_token.address, voting_pre.address, parameterizer.address, reserve.address).transact() tx_rcpt = w3.eth.waitForTransactionReceipt(tx_hash) instance = Datatrust(w3.eth.defaultAccount) instance.at(w3, tx_rcpt['contractAddress']) return instance
print(colored(heading('Private key check'), 'yellow')) if not PRIVATE_KEY: sys.exit(1) print('Private key available. Continuing...') print(colored(heading('Datatrust Address check'), 'yellow')) if not DATATRUST_ADDRESS: sys.exit(1) print('Datatrust Address available. Continuing...') print(colored(heading('Listing Address check'), 'yellow')) if not LISTING_ADDRESS: sys.exit(1) print('Listing Address available. Continuing...') print(colored(heading('Set Datatrust privileged'), 'yellow')) print(colored('instantiating Datatrust', 'blue')) datatrust = Datatrust(PUBLIC_KEY) datatrust.at(w3, DATATRUST_ADDRESS) print(colored('Setting addresses...', 'blue')) d_gas = datatrust.deployed.functions.setPrivileged( LISTING_ADDRESS).estimateGas() d_args = datatrust.set_privileged(LISTING_ADDRESS, { 'gas': d_gas, 'gas_price': w3.toWei(GAS_PRICE, 'gwei') }) d_tx_hash = send(w3, PRIVATE_KEY, d_args) d_tx_rct = w3.eth.waitForTransactionReceipt(d_tx_hash) print(colored(d_tx_rct, 'green'))
def __init__(self): self.w3 = get_w3() account = self.w3.toChecksumAddress(os.environ.get('public_key')) self.contract = DT(account) self.contract.at(self.w3, DATATRUST_CONTRACT_ADDRESS)
class Datatrust(Model): def __init__(self): self.w3 = get_w3() account = self.w3.toChecksumAddress(os.environ.get('public_key')) self.contract = DT(account) self.contract.at(self.w3, DATATRUST_CONTRACT_ADDRESS) def get_reserve(self): return call(self.contract.get_reserve()) def get_hash(self, url): # use web3 to send back hex string hashed = call(self.contract.get_hash(url)) return self.w3.toHex(hashed) def get_backend_address(self): return call(self.contract.get_backend_address()) def set_backend_url(self, url, gas_price): args = self.contract.set_backend_url( url, {'gas_price': self.gwei_to_wei(int(gas_price))}) return self.transact(args) def get_backend_url(self): return call(self.contract.get_backend_url()) # NOTE that the msg.sender can only be the the registered datatrust address def set_data_hash(self, listing, data, gas_price): args = self.contract.set_data_hash( listing, data, {'gas_price': self.gwei_to_wei(int(gas_price))}) return self.transact(args) def get_data_hash(self, listing): return call(self.contract.get_data_hash(listing)) def register(self, url, gas_price): args = self.contract.register( url, {'gas_price': self.gwei_to_wei(int(gas_price))}) return self.transact(args) def resolve_registration(self, hash, gas_price): args = self.contract.resolve_registration( hash, {'gas_price': self.gwei_to_wei(int(gas_price))}) return self.transact(args) def request_delivery(self, hash, amount, gas_price): args = self.contract.request_delivery( hash, int(amount), {'gas_price': self.gwei_to_wei(int(gas_price))}) return self.transact(args) def get_bytes_purchased(self, addr): return call(self.contract.get_bytes_purchased(addr)) def get_delivery(self, hash): """ returns (owner, bytes_requested, bytes_delivered) """ return call(self.contract.get_delivery(hash)) # NOTE that the msg.sender can only be the the registered datatrust address def listing_accessed(self, listing, delivery, amount, gas_price): args = self.contract.listing_accessed( listing, delivery, int(amount), {'gas_price': self.gwei_to_wei(int(gas_price))}) return self.transact(args) def get_access_reward_earned(self, hash): return call(self.contract.get_access_reward_earned(hash)) # NOTE that the msg.sender can only be the the registered datatrust address def delivered(self, delivery, url, gas_price): args = self.contract.delivered( delivery, url, {'gas_price': self.gwei_to_wei(int(gas_price))}) return self.transact(args) def set_privileged(self, listing, gas_price): args = self.contract.set_privileged( listing, {'gas_price': self.gwei_to_wei(int(gas_price))}) return self.transact(args) def get_privileged(self): return call(self.contract.get_privileged())
class Protocol(): """ Class to manage all interactions with the deployed contracts """ def __init__(self): self.datatrust = None self.voting = None def init_protocol(self, rpc_path, datatrust_contract, datatrust_host, voting_contract, datatrust_key, datatrust_wallet): """ :param rpc_path: URL to the RPC provider for the network :param datatrust_contract: Deployed address of the datatrust contract :param datatrust_host: URL of this application. Used to submit self as datatrust :param voting_contract: Deployed address of voting contract :param datatrust_key: Private key for wallet :param datatrust_wallet: Wallet address """ self.w3 = self.initialize_web3(rpc_path) self.datatrust_contract = datatrust_contract self.datatrust_host = datatrust_host self.voting_contract = voting_contract self.datatrust_key = datatrust_key self.datatrust_wallet = datatrust_wallet def initialize_web3(self, rpc_path): """ Setup the web3 provider """ w3 = Web3(Web3.HTTPProvider(rpc_path)) log.info('w3 provider set') return w3 def initialize_datatrust(self): """ Confirm or create role as datatrust backend in protocol """ log.info('Getting current datatrust address from network') self.datatrust = Datatrust(self.datatrust_wallet) self.datatrust.at(self.w3, self.datatrust_contract) self.voting = Voting(self.datatrust_wallet) self.voting.at(self.w3, self.voting_contract) backend = call(self.datatrust.get_backend_address()) datatrust_hash = self.w3.sha3(text=self.datatrust_host) if backend == self.datatrust_wallet: log.info('This server is the datatrust host. Resolving registration') resolve = send( self.w3, self.datatrust_key, self.datatrust.resolve_registration( self.w3.sha3(text=self.datatrust_host) ) ) log.info(f'Resolved, transaction id: {resolve}') else: # backend not set, or is set to a different host datatrust_url = call(self.datatrust.get_backend_url()) is_candidate = call(self.voting.is_candidate(datatrust_hash)) candidate_is = call(self.voting.candidate_is(datatrust_hash, constants.PROTOCOL_REGISTRATION)) if datatrust_url == self.datatrust_host: log.info('Server has been registered as datatrust, but not voted in') elif is_candidate and candidate_is: log.info('This datatrust is a candidate but has not been voted in') poll_status = call(self.voting.poll_closed(datatrust_hash)) if poll_status: log.info('This datatrust was a candidate, but was not voted in before the poll closed') resolve = send( self.w3, self.datatrust_key, self.datatrust.resolve_registration(datatrust_hash) ) log.info(f'Resolved any prior registration, transaction id: {resolve.hex()}') self.wait_for_mining(resolve) register = self.register_host() log.info(f'Datatrust has been registered.') else: log.info('This datatrust is a candidate. Voting polls are still open.') else: log.info('No backend or different host set. Resolving prior registrations and Submitting this one for voting') resolve = send( self.w3, self.datatrust_key, self.datatrust.resolve_registration(datatrust_hash) ) log.info(f'Resolved any prior registration, transaction id: {resolve.hex()}') self.wait_for_mining(resolve) register = self.register_host() def wait_for_vote(self): """ Check if this backend is registered as the datatrust """ is_host = False while is_host == False: backend = call(self.datatrust.get_backend_url()) if backend != self.datatrust_host: print('backend not voted in yet, waiting for votes...') sleep(30) else: is_host = True return True def register_host(self): """ Register a host as the datatrust in protocol """ log.info('****Registering host****') register = send(self.w3, self.datatrust_key, self.datatrust.register(self.datatrust_host)) self.wait_for_mining(register) voting = Voting(self.datatrust_wallet) voting.at(self.w3, self.voting_contract) datatrust_hash = self.w3.sha3(text=self.datatrust_host) is_registered = call(voting.is_candidate(datatrust_hash)) if is_registered: log.info(f'Backend registered. Voting is now open.') else: log.error('Host attempted to register but did not succeed') def send_data_hash(self, listing, data_hash): """ On a successful post to the API db, send the data hash to protocol """ datatrust_hash = self.w3.sha3(text=self.datatrust_host) is_candidate = call(self.voting.is_candidate(datatrust_hash)) candidate_is = call(self.voting.candidate_is(datatrust_hash, constants.PROTOCOL_APPLICATION)) if is_candidate and candidate_is: receipt = send(self.w3, self.datatrust_key, self.datatrust.set_data_hash(listing, data_hash)) return receipt else: log.critical('This server is not the datatrust, unable to send data hash') raise ValueError('Server is not the datatrust, unable to send data hash') def wait_for_mining(self, tx): """ Wait for a transaction to be mined before proceeding :param tx: Transaction receipt """ is_mined = self.w3.eth.getTransactionReceipt(tx.hex()) while is_mined is None: log.info('Transaction has not been mined, going to sleep') sleep(15) is_mined = self.w3.eth.getTransactionReceipt(tx.hex()) def create_file_hash(self, data): """ Return a sha3 hash for the file provided :param data: The file object to hash :return: sha3 hash of file contents :return type: string """ sha3_hash = None with open(data, 'rb') as file_contents: file_contents.read() sha3_hash = self.w3.sha3(file_contents) return sha3_hash
print(colored('instantiating Voting', 'blue')) voting = Voting(PUBLIC_KEY) voting.at(w3, voting_address) print(colored('Setting addresses...', 'blue')) v_gas = voting.deployed.functions.setPrivileged( parameterizer_address, datatrust_address, listing_address).estimateGas() v_args = voting.set_privileged( parameterizer_address, datatrust_address, listing_address, { 'gas': v_gas, 'gas_price': w3.toWei(GAS_PRICE, 'gwei') }) v_tx_hash = send(w3, PRIVATE_KEY, v_args) v_tx_rct = w3.eth.waitForTransactionReceipt(v_tx_hash) print(colored(v_tx_rct, 'green')) print(colored(heading('Set Datatrust privileged'), 'yellow')) print(colored('instantiating Datatrust', 'blue')) datatrust = Datatrust(PUBLIC_KEY) datatrust.at(w3, datatrust_address) print(colored('Setting addresses...', 'blue')) d_gas = datatrust.deployed.functions.setPrivileged( listing_address).estimateGas() d_args = datatrust.set_privileged(listing_address, { 'gas': d_gas, 'gas_price': w3.toWei(GAS_PRICE, 'gwei') }) d_tx_hash = send(w3, PRIVATE_KEY, d_args) d_tx_rct = w3.eth.waitForTransactionReceipt(d_tx_hash) print(colored(d_tx_rct, 'green'))