Exemplo n.º 1
0
    sexp = args.rest().first()
    env = args.rest().rest().first()
    new_bindings = make_bindings(bindings)
    original_operator_lookup = run_program.operator_lookup
    run_program.operator_lookup = OperatorDict(original_operator_lookup)
    run_program.operator_lookup.update(new_bindings)
    cost, r = run_program(sexp, env)
    run_program.operator_lookup = original_operator_lookup
    return cost, r


BINDINGS = {
    "bind": do_bind,
}

brun = run = binutils.assemble("(a 2 3)")


class RunProgram:
    def __init__(self):
        operator_lookup = OperatorDict(OPERATOR_LOOKUP)
        operator_lookup.update(
            (k.encode("utf8"), v) for (k, v) in BINDINGS.items())
        self.operator_lookup = operator_lookup

    def __call__(self,
                 program,
                 args,
                 max_cost=None,
                 pre_eval_f=None,
                 strict=False):
Exemplo n.º 2
0
def rl_make_aggregation_solution(myid, wallet_coin_primary_input, wallet_coin_amount):
    opcode_myid = hexlify(myid).decode("ascii")
    primary_input = hexlify(wallet_coin_primary_input).decode("ascii")
    sol = f"(0x{opcode_myid} 0x{primary_input} {wallet_coin_amount})"
    return Program(binutils.assemble(sol))
Exemplo n.º 3
0
def puzzle_for_pk(public_key: bytes) -> Program:
    aggsig = ConditionOpcode.AGG_SIG[0]
    TEMPLATE = (
        f"(c (c (q {aggsig}) (c (q 0x%s) (c (sha256tree (f (a))) (q ())))) "
        f"((c (f (a)) (f (r (a))))))")
    return Program.to(binutils.assemble(TEMPLATE % public_key.hex()))
Exemplo n.º 4
0
    ))
    (go deserialize-mod historical-generators)
)
"""

COMPILED_GENERATOR_CODE = bytes.fromhex(
    "ff02ffff01ff04ffff02ff04ffff04ff02ffff04ff05ffff04ff0bff8080808080ffff02"
    "ff06ffff04ff02ffff04ff05ffff04ff0bff808080808080ffff04ffff01ffff02ff05ff"
    "1380ff02ff05ff2b80ff018080")

COMPILED_GENERATOR_CODE = bytes(
    Program.to(compile_clvm_text(GENERATOR_CODE, [])))

FIRST_GENERATOR = Program.to(
    binutils.assemble(
        '((parent_id (c 1 (q "puzzle blob")) 50000 "solution is here" extra data for coin))'
    )).as_bin()

SECOND_GENERATOR = Program.to(
    binutils.assemble("(extra data for block)")).as_bin()

FIRST_GENERATOR = Program.to(
    binutils.assemble("""
        ((0x0000000000000000000000000000000000000000000000000000000000000000 1 50000
        ((51 0x0000000000000000000000000000000000000000000000000000000000000001 500)) "extra" "data" "for" "coin" ))"""
                      )).as_bin()

SECOND_GENERATOR = Program.to(
    binutils.assemble("(extra data for block)")).as_bin()

Exemplo n.º 5
0
 def as_make_solution_sender(self):
     sol = "(77777 "
     sol += ")"
     return Program(binutils.assemble(sol))
Exemplo n.º 6
0
from clvm import run_program  # noqa
try:
    from clvm.runtime_001 import OPERATOR_LOOKUP  # noqa
except ImportError:
    from clvm.operators import OPERATOR_LOOKUP  # noqa

from clvm_tools import binutils

brun = run = binutils.assemble("((c (f 1) (r 1)))")
"""
Copyright 2019 Chia Network Inc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
Exemplo n.º 7
0
 def ac_make_aggregation_solution(self, myid, wallet_coin_primary_input, wallet_coin_amount):
     sol = f"(0x{hexlify(myid).decode('ascii')} 0x{hexlify(wallet_coin_primary_input).decode('ascii')} {wallet_coin_amount})"
     return Program(binutils.assemble(sol))
Exemplo n.º 8
0
 def solution_for_rl(self, my_parent_id, my_puzzlehash, my_amount, out_puzzlehash, out_amount, my_parent_parent_id,
                     parent_amount):
     min_block_count = math.ceil((out_amount * self.interval) / self.limit)
     solution = f"(1 0x{my_parent_id} 0x{my_puzzlehash} {my_amount} 0x{out_puzzlehash} {out_amount} {min_block_count} 0x{my_parent_parent_id} {parent_amount})"
     return Program(binutils.assemble(solution))
