def test_sign_tx_invalid_multisig_already_fully_signed(self): key1 = PrivateKey(WALLET_FORMAT_TEST_1) key2 = PrivateKey(WALLET_FORMAT_TEST_2) multi = MultiSig(key1, [key1.public_key, key2.public_key], 2) txobj = deserialize(FINAL_TX_BATCH) with pytest.raises(ValueError): sign_tx(multi, txobj, unspents=[UNSPENTS_BATCH[0]])
def test_scriptcode(self): key1 = PrivateKey() key2 = PrivateKey() multisig = MultiSig(key1, [key1.public_key, key2.public_key], 2) assert multisig.scriptcode == multisig.redeemscript assert multisig.segwit_scriptcode == (b'\x00' + b'\x20' + sha256(multisig.redeemscript))
def test_sign_tx_multisig(self): key1 = PrivateKey(WALLET_FORMAT_TEST_1) key2 = PrivateKey(WALLET_FORMAT_TEST_2) multi = MultiSig(key1, [key1.public_key, key2.public_key], 2) txobj = deserialize(UNSIGNED_TX_BATCH) tx = sign_tx(multi, txobj, unspents=[UNSPENTS_BATCH[0]]) assert tx[:238] == FINAL_TX_BATCH[:238]
def test_init_default(self): key1 = PrivateKey() key2 = PrivateKey() multisig = MultiSig(key1, [key1.public_key, key2.public_key], 2) assert multisig._address is None assert multisig.balance == 0 assert multisig.unspents == [] assert multisig.transactions == [] assert multisig.m == 2
def test_can_sign_unspent(self): key1 = PrivateKey(WALLET_FORMAT_MAIN_1) key2 = PrivateKey(WALLET_FORMAT_MAIN_2) multisig = MultiSig(key1, [key1.public_key, key2.public_key], 2) assert multisig.can_sign_unspent(UNSPENTS[3]) assert multisig.can_sign_unspent(UNSPENTS[4]) # Non-segwit multisig: key1 = PrivateKey(WALLET_FORMAT_MAIN) key2 = PrivateKey(WALLET_FORMAT_MAIN_1) multisig = MultiSig(key1, [key1.public_key, key2.public_key], 2) assert multisig.can_sign_unspent(UNSPENTS[7])
def test_invalid_init(self): key1 = PrivateKey() key2 = PrivateKey() with pytest.raises(TypeError): MultiSig(PrivateKeyTestnet(), [key1.public_key, key2.public_key], 2) with pytest.raises(ValueError): MultiSig(PrivateKey(), [key1.public_key, key2.public_key], 2) with pytest.raises(TypeError): # Public keys must be provided in list or set MultiSig(key1, (key1.public_key, key2.public_key), 1)
def test_lexicographical_ordering_pubkeys(self): key1 = PrivateKey(WALLET_FORMAT_MAIN_1) key2 = PrivateKey(WALLET_FORMAT_MAIN_2) multisig = MultiSig(key1, [key2.public_key, key1.public_key], 2) assert multisig.public_keys == [key2.public_key, key1.public_key] multisig = MultiSig(key1, [key1.public_key, key2.public_key], 2) assert multisig.public_keys == [key1.public_key, key2.public_key] multisig = MultiSig(key1, {key2.public_key, key1.public_key}, 2) assert multisig.public_keys == [key2.public_key, key1.public_key] multisig = MultiSig(key1, {key1.public_key, key2.public_key}, 2) assert multisig.public_keys == [key2.public_key, key1.public_key]
def test_sign_tx_invalid_segwit_no_amount(self): key = PrivateKey(WALLET_FORMAT_TEST_1) txobj = deserialize(UNSIGNED_TX_SEGWIT) unspents = copy.deepcopy(UNSPENTS_SEGWIT) unspents[1].amount = None with pytest.raises(ValueError): sign_tx(key, txobj, unspents=unspents)
def test_init_default(self): private_key = PrivateKey() assert private_key._address is None assert private_key.balance == 0 assert private_key.unspents == [] assert private_key.transactions == []
def test_can_sign_unspent(self): private_key = PrivateKey(WALLET_FORMAT_MAIN) assert private_key.can_sign_unspent(UNSPENTS[0]) assert not private_key.can_sign_unspent(UNSPENTS[1]) private_key = PrivateKey(WALLET_FORMAT_COMPRESSED_MAIN) assert private_key.can_sign_unspent(UNSPENTS[1]) assert private_key.can_sign_unspent(UNSPENTS[2])
def test_get_transactions(self): private_key = PrivateKey(WALLET_FORMAT_MAIN) transactions = private_key.get_transactions() assert transactions == private_key.transactions private_key = PrivateKey(WALLET_FORMAT_COMPRESSED_MAIN) transactions = private_key.get_transactions() assert transactions == private_key.transactions
def test_get_unspent(self): private_key = PrivateKey(WALLET_FORMAT_MAIN) unspent = private_key.get_unspents() assert unspent == private_key.unspents private_key = PrivateKey(WALLET_FORMAT_COMPRESSED_MAIN) unspent = private_key.get_unspents() assert unspent == private_key.unspents
def test_opt_in_for_RBF(self): # test based on tx 4162a41175658e76ae5d22f02739932c9997caaeaeaa1e1db30f352f926aa97a, mined in block 640001 unspents = [] for unspent in UNSPENTS_RBF: replaceable_unspent = Unspent.from_dict(unspent.to_dict()) replaceable_unspent.opt_in_for_RBF() unspents.append(replaceable_unspent) rbf_tx = create_new_transaction(PrivateKey(), unspents, OUTPUTS_RBF) START = 8 # exclude transaction version END = len( rbf_tx) - 12 # exlude locktime and 2x one byte of empty witness assert rbf_tx[START:END] == FINAL_TX_RBF[START:END]
def test_dont_overwrite_relative_locktime(self): # opting in for RBF shouldn't overwrite a relative locktime unspents = [] for unspent in UNSPENTS_RBF: locked_unspent = Unspent.from_dict(unspent.to_dict()) locked_unspent.sequence = 50000 locked_unspent.opt_in_for_RBF() unspents.append(locked_unspent) rbf_tx = create_new_transaction(PrivateKey(), unspents, OUTPUTS_RBF) START = 8 # exclude transaction version END = len( rbf_tx) - 12 # exlude locktime and 2x one byte of empty witness assert rbf_tx[START:END] != FINAL_TX_RBF[START:END]
def test_get_unspent_size(self, mock_get_unspent): mock_get_unspent.return_value = yield [ Unspent(amount=1, confirmations=1, script=b'script', txid=b'txid', txindex=0) ] key1 = PrivateKey(WALLET_FORMAT_MAIN_1) multisig1 = MultiSig(key1, [key1.public_key, 33 * b'\x00'], 2) multisig2 = MultiSig(key1, [key1.public_key, 33 * b'\x00'], 1) multisig3 = MultiSig(key1, [key1.public_key, 33 * b'\x00', 33 * b'\x00'], 2) unspent1 = multisig1.get_unspents() unspent2 = multisig2.get_unspents() unspent3 = multisig3.get_unspents() assert unspent1[0].vsize == 262 # Legacy 2-of-2 assert unspent1[1].vsize == 131.5 # Nested Segwit 2-of-2 assert unspent2[0].vsize == 188 # Legacy 1-of-2 assert unspent2[1].vsize == 113 # Nested Segwit 1-of-2 assert unspent3[0].vsize == 298 # Legacy 2-of-3 assert unspent3[1].vsize == 140 # Nested Segwit 2-of-3
def test_get_transactions(self): key1 = PrivateKey(WALLET_FORMAT_MAIN_1) key2 = PrivateKey(WALLET_FORMAT_MAIN_2) multisig = MultiSig(key1, [key1.public_key, key2.public_key], 2) transactions = multisig.get_transactions() assert transactions == multisig.transactions
def test_get_unspent(self): key1 = PrivateKey(WALLET_FORMAT_MAIN_1) key2 = PrivateKey(WALLET_FORMAT_MAIN_2) multisig = MultiSig(key1, [key1.public_key, key2.public_key], 2) unspent = multisig.get_unspents() assert unspent == multisig.unspents
def test_get_balance(self): key1 = PrivateKey(WALLET_FORMAT_MAIN_1) key2 = PrivateKey(WALLET_FORMAT_MAIN_2) multisig = MultiSig(key1, [key1.public_key, key2.public_key], 2) balance = int(multisig.get_balance()) assert balance == multisig.balance
def test_address(self): key1 = PrivateKey(WALLET_FORMAT_MAIN_1) key2 = PrivateKey(WALLET_FORMAT_MAIN_2) multisig = MultiSig(key1, [key1.public_key, key2.public_key], 2) assert multisig.address == BITCOIN_ADDRESS_P2SH_MULTISIG assert multisig.segwit_address == BITCOIN_ADDRESS_NP2SH_MULTISIG
def test_repr(self): assert repr(PrivateKey(WALLET_FORMAT_MAIN) ) == '<PrivateKey: 1ELReFsTCUY2mfaDTy32qxYiT49z786eFg>'
def test_from_int(self): key = PrivateKey.from_int(PRIVATE_KEY_NUM) assert isinstance(key, PrivateKey) assert key.to_int() == PRIVATE_KEY_NUM
def test_from_pem(self): key = PrivateKey.from_pem(PRIVATE_KEY_PEM) assert isinstance(key, PrivateKey) assert key.to_pem() == PRIVATE_KEY_PEM
def test_from_der(self): key = PrivateKey.from_der(PRIVATE_KEY_DER) assert isinstance(key, PrivateKey) assert key.to_der() == PRIVATE_KEY_DER
def test_from_hex(self): key = PrivateKey.from_hex(PRIVATE_KEY_HEX) assert isinstance(key, PrivateKey) assert key.to_hex() == PRIVATE_KEY_HEX
def test_get_balance(self): private_key = PrivateKey(WALLET_FORMAT_MAIN) balance = int(private_key.get_balance()) assert balance == private_key.balance
def test_to_wif(self): private_key = PrivateKey(WALLET_FORMAT_MAIN) assert private_key.to_wif() == WALLET_FORMAT_MAIN private_key = PrivateKey(WALLET_FORMAT_COMPRESSED_MAIN) assert private_key.to_wif() == WALLET_FORMAT_COMPRESSED_MAIN
def test_repr(self): key1 = PrivateKey(WALLET_FORMAT_MAIN_1) key2 = PrivateKey(WALLET_FORMAT_MAIN_2) multisig = MultiSig(key1, [key1.public_key, key2.public_key], 2) assert repr(multisig) == '<MultiSig: {}>'.format( BITCOIN_ADDRESS_P2SH_MULTISIG)
def test_sign_tx_invalid_unspents(self): key = PrivateKey(WALLET_FORMAT_TEST_1) txobj = deserialize(UNSIGNED_TX_SEGWIT) with pytest.raises(TypeError): # Unspents must be presented as list: sign_tx(key, txobj, unspents=UNSPENTS_SEGWIT[0])
def test_matching(self): private_key = PrivateKey(WALLET_FORMAT_MAIN) tx = create_p2pkh_transaction(private_key, UNSPENTS, OUTPUTS) assert tx[-288:] == FINAL_TX_1[-288:]
def test_address(self): private_key = PrivateKey(WALLET_FORMAT_MAIN) assert private_key.address == BITCOIN_ADDRESS assert private_key.segwit_address is None