def sign_transaction(self,
                         coin_solutions: List[CoinSolution]) -> SpendBundle:
        signatures = []
        solution: Program
        puzzle: Program
        for coin_solution in coin_solutions:  # type: ignore # noqa
            secret_key = self.get_private_key_for_puzzle_hash(
                coin_solution.coin.puzzle_hash)
            synthetic_secret_key = calculate_synthetic_secret_key(
                secret_key, DEFAULT_HIDDEN_PUZZLE_HASH)
            err, con, cost = conditions_for_solution(
                coin_solution.puzzle_reveal, coin_solution.solution,
                self.constants.MAX_BLOCK_COST_CLVM)
            if not con:
                raise ValueError(err)
            conditions_dict = conditions_by_opcode(con)

            for _, msg in pkm_pairs_for_conditions_dict(
                    conditions_dict, bytes(coin_solution.coin.name()),
                    self.constants.AGG_SIG_ME_ADDITIONAL_DATA):
                signature = AugSchemeMPL.sign(synthetic_secret_key, msg)
                signatures.append(signature)
        aggsig = AugSchemeMPL.aggregate(signatures)
        spend_bundle = SpendBundle(coin_solutions, aggsig)
        return spend_bundle
示例#2
0
    def sign_transaction(self, coin_spends: List[CoinSpend]) -> SpendBundle:
        signatures = []
        solution: Program
        puzzle: Program
        for coin_spend in coin_spends:  # noqa
            secret_key = self.get_private_key_for_puzzle_hash(coin_spend.coin.puzzle_hash)
            synthetic_secret_key = calculate_synthetic_secret_key(secret_key, DEFAULT_HIDDEN_PUZZLE_HASH)
            err, con, cost = conditions_for_solution(
                coin_spend.puzzle_reveal, coin_spend.solution, self.constants.MAX_BLOCK_COST_CLVM
            )
            if not con:
                raise ValueError(err)
            conditions_dict = conditions_by_opcode(con)

            for cwa in conditions_dict.get(ConditionOpcode.AGG_SIG_UNSAFE, []):
                msg = cwa.vars[1]
                signature = AugSchemeMPL.sign(synthetic_secret_key, msg)
                signatures.append(signature)

            for cwa in conditions_dict.get(ConditionOpcode.AGG_SIG_ME, []):
                msg = cwa.vars[1] + bytes(coin_spend.coin.name()) + self.constants.AGG_SIG_ME_ADDITIONAL_DATA
                signature = AugSchemeMPL.sign(synthetic_secret_key, msg)
                signatures.append(signature)

        aggsig = AugSchemeMPL.aggregate(signatures)
        spend_bundle = SpendBundle(coin_spends, aggsig)
        return spend_bundle
示例#3
0
 def signature_for_solution(self, coin_solution: CoinSolution, additional_data: bytes) -> AugSchemeMPL:
     signatures = []
     err, conditions, cost = conditions_for_solution(coin_solution.puzzle_reveal, coin_solution.solution)
     assert conditions is not None
     conditions_dict = conditions_by_opcode(conditions)
     for public_key, message_hash in pkm_pairs_for_conditions_dict(
         conditions_dict, coin_solution.coin.name(), additional_data
     ):
         signature = self.sign(bytes(public_key), message_hash)
         signatures.append(signature)
     return AugSchemeMPL.aggregate(signatures)
