def test_verify_with_change(): deposit_sats = 100000 input_sats = 100000 output_sats = deposit_sats + input_sats change_sats = 547 faucet.set_data_part(scryptlib.utils.get_push_int(1602553516)) context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = faucet.locking_script context.utxo.value = input_sats tx_out_0 = TxOutput(value=output_sats, script_pubkey=faucet.locking_script) context.tx.outputs.append(tx_out_0) tx_out_1 = TxOutput(value=change_sats, script_pubkey=P2PKH_Address(pkh, Bitcoin).to_script()) context.tx.outputs.append(tx_out_1) sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID) preimage = scryptlib.utils.get_preimage_from_input_context( context, sighash_flag) verify_result = faucet.deposit(SigHashPreimage(preimage), deposit_sats, Ripemd160(pkh), change_sats).verify(context) assert verify_result == True with pytest.raises(bitcoinx.VerifyFailed): faucet.deposit(SigHashPreimage(preimage), deposit_sats, Ripemd160(pkh), change_sats + 1).verify(context)
def test_verify_scenario_2(): context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = escrow.locking_script context.utxo.value = input_sats change_out = TxOutput(int(input_sats - fee), P2PKH_Address(pkh_A, Bitcoin).to_script()) context.tx.outputs.append(change_out) sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID) sighash = context.tx.signature_hash(0, input_sats, escrow.locking_script, sighash_flag) sig_A = key_priv_A.sign(sighash, hasher=None) sig_A = sig_A + pack_byte(sighash_flag) sig_E = key_priv_E.sign(sighash, hasher=None) sig_E = sig_E + pack_byte(sighash_flag) preimage = scryptlib.utils.get_preimage_from_input_context( context, sighash_flag) verify_result = escrow.unlock(SigHashPreimage(preimage), PubKey(key_pub_A), Sig(sig_A), PubKey(key_pub_E), Sig(sig_E), Bytes(secret0)).verify(context) assert verify_result == True # Wrong secret with pytest.raises(bitcoinx.VerifyFailed): verify_result = escrow.unlock(SigHashPreimage(preimage), PubKey(key_pub_A), Sig(sig_A), PubKey(key_pub_E), Sig(sig_E), Bytes(secret1)).verify(context)
def test_verify_withdraw(): withdraw_sats = 2000000 fee = 3000 input_sats = 10000000 output_sats = input_sats - withdraw_sats - fee mature_time = 1627122529 faucet.set_data_part(scryptlib.utils.get_push_int(mature_time)) context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = faucet.locking_script context.utxo.value = input_sats new_locking_script = faucet.code_part << Script( scryptlib.utils.get_push_int(mature_time + 300)) tx_out_0 = TxOutput(value=output_sats, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out_0) tx_out_1 = TxOutput(value=withdraw_sats, script_pubkey=P2PKH_Address(pkh, Bitcoin).to_script()) context.tx.outputs.append(tx_out_1) context.tx.inputs[0].sequence = 0xfffffffe context.tx.locktime = mature_time + 300 preimage = scryptlib.utils.get_preimage_from_input_context(context) verify_result = faucet.withdraw(SigHashPreimage(preimage), Ripemd160(pkh)).verify(context) assert verify_result == True # Wrong mature time context.tx.outputs = [] new_locking_script = faucet.code_part << Script( scryptlib.utils.get_push_int(mature_time + 299)) tx_out_0 = TxOutput(value=output_sats, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out_0) tx_out_1 = TxOutput(value=withdraw_sats, script_pubkey=P2PKH_Address(pkh, Bitcoin).to_script()) context.tx.outputs.append(tx_out_1) context.tx.locktime = mature_time + 299 preimage = scryptlib.utils.get_preimage_from_input_context(context) with pytest.raises(bitcoinx.VerifyFailed): faucet.withdraw(SigHashPreimage(preimage), Ripemd160(pkh)).verify(context)
def test_verify_correct(): # Intial state state = {'counter': 11, 'buf': b'\x12\x34', 'flag': True} counter.set_data_part(state) # Alter state state['counter'] += 1 state['buf'] += b'\xff\xff' state['flag'] = False serialized_state = scryptlib.serializer.serialize_state(state) new_locking_script = Script(counter.code_part.to_bytes() + serialized_state) # Deserialize state from new locking script new_state = scryptlib.serializer.deserialize_state(new_locking_script, state) assert new_state['counter'] == 12 assert new_state['buf'] == b'\x12\x34\xff\xff' assert new_state['flag'] == False context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = counter.locking_script tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out) preimage = scryptlib.utils.get_preimage_from_input_context(context) verfiy_result = counter.mutate(SigHashPreimage(preimage), out_sats).verify(context) assert verfiy_result == True
def sale(n_bought, pkh, pub_key): context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = ats.locking_script context.utxo.value = input_sats new_data_part = ats.data_part << pub_key.to_bytes( ) + scryptlib.utils.get_push_int(n_bought)[1:] new_locking_script = Script(ats.code_part.to_bytes() + new_data_part.to_bytes()) change_sats = input_sats - n_bought * SATS_PER_TOKEN out_sats = input_sats + n_bought * SATS_PER_TOKEN # Counter output tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out) # Change output change_out = TxOutput( change_sats, P2PKH_Address(pub_key.hash160(), Bitcoin).to_script()) context.tx.outputs.append(change_out) preimage = scryptlib.utils.get_preimage_from_input_context( context, sighash_flag) verify_result = ats.buy(SigHashPreimage(preimage), Ripemd160(pkh), change_sats, Bytes(pub_key.to_bytes()), n_bought).verify(context) assert verify_result == True return new_data_part
def test_issue(priv_key, receiver, new_issuer=issuer, next_tok_id=curr_token_id + 1, issued_tok_id=curr_token_id): context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = token.locking_script context.utxo.value = input_sats new_data_part = b'\x23' + scryptlib.utils.get_push_int(next_tok_id)[1:] + \ new_issuer.to_bytes() + action_issue new_locking_script = Script(token.code_part.to_bytes() + new_data_part) tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out) new_data_part = b'\x23' + scryptlib.utils.get_push_int(issued_tok_id)[1:] + \ receiver.to_bytes() + action_transfer new_locking_script = Script(token.code_part.to_bytes() + new_data_part) tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out) sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID) sighash = context.tx.signature_hash(0, input_sats, token.locking_script, sighash_flag) sig = priv_key.sign(sighash, hasher=None) sig = sig + pack_byte(sighash_flag) preimage = scryptlib.utils.get_preimage_from_input_context( context, sighash_flag) return token.issue(Sig(sig), PubKey(receiver), out_sats, out_sats, SigHashPreimage(preimage)).verify(context)
def test_finish(key_priv, pkh_B, action_A, action_B, total_sats, input_sats, out_sats, change_sats): rps.set_data_part(player_A_data + pkh_B + scryptlib.utils.get_push_int(action_B)[1:]) context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = rps.locking_script context.utxo.value = total_sats change_out = TxOutput(change_sats, P2PKH_Address(pkh_A, Bitcoin).to_script()) context.tx.outputs.append(change_out) if out_sats > 0: pay_out = TxOutput(out_sats, P2PKH_Address(pkh_B, Bitcoin).to_script()) context.tx.outputs.append(pay_out) preimage = scryptlib.utils.get_preimage_from_input_context( context, sighash_flag) input_idx = 0 utxo_satoshis = context.utxo.value sighash = context.tx.signature_hash(input_idx, utxo_satoshis, rps.locking_script, sighash_flag) sig = key_priv.sign(sighash, hasher=None) sig = sig + pack_byte(sighash_flag) return rps.finish(SigHashPreimage(preimage), action_A, Sig(sig), PubKey(key_pub_A), change_sats).verify(context)
def test_verify_correct(): verify_result = token.transfer(PubKey(key_pub_0), Sig(sig), PubKey(key_pub_1), 40, SigHashPreimage(preimage), 222222).verify(context) assert verify_result == True
def test_verify_wrong_out_amount(): pkh_0_out_wrong = TxOutput(in_sats - miner_fee + 123, P2PKH_Address(pkh_0, Bitcoin).to_script()) context = create_input_context(in_sats, acs.locking_script, pkh_0_out_wrong) preimage = scryptlib.utils.get_preimage_from_input_context( context, sighash_flag) verify_result = acs.unlock(SigHashPreimage(preimage)).verify(context) assert verify_result == False
def increment_counter(counter_obj, prev_txid, prev_out_idx, funding_txid, funding_out_idx, unlock_key_priv, miner_fee): # Get data from previous counter tx r = requests.get('https://api.whatsonchain.com/v1/bsv/main/tx/{}'.format( prev_txid)).json() prev_locking_script = Script.from_hex( r['vout'][prev_out_idx]['scriptPubKey']['hex']) prev_counter_bytes = list(prev_locking_script.ops())[-1] prev_counter_val = int.from_bytes(prev_counter_bytes, 'little') unlocked_satoshis_counter = int(r['vout'][prev_out_idx]['value'] * 10**8) # Get data from funding tx r = requests.get('https://api.whatsonchain.com/v1/bsv/main/tx/{}'.format( funding_txid)).json() funding_locking_script = Script.from_hex( r['vout'][funding_out_idx]['scriptPubKey']['hex']) unlocked_satoshis_funding = int(r['vout'][funding_out_idx]['value'] * 10**8) # Set data for next iteration counter_obj.set_data_part( scryptlib.utils.get_push_int(prev_counter_val + 1)) ## Construct tx n_sequence = 0xffffffff # Counter input and output prev_tx_hash = hex_str_to_hash(prev_txid) counter_in = TxInput(prev_tx_hash, prev_out_idx, None, n_sequence) out_satoshis = unlocked_satoshis_counter + unlocked_satoshis_funding - miner_fee contract_out = TxOutput(out_satoshis, counter_obj.locking_script) # Funding input funding_tx_hash = hex_str_to_hash(funding_txid) funding_in = TxInput(funding_tx_hash, funding_out_idx, None, n_sequence) tx = Tx(2, [counter_in, funding_in], [contract_out], 0x00000000) # Set input script to unlock previous counter sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID) preimage = scryptlib.utils.get_preimage(tx, 0, unlocked_satoshis_counter, prev_locking_script, sighash_flag) increment_func_call = counter_obj.increment(SigHashPreimage(preimage), Int(out_satoshis)) tx.inputs[0].script_sig = increment_func_call.script # Set input script to unlock funding output unlock_key_pub = unlock_key_priv.public_key sighash = tx.signature_hash(1, unlocked_satoshis_funding, funding_locking_script, sighash_flag) sig = unlock_key_priv.sign(sighash, hasher=None) sig = sig + pack_byte(sighash_flag) unlock_script = Script() << sig << unlock_key_pub.to_bytes() tx.inputs[1].script_sig = unlock_script broadcast_tx(tx)
def test_verify_not_first_call(): token.first_call = False with pytest.raises(bitcoinx.errors.NullFailError): token.transfer(PubKey(key_pub_0), Sig(sig), PubKey(key_pub_1), 40, SigHashPreimage(preimage), 222222).verify(context)
def test_verify_wrong_val_2(): token.first_call = True verify_result = token.transfer(PubKey(key_pub_0), Sig(sig), PubKey(key_pub_1), 43, SigHashPreimage(preimage), 222222).verify(context) assert verify_result == False
def test_verify_wrong_addr(): key_priv = PrivateKey.from_arbitrary_bytes(b'123test') key_pub = key_priv.public_key pkh = key_pub.hash160() pkh_0_out_wrong = TxOutput(in_sats - miner_fee, P2PKH_Address(pkh, Bitcoin).to_script()) context = create_input_context(in_sats, acs.locking_script, pkh_0_out_wrong) preimage = scryptlib.utils.get_preimage_from_input_context( context, sighash_flag) verify_result = acs.unlock(SigHashPreimage(preimage)).verify(context) assert verify_result == False
def test_verify_correct(): context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = p2sh.locking_script context.utxo.value = input_sats tx_out = TxOutput(value=input_sats, script_pubkey=demo_contract.code_part) context.tx.outputs.append(tx_out) preimage = scryptlib.utils.get_preimage_from_input_context(context) verify_result = p2sh.redeem(Bytes(demo_contract.code_part.to_bytes()), SigHashPreimage(preimage)).verify(context) assert verify_result == True
def test_verify_wrong_output(): context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = gol.locking_script new_locking_script = Script(gol.code_part.to_bytes() + wb1) tx_out = TxOutput(value=out_amount, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out) sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID) preimage = scryptlib.utils.get_preimage_from_input_context(context, sighash_flag) verify_result = gol.play(out_amount, SigHashPreimage(preimage)).verify(context) assert verify_result == False
def test_merge(input_idx, balance0, balance1): context = scryptlib.utils.create_dummy_input_context() context.utxo.value = in_sats context.input_index = input_idx tx_in = TxInput(context.tx.inputs[0].prev_hash, 1, Script(), 0xffffffff) context.tx.inputs.append(tx_in) prev_txid = context.tx.inputs[0].prev_hash prevouts = prev_txid + b'\x00\x00\x00\x00' + prev_txid + b'\x01\x00\x00\x00' new_locking_script = Script(token.code_part.to_bytes() + b'\x23' + key_pub_2.to_bytes() + scryptlib.utils.get_push_int(balance0)[1:] + scryptlib.utils.get_push_int(balance1)[1:]) tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out) if input_idx == 0: balance = balance1 context.utxo.script_pubkey = locking_script_0 key_to_sign = key_priv_0 token.set_data_part(b'\x23' + data_part_0) else: balance = balance0 context.utxo.script_pubkey = locking_script_1 key_to_sign = key_priv_1 token.set_data_part(b'\x23' + data_part_1) sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID) #preimage = scryptlib.utils.get_preimage_from_input_context(context, sighash_flag) if input_idx == 0: preimage = scryptlib.utils.get_preimage(context.tx, input_idx, in_sats, locking_script_0, sighash_flag=sighash_flag) else: preimage = scryptlib.utils.get_preimage(context.tx, input_idx, in_sats, locking_script_1, sighash_flag=sighash_flag) if input_idx == 0: sighash = context.tx.signature_hash(input_idx, in_sats, locking_script_0, sighash_flag) else: sighash = context.tx.signature_hash(input_idx, in_sats, locking_script_1, sighash_flag) sig = key_to_sign.sign(sighash, hasher=None) sig = sig + pack_byte(sighash_flag) return token.merge( Sig(sig), PubKey(key_pub_2), Bytes(prevouts), balance, out_sats, SigHashPreimage(preimage) ).verify(context)
def test_verify_wrong_nextval(): subsequent_counter_val_bytes = scryptlib.utils.get_push_int( COUNTER_INITIAL_VAL + 2) new_locking_script = counter.code_part << Script( subsequent_counter_val_bytes) tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script) context.tx.outputs[0] = tx_out preimage = scryptlib.utils.get_preimage_from_input_context( context, sighash_flag) verify_result = counter.increment(SigHashPreimage(preimage), out_sats, Ripemd160(pkh_0), change_sats - 1).verify(context) assert verify_result == False
def test_verify_incorrect_sat_amount(): context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = counter_obj.locking_script subsequent_counter_val_bytes = scryptlib.utils.get_push_int(COUNTER_INITIAL_VAL + 1) new_locking_script = counter_obj.code_part << Script(subsequent_counter_val_bytes) tx_out = TxOutput(value=0, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out) sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID) preimage = scryptlib.utils.get_preimage_from_input_context(context, sighash_flag) new_output_satoshis = 100 verify_result = counter_obj.increment(SigHashPreimage(preimage), Int(new_output_satoshis)).verify(context) assert verify_result == False
def test_verify_correct_constructor(): context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = counter_obj.locking_script new_locking_script = counter_obj.get_state_script( {"counter": COUNTER_INITIAL_VAL + 1}) tx_out = TxOutput(value=0, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out) sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID) preimage = scryptlib.utils.get_preimage_from_input_context( context, sighash_flag) new_output_satoshis = 0 verify_result = counter_obj.unlock( SigHashPreimage(preimage), Int(new_output_satoshis)).verify(context) assert verify_result == True
def test_split(key_priv, balance0, balance1, balance_input0=None, balance_input1=None): if not balance_input0: balance_input0 = balance0 if not balance_input1: balance_input1 = balance1 context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = token.locking_script context.utxo.value = in_sats new_locking_script = Script(token.code_part.to_bytes() + b'\x23' + key_pub_1.to_bytes() + b'\x00' + scryptlib.utils.get_push_int(balance0)[1:]) tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out) if balance1 > 0: new_locking_script = Script(token.code_part.to_bytes() + b'\x23' + key_pub_2.to_bytes() + b'\x00' + scryptlib.utils.get_push_int(balance1)[1:]) tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out) sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID) preimage = scryptlib.utils.get_preimage_from_input_context(context, sighash_flag) input_idx = 0 utxo_satoshis = context.utxo.value sighash = context.tx.signature_hash(input_idx, utxo_satoshis, token.locking_script, sighash_flag) sig = key_priv.sign(sighash, hasher=None) sig = sig + pack_byte(sighash_flag) return token.split( Sig(sig), PubKey(key_pub_1), balance_input0, out_sats, PubKey(key_pub_2), balance_input1, out_sats, SigHashPreimage(preimage) ).verify(context)
def test_follow(pkh_B, action, init_sats, input_sats, out_sats, change_sats): rps.set_data_part(player_A_data + b'\x00' * pub_key_hashlen + scryptlib.utils.get_push_int(action_INIT)[1:]) context = scryptlib.utils.create_dummy_input_context() context.utxo.script_pubkey = rps.locking_script context.utxo.value = init_sats new_data_part = player_A_data + pkh_B + scryptlib.utils.get_push_int( action)[1:] new_locking_script = Script(rps.code_part.to_bytes() + new_data_part) tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script) context.tx.outputs.append(tx_out) change_out = TxOutput(change_sats, P2PKH_Address(pkh_B, Bitcoin).to_script()) context.tx.outputs.append(change_out) preimage = scryptlib.utils.get_preimage_from_input_context( context, sighash_flag) return rps.follow(SigHashPreimage(preimage), action, Ripemd160(pkh_B), change_sats).verify(context)
def test_verify_correct(): verify_result = counter.increment(SigHashPreimage(preimage), out_sats, Ripemd160(pkh_0), change_sats).verify(context) assert verify_result == True
def test_verify_correct(): verify_result = clone.unlock(SigHashPreimage(preimage)).verify(context) assert verify_result == True
def test_verify_wrong_sats2(): verify_result = counter.increment(SigHashPreimage(preimage), out_sats, Ripemd160(pkh_0), change_sats - 1).verify(context) assert verify_result == False
def test_verify_correct(): preimage = get_preimage_after_purchase(key_pub) verify_result = token_sale.buy(PubKey(key_pub), n_tokens, SigHashPreimage(preimage)).verify(context) assert verify_result == True