Exemplo n.º 9
0
def test_pattern_match():

    r = match(assemble("($ . $)"), assemble("$"))
    assert r == {}

    r = match(assemble("($ . $)"), assemble("x"))
    assert r is None

    r = match(assemble("(: . :)"), assemble(":"))
    assert r == {}

    r = match(assemble("(: . :)"), assemble("x"))
    assert r is None

    r = match(assemble("$"), assemble("$"))
    assert r == {}

    # () is an atom
    r = match(assemble("($ . n)"), assemble("()"))
    assert r == {"n": assemble("()")}

    r = match(assemble("($ . size)"), assemble("200"))
    assert r == {"size": assemble("200")}

    r = match(assemble("(: . size)"), assemble("200"))
    assert r == {"size": assemble("200")}

    r = match(assemble("($ . size)"), assemble("(I like cheese)"))
    assert r is None

    r = match(assemble("(: . size)"), assemble("(I like cheese)"))
    assert r == {"size": assemble("(I like cheese)")}

    r = match(assemble("(= (f (r (a))) ($ . pubkey))"),
              assemble("(= (f (r (a))) 50000)"))
    assert r == {"pubkey": assemble("50000")}

    r = match(
        assemble("(= (f (r (a))) ($ . pubkey1) ($ . pubkey2))"),
        assemble("(= (f (r (a))) 50000 60000)"),
    )
    assert r == {"pubkey1": assemble("50000"), "pubkey2": assemble("60000")}

    r = match(
        assemble("(= (f (r (a))) ($ . pubkey1) ($ . pubkey1))"),
        assemble("(= (f (r (a))) 50000 60000)"),
    )
    assert r is None

    r = match(
        assemble("(= (f (r (a))) ($ . pubkey1) ($ . pubkey1))"),
        assemble("(= (f (r (a))) 50000 50000)"),
    )
    assert r == {"pubkey1": assemble("50000")}
