示例#1
0
def open_tx(committer, secret, commit_tx_hash):
    # 创建输入脚本
    p2pkh_solver = P2pkhSolver(committer.privk)
    hasklock_solver = HashlockSolver(secret.encode(), p2pkh_solver)
    if_solver = IfElseSolver(
        Branch.IF,  # branch selection
        hasklock_solver)
    # 创建输出脚本
    script = P2pkhScript(committer.pubk)

    # 获取commit交易
    to_spend_raw = get_raw_tx(commit_tx_hash, coin_symbol)
    to_spend = TransactionFactory.unhexlify(to_spend_raw)

    # 获取罚金数额
    penalty = int(float(to_spend.to_json()['vout'][0]['value']) * (10**8))

    # 估算挖矿费用
    print('estimating mining fee...')
    mining_fee_per_kb = get_mining_fee_per_kb(coin_symbol,
                                              committer.api_key,
                                              condidence='high')
    estimated_tx_size = cal_tx_size_in_byte(inputs_num=1, outputs_num=1)
    mining_fee = int(mining_fee_per_kb * (estimated_tx_size / 1000)) * 2

    # 创建交易
    unsigned = MutableTransaction(version=2,
                                  ins=[
                                      TxIn(txid=to_spend.txid,
                                           txout=0,
                                           script_sig=ScriptSig.empty(),
                                           sequence=Sequence.max())
                                  ],
                                  outs=[
                                      TxOut(value=penalty - mining_fee,
                                            n=0,
                                            script_pubkey=script),
                                  ],
                                  locktime=Locktime(0))

    # 修改交易
    signed = unsigned.spend([to_spend.outs[0]], [if_solver])

    # 广播交易
    print('open_tx_hex: ', signed.hexlify())
    msg = pushtx(coin_symbol=coin_symbol,
                 api_key=committer.api_key,
                 tx_hex=signed.hexlify())
    format_output(msg)

    return msg['tx']['hash']
示例#2
0
def get_secret(open_tx_hash):
    # 获取Open交易
    raw_open_tx = get_raw_tx(open_tx_hash, coin_symbol)
    open_tx_raw = TransactionFactory.unhexlify(
        raw_open_tx)  # decode raw transaction
    open_tx_json = open_tx_raw.to_json()

    # 获取输入脚本
    scriptSig = open_tx_json['vin'][0]['scriptSig']['asm']

    # 将输入脚本按空格分割
    scriptSig_list = scriptSig.split()

    # 如无意外,秘密应该在脚本的倒数第二个位置
    secret_hex = scriptSig_list[-2]

    # 从hex将秘密解码出来
    print('secret hex: ', secret_hex)
    print('decoded secret: ', bytes.fromhex(secret_hex).decode())
示例#3
0
# 估算挖矿费用
print('estimating mining fee...')
mining_fee_per_kb = get_mining_fee_per_kb(coin_symbol,
                                          api_key,
                                          condidence='high')
estimated_tx_size = cal_tx_size_in_byte(inputs_num=1, outputs_num=2)
mining_fee = int(mining_fee_per_kb * (estimated_tx_size / 1000)) * 2

# 设置罚金
penalty = 100000
assert penalty + mining_fee <= balance, 'committer账户余额不足'

# 创建交易
to_spend_raw = get_raw_tx(to_spend_hash, coin_symbol)
to_spend = TransactionFactory.unhexlify(to_spend_raw)

