def test_set_methods(): c = Contract(str(accounts[1]), build.get('Token'), None) for item in build.get('Token')['abi']: if item['type'] != "function": if 'name' not in item: continue assert not hasattr(c, item['name']) elif item['stateMutability'] in ('view', 'pure'): assert type(getattr(c, item['name'])) == ContractCall else: assert type(getattr(c, item['name'])) == ContractTx
def test_namespace_collision(): b = deepcopy(build.get('Token')) b['abi'].append({ 'constant': False, 'inputs': [{ 'name': '_to', 'type': 'address' }, { 'name': '_value', 'type': 'uint256' }, { 'name': '_test', 'type': 'uint256' }], 'name': 'bytecode', 'outputs': [{ 'name': '', 'type': 'bool' }], 'payable': False, 'stateMutability': 'nonpayable', 'type': 'function' }) with pytest.raises(AttributeError): Contract(str(accounts[1]), b, None)
def _reverted_trace(self, trace): self.modified_state = False # get events from trace self.events = decode_trace(trace) if self.revert_msg is not None: return # get revert message step = next(i for i in trace if i['op'] in ("REVERT", "INVALID")) if step['op'] == "REVERT" and int(step['stack'][-2], 16): # get returned error string from stack data = _get_memory(step, -1)[4:] self.revert_msg = decode_abi(['string'], data)[0].decode() return # check for dev revert string using program counter self.revert_msg = build.get_dev_revert(step['pc']) if self.revert_msg is not None: return # if none is found, expand the trace and get it from the pcMap self._expand_trace() try: pc_map = build.get(step['contractName'])['pcMap'] # if this is the function selector revert, check for a jump if 'first_revert' in pc_map[step['pc']]: i = trace.index(step) - 4 if trace[i]['pc'] != step['pc'] - 4: step = trace[i] self.revert_msg = pc_map[step['pc']]['dev'] except KeyError: self.revert_msg = ""
def set_active(self, contract_name): build_json = build.get(contract_name) self.main.note.set_visible(build_json['allSourcePaths']) self.main.note.set_active(build_json['sourcePath']) self.main.oplist.set_opcodes(build_json['pcMap']) self.pcMap = dict((str(k), v) for k, v in build_json['pcMap'].items()) if self.toolbar.highlight.active: self.toolbar.highlight.reset()
def _compare_build_json(contract_name): try: build_json = build.get(contract_name) except KeyError: return True return (build_json['compiler'] != CONFIG['solc'] or build_json['sha1'] != sources.get_hash( contract_name, CONFIG['solc']['minify_source']))
def _get_totals(coverage_eval): '''Returns a modified coverage eval dict showing counts and totals for each contract function. Arguments: coverage_eval: Standard coverage evaluation dict Returns: { "ContractName": { "statements": { "path/to/file": { "ContractName.functionName": (count, total), .. }, .. }, "branches" { "path/to/file": { "ContractName.functionName": (true count, false count, total), .. }, .. } }''' coverage_eval = _split_by_fn(coverage_eval) results = dict((i, { 'statements': {}, 'totals': { 'statements': 0, 'branches': [0, 0] }, 'branches': { 'true': {}, 'false': {} } }) for i in coverage_eval) for name in coverage_eval: coverage_map = build.get(name)['coverageMap'] r = results[name] r['statements'], r['totals']['statements'] = _statement_totals( coverage_eval[name], coverage_map['statements']) r['branches'], r['totals']['branches'] = _branch_totals( coverage_eval[name], coverage_map['branches']) return results
def _split_by_fn(coverage_eval): '''Splits a coverage eval dict so that coverage indexes are stored by contract function. Once done, the dict is no longer compatible with other methods in this module. Original format: {"path/to/file": [index, ..], .. } New format: {"path/to/file": { "ContractName.functionName": [index, .. ], .. } ''' results = dict((i, { 'statements': {}, 'branches': { 'true': {}, 'false': {} } }) for i in coverage_eval) for name in coverage_eval: map_ = build.get(name)['coverageMap'] results[name] = dict( (k, _split(v, map_, k)) for k, v in coverage_eval[name].items()) return results
def _get_highlights(coverage_eval): '''Returns a highlight map formatted for display in the GUI. Arguments: coverage_eval: coverage evaluation dict Returns: { "statements": { "ContractName": {"path/to/file": [start, stop, color, msg .. ], .. }, }, "branches": { "ContractName": {"path/to/file": [start, stop, color, msg .. ], .. }, } }''' results = {'statements': {}, 'branches': {}} for name, eval_ in coverage_eval.items(): coverage_map = build.get(name)['coverageMap'] results['statements'][name] = _statement_highlights( eval_, coverage_map['statements']) results['branches'][name] = _branch_highlights( eval_, coverage_map['branches']) return results
def test_overloaded(): b = deepcopy(build.get('Token')) b['abi'].append({ 'constant': False, 'inputs': [{ 'name': '_to', 'type': 'address' }, { 'name': '_value', 'type': 'uint256' }, { 'name': '_test', 'type': 'uint256' }], 'name': 'transfer', 'outputs': [{ 'name': '', 'type': 'bool' }], 'payable': False, 'stateMutability': 'nonpayable', 'type': 'function' }) c = Contract(str(accounts[1]), b, None) fn = c.transfer assert type(fn) == OverloadedMethod assert len(fn) == 2 assert type(fn['address', 'uint']) == ContractTx assert fn['address, uint256'] != fn['address, uint256, uint256'] assert fn['address', 'uint'] == fn['address,uint256'] repr(fn)
def test_comparison(): c = Contract(str(accounts[1]), build.get('Token'), None) assert c != 123 assert c == str(accounts[1]) assert c != Contract(str(accounts[2]), build.get('Token'), None)
def test_balance(): balance = Contract(str(accounts[1]), build.get('Token'), None).balance() assert type(balance) is Wei assert balance == "100 ether"
def test_repr(): c = Contract(str(accounts[1]), build.get('Token'), None) repr(c)