Example #1
0
    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()
Example #2
0
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
Example #3
0
    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'))
Example #4
0
 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)
Example #5
0
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())
Example #6
0
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'))