1 #include <bitcoin/bitcoin.hpp>
2 using namespace libbitcoin;
4 #include <boost/python.hpp>
5 namespace python = boost::python;
7 #include "/home/genjix/python-bitcoin/src/primitive.h"
9 namespace ph = std::placeholders;
12 : public std::enable_shared_from_this<tracer>,
16 typedef std::vector<std::string> string_list;
18 typedef std::function<
19 void (const std::error_code&, const string_list&)> finish_handler;
21 tracer(async_service& service, blockchain_ptr chain)
22 : strand_(service.get_service()), chain_(chain)
26 void start(const message::transaction& tx, finish_handler handle_finish)
28 auto this_ptr = shared_from_this();
30 [&, this_ptr, tx, handle_finish]()
33 handle_finish_ = std::move(handle_finish);
34 this_ptr->run(std::error_code());
38 void run(const std::error_code& ec);
41 io_service::strand strand_;
42 blockchain_ptr chain_;
44 message::transaction tx_;
45 finish_handler handle_finish_;
49 std::vector<script> output_scripts_;
52 typedef std::shared_ptr<tracer> tracer_ptr;
54 void tracer::run(const std::error_code& ec)
56 auto this_ptr = shared_from_this();
63 output_scripts_.resize(tx_.inputs.size());
64 for (size_t input_idx = 0;
65 input_idx < tx_.inputs.size(); ++input_idx)
67 const auto& tx_input = tx_.inputs[input_idx];
68 auto prevout_idx = tx_input.previous_output.index;
69 chain_->fetch_transaction(
70 tx_input.previous_output.hash,
71 strand_.wrap([&, this_ptr, input_idx, prevout_idx]
72 (const std::error_code& ec,
73 const message::transaction& prev_tx)
83 prevout_idx < prev_tx.outputs.size());
85 input_idx < output_scripts_.size());
86 output_scripts_[input_idx] =
87 prev_tx.outputs[prevout_idx].output_script;
89 if (count_ == tx_.inputs.size())
97 handle_finish_(ec, string_list());
101 for (const auto& outscript: output_scripts_)
103 payment_address addr;
104 if (!extract(addr, outscript))
107 handle_finish_(ec, string_list());
110 result.push_back(addr.encoded());
112 handle_finish_(std::error_code(), result);
116 void keep_trace_alive_proxy(const std::error_code& ec,
117 const tracer::string_list& input_addrs,
118 python::object handle_finish, tracer_ptr trace)
121 for (const auto& addr: input_addrs)
123 pyfunction<const std::error_code&, python::list> f(handle_finish);
127 void trace_tx(async_service_ptr service, blockchain_ptr chain,
128 const message::transaction& tx, python::object handle_finish)
130 auto trace = std::make_shared<tracer>(*service, chain);
132 std::bind(keep_trace_alive_proxy, ph::_1, ph::_2,
133 handle_finish, trace));
136 BOOST_PYTHON_MODULE(trace_tx)
138 using namespace boost::python;
139 def("trace_tx", trace_tx);