示例#4
0
def get_name_puzzle_conditions(
    block_program: SerializedProgram, safe_mode: bool
) -> Tuple[Optional[str], Optional[List[NPC]], Optional[uint64]]:
    # TODO: allow generator mod to take something (future)
    # TODO: write more tests
    block_program_args = SerializedProgram.from_bytes(b"\x80")

    try:
        if safe_mode:
            cost, result = GENERATOR_MOD.run_safe_with_cost(
                block_program, block_program_args)
        else:
            cost, result = GENERATOR_MOD.run_with_cost(block_program,
                                                       block_program_args)
        npc_list: List[NPC] = []
        opcodes: Set[bytes] = set(item.value for item in ConditionOpcode)

        for res in result.as_iter():
            conditions_list: List[ConditionWithArgs] = []

            spent_coin_parent_id: bytes32 = res.first().first().as_atom()
            spent_coin_puzzle_hash: bytes32 = res.first().rest().first(
            ).as_atom()
            spent_coin_amount: uint64 = uint64(
                res.first().rest().rest().first().as_int())
            spent_coin: Coin = Coin(spent_coin_parent_id,
                                    spent_coin_puzzle_hash, spent_coin_amount)

            for cond in res.rest().first().as_iter():
                if cond.first().as_atom() in opcodes:
                    opcode: ConditionOpcode = ConditionOpcode(
                        cond.first().as_atom())
                elif not safe_mode:
                    opcode = ConditionOpcode.UNKNOWN
                else:
                    return "Unknown operator in safe mode.", None, None
                conditions_list.append(
                    ConditionWithArgs(opcode,
                                      cond.rest().as_atom_list()))
            conditions_dict = conditions_by_opcode(conditions_list)
            if conditions_dict is None:
                conditions_dict = {}
            npc_list.append(
                NPC(spent_coin.name(), spent_coin.puzzle_hash,
                    [(a, b) for a, b in conditions_dict.items()]))
        return None, npc_list, uint64(cost)
    except Exception:
        tb = traceback.format_exc()
        return tb, None, None
def get_name_puzzle_conditions(block_program: SerializedProgram,
                               safe_mode: bool):
    # TODO: allow generator mod to take something (future)
    # TODO: write more tests
    block_program_args = SerializedProgram.from_bytes(b"\x80")

    try:
        if safe_mode:
            cost, result = GENERATOR_MOD.run_safe_with_cost(
                block_program, block_program_args)
        else:
            cost, result = GENERATOR_MOD.run_with_cost(block_program,
                                                       block_program_args)
        npc_list = []
        opcodes = set(item.value for item in ConditionOpcode)
        for res in result.as_iter():
            conditions_list = []
            name = std_hash(
                bytes(res.first().first().as_atom() +
                      res.first().rest().first().as_atom() +
                      res.first().rest().rest().first().as_atom()))
            puzzle_hash = bytes32(res.first().rest().first().as_atom())
            for cond in res.rest().first().as_iter():
                if cond.first().as_atom() in opcodes:
                    opcode = ConditionOpcode(cond.first().as_atom())
                elif not safe_mode:
                    opcode = ConditionOpcode.UNKNOWN
                else:
                    return "Unknown operator in safe mode.", None, None
                if len(list(cond.as_iter())) > 1:
                    cond_var_list = []
                    for cond_1 in cond.rest().as_iter():
                        cond_var_list.append(cond_1.as_atom())
                    cvl = ConditionVarPair(opcode, cond_var_list)
                else:
                    cvl = ConditionVarPair(opcode, [])
                conditions_list.append(cvl)
            conditions_dict = conditions_by_opcode(conditions_list)
            if conditions_dict is None:
                conditions_dict = {}
            npc_list.append(
                NPC(name, puzzle_hash,
                    [(a, b) for a, b in conditions_dict.items()]))
        return None, npc_list, uint64(cost)
    except Exception:
        tb = traceback.format_exc()
        return tb, None, None
示例#6
0
 def signature_for_solution(self, coin_spend: CoinSpend,
                            additional_data: bytes) -> AugSchemeMPL:
     signatures = []
     err, conditions, cost = conditions_for_solution(
         coin_spend.puzzle_reveal, coin_spend.solution,
         test_constants.MAX_BLOCK_COST_CLVM)
     assert conditions is not None
     conditions_dict = conditions_by_opcode(conditions)
     for public_key, message_hash in pkm_pairs_for_conditions_dict(
             conditions_dict, coin_spend.coin.name(), additional_data):
         # TODO: address hint error and remove ignore
         #       error: Argument 2 to "sign" of "KeyTool" has incompatible type "bytes"; expected "bytes32"
         #       [arg-type]
         signature = self.sign(public_key,
                               message_hash)  # type: ignore[arg-type]
         signatures.append(signature)
     return AugSchemeMPL.aggregate(signatures)
