Skip to content

Commit

Permalink
Add transaction examples, improve docs of signature generator ex
Browse files Browse the repository at this point in the history
  • Loading branch information
bbrtj committed Oct 12, 2023
1 parent 1d98420 commit 246a548
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 1 deletion.
48 changes: 48 additions & 0 deletions ex/op_return.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use v5.10;
use strict;
use warnings;

use Bitcoin::Crypto qw(btc_transaction btc_utxo btc_prv);
use Bitcoin::Crypto::Util qw(to_format);
use Bitcoin::Crypto::Network;

# This code was used to produce this testnet transaction:
# https://mempool.space/testnet/tx/11cca738065ca9172394f800bab3f997698851fd0245848ec491b2744d1807e8

Bitcoin::Crypto::Network->get('bitcoin_testnet')->set_default;

my $tx = btc_transaction->new;

btc_utxo->extract(
[
hex =>
'01000000000104381f7552e3ba01067333f2cf3321ceba15bb3077939c6133dcbc98df09870ca40000000000ffffffff5ba13b9c3180d36f24668f652e002640d1f51db48d7c2df4774a705befea6c6700000000171600140454b800857687eaee9bc68efc57c3598e3de4d9ffffffff27954badb0343f4335480d8d92d5e9853389bcb921fab9c2ddd495baebd1d89d0000000000ffffffff593d6ac408b55fa50c6747741b5867aab365a3f8fc3326e25bb4c4371fe2dba0010000001716001448087e9cf4495e34626a476aad75a2978e18d593ffffffff01493d020000000000160014216fdd3ff0d541788058d526d5ac7dc3c94f51cf0247304402205797f0cbca0b5e6151d2ee64bdf55f706f33683115ba5bcda382d328b526f06b022053ed5d5861481dc8af12c2a37da82c5e9c51cdf972e15743b7444adcc0a33b43012103355d2f5c6d699fe901ad79104c2abbbd362bbb2a2f6a8eca7e8d9cd140f4b7740247304402205b3cdc0912cdd8de191f1ed16d50b410930c029abbda8a7acf4eb9d52dbdb41102202966190e6727000fff320d36f2364d71790cd396dc72bc0fba21585daaa04ac40121021ca092cf73cad2b3c3549166ea404e033bed183491e15b7dd126d3be75c2893402483045022100a705a1b9cd1ca64743ef475444795cd8b76641710641826499e061246d0ae7bc02203c0f9fd28cb3ef49d55dcc40bea7a5f16a19be399b7f5444ec65c220178ed385012103019d0de5f90e8f5479089a4c2bc7f3704edb1c2b160c2682f33096b6c4c206b402483045022100e8527eefba1ce9f8db63af441d34e1fc4c364befec37599659d2e0fdfe33e9a80220671c8367a0d28ee722f213288829440947012ef5eacf428faff54d13168dd82a01210307755740cd57203167ead2eef17dabcd40e6e9853db31afca15072b107b98f7c00000000'
]
);

$tx->add_input(
utxo => [[hex => 'f8990964483b62a86ad1a5ae445b2d5b3ccd74c3611a857dc794a37eb5c62e3f'], 0],
);

$tx->add_output(
locking_script => [P2WPKH => 'tb1qprasdghq2svf5hmta98zf93aj6z36ep7cpkj68'],
value => 0,
);

$tx->add_output(
locking_script => [NULLDATA => 'Have fun with Perl, use Bitcoin::Crypto!'],
value => 0,
);

$tx->set_rbf;

# unsigned tx virtual size is used, so the real fee rate will be approx two times smaller
my $wanted_fee_rate = 2;
$tx->outputs->[0]->set_value($tx->fee - int($tx->virtual_size * $wanted_fee_rate));

btc_prv->from_wif('cVKqti7zi1P5zZ6yXhBxg6hRHtMAchdYPFfSmr5nMskiwUgzmfa8')->sign_transaction($tx, signing_index => 0);

$tx->verify;
say $tx->dump;
say to_format [hex => $tx->to_serialized];