Exemplo n.º 10
0
    async def respond_to_offer(self,
                               file_path: Path) -> Tuple[bool, Optional[str]]:
        has_wallets = await self.maybe_create_wallets_for_offer(file_path)
        if not has_wallets:
            return False, "Unknown Error"
        trade_offer_hex = file_path.read_text()
        trade_offer = SpendBundle.from_bytes(bytes.fromhex(trade_offer_hex))

        coinsols = []  # [] of CoinSolutions
        cc_coinsol_outamounts: Dict[bytes32, List[Tuple[Any, int]]] = dict()
        # Used for generating auditor solution, key is colour
        auditees: Dict[bytes32, List[Tuple[bytes32, bytes32, Any,
                                           int]]] = dict()
        aggsig = trade_offer.aggregated_signature
        cc_discrepancies: Dict[bytes32, int] = dict()
        chia_discrepancy = None
        wallets: Dict[bytes32, Any] = dict()  # colour to wallet dict

        for coinsol in trade_offer.coin_solutions:
            puzzle = coinsol.solution.first()
            solution = coinsol.solution.rest().first()

            # work out the deficits between coin amount and expected output for each
            if cc_wallet_puzzles.check_is_cc_puzzle(puzzle):
                parent_info = binutils.disassemble(
                    solution.rest().first()).split(" ")

                if len(parent_info) > 1:
                    # Calculate output amounts
                    colour = cc_wallet_puzzles.get_genesis_from_puzzle(
                        binutils.disassemble(puzzle))
                    if colour not in wallets:
                        wallets[
                            colour] = await self.wallet_state_manager.get_wallet_for_colour(
                                colour)
                    unspent = await self.wallet_state_manager.get_spendable_coins_for_wallet(
                        wallets[colour].wallet_info.id)
                    if coinsol.coin in [record.coin for record in unspent]:
                        return False, "can't respond to own offer"
                    innerpuzzlereveal = solution.rest().rest().rest().first()
                    innersol = solution.rest().rest().rest().rest().first()
                    out_amount = cc_wallet_puzzles.get_output_amount_for_puzzle_and_solution(
                        innerpuzzlereveal, innersol)

                    if colour in cc_discrepancies:
                        cc_discrepancies[
                            colour] += coinsol.coin.amount - out_amount
                    else:
                        cc_discrepancies[
                            colour] = coinsol.coin.amount - out_amount
                    # Store coinsol and output amount for later
                    if colour in cc_coinsol_outamounts:
                        cc_coinsol_outamounts[colour].append(
                            (coinsol, out_amount))
                    else:
                        cc_coinsol_outamounts[colour] = [(coinsol, out_amount)]

                    # auditees should be (primary_input, innerpuzhash, coin_amount, output_amount)
                    if colour in auditees:
                        auditees[colour].append((
                            coinsol.coin.parent_coin_info,
                            Program(innerpuzzlereveal).get_tree_hash(),
                            coinsol.coin.amount,
                            out_amount,
                        ))
                    else:
                        auditees[colour] = [(
                            coinsol.coin.parent_coin_info,
                            Program(innerpuzzlereveal).get_tree_hash(),
                            coinsol.coin.amount,
                            out_amount,
                        )]
                else:
                    coinsols.append(coinsol)
            else:
                # standard chia coin
                unspent = await self.wallet_state_manager.get_spendable_coins_for_wallet(
                    1)
                if coinsol.coin in [record.coin for record in unspent]:
                    return False, "can't respond to own offer"
                if chia_discrepancy is None:
                    chia_discrepancy = cc_wallet_puzzles.get_output_discrepancy_for_puzzle_and_solution(
                        coinsol.coin, puzzle, solution)
                else:
                    chia_discrepancy += cc_wallet_puzzles.get_output_discrepancy_for_puzzle_and_solution(
                        coinsol.coin, puzzle, solution)
                coinsols.append(coinsol)

        chia_spend_bundle: Optional[SpendBundle] = None
        if chia_discrepancy is not None:
            chia_spend_bundle = await self.wallet_state_manager.main_wallet.create_spend_bundle_relative_chia(
                chia_discrepancy, [])

        zero_spend_list: List[SpendBundle] = []
        # create coloured coin
        self.log.info(cc_discrepancies)
        for colour in cc_discrepancies.keys():
            if cc_discrepancies[colour] < 0:
                my_cc_spends = await wallets[colour].select_coins(
                    abs(cc_discrepancies[colour]))
            else:
                if chia_spend_bundle is None:
                    to_exclude: List = []
                else:
                    to_exclude = chia_spend_bundle.removals()
                zero_spend_bundle: SpendBundle = await wallets[
                    colour].generate_zero_val_coin(False, to_exclude)
                zero_spend_list.append(zero_spend_bundle)

                additions = zero_spend_bundle.additions()
                removals = zero_spend_bundle.removals()
                my_cc_spends = set()
                for add in additions:
                    if add not in removals and add.amount == 0:
                        my_cc_spends.add(add)

            if my_cc_spends == set() or my_cc_spends is None:
                return False, "insufficient funds"

            auditor = my_cc_spends.pop()
            auditor_inner_puzzle = await self.get_inner_puzzle_for_puzzle_hash(
                auditor.puzzle_hash)
            assert auditor_inner_puzzle is not None
            inner_hash = auditor_inner_puzzle.get_tree_hash()

            auditor_info = (
                auditor.parent_coin_info,
                inner_hash,
                auditor.amount,
            )
            auditor_formatted = (
                f"(0x{auditor.parent_coin_info} 0x{inner_hash} {auditor.amount})"
            )
            core = cc_wallet_puzzles.cc_make_core(colour)
            parent_info = await wallets[colour].get_parent_for_coin(auditor)

            for coloured_coin in my_cc_spends:
                inner_solution = self.wallet_state_manager.main_wallet.make_solution(
                    consumed=[auditor.name()])
                sig = await wallets[
                    colour].get_sigs_for_innerpuz_with_innersol(
                        await self.get_inner_puzzle_for_puzzle_hash(
                            coloured_coin.puzzle_hash),
                        inner_solution,
                    )
                aggsig = BLSSignature.aggregate(
                    [BLSSignature.aggregate(sig), aggsig])
                inner_puzzle = await self.get_inner_puzzle_for_puzzle_hash(
                    coloured_coin.puzzle_hash)
                assert inner_puzzle is not None
                # auditees should be (primary_input, innerpuzhash, coin_amount, output_amount)
                auditees[colour].append((
                    coloured_coin.parent_coin_info,
                    inner_puzzle.get_tree_hash(),
                    coloured_coin.amount,
                    0,
                ))

                solution = cc_wallet_puzzles.cc_make_solution(
                    core,
                    (
                        parent_info.parent_name,
                        parent_info.inner_puzzle_hash,
                        parent_info.amount,
                    ),
                    coloured_coin.amount,
                    binutils.disassemble(inner_puzzle),
                    binutils.disassemble(inner_solution),
                    auditor_info,
                    None,
                )
                coin_spend = CoinSolution(
                    coloured_coin,
                    clvm.to_sexp_f([
                        cc_wallet_puzzles.cc_make_puzzle(
                            inner_puzzle.get_tree_hash(),
                            core,
                        ),
                        solution,
                    ]),
                )
                coinsols.append(coin_spend)

                ephemeral = cc_wallet_puzzles.create_spend_for_ephemeral(
                    coloured_coin, auditor, 0)
                coinsols.append(ephemeral)

                auditor = cc_wallet_puzzles.create_spend_for_auditor(
                    auditor, coloured_coin)
                coinsols.append(auditor)

            # Tweak the offer's solution to include the new auditor
            for cc_coinsol_out in cc_coinsol_outamounts[colour]:
                cc_coinsol = cc_coinsol_out[0]
                offer_sol = binutils.disassemble(cc_coinsol.solution)
                # auditor is (primary_input, innerpuzzlehash, amount)
                offer_sol = offer_sol.replace(
                    "))) ()) () ()))", f"))) ()) {auditor_formatted} ()))")
                new_coinsol = CoinSolution(cc_coinsol.coin,
                                           binutils.assemble(offer_sol))
                coinsols.append(new_coinsol)

                eph = cc_wallet_puzzles.create_spend_for_ephemeral(
                    cc_coinsol.coin, auditor, cc_coinsol_out[1])
                coinsols.append(eph)

                aud = cc_wallet_puzzles.create_spend_for_auditor(
                    auditor, cc_coinsol.coin)
                coinsols.append(aud)

            # Finish the auditor CoinSolution with new information
            newinnerpuzhash = await wallets[colour].get_new_inner_hash()
            outputamount = (sum([c.amount for c in my_cc_spends]) +
                            cc_discrepancies[colour] + auditor.amount)
            innersol = self.wallet_state_manager.main_wallet.make_solution(
                primaries=[{
                    "puzzlehash": newinnerpuzhash,
                    "amount": outputamount
                }])
            parent_info = await wallets[colour].get_parent_for_coin(auditor)

            auditees[colour].append((
                auditor.parent_coin_info,
                auditor_inner_puzzle.get_tree_hash(),
                auditor.amount,
                outputamount,
            ))

            sig = await wallets[colour].get_sigs(auditor_inner_puzzle,
                                                 innersol)
            aggsig = BLSSignature.aggregate(
                [BLSSignature.aggregate(sig), aggsig])

            solution = cc_wallet_puzzles.cc_make_solution(
                core,
                (
                    parent_info.parent_name,
                    parent_info.inner_puzzle_hash,
                    parent_info.amount,
                ),
                auditor.amount,
                binutils.disassemble(auditor_inner_puzzle),
                binutils.disassemble(innersol),
                auditor_info,
                auditees[colour],
            )

            cs = CoinSolution(
                auditor,
                clvm.to_sexp_f([
                    cc_wallet_puzzles.cc_make_puzzle(
                        auditor_inner_puzzle.get_tree_hash(), core),
                    solution,
                ]),
            )
            coinsols.append(cs)

            cs_eph = create_spend_for_ephemeral(auditor, auditor, outputamount)
            coinsols.append(cs_eph)

            cs_aud = create_spend_for_auditor(auditor, auditor)
            coinsols.append(cs_aud)

        spend_bundle = SpendBundle(coinsols, aggsig)
        my_tx_records = []

        if zero_spend_list is not None:
            zero_spend_list.append(spend_bundle)
            spend_bundle = SpendBundle.aggregate(zero_spend_list)

        # Add transaction history hor this trade
        if chia_spend_bundle is not None:
            spend_bundle = SpendBundle.aggregate(
                [spend_bundle, chia_spend_bundle])
            if chia_discrepancy < 0:
                tx_record = TransactionRecord(
                    confirmed_at_index=uint32(0),
                    created_at_time=uint64(int(time.time())),
                    to_puzzle_hash=token_bytes(),
                    amount=uint64(abs(chia_discrepancy)),
                    fee_amount=uint64(0),
                    incoming=False,
                    confirmed=False,
                    sent=uint32(10),
                    spend_bundle=chia_spend_bundle,
                    additions=chia_spend_bundle.additions(),
                    removals=chia_spend_bundle.removals(),
                    wallet_id=uint32(1),
                    sent_to=[],
                )
            else:
                tx_record = TransactionRecord(
                    confirmed_at_index=uint32(0),
                    created_at_time=uint64(int(time.time())),
                    to_puzzle_hash=token_bytes(),
                    amount=uint64(abs(chia_discrepancy)),
                    fee_amount=uint64(0),
                    incoming=True,
                    confirmed=False,
                    sent=uint32(10),
                    spend_bundle=chia_spend_bundle,
                    additions=chia_spend_bundle.additions(),
                    removals=chia_spend_bundle.removals(),
                    wallet_id=uint32(1),
                    sent_to=[],
                )
            my_tx_records.append(tx_record)

        for colour, amount in cc_discrepancies.items():
            wallet = wallets[colour]
            if chia_discrepancy > 0:
                tx_record = TransactionRecord(
                    confirmed_at_index=uint32(0),
                    created_at_time=uint64(int(time.time())),
                    to_puzzle_hash=token_bytes(),
                    amount=uint64(abs(amount)),
                    fee_amount=uint64(0),
                    incoming=False,
                    confirmed=False,
                    sent=uint32(10),
                    spend_bundle=spend_bundle,
                    additions=spend_bundle.additions(),
                    removals=spend_bundle.removals(),
                    wallet_id=wallet.wallet_info.id,
                    sent_to=[],
                )
            else:
                tx_record = TransactionRecord(
                    confirmed_at_index=uint32(0),
                    created_at_time=uint64(int(time.time())),
                    to_puzzle_hash=token_bytes(),
                    amount=uint64(abs(amount)),
                    fee_amount=uint64(0),
                    incoming=True,
                    confirmed=False,
                    sent=uint32(10),
                    spend_bundle=spend_bundle,
                    additions=spend_bundle.additions(),
                    removals=spend_bundle.removals(),
                    wallet_id=wallet.wallet_info.id,
                    sent_to=[],
                )
            my_tx_records.append(tx_record)

        tx_record = TransactionRecord(
            confirmed_at_index=uint32(0),
            created_at_time=uint64(int(time.time())),
            to_puzzle_hash=token_bytes(),
            amount=uint64(0),
            fee_amount=uint64(0),
            incoming=False,
            confirmed=False,
            sent=uint32(0),
            spend_bundle=spend_bundle,
            additions=spend_bundle.additions(),
            removals=spend_bundle.removals(),
            wallet_id=uint32(0),
            sent_to=[],
        )

        await self.wallet_state_manager.add_pending_transaction(tx_record)
        for tx in my_tx_records:
            await self.wallet_state_manager.add_transaction(tx)

        return True, None