def get_name_puzzle_conditions(generator: BlockGenerator, max_cost: int,
                               safe_mode: bool) -> NPCResult:
    try:
        block_program, block_program_args = setup_generator_args(generator)
        if safe_mode:
            cost, result = GENERATOR_MOD.run_safe_with_cost(
                max_cost, block_program, block_program_args)
        else:
            cost, result = GENERATOR_MOD.run_with_cost(max_cost, block_program,
                                                       block_program_args)
        npc_list: List[NPC] = []
        opcodes: Set[bytes] = set(item.value for item in ConditionOpcode)

        for res in result.as_iter():
            conditions_list: List[ConditionWithArgs] = []

            spent_coin_parent_id: bytes32 = res.first().first().as_atom()
            spent_coin_puzzle_hash: bytes32 = res.first().rest().first(
            ).as_atom()
            spent_coin_amount: uint64 = uint64(
                res.first().rest().rest().first().as_int())
            spent_coin: Coin = Coin(spent_coin_parent_id,
                                    spent_coin_puzzle_hash, spent_coin_amount)

            for cond in res.rest().first().as_iter():
                if cond.first().as_atom() in opcodes:
                    opcode: ConditionOpcode = ConditionOpcode(
                        cond.first().as_atom())
                elif not safe_mode:
                    opcode = ConditionOpcode.UNKNOWN
                else:
                    return NPCResult(uint16(Err.GENERATOR_RUNTIME_ERROR.value),
                                     [], uint64(0))
                cvl = ConditionWithArgs(opcode, cond.rest().as_atom_list())
                conditions_list.append(cvl)
            conditions_dict = conditions_by_opcode(conditions_list)
            if conditions_dict is None:
                conditions_dict = {}
            npc_list.append(
                NPC(spent_coin.name(), spent_coin.puzzle_hash,
                    [(a, b) for a, b in conditions_dict.items()]))
        return NPCResult(None, npc_list, uint64(cost))
    except Exception:
        return NPCResult(uint16(Err.GENERATOR_RUNTIME_ERROR.value), [],
                         uint64(0))
def get_name_puzzle_conditions_python(generator: BlockGenerator, max_cost: int,
                                      *, cost_per_byte: int,
                                      safe_mode: bool) -> NPCResult:
    """
    This executes the generator program and returns the coins and their
    conditions. If the cost of the program (size, CLVM execution and conditions)
    exceed max_cost, the function fails. In order to accurately take the size
    of the program into account when calculating cost, cost_per_byte must be
    specified.
    safe_mode determines whether the clvm program and conditions are executed in
    strict mode or not. When in safe/strict mode, unknow operations or conditions
    are considered failures. This is the mode when accepting transactions into
    the mempool.
    """
    block_program, block_program_args = setup_generator_args(generator)
    max_cost -= len(bytes(generator.program)) * cost_per_byte
    if max_cost < 0:
        return NPCResult(uint16(Err.INVALID_BLOCK_COST.value), [], uint64(0))
    if safe_mode:
        clvm_cost, result = GENERATOR_MOD.run_safe_with_cost(
            max_cost, block_program, block_program_args)
    else:
        clvm_cost, result = GENERATOR_MOD.run_with_cost(
            max_cost, block_program, block_program_args)

    max_cost -= clvm_cost
    if max_cost < 0:
        return NPCResult(uint16(Err.INVALID_BLOCK_COST.value), [], uint64(0))
    npc_list: List[NPC] = []

    for res in result.first().as_iter():
        conditions_list: List[ConditionWithArgs] = []

        if len(res.first().atom) != 32:
            raise ValidationError(Err.INVALID_CONDITION)
        spent_coin_parent_id: bytes32 = res.first().as_atom()
        res = res.rest()
        if len(res.first().atom) != 32:
            raise ValidationError(Err.INVALID_CONDITION)
        spent_coin_puzzle_hash: bytes32 = res.first().as_atom()
        res = res.rest()
        spent_coin_amount: uint64 = uint64(sanitize_int(
            res.first(), safe_mode))
        res = res.rest()
        spent_coin: Coin = Coin(spent_coin_parent_id, spent_coin_puzzle_hash,
                                spent_coin_amount)

        for cond in res.first().as_iter():
            cost, cvl = parse_condition(cond, safe_mode)
            max_cost -= cost
            if max_cost < 0:
                return NPCResult(uint16(Err.INVALID_BLOCK_COST.value), [],
                                 uint64(0))
            if cvl is not None:
                conditions_list.append(cvl)

        conditions_dict = conditions_by_opcode(conditions_list)
        if conditions_dict is None:
            conditions_dict = {}
        npc_list.append(
            NPC(spent_coin.name(), spent_coin.puzzle_hash,
                [(a, b) for a, b in conditions_dict.items()]))
    return NPCResult(None, npc_list, uint64(clvm_cost))