bit-wasp / bitcoin-php Goto Github PK
View Code? Open in Web Editor NEWBitcoin implementation in PHP
License: The Unlicense
Bitcoin implementation in PHP
License: The Unlicense
It might be nice to be able to build the derive path by supplying an array of variables (or even an object) rather than supplying a string.
For instance, instead of
$bip44ChildKey = $masterKey->derivePath("44'/0'/0'/0/0");
Someone could do
$path = [ "purpose" => 44, "coin_type" => 0, "account" => 0, "chain" => 0, "address_index" => 0];
$bip44ChildKey = $masterKey->derivePath($path);
Or for the unhardened varieties (longer names since it's not as common anymore)
$path = [ "purpose_unhardened" => 44, "coin_type_unhardened" => 0, "account_unhardened" => 0, "chain" => 0, "address_index" => 0];
How to catch an exception which for example may occur when bitcoind is offline?
Wasn't able to solve this by using:
private function getAddress(){
//...prepare connection
try{
$response = $client->sendCommand($command);
return json_decode($response->getBody()->getContents());
}
catch(Exception $e){
return json_encode([
'errors' => 'server offline',
]);
}
}
Hey, very cool repo! I think I'm hitting a wall due to edge-case-y stuff.
I'm trying to sweep utxo dust from an address that utilized the Counterparty protocol to make a lot of multisig outputs. Counterparty uses 1-of-3 multisig, so I should be able to sweep them up and send them back to myself, no?
I am trying to create a tool like: http://redeem.bitwatch.co/ (which has ceased working).
Using your code, I have almost been able to get there, but both my code and redeem.bitwatch.co tool produce the same error which makes me think that perhaps it's not doable, but I'm told that redeem.bitwatch.co worked, in the past.
When you decode the tx that either my code or redeem.bitwatch.co creates, the addresses of my input transactions look like:
4RzbbApVjQzsiJsmPPVZXh4CGQ3um15wvY
I'm not expert, but I'm pretty sure bitcoin addresses have to start with 1 or 3, no?
What do you think would cause this / is there an obvious answer here? I know this is kind of out of left field.
Here's the raw unsigned transaction I've created...
It's totally possible that the code that generated this still has issues in terms of generating the script, but I don't think that would be what causes the addresses to start with the number 4.
01000000250bb4117d530b5f12248acf6d93f4383479a2f004ff79e76296db42301ab4c8a6000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff9138746736c9f304ade0c34c2a5b634cb894bade6241c1373821f55a8037f97b000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff9138746736c9f304ade0c34c2a5b634cb894bade6241c1373821f55a8037f97b010000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffe77789fdbe4e1cd38eedc52e734b83804322b0e9899e385cd235734018ee248b000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff5805c11a4179556af56e0617a7cca78d66eb5d3d92ed8fa58e372f38ed1b839d000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff8f9e026b27b9eab5ba92f018fb3926b715a00c1e760965122a49dff4ea2457f2000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aefffffffff37f77e6de1c0cfd362515b4f0dee19c02138cae2ef012275876607443befada000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffcb81433f173b8bc1a3ccb9500b157b5fedcf678ef84bc33f757646b3626c1bfa000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff86f3d7d57acf31049d00fbebbe58debd551674005bff5115332ac06b64f6ebd2000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffdecdd4d1bce67e4ffb351ec10b07b2bb1250155e6775dc48ebd3bc8c36cc1888000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff4c1ffc5bfec5ab440b11a8824cc854db76014bf0e5d528339f2b329f75c764b5000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff1dacd0be7c12cac8b4ad932ec4b2d6d04558c34d1356c3d437430042c0e91e8b000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff70331fad48b71e2985430329dc3895898867a456029b8e0c38bfc056e80e5129000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffbe25a801da6868246d626a11abedb6bacc32ef62d5ca62fff19c65abe8c8bcf3000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff1e71260ef8bcc6c51f1c239787d064f7343ad6c13d46ae1f531b7e65e42d25f4000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffa33ce3c2bda5f1eb41021618d02220a4b53c9570af927110ad00b2ec1d181f3d000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffead1c45407f77d5be10162b250a766b78852a1e3a6dfeacaafa9ba71b952e8ca000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aefffffffff6524c85d2e46027150b96127618208f452aadb9280a151a3814e96cfe0eeda8000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff3272d32c6726c0d8e7832a81a45004963816fa766267bfbd8f2be3472be4eb87000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffd76804422b63634232bf6c9167332f624971266f0ba64f54f18a6e25387d1c05000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff61536042ba40f414d6bf37fd37bb2fb1fd113339fb8d3dc949f2ce81a24838cd000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff7b3adff7471a4b6cc20cc2c67d7d3641c081321bced12c2a38c964f5b5d36dd1000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffffc5ebc5f834164162a999b0f18634bd005b8eb8907b3797eb96bbfc3512ea96000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff7de78289699f2b0647782f975b0ca302d71b28c0cf1249e9fbb1333358c3df72000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffd6617ec0e8df31ca26f058cebc010d7fb51b1ec47dac512498579a68b95edcf2000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffbc16a04c0023c369dd6ea3ae05f39b0ac1b50f6a478b9f91fdc42e7a95a83968000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff88f35f104cf71296d2a00ec4c02c06ce17302c56ae343de01a079353850724c2000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffa74d0f1dbd3896bfa741c520440f1e4dfbdfffbf0543054139b86d363b2ae6b6000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffead56c54850af2593ff6622239141682495b0ecfd5badd4f1c0d7d3de33daf89000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffcc22fd95ff59ed6ce1718b2339cd54651d8db4c606dbab72da5ca4b30356d6cd000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffba8753fc928f053eacf65c87166c39347dfac8db948889327ed68199327cb246000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff5a6c597e05330826480f8a3ebbe6133a1ec1faa39b23092c0e217f8ed03fe45e010000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffad8c1807b590febf2cd50b91200512c2b69a7856f6e6de0c2108500ee92d0e3c010000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff188e63b2a1759250b5e96dd65ba9d026ee211df0e88d85373fd93796abecc79f010000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff9486fad379c167671e8dc3ffacfa303b7671cd785cf7ffb664a76e9a0657a993010000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff7289de75d9c8fec95493a62e2d5784bb3ee67b448b82cbfa4cc82ee54eb38b42010000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffffcb8d86d1183a36d3db6d48abcaf3dc8f1028e75f8e13cc089eec78769aa107c2000000002551210212fcb1d3a0ffec857b35fac8e5c63df72d626d66d7484e6c3e857edd0df52a9c51aeffffffff01b54a0400000000001976a914bc55167fcf51cef5d1a9cbddf09919db97ddc4e388ac00000000
I apologize for creating an issue for a simple as this, but I couldn't find anything in the examples to get started.
decoderawtransaction
?I can get each individual part:
$hex = '0100000001ed0674bb77827f2c49354e5ca7e98bda5ab533a4ec71402af0450ad303a4b71f010000006b483045022100b658797b9d64ac1982cd51b1ebed2288e5425fffcb41096b9e66ee23ae4af46c022070ae040118d0cfbca39c70eb6b4750fabc20e8b6cdbd85360e8cae757f213d97012103e80379927edaeec03ead411e7e39f4345406296454d182c41e18b7a45296b64effffffff02fc170000000000001976a91482a105517ee064dab22dd455a52c6ee3ebad307588ace0fe0700000000001976a91441a0b8066150491d51b58ec7045360b5d5950d5088ac00000000';
$tx = TransactionFactory::fromHex($hex);
var_dump($tx->getTxId());
But is there a $tx->decode()
for the full output?
TODO
I'm trying to create a multisig address from three public keys (such as 0379ddc228d8c44a85ae30c877a6b037ec3d627e0507f223a0412790a83a46cd5f) but haven't been able to find how. There is the multisig function in https://github.com/Bit-Wasp/bitcoin-php/blob/master/src/Script/Factory/OutputScriptFactory.php, but it takes instances of PublicKeyInterface as input. Should I convert the string to a PublicKeyInterface, and if so, how can I do that? Sorry if it's a trivial question, I'm pretty new to this. Thanks.
I'll have to see why this is the case - it may only be that way because it worked well during serialization, but my gut says they should be declared in the correct order to avoid confusion when comparing to chainparams files.
If I use code line
$outputScript = ScriptFactory::scriptPubKey()->payToPubKeyHash($privateKey->getPublicKey());
then code falls down with
PHP Catchable fatal error: Argument 1 passed to BitWasp\Bitcoin\Script\Factory\OutputScriptFactory::payToPubKeyHash() must implement interface BitWasp\Buffertools\BufferInterface, instance of BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Key\PublicKey given, called in /tmp/index.php line 18 and defined in /tmp/vendor/bitwasp/bitcoin/src/Script/Factory/OutputScriptFactory.php on line 89
but if i change this code line to
$outputScript = ScriptFactory::scriptPubKey()->payToPubKeyHash($privateKey->getPubKeyHash());
then error does not appears.
It seems to me that getPubKeyHash has to be here, no getPublicKey.
This class is oriented towards dealing with P2SH multisig scripts only. There needs to be a better way of dealing with P2SH, which is far more general than the current focus of class. This is probably connected to having a smart script solver.
P2SH scripts are deferred output scripts. The redeemScript is provided in a redeeming transaction such that the Interpreter class can pop this blob of Script, and execute it as it would an output script. It does this only once the initial output script (the p2sh output funding script, OP_HASH160 OP_EQUAL) evaluates to true if provided the correct redeemScript for this output.
I believe the RedeemScript class could probably be replaced with ScriptInterface, or an extended ScriptInterface which can classify scripts and return appropriately parsed structures.
My worry here is that there may be a strong coupling between script types the library can classify, and it's ability to validate transactions. There is definitely such a coupling for signing transactions.
Note, that the ability to parse an output script is vital to ones ability to sign. If you can't assess the requirements of an output script, you don't know what signatures to provide, and so on. Bitcoin Core avoids this problem by only dealing with standard script types.
By having an extended ScriptInterface, we can take care to use only the simple ScriptInterface throughout validation code, and make use of the extended interface wherever signing is necessary.
I believe a Solver should be able to identify signable inputs to start with, and eventually should be able to suggest the types of parameters which can be passed to complicated scripts.
I am trying to find out values in
https://github.com/Bit-Wasp/bitcoin-php/blob/master/src/Network/NetworkFactory.php
for Dogecoin and Urocoin
$pubKey = '30440220401186e39a8ff0c64a6be2256ed4c818e09ff35ddf60bb1678f6ceaa3268fa5802203ec554c18a3bcf6eed34c279c4057afb04d4b73d2f6dc46ea97d9f6b9a3c7819';
$script = new \BitWasp\Bitcoin\Script\Script(\BitWasp\Buffertools\Buffer::hex($pubKey));
Gives exception:
InvalidArgumentException: Buffer::hex: non-hex character
Why?
Hi. We are using v0.0.7 (in https://github.com/blockcypher/php-client) and that version (v0.0.7) contains this dependency in the composer.json:
mdanter/ecc": "~0.3",
https://github.com/Bit-Wasp/bitcoin-php/blob/v0.0.7/composer.json#L30
That version allows to upgrade to the latest mdanter/ecc version (v.0.4.0). But it seems it does not work with mdanter/ecc version higher than v0.3.1
. Because the API was changed. Thas class Gmp was renamed.
I think the problem should be fixed if you change the dependency to a fixed version on v0.0.7
. The latest one compatible (v0.3.1).
We would try to upgrade to your latest relase asap.
More info about the related issue:
blockcypher/php-client#21 (comment)
Is there any function to make it easy to get the balance of a wallet from a seed, pubkey, prvkey, etc?
Or should I just write my own function to derive the first (variable) addresses and iterate through them and check the balances and add them up?
Is this a function that would be useful within Bitwasp?
In theory, it would accept the seed or pubkey or prvkey, and the number of derived addresses to check, and an optional starting point to allow for a sort of pagination.
I have noticed a lack of wallet related examples in the examples directory, unless I've missed some.
Im am trying to create multisig address from uncompressed and compressed public keys:
040986ca780a396ec974d03309c31b6d79ff4c8ec011859bf13a9fbcc2f33432818df1efef7a23a3237ca7c808bcde554f3e16241dd4cdec16c4ef5329a93d73cc
048777374ae236dc1556a0b35f733c420a1b95e96c2dae33094fc735549942b0180f7018749ee96718c2884d62e38c0a5ff0c84321b36a8b3b33553bb57932be90
037c1eac3fd87aa7c044353272f6cee6a4865067d7900789d4020815dd3aa82762
....
PublicKeyFactory::fromHex($pubKey);
....
$script = ScriptFactory::p2sh()->multisig(2, $pubKeyArray);
print $script->getAddress()->getAddress();
If you work with uncompressed keys only, it'll return the same address than https://coinb.in/#newMultiSig. If one of the addresses is compressed, the address is different.
Does bitcoin-php include a function to decompress a compressed public key before feeding it into PublicKeyFactory::fromHex ? I'd like to avoid the usage of additional modules.
I'm trying to generate wallet addresses based on XPUB I got from electrum-LTC.
Here's what I do (real XPUB from my wallet):
$network = NetworkFactory::litecoin();
$xpub = 'xpub661MyMwAqRbcFg6poD2ucZRPwoNpk9CLYwNvoZCGUp1Y6eYNoN64LryZuxDdnm9XViSoSbaspae4yHXAmVVFNJmXbPce1RY4aUDdZiSTBaQ';
$hk = HierarchicalKeyFactory::fromExtended($xpub, $network);
$master = $hk->derivePath("0/0");
$address = $master->getPublicKey();
echo $address->getAddress()->getAddress();
It produces this error:
An uncaught Exception was encountered
Type: InvalidArgumentException
Message: HD key magic bytes do not match network magic bytes
Filename: <path to my project>/bitcoin-php/Serializer/Key/HierarchicalKey/HexExtendedKeySerializer.php
Line Number: 98
Backtrace:
File: <path to my project>/bitcoin-php/Serializer/Key/HierarchicalKey/HexExtendedKeySerializer.php
Line: 117
Function: fromParser
File: <path to my project>/bitcoin-php/Serializer/Key/HierarchicalKey/ExtendedKeySerializer.php
Line: 43
Function: parse
File: <path to my project>/bitcoin-php/Key/Deterministic/HierarchicalKeyFactory.php
Line: 67
Function: parse
File: <path to my project>/myscript.php
Line: 46
Function: fromExtended
The above code works perfectly fine when using bitcoin network and XPUB from my bitcoin Electrum wallet.
P.S. I tried to add dogecoin network to NetworkFactory class and it gave me the same exact error though I believe the values are correct.
public static function dogecoin()
{
$network = NetworkFactory::create('1e', '16', '9e')
->setHDPubByte('02fd3929')
->setHDPrivByte('02fd3955')
->setNetMagicBytes('c0c0c0c0');
}
can I use this library to generate address, private and public key for testnet?
I asked in stackexchange, but after this I thought that there is better place for this question.
Am I misunderstanding something? The Deterministic/HierarchicalKey code allows you to get the deterministic child pubkey along with its associated private key.
There doesn't seem to be the same option for ElectrumKey
The Docblock at https://github.com/Bit-Wasp/bitcoin-php/blob/master/src/Key/Deterministic/ElectrumKey.php#L100 says that the deriveChild function should return both a PrivateKeyInterface and a PublicKeyInterface, but all I'm getting back is BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Key\PublicKey
Thoughts?
I'm trying to get a given transaction signed. It's a 3 of 4 multisignature transaction, and has 1 sign on it. I want to enter its hex code and a private key and get the returned transaction, but I get the "Signing with the wrong private key" error. I'm sure that they match. What am I doing wrong?
Here's the code:
$myTransaction = TransactionFactory::fromHex($transaction);
$myPrivateKey = PrivateKeyFactory::fromHex($privateKey, $compressed = TRUE);
$txOut = $myTransaction->getOutput(0);
$ec = \BitWasp\Bitcoin\Bitcoin::getEcAdapter();
$signed = (new Signer($myTransaction, $ec))
->sign(0, $myPrivateKey, $txOut)
->get();
Thanks.
I am working on creating a script that will scrape a few blockchain websites such as blockchain.info, blockr.io, etc.. From scraping I am taking the transaction ID and the Vout to build a transaction that I can then sign. The code below code is intended to get the inputs list with the transaction id and Vout and convert it into a bitcoin-php transaction factory. Once converted it will be signed with one private key and then displayed to the user in order to sign with a final key.
With my current code I am getting an error saying "Catchable fatal error: Argument 1 passed to BitWasp\Bitcoin\Transaction\TransactionInput::__construct() must be an instance of BitWasp\Bitcoin\Transaction\OutPointInterface, string given, called in \php\bitcoin.php on line 80 and defined in \php\bitwasp\src\Transaction\TransactionInput.php on line 38"
Let me know if something is not clear, and thanks for any help. Below is most of the code I am using excluding the website scraping
...
function createinputlist($pubkeyone,$pubkeytwo,$privatekey, $inputlist){
$private = PrivateKeyFactory::fromWif($privatekey);
$redeemScript = ScriptFactory::scriptPubKey()->multisig(2, [PublicKeyFactory::fromHex($pubkeyone),PublicKeyFactory::fromHex($pubkeytwo),$private->getPublicKey()]);
$p2sh = ScriptFactory::create()->push($redeemScript->getBuffer())->getScript();
$inputs = array();
foreach($inputlist as $transaction){
$inputs[] = new TransactionInput($transaction['txid'], $transaction['vout'], $p2sh);
}
return $inputs;
}
function createrawtx($orderid, $escrowaddress, $escrowamount, $refundaddress, $refundamount){
$ecAdapter = Bitcoin::getEcAdapter();
require_once("market.php");
$depositinfo = getdepositinfo($orderid);
$pk1 = PrivateKeyFactory::fromWif($depositinfo['privatekey']);
$rs = new Script(Buffer::hex($depositinfo['redeemscript']));
$redeemScript = new \BitWasp\Bitcoin\Script\P2shScript($rs);
$os = $redeemScript->getOutputScript();
// One party wants to spend funds. He creates a transaction spending the funding tx to his address.
$spendTx = TransactionFactory::build()
->input(createinputlist($depositinfo['publickeyone'], $depositinfo['publickeytwo'], $depositinfo['privatekey'], getinputs($depositinfo['multisig'])))
->payToAddress($escrowamount, AddressFactory::fromString($escrowaddress))
->payToAddress($refundamount, AddressFactory::fromString($refundaddress))
->get();
$signer = TransactionFactory::sign($spendTx);
$signer
->sign(0, $pk1, $os, $redeemScript);
$signed = $signer->get();
return $signed->getHex();
}
...
Until now I've been making loose releases every time there is an API break. I have resigned to using 0.0.* whilst the library is still in flux, but it's starting to reach maturity now.
I'll probably try follow this strategy for branching http://nvie.com/posts/a-successful-git-branching-model/ mainly so breaks come at reasonable intervals.
Thank you for providing this great library!
From Javascript Libraries I know simple ways to retrieve the respective output addresses in transactions. E.g. (https://github.com/bitpay/bitcore-lib/blob/master/lib/script/script.js#L977)
Unfortunately, I couldn't find an easy way with the API to do a similar thing. Could somebody give me a hint how to achieve this?
The example doesn't work anymore. TransactionFactory doesn't seem to allow getHex() (line 15)
Too bad, it was such a clear and simple example. A lot of the other examples are segwit focused.
Affects parsing and serialization.
First off, Thank you for this amazing library, It makes life much easier!
Secondly; is it possible to use the multisig.HD example to generate a multisig wallet that could be imported into Electrum?
I feel that it should just be a matter of changing the derivePath variable, but I also see the Electrum Key that does not look compatible with the multisig.HD example. Due to my lack on knowledge I thought I'd just ask.
Excuse me, I was not online last weeks. Thank you for the answer, situation is more understandable.
It seems to me that in last case it's better to return that addresses, which it is possible to extract from scriptpubkey (like in https://github.com/bitcoin/bitcoin/blob/8152d3fe57a991e9088d0b9d261d2b10936f45a9/src/script/standard.cpp#L228
), but, certainly it's IMHO only.
But story is not finished yet :(. Try please to execute next snippet of code (based on
https://www.blocktrail.com/BTC/tx/d01a99b5cf7b258d1431822b0fe151772023ca525269369ce6157bf6e32041cb?txoutIdx=3
):
<?php
require __DIR__ . "/../vendor/autoload.php";
$hex = "5141046102da5b459ddd9db7da926ea5a80efb4e13260f155566193f401c9f182e2862df3829aafbc8b014eba374c70d1d2b94cd08f887a29b1aa55ad4e31f906eba252102b31fd38ae163eeaeeec62aca9e39fd925128b6cb4d579f2a50795d3418cff92752ae";
$script = new \BitWasp\Bitcoin\Script\Script(\BitWasp\Buffertools\Buffer::hex($hex));
$solutions = null;
$decoded = $script->getScriptParser()->decode();
$classifier = new \BitWasp\Bitcoin\Script\Classifier\OutputClassifier();
$type = $classifier->classify($script,$solutions);
print "type = " . $type . PHP_EOL;
print "size of soultions = " . count($solutions) . PHP_EOL;
$a1 = BitWasp\Bitcoin\Key\PublicKeyFactory::fromHex($solutions[0])->getAddress()->getAddress();
$a2 = BitWasp\Bitcoin\Key\PublicKeyFactory::fromHex($solutions[1])->getAddress()->getAddress();
Code fails:
username@machinename:~/bitcoinphp-lib/tests$ php multisig1.php
type = multisig
size of soultions = 2
PHP Fatal error: Uncaught exception 'LogicException' with message '36126036814164657098511955728052231927830236627713106616318751105840950552302 has no square root modulo 115792089237316195423570985008687907853269984665640564039457584007908834671663' in /home/username/bitcoinphp-lib/vendor/mdanter/ecc/src/Math/NumberTheory.php:197
Stack trace:
#0 /home/username/bitcoinphp-lib/vendor/mdanter/ecc/src/Primitives/CurveFp.php(125): Mdanter\Ecc\Math\NumberTheory->squareRootModP(Object(GMP), Object(GMP))
#1 /home/username/bitcoinphp-lib/vendor/bitwasp/bitcoin/src/Crypto/EcAdapter/Impl/PhpEcc/Adapter/EcAdapter.php(331): Mdanter\Ecc\Primitives\CurveFp->recoverYfromX(false, Object(GMP))
#2 /home/username/bitcoinphp-lib/vendor/bitwasp/bitcoin/src/Crypto/EcAdapter/Impl/PhpEcc/Serializer/Key/PublicKeySerializer.php(87): BitWasp\Bitcoin\Crypto\EcAdapter\Impl\PhpEcc\Adapter\EcAdapter->publicKeyFromBuffer(Object(BitWasp\Buffertools\Buffer))
#3 /home/username/bitcoinphp-lib/vendor/bitwasp/bitcoin/src/Key/PublicKeyFactory.php(29): BitWasp\Bitcoin\Crypto in /home/username/bitcoinphp-lib/vendor/mdanter/ecc/src/Math/NumberTheory.php on line 197
My php version:
$ php --version
PHP 5.6.11-1ubuntu3.4 (cli)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
In the same time:
bitcoind@machinename:/home/username$ bitcoin-cli decodescript 5141046102da5b459ddd9db7da926ea5a80efb4e13260f155566193f401c9f182e2862df3829aafbc8b014eba374c70d1d2b94cd08f887a29b1aa55ad4e31f906eba252102b31fd38ae163eeaeeec62aca9e39fd925128b6cb4d579f2a50795d3418cff92752ae
{
"asm": "1 046102da5b459ddd9db7da926ea5a80efb4e13260f155566193f401c9f182e2862df3829aafbc8b014eba374c70d1d2b94cd08f887a29b1aa55ad4e31f906eba25 02b31fd38ae163eeaeeec62aca9e39fd925128b6cb4d579f2a50795d3418cff927 2 OP_CHECKMULTISIG",
"reqSigs": 1,
"type": "multisig",
"addresses": [
"18888888PPJ8oGeqR6AKmoiKUme9da48Xf",
"1NLj9gQZwTQBgNApxqcA7fM41E8usnUsXg"
],
"p2sh": "3BySBpZgkeirer6SDBhogQYy6LMEG8b3vc"
}
How could you comment this behaviour?
Can anyone share php code for getting xpriv (extended private key) from mnemonic for $i address?
This must be pretty simple but I still cannot figure out the code. Please help!
Linux Mint 17.3, PHP 5.6 ( Ondrej/php PPA )
Problem 1
- bitwasp/bitcoin v0.0.29.1 requires mdanter/ecc ~0.4 -> satisfiable by mdanter/ecc[v0.4.0].
- Installation request for bitwasp/bitcoin v0.0.29.1 -> satisfiable by bitwasp/bitcoin[v0.0.29.1].
- Conclusion: remove paragonie/random_compat 1.0.10
- Conclusion: don't install paragonie/random_compat 1.0.10
- mdanter/ecc v0.4.0 requires paragonie/random_compat 1.4.1|2.0.2 -> satisfiable by paragonie/random_compat[v1.4.1, v2.0.2].
- Can only install one of: paragonie/random_compat[v1.4.1, 1.0.10].
- Can only install one of: paragonie/random_compat[v2.0.2, 1.0.10].
- Installation request for paragonie/random_compat (locked at 1.0.10) -> satisfiable by paragonie/random_compat[1.0.10].
$ecAdapter = Bitcoin::getEcAdapter();
$private_key = PrivateKeyFactory::fromWif('wif_private_key');
// from address1 to address2
$transaction = TransactionFactory::build()
->input('address1 unspet tx',$out)
->payToAddress('$amount',AddressFactory::fromString('address2'))
->payToAddress('$amount',AddressFactory::fromString('address1'))
->get();
And then ? How to sign it?
Logging some thoughts here before I forget: I added these because you need to inject information about the txOut, mainly the script, when you're trying to spend.
Currently the only method which relies on this is TransactionBuilder::signInputWithKey().
With how I'm approaching things now, it may be best to explicitly provide the output script.
Also, the signInputWithKey method could be refactored so payToScriptHash is treated as a special case, since the redeemScript is substituted for the output script in places, or at least can derive the output script.
Certain things like a transactionID should be strictly checked for content when set via constructors.. Just a note for later!
Hi
When I use the composer install command the install fails and I get this, (I am using laravel 4)
Problem 1
- bitwasp/bitcoin v0.0.23 requires mdanter/ecc ~0.3 -> satisfiable by mdanter/ecc[v0.3.0].
- Installation request for bitwasp/bitcoin ^0.0.23 -> satisfiable by bitwasp/bitcoin[v0.0.23].
- Conclusion: remove symfony/console v2.5.12
- Conclusion: don't install symfony/console v2.5.12
- mdanter/ecc v0.3.0 requires symfony/console ~2.6 -> satisfiable by symfony/console[v2.6.0, v2.6.1, v2.6.10, v2.6.11, v2.6.12, v2.6.13, v2.6.2, v2.6.3, v2.6.4, v2.6.5, v2.6.6, v2.6.7, v2.6.8, v2.6.9, v2.7.0, v2.7.1, v2.7.10, v2.7.11, v2.7.12, v2.7.13, v2.7.2, v2.7.3, v2.7.4, v2.7.5, v2.7.6, v2.7.7, v2.7.8, v2.7.9, v2.8.0, v2.8.1, v2.8.2, v2.8.3, v2.8.4, v2.8.5, v2.8.6].
- Can only install one of: symfony/console[v2.6.0, v2.5.12].
- Can only install one of: symfony/console[v2.6.1, v2.5.12].
- Can only install one of: symfony/console[v2.6.10, v2.5.12].
- Can only install one of: symfony/console[v2.6.11, v2.5.12].
- Can only install one of: symfony/console[v2.6.12, v2.5.12].
In Ruby there is a bitcoin gem.
How i can reproduce next code within your library and is that is possible?
keypair = Bitcoin.open_key priv_key sig = Bitcoin.sign_data(keypair, [sighash].pack("H*"))
Please advice, thank you for your work
Really great lib! Thank you very much for it!
I have some question (It seems as bug, but I am not sure, provide some comment please):
I need to extract addresses/address from multisig-scriptPubKey
For example, scriptPubKey =
5141046102da5b459ddd9db7da926ea5a80efb4e13260f155566193f401c9f182e2862df3829aafbc8b014eba374c70d1d2b94cd08f887a29b1aa55ad4e31f906eba2521204348414e4345434f00000028000000000bebc200404b8000000000003ffccccc52ae
(this scriptPubKey is from btc-transaction with hash 0000a524025cca89db9743a6ec940d2a987bbb7f19f392adb3912b85c7a9a12f )
or scriptPubKey =
512102fa6ddd34c184151a1868f5233bb77e5efd9b5aa88885825c3c84cc8863fe0b69211c434e54525052545900000000000000000004ebdf000000389f40e9800000000052ae
(this scriptPubKey is from btc-transaction with hash 0000fa31b80b4da025c65c32f06881e321d8eefcd949e0e96deb6e43b9bfc219 )
Next code:
`
`
Raised RuntimeException: Script type is not associated with an address
I tried to use
`
$solutions = null;
$type = (new OutputClassifier())->classify($script,$solutions);
instead
$address = \BitWasp\Bitcoin\Address\AddressFactory::getAssociatedAddress($script);
`
but $type had value "nonstandard" and $solutions variable had null value after executing of this code.
Meanwhile we can see output of bitcoin-daemon
bitcoind@machinename:/home/username$ bitcoin-cli decodescript 5141046102da5b459ddd9db7da926ea5a80efb4e13260f155566193f401c9f182e2862df3829aafbc8b014eba374c70d1d2b94cd08f887a29b1aa55ad4e31f906eba2521204348414e4345434f00000028000000000bebc200404b8000000000003ffccccc52ae
{
"asm": "1 046102da5b459ddd9db7da926ea5a80efb4e13260f155566193f401c9f182e2862df3829aafbc8b014eba374c70d1d2b94cd08f887a29b1aa55ad4e31f906eba25 204348414e4345434f00000028000000000bebc200404b8000000000003ffccccc 2 OP_CHECKMULTISIG",
"reqSigs": 1,
"type": "multisig",
"addresses": ["18888888PPJ8oGeqR6AKmoiKUme9da48Xf"],
"p2sh": "3Ev41axPPvCjsbzrQMVzhCNimiJxViRyo9"
}
So this output has destination address = 18888888PPJ8oGeqR6AKmoiKUme9da48Xf.
How could I extract this address using your library?
Additionly I have to note that if I'll try to extract addresses from the output with the multisig scriptPubKey
(with several destination addresses) - then glory and victory:
`
$script = \BitWasp\Bitcoin\Script\ScriptFactory::fromHex("514104f71366b5cbfb2f87227658cfde6294f02ebb3babcdbc1723f35ed846489e7b5a8565e891096a0f2583160cb19b4ed17d0853fc99cf7412c6041e5b2117e78f2921022d7f68ac457d834fb67a112f3571da0eb6365d4c0523f9f74b298096160a02f752ae");
$solutions = null;
$type = (new OutputClassifier())->classify($script,$solutions);
//$type = multisig
$a1 = PublicKeyFactory::fromHex($solutions[0])->getAddress()->getAddress();
//$a1 = "1MaStErt4XsYHPwfrN9TpgdURLhHTdMenH"
$a2 = PublicKeyFactory::fromHex($solutions[1])->getAddress()->getAddress();
//$a2 = "1MeMwGjff7uG9hHKAE1jJFeGRdfMxNkovX"
`
bitcoind@machinename:/home/username$ bitcoin-cli decodescript 514104f71366b5cbfb2f87227658cfde6294f02ebb3babcdbc1723f35ed846489e7b5a8565e891096a0f2583160cb19b4ed17d0853fc99cf7412c6041e5b2117e78f2921022d7f68ac457d834fb67a112f3571da0eb6365d4c0523f9f74b298096160a02f752ae
{
"asm": "1 04f71366b5cbfb2f87227658cfde6294f02ebb3babcdbc1723f35ed846489e7b5a8565e891096a0f2583160cb19b4ed17d0853fc99cf7412c6041e5b2117e78f29 022d7f68ac457d834fb67a112f3571da0eb6365d4c0523f9f74b298096160a02f7 2 OP_CHECKMULTISIG",
"reqSigs": 1,
"type": "multisig",
"addresses": ["1MaStErt4XsYHPwfrN9TpgdURLhHTdMenH","1MeMwGjff7uG9hHKAE1jJFeGRdfMxNkovX"],
"p2sh": "3HtwSa6Dnwnbcfaejc8nu7JsoHuWTZUBrr"
}
Results (at least in context of destination addresses are equal).
Running this sample:
https://github.com/Bit-Wasp/bitcoin-php/blob/master/examples/offlinetx.p2pkh.testnet.php
I get this warning:
Warning: gmp_init(): Unable to convert variable to GMP - wrong type in C:\Users\Jose\Projects\BlockCypher\php-client\vendor\mdanter\ecc\src\Math\Gmp.php on line 281
Link to the warning line:
https://github.com/mdanter/phpecc/blob/master/src/Math/Gmp.php#L281
And the problem seems to be this:
phpecc/phpecc#90
(passing double to gmp_init)
Hello,
I would like to create a multisig address from 2 public keys .
I have been trying to get this work, it is pretty simple I think but I cannot get it work.
`require DIR . "/../../../../vendor/autoload.php";
use BitWasp\Bitcoin\Bitcoin;
use BitWasp\Bitcoin\Address\AddressFactory;
use BitWasp\Bitcoin\Key\PrivateKeyFactory;
use BitWasp\Bitcoin\Script\ScriptFactory;
use BitWasp\Bitcoin\Script\Factory;
use BitWasp\Bitcoin\Key\PublicKeyFactory;
use BitWasp\Bitcoin\Network\NetworkFactory;
use BitWasp\Buffertools\Buffer;
use BitWasp\Bitcoin\Script\Factory\OutputScriptFactory;
$privateKey1 = PrivateKeyFactory::fromHex('5bce4b3976d53b7cc3743e488f28ea023995332ab36758d3a2411783796b7ec0', true);
$privateKey2 = PrivateKeyFactory::fromHex('48fdcb0d50826f876d9487d31e03124846b735f756914df7b6aa2cb70c4a68c9', true);
echo '
';
echo $privateKey1->getAddress()->getAddress();
echo '
';
echo $privateKey2->getAddress()->getAddress();
echo '
';
$redeemScript = ScriptFactory::p2sh()->multisig(2, array($privateKey1->getPublicKey()->getHex(), $privateKey2->getPublicKey()->getHex()));
print $redeemScript->getAddress()->getAddress();`
But I cannot get it work, can anyone give me advice about how to solve this issue?
All kind of help is appreciated.
The Electrum API supports arrays of addresses [1] for functions such as blockchain.address.get_history, blockchain.address.get_balance, blockchain.address.listunspent, blockchain.transaction.get
[1] http://docs.electrum.org/en/latest/protocol.html#request
/src/Rpc/Client/ElectrumServer.php only accepts a single AddressInterface object for those functions.
Your /src/Rpc/Client/Bitcoind.php implementation has a clever way of dealing with this on line 187 where you can pass an array of AddressInterface objects which it them uses array_map and a function to process the objects into strings using $address->getAddress($network)
Could the applicable functions in the ElectrumServer class be changed to have a similar ability?
I could take a crack at the code but you're a superior coder and I think you would be more effective. If you like, I can try.
This would be a breaking change since existing code that implements those functions are just passing a singular object rather than an array, so it won't be backwards compatible unless instead of altering the existing functions, new functions were created such as
addressListUnspentArray
Function should fetch getblockcount,
not bestblockhash
/**
* @return int
*/
public function getblockcount()
{
$count = $this->client->execute('getblockcount');
return $count;
}
I've spent a few days trying to build and sign a transaction with BitWasp, but I can't get past this error. This example has the following code
$outputScript = ScriptFactory::scriptPubKey()->payToPubKeyHash($privateKey->getPublicKey());
But this statement returns the following error
Uncaught TypeError: Argument 1 passed to BitWasp\Bitcoin\Script\Factory\OutputScriptFactory::payToPubKeyHash() must implement interface BitWasp\Buffertools\BufferInterface, instance of BitWasp\Bitcoin\Crypto\EcAdapter\Impl\Secp256k1\Key\PublicKey given, called in /tmp/test.php on line 17 and defined in /home/orangepi/bitcoin-php/src/Script/Factory/OutputScriptFactory.php:90 Stack trace:
I cannot figure out how to get past this.
While I read the code and the documentation I see that there is a way to use testnet
but I can't seem to find a way for regtest
network.
So can I use regtest
network with this library?
I don't have a lot of knowledge about the difference between regtest
network and the main
one.
Hi when I create an xpub with the Litecoin electrum wallet, I notice there's a slight difference in address.
When I do
$network = NetworkFactory::litecoin();
$xpub = .....
$hk = HierarchicalKeyFactory::fromExtended($xpub, $network);
I get a Base58ChecksumFailure
Love that you're moving from mcrypt to paragonie/random_compat, but the required version (~2.0) is causing a problem with Laravel.
Laravel is stuck on the paragonie/random_compat ~1.4 stable branch.
Can you test BitWasp to see if it works with the 1.4 branch and then before the next release do it this way in the composer.json?
"paragonie/random_compat": "~1.4|~2.0",
Forgive my ignorance.
I'm using the BitWasp library to work with BIP0032 HD wallets and it's doing great. I want to work with BIP0044 wallets.
They're basically BIP0032 wallets but with deeper hierarchy levels in order to standardize what the different hierarchies mean (coin type, account, account, chain, and address).
Any anticipated problems using BitWasp with this before I dive into implementation? Are there any functions or accessible objects that would make working with BIP0044 easier?
If it does work, you might want to add BIP0044 to the Implemented BIPs list.
When I try to extract the address from the public key in an input script, Secp256k1 fails to parse it.
// $transaction is a BitWasp\Bitcoin\Transaction\Transaction
foreach ($transaction->getInputs() as $input) {
$script = $input->getScript();
$classifier = new BitWasp\Bitcoin\Script\Classifier\InputClassifier($script);
if ($classifier->isPayToPublicKeyHash()) {
$decoded = $script->getScriptParser()->decode();
$hex_buffer = $decoded[1]->getData();
$public_key = PublicKeyFactory::fromHex($hex_buffer);
// Exception thrown: Secp256k1 failed to parse public key
}
}
Is this because Secp256k1 doesn't handle a compressed public key properly?
Hey, I'm trying to add this package with composer require bitwasp/bitcoin
but I keep getting bitwasp/bitcoin v0.0.4 requires mdanter/ecc dev-master -> no matching package found
. Any thoughts?
Btw thanks for the awesome work. I think it'll be incredibly useful for https://github.com/anonymart/anonymart
Not sure if this is the best place to post this, but I was using bitcoin-php, and was trying to figure out how to import a redeemscript. Basically I already have the redeemscript and multisig address created with a transaction input. I was trying to figure out how to import the redeemscript into the right class and then simply spend the one input.
Great xpub libs! Thank you very much for them!
I have a list of indexes to which payments were made: 1137's, 93924's, 427104's, 17480001's addresses etc. Usual gap limit for the majority of wallets is 20. I need to be able to spend from exact index of the multitude of addresses.
GAE doesn't support gmp. Maybe you know how to install gmp to GAE?
Uncaught Error: Class 'HierarchialKeyFactory' not found in ...
$pubKey = '30440220401186e39a8ff0c64a6be2256ed4c818e09ff35ddf60bb1678f6ceaa3268fa5802203ec554c18a3bcf6eed34c279c4057afb04d4b73d2f6dc46ea97d9f6b9a3c7819';
$publicKey = BitWasp\Bitcoin\Key\PublicKeyFactory::fromHex($pubKey);
Gives exception:
Invalid hex string, must match size of compressed or uncompressed public key
bitwasp/bitcoin/src/Crypto/EcAdapter/Impl/PhpEcc/Serializer/Key/PublicKeySerializer.php on line 83
Why?
I'm in the process of trying to create a transaction, and have multiple parties sign it. I'm fairly sure I'm just not doing something correct; But I have the following code; which generates a transaction; and I'm able to sign it; but it ends up not being a valid transaction.
I did remove the other private key signing, but it follows the same as the first.
/*
* First Request
*/
//Build Wallet
$keys = array(
HierarchicalKeyFactory::fromExtended("xpub661MyMwAqRbcGL2QoVnUfWuSrF9VM2MTvvCr6RrV8NWJRqYbxkmNULpGf1aHcjV7z7ownfg4hv5cr49FPd5TEUZeYRkbjPtsNniRHV34ufS"),
HierarchicalKeyFactory::fromExtended("xpub661MyMwAqRbcEv4MBs7yVyrQWFxuqLgcAn8K6an8pyrLbqCWNfwDySDuEqWcEnUYU5ZPkRBHm4idyZw6fBt1xscEkbNNBMwK7pEmg3Ttv4k"),
HierarchicalKeyFactory::fromExtended("xpub661MyMwAqRbcGL92A9hhGZc17vrf4UXdvg3syTCtxDnGP1jop8k3NS4nxKXmonVn1KFP5zfoqpJ4uSJDoyzbBYpYMpcCc7ZKwR3KH5ZWsJH")
);
$ecAdapter = Bitcoin::getEcAdapter();
$sequences = new HierarchicalKeySequence();
$masterWallet = new MultisigHD(2,'m',$keys,$sequences,true);
$transactionWallet = $masterWallet->derivePath("0/0");
echo "1) Funds Were Sent To: ".$transactionWallet->getAddress()->getAddress();
echo PHP_EOL;
//Build Transaction
$utx = array(
'tx_hash' => 'db98592de692c251ef3c4c3336741e3236f791a9deb62851467d3fbd6191f52c',
'tx_hash_le' => '2cf59161bd3f7d465128b6dea991f736321e7436334c3cef51c292e62d5998db',
'tx_index' => 220648228,
'tx_output_n' => 0,
'script' => 'a9146e360babf021eb1886dc7478078a5aabbf403b6187',
'value' => 0.00110000,
'value_hex' => '01adb0',
'confirmations' => 382
);
$txAddress = AddressFactory::fromString("1hMQLE6PokBcnfbS9f4FUia9DH4jKUtXQ");
$outPoint = new OutPoint(Buffer::hex($utx['tx_hash'],32),$utx['tx_output_n']);
$tx = (new TxBuilder())
->spendOutPoint($outPoint)
->PayToAddress(intval($utx['value']*100000000), $txAddress)
->get();
echo "2) Unsigned Transaction Hex: ".$tx->getHex();
echo PHP_EOL;
/*
* Second Request
*/
// Sign Transaction 1
$keys2 = array(
HierarchicalKeyFactory::fromExtended("xprv9s21ZrQH143K3qwwhUFUJNxiJDJzwZdcZhHFJ3Ssa2yKZ3DTRDT7vYVnohBS6yVBLjXAH4pncos2RWQAFWZCgL5itT23RX2CT4nyFFet5QH"),
HierarchicalKeyFactory::fromExtended("xpub661MyMwAqRbcEv4MBs7yVyrQWFxuqLgcAn8K6an8pyrLbqCWNfwDySDuEqWcEnUYU5ZPkRBHm4idyZw6fBt1xscEkbNNBMwK7pEmg3Ttv4k"),
HierarchicalKeyFactory::fromExtended("xpub661MyMwAqRbcGL92A9hhGZc17vrf4UXdvg3syTCtxDnGP1jop8k3NS4nxKXmonVn1KFP5zfoqpJ4uSJDoyzbBYpYMpcCc7ZKwR3KH5ZWsJH")
);
$tx2 = signTx($keys2, $tx, $utx);
echo "3) One Sig Transaction Hex: ".$tx2->getHex();
echo PHP_EOL;
echo " Raw Script Hex: ".$tx2->getInputs()[0]->getScript()->getHex();
echo PHP_EOL;
echo " Decoded Script: ".$tx2->getInputs()[0]->getScript()->getScriptParser()->getHumanReadable();
echo PHP_EOL;
$keys3 = array(
HierarchicalKeyFactory::fromExtended("xpub661MyMwAqRbcGL2QoVnUfWuSrF9VM2MTvvCr6RrV8NWJRqYbxkmNULpGf1aHcjV7z7ownfg4hv5cr49FPd5TEUZeYRkbjPtsNniRHV34ufS"),
HierarchicalKeyFactory::fromExtended("xprv......"),
HierarchicalKeyFactory::fromExtended("xpub661MyMwAqRbcGL92A9hhGZc17vrf4UXdvg3syTCtxDnGP1jop8k3NS4nxKXmonVn1KFP5zfoqpJ4uSJDoyzbBYpYMpcCc7ZKwR3KH5ZWsJH")
);
$tx3 = signTx($keys3, $tx2, $utx);
echo "4) Two Sig Transaction Hex: ".$tx2->getHex();
echo PHP_EOL;
echo " Raw Script Hex: ".$tx3->getInputs()[0]->getScript()->getHex();
echo PHP_EOL;
echo " Decoded Script: ".$tx3->getInputs()[0]->getScript()->getScriptParser()->getHumanReadable();
echo PHP_EOL;
function signTx($keys, $tx, $utx){
$ecAdapter = Bitcoin::getEcAdapter();
$sequences = new HierarchicalKeySequence();
$masterWallet = new MultisigHD(2,'m',$keys,$sequences,true);
$transactionWallet = $masterWallet->derivePath("0/0");
foreach($transactionWallet->getKeys() as $key){
if(strpos(substr($key->toExtendedKey(),0,4),"xprv") !== false){
$signingKey = $key->getPrivateKey();
}
}
$txOut = new TransactionOutput($utx['value']*100000000, $transactionWallet->getRedeemScript());
$signed = (new Signer($tx, $ecAdapter))
->sign(0,$signingKey,$txOut);
$tx = $signed->get();
return $tx;
}
Again, Please forgive my lack of knowledge on the subject, but hopefully you will be able to assist in resolving this and maybe it can become an example?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.