from tests.clvm.coin_store import BadSpendBundleError, CoinStore, CoinTimestamp

SINGLETON_MOD = load_clvm("singleton_top_layer.clvm")
LAUNCHER_PUZZLE = load_clvm("singleton_launcher.clvm")
P2_SINGLETON_MOD = load_clvm("p2_singleton_or_delayed_puzhash.clvm")
POOL_MEMBER_MOD = load_clvm("pool_member_innerpuz.clvm")
POOL_WAITINGROOM_MOD = load_clvm("pool_waitingroom_innerpuz.clvm")

LAUNCHER_PUZZLE_HASH = LAUNCHER_PUZZLE.get_tree_hash()
SINGLETON_MOD_HASH = SINGLETON_MOD.get_tree_hash()
P2_SINGLETON_MOD_HASH = P2_SINGLETON_MOD.get_tree_hash()

ANYONE_CAN_SPEND_PUZZLE = Program.to(1)
ANYONE_CAN_SPEND_WITH_PADDING_PUZZLE_HASH = Program.to(
    binutils.assemble("(a (q . 1) 3)")).get_tree_hash()

POOL_REWARD_PREFIX_MAINNET = bytes32.fromhex(
    "ccd5bb71183532bff220ba46c268991a00000000000000000000000000000000")

