def try_pack(val_node, type_node): type_prim, type_args = parse_prim_expr(type_node) is_string = isinstance(val_node, dict) and val_node.get('string') if type_prim in ['set', 'list']: val_node = [try_pack(i, type_args[0]) for i in val_node] elif type_prim in ['map', 'big_map']: val_node = [{'prim': 'Elt', 'args': [try_pack(elt['args'][i], type_args[i]) for i in [0, 1]]} for elt in val_node] elif type_prim == 'pair': val_node['args'] = [try_pack(val_node['args'][i], type_args[i]) for i in [0, 1]] elif type_prim == 'option': if val_node['prim'] == 'Some': val_node['args'] = [try_pack(val_node['args'][0], type_args[0])] elif type_prim == 'or': type_idx = 0 if val_node['prim'] == 'Left' else 1 val_node['args'] = [try_pack(val_node['args'][0], type_args[type_idx])] elif type_prim == 'lambda': pass # TODO: PUSH, SELF, CONTRACT elif type_prim == 'chain_id' and is_string: return {'bytes': forge_base58(val_node['string']).hex()} elif type_prim == 'signature' and is_string: return {'bytes': forge_base58(val_node['string']).hex()} elif type_prim == 'key_hash' and is_string: return {'bytes': forge_address(val_node['string'], tz_only=True).hex()} elif type_prim == 'key' and is_string: return {'bytes': forge_public_key(val_node['string']).hex()} elif type_prim == 'address' and is_string: return {'bytes': forge_address(val_node['string']).hex()} elif type_prim == 'contract' and is_string: return {'bytes': forge_contract(val_node['string']).hex()} elif type_prim == 'timestamp' and is_string: return {'int': forge_timestamp(val_node['string'])} return val_node
def parse_instruction(code_expr): prim, args = parse_prim_expr(code_expr) key = (prim, len(args)) if key not in instructions: raise MichelsonRuntimeError.init(f'unknown instruction or wrong args len: {key}', prim) handler = instructions[key] annots = code_expr.get('annots', []) return prim, args, annots, handler
def _get_type(type_expr): prim, args = parse_prim_expr(type_expr) assert prim in StackItem.__cls__, f'{prim}: unknown type primitive' item_cls, args_len = StackItem.__cls__[type_expr['prim']] assert len( args ) == args_len, f'{prim}: expected {args_len} arg(s), got {len(args)}' return item_cls
def do_patch(ctx: Context, prim, args, annots): key, _ = parse_prim_expr(args[0]) assert key in patch_prim, f'expected one of {", ".join(patch_prim)}, got {args[0]}' if key in ['AMOUNT', 'BALANCE']: res = Mutez(get_int(args[1])) elif key == 'NOW': res = Timestamp(get_int(args[1])) elif key in ['SOURCE', 'SENDER']: res = Address.new(get_string(args[1])) elif key == 'CHAIN_ID': res = ChainID(get_string(args[1])) else: assert False ctx.set(key, res)
def do_unset(ctx: Context, prim, args, annots): key, _ = parse_prim_expr(args[0]) assert key in patch_prim, f'expected one of {", ".join(patch_prim)}, got {args[0]}' ctx.unset(key)
def is_left(self): prim, _ = parse_prim_expr(self.val_expr) return prim == 'Left'