10000 CryptoKup (CryptoKup) · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
View CryptoKup's full-sized avatar

Block or report CryptoKup

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Please don't include any personal information such as legal names or email addresses. Maximum 100 characters, markdown supported. This note will be visible to only you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
CryptoKup/README.md

Transactions A transaction contains the following fields: Field Description Version Protocol version number Arbitrary Data Used for metadata or otherwise Inputs Incoming funds Outputs Outgoing funds (optional) File Contract See: File Contracts (optional) Storage Proof See: Proof of Storage (optional) Signatures Signatures from each input KupFIXFee Reward giventoUS REZERVE Inputs and Outputs An output comprises a volume of coins. Each output has an associated identifier, which is derived from the transaction that the output appeared in. The ID of output i in transaction t is defined as: H(t||“output”||i) where H is a cryptographic hashing function, and “output” is a string literal. The block reward and miner fees have special output IDs, given by:

https://explorer.cryptokup.com/H(H(Block Header)||“blockreward”)email wallet

H(transaction||“contract”||i) where i is the index of the contract within the transaction. The output ID of the proof can then be determined from: H(contract ID||outcome||Wi) Valid-blockchain-KUP -System v2-by-anonimus-prt-bitcoin Algorithm Hosts prove their storage by providing a segment of the original file and a list of hashes from the file’s Merkle tree. This information is sufficient to prove that the segment came from the original file. Because proofs are submitted to the blockchain, anyone can verify their validity or invalidity. Each storage proof uses a randomly selected segment. The random seed for challenge window Wi is given by: H(contract ID||H(Bi−1)) Introduced several improvements such as views which give smart contracts the ability to read the storage state of other smart contracts, timelock encryption to serve as a countermeasure against Block Producer Extractable Value, caching to provide faster access at lower gas costs to data that is accessed regularly, and a global table of constants to facilitate development of more complex smart contracts.

#!/usr/bin/env python

""" run_block: Convert an encoded FullBlock from the KUP blockchain into a list of transactions As input, takes a file containing a FullBlock in json format

curl --insecure --cert $config_root/config/ssl/full_node/private_full_node.crt \
     --key $config_root/config/ssl/full_node/private_full_node.key \
     -d '{ "header_hash": "'$hash'" }' -H "Content-Type: application/json" \
     -X POST https://localhost:$port/get_block
$ca_root is the directory containing your current KUP config files
$hash is the header_hash of the [BlockRecord](../KUP/consensus/block_record.py)
$port is the Full Node RPC API port

The transactions_generator and transactions_generator_ref_list fields of a FullBlock contain the information necessary to produce transaction record details. transactions_generator is CLVM bytecode transactions_generator_ref_list is a list of block heights as uint32 When this CLVM code is run in the correct environment, it produces information that can then be verified by the consensus rules, or used to view some aspects of transaction history. The information for each spend is an "NPC" (Name, Puzzle, Condition): "coin_name": a unique 32 byte identifier "conditions": a list of condition expressions, as in condition_opcodes.py "puzzle_hash": the sha256 of the CLVM bytecode that controls spending this coin Condition Opcodes, such as AGG_SIG_ME, or CREATE_COIN are created by running the "puzzle", i.e. the CLVM bytecode associated with the coin being spent. Condition Opcodes are verified by every client on the network for every spend, and in this way they control whether a spend is valid or not. """ import json from dataclasses import dataclass from pathlib import Path from typing import Dict, List, Tuple

import click from KUP_rs import COND_CANON_INTS, NO_NEG_DIV from clvm.casts import int_from_bytes

from KUP.consensus.constants import ConsensusConstants from KUP.consensus.default_constants import DEFAULT_CONSTANTS from KUP.full_node.generator import create_generator_args from KUP.types.blockchain_format.coin import Coin from KUP.types.blockchain_format.program import SerializedProgram from KUP.types.blockchain_format.sized_bytes import bytes32 from KUP.types.condition_opcodes import ConditionOpcode from KUP.types.condition_with_args import ConditionWithArgs from KUP.types.generator_types import BlockGenerator from KUP.util.config import load_config from KUP.util.default_root import DEFAULT_ROOT_PATH from KUP.util.ints import uint32, uint64 from KUP.wallet.cat_wallet.cat_utils import match_cat_puzzle

@dataclass class NPC: coin_name: bytes32 puzzle_hash: bytes32 conditions: List[Tuple[ConditionOpcode, List[ConditionWithArgs]]]

@dataclass class CAT: asset_id: str memo: str npc: NPC

def cat_to_dict(self):
    return {"asset_id": self.asset_id, "memo": self.memo, "npc": npc_to_dict(self.npc)}

def condition_with_args_to_dict(condition_with_args: ConditionWithArgs): return { "condition_opcode": condition_with_args.opcode.name, "arguments": [arg.hex() for arg in condition_with_args.vars], }

def condition_list_to_dict(condition_list: Tuple[ConditionOpcode, List[ConditionWithArgs]]): assert all([condition_list[0] == cwa.opcode for cwa in condition_list[1]]) return [condition_with_args_to_dict(cwa) for cwa in condition_list[1]]

def npc_to_dict(npc: NPC): return { "coin_name": npc.coin_name.hex(), "conditions": [{"condition_type": c[0].name, "conditions": condition_list_to_dict(c)} for c in npc.conditions], "puzzle_hash": npc.puzzle_hash.hex(), }