MAX_BLOCK_COST_CLVM = int(1e18)


class PuzzleDB:
    def __init__(self):
        self._db = {}

    def add_puzzle(self, puzzle: Program):
        self._db[puzzle.get_tree_hash()] = Program.from_bytes(bytes(puzzle))

    def puzzle_for_hash(self, puzzle_hash: bytes32) -> Optional[Program]:
Exemplo n.º 12
0
async def main() -> None:
    rpc_port: uint16 = uint16(8555)
    self_hostname = "localhost"
    path = DEFAULT_ROOT_PATH
    config = load_config(path, "config.yaml")
    client = await FullNodeRpcClient.create(self_hostname, rpc_port, path,
                                            config)
    try:
        farmer_prefarm = (
            await
            client.get_block_record_by_height(1)).reward_claims_incorporated[1]
        pool_prefarm = (
            await
            client.get_block_record_by_height(1)).reward_claims_incorporated[0]

        pool_amounts = int(calculate_pool_reward(uint32(0)) / 2)
        farmer_amounts = int(calculate_base_farmer_reward(uint32(0)) / 2)
        print(farmer_prefarm.amount, farmer_amounts)
        assert farmer_amounts == farmer_prefarm.amount // 2
        assert pool_amounts == pool_prefarm.amount // 2
        address1 = "xch1rdatypul5c642jkeh4yp933zu3hw8vv8tfup8ta6zfampnyhjnusxdgns6"  # Key 1
        address2 = "xch1duvy5ur5eyj7lp5geetfg84cj2d7xgpxt7pya3lr2y6ke3696w9qvda66e"  # Key 2

        ph1 = decode_puzzle_hash(address1)
        ph2 = decode_puzzle_hash(address2)

        p_farmer_2 = Program.to(
            binutils.assemble(
                f"(q . ((51 0x{ph1.hex()} {farmer_amounts}) (51 0x{ph2.hex()} {farmer_amounts})))"
            ))
        p_pool_2 = Program.to(
            binutils.assemble(
                f"(q . ((51 0x{ph1.hex()} {pool_amounts}) (51 0x{ph2.hex()} {pool_amounts})))"
            ))

        print(f"Ph1: {ph1.hex()}")
        print(f"Ph2: {ph2.hex()}")
        assert ph1.hex(
        ) == "1b7ab2079fa635554ad9bd4812c622e46ee3b1875a7813afba127bb0cc9794f9"
        assert ph2.hex(
        ) == "6f184a7074c925ef8688ce56941eb8929be320265f824ec7e351356cc745d38a"

        p_solution = Program.to(binutils.assemble("()"))

        sb_farmer = SpendBundle(
            [CoinSpend(farmer_prefarm, p_farmer_2, p_solution)], G2Element())
        sb_pool = SpendBundle([CoinSpend(pool_prefarm, p_pool_2, p_solution)],
                              G2Element())

        print("\n\n\nConditions")
        print_conditions(sb_pool)
        print("\n\n\n")
        print("Farmer to spend")
        print(sb_pool)
        print(sb_farmer)
        print("\n\n\n")
        # res = await client.push_tx(sb_farmer)
        # res = await client.push_tx(sb_pool)

        # print(res)
        up = await client.get_coin_records_by_puzzle_hash(
            farmer_prefarm.puzzle_hash, True)
        uf = await client.get_coin_records_by_puzzle_hash(
            pool_prefarm.puzzle_hash, True)
        print(up)
        print(uf)
    finally:
        client.close()
