Transaction

55becb2bec8ac3ac340e07b5dc61fa2dbcba46a8aaa573e947c28e2868e9d230
( - )
265,838
2019-04-17 06:09:28
1
24,472 B

1 Output

Total Output:
  • j"19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAutM—^<!DOCTYPE html> <html> <head><meta name="generator" content="Hexo 3.8.0"> <meta charset="utf-8"> <title>Connecting to P2P Network | Monkeylord&#39;s Blog</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <meta name="description" content="BackgroundFor broadcasting or listening, Sometimes we need to connect to P2P network. Most of library use HTTP API to access things on chain, however, as server, sometimes directly connecting is much"> <meta property="og:type" content="article"> <meta property="og:title" content="Connecting to P2P Network"> <meta property="og:url" content="./2019/04/14/Connecting-to-P2P-Network/index.html"> <meta property="og:site_name" content="Monkeylord&#39;s Blog"> <meta property="og:description" content="BackgroundFor broadcasting or listening, Sometimes we need to connect to P2P network. Most of library use HTTP API to access things on chain, however, as server, sometimes directly connecting is much"> <meta property="og:locale" content="default"> <meta property="og:updated_time" content="2019-04-15T05:45:34.388Z"> <meta name="twitter:card" content="summary"> <meta name="twitter:title" content="Connecting to P2P Network"> <meta name="twitter:description" content="BackgroundFor broadcasting or listening, Sometimes we need to connect to P2P network. Most of library use HTTP API to access things on chain, however, as server, sometimes directly connecting is much"> <link rel="icon" href="favicon.png"> <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css"> <link rel="stylesheet" href="../../../../css/style.css"> </head> </html> <body> <div id="container"> <div id="wrap"> <header id="header"> <div id="banner"></div> <div id="header-outer" class="outer"> <div id="header-title" class="inner"> <h1 id="logo-wrap"> <a href="../../../../index.html" id="logo">Monkeylord&#39;s Blog</a> </h1> </div> <div id="header-inner" class="inner"> <nav id="main-nav"> <a id="main-nav-toggle" class="nav-icon"></a> <a class="main-nav-link" href="../../../../index.html">Home</a> <a class="main-nav-link" href="../../../../archives/">Archives</a> </nav> <nav id="sub-nav"> <a id="nav-search-btn" class="nav-icon" title="Search"></a> </nav> <div id="search-form-wrap"> <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="."></form> </div> </div> </div> </header> <div class="outer"> <section id="main"><article id="post-Connecting-to-P2P-Network" class="article article-type-post" itemscope itemprop="blogPost"> <div class="article-meta"> <a href class="article-date"> <time datetime="2019-04-14T00:48:36.000Z" itemprop="datePublished">2019-04-14</time> </a> </div> <div class="article-inner"> <header class="article-header"> <h1 class="article-title" itemprop="name"> Connecting to P2P Network </h1> </header> <div class="article-entry" itemprop="articleBody"> <h3 id="Background"><a href="#Background" class="headerlink" title="Background"></a>Background</h3><p>For broadcasting or listening, Sometimes we need to connect to P2P network.</p> <p>Most of library use HTTP API to access things on chain, however, as server, sometimes directly connecting is much better.</p> <p>Plus, connecting to P2P network directly is more efficient.</p> <h3 id="How-to-Do-That"><a href="#How-to-Do-That" class="headerlink" title="How to Do That?"></a>How to Do That?</h3><p>We need 2 things:</p> <ol> <li>Peer address</li> <li>A protocol handler</li> </ol> <p>I’ll show you some demo.</p> <h3 id="Peer-Address"><a href="#Peer-Address" class="headerlink" title="Peer Address"></a>Peer Address</h3><p>In bitcoin protocol, some server play as DNS seed.</p> <p>A seed is a first peer, for example:</p> <blockquote> <p> ‘seed.bitcoinsv.org’,<br> ‘seed.bitcoinunlimited.info’</p> </blockquote> <p>Then, in the protocol there is message <code>GetAddr</code> , and the peer will start sending known peers to you in <code>addr</code> message.</p> <p>However, if you don’t want to bother peer finding, you can find peers at <code>http://bitsonar.mempool.com/</code>.</p> <h3 id="Handle-Protocol"><a href="#Handle-Protocol" class="headerlink" title="Handle Protocol"></a>Handle Protocol</h3><p>I use <code>bitcore-p2p-cash</code> library, since there are no bsv immigration now (maybe I will do it later).</p> <p>To adapt it to bsv, you just need to tell it use bsv library to handle messages.</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> bsv = <span class="built_in">require</span>(<span class="string">'bsv'</span>)</span><br><span class="line"><span class="keyword">var</span> Peer = <span class="built_in">require</span>(<span class="string">'bitcore-p2p-cash'</span>).Peer;</span><br><span class="line"><span class="keyword">var</span> Messages = <span class="built_in">require</span>(<span class="string">'bitcore-p2p-cash'</span>).Messages;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> bsvMessages = <span class="keyword">new</span> Messages(&#123;<span class="attr">Block</span>: bsv.Block, </span><br><span class="line"> BlockHeader: bsv.BlockHeader,</span><br><span class="line"> Transaction: bsv.Transaction,</span><br><span class="line"> MerkleBlock: bsv.MerkleBlock</span><br><span class="line"> &#125;)</span><br><span class="line"><span class="keyword">var</span> peer = <span class="keyword">new</span> Peer(&#123;<span class="attr">host</span>: <span class="string">'39.105.151.223'</span>, <span class="attr">messages</span>: bsvMessages&#125;)</span><br></pre></td></tr></table></figure> <h4 id="Connection"><a href="#Connection" class="headerlink" title="Connection"></a>Connection</h4><p>It’s quite easy to connect to network.</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">peer.on(<span class="string">'ready'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"> <span class="comment">// peer info</span></span><br><span class="line"> <span class="built_in">console</span>.log(peer.version, peer.subversion, peer.bestHeight)</span><br><span class="line">&#125;)</span><br><span class="line">peer.connect()</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">70015 '/Bitcoin SV:0.1.1(EB128.0)/' 578163</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure> <h4 id="Listening"><a href="#Listening" class="headerlink" title="Listening"></a>Listening</h4><p>Peer will send you <code>inv</code> message that you can listen.</p> <p>But you need to acquire tx or block by sending <code>getdata</code> message.</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> Type = [</span><br><span class="line"> <span class="string">'Error'</span>,</span><br><span class="line"> <span class="string">'Transaction'</span>,</span><br><span class="line"> <span class="string">'Block'</span>,</span><br><span class="line"> <span class="string">'Filtered Block'</span>,</span><br><span class="line"> <span class="string">'Cmpct Block'</span></span><br><span class="line">]</span><br><span class="line">peer.on(<span class="string">'inv'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">message</span>) </span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'inv message'</span>)</span><br><span class="line"> message.inventory.forEach(<span class="function"><span class="params">item</span>=&gt;</span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">`Item type:<span class="subst">$&#123;Type[item.type]&#125;</span> hash:<span class="subst">$&#123;item.hash.toString(<span class="string">'hex'</span>)&#125;</span>`</span>)</span><br><span class="line"> &#125;)</span><br><span class="line"> <span class="keyword">this</span>.sendMessage(<span class="keyword">this</span>.messages.GetData(message.inventory))</span><br><span class="line">&#125;)</span><br><span class="line">peer.on(<span class="string">'tx'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">message</span>) </span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Transaction message'</span>)</span><br><span class="line"> <span class="built_in">console</span>.log(message.transaction)</span><br><span class="line">&#125;)</span><br><span class="line">peer.on(<span class="string">'block'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">message</span>) </span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Block message'</span>)</span><br><span class="line"> <span class="built_in">console</span>.log(message.block)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure> <h4 id="Broadcasting"><a href="#Broadcasting" class="headerlink" title="Broadcasting"></a>Broadcasting</h4><p>It’s quite easy to broadcast transaction. A <code>tx</code> message do the job.</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> txMsg = peer.messages.Transaction(tx)</span><br><span class="line">peer.sendMessage(txMsg)</span><br></pre></td></tr></table></figure> <h4 id="Error-Handling"><a href="#Error-Handling" class="headerlink" title="Error Handling"></a>Error Handling</h4><p>However, there are still errors that you should handle.</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">peer.on(<span class="string">'disconnect'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'connection closed'</span>);</span><br><span class="line">&#125;)</span><br><span class="line">peer.on(<span class="string">'error'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'connection lost'</span>);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure> <h3 id="Demo"><a href="#Demo" class="headerlink" title="Demo"></a>Demo</h3><p>Here’s a demo of recording blocks and transactions.</p> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>)</span><br><span class="line"><span class="keyword">var</span> bsv = <span class="built_in">require</span>(<span class="string">'bsv'</span>)</span><br><span class="line"><span class="keyword">var</span> Peer = <span class="built_in">require</span>(<span class="string">'bitcore-p2p-cash'</span>).Peer;</span><br><span class="line"><span class="keyword">var</span> Messages = <span class="built_in">require</span>(<span class="string">'bitcore-p2p-cash'</span>).Messages;</span><br><span class="line"><span class="keyword">var</span> bsvMessages = <span class="keyword">new</span> Messages(&#123;<span class="attr">Block</span>: bsv.Block, </span><br><span class="line"> BlockHeader: bsv.BlockHeader,</span><br><span class="line"> Transaction: bsv.Transaction,</span><br><span class="line"> MerkleBlock: bsv.MerkleBlock</span><br><span class="line"> &#125;)</span><br><span class="line"><span class="keyword">const</span> Type = [</span><br><span class="line"> <span class="string">'Error'</span>,</span><br><span class="line"> <span class="string">'Transaction'</span>,</span><br><span class="line"> <span class="string">'Block'</span>,</span><br><span class="line"> <span class="string">'Filtered Block'</span>,</span><br><span class="line"> <span class="string">'Cmpct Block'</span></span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> peer = <span class="keyword">new</span> Peer(&#123;<span class="attr">host</span>: <span class="string">'39.105.151.223'</span>, <span class="attr">messages</span>: bsvMessages&#125;)</span><br><span class="line"></span><br><span class="line">peer.on(<span class="string">'ready'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"> <span class="comment">// peer info</span></span><br><span class="line"> <span class="built_in">console</span>.log(peer.version, peer.subversion, peer.bestHeight)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">peer.on(<span class="string">'inv'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">message</span>) </span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'inv message'</span>)</span><br><span class="line"> message.inventory.forEach(<span class="function"><span class="params">item</span>=&gt;</span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">`Item type:<span class="subst">$&#123;Type[item.type]&#125;</span> hash:<span class="subst">$&#123;item.hash.toString(<span class="string">'hex'</span>)&#125;</span>`</span>)</span><br><span class="line"> &#125;)</span><br><span class="line"> <span class="keyword">this</span>.sendMessage(<span class="keyword">this</span>.messages.GetData(message.inventory))</span><br><span class="line">&#125;)</span><br><span class="line">peer.on(<span class="string">'tx'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">message</span>) </span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">`Transaction message <span class="subst">$&#123;message.transaction.id.toString()&#125;</span>`</span>)</span><br><span class="line"> fs.writeFileSync(<span class="string">`<span class="subst">$&#123;message.transaction.id.toString()&#125;</span>.tx`</span>, message.transaction.toString())</span><br><span class="line"> <span class="built_in">console</span>.log(message.transaction)</span><br><span class="line">&#125;)</span><br><span class="line">peer.on(<span class="string">'block'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">message</span>) </span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Block message'</span>)</span><br><span class="line"> fs.writeFileSync(<span class="string">`<span class="subst">$&#123;message.block.id.toString()&#125;</span>.block`</span>, message.block.toString())</span><br><span class="line"> <span class="built_in">console</span>.log(message.block)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">peer.on(<span class="string">'addr'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">message</span>) </span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Peer addresses received'</span>)</span><br><span class="line"> <span class="built_in">console</span>.log(message.addresses)</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">peer.on(<span class="string">'disconnect'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'connection closed'</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">peer.on(<span class="string">'error'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'connection lost'</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">peer.connect()</span><br></pre></td></tr></table></figure> <h3 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h3><p>OK, that’s basically how you can connect to P2P network, enjoy your SPV.</p> <p>There are few things you should pay attention to.</p> <ol> <li>You should cache transactions you care. It’s not recommended in protocol that ask history tx from other node every time, even though they are friendly to answer you, most of nodes are not designed to do history search. So, you should be nice, ask and cache and do not ask again.</li> <li>Behavior yourself, do verification and check before sending transactions to nodes, or they may reject you and ban you out.</li> </ol> </div> <footer class="article-footer"> <a data-url="./2019/04/14/Connecting-to-P2P-Network/" data-id="cjuhyngf00000e4uf4ld6e0w5" class="article-share-link">Share</a> </footer> </div> <nav id="article-nav"> <a href="../../../03/20/How-to-Build-an-On-chain-Blog/" id="article-nav-older" class="article-nav-link-wrap"> <strong class="article-nav-caption">Older</strong> <div class="article-nav-title">How to Build an On-chain Blog</div> </a> </nav> </article> </section> <aside id="sidebar"> <div class="widget-wrap"> <h3 class="widget-title">Archives</h3> <div class="widget"> <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="../../../../archives/2019/04/">April 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="../../../../archives/2019/03/">March 2019</a></li></ul> </div> </div> <div class="widget-wrap"> <h3 class="widget-title">Recent Posts</h3> <div class="widget"> <ul> <li> <a href>Connecting to P2P Network</a> </li> <li> <a href="../../../03/20/How-to-Build-an-On-chain-Blog/">How to Build an On-chain Blog</a> </li> <li> <a href="../../../03/19/How-to-Upload-Big-Files/">How to Upload Big Files</a> </li> <li> <a href="../../../03/11/Metanet应用开发/">Metanet应用开发</a> </li> <li> <a href="../../../03/04/The-Siteloader-is-Released/">The Siteloader is Released.</a> </li> </ul> </div> </div> </aside> </div> <footer id="footer"> <div class="outer"> <div id="footer-info" class="inner"> &copy; 2019 Monkeylord<br> Powered by <a href="http://hexo.io/" target="_blank">Hexo</a> </div> </div> </footer> </div> <nav id="mobile-nav"> <a href="../../../../index.html" class="mobile-nav-link">Home</a> <a href="../../../../archives/" class="mobile-nav-link">Archives</a> </nav> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> <link rel="stylesheet" href="../../../../fancybox/jquery.fancybox.css"> <script src="../../../../fancybox/jquery.fancybox.pack.js"></script> <script src="../../../../js/script.js"></script> </div> </body> </html> text/htmlbinary bc06f1ce909cf46c5b51a710f1b019d1
    https://whatsonchain.com/tx/55becb2bec8ac3ac340e07b5dc61fa2dbcba46a8aaa573e947c28e2868e9d230