Bitcoin Forum
June 14, 2024, 10:29:44 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: 2 BTC Bounty: PHP / JSON-RPC Sweep Key Function  (Read 1954 times)
🏰 TradeFortress 🏰 (OP)
Bitcoin Veteran
VIP
Legendary
*
Offline Offline

Activity: 1316
Merit: 1043

👻


View Profile
June 05, 2013, 10:11:53 AM
Last edit: June 20, 2013, 07:02:49 AM by TradeFortress
 #1

Given a private key, a sweep to address and a RPC connection to Bitcoin-Qt, this function must send all the coins to the sweep to address, paying the appropriate network fee.

1.5 2 BTC bounty. Note: Cannot make use of costly wallet reindex operations.
bitspill
Legendary
*
Offline Offline

Activity: 2086
Merit: 1015



View Profile
June 17, 2013, 03:42:03 AM
 #2

Given a sweep address, a sweep to address and a RPC connection to Bitcoin-Qt, this function must send all the coins to the sweep to address, paying the appropriate network fee.

1.5 BTC bounty.
1) By sweep you mean to take the entire balance of "Address A" and send it to "Address B", correct?
2) "Appropriate network fee" Would you like that exposed as a parameter to the method or calculated somehow based upon the size of the transaction?


As of right now I have a crude but functional implementation that needs some error checking and other improvements.

{ BitSpill }
bitspill
Legendary
*
Offline Offline

Activity: 2086
Merit: 1015



View Profile
June 18, 2013, 08:00:41 AM
 #3

Well, I feel it is mostly complete now and the fee is exposed as a parameter however if it is -1 then the fee is calculated based upon tx size.

Would you prefer I PM you, or post the code here publicly?

{ BitSpill }
Evolyn
Sr. Member
****
Offline Offline

Activity: 376
Merit: 312


Can you say... nighty-night?


View Profile
June 21, 2013, 01:41:39 AM
Last edit: June 21, 2013, 01:55:06 AM by Evolyn
 #4

was a bit bored and cannot sleep (hope there are no major mistakes Shocked)... had not tested the code, usage with caution and on your own risk!

i think the most difficult part is done ^.-

guess bitspill uses importprivkey and this is no option if i get the task right

todo:
- generating public address from given private key needs to be added
- may the script transform into a function
- ... aaand errorhandling!

i'm posting the code public, so everyone can blame me, can improve the code and benefit from it and one can get the bounty for finishin' the work :x

requirements:
- bitcoind/bitcoin-qt >= 0.7
- php >= 5.2.0

Code:
<?php

// guess this part is already done ^.^
$require_once("oneoftheserpclibs");
$rpc=new jsonRPCClient(...);
//


// -- user inputs?
$privatekey="";
$publickey=""; // replacing later to generate publickey from privatekey
$sweep="";
// -- user inputs end


// -- settings
$fee_per_kb=0.0001;
$value_min=0; // mabe change from 0 to 0.00005430 due to 0.8.2?
// -- settings end


// -- main part
$unspent_data=json_decode(file_get_contents("http://blockchain.info/unspent?active=".$publickey),true); // you have to get the unspent data from somewhere, rescan is no option, so pull from somewhere else, in this case, blockchain.info

$txs=array();
$txs_s=array();
$value=0.0;
foreach(
$unspent_data AS $k=>$v) // now parse the unspent data and prepare to send ;)
{
$txs[]=array("txid"=>$v['tx_hash'],"vout"=>$v['tx_output_n']);
$txs_s[]=array("txid"=>$v['tx_hash'],"vout"=>$v['tx_output_n'],"scriptPubKey"=>$v['script']);
$value+=($v['value']*1e8);
}
$fee=$fee_per_kb*ceil((count($txs)*181+74)/1024); // very simple calculating size and fee, should be enough in this case
$value-=$fee;
$recipients=array($sweep=>$value);

if(
$value>$value_min&&!empty($txs)) // only checking if real sending value is greater then 0/min and if inputs are given before creating the transaction, sign' and sending
{
$rawtransaction=$rpc->createrawtransaction($txs,$recipients);
$signed_transaction=$rpc->signrawtransaction($rawtransaction,$txs_s,array($privatekey));
if($signed_transaction['complete']==1)
{
$rpc->sendrawtransaction($signed_transaction['hex']);
}
}
// -- main part end

?>


edit: few typos

Forex meets Bitcoin Exchange: Release the Kraken
bitspill
Legendary
*
Offline Offline

Activity: 2086
Merit: 1015



View Profile
June 21, 2013, 02:06:47 AM
 #5

I actually implemented a sweep address not sweep privkey as was orifinally posted however by PM he said that was an erro on his part it should have stated a sweep privkey as it does now, and and he sent me 0.5 BTC.

Here was my code for free use:
Code: (php)
/**
 * Take the entire Balance of Address A and send it to Address B
 *
 * @param jsonRPCClient $jsonrpc A valid jsonRPCClient connected to bitcoind
 * @param string $addrA Address to sweep
 * @param string $addrB Address to receive swept funds
 * @param int $fee Fee to be applied (satoshis), is computed as ($perkb * size in kb) if $fee == -1
 *  else it is applied directly
 * @param int $perkb Fee (satoshis) to be applied per kb of transaction size
 * @param int $minconf Minimum number of confirmations required to be swept
 * @return array Result contains 2 elements, success and either message or txid.
 *  If success == true then txid contains the transaction id else message contains the error
 */
function sweepBTC($jsonrpc, $addrA, $addrB, $fee = -1, $perkb = 10000, $minconf = 0) {
    $unspent = $jsonrpc->listunspent($minconf);
    $txinputs = array();
    $addrbalance = 0;
 
    foreach ($unspent as $value) {
        if ($value["address"] == $addrA) {
            $txinputs[] = array("txid" => $value["txid"],
                "vout" => $value["vout"]);
            $addrbalance += (int) round($value["amount"] * 1e8);
        }
    }
 
    if (count($txinputs) < 1) {
        return array("success" => false, "message" => "No unspent outputs available");
    }
 
// fee calculate by ($perkb * size in kb) following the formula at:
// http://bitcoin.stackexchange.com/questions/1195/how-to-calculate-transaction-size-before-sending
    if ($fee == -1)
        $fee = (int) max($perkb * floor((count($txinputs) * 148 + 44) / 1024), $perkb);
    else if ($fee < 0) {
        return array("succes" => false, "message" => "Fee must be non-negative");
    }
 
    $btcToSend = ($addrbalance - $fee);
    if ($btcToSend < 0) {
        return array("success" => false, "message" => "Not enough funds to cover fee");
    }
    $rawtx = $jsonrpc->createrawtransaction(
            $txinputs, array(
        $addrB => ($btcToSend / 1e8)));
 
    $signedtx = $jsonrpc->signrawtransaction($rawtx);
    if ($signedtx["Complete"] == 1) {
        $txid = $jsonrpc->sendrawtransaction($signedtx["hex"]);
    } else {
        return array("success" => false, "message" => "Oddly the transaction did not sign completely...");
    }
    return array("success" => true, "txid" => $txid);
}

{ BitSpill }
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!