13 changes: 12 additions & 1 deletion ex/signature_generator.pl
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,16 @@ sub verify_message
=head1 Message signing script example
This example shows how to build a solution that will allow proving ownership of a private key. I<sign_message> function produces a hashref containing all the data required to verify you own a bitcoin address or a public key (bitcoin address is deterministically generated from a public key so they are pretty much the same thing), ready to be serialized using JSON for example. I<verify> function accepts this hashref and returns a true or false value, meaning whether the message is verified successfully.
This example shows how to build a custom solution that will allow proving
ownership of a private key. I<sign_message> function produces a hashref
containing all the data required to verify you own a bitcoin address or a
public key (bitcoin address is deterministically generated from a public key so
they are pretty much the same thing), ready to be serialized using JSON for
example. I<verify> function accepts this hashref and returns a true or false
value, meaning whether the message is verified successfully.
Note that disclosing your public key decreases the security of your coins, as
it becomes easier to brute force the private key using algorithms such as
Pollard's Kangaroo, although as long as the private key entropy is random and
using full 256 bit range of secp256k1 it should not be an issue (for now).
77 changes: 77 additions & 0 deletions ex/transaction.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use v5.10;
use strict;
use warnings;

use Bitcoin::Crypto qw(btc_transaction btc_utxo btc_prv);
use Bitcoin::Crypto::Util qw(to_format);
use Bitcoin::Crypto::Network;

# This code was used to produce this testnet transaction:
# https://mempool.space/testnet/tx/f8990964483b62a86ad1a5ae445b2d5b3ccd74c3611a857dc794a37eb5c62e3f

Bitcoin::Crypto::Network->get('bitcoin_testnet')->set_default;

my $tx = btc_transaction->new;

btc_utxo->extract(
[
hex =>
'010000000001025c86bc8650181835c3853d685cf11f6fa42a8eb9e59cb25b2de64ae33ccdb9e00000000000ffffffffeb42cef4d898b0c1d93dd0aca91ef140ba2df35d5b722a18b2d88d3c255278de0000000000ffffffff021027000000000000160014dbabdc8a9a03e3e7268e7e87f99f1af235e7bebb4594000000000000160014df212a4c455f96199371a616ee30f9cd1b55c0b402483045022100e14daab47feff38dca3acbd04eb0036a1c64efdd3c5bd34c6a06a3612543422102201816503f77b3595fc7d829bbfd82282d9bc5b37bb7771070d0f7d74381fa8ccd0121037e01f2929a9219a7862fc25848a85df69b6a8ef49b7edbebfa64a095e136897d024730440220017703b6a4b0f6cc7799b0b7cae24f1a65188d0f40c28bb118b5c56de6f050ba022029f2e64ab5a6e9b04c07ac56bd46b07068d9ffe2b41fa6ff8f958d7dfa09be0c012103f97e2a442ed2bd4cb01fbf7c2ee8d0bd30dac47478671fb3a3bbef23ca57c71000000000'
]
);

$tx->add_input(
utxo => [[hex => 'a40c8709df98bcdc33619c937730bb15bace2133cff233730601bae352751f38'], 0],
);

btc_utxo->extract(
[
hex =>
'01000000000101593d6ac408b55fa50c6747741b5867aab365a3f8fc3326e25bb4c4371fe2dba00000000000ffffffff02102700000000000017a91414f6d8848d031b6bb813866e2bcdd6608fb9c41b870745000000000000160014ce7b28a8445150159f98c2790b2ccdfb1767f59702483045022100a170dccb2bd8370edbd58c8a439203af6fe1d0101449469faa4ead2dcb2639a00220697ad9db7bf36f84aa8b1dc2c01eb2dedc070567581821e8272f41aa588fe04f0121024bd5b0fca10d2c8ade0dd2cbe868b4116d802d46d0898864c5c84253022e05e800000000'
]
);

$tx->add_input(
utxo => [[hex => '676ceaef5b704a77f42d7c8db41df5d14026002e658f66246fd380319c3ba15b'], 0],
);