Exemplo n.º 13
0
from clvm import run_program, SExp, KEYWORD_TO_ATOM
from clvm.operators import OPERATOR_LOOKUP

from clvm_tools.binutils import assemble

from .pattern_match import match

# CURRY_OBJ_CODE contains compiled code from the output of the following:
# run -i clvm_runtime '(mod (F . args) (include curry.clvm) (curry_args F args))'

CURRY_OBJ_CODE = assemble("""
    ((c (q ((c 4 (c 2 (c 5 (c 7 (q ()))))))) (c (q ((c (c (q 5) (c (c (q 1) (c 5 (q ())))
    (c ((c 6 (c 2 (c 11 (q (q)))))) (q ())))) (q ())) (c (i 5 (q (c (q 5) (c (c (q 1)
    (c 9 (q ()))) (c ((c 6 (c 2 (c 13 (c 11 (q ())))))) (q ()))))) (q 11)) 1))) 1)))
""")


def curry(program, args):
    """
    ;; A "curry" binds values to a function, making them constant,
    ;; and returning a new function that returns fewer arguments (since the
    ;; arguments are now fixed).
    ;; Example: (defun add2 (V1 V2) (+ V1 V2))  ; add two values
    ;; (curry add2 15) ; this yields a function that accepts ONE argument, and adds 15 to it

    `program`: an SExp
    `args`: an SExp that is a list of constants to be bound to `program`
    """

    args = SExp.to((program, args))
    r = run_program(
Exemplo n.º 14
0
def adaptor_for_singleton_inner_puzzle(puzzle: Program) -> Program:
    # this is prety slow
    return Program.to(
        binutils.assemble("(a (q . %s) 3)" % binutils.disassemble(puzzle)))
Exemplo n.º 15
0
 async def test_valid_block_height(self):
     conditions = Program.to(
         assemble(f"(({ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE[0]} 3))"))
     await check_conditions(conditions)
Exemplo n.º 16
0
    it's a constant. So we can simply evaluate it and
    return the quoted result.
    """
    if seems_constant(r) and non_nil(r):
        cost, r1 = eval(r, r.null())
        r = r.to(quote(r1))
    return r


def is_args_call(r):
    if not r.listp() and r.as_int() == 1:
        return True
    return False


CONS_Q_A_OPTIMIZER_PATTERN = assemble("(a (q . (: . sexp)) (: . args))")


def cons_q_a_optimizer(r, eval):
    """
    This applies the transform
    (a (q . SEXP) @) => SEXP
    """
    t1 = match(CONS_Q_A_OPTIMIZER_PATTERN, r)
    if t1 and is_args_call(t1["args"]):
        return t1["sexp"]
    return r


CONS_PATTERN = assemble("(c (: . first) (: . rest)))")
Exemplo n.º 17
0
from clvm_tools.binutils import assemble

from stages.stage_0 import run_program

from .pattern_match import match


# CURRY_OBJ_CODE contains compiled code from the output of the following:
# run -i clvm_runtime '(mod (F . args) (include curry.clvm) (curry_args F args))'

# the text below has been hand-optimized to replace `((c (q X) Y))` with `(a (q X) Y)`
# and `(q 0)` with `0`

CURRY_OBJ_CODE = assemble(
    """
(a (q #a 4 (c 2 (c 5 (c 7 0)))) (c (q (c (q . 2) (c (c (q . 1) 5) (c (a 6 (c 2 (c 11 (q 1)))) 0))) #a (i 5 (q 4 (q . 4) (c (c (q . 1) 9) (c (a 6 (c 2 (c 13 (c 11 0)))) 0))) (q . 11)) 1) 1))
    """
)


def curry(program, args):
    """
    ;; A "curry" binds values to a function, making them constant,
    ;; and returning a new function that returns fewer arguments (since the
    ;; arguments are now fixed).
    ;; Example: (defun add2 (V1 V2) (+ V1 V2))  ; add two values
    ;; (curry add2 15) ; this yields a function that accepts ONE argument, and adds 15 to it

    `program`: an SExp
    `args`: an SExp that is a list of constants to be bound to `program`
    """
Exemplo n.º 18
0
def rl_make_aggregation_solution(myid, wallet_coin_primary_input,
                                 wallet_coin_amount):
    opcode_myid = "0x" + hexlify(myid).decode("ascii")
    primary_input = "0x" + hexlify(wallet_coin_primary_input).decode("ascii")
    sol = sexp(opcode_myid, primary_input, wallet_coin_amount)
    return Program.to(binutils.assemble(sol))
Exemplo n.º 19
0
 def ap_make_solution_mode_1(self, outputs=[], my_primary_input=0x0000, my_puzzle_hash=0x0000):
     sol = "(1 ("
     for puzhash, amount in outputs:
         sol += f"(0x{hexlify(puzhash).decode('ascii')} {amount})"
     sol += f") 0x{hexlify(my_primary_input).decode('ascii')} 0x{hexlify(my_puzzle_hash).decode('ascii')})"
     return Program(binutils.assemble(sol))
Exemplo n.º 20
0
def make_clawback_solution(puzzlehash, amount, fee):
    opcode_create = hexlify(ConditionOpcode.CREATE_COIN).decode("ascii")
    solution = sexp(
        CLAWBACK_MODE,
        sexp("0x" + opcode_create, "0x" + str(puzzlehash), amount - fee))
    return Program.to(binutils.assemble(solution))
Exemplo n.º 21
0
 def ap_make_solution_mode_2(self, wallet_puzzle_hash, consolidating_primary_input, consolidating_coin_puzzle_hash, outgoing_amount, my_primary_input, incoming_amount):
     sol = f"(2 0x{hexlify(wallet_puzzle_hash).decode('ascii')} 0x{hexlify(consolidating_primary_input).decode('ascii')} 0x{hexlify(consolidating_coin_puzzle_hash).decode('ascii')} {outgoing_amount} 0x{hexlify(my_primary_input).decode('ascii')} {incoming_amount})"
     return Program(binutils.assemble(sol))
Exemplo n.º 22
0
from chia.types.condition_opcodes import ConditionOpcode
from chia.types.full_block import FullBlock
from chia.types.spend_bundle import SpendBundle
from chia.util.block_tools import BlockTools, test_constants
from chia.util.errors import Err

from .ram_db import create_ram_blockchain

bt = BlockTools(constants=test_constants)

log = logging.getLogger(__name__)

# This puzzle simply returns the solution as conditions.
# We call it the `EASY_PUZZLE` because it's pretty easy to solve.

EASY_PUZZLE = Program.to(assemble("1"))
EASY_PUZZLE_HASH = EASY_PUZZLE.get_tree_hash()


def initial_blocks(block_count: int = 4) -> List[FullBlock]:
    blocks = bt.get_consecutive_blocks(
        block_count,
        guarantee_transaction_block=True,
        farmer_reward_puzzle_hash=EASY_PUZZLE_HASH,
        pool_reward_puzzle_hash=EASY_PUZZLE_HASH,
    )
    return blocks


async def check_spend_bundle_validity(
    constants: ConsensusConstants,
Exemplo n.º 23
0
def create_recovery_message_puzzle(recovering_coin: bytes32, newpuz: bytes32,
                                   pubkey: G1Element):
    puzstring = f"(q . ((0x{ConditionOpcode.CREATE_COIN_ANNOUNCEMENT.hex()} 0x{recovering_coin.hex()}) (0x{ConditionOpcode.AGG_SIG_UNSAFE.hex()} 0x{bytes(pubkey).hex()} 0x{newpuz.hex()})))"  # noqa
    puz = binutils.assemble(puzstring)
    return Program.to(puz)
Exemplo n.º 24
0
 async def test_invalid_block_age(self):
     conditions = Program.to(
         assemble(f"(({ConditionOpcode.ASSERT_HEIGHT_RELATIVE[0]} 2))"))
     await check_conditions(conditions,
                            expected_err=Err.ASSERT_HEIGHT_RELATIVE_FAILED)
Exemplo n.º 25
0
 def as_make_solution_receiver(self, as_sec_to_try):
     sol = "(33333 "
     sol += f"{as_sec_to_try}"
     sol += ")"
     return Program(binutils.assemble(sol))
Exemplo n.º 26
0
 async def test_valid_block_age(self):
     conditions = Program.to(
         assemble(f"(({ConditionOpcode.ASSERT_HEIGHT_RELATIVE[0]} 1))"))
     await check_conditions(conditions)
Exemplo n.º 27
0
def make_clawback_solution(puzzlehash, amount):
    opcode_create = hexlify(ConditionOpcode.CREATE_COIN).decode("ascii")
    solution = f"(3 (0x{opcode_create} 0x{puzzlehash} {amount}))"
    return Program(binutils.assemble(solution))
Exemplo n.º 28
0
 async def test_invalid_block_height(self):
     conditions = Program.to(
         assemble(f"(({ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE[0]} 4))"))
     await check_conditions(conditions,
                            expected_err=Err.ASSERT_HEIGHT_ABSOLUTE_FAILED)
Exemplo n.º 29
0
    async def rl_generate_signed_aggregation_transaction(
            self, rl_info: RLInfo, consolidating_coin: Coin, rl_parent: Coin,
            rl_coin: Coin):
        if (rl_info.limit is None or rl_info.interval is None
                or rl_info.limit is None or rl_info.interval is None
                or rl_info.user_pubkey is None
                or rl_info.admin_pubkey is None):
            raise Exception("One ore more of the elements of rl_info is None")

        list_of_coinsolutions = []

        pubkey, secretkey = await self.get_keys(
            self.rl_coin_record.coin.puzzle_hash)
        # Spend wallet coin
        puzzle = rl_puzzle_for_pk(
            rl_info.user_pubkey,
            rl_info.limit,
            rl_info.interval,
            rl_info.rl_origin,
            rl_info.admin_pubkey,
        )

        solution = rl_make_solution_mode_2(
            rl_coin.puzzle_hash,
            consolidating_coin.parent_coin_info,
            consolidating_coin.puzzle_hash,
            consolidating_coin.amount,
            rl_coin.parent_coin_info,
            rl_coin.amount,
            rl_parent.amount,
            rl_parent.parent_coin_info,
        )

        signature = secretkey.sign(solution.get_tree_hash())
        list_of_coinsolutions.append(
            CoinSolution(self.rl_coin_record.coin,
                         Program.to([puzzle, solution])))

        # Spend consolidating coin
        puzzle = rl_make_aggregation_puzzle(
            self.rl_coin_record.coin.puzzle_hash)
        solution = rl_make_aggregation_solution(
            consolidating_coin.name(),
            self.rl_coin_record.coin.parent_coin_info,
            self.rl_coin_record.coin.amount,
        )
        list_of_coinsolutions.append(
            CoinSolution(consolidating_coin, Program.to([puzzle, solution])))
        # Spend lock
        puzstring = ("(r (c (q 0x" +
                     hexlify(consolidating_coin.name()).decode("ascii") +
                     ") (q ())))")

        puzzle = Program(binutils.assemble(puzstring))
        solution = Program(binutils.assemble("()"))
        list_of_coinsolutions.append(
            CoinSolution(
                Coin(self.rl_coin_record.coin, puzzle.get_hash(), uint64(0)),
                Program.to([puzzle, solution]),
            ))

        aggsig = AugSchemeMPL.aggregate([signature])

        return SpendBundle(list_of_coinsolutions, aggsig)
Exemplo n.º 30
0
def puzzle_for_puzzle_hash(underlying_puzzle_hash):
    TEMPLATE = "((c (i (= (sha256tree (f (a))) (q 0x%s)) (q ((c (f (a)) (f (r (a)))))) (q (x))) (a)))"
    return Program.to(
        binutils.assemble(TEMPLATE % underlying_puzzle_hash.hex()))