Esempio n. 1
0
class Blockchain:
    def __init__(self):
        self.proxy = Proxy('http://*****:*****@blockchain.infnote.com:8962')

    @staticmethod
    def deserialize_transaction(raw_tx):
        return CTransaction.deserialize(unhexlify(raw_tx.encode('utf8')))

    def decode_transaction(self, tx):
        contents = []
        for out in tx.vout:
            if out.nValue > 0:
                continue
            data = self.get_data_from_vout(out)
            if data:
                contents.append(data)
        return contents

    def send_transaction(self, raw_tx):
        transaction = self.deserialize_transaction(raw_tx)
        txid = self.proxy.sendrawtransaction(transaction)
        return txid

    @staticmethod
    def get_data_from_vout(vout):
        i = iter(vout.scriptPubKey)
        flag = next(i)
        # TODO: 需要区分类型,以填充至不同的模型
        if flag == script.OP_RETURN or flag == script.OP_NOP8:
            data = next(i).decode('utf8')
            return json.loads(data)
        return None

    def get_transaction(self, txid):
        return self.proxy.getrawtransaction(txid)

    def get_block_count(self):
        return self.proxy.getblockcount()

    def get_block_by_height(self, height: int):
        return self.proxy.getblock(self.proxy.getblockhash(height))

    def server_unspent(self):
        return self.proxy.listunspent()

    @staticmethod
    def freeze_coins_in_tx(tx: CTransaction):
        for vin in tx.vin:
            coin = Coin.objects.get(txid=b2lx(vin.prevout.hash),
                                    vout=vin.prevout.n)
            coin.frozen = True
            coin.save()

    def send_coin_to(self, address, coin: Coin):
        txin = CMutableTxIn(COutPoint(lx(coin.txid), coin.vout))
        txout = CMutableTxOut(coin.value - 1e5,
                              CBitcoinAddress(address).to_scriptPubKey())
        tx = CMutableTransaction([txin], [txout])
        tx = self.proxy.signrawtransaction(tx)['tx']

        # sig_hash = SignatureHash(txin_script_pubkey, tx, 0, SIGHASH_ALL)
        # sig = seckey.sign(sig_hash) + bytes([SIGHASH_ALL])
        # txin.scriptSig = CScript([sig, seckey.pub])
        # VerifyScript(txin.scriptSig, txin_script_pubkey, tx, 0, (SCRIPT_VERIFY_P2SH,))
        # print(b2x(tx.serialize()))

        self.proxy.sendrawtransaction(tx)
        coin.frozen = True
        coin.save()
Esempio n. 2
0
def issue_op_return(conf, op_return_bstring):
    print('\nConfigured values are:\n')
    print('working_directory:\t{}'.format(conf.working_directory))
    print('issuing_address:\t{}'.format(conf.issuing_address))
    print('full_node_url:\t\t{}'.format(conf.full_node_url))
    print('full_node_rpc_user:\t{}'.format(conf.full_node_rpc_user))
    print('testnet:\t\t{}'.format(conf.testnet))
    print('tx_fee_per_byte:\t{}'.format(conf.tx_fee_per_byte))
    print('Bytes for OP_RETURN:\n{}'.format(op_return_bstring))
    print('Hex for OP_RETURN:\n{}'.format(binascii.hexlify(op_return_bstring)))

    op_return_cert_protocol = op_return_bstring

    consent = input('Do you want to continue? [y/N]: ').lower() in ('y', 'yes')
    if not consent:
        sys.exit()

    full_node_rpc_password = getpass.getpass(
        '\nPlease enter the password for the node\'s RPC user: '******'testnet')
    else:
        SelectParams('mainnet')

    proxy = Proxy("http://{0}:{1}@{2}".format(conf.full_node_rpc_user,
                                              full_node_rpc_password,
                                              conf.full_node_url))

    # create transaction
    tx_outputs = []
    unspent = sorted(proxy.listunspent(1, 9999999, [conf.issuing_address]),
                     key=lambda x: hash(x['amount']),
                     reverse=True)

    issuing_pubkey = proxy.validateaddress(conf.issuing_address)['pubkey']

    tx_inputs = [CMutableTxIn(unspent[0]['outpoint'])]
    input_amount = unspent[0]['amount']

    change_script_out = CBitcoinAddress(conf.issuing_address).to_scriptPubKey()
    change_output = CMutableTxOut(input_amount, change_script_out)

    op_return_output = CMutableTxOut(
        0, CScript([OP_RETURN, op_return_cert_protocol]))
    tx_outputs = [change_output, op_return_output]

    tx = CMutableTransaction(tx_inputs, tx_outputs)

    # sign transaction to get its size
    r = proxy.signrawtransaction(tx)
    assert r['complete']
    signed_tx = r['tx']
    signed_tx_size = len(signed_tx.serialize())

    # calculate fees and change
    tx_fee = signed_tx_size * conf.tx_fee_per_byte
    change_amount = input_amount - tx_fee

    if (change_amount < 0):
        sys.exit(
            "Specified address cannot cover the transaction fee of: {} satoshis"
            .format(tx_fee))

    # update tx out for change and re-sign
    tx.vout[0].nValue = change_amount
    r = proxy.signrawtransaction(tx)
    assert r['complete']
    signed_tx = r['tx']

    # send transaction
    print('The fee will be {} satoshis.\n'.format(tx_fee))
    consent = input(
        'Do you want to issue on the blockchain? [y/N]: ').lower() in ('y',
                                                                       'yes')
    if not consent:
        sys.exit()

    tx_id = b2lx(proxy.sendrawtransaction(signed_tx))
    return tx_id