btc_utxo->extract(
[
hex =>
'010000000001033d97edd0856edc7655f9b42f9443efe1dbd596fc87cf45ab5c968a1165cfdd300000000000ffffffffd60af20e05a8de17e65ace71de6eae94c3f7f14c8aff65268467fb8d0b42f8370100000000ffffffff9958e77992d4b3576ddd6a371d04a5b5a732871ab630c0bb2aa76468cd725de70000000000ffffffff01b3c9010000000000160014f07d99d91cfa99a55ed583a45bc47309eded40cd0247304402202a4841b52238b2bccae3b69a5d204ce7a281ef73042880b83a241b012226a9c802204166961d6254faf17805c9f1b2a5c695074f17c452e7c077d3890bfd99e11749012103a7c8c7c76f85c8e65a378d64780a26b064c3955a6effb9f6cde9c885138cab9702483045022100e8d29e5cd7959a59b68f20cf814f71430a82d85dbe4a908cc9ac201c4bf8ae8902206c8d56bbd6bf01f5a45819358b322653c953d558517aaff1138fa28e4492008c012103eed605f9a9f7223492976ec80ccacc8ea280b9dae91702a9c9b416a6475cbd330247304402207c8fdd43e7dca55f84c2ab097dc93725b5505470d15c0d6dde4601a59727cfe20220566dfd0de5eed923c8f418e2ff3596009bc99afdd2c1e414aace7ae69a8671ee012103611606d82a61c22091485265c5285d02e165f3ee7ed72ffdbba45785f491ba4000000000'
]
);

$tx->add_input(
utxo => [[hex => '9dd8d1ebba95d4ddc2b9fa21b9bc893385e9d5928d0d4835433f34b0ad4b9527'], 0],
);

btc_utxo->extract(
[
hex =>
'01000000000101381f7552e3ba01067333f2cf3321ceba15bb3077939c6133dcbc98df09870ca40100000000ffffffff02a66c000000000000160014163e48c26c6ce807b00b1400efbf72563838ea3e102700000000000017a91445fe03f2e3c7b6e962c696c0005e613b985a85cf870247304402202e64e2d158f201d2fdc14056629382a7ea3849b9415ec69659f6671c8a774bc7022075f7a32ba99e84605e5e4fc14d1e835be7c1c5a15d91d72d184f54fb7f89cf570121033b2e0f81f9e701f4474076378f1dae1bbd6a62342fd16e92a75832b85055b7cf00000000'
]
);

$tx->add_input(
utxo => [[hex => 'a0dbe21f37c4b45be22633fcf8a365b3aa67581b7447670ca55fb508c46a3d59'], 1],
);

$tx->add_output(
locking_script => [P2WPKH => 'tb1qy9ha60ls64qh3qzc65ndttrac0y575w0m0lysn'],
value => 0,
);

# unsigned tx virtual size is used, so the real fee rate will be approx two times smaller
my $wanted_fee_rate = 2;
$tx->outputs->[0]->set_value($tx->fee - int($tx->virtual_size * $wanted_fee_rate));

btc_prv->from_wif('cRdrKz5KKznsXDP33JiC187aRAvHvDkJPk4StLcQhfTSzgK6sciY')->sign_transaction($tx, signing_index => 0);
btc_prv->from_wif('cVHF9anUyf8mgVMH8CY4AdPB4AmictADwpLby1WMnS7SnKvzCaat')->sign_transaction($tx, signing_index => 1);
btc_prv->from_wif('cR3JQywaVoz1YtXhpSsgpaGq3juaQyrdv6C7xXjR91f3JRKKaG8T')->sign_transaction($tx, signing_index => 2);
btc_prv->from_wif('cPswC8N3dkykncfVQezhQbrbSWMwttuq7Zk9f5eH8Po5CCiHFQMd')->sign_transaction($tx, signing_index => 3);

$tx->verify;
say $tx->dump;
say to_format [hex => $tx->to_serialized];

0 comments on commit 246a548

Please sign in to comment.