-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ed819ac
commit d37fec5
Showing
19 changed files
with
18,571 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import os | ||
import bech32 | ||
import base58 | ||
import base64 | ||
import ecdsa | ||
import hashlib | ||
|
||
|
||
def address_generation(): | ||
private_key = os.urandom(32).hex() | ||
sk = ecdsa.SigningKey.from_string( | ||
bytes.fromhex(private_key), ecdsa.SECP256k1) | ||
vk = sk.verifying_key | ||
public_key = (b'\x04' + vk.to_string()).hex() | ||
ripemd160 = hashlib.new('ripemd160') | ||
ripemd160.update(hashlib.sha256(bytes.fromhex(public_key)).digest()) | ||
middle = b'\x6f' + ripemd160.digest() | ||
checksum = hashlib.sha256(hashlib.sha256(middle).digest()).digest()[:4] | ||
binary_addr = middle + checksum | ||
addr = base58.b58encode(binary_addr) | ||
return private_key, public_key, addr | ||
|
||
|
||
def wif_formatter(private_key): | ||
wif_private_key = b'\x80' + bytes.fromhex(private_key) + b'\x01' | ||
checksum2 = hashlib.sha256(hashlib.sha256( | ||
wif_private_key).digest()).digest()[:4] | ||
wif_private_key = wif_private_key + checksum2 | ||
return wif_private_key | ||
|
||
|
||
prv_key, pub_key, addr = address_generation() | ||
print("BTC address: " + addr.decode("utf-8")) | ||
|
||
|
||
wif_prv_key = wif_formatter(prv_key) | ||
print("wif private key in base 58 : " + | ||
base58.b58encode(wif_prv_key).decode("utf-8")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import os | ||
import bech32 | ||
import base58 | ||
import base64 | ||
import ecdsa | ||
import hashlib | ||
|
||
|
||
def address_generation(): | ||
private_key = os.urandom(32).hex() | ||
sk = ecdsa.SigningKey.from_string( | ||
bytes.fromhex(private_key), ecdsa.SECP256k1) | ||
vk = sk.verifying_key | ||
public_key = (b'\x04' + vk.to_string()).hex() | ||
ripemd160 = hashlib.new('ripemd160') | ||
ripemd160.update(hashlib.sha256(bytes.fromhex(public_key)).digest()) | ||
middle = b'\x6f' + ripemd160.digest() | ||
checksum = hashlib.sha256(hashlib.sha256(middle).digest()).digest()[:4] | ||
binary_addr = middle + checksum | ||
addr = base58.b58encode(binary_addr) | ||
return private_key, public_key, addr | ||
|
||
|
||
def generate_vanuty_address(key): | ||
while True: | ||
prv_key, _, addr = address_generation() | ||
vanitystring = addr.decode("utf-8")[1:4] | ||
if vanitystring in key: | ||
wif_private_key = b'\x80' + bytes.fromhex(prv_key) + b'\x01' | ||
checksum2 = hashlib.sha256(hashlib.sha256( | ||
wif_private_key).digest()).digest()[:4] | ||
wif_private_key = wif_private_key + checksum2 | ||
return wif_private_key, addr | ||
|
||
|
||
wif_prv_key, addr = generate_vanuty_address(key="moh") | ||
print("found the address") | ||
print("BTC address: " + addr.decode("utf-8")) | ||
print("wif private key in base 58 : " + base58.b58encode(wif_prv_key).decode("utf-8")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
### **Task1: Generating Valid Bitcoin Addresses** | ||
|
||
#### Q1: Test Network Address Generation | ||
|
||
`Q1.py` will generate a Bitcoin address for the test network (testnet). The output is in Base58 format, along with the corresponding private key in WIF (Wallet Import Format). | ||
|
||
#### Q2: Vanity Address Generation | ||
|
||
`Q2.py` will generate a “vanity address.” A vanity address starts with specific characters of your choice. Given three input characters, the code produces an address where those characters appear in positions 2 to 4 (since the first character follows a specific Bitcoin format). The output is again in Base58 format, along with the corresponding private key in WIF. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import bitcoin.wallet ,hashlib | ||
from bitcoin.core import COIN, b2lx, serialize, x, lx, b2x | ||
from utils import * | ||
from Crypto.Hash import RIPEMD160 | ||
|
||
bitcoin.SelectParams("testnet") | ||
my_private_key = bitcoin.wallet.CBitcoinSecret("cS3Ykn28yDPagMXBgUNkrSdxzT3Hii5g2LgAQb2yN4kWJwWJ99Gg") # Private key in WIF format XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | ||
my_public_key = my_private_key.pub | ||
my_address = bitcoin.wallet.P2PKHBitcoinAddress.from_pubkey(my_public_key) | ||
# destination_address = bitcoin.wallet.CBitcoinAddress('') # Destination address (recipient of the money) | ||
# destination_address2 = bitcoin.wallet.CBitcoinAddress('') # Destination address (recipient of the money) | ||
|
||
def P2PKH_scriptPubKey(address): | ||
|
||
return [ OP_DUP , OP_HASH160 ,address , OP_EQUALVERIFY ,OP_CHECKSIG] | ||
|
||
def P2PKH_scriptPubKey_NOBODY(): | ||
|
||
return [OP_RETURN] | ||
|
||
def P2PKH_scriptPubKey_EVERYBODY(): | ||
|
||
return [] | ||
|
||
def P2PKH_scriptSig(txin, txout, txin_scriptPubKey): | ||
|
||
signature = create_OP_CHECKSIG_signature(txin, txout, txin_scriptPubKey, my_private_key) | ||
|
||
return [signature , my_public_key] | ||
|
||
|
||
def send_from_P2PKH_transaction(amount_to_send,amount_to_send2, txid_to_spend, utxo_index, | ||
txout_scriptPubKey,txout_scriptPubKey2 ): | ||
txout = create_txout(amount_to_send, txout_scriptPubKey) | ||
txout2 = create_txout(amount_to_send2, txout_scriptPubKey2) | ||
txin_scriptPubKey = P2PKH_scriptPubKey(my_address) | ||
txin = create_txin(txid_to_spend, utxo_index) | ||
txin_scriptSig = P2PKH_scriptSig(txin, [txout,txout2] , txin_scriptPubKey) | ||
new_tx = create_signed_transaction(txin, [txout,txout2], txin_scriptPubKey, | ||
txin_scriptSig) | ||
return broadcast_transaction(new_tx) | ||
|
||
def create_OP_CHECKSIG_signature(txin, txout, txin_scriptPubKey, seckey): | ||
tx = CMutableTransaction([txin], [txout[0],txout[1]]) | ||
sighash = SignatureHash(CScript(txin_scriptPubKey), tx, | ||
0, SIGHASH_ALL) | ||
sig = seckey.sign(sighash) + bytes([SIGHASH_ALL]) | ||
return sig | ||
|
||
|
||
def create_signed_transaction(txin, txout, txin_scriptPubKey,txin_scriptSig): | ||
tx = CMutableTransaction([txin], [txout[0],txout[1]]) | ||
txin.scriptSig = CScript(txin_scriptSig) | ||
VerifyScript(txin.scriptSig, CScript(txin_scriptPubKey), | ||
tx, 0, (SCRIPT_VERIFY_P2SH,)) | ||
return tx | ||
|
||
if __name__ == '__main__': | ||
###################################################################### | ||
amount_to_send = 0.00002 | ||
amount_to_send2 = 0.00007 | ||
txid_to_spend = ('3d628c35a628f963b61c0c323da805ffacf2d8d5769f06cf47983abb637f37aa') # TxHash of UTXO | ||
utxo_index = 1 # UTXO index among transaction outputs | ||
###################################################################### | ||
|
||
print(my_address) # Prints your address in base58 | ||
print(my_public_key.hex()) # Print your public key in hex | ||
print(my_private_key.hex()) # Print your private key in hex | ||
txout_scriptPubKey = P2PKH_scriptPubKey_NOBODY() | ||
txout_scriptPubKey2 = P2PKH_scriptPubKey_EVERYBODY() | ||
response = send_from_P2PKH_transaction(amount_to_send,amount_to_send2, txid_to_spend, utxo_index, | ||
txout_scriptPubKey,txout_scriptPubKey2) | ||
print(response.status_code, response.reason) | ||
print(response.text) # Report the hash of transaction which is printed in this section result | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import bitcoin.wallet | ||
import hashlib | ||
from bitcoin.core import COIN, b2lx, serialize, x, lx, b2x | ||
from utils import * | ||
from Crypto.Hash import RIPEMD160 | ||
|
||
bitcoin.SelectParams("testnet") | ||
# Private key in WIF format XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | ||
my_private_key = bitcoin.wallet.CBitcoinSecret( | ||
"cS3Ykn28yDPagMXBgUNkrSdxzT3Hii5g2LgAQb2yN4kWJwWJ99Gg") | ||
my_public_key = my_private_key.pub | ||
my_address = bitcoin.wallet.P2PKHBitcoinAddress.from_pubkey(my_public_key) | ||
destination_address = bitcoin.wallet.CBitcoinAddress( | ||
'mpNvmLAb9hYJ1q2BFcCbnsfKNNLGxVtW8o') # Destination address (recipient of the money) | ||
|
||
|
||
def P2PKH_scriptPubKey(address): | ||
|
||
return [OP_DUP, OP_HASH160, address, OP_EQUALVERIFY, OP_CHECKSIG] | ||
|
||
|
||
def P2PKH_scriptPubKey_EVERYBODY(address): | ||
|
||
return [] | ||
|
||
|
||
def P2PKH_scriptSig_EVERYBODY(): | ||
return [OP_TRUE] | ||
|
||
|
||
def P2PKH_scriptSig(txin, txout, txin_scriptPubKey): | ||
|
||
signature = create_OP_CHECKSIG_signature( | ||
txin, txout, txin_scriptPubKey, my_private_key) | ||
|
||
return [] | ||
|
||
|
||
def send_from_P2PKH_transaction(amount_to_send, txid_to_spend, utxo_index, | ||
txout_scriptPubKey): | ||
txout = create_txout(amount_to_send, txout_scriptPubKey) | ||
txin_scriptPubKey = P2PKH_scriptPubKey_EVERYBODY(my_address) | ||
txin = create_txin(txid_to_spend, utxo_index) | ||
|
||
txin_scriptSig = P2PKH_scriptSig_EVERYBODY() | ||
|
||
new_tx = create_signed_transaction(txin, txout, txin_scriptPubKey, | ||
txin_scriptSig) | ||
|
||
return broadcast_transaction(new_tx) | ||
|
||
|
||
if __name__ == '__main__': | ||
###################################################################### | ||
amount_to_send = 0.00006 | ||
# TxHash of UTXO | ||
txid_to_spend = ('a34d95fba359ef6a5359579157947e27450187004d742b4b67214df93d10d1a6') | ||
utxo_index = 1 # UTXO index among transaction outputs | ||
###################################################################### | ||
|
||
print(my_address) # Prints your address in base58 | ||
print(my_public_key.hex()) # Print your public key in hex | ||
print(my_private_key.hex()) # Print your private key in hex | ||
txout_scriptPubKey = P2PKH_scriptPubKey(destination_address) | ||
response = send_from_P2PKH_transaction(amount_to_send, txid_to_spend, utxo_index, | ||
txout_scriptPubKey) | ||
print(response.status_code, response.reason) | ||
# Report the hash of transaction which is printed in this section result | ||
print(response.text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import bitcoin.wallet ,hashlib | ||
from bitcoin.core import COIN, b2lx, serialize, x, lx, b2x | ||
from utils import * | ||
from Crypto.Hash import RIPEMD160 | ||
|
||
bitcoin.SelectParams("testnet") | ||
my_private_key = bitcoin.wallet.CBitcoinSecret("cS3Ykn28yDPagMXBgUNkrSdxzT3Hii5g2LgAQb2yN4kWJwWJ99Gg") # Private key in WIF format XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | ||
my_public_key = my_private_key.pub | ||
my_address = bitcoin.wallet.P2PKHBitcoinAddress.from_pubkey(my_public_key) | ||
destination_address1 = bitcoin.wallet.CBitcoinAddress('mrrJH8rfQswojwztr2pGNsdbdz6hELXg85') # Destination address (recipient of the money) | ||
destination_address2 = bitcoin.wallet.CBitcoinAddress('mxg8CPu3UT1ZvfiaRBW12HKouoCW1oqAvp') # Destination address (recipient of the money) | ||
destination_address3 = bitcoin.wallet.CBitcoinAddress('msgjfBCqVwSvTvzBiLpYQGD1MHXbfY5Ds5') # Destination address (recipient of the money) | ||
|
||
def P2PKH_scriptPubKey(address): | ||
|
||
return [ OP_DUP , OP_HASH160 ,address , OP_EQUALVERIFY ,OP_CHECKSIG] | ||
|
||
def P2MS_scriptPubKey(pkey1, pkey2, pkey3): | ||
|
||
return [OP_2, pkey1, pkey2, pkey3, OP_3 , OP_CHECKMULTISIG] | ||
|
||
|
||
def P2PKH_scriptSig(txin, txout, txin_scriptPubKey): | ||
|
||
signature = create_OP_CHECKSIG_signature(txin, txout, txin_scriptPubKey, my_private_key) | ||
|
||
return [signature , my_public_key] | ||
|
||
|
||
def send_from_P2PKH_transaction(amount_to_send, txid_to_spend, utxo_index, | ||
txout_scriptPubKey ): | ||
txout = create_txout(amount_to_send, txout_scriptPubKey) | ||
txin_scriptPubKey = P2PKH_scriptPubKey(my_address) | ||
txin = create_txin(txid_to_spend, utxo_index) | ||
txin_scriptSig = P2PKH_scriptSig(txin, txout, txin_scriptPubKey) | ||
|
||
new_tx = create_signed_transaction(txin, txout ,txin_scriptPubKey, | ||
txin_scriptSig) | ||
|
||
return broadcast_transaction(new_tx) | ||
|
||
|
||
if __name__ == '__main__': | ||
###################################################################### | ||
amount_to_send = 0.0009 | ||
txid_to_spend = ('3b27769a29955c47fcc209445316dd38c40b9ac3d6cc214186465b7050a6fee1') # TxHash of UTXO | ||
utxo_index = 0 # UTXO index among transaction outputs | ||
###################################################################### | ||
|
||
print(my_address) # Prints your address in base58 | ||
print(my_public_key.hex()) # Print your public key in hex | ||
print(my_private_key.hex()) # Print your private key in hex | ||
txout_scriptPubKey = P2MS_scriptPubKey(destination_address1, destination_address2, destination_address3) | ||
response = send_from_P2PKH_transaction(amount_to_send, txid_to_spend, utxo_index, | ||
txout_scriptPubKey) | ||
print(response.status_code, response.reason) | ||
print(response.text) # Report the hash of transaction which is printed in this section result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
### **Task 2: Bitcoin Transaction Handling with bitcoinlib-python** | ||
|
||
In this task, we utilize the `bitcoinlib-python` library to perform Bitcoin transactions on the test network (testnet). The library provides various functions for creating different types of transactions. | ||
|
||
#### Q1: Creating a Simple Transaction | ||
|
||
In part 1, we create a transaction with one input and two output which The first output cannot be spent by anyone and the second output can be spent by anyone. | ||
|
||
In part 2, we spend the spendable output of this transaction in another transaction and return that to our original address as P2PKH output. | ||
|
||
#### Q2: Multisig Transaction | ||
|
||
in `Q2.py`, 3 addresses are generated first. Next, a transaction with one input and one output of P2MS type is generated which can be spent by 2 of the 3 generated addresses. Finally, using another transaction, this output is spent and the money is returned to the original address. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import requests | ||
|
||
from bitcoin.core import b2x, lx, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160 | ||
from bitcoin.core.script import * | ||
from bitcoin.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH | ||
|
||
|
||
def send_from_custom_transaction( | ||
amount_to_send, txid_to_spend, utxo_index, | ||
txin_scriptPubKey, txin_scriptSig, txout_scriptPubKey): | ||
txout = create_txout(amount_to_send, txout_scriptPubKey) | ||
txin = create_txin(txid_to_spend, utxo_index) | ||
new_tx = create_signed_transaction(txin, txout, txin_scriptPubKey, | ||
txin_scriptSig) | ||
return broadcast_transaction(new_tx) | ||
|
||
|
||
def create_txin(txid, utxo_index): | ||
return CMutableTxIn(COutPoint(lx(txid), utxo_index)) | ||
|
||
|
||
def create_txout(amount, scriptPubKey): | ||
return CMutableTxOut(amount*COIN, CScript(scriptPubKey)) | ||
|
||
|
||
def create_OP_CHECKSIG_signature(txin, txout, txin_scriptPubKey, seckey): | ||
tx = CMutableTransaction([txin], [txout]) | ||
sighash = SignatureHash(CScript(txin_scriptPubKey), tx, | ||
0, SIGHASH_ALL) | ||
sig = seckey.sign(sighash) + bytes([SIGHASH_ALL]) | ||
return sig | ||
|
||
|
||
def create_signed_transaction(txin, txout, txin_scriptPubKey,txin_scriptSig): | ||
tx = CMutableTransaction([txin], [txout]) | ||
txin.scriptSig = CScript(txin_scriptSig) | ||
VerifyScript(txin.scriptSig, CScript(txin_scriptPubKey), | ||
tx, 0, (SCRIPT_VERIFY_P2SH,)) | ||
return tx | ||
|
||
|
||
def broadcast_transaction(tx): | ||
raw_transaction = b2x(tx.serialize()) | ||
headers = {'content-type': 'application/x-www-form-urlencoded'} | ||
return requests.post( | ||
'https://api.blockcypher.com/v1/btc/test3/txs/push', | ||
headers=headers, | ||
data='{"tx": "%s"}' % raw_transaction) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
### **Task 3: Mining a Bitcoin block** | ||
|
||
In this task, a valid Bitcoin block is created locally. |
Oops, something went wrong.