def test_script(): blkaction.load_wallet() timestamp = "The Times 22/Mar/2017 Chancellor on brink of second bailout for banks" tx_new = Tx.PyTransaction() txin = Tx.PyTxIn() init_nbits = 0x1f00ffff sig = PyScript().append(init_nbits).append_num(4).extend(timestamp) # script << nbits << extra_nonce txin.script_sig = sig txout = Tx.PyTxOut() txout.value = 50 * cfg.COIN # scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; Hash160(pubkey) # txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG; # txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG; txout.script_pubkey = PyScript().extend(binascii.unhexlify(cfg.GENESIS_PUBKEY)) \ .append(OpCodeType.OP_CHECKSIG) tx_new.l_in.append(txin) tx_new.l_out.append(txout) block = Block.PyBlock() block.l_tx.append(tx_new) block.hash_prev_block = 0 block.hash_merkle_root = block.build_merkle_tree() block.version = 1 block.time = 1490092537 block.bits = init_nbits block.nonce = 87401 Block.add_to_wallet_if_mine(tx_new, block) pass
def test_block(): timestamp = "The Times 22/Mar/2017 Chancellor on brink of second bailout for banks" tx_new = Tx.PyTransaction() txin = Tx.PyTxIn() init_nbits = 0x1f00ffff sig = Script.PyScript().append(init_nbits).append_num(4).extend(timestamp) # script << nbits << extra_nonce txin.script_sig = sig txout = Tx.PyTxOut() txout.value = 50 * cfg.COIN txout.script_pubkey = Script.PyScript().extend(binascii.unhexlify(cfg.GENESIS_PUBKEY)) \ .append(Script.OpCodeType.OP_CHECKSIG) tx_new.l_in.append(txin) tx_new.l_out.append(txout) block = Block.PyBlock() block.l_tx.append(tx_new) block.hash_prev_block = 0 block.hash_merkle_root = block.build_merkle_tree() block.version = 1 block.time = 1490092537 block.bits = init_nbits block.nonce = 87401 print block.get_hash('hex')
def copytx(): timestamp = "The Times 22/Mar/2017 Chancellor on brink of second bailout for banks" tx_new = Tx.PyTransaction() txin = Tx.PyTxIn() init_nbits = 0x1f00ffff sig = Script.PyScript().append(init_nbits).append_num(4).extend(timestamp) # script << nbits << extra_nonce txin.script_sig = sig txout = Tx.PyTxOut() txout.value = 50 * cfg.COIN # scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; Hash160(pubkey) # txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG; # txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG; txout.script_pubkey = Script.PyScript().extend(binascii.unhexlify(cfg.GENESIS_PUBKEY)) \ .append(Script.OpCodeType.OP_CHECKSIG) tx_new.l_in.append(txin) tx_new.l_out.append(txout) tx = copy.deepcopy(tx_new) l1 = list() # l1.append(txout) # l1.append(txin) # copy.deepcopy(l1) # s = copy.deepcopy(txout.script_pubkey) # print txout.script_pubkey # print s pass
def load_blockindex(): # Load block index txdb = Block.PyTxExtDB("cr") if not txdb.load_blockindex(): txdb.close() return False txdb.close() # Init with genesis block if not ctx.dictBlockIndex: # dictBlockIndex is empty() if not cfg.ALLOW_NEW: return False # Genesis block ! timestamp = "The Times 22/Mar/2017 Chancellor on brink of second bailout for banks" tx_new = Tx.PyTransaction() txin = Tx.PyTxIn() init_nbits = 0x1f00ffff sig = Script.PyScript().append(init_nbits).append_num(4).extend( timestamp) # script << nbits << extra_nonce txin.script_sig = sig txout = Tx.PyTxOut() txout.value = 50 * cfg.COIN # scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; Hash160(pubkey) # txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG; # txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG; txout.script_pubkey = Script.PyScript().extend(binascii.unhexlify(cfg.GENESIS_PUBKEY)) \ .append(Script.OpCodeType.OP_CHECKSIG) tx_new.l_in.append(txin) tx_new.l_out.append(txout) block = Block.PyBlock() block.l_tx.append(tx_new) block.hash_prev_block = 0 block.hash_merkle_root = block.build_merkle_tree() block.version = 1 block.time = 1490092537 block.bits = init_nbits block.nonce = 45164 assert block.get_hash( ) == ctx.hashGenesisBlock, "genesis block hash not equal to block.get_hash()" # start new block file ret = block.write_to_disk(not ctx.fClient) if ret is None: print("LoadBlockIndex() : writing genesis block to disk failed") return False file_index = ret[0] block_pos = ret[1] if not block.add_to_blockindex(file_index, block_pos): print("LoadBlockIndex() : genesis block not accepted") return False load_genesis_tx(tx_new, block) pass # end if return True
def genesis_block(): timestamp = "The Times 22/Mar/2017 Chancellor on brink of second bailout for banks" tx_new = Tx.PyTransaction() txin = Tx.PyTxIn() init_nbits = 0x1f00ffff sig = Script.PyScript().append(init_nbits).append_num(4).extend(timestamp) # script << nbits << extra_nonce txin.script_sig = sig txout = Tx.PyTxOut() txout.value = 50 * cfg.COIN # scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; Hash160(pubkey) # txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG; # txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG; txout.script_pubkey = Script.PyScript().extend(binascii.unhexlify(cfg.GENESIS_PUBKEY)) \ .append(Script.OpCodeType.OP_CHECKSIG) tx_new.l_in.append(txin) tx_new.l_out.append(txout) block = Block.PyBlock() block.l_tx.append(tx_new) block.hash_prev_block = 0 block.hash_merkle_root = block.build_merkle_tree() block.version = 1 block.time = 1490092537 # block.bits = 0x2000ffff # block.bits = init_nbits # nonce:45164 hash:2e72d19b7558bd6ec869e5601c3613cc7a6b3f24118773d7aaaa3c285493fdfc # block.bits = 0x1e00ffff # nonce:xxx (cast almost 5 min) block.nonce = 0 hash_target = BN.PyBigNum.set_compact(block.bits).get_uint256() target_hex = serialize.hexser_uint256(hash_target) # target_hex = long(hash_target) time1 = timeutil.get_time() print 'start time:', time1 while True: block_hash = cryptoutil.Hash(block.serialize()) print 'nonce:', block.nonce print 'now hash:' print serialize.hexser_uint256(block_hash) # print long(block_hash) print 'target' print target_hex if block_hash <= hash_target: print 'current nonce:' print block.nonce print binascii.hexlify(serialize.ser_uint256(block.get_hash())) print block.get_hash('hex') print long(hash_target) break block.nonce += 1 time2 = timeutil.get_time() print 'end time:', time2 diff = time2 - time1 print("%d:%d" % (diff / 60, diff % 60))
def bitcoin_miner(t): """ :param t: :type t: ExitedThread :return: """ print "Miner started" # TODO add thread priority THREAD_PRIORITY_LOWEST key = Key.PyKey() key.make_new_key() extra_nonce = 0 while ctx.fGenerateCoins: timeutil.sleep_msec(50) # 50 ms t.check_self_shutdown() if t.exit: break # while len(ctx.listNodes) == 0: # timeutil.sleep_msec(1000) # t.check_self_shutdown() # if t.exit: # return True transactions_updated_last = ctx.transactionsUpdated index_prev = ctx.indexBest bits = Block.get_next_work_required(index_prev) # create coinbase tx tx_new = Tx.PyTransaction() tx_in = Tx.PyTxIn() tx_in.prev_out.set_null() extra_nonce += 1 tx_in.script_sig.append(bits).append(extra_nonce) tx_new.l_in.append(tx_in) tx_out = Tx.PyTxOut() tx_out.script_pubkey.extend(key.get_pubkey()).append( Script.OpCodeType.OP_CHECKSIG) tx_new.l_out.append(tx_out) # create new block block = Block.PyBlock() # Add our coinbase tx as first transaction block.l_tx.append(tx_new) # Collect the latest transactions into the block fees = 0 with ctx.mainLock: with ctx.dictTransactionsLock: txdb = Tx.PyTxDB("r") test_pool = dict() # map<uint256, PyTxIndex> flag_already_added = [False] * len(ctx.dictTransactions) found_something = True block_size = 0 while found_something and block_size < cfg.MAX_SIZE / 2: # block_size < 2MB/2 = 1MB found_something = False n = 0 for tx_hash, tx in ctx.dictTransactions.iteritems(): if flag_already_added[n]: continue if tx.is_coinbase() or not tx.is_final(): continue # Transaction fee requirements, mainly only needed for flood control # Under 10K (about 80 inputs) is free for first 100 transactions # Base rate is 0.01 per KB min_fee = tx.get_min_fee( len(block.l_tx) < 100) # 100 个交易内的打折,之后的不打折 tmp_test_pool = copy.deepcopy( test_pool) # 防止下面执行出错对test_pool产生干扰 ret = tx.connect_inputs(txdb, tmp_test_pool, Tx.PyDiskTxPos(1, 1, 1), 0, False, True, min_fee) if ret is None: continue fees += ret # 累积交易费 test_pool = tmp_test_pool block.l_tx.append(tx) block_size += tx.serialize_size( serialize.SerType.SER_NETWORK) flag_already_added[n] = True found_something = True # 这是为了跳出外层 while n += 1 # end for pass pass # end while txdb.close() pass # end critical_block pass block.bits = bits block.l_tx[0].l_out[0].value = block.get_block_value(fees) print("\n\nRunning Miner with %d transactions in block" % len(block.l_tx)) # Prebuild hash buffer class Unnamed1(serialize.Serializable): class Unnamed2(serialize.Serializable): def __init__(self): self.version = 0 self.hash_prev_block = 0 self.hash_merkle_root = 0 self.time = 0 self.bits = 0 self.nonce = 0 def serialize(self, nType=0, nVersion=cfg.VERSION): s = b'' s += serialize.ser_int(self.version) s += serialize.ser_uint256(self.hash_prev_block) s += serialize.ser_uint256(self.hash_merkle_root) s += serialize.ser_uint(self.time) s += serialize.ser_uint(self.bits) s += serialize.ser_uint(self.nonce) return s def __init__(self): self.block = Unnamed1.Unnamed2() self.padding0 = ['\x00'] * 64 self.hash1 = 0 self.padding1 = ['\x00'] * 64 tmp = Unnamed1() tmp.block.version = block.version tmp.block.hash_prev_block = block.hash_prev_block = ( index_prev.get_block_hash() if index_prev else 0) tmp.block.hash_merkle_root = block.hash_merkle_root = block.build_merkle_tree( ) tmp.block.time = block.time = max( (index_prev.get_median_time_past() + 1 if index_prev else 0), timeutil.get_adjusted_time()) tmp.block.bits = block.bits = bits # difficulty tmp.block.nonce = block.nonce = 1 # 从1 开始计算 # blocks0 = format_hash_blocks(tmp.block.serialize(), tmp.padding0) # blocks1 = format_hash_blocks(serialize.ser_uint256(tmp.hash1), tmp.padding1) # search start = timeutil.get_time() block_hash = 0 hash_target = BN.PyBigNum.set_compact(block.bits).get_uint256() while True: if t.exit: break # use local sha256 block_hash = cryptoutil.Hash(tmp.block.serialize()) if block_hash <= hash_target: block.nonce = tmp.block.nonce assert block_hash == block.get_hash() # debug print print("Miner:") print("proof-of-work found \n hash: %s \ntarget: %s\n" % (serialize.hexser_uint256(block_hash), serialize.hexser_uint256(hash_target))) print str(block) # TODO setthreadpriority THREAD_PRIORITY_NORMAL with ctx.mainLock: # save key kaction.add_key(key) key.make_new_key() # Process this block the same as if we had received it from another node if not blkaction.process_block(None, block): print( "ERROR in CoinMiner, ProcessBlock, block not accepted" ) else: print("miner a block, waiting for relay") # TODO ADD THREAD_PRIORITY_LOWEST timeutil.sleep_msec(500) break # Update nTime every few seconds tmp.block.nonce += 1 if tmp.block.nonce & 0x3FFFF == 0: # checkforshutdown if tmp.block.nonce == 0: break if id(index_prev) != id(ctx.indexBest): break if ctx.transactionsUpdated != transactions_updated_last and ( timeutil.get_time() - start > 60): break if not ctx.fGenerateCoins: break tmp.block.time = block.time = max( (index_prev.get_median_time_past() + 1), timeutil.get_adjusted_time()) pass # end nonce loop pass # end whole loop return True
def create_transaction(script_pubkey, value, wtx_new, fee_required=None): """ 根据指向自己的PyWalletTx的Out填充wtx_new的 PyTxIn, value指明转账费, 将会验证交易费,合法性,\n 并自动收集满足条件的交易, 并对 wtx_new 的 PyTxIn进行签名\n :param script_pubkey: 填充 wtx_new PyTxOut 的 pubkey_script :param value: 转账的数目 :param wtx_new: 被填充的交易 :type wtx_new: Block.PyWalletTx :return: None 或 需要支付的交易费 fee """ if fee_required is None: fee_required = list() if len(fee_required) == 0: fee_required.append(0) else: fee_required[0] = 0 with ctx.mainLock: with Tx.PyTxDB("r") as txdb: with ctx.dictWalletLock: # txdb = Tx.PyTxDB("r") fee = ctx.transactionFee # 全局配置的交易费 while True: del wtx_new.l_in[:] del wtx_new.l_out[:] if value < 0: return None value_out = value # 此时的value_out 代表真正想要转出的钱 value += fee # 此时 value 包含手续费 # Choose coins to use set_coins = select_coins(value) if set_coins is None: return None set_coins = tuple(set_coins) value_in = 0 # 获取自己能给出的全部钱总和 for coin in set_coins: # PyWalletTx value_in += coin.get_credit() # Fill vout[0] to the payee wtx_new.l_out.append(Tx.PyTxOut(value_out, script_pubkey)) # Fill vout[1] back to self with any change if value_in > value: # value 包含了手续费 # Use the same key as one of the coins tx_first = set_coins[0] pubkey = b'' for txout in tx_first.l_out: if txout.is_mine(): pubkey = Script.extract_pubkey(txout.script_pubkey, True) if pubkey is not None: break if len(pubkey) == 0: return None # Fill vout[1] to ourself my_script_pubkey = Script.PyScript() my_script_pubkey.extend(pubkey).append(Script.OpCodeType.OP_CHECKSIG) wtx_new.l_out.append(Tx.PyTxOut(value_in - value, my_script_pubkey)) # fill vin for coin in set_coins: for index, out in enumerate(coin.l_out): if out.is_mine(): wtx_new.l_in.append(Tx.PyTxIn(Tx.PyOutPoint(coin.get_hash(), index))) # no sign # Sign nin = 0 for coin in set_coins: for out in coin.l_out: if out.is_mine(): ret = Script.sign_signature(coin, wtx_new, nin) if ret is False: print ("sign failed for txin index: %d: to wtx_new: %s" % (nin, str(wtx_new))) return None nin += 1 # Check that enough fee is included real_fee = wtx_new.get_min_fee(True) # 如果交易费小于最小的交易费,那么就要调整并重新运算 if fee < real_fee: fee = real_fee fee_required[0] = fee continue wtx_new.add_supporting_transactions(txdb) wtx_new.time_received_is_tx_time = 1 # 该函数只会由生产tx的节点调用,这个属性的意义就代表的这个wtx是自己产生的还是别人 break return fee