unsigned = MutableTransaction(version=2,
                              ins=[
                                  TxIn(txid=to_spend.txid,
                                       txout=0,
                                       script_sig=ScriptSig.empty(),
                                       sequence=Sequence.max())
                              ],
                              outs=[
                                  TxOut(value=penalty,
                                        n=0,
                                        script_pubkey=lock_time_script),
                                  TxOut(value=balance - penalty - mining_fee,
                                        n=1,
                                        script_pubkey=change_script)
示例#4
0
from utils import *
from btcpy.setup import setup
from btcpy.structs.transaction import TransactionFactory

# global
setup('testnet', strict=True)
coin_symbol = 'btc-testnet'

# 获取Open交易
open_tx_hash = '61fe8f28851536c3778b90ba58d649751e5b088af26069992fe52faca0239828'  # open交易的hash
raw_open_tx = get_raw_tx(open_tx_hash, coin_symbol)
open_tx = TransactionFactory.unhexlify(raw_open_tx)  # decode raw transaction
open_tx = open_tx.to_json()

# 获取输入脚本
scriptSig = open_tx['vin'][0]['scriptSig']['asm']

# 将输入脚本按空格分割
scriptSig_list = scriptSig.split()

# 如无意外,秘密应该在脚本的倒数第二个位置
secret_hex = scriptSig_list[-2]

# 从hex将秘密解码出来
print('secret hex: ', secret_hex)
print('decoded secret: ', bytes.fromhex(secret_hex).decode())
示例#5
0
    def test_all(self):
        global keys
        priv = ExtendedPrivateKey.decode(keys[0][1]).key
        pk = priv.pub()
        addr_string = str(pk.to_address())
        utxo = []

        for i in range(3):
            # create 3 tx to add to UTXO
            txid = regtest.send_rpc_cmd(['sendtoaddress', addr_string, '100'],
                                        0)
            to_spend = TransactionFactory.unhexlify(
                regtest.send_rpc_cmd(['getrawtransaction', txid, '0'], 0))
            txout = None
            for out in to_spend.outs:
                if str(out.script_pubkey.address()) == addr_string:
                    txout = out
                    break
            assert txout is not None

            utxo.append({
                'txid': txid,
                'txout': txout,
                'solver': P2pkhSolver(priv),
                'next_seq': Sequence.max(),
                'next_locktime': Locktime(0)
            })

        regtest.send_rpc_cmd(['generate', '100'], 0)

        generate = False

        i = 0
        while i < len(self.all) - 2:
            # print('{:04d}\r'.format(i), end='', flush=True)
            ins = [
                MutableTxIn(unspent['txid'], unspent['txout'].n,
                            ScriptSig.empty(), unspent['next_seq'])
                for unspent in utxo
            ]
            outs = []
            prev_types = []

            for j, (unspent, script) in enumerate(zip(utxo,
                                                      self.all[i:i + 3])):
                outs.append(
                    TxOut(unspent['txout'].value - 1000000, j, script[0]))
                prev_types.append(script[2])
                print('Spending `{}`, sighashes: {}'.format(
                    get_type(unspent['solver']), ', '.join([
                        str(sh) for sh in unspent['solver'].get_sighashes()
                    ])))

            tx = MutableTransaction(2, ins, outs, Locktime(0))
            mutable = copy.deepcopy(tx)
            tx = tx.spend([unspent['txout'] for unspent in utxo],
                          [unspent['solver'] for unspent in utxo])
            # print(json.dumps({'signed': tx.to_json()}))

            # print('====================')
            # print('txid: {}'.format(tx.txid))
            # print()
            # print(tx)
            # print()
            # print('raw: {}'.format(tx.hexlify()))
            # print('prev_scripts, amounts, solvers:')
            # print('TX: {}'.format(i))
            regtest.send_rpc_cmd(['sendrawtransaction', tx.hexlify()], 0)

            # print('Mempool size: {}'.format(len(regtest.send_rpc_cmd(['getrawmempool'], 0))))

            if cmdline_args.dumpfile is not None:
                with open(cmdline_args.dumpfile, 'a') as out:
                    for j, unspent in enumerate(utxo):
                        json.dump(
                            self.json_dump(unspent, tx.ins[j], j,
                                           copy.deepcopy(mutable).to_segwit()),
                            out)
                        out.write('\n')

            utxo = []

            for j, (output, prev_type) in enumerate(zip(tx.outs, prev_types)):

                if 'relativetime' in prev_type:
                    generate = True

                utxo.append({
                    'txid': tx.txid,
                    'txout': output,
                    'solver': self.all[i + j][1][0],  # solver
                    'next_seq': Sequence.max(),
                    'next_locktime': Locktime(0)
                })
            if generate:
                regtest.send_rpc_cmd(['generate', '4'], 0)
                generate = False

            if not i % 10:
                # print('generating 2')
                regtest.send_rpc_cmd(['generate', '2'], 0)

            i += 1

        ins = [
            MutableTxIn(unspent['txid'], unspent['txout'].n, ScriptSig.empty(),
                        unspent['next_seq']) for unspent in utxo
        ]

        tx = MutableTransaction(
            2, ins, [
                TxOut(
                    sum(unspent['txout'].value for unspent in utxo) - 1000000,
                    0, self.final['script'])
            ], min_locktime(unspent['next_locktime'] for unspent in utxo))

        tx = tx.spend([unspent['txout'] for unspent in utxo],
                      [unspent['solver'] for unspent in utxo])

        # print('====================')
        # print('txid: {}'.format(tx.txid))
        # print()
        # print(tx)
        # print()
        # print('raw: {}'.format(tx.hexlify()))
        # print('prev_scripts, amounts, solvers:')
        # for unspent in utxo:
        #     print(unspent['txout'].script_pubkey, unspent['txout'].value, unspent['solver'].__class__.__name__)
        regtest.send_rpc_cmd(['sendrawtransaction', tx.hexlify()], 0)

        regtest.teardown()
示例#6
0
def commit_tx(committer, receiver, secret, type, lock_time, penalty):
    if type not in ['Timed', 'Height']:
        raise ValueError("type should be 'Timed' or 'Height'")

    secret_hash = hashlib.sha256(hashlib.sha256(
        secret.encode()).digest()).digest()
    secret_hash = StackData.from_bytes(secret_hash)
    print("秘密经hash256加密结果:", secret_hash)

    # 创建输出脚本
    if type is 'Height':

        # Relative - HeightBased
        sequence = lock_time
        lock_time_script = IfElseScript(
            # if branch
            Hashlock256Script(secret_hash, P2pkhScript(committer.pubk)),
            # else branch
            RelativeTimelockScript(  # timelocked script
                HeightBasedSequence(sequence),  # expiration
                P2pkhScript(receiver.pubk)))
    else:
        # Relative - TimedBased
        time_delta = datetime.timedelta(minutes=lock_time)
        time_now = datetime.datetime.now()
        print("current time: ", time_now.strftime("%y-%m-%d %H:%M:%S"))
        print("pay deposit time: ",
              (time_now + time_delta).strftime("%y-%m-%d %H:%M:%S"))

        lock_time_script = IfElseScript(
            # if branch
            Hashlock256Script(secret_hash, P2pkhScript(committer.pubk)),
            # else branch
            RelativeTimelockScript(  # timelocked script
                TimeBasedSequence.from_timedelta(time_delta),  # expiration
                P2pkhScript(receiver.pubk)))

    # 找零脚本
    change_script = P2pkhScript(committer.pubk)

    # 清理资产
    print("sweeping fund...")
    to_spend_hash, balance = sweep_fund(privkey=str(committer.privk),
                                        address=str(committer.address),
                                        coin_symbol=coin_symbol,
                                        api_key=committer.api_key)

    # 估算挖矿费用
    print('estimating mining fee...')
    mining_fee_per_kb = get_mining_fee_per_kb(coin_symbol,
                                              committer.api_key,
                                              condidence='high')
    estimated_tx_size = cal_tx_size_in_byte(inputs_num=1, outputs_num=2)
    mining_fee = int(mining_fee_per_kb * (estimated_tx_size / 1000)) * 2

    # 设置罚金
    assert penalty + mining_fee <= balance, 'committer账户余额不足'

    # 创建交易
    to_spend_raw = get_raw_tx(to_spend_hash, coin_symbol)
    to_spend = TransactionFactory.unhexlify(to_spend_raw)

    unsigned = MutableTransaction(version=2,
                                  ins=[
                                      TxIn(txid=to_spend.txid,
                                           txout=0,
                                           script_sig=ScriptSig.empty(),
                                           sequence=Sequence.max())
                                  ],
                                  outs=[
                                      TxOut(value=penalty,
                                            n=0,
                                            script_pubkey=lock_time_script),
                                      TxOut(value=balance - penalty -
                                            mining_fee,
                                            n=1,
                                            script_pubkey=change_script)
                                  ],
                                  locktime=Locktime(0))

    # 输入脚本
    solver = P2pkhSolver(committer.privk)

    # 修改交易
    signed = unsigned.spend([to_spend.outs[0]], [solver])
    print('commit_tx_hex: ', signed.hexlify())

    # 发送交易
    tx = pushtx(coin_symbol=coin_symbol,
                api_key=committer.api_key,
                tx_hex=signed.hexlify())
    format_output(tx)
    return tx['tx']['hash']