随着勒索病毒的爆发,比特币更是近一步的被人们接触,机缘巧合之下,从大四开始接触比特币钱包的后台开发,我只做简单的介绍。
- 比特币终端是一个跨平台的软件,运行在windows ,linux ,移动设备上,本文以Windows平台为例。
- 服务器:windows 2012 server . Bitcoin Core . 由于同步钱包需要很多时间,并且现在同步容量应该在200G内(我最近一次是160g).
- 先上图
- 你的钱包只是在官网上下载的一个客户端,每个钱包可以生成N个钱包地址,从别的钱包转账可以转到这N个地址中的一个,你最先收到钱包转账的通知,也就是确认数为1,但是这个时候区块链还没有发出确认通知,当确认数>=2的时候可以认为转账成功了。
- 钱包服务器配置:
0 1 2 3 4 5 6 7 8 9 10 |
// 文件在家目录会有一个bitcoin文件夹 ,新建一个bitcoin.conf // 下面4个注释的是最重要的。 listen=1 server=1 daemon=1 rpcuser=user # rpc 通讯用户的账号 rpcpassword=password # rpc 密码 rpcallowip=127.0.0.1 # rpc 允许接受哪一个ip的消息 rpcport=8333 # rpc 端口 rpcallowip=122.114.20.103 addnode=122.114.20.103 |
- 下面是一个简单的和钱包服务器进行rpc通讯的类
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
<span class="cp"><?php</span> <span class="k">namespace</span> <span class="nx">App\Coin\Client</span><span class="p">;</span> <span class="k">class</span> <span class="nc">CoinClient</span> <span class="p">{</span> <span class="c1">// 钱包服务器ip </span> <span class="k">private</span> <span class="nv">$url</span><span class="p">;</span> <span class="c1">// 连接超时时间 </span> <span class="k">private</span> <span class="nv">$timeout</span><span class="p">;</span> <span class="c1">// 钱包服务器 用户名 </span> <span class="k">private</span> <span class="nv">$username</span><span class="p">;</span> <span class="c1">// 钱包服务器密码 </span> <span class="k">private</span> <span class="nv">$password</span><span class="p">;</span> <span class="k">public</span> <span class="nv">$is_batch</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span> <span class="k">public</span> <span class="nv">$batch</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span> <span class="k">public</span> <span class="nv">$debug</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span> <span class="k">public</span> <span class="nv">$jsonformat</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span> <span class="k">public</span> <span class="nv">$res</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span> <span class="k">private</span> <span class="nv">$headers</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">'User-Agent: github.com Rpc'</span><span class="p">,</span> <span class="s1">'Content-Type: application/json'</span><span class="p">,</span> <span class="s1">'Accept: application/json'</span><span class="p">,</span> <span class="s1">'Connection: close'</span><span class="p">);</span> <span class="k">public</span> <span class="nv">$ssl_verify_peer</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span> <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span><span class="nv">$username</span><span class="p">,</span> <span class="nv">$password</span><span class="p">,</span> <span class="nv">$ip</span><span class="p">,</span> <span class="nv">$port</span><span class="p">,</span> <span class="nv">$timeout</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span> <span class="nv">$headers</span> <span class="o">=</span> <span class="k">array</span><span class="p">(),</span> <span class="nv">$jsonformat</span> <span class="o">=</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-></span><span class="na">url</span> <span class="o">=</span> <span class="s1">'http://'</span> <span class="o">.</span> <span class="nv">$ip</span> <span class="o">.</span> <span class="s1">':'</span> <span class="o">.</span> <span class="nv">$port</span><span class="p">;</span> <span class="nv">$this</span><span class="o">-></span><span class="na">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span> <span class="nv">$this</span><span class="o">-></span><span class="na">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span> <span class="nv">$this</span><span class="o">-></span><span class="na">timeout</span> <span class="o">=</span> <span class="nv">$timeout</span><span class="p">;</span> <span class="nv">$this</span><span class="o">-></span><span class="na">headers</span> <span class="o">=</span> <span class="nx">array_merge</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">headers</span><span class="p">,</span> <span class="nv">$headers</span><span class="p">);</span> <span class="nv">$this</span><span class="o">-></span><span class="na">jsonformat</span> <span class="o">=</span> <span class="nv">$jsonformat</span><span class="p">;</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 这里通过魔术方法调用api </span><span class="sd"> * 比如 $client->getinfo() ; 可以直接获取到getinfo方法, </span><span class="sd"> * @param $method </span><span class="sd"> * @param array $params </span><span class="sd"> * @return string </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="fm">__call</span><span class="p">(</span><span class="nv">$method</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$params</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">((</span><span class="nx">count</span><span class="p">(</span><span class="nv">$params</span><span class="p">)</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&&</span> <span class="nx">is_array</span><span class="p">(</span><span class="nv">$params</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> <span class="p">{</span> <span class="nv">$params</span> <span class="o">=</span> <span class="nv">$params</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> <span class="p">}</span> <span class="nv">$res</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">execute</span><span class="p">(</span><span class="nv">$method</span><span class="p">,</span> <span class="nv">$params</span><span class="p">);</span> <span class="nv">$this</span><span class="o">-></span><span class="na">debug</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">'method'</span> <span class="o">=></span> <span class="nv">$method</span><span class="p">,</span> <span class="s1">'params'</span> <span class="o">=></span> <span class="nv">$params</span><span class="p">,</span> <span class="s1">'res'</span> <span class="o">=></span> <span class="nv">$res</span><span class="p">));</span> <span class="k">return</span> <span class="nv">$res</span> <span class="o">?</span> <span class="nv">$res</span> <span class="o">:</span> <span class="nv">$this</span><span class="o">-></span><span class="na">res</span><span class="p">;</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 构造参数 </span><span class="sd"> * @param $procedure </span><span class="sd"> * @param array $params </span><span class="sd"> * @return string </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">execute</span><span class="p">(</span><span class="nv">$procedure</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$params</span> <span class="o">=</span> <span class="k">array</span><span class="p">())</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">doRequest</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">prepareRequest</span><span class="p">(</span><span class="nv">$procedure</span><span class="p">,</span> <span class="nv">$params</span><span class="p">));</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 构造 发送的内容 </span><span class="sd"> * @param $procedure </span><span class="sd"> * @param array $params </span><span class="sd"> * @return array </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">prepareRequest</span><span class="p">(</span><span class="nv">$procedure</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$params</span> <span class="o">=</span> <span class="k">array</span><span class="p">())</span> <span class="p">{</span> <span class="nv">$payload</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">'jsonrpc'</span> <span class="o">=></span> <span class="s1">'2.0'</span><span class="p">,</span> <span class="s1">'method'</span> <span class="o">=></span> <span class="nv">$procedure</span><span class="p">,</span> <span class="s1">'id'</span> <span class="o">=></span> <span class="nx">mt_rand</span><span class="p">());</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$params</span><span class="p">))</span> <span class="p">{</span> <span class="nv">$payload</span><span class="p">[</span><span class="s1">'params'</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$params</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="nv">$payload</span><span class="p">;</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 执行 rpc 请求 </span><span class="sd"> * @param array $payload </span><span class="sd"> * @return string </span><span class="sd"> * @throws \Exception </span><span class="sd"> */</span> <span class="k">private</span> <span class="k">function</span> <span class="nf">doRequest</span><span class="p">(</span><span class="k">array</span> <span class="nv">$payload</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$stream</span> <span class="o">=</span> <span class="o">@</span><span class="nx">fopen</span><span class="p">(</span><span class="nx">trim</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">url</span><span class="p">),</span> <span class="s1">'r'</span><span class="p">,</span> <span class="k">false</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="na">getContext</span><span class="p">(</span><span class="nv">$payload</span><span class="p">));</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">is_resource</span><span class="p">(</span><span class="nv">$stream</span><span class="p">))</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">\Exception</span><span class="p">(</span><span class="s1">'钱包链接失败'</span><span class="p">)</span> <span class="p">;</span> <span class="p">}</span> <span class="nv">$metadata</span> <span class="o">=</span> <span class="nx">stream_get_meta_data</span><span class="p">(</span><span class="nv">$stream</span><span class="p">);</span> <span class="c1">// 服务器响应内容 . </span> <span class="nv">$response</span> <span class="o">=</span> <span class="nx">json_decode</span><span class="p">(</span><span class="nx">stream_get_contents</span><span class="p">(</span><span class="nv">$stream</span><span class="p">),</span> <span class="k">true</span><span class="p">);</span> <span class="nv">$header_1</span> <span class="o">=</span> <span class="nv">$metadata</span><span class="p">[</span><span class="s1">'wrapper_data'</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span> <span class="nx">preg_match</span><span class="p">(</span><span class="s1">'/[\\d]{3}/i'</span><span class="p">,</span> <span class="nv">$header_1</span><span class="p">,</span> <span class="nv">$code</span><span class="p">);</span> <span class="nv">$code</span> <span class="o">=</span> <span class="nx">trim</span><span class="p">(</span><span class="nv">$code</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span> <span class="c1">// 返回的状态值 . </span> <span class="k">if</span> <span class="p">(</span><span class="nv">$code</span> <span class="o">==</span> <span class="s1">'200'</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 这段就是服务器返回的信息 . </span> <span class="k">return</span> <span class="nx">isset</span><span class="p">(</span><span class="nv">$response</span><span class="p">[</span><span class="s1">'result'</span><span class="p">])</span> <span class="o">?</span> <span class="nv">$response</span><span class="p">[</span><span class="s1">'result'</span><span class="p">]</span> <span class="o">:</span> <span class="s1">'nodata'</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$response</span><span class="p">[</span><span class="s1">'error'</span><span class="p">]</span> <span class="o">&&</span> <span class="nx">is_array</span><span class="p">(</span><span class="nv">$response</span><span class="p">[</span><span class="s1">'error'</span><span class="p">]))</span> <span class="p">{</span> <span class="nv">$detail</span> <span class="o">=</span> <span class="s1">'code='</span> <span class="o">.</span> <span class="nv">$response</span><span class="p">[</span><span class="s1">'error'</span><span class="p">][</span><span class="s1">'code'</span><span class="p">]</span> <span class="o">.</span> <span class="s1">',message='</span> <span class="o">.</span> <span class="nv">$response</span><span class="p">[</span><span class="s1">'error'</span><span class="p">][</span><span class="s1">'message'</span><span class="p">];</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">\Exception</span><span class="p">(</span><span class="nv">$detail</span><span class="p">)</span> <span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">\Exception</span><span class="p">(</span><span class="nv">$code</span><span class="p">)</span> <span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 获取上下文 </span><span class="sd"> * @param array $payload </span><span class="sd"> * @return resource </span><span class="sd"> */</span> <span class="k">private</span> <span class="k">function</span> <span class="nf">getContext</span><span class="p">(</span><span class="k">array</span> <span class="nv">$payload</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$headers</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">headers</span><span class="p">;</span> <span class="c1">// 用户名密码 认证过程 </span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">username</span><span class="p">)</span> <span class="o">&&</span> <span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">password</span><span class="p">))</span> <span class="p">{</span> <span class="nv">$headers</span><span class="p">[]</span> <span class="o">=</span> <span class="s1">'Authorization: Basic '</span> <span class="o">.</span> <span class="nx">base64_encode</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">username</span> <span class="o">.</span> <span class="s1">':'</span> <span class="o">.</span> <span class="nv">$this</span><span class="o">-></span><span class="na">password</span><span class="p">);</span> <span class="p">}</span> <span class="c1">// 请求内容 </span> <span class="nv">$context</span> <span class="o">=</span> <span class="nx">stream_context_create</span><span class="p">(</span><span class="k">array</span><span class="p">(</span> <span class="s1">'http'</span> <span class="o">=></span> <span class="k">array</span><span class="p">(</span><span class="s1">'method'</span> <span class="o">=></span> <span class="s1">'POST'</span><span class="p">,</span> <span class="s1">'protocol_version'</span> <span class="o">=></span> <span class="mf">1.1000000000000001</span><span class="p">,</span> <span class="s1">'timeout'</span> <span class="o">=></span> <span class="nv">$this</span><span class="o">-></span><span class="na">timeout</span><span class="p">,</span> <span class="s1">'max_redirects'</span> <span class="o">=></span> <span class="mi">2</span><span class="p">,</span> <span class="s1">'header'</span> <span class="o">=></span> <span class="nx">implode</span><span class="p">(</span><span class="s2">"</span><span class="se">\r\n</span><span class="s2">"</span><span class="p">,</span> <span class="nv">$headers</span><span class="p">),</span> <span class="s1">'content'</span> <span class="o">=></span> <span class="nx">json_encode</span><span class="p">(</span><span class="nv">$payload</span><span class="p">),</span> <span class="s1">'ignore_errors'</span> <span class="o">=></span> <span class="k">true</span> <span class="p">),</span> <span class="c1">// ssl 证书 </span> <span class="s1">'ssl'</span> <span class="o">=></span> <span class="k">array</span><span class="p">(</span><span class="s1">'verify_peer'</span> <span class="o">=></span> <span class="nv">$this</span><span class="o">-></span><span class="na">ssl_verify_peer</span><span class="p">,</span> <span class="s1">'verify_peer_name'</span> <span class="o">=></span> <span class="nv">$this</span><span class="o">-></span><span class="na">ssl_verify_peer</span><span class="p">)</span> <span class="p">));</span> <span class="k">return</span> <span class="nv">$context</span> <span class="p">;</span> <span class="p">}</span> <span class="p">}</span> |
- 下面简述开发过程中经常用到的方法:
- 查询钱包状态
- 生成钱包地址
- 对外转账
- 收取转账信息
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
<span class="cp"><?php</span> <span class="k">class</span> <span class="nc">HandleClient</span><span class="p">{</span> <span class="c1">// 客户端 </span> <span class="k">private</span> <span class="nv">$client</span> <span class="p">;</span> <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">()</span> <span class="p">{</span> <span class="nv">$host</span> <span class="o">=</span> <span class="s2">"127.0.0.1"</span> <span class="p">;</span> <span class="c1">// 钱包地址,本地开发通常是本机 本地开发可以用轻量级的山寨币钱包, </span> <span class="nv">$user</span> <span class="o">=</span> <span class="s1">'user'</span><span class="p">;</span> <span class="nv">$password</span> <span class="o">=</span> <span class="s1">'password'</span><span class="p">;</span> <span class="nv">$port</span> <span class="o">=</span> <span class="s1">'6300'</span><span class="p">;</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Client</span><span class="p">(</span><span class="nv">$host</span> <span class="p">,</span><span class="nv">$user</span> <span class="p">,</span><span class="nv">$password</span> <span class="p">,</span><span class="nv">$port</span> <span class="p">,</span><span class="mi">30</span><span class="p">);</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 给站内用户生成一个 地址 ,表结构大致如下 </span><span class="sd"> * -------------------------------- </span><span class="sd"> * id | address | username </span><span class="sd"> * --------------------------------- </span><span class="sd"> * @param $label 用户->address 一对多的关系 </span><span class="sd"> * @return bool|mixed </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">createAddress</span><span class="p">(</span><span class="nv">$label</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 这步骤是获取这个标签的钱包地址,如果已经存在则返回, </span> <span class="nv">$address</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">getaddressesbyaccount</span><span class="p">(</span><span class="nv">$label</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">is_array</span><span class="p">(</span><span class="nv">$address</span><span class="p">)){</span> <span class="nv">$address</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">getnewaddress</span><span class="p">(</span><span class="nv">$label</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$address</span><span class="p">){</span> <span class="k">return</span> <span class="k">false</span> <span class="p">;</span> <span class="p">}</span> <span class="p">}</span><span class="k">else</span><span class="p">{</span> <span class="nv">$address</span> <span class="o">=</span> <span class="nv">$address</span> <span class="p">[</span><span class="mi">0</span><span class="p">];</span> <span class="p">}</span> <span class="k">return</span> <span class="nv">$address</span> <span class="p">;</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 将币转出,平台会有转出币钱包场景,在这之前需要判断是否是站内互转 </span><span class="sd"> * 在这之前需要判断是否是一个有效的钱包地址 </span><span class="sd"> * 该步骤通常以后台任务队列运行 </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">turnout</span><span class="p">(</span><span class="nv">$address</span><span class="p">,</span><span class="nv">$number</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 判断是否是一个有效的钱包地址 </span> <span class="nv">$isAddr</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">validateaddress</span><span class="p">(</span><span class="nv">$address</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$isAddr</span><span class="p">){</span> <span class="k">return</span> <span class="k">false</span><span class="p">;</span> <span class="p">}</span> <span class="c1">// 获取钱包的余额 </span> <span class="nv">$info</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">getinfo</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="nv">$info</span><span class="p">[</span><span class="s1">'balance'</span><span class="p">]</span> <span class="o"><</span> <span class="nv">$number</span> <span class="p">){</span> <span class="k">return</span> <span class="k">false</span> <span class="p">;</span> <span class="p">}</span> <span class="c1">// 发送接口 </span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">sendtoaddress</span><span class="p">(</span><span class="nv">$address</span><span class="p">,</span> <span class="nv">$number</span> <span class="p">);</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 交易查询接口. </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">trade</span><span class="p">()</span> <span class="p">{</span> <span class="c1">// 该方法 有3个参数,第一个是指查询标签的意思* 查找所有用户 123456 ,查找123456的交易情况 </span> <span class="nv">$list</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">listtransactions</span><span class="p">(</span><span class="s2">"*"</span><span class="p">,</span><span class="mi">100</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span> <span class="k">foreach</span><span class="p">(</span><span class="nv">$list</span> <span class="k">as</span> <span class="nv">$key</span> <span class="o">=></span> <span class="nv">$val</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="nv">$val</span> <span class="p">[</span><span class="s1">'category'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'receive'</span><span class="p">){</span> <span class="c1">// 接受的交易 </span> <span class="nv">$this</span><span class="o">-></span><span class="na">handleReceive</span><span class="p">(</span><span class="nv">$val</span><span class="p">);</span> <span class="p">}</span><span class="k">elseif</span><span class="p">(</span><span class="nv">$val</span> <span class="p">[</span><span class="s1">'category'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'send'</span><span class="p">){</span> <span class="c1">// 发送的交易 </span> <span class="nv">$this</span><span class="o">-></span><span class="na">handleSend</span><span class="p">(</span><span class="nv">$val</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="c1">// 这里是系统用户向平台充币的处理, </span> <span class="c1">// 由于充币事先是不知道的,这里需要动态生成订单 </span> <span class="c1">// txid 是交易的唯一编号 注意启动事务 </span> <span class="k">private</span> <span class="k">function</span> <span class="nf">handleReceive</span><span class="p">(</span><span class="nv">$item</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$address</span> <span class="o">=</span> <span class="nx">DB</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'address'</span><span class="p">)</span><span class="o">-></span><span class="na">where</span><span class="p">([</span><span class="s1">'address'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'address'</span><span class="p">]])</span><span class="o">-></span><span class="na">get</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$address</span><span class="p">){</span> <span class="k">return</span> <span class="p">;</span> <span class="p">}</span> <span class="nv">$row</span> <span class="o">=</span> <span class="nx">DB</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'trade'</span><span class="p">)</span><span class="o">-></span><span class="na">where</span><span class="p">([</span><span class="s1">'txid'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'txid'</span><span class="p">]</span> <span class="p">,</span> <span class="s1">'status'</span> <span class="o">=></span> <span class="mi">0</span> <span class="p">,</span> <span class="s1">'type'</span> <span class="o">=></span> <span class="s1">'receive'</span><span class="p">])</span><span class="o">-></span><span class="na">get</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="nv">$row</span><span class="p">){</span> <span class="c1">// 如果有订单,判断确认次数 </span> <span class="k">if</span><span class="p">(</span><span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">]</span> <span class="o">>=</span> <span class="mi">2</span><span class="p">){</span> <span class="nv">$row</span><span class="o">-></span><span class="na">save</span><span class="p">([</span><span class="s1">'status'</span> <span class="o">=></span> <span class="mi">1</span> <span class="p">,</span> <span class="s1">'confirmations'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">]]);</span> <span class="c1">// 给用户加钱 </span> <span class="nv">$user</span> <span class="o">=</span> <span class="nv">$address</span><span class="o">-></span><span class="na">user</span><span class="p">()</span><span class="o">-></span><span class="na">increment</span><span class="p">(</span><span class="s1">'coin'</span><span class="p">,</span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'amount'</span><span class="p">]);</span> <span class="p">}</span> <span class="p">}</span><span class="k">else</span><span class="p">{</span> <span class="nv">$arr</span> <span class="o">=</span> <span class="p">[</span> <span class="s1">'confirmations'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">],</span> <span class="s1">'user_id'</span> <span class="o">=></span> <span class="nv">$address</span><span class="o">-></span><span class="na">user</span><span class="o">-></span><span class="na">id</span> <span class="p">,</span> <span class="s1">'amount'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'amount'</span><span class="p">],</span> <span class="s1">'txid'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'txid'</span><span class="p">],</span> <span class="p">];</span> <span class="k">if</span><span class="p">(</span><span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">]</span> <span class="o">>=</span> <span class="mi">2</span><span class="p">){</span> <span class="nv">$arr</span> <span class="p">[</span><span class="s1">'status'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">;</span> <span class="nv">$user</span> <span class="o">=</span> <span class="nv">$address</span><span class="o">-></span><span class="na">user</span><span class="p">()</span><span class="o">-></span><span class="na">increment</span><span class="p">(</span><span class="s1">'coin'</span><span class="p">,</span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'amount'</span><span class="p">]);</span> <span class="p">}</span><span class="k">else</span><span class="p">{</span> <span class="nv">$arr</span> <span class="p">[</span><span class="s1">'status'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="nx">DB</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'trade'</span><span class="p">)</span><span class="o">-></span><span class="na">create</span><span class="p">(</span><span class="nv">$arr</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="c1">// 处理转出情况,转出是用户发起的,不需要动态插表 </span> <span class="k">private</span> <span class="k">function</span> <span class="nf">handleSend</span><span class="p">(</span><span class="nv">$item</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$row</span> <span class="o">=</span> <span class="nx">DB</span><span class="o">::</span><span class="na">where</span><span class="p">([</span><span class="s1">'address'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'address'</span><span class="p">]])</span><span class="o">-></span><span class="na">get</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$row</span><span class="p">){</span> <span class="k">return</span> <span class="p">;</span> <span class="p">}</span> <span class="k">if</span><span class="p">(</span><span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">]</span> <span class="o">>=</span> <span class="mi">2</span><span class="p">){</span> <span class="nv">$row</span><span class="o">-></span><span class="na">save</span><span class="p">([</span><span class="s1">'status'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">,</span><span class="s1">'txid'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'txid'</span><span class="p">]</span> <span class="p">,</span> <span class="s1">'confirmations'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">]]);</span> <span class="c1">// 可能需要处理用户币的冻结情况, </span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> |
- 由于接触虚拟币开发比较多,因此对这个略有了解,虚拟币开发我几乎没找到什么文档,希望给广大的爱好者来一发!
- rpc接口列表.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
addmultisigaddress <nrequired> <'["key","key"]'> [account] addnode <node> <add|remove|onetry> backupwallet <destination> createmultisig <nrequired> <'["key","key"]'> createrawtransaction [{"txid":txid,"vout":n},...] {address:amount,...} decoderawtransaction <hex string> dumpprivkey <chinacoinaddress> encryptwallet <passphrase> getaccount <chinacoinaddress> getaccountaddress <account> getaddednodeinfo <dns> [node] getaddressesbyaccount <account> getbalance [account] [minconf=1] getbestblockhash getblock <hash> [verbose=true] getblockcount getblockhash <index> getblocktemplate [params] getconnectioncount getdifficulty getgenerate gethashespersec getinfo getmininginfo getnetworkhashps [blocks] [height] getnewaddress [account] getpeerinfo getrawmempool getrawtransaction <txid> [verbose=0] getreceivedbyaccount <account> [minconf=1] getreceivedbyaddress <chinacoinaddress> [minconf=1] gettransaction <txid> gettxout <txid> <n> [includemempool=true] gettxoutsetinfo getwork [data] getworkex [data, coinbase] help [command] importprivkey <chinacoinprivkey> [label] [rescan=true] keypoolrefill listaccounts [minconf=1] listaddressgroupings listlockunspent listreceivedbyaccount [minconf=1] [includeempty=false] listreceivedbyaddress [minconf=1] [includeempty=false] listsinceblock [blockhash] [target-confirmations] listtransactions [account] [count=10] [from=0] listunspent [minconf=1] [maxconf=9999999] ["address",...] lockunspent unlock? [array-of-Objects] move <fromaccount> <toaccount> <amount> [minconf=1] [comment] sendfrom <fromaccount> <tochinacoinaddress> <amount> [minconf=1] [comment] [comment-to] sendmany <fromaccount> {address:amount,...} [minconf=1] [comment] sendrawtransaction <hex string> sendtoaddress <chinacoinaddress> <amount> [comment] [comment-to] setaccount <chinacoinaddress> <account> setgenerate <generate> [genproclimit] setmininput <amount> settxfee <amount> signmessage <chinacoinaddress> <message> signrawtransaction <hex string> [{"txid":txid,"vout":n,"scriptPubKey":hex,"redeemScript":hex},...] [<privatekey1>,...] [sighashtype="ALL"] stop submitblock <hex data> [optional-params-obj] validateaddress <chinacoinaddress> verifychain [check level] [num blocks] verifymessage <chinacoinaddress> <signature> <message> |
原文:https://zhuanlan.zhihu.com/p/27702684
随着勒索病毒的爆发,比特币更是近一步的被人们接触,机缘巧合之下,从大四开始接触比特币钱包的后台开发,我只做简单的介绍。
- 比特币终端是一个跨平台的软件,运行在windows ,linux ,移动设备上,本文以Windows平台为例。
- 服务器:windows 2012 server . Bitcoin Core . 由于同步钱包需要很多时间,并且现在同步容量应该在200G内(我最近一次是160g).
- 先上图
- 你的钱包只是在官网上下载的一个客户端,每个钱包可以生成N个钱包地址,从别的钱包转账可以转到这N个地址中的一个,你最先收到钱包转账的通知,也就是确认数为1,但是这个时候区块链还没有发出确认通知,当确认数>=2的时候可以认为转账成功了。
- 钱包服务器配置:
0 1 2 3 4 5 6 7 8 9 10 |
// 文件在家目录会有一个bitcoin文件夹 ,新建一个bitcoin.conf // 下面4个注释的是最重要的。 listen=1 server=1 daemon=1 rpcuser=user # rpc 通讯用户的账号 rpcpassword=password # rpc 密码 rpcallowip=127.0.0.1 # rpc 允许接受哪一个ip的消息 rpcport=8333 # rpc 端口 rpcallowip=122.114.20.103 addnode=122.114.20.103 |
- 下面是一个简单的和钱包服务器进行rpc通讯的类
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
<span class="cp"><?php</span> <span class="k">namespace</span> <span class="nx">App\Coin\Client</span><span class="p">;</span> <span class="k">class</span> <span class="nc">CoinClient</span> <span class="p">{</span> <span class="c1">// 钱包服务器ip </span> <span class="k">private</span> <span class="nv">$url</span><span class="p">;</span> <span class="c1">// 连接超时时间 </span> <span class="k">private</span> <span class="nv">$timeout</span><span class="p">;</span> <span class="c1">// 钱包服务器 用户名 </span> <span class="k">private</span> <span class="nv">$username</span><span class="p">;</span> <span class="c1">// 钱包服务器密码 </span> <span class="k">private</span> <span class="nv">$password</span><span class="p">;</span> <span class="k">public</span> <span class="nv">$is_batch</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span> <span class="k">public</span> <span class="nv">$batch</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span> <span class="k">public</span> <span class="nv">$debug</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span> <span class="k">public</span> <span class="nv">$jsonformat</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span> <span class="k">public</span> <span class="nv">$res</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span> <span class="k">private</span> <span class="nv">$headers</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">'User-Agent: github.com Rpc'</span><span class="p">,</span> <span class="s1">'Content-Type: application/json'</span><span class="p">,</span> <span class="s1">'Accept: application/json'</span><span class="p">,</span> <span class="s1">'Connection: close'</span><span class="p">);</span> <span class="k">public</span> <span class="nv">$ssl_verify_peer</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span> <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span><span class="nv">$username</span><span class="p">,</span> <span class="nv">$password</span><span class="p">,</span> <span class="nv">$ip</span><span class="p">,</span> <span class="nv">$port</span><span class="p">,</span> <span class="nv">$timeout</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span> <span class="nv">$headers</span> <span class="o">=</span> <span class="k">array</span><span class="p">(),</span> <span class="nv">$jsonformat</span> <span class="o">=</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-></span><span class="na">url</span> <span class="o">=</span> <span class="s1">'http://'</span> <span class="o">.</span> <span class="nv">$ip</span> <span class="o">.</span> <span class="s1">':'</span> <span class="o">.</span> <span class="nv">$port</span><span class="p">;</span> <span class="nv">$this</span><span class="o">-></span><span class="na">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span> <span class="nv">$this</span><span class="o">-></span><span class="na">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span> <span class="nv">$this</span><span class="o">-></span><span class="na">timeout</span> <span class="o">=</span> <span class="nv">$timeout</span><span class="p">;</span> <span class="nv">$this</span><span class="o">-></span><span class="na">headers</span> <span class="o">=</span> <span class="nx">array_merge</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">headers</span><span class="p">,</span> <span class="nv">$headers</span><span class="p">);</span> <span class="nv">$this</span><span class="o">-></span><span class="na">jsonformat</span> <span class="o">=</span> <span class="nv">$jsonformat</span><span class="p">;</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 这里通过魔术方法调用api </span><span class="sd"> * 比如 $client->getinfo() ; 可以直接获取到getinfo方法, </span><span class="sd"> * @param $method </span><span class="sd"> * @param array $params </span><span class="sd"> * @return string </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="fm">__call</span><span class="p">(</span><span class="nv">$method</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$params</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">((</span><span class="nx">count</span><span class="p">(</span><span class="nv">$params</span><span class="p">)</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&&</span> <span class="nx">is_array</span><span class="p">(</span><span class="nv">$params</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> <span class="p">{</span> <span class="nv">$params</span> <span class="o">=</span> <span class="nv">$params</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> <span class="p">}</span> <span class="nv">$res</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">execute</span><span class="p">(</span><span class="nv">$method</span><span class="p">,</span> <span class="nv">$params</span><span class="p">);</span> <span class="nv">$this</span><span class="o">-></span><span class="na">debug</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">'method'</span> <span class="o">=></span> <span class="nv">$method</span><span class="p">,</span> <span class="s1">'params'</span> <span class="o">=></span> <span class="nv">$params</span><span class="p">,</span> <span class="s1">'res'</span> <span class="o">=></span> <span class="nv">$res</span><span class="p">));</span> <span class="k">return</span> <span class="nv">$res</span> <span class="o">?</span> <span class="nv">$res</span> <span class="o">:</span> <span class="nv">$this</span><span class="o">-></span><span class="na">res</span><span class="p">;</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 构造参数 </span><span class="sd"> * @param $procedure </span><span class="sd"> * @param array $params </span><span class="sd"> * @return string </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">execute</span><span class="p">(</span><span class="nv">$procedure</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$params</span> <span class="o">=</span> <span class="k">array</span><span class="p">())</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">doRequest</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">prepareRequest</span><span class="p">(</span><span class="nv">$procedure</span><span class="p">,</span> <span class="nv">$params</span><span class="p">));</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 构造 发送的内容 </span><span class="sd"> * @param $procedure </span><span class="sd"> * @param array $params </span><span class="sd"> * @return array </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">prepareRequest</span><span class="p">(</span><span class="nv">$procedure</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$params</span> <span class="o">=</span> <span class="k">array</span><span class="p">())</span> <span class="p">{</span> <span class="nv">$payload</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">'jsonrpc'</span> <span class="o">=></span> <span class="s1">'2.0'</span><span class="p">,</span> <span class="s1">'method'</span> <span class="o">=></span> <span class="nv">$procedure</span><span class="p">,</span> <span class="s1">'id'</span> <span class="o">=></span> <span class="nx">mt_rand</span><span class="p">());</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$params</span><span class="p">))</span> <span class="p">{</span> <span class="nv">$payload</span><span class="p">[</span><span class="s1">'params'</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$params</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="nv">$payload</span><span class="p">;</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 执行 rpc 请求 </span><span class="sd"> * @param array $payload </span><span class="sd"> * @return string </span><span class="sd"> * @throws \Exception </span><span class="sd"> */</span> <span class="k">private</span> <span class="k">function</span> <span class="nf">doRequest</span><span class="p">(</span><span class="k">array</span> <span class="nv">$payload</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$stream</span> <span class="o">=</span> <span class="o">@</span><span class="nx">fopen</span><span class="p">(</span><span class="nx">trim</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">url</span><span class="p">),</span> <span class="s1">'r'</span><span class="p">,</span> <span class="k">false</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="na">getContext</span><span class="p">(</span><span class="nv">$payload</span><span class="p">));</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">is_resource</span><span class="p">(</span><span class="nv">$stream</span><span class="p">))</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">\Exception</span><span class="p">(</span><span class="s1">'钱包链接失败'</span><span class="p">)</span> <span class="p">;</span> <span class="p">}</span> <span class="nv">$metadata</span> <span class="o">=</span> <span class="nx">stream_get_meta_data</span><span class="p">(</span><span class="nv">$stream</span><span class="p">);</span> <span class="c1">// 服务器响应内容 . </span> <span class="nv">$response</span> <span class="o">=</span> <span class="nx">json_decode</span><span class="p">(</span><span class="nx">stream_get_contents</span><span class="p">(</span><span class="nv">$stream</span><span class="p">),</span> <span class="k">true</span><span class="p">);</span> <span class="nv">$header_1</span> <span class="o">=</span> <span class="nv">$metadata</span><span class="p">[</span><span class="s1">'wrapper_data'</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span> <span class="nx">preg_match</span><span class="p">(</span><span class="s1">'/[\\d]{3}/i'</span><span class="p">,</span> <span class="nv">$header_1</span><span class="p">,</span> <span class="nv">$code</span><span class="p">);</span> <span class="nv">$code</span> <span class="o">=</span> <span class="nx">trim</span><span class="p">(</span><span class="nv">$code</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span> <span class="c1">// 返回的状态值 . </span> <span class="k">if</span> <span class="p">(</span><span class="nv">$code</span> <span class="o">==</span> <span class="s1">'200'</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 这段就是服务器返回的信息 . </span> <span class="k">return</span> <span class="nx">isset</span><span class="p">(</span><span class="nv">$response</span><span class="p">[</span><span class="s1">'result'</span><span class="p">])</span> <span class="o">?</span> <span class="nv">$response</span><span class="p">[</span><span class="s1">'result'</span><span class="p">]</span> <span class="o">:</span> <span class="s1">'nodata'</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$response</span><span class="p">[</span><span class="s1">'error'</span><span class="p">]</span> <span class="o">&&</span> <span class="nx">is_array</span><span class="p">(</span><span class="nv">$response</span><span class="p">[</span><span class="s1">'error'</span><span class="p">]))</span> <span class="p">{</span> <span class="nv">$detail</span> <span class="o">=</span> <span class="s1">'code='</span> <span class="o">.</span> <span class="nv">$response</span><span class="p">[</span><span class="s1">'error'</span><span class="p">][</span><span class="s1">'code'</span><span class="p">]</span> <span class="o">.</span> <span class="s1">',message='</span> <span class="o">.</span> <span class="nv">$response</span><span class="p">[</span><span class="s1">'error'</span><span class="p">][</span><span class="s1">'message'</span><span class="p">];</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">\Exception</span><span class="p">(</span><span class="nv">$detail</span><span class="p">)</span> <span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">\Exception</span><span class="p">(</span><span class="nv">$code</span><span class="p">)</span> <span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 获取上下文 </span><span class="sd"> * @param array $payload </span><span class="sd"> * @return resource </span><span class="sd"> */</span> <span class="k">private</span> <span class="k">function</span> <span class="nf">getContext</span><span class="p">(</span><span class="k">array</span> <span class="nv">$payload</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$headers</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">headers</span><span class="p">;</span> <span class="c1">// 用户名密码 认证过程 </span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">username</span><span class="p">)</span> <span class="o">&&</span> <span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">password</span><span class="p">))</span> <span class="p">{</span> <span class="nv">$headers</span><span class="p">[]</span> <span class="o">=</span> <span class="s1">'Authorization: Basic '</span> <span class="o">.</span> <span class="nx">base64_encode</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">username</span> <span class="o">.</span> <span class="s1">':'</span> <span class="o">.</span> <span class="nv">$this</span><span class="o">-></span><span class="na">password</span><span class="p">);</span> <span class="p">}</span> <span class="c1">// 请求内容 </span> <span class="nv">$context</span> <span class="o">=</span> <span class="nx">stream_context_create</span><span class="p">(</span><span class="k">array</span><span class="p">(</span> <span class="s1">'http'</span> <span class="o">=></span> <span class="k">array</span><span class="p">(</span><span class="s1">'method'</span> <span class="o">=></span> <span class="s1">'POST'</span><span class="p">,</span> <span class="s1">'protocol_version'</span> <span class="o">=></span> <span class="mf">1.1000000000000001</span><span class="p">,</span> <span class="s1">'timeout'</span> <span class="o">=></span> <span class="nv">$this</span><span class="o">-></span><span class="na">timeout</span><span class="p">,</span> <span class="s1">'max_redirects'</span> <span class="o">=></span> <span class="mi">2</span><span class="p">,</span> <span class="s1">'header'</span> <span class="o">=></span> <span class="nx">implode</span><span class="p">(</span><span class="s2">"</span><span class="se">\r\n</span><span class="s2">"</span><span class="p">,</span> <span class="nv">$headers</span><span class="p">),</span> <span class="s1">'content'</span> <span class="o">=></span> <span class="nx">json_encode</span><span class="p">(</span><span class="nv">$payload</span><span class="p">),</span> <span class="s1">'ignore_errors'</span> <span class="o">=></span> <span class="k">true</span> <span class="p">),</span> <span class="c1">// ssl 证书 </span> <span class="s1">'ssl'</span> <span class="o">=></span> <span class="k">array</span><span class="p">(</span><span class="s1">'verify_peer'</span> <span class="o">=></span> <span class="nv">$this</span><span class="o">-></span><span class="na">ssl_verify_peer</span><span class="p">,</span> <span class="s1">'verify_peer_name'</span> <span class="o">=></span> <span class="nv">$this</span><span class="o">-></span><span class="na">ssl_verify_peer</span><span class="p">)</span> <span class="p">));</span> <span class="k">return</span> <span class="nv">$context</span> <span class="p">;</span> <span class="p">}</span> <span class="p">}</span> |
- 下面简述开发过程中经常用到的方法:
- 查询钱包状态
- 生成钱包地址
- 对外转账
- 收取转账信息
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
<span class="cp"><?php</span> <span class="k">class</span> <span class="nc">HandleClient</span><span class="p">{</span> <span class="c1">// 客户端 </span> <span class="k">private</span> <span class="nv">$client</span> <span class="p">;</span> <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">()</span> <span class="p">{</span> <span class="nv">$host</span> <span class="o">=</span> <span class="s2">"127.0.0.1"</span> <span class="p">;</span> <span class="c1">// 钱包地址,本地开发通常是本机 本地开发可以用轻量级的山寨币钱包, </span> <span class="nv">$user</span> <span class="o">=</span> <span class="s1">'user'</span><span class="p">;</span> <span class="nv">$password</span> <span class="o">=</span> <span class="s1">'password'</span><span class="p">;</span> <span class="nv">$port</span> <span class="o">=</span> <span class="s1">'6300'</span><span class="p">;</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Client</span><span class="p">(</span><span class="nv">$host</span> <span class="p">,</span><span class="nv">$user</span> <span class="p">,</span><span class="nv">$password</span> <span class="p">,</span><span class="nv">$port</span> <span class="p">,</span><span class="mi">30</span><span class="p">);</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 给站内用户生成一个 地址 ,表结构大致如下 </span><span class="sd"> * -------------------------------- </span><span class="sd"> * id | address | username </span><span class="sd"> * --------------------------------- </span><span class="sd"> * @param $label 用户->address 一对多的关系 </span><span class="sd"> * @return bool|mixed </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">createAddress</span><span class="p">(</span><span class="nv">$label</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 这步骤是获取这个标签的钱包地址,如果已经存在则返回, </span> <span class="nv">$address</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">getaddressesbyaccount</span><span class="p">(</span><span class="nv">$label</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">is_array</span><span class="p">(</span><span class="nv">$address</span><span class="p">)){</span> <span class="nv">$address</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">getnewaddress</span><span class="p">(</span><span class="nv">$label</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$address</span><span class="p">){</span> <span class="k">return</span> <span class="k">false</span> <span class="p">;</span> <span class="p">}</span> <span class="p">}</span><span class="k">else</span><span class="p">{</span> <span class="nv">$address</span> <span class="o">=</span> <span class="nv">$address</span> <span class="p">[</span><span class="mi">0</span><span class="p">];</span> <span class="p">}</span> <span class="k">return</span> <span class="nv">$address</span> <span class="p">;</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 将币转出,平台会有转出币钱包场景,在这之前需要判断是否是站内互转 </span><span class="sd"> * 在这之前需要判断是否是一个有效的钱包地址 </span><span class="sd"> * 该步骤通常以后台任务队列运行 </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">turnout</span><span class="p">(</span><span class="nv">$address</span><span class="p">,</span><span class="nv">$number</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 判断是否是一个有效的钱包地址 </span> <span class="nv">$isAddr</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">validateaddress</span><span class="p">(</span><span class="nv">$address</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$isAddr</span><span class="p">){</span> <span class="k">return</span> <span class="k">false</span><span class="p">;</span> <span class="p">}</span> <span class="c1">// 获取钱包的余额 </span> <span class="nv">$info</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">getinfo</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="nv">$info</span><span class="p">[</span><span class="s1">'balance'</span><span class="p">]</span> <span class="o"><</span> <span class="nv">$number</span> <span class="p">){</span> <span class="k">return</span> <span class="k">false</span> <span class="p">;</span> <span class="p">}</span> <span class="c1">// 发送接口 </span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">sendtoaddress</span><span class="p">(</span><span class="nv">$address</span><span class="p">,</span> <span class="nv">$number</span> <span class="p">);</span> <span class="p">}</span> <span class="sd">/** </span><span class="sd"> * 交易查询接口. </span><span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">trade</span><span class="p">()</span> <span class="p">{</span> <span class="c1">// 该方法 有3个参数,第一个是指查询标签的意思* 查找所有用户 123456 ,查找123456的交易情况 </span> <span class="nv">$list</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">client</span><span class="o">-></span><span class="na">listtransactions</span><span class="p">(</span><span class="s2">"*"</span><span class="p">,</span><span class="mi">100</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span> <span class="k">foreach</span><span class="p">(</span><span class="nv">$list</span> <span class="k">as</span> <span class="nv">$key</span> <span class="o">=></span> <span class="nv">$val</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="nv">$val</span> <span class="p">[</span><span class="s1">'category'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'receive'</span><span class="p">){</span> <span class="c1">// 接受的交易 </span> <span class="nv">$this</span><span class="o">-></span><span class="na">handleReceive</span><span class="p">(</span><span class="nv">$val</span><span class="p">);</span> <span class="p">}</span><span class="k">elseif</span><span class="p">(</span><span class="nv">$val</span> <span class="p">[</span><span class="s1">'category'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'send'</span><span class="p">){</span> <span class="c1">// 发送的交易 </span> <span class="nv">$this</span><span class="o">-></span><span class="na">handleSend</span><span class="p">(</span><span class="nv">$val</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="c1">// 这里是系统用户向平台充币的处理, </span> <span class="c1">// 由于充币事先是不知道的,这里需要动态生成订单 </span> <span class="c1">// txid 是交易的唯一编号 注意启动事务 </span> <span class="k">private</span> <span class="k">function</span> <span class="nf">handleReceive</span><span class="p">(</span><span class="nv">$item</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$address</span> <span class="o">=</span> <span class="nx">DB</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'address'</span><span class="p">)</span><span class="o">-></span><span class="na">where</span><span class="p">([</span><span class="s1">'address'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'address'</span><span class="p">]])</span><span class="o">-></span><span class="na">get</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$address</span><span class="p">){</span> <span class="k">return</span> <span class="p">;</span> <span class="p">}</span> <span class="nv">$row</span> <span class="o">=</span> <span class="nx">DB</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'trade'</span><span class="p">)</span><span class="o">-></span><span class="na">where</span><span class="p">([</span><span class="s1">'txid'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'txid'</span><span class="p">]</span> <span class="p">,</span> <span class="s1">'status'</span> <span class="o">=></span> <span class="mi">0</span> <span class="p">,</span> <span class="s1">'type'</span> <span class="o">=></span> <span class="s1">'receive'</span><span class="p">])</span><span class="o">-></span><span class="na">get</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="nv">$row</span><span class="p">){</span> <span class="c1">// 如果有订单,判断确认次数 </span> <span class="k">if</span><span class="p">(</span><span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">]</span> <span class="o">>=</span> <span class="mi">2</span><span class="p">){</span> <span class="nv">$row</span><span class="o">-></span><span class="na">save</span><span class="p">([</span><span class="s1">'status'</span> <span class="o">=></span> <span class="mi">1</span> <span class="p">,</span> <span class="s1">'confirmations'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">]]);</span> <span class="c1">// 给用户加钱 </span> <span class="nv">$user</span> <span class="o">=</span> <span class="nv">$address</span><span class="o">-></span><span class="na">user</span><span class="p">()</span><span class="o">-></span><span class="na">increment</span><span class="p">(</span><span class="s1">'coin'</span><span class="p">,</span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'amount'</span><span class="p">]);</span> <span class="p">}</span> <span class="p">}</span><span class="k">else</span><span class="p">{</span> <span class="nv">$arr</span> <span class="o">=</span> <span class="p">[</span> <span class="s1">'confirmations'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">],</span> <span class="s1">'user_id'</span> <span class="o">=></span> <span class="nv">$address</span><span class="o">-></span><span class="na">user</span><span class="o">-></span><span class="na">id</span> <span class="p">,</span> <span class="s1">'amount'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'amount'</span><span class="p">],</span> <span class="s1">'txid'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'txid'</span><span class="p">],</span> <span class="p">];</span> <span class="k">if</span><span class="p">(</span><span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">]</span> <span class="o">>=</span> <span class="mi">2</span><span class="p">){</span> <span class="nv">$arr</span> <span class="p">[</span><span class="s1">'status'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">;</span> <span class="nv">$user</span> <span class="o">=</span> <span class="nv">$address</span><span class="o">-></span><span class="na">user</span><span class="p">()</span><span class="o">-></span><span class="na">increment</span><span class="p">(</span><span class="s1">'coin'</span><span class="p">,</span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'amount'</span><span class="p">]);</span> <span class="p">}</span><span class="k">else</span><span class="p">{</span> <span class="nv">$arr</span> <span class="p">[</span><span class="s1">'status'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="nx">DB</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'trade'</span><span class="p">)</span><span class="o">-></span><span class="na">create</span><span class="p">(</span><span class="nv">$arr</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="c1">// 处理转出情况,转出是用户发起的,不需要动态插表 </span> <span class="k">private</span> <span class="k">function</span> <span class="nf">handleSend</span><span class="p">(</span><span class="nv">$item</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$row</span> <span class="o">=</span> <span class="nx">DB</span><span class="o">::</span><span class="na">where</span><span class="p">([</span><span class="s1">'address'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'address'</span><span class="p">]])</span><span class="o">-></span><span class="na">get</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$row</span><span class="p">){</span> <span class="k">return</span> <span class="p">;</span> <span class="p">}</span> <span class="k">if</span><span class="p">(</span><span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">]</span> <span class="o">>=</span> <span class="mi">2</span><span class="p">){</span> <span class="nv">$row</span><span class="o">-></span><span class="na">save</span><span class="p">([</span><span class="s1">'status'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">,</span><span class="s1">'txid'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'txid'</span><span class="p">]</span> <span class="p">,</span> <span class="s1">'confirmations'</span> <span class="o">=></span> <span class="nv">$item</span><span class="p">[</span><span class="s1">'confirmations'</span><span class="p">]]);</span> <span class="c1">// 可能需要处理用户币的冻结情况, </span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> |
- 由于接触虚拟币开发比较多,因此对这个略有了解,虚拟币开发我几乎没找到什么文档,希望给广大的爱好者来一发!
- rpc接口列表.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
addmultisigaddress <nrequired> <'["key","key"]'> [account] addnode <node> <add|remove|onetry> backupwallet <destination> createmultisig <nrequired> <'["key","key"]'> createrawtransaction [{"txid":txid,"vout":n},...] {address:amount,...} decoderawtransaction <hex string> dumpprivkey <chinacoinaddress> encryptwallet <passphrase> getaccount <chinacoinaddress> getaccountaddress <account> getaddednodeinfo <dns> [node] getaddressesbyaccount <account> getbalance [account] [minconf=1] getbestblockhash getblock <hash> [verbose=true] getblockcount getblockhash <index> getblocktemplate [params] getconnectioncount getdifficulty getgenerate gethashespersec getinfo getmininginfo getnetworkhashps [blocks] [height] getnewaddress [account] getpeerinfo getrawmempool getrawtransaction <txid> [verbose=0] getreceivedbyaccount <account> [minconf=1] getreceivedbyaddress <chinacoinaddress> [minconf=1] gettransaction <txid> gettxout <txid> <n> [includemempool=true] gettxoutsetinfo getwork [data] getworkex [data, coinbase] help [command] importprivkey <chinacoinprivkey> [label] [rescan=true] keypoolrefill listaccounts [minconf=1] listaddressgroupings listlockunspent listreceivedbyaccount [minconf=1] [includeempty=false] listreceivedbyaddress [minconf=1] [includeempty=false] listsinceblock [blockhash] [target-confirmations] listtransactions [account] [count=10] [from=0] listunspent [minconf=1] [maxconf=9999999] ["address",...] lockunspent unlock? [array-of-Objects] move <fromaccount> <toaccount> <amount> [minconf=1] [comment] sendfrom <fromaccount> <tochinacoinaddress> <amount> [minconf=1] [comment] [comment-to] sendmany <fromaccount> {address:amount,...} [minconf=1] [comment] sendrawtransaction <hex string> sendtoaddress <chinacoinaddress> <amount> [comment] [comment-to] setaccount <chinacoinaddress> <account> setgenerate <generate> [genproclimit] setmininput <amount> settxfee <amount> signmessage <chinacoinaddress> <message> signrawtransaction <hex string> [{"txid":txid,"vout":n,"scriptPubKey":hex,"redeemScript":hex},...] [<privatekey1>,...] [sighashtype="ALL"] stop submitblock <hex data> [optional-params-obj] validateaddress <chinacoinaddress> verifychain [check level] [num blocks] verifymessage <chinacoinaddress> <signature> <message> |