def fundrawtransaction(self, given_transaction, *args, **kwargs): """ Make up some inputs for the given transaction. """ # just use any txid here vintxid = lx("99264749804159db1e342a0c8aa3279f6ef4031872051a1e52fb302e51061bef") if isinstance(given_transaction, str): given_bytes = x(given_transaction) elif isinstance(given_transaction, CMutableTransaction): given_bytes = given_transaction.serialize() else: raise FakeBitcoinProxyException("Wrong type passed to fundrawtransaction.") # this is also a clever way to not cause a side-effect in this function transaction = CMutableTransaction.deserialize(given_bytes) for vout_counter in range(0, self._num_fundrawtransaction_inputs): txin = CMutableTxIn(COutPoint(vintxid, vout_counter)) transaction.vin.append(txin) # also allocate a single output (for change) txout = make_txout() transaction.vout.append(txout) transaction_hex = b2x(transaction.serialize()) return {"hex": transaction_hex, "fee": 5000000}
def test_sendrawtransaction(self): num_outputs = 5 given_transaction = CMutableTransaction( [], [make_txout() for x in range(0, num_outputs)]) expected_txid = b2lx(given_transaction.GetHash()) given_transaction_hex = b2x(given_transaction.serialize()) proxy = FakeBitcoinProxy() resulting_txid = proxy.sendrawtransaction(given_transaction_hex) self.assertEqual(resulting_txid, expected_txid)
def test_fundrawtransaction_adds_output(self): num_outputs = 5 unfunded_transaction = CMutableTransaction( [], [make_txout() for x in range(0, num_outputs)]) proxy = FakeBitcoinProxy() funded_transaction_hex = proxy.fundrawtransaction( b2x(unfunded_transaction.serialize()))["hex"] funded_transaction = CMutableTransaction.deserialize( x(funded_transaction_hex)) self.assertTrue(len(funded_transaction.vout) > num_outputs) self.assertEqual(len(funded_transaction.vout), num_outputs + 1)
def signrawtransaction(self, given_transaction): """ This method does not actually sign the transaction, but it does return a transaction based on the given transaction. """ if isinstance(given_transaction, str): given_bytes = x(given_transaction) elif isinstance(given_transaction, CMutableTransaction): given_bytes = given_transaction.serialize() else: raise FakeBitcoinProxyException("Wrong type passed to signrawtransaction.") transaction = CMutableTransaction.deserialize(given_bytes) transaction_hex = b2x(transaction.serialize()) return {"hex": transaction_hex}
def test_fundrawtransaction_hex_hash(self): unfunded_transaction = CMutableTransaction( [], [make_txout() for x in range(0, 5)]) proxy = FakeBitcoinProxy() funded_transaction_hex = proxy.fundrawtransaction( b2x(unfunded_transaction.serialize()))["hex"] funded_transaction = CMutableTransaction.deserialize( x(funded_transaction_hex)) self.assertTrue(unfunded_transaction is not funded_transaction) self.assertEqual(type(funded_transaction), type(unfunded_transaction)) self.assertNotEqual(len(funded_transaction.vin), 0) self.assertTrue( len(funded_transaction.vin) > len(unfunded_transaction.vin)) self.assertEqual(type(funded_transaction.vin[0]), CTxIn)
def test(self): if not is_libsec256k1_available(): return use_libsecp256k1_for_signing(True) # Test Vectors for RFC 6979 ECDSA, secp256k1, SHA-256 # (private key, message, expected k, expected signature) test_vectors = [ (0x1, "Satoshi Nakamoto", 0x8F8A276C19F4149656B280621E358CCE24F5F52542772691EE69063B74F15D15, "934b1ea10a4b3c1757e2b0c017d0b6143ce3c9a7e6a4a49860d7a6ab210ee3d82442ce9d2b916064108014783e923ec36b49743e2ffa1c4496f01a512aafd9e5" ), (0x1, "All those moments will be lost in time, like tears in rain. Time to die...", 0x38AA22D72376B4DBC472E06C3BA403EE0A394DA63FC58D88686C611ABA98D6B3, "8600dbd41e348fe5c9465ab92d23e3db8b98b873beecd930736488696438cb6b547fe64427496db33bf66019dacbf0039c04199abb0122918601db38a72cfc21" ), (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140, "Satoshi Nakamoto", 0x33A19B60E25FB6F4435AF53A3D42D493644827367E6453928554F43E49AA6F90, "fd567d121db66e382991534ada77a6bd3106f0a1098c231e47993447cd6af2d06b39cd0eb1bc8603e159ef5c20a5c8ad685a45b06ce9bebed3f153d10d93bed5" ), (0xf8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181, "Alan Turing", 0x525A82B70E67874398067543FD84C83D30C175FDC45FDEEE082FE13B1D7CFDF1, "7063ae83e7f62bbb171798131b4a0564b956930092b33b07b395615d9ec7e15c58dfcc1e00a35e1572f366ffe34ba0fc47db1e7189759b9fb233c5b05ab388ea" ), (0xe91671c46231f833a6406ccbea0e3e392c76c167bac1cb013f6f1013980455c2, "There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!", 0x1F4B84C23A86A221D233F2521BE018D9318639D5B8BBD6374A8A59232D16AD3D, "b552edd27580141f3b2a5463048cb7cd3e047b97c9f98076c32dbdf85a68718b279fa72dd19bfae05577e06c7c0c1900c371fcd5893f7e1d56a37d30174671f6" ) ] for vector in test_vectors: secret = CBitcoinSecret.from_secret_bytes( x('{:064x}'.format(vector[0]))) encoded_sig = secret.signECDSA( hashlib.sha256(vector[1].encode('utf8')).digest()) assert (encoded_sig[0] == 0x30) assert (encoded_sig[1] == len(encoded_sig) - 2) assert (encoded_sig[2] == 0x02) rlen = encoded_sig[3] rpos = 4 assert (rlen in (32, 33)) if rlen == 33: assert (encoded_sig[rpos] == 0) rpos += 1 rlen -= 1 rval = encoded_sig[rpos:rpos + rlen] spos = rpos + rlen assert (encoded_sig[spos] == 0x02) spos += 1 slen = encoded_sig[spos] assert (slen in (32, 33)) spos += 1 if slen == 33: assert (encoded_sig[spos] == 0) spos += 1 slen -= 1 sval = encoded_sig[spos:spos + slen] sig = b2x(rval + sval) assert (str(sig) == vector[3]) use_libsecp256k1_for_signing(False)
def T(base58_privkey, expected_hex_pubkey, expected_is_compressed_value): key = CBitcoinSecret(base58_privkey) self.assertEqual(b2x(key.pub), expected_hex_pubkey) self.assertEqual(key.is_compressed, expected_is_compressed_value)
def T(str_addr, expected_scriptPubKey_hexbytes): addr = CBitcoinAddress(str_addr) actual_scriptPubKey = addr.to_scriptPubKey() self.assertEqual(b2x(actual_scriptPubKey), expected_scriptPubKey_hexbytes)
from bitcoincash import SelectParams from bitcoincash.core import b2x, lx, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160 from bitcoincash.core.script import CScript, OP_DUP, OP_HASH160, OP_EQUALVERIFY, OP_CHECKSIG, SignatureHash, SIGHASH_ALL from bitcoincash.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH from bitcoincash.wallet import CBitcoinAddress, CBitcoinSecret SelectParams('mainnet') # Create the (in)famous correct brainwallet secret key. h = hashlib.sha256(b'correct horse battery staple').digest() seckey = CBitcoinSecret.from_secret_bytes(h) # Create a redeemScript. Similar to a scriptPubKey the redeemScript must be # satisfied for the funds to be spent. txin_redeemScript = CScript([seckey.pub, OP_CHECKSIG]) print(b2x(txin_redeemScript)) # Create the magic P2SH scriptPubKey format from that redeemScript. You should # look at the CScript.to_p2sh_scriptPubKey() function in bitcoincash.core.script to # understand what's happening, as well as read BIP16: # https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey() # Convert the P2SH scriptPubKey to a base58 Bitcoin address and print it. # You'll need to send some funds to it to create a txout to spend. txin_p2sh_address = CBitcoinAddress.from_scriptPubKey(txin_scriptPubKey) print('Pay to:', str(txin_p2sh_address)) # Same as the txid:vout the createrawtransaction RPC call requires # # lx() takes *little-endian* hex and converts it to bytes; in Bitcoin
[OP_DUP, OP_HASH160, Hash160(seckey.pub), OP_EQUALVERIFY, OP_CHECKSIG]) # Create the txout. This time we create the scriptPubKey from a Bitcoin # address. txout = CMutableTxOut( 0.001 * COIN, CBitcoinAddress('1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8').to_scriptPubKey()) # Create the unsigned transaction. tx = CMutableTransaction([txin], [txout]) # Calculate the signature hash for that transaction. sighash = SignatureHash(txin_scriptPubKey, tx, 0, SIGHASH_ALL) # Now sign it. We have to append the type of signature we want to the end, in # this case the usual SIGHASH_ALL. sig = seckey.sign(sighash) + bytes([SIGHASH_ALL]) # Set the scriptSig of our transaction input appropriately. txin.scriptSig = CScript([sig, seckey.pub]) # Verify the signature worked. This calls EvalScript() and actually executes # the opcodes in the scripts to see if everything worked out. If it doesn't an # exception will be raised. VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH, )) # Done! Print the transaction to standard output with the bytes-to-hex # function. print(b2x(tx.serialize()))
def T(redeemScript, expected_hex_bytes): redeemScript = CScript(redeemScript) actual_script = redeemScript.to_p2sh_scriptPubKey() self.assertEqual(b2x(actual_script), expected_hex_bytes)