def run_generator( block_generator: BlockGenerator, constants: ConsensusConstants, max_cost: int, height: uint32 ) -> List[CAT]:

if height >= DEFAULT_CONSTANTS.SOFT_FORK_HEIGHT:
    # conditions must use integers in canonical encoding (i.e. no redundant
    # leading zeros)
    # the division operator may not be used with negative operands
    flags = COND_CANON_INTS | NO_NEG_DIV
else:
    flags = 0

args = create_generator_args(block_generator.generator_refs).first()
_, block_result = block_generator.program.run_with_cost(max_cost, flags, args)

coin_spends = block_result.first()

cat_list: List[CAT] = []
for spend in coin_spends.as_iter():

    parent, puzzle, amount, solution = spend.as_iter()
    matched, curried_args = match_cat_puzzle(puzzle)

    if not matched:
        continue

    _, asset_id, _ = curried_args
    memo = ""

    puzzle_result = puzzle.run(solution)

    conds: Dict[ConditionOpcode, List[ConditionWithArgs]] = {}

    for condition in puzzle_result.as_python():
        op = ConditionOpcode(condition[0])

        if op not in conds:
            conds[op] = []

        if condition[0] != ConditionOpcode.CREATE_COIN or len(condition) < 4:
            conds[op].append(ConditionWithArgs(op, [i for i in condition[1:3]]))
            continue

        # If only 3 elements (opcode + 2 args), there is no memo, this is ph, amount
        if type(condition[3]) != list:
            # If it's not a list, it's not the correct format
            conds[op].append(ConditionWithArgs(op, [i for i in condition[1:3]]))
            continue

        conds[op].append(ConditionWithArgs(op, [i for i in condition[1:3]] + [condition[3][0]]))

        # special retirement address
        if condition[3][0].hex() != "0000000000000000000000000000000000000000000000000000000000000000":
            continue

        if len(condition[3]) >= 2:
            try:
                memo = condition[3][1].decode("utf-8", errors="strict")
            except UnicodeError:
                pass  # ignore this error which should leave memo as empty string

        # technically there could be more such create_coin ops in the list but our wallet does not
        # so leaving it for the future
        break

    puzzle_hash = puzzle.get_tree_hash()
    coin = Coin(parent.atom, puzzle_hash, int_from_bytes(amount.atom))
    cat_list.append(
        CAT(
            asset_id=bytes(asset_id).hex()[2:],
            memo=memo,
            npc=NPC(coin.name(), puzzle_hash, [(op, cond) for op, cond in conds.items()]),
        )
    )

return cat_list

def ref_list_to_args(ref_list: List[uint32], root_path: Path) -> List[SerializedProgram]: args = [] for height in ref_list: with open(root_path / f"{height}.json", "rb") as f: program_str = json.load(f)["block"]["transactions_generator"] args.append(SerializedProgram.fromhex(program_str)) return args

def run_generator_with_args( generator_program_hex: str, generator_args: List[SerializedProgram], constants: ConsensusConstants, cost: uint64, height: uint32, ) -> List[CAT]: if not generator_program_hex: return [] generator_program = SerializedProgram.fromhex(generator_program_hex) block_generator = BlockGenerator(generator_program, generator_args, []) return run_generator(block_generator, constants, min(constants.MAX_BLOCK_COST_CLVM, cost), height)

@click.command() @click.argument("filename", type=click.Path(exists=True), default="testnet10.396963.json") def cmd_run_json_block_file(filename): """file is a file containing a FullBlock in JSON format""" return run_json_block_file(Path(filename))

def run_json_block(full_block, parent: Path, constants: ConsensusConstants) -> List[CAT]: ref_list = full_block["block"]["transactions_generator_ref_list"] tx_info: dict = full_block["block"]["transactions_info"] generator_program_hex: str = full_block["block"]["transactions_generator"] height = full_block["block"]["reward_chain_block"]["height"] cat_list: List[CAT] = [] if tx_info and generator_program_hex: cost = tx_info["cost"] args = ref_list_to_args(ref_list, parent) cat_list = run_generator_with_args(generator_program_hex, args, constants, cost, height)

return cat_list

def run_json_block_file(filename: Path): full_block = json.load(filename.open("rb")) # pull in current constants from config.yaml _, constants = get_config_and_constants()

cat_list = run_json_block(full_block, filename.parent.absolute(), constants)

cat_list_json = json.dumps([cat.cat_to_dict() for cat in cat_list])
print(cat_list_json)

def get_config_and_constants(): config = load_config(DEFAULT_ROOT_PATH, "config.yaml") network = config["selected_network"] overrides = config["network_overrides"]["constants"][network] updated_constants = DEFAULT_CONSTANTS.replace_str_to_bytes(**overrides) return config, updated_constants

if name == "main": cmd_run_json_block_file() # pylint: disable=no-value-for-parameter

Popular repositories Loading

  1. CryptoKup CryptoKup Public

    Config files for my GitHub profile.

  2. core core Public

    Forked from terra-money/classic-core

    GO implementation of the Terra Protocol

    JavaScript

  3. Whitepaper Whitepaper Public

    A white paper is an authoritative report or guide that informs readers concisely about a complex issue and presents the issuing body's philosophy on the matter. It is meant to help readers understa…

  4. 5july 5july Public

  5. tools tools Public

    Python

0