def genesis_block(cls): return cls( version= '5465616d3a20456467656e63650a4c65616465723a20776f6c6662726f746865720a4d656d626572733a2063626f7a69' '2c204c6561684c69752c207069616f6c69616e676b622c2053616c7661746f7265303632362c2053696c7669614c69313' '232352c204a69617169204c69752c2078696179756e696c0a', prev_block_hash=None, merkle_hash= '8cfb8d2d2ed9343461b0eefb73c775b9366a32e05e81b0e8946620e2f1935507', timestamp=1554460209, bits=Params.INITIAL_DIFFICULTY_BITS, nonce=17040052, txns=[ Transaction( txins=[ TxIn(to_spend=None, unlock_sig=b'0', unlock_pk=None, sequence=0) ], txouts=[ TxOut(value=5000000000, to_address='0000000000000000000000000000000000') ], locktime=None) ])
def genesis_block(cls): return cls( version="5465616d3a20456467656e63650a4c65616465723a20776f6c6662726f746865720a4d656d626572733a2063626f7a69" "2c204c6561684c69752c207069616f6c69616e676b622c2053616c7661746f7265303632362c2053696c7669614c69313" "232352c204a69617169204c69752c2078696179756e696c0a", prev_block_hash=None, merkle_hash="a578b7a3bdc2d1385bce32a445a8ec4ffb9ab78b76afc30f53787b3189be289c", timestamp=1554460209, bits=Params.INITIAL_DIFFICULTY_BITS, nonce=41912381, txns=[ Transaction( txins=[TxIn(to_spend=None, signature_script=b"0", sequence=0)], txouts=[ TxOut( value=5000000000, pk_script=scriptBuild.get_pk_script( "1NY36FKZqM97oEobfCewhUpHsbzAUSifzo" ), ) ], locktime=None, serviceId=None, postId=None, actionId=None, data=None, ) ], )
def assemble_and_solve_block(self, txns=None) -> Block: """ Construct a Block by pulling transactions from the mempool, then mine it. """ with self.chain_lock: #chain_use_id = [str(number).split('.')[0] + '.' + str(number).split('.')[1][:5] for number in [random.random()]][0] #logger.info(f'####### into chain_lock: {chain_use_id} of assemble_and_solve_block') prev_block_hash = self.active_chain.chain[ -1].id if self.active_chain.chain else None block = Block( version=0, prev_block_hash=prev_block_hash, merkle_hash='', timestamp=int(time.time()), bits=Block.get_next_work_required(prev_block_hash, self.active_chain, self.side_branches), nonce=0, txns=[None, *txns] if txns else [None], ) if block.bits is None: #logger.info(f'####### out of chain_lock: {chain_use_id} of assemble_and_solve_block') return None if not block.txns[1:]: block = self.mempool.select_from_mempool(block, self.utxo_set) # print("EdgenceChain 113: build block with txn:", end="") # print(block) if len(block.txns[1:]) > 0: logger.info( f'{len(block.txns[1:])} transactions selected from mempool to construct this block' ) # print("EdgenceChain 117: build txn:") # print(block) fees = block.calculate_fees(self.utxo_set) # print("fee is: ", end="") # print(fees) my_address = self.wallet()[2] coinbase_txn = Transaction.create_coinbase( my_address, Block.get_block_subsidy(self.active_chain) + fees, self.active_chain.height) #logger.info(f'####### out of chain_lock: {chain_use_id} of assemble_and_solve_block') block.txns[0] = coinbase_txn block = block._replace( merkle_hash=MerkleNode.get_merkle_root_of_txns(block.txns).val) if len(Utils.serialize(block)) > Params.MAX_BLOCK_SERIALIZED_SIZE: raise ValueError('txns specified create a block too large') block = PoW.mine(block, self.mine_interrupt) # print("EdgenceChain 138: after mine: ") # print(block) return block
def _makeTransaction(self, txinType, to_addr, value: int = 0, fee: int = 0) -> Transaction: utxos_to_spend = set() if txinType == 0: utxos = list( sorted(self.getUTXO4Addr(self.wallet.my_address), key=lambda i: (i.value, i.height))) if txinType == 1: utxos = list( sorted(self.getUTXO4Addr(self.getMultiAddress()), key=lambda i: (i.value, i.height))) if sum(i.value for i in utxos) < value + fee: logger.info(f'[EdgeHand] value to send is larger than balance.') return False for utxo in utxos: utxos_to_spend.add(utxo) if sum(i.value for i in utxos_to_spend) > value + fee: break # print(utxos_to_spend) change = sum(i.value for i in utxos_to_spend) - value - fee txout = [TxOut(value=value, pk_script=self._make_pk_script(to_addr))] txout.append( TxOut(value=change, pk_script=self._make_pk_script(self.wallet.my_address))) txin = [ self._makeTxin(txinType, utxo.outpoint, txout) for utxo in utxos_to_spend ] txn = Transaction(txins=txin, txouts=txout) return txn
def genesis_block(cls): return cls( version= '5465616d3a20456467656e63650a4c65616465723a20776f6c6662726f746865720a4d656d626572733a2063626f7a69' '2c204c6561684c69752c207069616f6c69616e676b622c2053616c7661746f7265303632362c2053696c7669614c69313' '232352c204a69617169204c69752c2078696179756e696c0a', prev_block_hash=None, merkle_hash= 'b7b51d3818055321711cf3049b7067afb7d5cbddacc6c106ca92906974316b14', timestamp=1554460209, bits=Params.INITIAL_DIFFICULTY_BITS, nonce=5808524, txns=[ Transaction(txins=[ TxIn(to_spend=None, signature_script=b'0', sequence=0) ], txouts=[ TxOut( value=5000000000, pk_script=scriptBuild.get_pk_script( '1NY36FKZqM97oEobfCewhUpHsbzAUSifzo')) ], locktime=None) ])
def validate_txn( self, txn: Transaction, mempool: BaseMemPool = None, as_coinbase: bool = False, siblings_in_block: Iterable[NamedTuple] = None, # object allow_utxo_from_mempool: bool = True, ) -> bool: def get_current_height(chainfile=Params.CHAIN_FILE): if not os.path.isfile(chainfile): raise ChainFileLostError("chain file not found") try: with open(chainfile, "rb") as f: height = int(binascii.hexlify(f.read(4) or b"\x00"), 16) except Exception: logger.exception(f"[ds] read block height failed") return 0 return height # pre-verify process txn.validate_basics(as_coinbase=as_coinbase) # check the fee available_to_spend = 0 for idx, txin in enumerate(txn.txins): utxo = self.get().get(txin.to_spend) if siblings_in_block: utxo = utxo or UTXO_Set.find_utxo_in_list( txin, siblings_in_block) if allow_utxo_from_mempool: utxo = utxo or mempool.find_utxo_in_mempool(txin) # get utxo from the mempool for farther verify if not utxo: raise TxnValidationError( f"Could find no UTXO for TxIn [{idx}] for txn: {txn.id}", to_orphan=txn, ) if (utxo.is_coinbase and (get_current_height() - utxo.height) < Params.COINBASE_MATURITY): raise TxnValidationError(f"Coinbase UTXO not ready for spend") # do script check in this part! try: txio = script.Script(self.utxoSet, txn) valid = txio.verify() # temparary: produce new address to update the utxo.(ljq) # addresses = [txio.output_address(o) for o in range(0, txio.output_count)] if valid: logger.info(f"[script] Script check succeed!") else: logger.error( f"[script] Script check failed in Transaction part!") raise TxnValidationError(f"Script check failed") except TxUnlockError: raise TxnValidationError( f"{txin} is not a valid spend of {utxo}") available_to_spend += utxo.value if available_to_spend < sum(o.value for o in txn.txouts): raise TxnValidationError("Spend value is more than available") return True
from params.Params import Params from script import scriptBuild from utils.Utils import Utils import time txns = [ Transaction( txins=[TxIn(to_spend=None, signature_script=b"0", sequence=0)], txouts=[ TxOut( value=5000000000, pk_script=scriptBuild.get_pk_script( "1NY36FKZqM97oEobfCewhUpHsbzAUSifzo" ), ) ], serviceId=None, postId=None, actionId=None, data=None, locktime=None, ) ] merkle_hash = MerkleNode.get_merkle_root_of_txns(txns) print(f"merkle_hash={merkle_hash.val}") genesis_block = Block( version="5465616d3a20456467656e63650a4c65616465723a20776f6c6662726f746865720a4d656d626572733a2063626f7a69" "2c204c6561684c69752c207069616f6c69616e676b622c2053616c7661746f7265303632362c2053696c7669614c69313" "232352c204a69617169204c69752c2078696179756e696c0a",