<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Mas_Tan</title>
    <description>No Praise For Colorful</description>
    <link>https://github.com/tanhuiya/</link>
    <atom:link href="https://github.com/tanhuiya/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 18 Sep 2018 06:48:52 +0000</pubDate>
    <lastBuildDate>Tue, 18 Sep 2018 06:48:52 +0000</lastBuildDate>
    <generator>Jekyll v3.7.4</generator>
    
      <item>
        <title>乐谱 🎼 iOS 解析</title>
        <description>&lt;p&gt;上半年开发了一款含乐谱解析功能的&lt;code class=&quot;highlighter-rouge&quot;&gt;App&lt;/code&gt;,网上也没有找到类似的，就自己做了一款。后来由于某些原因，把代码上传到了&lt;code class=&quot;highlighter-rouge&quot;&gt;github&lt;/code&gt;上，之后就没管。不过最近不少人问我这个乐谱的相关功能实现，于是在这里讲一下，也可以给以后有此需求的童鞋们有个参照, 授人予鱼，不如授人予渔。&lt;/p&gt;

&lt;p&gt;效果如下，这里主要介绍一下一些知识点，和用到的算法。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1453111-67603136bf880b82.gif?imageMogr2/auto-orient/strip&quot; alt=&quot;playing.gif&quot; /&gt;&lt;/p&gt;

&lt;p&gt;乐谱的素材一般有两种，&lt;code class=&quot;highlighter-rouge&quot;&gt;xml&lt;/code&gt; 文件和 &lt;code class=&quot;highlighter-rouge&quot;&gt;midi&lt;/code&gt; 文件，&lt;code class=&quot;highlighter-rouge&quot;&gt;midi&lt;/code&gt; 是可以播放的二进制文件（用&lt;code class=&quot;highlighter-rouge&quot;&gt;iOS&lt;/code&gt;自带的播放器，效果很差！！！）。&lt;/p&gt;

&lt;p&gt;需求是，教师会在后台上传乐谱的&lt;code class=&quot;highlighter-rouge&quot;&gt;xml&lt;/code&gt;文件，客户端下载后解析&lt;/p&gt;

&lt;p&gt;这个项目用到了很多&lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt; 的实现，并且抽离具体项目开发。一个是 &lt;code class=&quot;highlighter-rouge&quot;&gt;C++ &lt;/code&gt;速度快，另一个是安卓可以复用。所以，有些功能模块的东西，都尽量用&lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt;写，&lt;code class=&quot;highlighter-rouge&quot;&gt;iOS &lt;/code&gt;可以引用 &lt;code class=&quot;highlighter-rouge&quot;&gt;.a&lt;/code&gt; 文件，安卓可以引用打包成的 &lt;code class=&quot;highlighter-rouge&quot;&gt;.so&lt;/code&gt; 文件。&lt;/p&gt;

&lt;h2 id=&quot;解析&quot;&gt;解析&lt;/h2&gt;

&lt;p&gt;第一步就是解析xml文件，一张乐谱的信息很多，这里就不细说了，打开&lt;code class=&quot;highlighter-rouge&quot;&gt;xml&lt;/code&gt;文件看看就知道了。解析的过程，找到了国外的一个&lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt;写的专门解析&lt;code class=&quot;highlighter-rouge&quot;&gt;xml&lt;/code&gt;的程序，想直接拿来用当然是不可能的啦！ 拿过来后略加修改，最烦的当然是和项目的对接啦&lt;/p&gt;

&lt;p&gt;比如头文件的引用，&lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt; 的编译版本， 有些文件和 &lt;code class=&quot;highlighter-rouge&quot;&gt;OC&lt;/code&gt; 的内置库文件重名，会导致编译通过，打包失败， 等等。。，（之前一个项目对接过&lt;code class=&quot;highlighter-rouge&quot;&gt;cocos2d-lua&lt;/code&gt;），经过这个项目后，对&lt;code class=&quot;highlighter-rouge&quot;&gt;iOS&lt;/code&gt;工程的 &lt;code class=&quot;highlighter-rouge&quot;&gt;build setting&lt;/code&gt; 更加熟悉了 😂。&lt;a href=&quot;https://github.com/Webern/MusicXML-Class-Library&quot;&gt;传送门&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;解析完之后，会得到一个 &lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt; 的 &lt;code class=&quot;highlighter-rouge&quot;&gt;mDoc&lt;/code&gt; 对象，&lt;code class=&quot;highlighter-rouge&quot;&gt;iOS&lt;/code&gt; 可以直接调试&lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt;代码，所以&lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt;这块工作都是我来做。 看看部分属性展示如下。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1453111-b03b6ea146d7cddf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;mDoc.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;类似一个树形结构吧，为了之后在程序中好用，统一写一个解析器，把这个 &lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt; 对象转成 &lt;code class=&quot;highlighter-rouge&quot;&gt;OC&lt;/code&gt; 对象&lt;code class=&quot;highlighter-rouge&quot;&gt;Score&lt;/code&gt;， 该对象的类图大概如下：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1453111-74306fea383c108c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;musicxml类图 (1).png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;有很多专业用词，比如音轨，还有tempo的解释我就不一一科普了，可以看出来，对象类型还是挺多的。按照如上的图，一个一个解析吧。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;解析的过程有几个难点：&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;音符(&lt;code class=&quot;highlighter-rouge&quot;&gt;note&lt;/code&gt;)的时长怎么定义，音符的宽度怎么定义&lt;/li&gt;
  &lt;li&gt;音节(&lt;code class=&quot;highlighter-rouge&quot;&gt;measure&lt;/code&gt;)的宽度怎么保持一致&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;音符的位置&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;音节如何换行&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;以上几个问题，是在绘制前需要解决的。我们一个一个来。&lt;/p&gt;

&lt;p&gt;音符的时长：&lt;/p&gt;

&lt;p&gt;学过的音乐的都知道，音符有二分之一拍，四分之一拍，八分之一拍 等等，不懂的可以去查维基百科&lt;/p&gt;

&lt;p&gt;每个音轨有个&lt;code class=&quot;highlighter-rouge&quot;&gt;division&lt;/code&gt;标签，代表一个四分之一音符对应的时长&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;attributes&amp;gt;
    &amp;lt;divisions&amp;gt;24&amp;lt;/divisions&amp;gt;
    &amp;lt;key&amp;gt;
      &amp;lt;fifths&amp;gt;-3&amp;lt;/fifths&amp;gt;
      &amp;lt;mode&amp;gt;major&amp;lt;/mode&amp;gt;
    &amp;lt;/key&amp;gt;
    &amp;lt;time&amp;gt;
      &amp;lt;beats&amp;gt;3&amp;lt;/beats&amp;gt;
      &amp;lt;beat-type&amp;gt;4&amp;lt;/beat-type&amp;gt;
    &amp;lt;/time&amp;gt;
    &amp;lt;clef&amp;gt;
      &amp;lt;sign&amp;gt;G&amp;lt;/sign&amp;gt;
      &amp;lt;line&amp;gt;2&amp;lt;/line&amp;gt;
    &amp;lt;/clef&amp;gt;
  &amp;lt;/attributes&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;key&lt;/code&gt; 代表的是这个音轨要 升 或 降 几调&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;division&lt;/code&gt; 代表每个四分之一音符的时长，这里是24&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;time&lt;/code&gt; 代表每个音节是几几拍，如上是每个四分之一音符为一拍，每个音节共三拍，简称四三拍&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;clef&lt;/code&gt; 是这个音节的音调&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;如下代表一个&lt;code class=&quot;highlighter-rouge&quot;&gt;note&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;note default-x=&quot;196&quot;&amp;gt;
    &amp;lt;pitch&amp;gt;
      &amp;lt;step&amp;gt;B&amp;lt;/step&amp;gt;
      &amp;lt;alter&amp;gt;-1&amp;lt;/alter&amp;gt;
      &amp;lt;octave&amp;gt;4&amp;lt;/octave&amp;gt;
    &amp;lt;/pitch&amp;gt;
    &amp;lt;duration&amp;gt;24&amp;lt;/duration&amp;gt;
    &amp;lt;voice&amp;gt;1&amp;lt;/voice&amp;gt;
    &amp;lt;type&amp;gt;quarter&amp;lt;/type&amp;gt;
    &amp;lt;stem default-y=&quot;-55.5&quot;&amp;gt;down&amp;lt;/stem&amp;gt;
    &amp;lt;lyric default-y=&quot;-80&quot; number=&quot;1&quot;&amp;gt;
      &amp;lt;syllabic&amp;gt;single&amp;lt;/syllabic&amp;gt;
      &amp;lt;text&amp;gt;Auf&amp;lt;/text&amp;gt;
    &amp;lt;/lyric&amp;gt;
  &amp;lt;/note&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;type -&amp;gt; quarter&lt;/code&gt; 代表是个四分之一音符，&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;duration&lt;/code&gt; 就对应之前的&lt;code class=&quot;highlighter-rouge&quot;&gt; division&lt;/code&gt;，&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;pitch &lt;/code&gt;代表这个音符的位置，在五线谱的垂直位置&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;stem&lt;/code&gt; 代表他的尾巴朝向，这个是由五线谱导出来的，有一定参考意义，但后面还需根据实际情况重新计算&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;lyric&lt;/code&gt; 歌词信息&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这里的duration就可以定义为时长，简单来说，duration 越大，这个音符时间越长！&lt;br /&gt;
注意，每个音轨（part）的 division 可能不一样，所以处理的时候，要统一成一个值。
比如：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;part1&lt;/code&gt; 中 &lt;code class=&quot;highlighter-rouge&quot;&gt;division&lt;/code&gt; = &lt;code class=&quot;highlighter-rouge&quot;&gt;24&lt;/code&gt;， 一个 &lt;code class=&quot;highlighter-rouge&quot;&gt;note&lt;/code&gt; 的 &lt;code class=&quot;highlighter-rouge&quot;&gt;duration&lt;/code&gt; 为&lt;code class=&quot;highlighter-rouge&quot;&gt; 12&lt;/code&gt;， 它就是一个 八分之一 音符，&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;part2&lt;/code&gt; 中 &lt;code class=&quot;highlighter-rouge&quot;&gt;division&lt;/code&gt; = &lt;code class=&quot;highlighter-rouge&quot;&gt;96&lt;/code&gt;， 一个 &lt;code class=&quot;highlighter-rouge&quot;&gt;note &lt;/code&gt;的 &lt;code class=&quot;highlighter-rouge&quot;&gt;duration&lt;/code&gt; 为 &lt;code class=&quot;highlighter-rouge&quot;&gt;192&lt;/code&gt;， 它就是一个 二分之一 音符&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;音符的开始时间，就是由它用轨道前面的所有&lt;code class=&quot;highlighter-rouge&quot;&gt;duration&lt;/code&gt;加起来（包括休止符– &lt;code class=&quot;highlighter-rouge&quot;&gt;rest&lt;/code&gt;），音符的时长可以定义成在整个音轨的绝对时间，也可以定义成相对于当前音节的相对时间。 我是从第一种后来改到第二张的，为了后面处理音节换行方便。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1453111-fdc4bf31b129b636.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;startTime.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;音节的开始时间有了，持续时间也有了，那具体画在什么位置呢，这个就有讲究了&lt;/p&gt;

&lt;p&gt;待续。。。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1453111-e5da3d3fdcacf094.gif?imageMogr2/auto-orient/strip&quot; alt=&quot;playing.gif&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 09 Sep 2018 06:59:28 +0000</pubDate>
        <link>https://github.com/tanhuiya/2018/09/iOS%E4%B9%90%E8%B0%B1%E8%A7%A3%E6%9E%90/</link>
        <guid isPermaLink="true">https://github.com/tanhuiya/2018/09/iOS%E4%B9%90%E8%B0%B1%E8%A7%A3%E6%9E%90/</guid>
        
        
      </item>
    
      <item>
        <title>cocos2d-js 视频小屏播放</title>
        <description>&lt;h2 id=&quot;问题&quot;&gt;问题&lt;/h2&gt;

&lt;p&gt;在大学的时候，做过 &lt;code class=&quot;highlighter-rouge&quot;&gt;cocos2d-x&lt;/code&gt; 开发，这次有个小项目，就准备用 cocos2d-js 写，用法都差不多，语言不一样而已。 这次还是碰到了一些坑，记录下踩坑过程！&lt;/p&gt;

&lt;p&gt;然后里面用到视频播放组件的时候，发现出了一些问题，不得不说，&lt;code class=&quot;highlighter-rouge&quot;&gt;cocos&lt;/code&gt; 的坑还是不少的 😂&lt;/p&gt;

&lt;p&gt;都知道微信h5中设置视频小屏播放的策略，给&lt;code class=&quot;highlighter-rouge&quot;&gt;video&lt;/code&gt; 标签加属性。&lt;/p&gt;

&lt;p&gt;但是在&lt;code class=&quot;highlighter-rouge&quot;&gt;cocos2d&lt;/code&gt;引擎里不怎么好加啊！&lt;/p&gt;

&lt;p&gt;深入到 &lt;code class=&quot;highlighter-rouge&quot;&gt;cocos2djs&lt;/code&gt; 的引擎代码，查看它内部是怎么设置属性的，看到可以添加一些样式，但是我要的那些属性却添加不了，当然，也有可能是我的姿势不对。&lt;/p&gt;

&lt;p&gt;研究了大概一天吧，后来想到一个方法，还是不在引擎源码里动手脚了。&lt;/p&gt;

&lt;h2 id=&quot;解决&quot;&gt;解决&lt;/h2&gt;

&lt;p&gt;在添加完 &lt;code class=&quot;highlighter-rouge&quot;&gt;videoPlayer&lt;/code&gt; 组件之后，利用原生&lt;code class=&quot;highlighter-rouge&quot;&gt;js &lt;/code&gt;对&lt;code class=&quot;highlighter-rouge&quot;&gt;dom&lt;/code&gt;进行操作。给 &lt;code class=&quot;highlighter-rouge&quot;&gt;video&lt;/code&gt; 标签动态添加属性。这个想法说出来有点普通，但是当时真的没想到啊！ 代码如下：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;创建 &lt;code class=&quot;highlighter-rouge&quot;&gt;videoPlayer&lt;/code&gt; 组建&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var player = new ccui.VideoPlayer(res.s_video)
this.addChild(player, 1, 1)
this.videoPlayer_ = player
player.setContentSize(395, 290)
player.setPosition(g_size.width * 0.5, -145)
var that = this
player.setEventListener(ccui.VideoPlayer.EventType.COMPLETED, function () {
    console.log(&quot;over&quot;)
})

geek_game_setup_video()

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;动态修改 &lt;code class=&quot;highlighter-rouge&quot;&gt;video&lt;/code&gt; 标签的属性&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;function geek_game_setup_video() {
    var video = document.getElementsByClassName(&quot;cocosVideo&quot;)[0]
    if (video) {
        video.setAttribute(&quot;webkit-playsinline&quot;, &quot;true&quot;)
        video.setAttribute(&quot;playsinline&quot;, &quot;true&quot;)
        
        video.setAttribute(&quot;x5-playsinline&quot;, &quot;true&quot;)
        video.setAttribute(&quot;x5-video-player-type&quot;, &quot;h5&quot;)
//            video.setAttribute(&quot;x5-video-orientation&quot;, &quot;portraint&quot;)
//            video.setAttribute(&quot;x5-video-player-fullscreen&quot;, &quot;true&quot;)
        video.setAttribute(&quot;controls&quot;, &quot;true&quot;)
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;前面两个属性 &lt;code class=&quot;highlighter-rouge&quot;&gt;webkit-playsinline&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;playsinline&lt;/code&gt; 会在苹果手机上起作用， 下面的是安卓端微信对内置&lt;code class=&quot;highlighter-rouge&quot;&gt; x5&lt;/code&gt; 浏览器的适配。&lt;/p&gt;

&lt;h2 id=&quot;延伸&quot;&gt;延伸&lt;/h2&gt;

&lt;p&gt;由于设置了 &lt;code class=&quot;highlighter-rouge&quot;&gt;controls&lt;/code&gt; 标签， 播放器会显示一些内置的组件，比如播放，快进，全屏这些。
所以我又要隐藏全屏的按钮。&lt;/p&gt;

&lt;p&gt;在&lt;code class=&quot;highlighter-rouge&quot;&gt;css&lt;/code&gt; 样式上，添加如下：&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;video::-webkit-media-controls-fullscreen-button {
    display: none;
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;这样就 &lt;code class=&quot;highlighter-rouge&quot;&gt;ok&lt;/code&gt; 了&lt;/p&gt;

&lt;h2 id=&quot;后续&quot;&gt;后续&lt;/h2&gt;

&lt;p&gt;在安卓手机上访问会发现，非常模糊，要说分辨率不够，也应该是 &lt;code class=&quot;highlighter-rouge&quot;&gt;iphone&lt;/code&gt; 上模糊呀。&lt;/p&gt;

&lt;p&gt;查到网上有以下修改方式&lt;/p&gt;

&lt;p&gt;原引擎代码如下：&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var devicePixelRatio = view._devicePixelRatio = 1;
if (view.isRetinaEnabled())
    devicePixelRatio = view._devicePixelRatio = window.devicePixelRatio || 1;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在安卓上，&lt;code class=&quot;highlighter-rouge&quot;&gt;devicePixelRatio&lt;/code&gt; 会背设置为 1， 导致显示模糊， 所以把上面直接修改为：&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;devicePixelRatio = view._devicePixelRatio = window.devicePixelRatio || 1;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;就可以清楚的显示了&lt;/p&gt;

&lt;h3 id=&quot;但是&quot;&gt;但是！&lt;/h3&gt;

&lt;p&gt;前面说到的 &lt;code class=&quot;highlighter-rouge&quot;&gt;videoPlayer&lt;/code&gt; 组件不显示了！&lt;br /&gt;
猜想是设置 &lt;code class=&quot;highlighter-rouge&quot;&gt;devicePixelRatio &lt;/code&gt; 的原因。&lt;/p&gt;

&lt;p&gt;查看源码发现，videoPlayer 内部也引用到了 &lt;code class=&quot;highlighter-rouge&quot;&gt;view.isRetinaEnabled()&lt;/code&gt; 判断来绘图，所以上面设置 devicePixelRatio 和 这边产生了冲突。&lt;br /&gt;
把上面的代码恢复了，后来又找到另一种方法可以统一设置。在引擎代码完全启动后，设置如下:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cc.view.enableRetina(true)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;这样在安卓上也能正常显示了。&lt;/p&gt;
</description>
        <pubDate>Sat, 08 Sep 2018 06:59:28 +0000</pubDate>
        <link>https://github.com/tanhuiya/2018/09/cocos2d-js%E8%A7%86%E9%A2%91%E6%92%AD%E6%94%BE%E5%B0%8F%E5%B1%8F/</link>
        <guid isPermaLink="true">https://github.com/tanhuiya/2018/09/cocos2d-js%E8%A7%86%E9%A2%91%E6%92%AD%E6%94%BE%E5%B0%8F%E5%B1%8F/</guid>
        
        
      </item>
    
      <item>
        <title>区块链-侧链</title>
        <description>&lt;h1 id=&quot;什么是侧链&quot;&gt;什么是侧链？&lt;/h1&gt;
&lt;p&gt;侧链，简单的说，就是一种使货币在两条区块链间移动的机制&lt;/p&gt;

&lt;h1 id=&quot;应用场景&quot;&gt;应用场景&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;用户&lt;code class=&quot;highlighter-rouge&quot;&gt;Alice&lt;/code&gt;, 在&lt;code class=&quot;highlighter-rouge&quot;&gt;xxx&lt;/code&gt;链上有一个币，可以兑换到&lt;code class=&quot;highlighter-rouge&quot;&gt;yyy&lt;/code&gt;链上总价值等量的三个币&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Alice&lt;/code&gt;在&lt;code class=&quot;highlighter-rouge&quot;&gt;yyy&lt;/code&gt;链上的三个币，又可以兑换回&lt;code class=&quot;highlighter-rouge&quot;&gt;xxx&lt;/code&gt;链上的一个币。&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;实现&quot;&gt;实现&lt;/h1&gt;
&lt;h2 id=&quot;双向挂钩&quot;&gt;双向挂钩&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;侧链协议的设计难点在于如何让资产在主链和侧链之间安全流转。简而言之，接受资产的链必须确保发送资产的链上的币被可靠锁定。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1453111-fd7f2cb15ac1e485.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;sidechain_spv.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;具体，协议采用双向挂钩机制实现比特币向侧链转移和返回。主链和侧链需要对对方的特定交易做 &lt;code class=&quot;highlighter-rouge&quot;&gt;SPV &lt;/code&gt;验证。完整过程如下：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;当用户要向侧链转移比特币时，首先在主链创建交易，待转移的比特币被发往一个特殊的输出。这些比特币在主链上被锁定。&lt;/li&gt;
  &lt;li&gt;等待一段确认期，使得上述交易获得足够的工作量确认。&lt;/li&gt;
  &lt;li&gt;用户在侧链创建交易提取比特币，需要在这笔交易的输入指明上述主链被锁定的输出，并提供足够的&lt;code class=&quot;highlighter-rouge&quot;&gt; SPV &lt;/code&gt;证明。&lt;/li&gt;
  &lt;li&gt;等待一段竞争期，防止双重花费攻击。&lt;/li&gt;
  &lt;li&gt;比特币在侧链上自由流通。&lt;/li&gt;
  &lt;li&gt;当用户想让比特币返回主链时，采取类似的反向操作。首先在侧链创建交易，待返回的比特币被发往一个特殊的输出。先等待一段确认期后，在主链用足够的对侧链输出的 &lt;code class=&quot;highlighter-rouge&quot;&gt;SPV&lt;/code&gt; 证明来解锁最早被锁定的输出。竞争期过后，主链比特币恢复流通。&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;侧链典型案例&quot;&gt;侧链典型案例&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;这里说一下两种比较有名的侧链架构&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;btc-relay&quot;&gt;BTC Relay&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;BTC Relay&lt;/code&gt; 本质上是在以太坊上用合约重写了比特币的spv验证规则。&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;BTC Relay&lt;/code&gt;其主要原理是把以太坊网络与比特币网络以一种安全去中心化的方式连接起来。&lt;code class=&quot;highlighter-rouge&quot;&gt;BTC Relay&lt;/code&gt;通过使用以太坊的智能合约功能可以允许用户在以太坊区块链上验证比特币交易。侧链机制不仅允许用户将交易发送到其他的地址或账户，还可以发送到其他的区块链。&lt;code class=&quot;highlighter-rouge&quot;&gt;BTC Relay&lt;/code&gt;使用区块头创建一种小型版本的比特币区块链，以太坊&lt;code class=&quot;highlighter-rouge&quot;&gt;DApp&lt;/code&gt;开发者可以从智能合约向&lt;code class=&quot;highlighter-rouge&quot;&gt;BTC Relay&lt;/code&gt;进行&lt;code class=&quot;highlighter-rouge&quot;&gt;API&lt;/code&gt;调用来验证比特币网络活动。其使用场景如下图：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1453111-e43fa1a4c8c66c58.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;sidechain_relay.png&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;应用场景-1&quot;&gt;应用场景&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Alice和Bob同意使用BTCSwap合约来进行交易，Alice要买Bob的eth，Bob把他的 eth发送到BTCSwap合约&lt;/li&gt;
  &lt;li&gt;Alice向Bob发送bitcoin，她希望BTCSwap这个合约能知道这件事以便BTCSwap合约可以释放Bob之前的eth&lt;/li&gt;
  &lt;li&gt;Alice通过bitcoin的交易信息以及BTCSwap合约地址来调用btcrelay.relayTx()，btcrelay验证这笔交易通过后就触发BTCSwap合约里面的processTransaction方法&lt;/li&gt;
  &lt;li&gt;BTCSwap合约在被触发后确认这个btcrelay地址是一个合法地址，然后释放之前Bob的eth，交易完成。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;asch&quot;&gt;Asch&lt;/h2&gt;

&lt;p&gt;一个&lt;code class=&quot;highlighter-rouge&quot;&gt;DApp&lt;/code&gt;对应一个侧链
&lt;code class=&quot;highlighter-rouge&quot;&gt;Asch&lt;/code&gt;(中文阿希）是一个区块链应用平台，它也是一个多链变形的体系，在这个生态体系里有一个主链和一系类的侧链。现在的阿希链就是这个平台的主链，而发布的&lt;code class=&quot;highlighter-rouge&quot;&gt;CCTIME&lt;/code&gt;、时讯和孔明屋就是侧链。侧链和侧链之间是无法互通的，他必须通过主链&lt;code class=&quot;highlighter-rouge&quot;&gt;Asch&lt;/code&gt;来进行互通。互通的是资产的代币，比如说：阿希币、时讯币、孔明币。&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Asch&lt;/code&gt;的主链与侧链之间是互惠互利的关系，主链为侧链提供基础设施，比如数据库写入的&lt;code class=&quot;highlighter-rouge&quot;&gt;api&lt;/code&gt;，网络通讯&lt;code class=&quot;highlighter-rouge&quot;&gt;api&lt;/code&gt;，加密&lt;code class=&quot;highlighter-rouge&quot;&gt;api&lt;/code&gt;等等，侧链则可以为主链补充更多的节点，以壮大整个系统。 侧链的开发者不需要提供所有的机器，可以利用已经存在主链节点，只需要节点主人安装该应用即可。 另外，主链的代币可以转入侧链中，由于代币可以在交易所交易，就相当于为侧链的资产提供了一种价值的媒介。 开发者在侧链发行一种资产后，可以直接与代币兑换，不需要考虑交易平台的问题。如图：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload-images.jianshu.io/upload_images/1453111-cd974df68851979c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240&quot; alt=&quot;sidechain_asch.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Asch&lt;/code&gt; 系统提供了一个命令行工具，可以用来轻松创建一个基础的侧链系统，侧链的开发者也可以深度定制自己的侧链，侧链拥有自己的数据库、共识机制、交易类型以及账户体系。侧链可以托管在独立的委托人节点集群中，这就自然形成了一种分片的机制，延缓了主区块链的膨胀。&lt;/p&gt;

&lt;p&gt;参考链接：&lt;a href=&quot;https://www.youtube.com/watch?v=ixY968Lhyh0&quot;&gt;侧链为王&lt;/a&gt; 、&lt;a href=&quot;https://www.jianshu.com/p/4ca26cd3aaa5&quot;&gt;侧链的价值&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Sat, 14 Jul 2018 06:59:28 +0000</pubDate>
        <link>https://github.com/tanhuiya/2018/07/%E5%8C%BA%E5%9D%97%E9%93%BE-%E4%BE%A7%E9%93%BE/</link>
        <guid isPermaLink="true">https://github.com/tanhuiya/2018/07/%E5%8C%BA%E5%9D%97%E9%93%BE-%E4%BE%A7%E9%93%BE/</guid>
        
        
      </item>
    
      <item>
        <title>Crontab 定时任务，维护进程</title>
        <description>&lt;hr /&gt;

&lt;blockquote&gt;
  &lt;p&gt;在服务器上跑一个进程，不过几天后可能会突然挂掉，可能是 RAM 不够等原因，具体还要排查。。。&lt;/p&gt;

  &lt;p&gt;于是就想写一个定时任务，每分钟检查这个进程还在不在，如果已经挂掉的话，就重新启动.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;crontab&quot;&gt;Crontab&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;crontab&lt;/code&gt; 是一个linux下的定时执行工具，可以在无需人工干预的情况下运行作业。是一个周期性运行的命令，在约定的时间执行已经计划好的工作.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cron&lt;/code&gt; 定时规则&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;包含以下几个参数 &lt;code class=&quot;highlighter-rouge&quot;&gt;m h  dom mon dow   command&lt;/code&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;m(分钟)&lt;/th&gt;
      &lt;th&gt;h(小时)&lt;/th&gt;
      &lt;th&gt;dom(日期)&lt;/th&gt;
      &lt;th&gt;mon(月份)&lt;/th&gt;
      &lt;th&gt;dow(星期)&lt;/th&gt;
      &lt;th&gt;command(命令)&lt;/th&gt;
      &lt;th&gt;解释&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;/home/start.sh&lt;/td&gt;
      &lt;td&gt;每分钟执行 start.sh&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;*/3&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;/home/start.sh&lt;/td&gt;
      &lt;td&gt;每3分钟执行 start.sh&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;/home/start.sh&lt;/td&gt;
      &lt;td&gt;每小时第3分钟执行 start.sh&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3,10&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;/home/start.sh&lt;/td&gt;
      &lt;td&gt;每小时第3分钟,第10分钟执行 start.sh&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;/home/start.sh&lt;/td&gt;
      &lt;td&gt;每天10:03执行 start.sh&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;/home/start.sh&lt;/td&gt;
      &lt;td&gt;每个周一的10:03执行 start.sh&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;/home/start.sh&lt;/td&gt;
      &lt;td&gt;从01:00到01:59 每隔1分钟 执行&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;*/1&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;/home/start.sh&lt;/td&gt;
      &lt;td&gt;每个小时的 0 分执行&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;/home/start.sh&lt;/td&gt;
      &lt;td&gt;每个小时的 0 分执行,同上&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;8-14/2&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;/home/start.sh&lt;/td&gt;
      &lt;td&gt;每天 8:01,10:01,12:01,14:01 执行&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;/home/start.sh&lt;/td&gt;
      &lt;td&gt;每个月的 3号03:03 执行&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;编辑配置文件&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;crontab -e
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;我的需求是每3分钟跑一下脚本，在最后添加一行&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;*/3 * * * * /home/startETH.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;保存退出&lt;/p&gt;

&lt;p&gt;不出意外，&lt;code class=&quot;highlighter-rouge&quot;&gt;startETH.sh&lt;/code&gt; 会在3分钟后执行。&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;startETH.sh&lt;/code&gt; 文件中判断也很简单&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#! /bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 查看是否存在 geth 进程&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;PROCESS_NUM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;ps &lt;span class=&quot;nt&quot;&gt;-fe&lt;/span&gt; |grep &lt;span class=&quot;s2&quot;&gt;&quot;geth&quot;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;grep&quot;&lt;/span&gt; | wc &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$PROCESS_NUM&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-eq&lt;/span&gt; 0 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then
&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Geth has shutdown&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Restarting ....&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 重新启动&lt;/span&gt;
nohup geth &lt;span class=&quot;nt&quot;&gt;--datadir&lt;/span&gt; /home/ethereum &lt;span class=&quot;nt&quot;&gt;--cache&lt;/span&gt; 1024 &lt;span class=&quot;nt&quot;&gt;--rpc&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--rpcaddr&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;0.0.0.0&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--rpcport&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;8545&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--rpcapi&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;db,eth,net,web3,personal&quot;&lt;/span&gt; 2&amp;gt;&amp;gt; ./logs/geth_network.log &amp;amp;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Started success&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;OK&lt;/code&gt;, 利用 &lt;code class=&quot;highlighter-rouge&quot;&gt;Cron&lt;/code&gt; 实现还是蛮方便的，或者直接写一个死循环也可以的～&lt;/p&gt;

</description>
        <pubDate>Sat, 14 Jul 2018 06:59:28 +0000</pubDate>
        <link>https://github.com/tanhuiya/2018/07/Crontab%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1/</link>
        <guid isPermaLink="true">https://github.com/tanhuiya/2018/07/Crontab%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1/</guid>
        
        
      </item>
    
      <item>
        <title>C++ 面试</title>
        <description>&lt;hr /&gt;
&lt;p&gt;layout: post
title: C++ 面试
date: 2018-07-14 15:59:28.000000000 +09:00
—&lt;/p&gt;

&lt;h3 id=&quot;为什么c的-member-function-template不能是virtual的-&quot;&gt;为什么&lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt;的 &lt;code class=&quot;highlighter-rouge&quot;&gt;member function template&lt;/code&gt;不能是&lt;code class=&quot;highlighter-rouge&quot;&gt;virtual&lt;/code&gt;的 ?&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;一个类的成员函数不能既是 template 又是 virtual 的&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class Animal{
  public:
      template&amp;lt;typename T&amp;gt;
      virtual void make_sound(){
        //...
      }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;因为&lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt;的编译与链接模型是”分离”的 (至少是部分原因吧)。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;从&lt;code class=&quot;highlighter-rouge&quot;&gt;Unix/C&lt;/code&gt;开始，一个&lt;code class=&quot;highlighter-rouge&quot;&gt;C/C++&lt;/code&gt;程序就可以被分开编译，然后用一个&lt;code class=&quot;highlighter-rouge&quot;&gt;linker&lt;/code&gt;链接起来。这种模型有一个问题，就是各个编译单元可能对另一个编译单元一无所知。&lt;/li&gt;
  &lt;li&gt;一个 &lt;code class=&quot;highlighter-rouge&quot;&gt;function template&lt;/code&gt;最后到底会被 &lt;code class=&quot;highlighter-rouge&quot;&gt;instantiate &lt;/code&gt;为多少个函数，要等整个程序(所有的编译单元)全部被编译完成才知道。&lt;/li&gt;
  &lt;li&gt;同时，&lt;code class=&quot;highlighter-rouge&quot;&gt;virtual function&lt;/code&gt;的实现大多利用了一个”虚函数表”的东西，这种实现中，一个类的内存布局(或者说虚函数表的内存布局)需要在这个类编译完成的时候就被完全确定。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;所以，由上面的矛盾可知，&lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt; 的 &lt;code class=&quot;highlighter-rouge&quot;&gt;member function&lt;/code&gt; 不能既是 &lt;code class=&quot;highlighter-rouge&quot;&gt;template&lt;/code&gt; 又是 &lt;code class=&quot;highlighter-rouge&quot;&gt;virtual&lt;/code&gt; 的。&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;reverse-一个字符串&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;reverse&lt;/code&gt; 一个字符串&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;手动循环还是使用系统库函数&lt;br /&gt;
是否返回一个新的字符串，或者只是返回原来的&lt;br /&gt;
是否支持 &lt;code class=&quot;highlighter-rouge&quot;&gt;Unicode&lt;/code&gt; ， &lt;code class=&quot;highlighter-rouge&quot;&gt;UTF-8&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;c-和其他语言有什么不同&quot;&gt;C++ 和其他语言有什么不同&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;主观判断应聘者的答案&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;shared_ptr-内部实现是否是多线程安全的&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;shared_ptr&lt;/code&gt; 内部实现，（是否是多线程安全的）&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;shared_ptr&lt;/code&gt; 本身是线程安全，但指向的对象操作不是线程安全&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;多线程中栈与堆是公有的还是私有的&quot;&gt;多线程中栈与堆是公有的还是私有的&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;栈私有, 堆公有&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;hash-表的原理&quot;&gt;Hash 表的原理&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;处理关键字 &lt;code class=&quot;highlighter-rouge&quot;&gt;key&lt;/code&gt; 冲突的办法 ： 开放定址法， 链地址法&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;什么是拷贝构造函数如何调用&quot;&gt;什么是拷贝构造函数（如何调用）&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;拷贝构造函数是一种特殊的构造函数，它在创建对象时，是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于：&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;通过使用另一个同类型的对象来初始化新创建的对象。&lt;/li&gt;
  &lt;li&gt;复制对象把它作为参数传递给函数。&lt;/li&gt;
  &lt;li&gt;复制对象，并从函数返回这个对象。&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;请问c的类和c里面的struct有什么区别&quot;&gt;请问C++的类和C里面的struct有什么区别？&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;C++&lt;/code&gt;中的类具有成员保护功能，并且具有继承，多态这类特点，而&lt;code class=&quot;highlighter-rouge&quot;&gt; c&lt;/code&gt;里的&lt;code class=&quot;highlighter-rouge&quot;&gt;struct&lt;/code&gt;没有
c里面的&lt;code class=&quot;highlighter-rouge&quot;&gt;struct&lt;/code&gt;没有成员函数,不能继承,派生等等.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;什么是内存泄漏面对内存泄漏和指针越界你有哪些方法你通常采用哪些方法来避免和减少这类错误&quot;&gt;什么是内存泄漏？面对内存泄漏和指针越界，你有哪些方法？你通常采用哪些方法来避免和减少这类错误？&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;用动态存储分配函数动态开辟的空间，在使用完毕后未释放，结果导致一直占据该内存单元即为内存泄露。&lt;/p&gt;

  &lt;p&gt;使用的时候要记得指针的长度。&lt;/p&gt;

  &lt;p&gt;malloc的时候得确定在那里free.&lt;/p&gt;

  &lt;p&gt;对指针赋值的时候应该注意被赋值指针需要不需要释放.&lt;/p&gt;

  &lt;p&gt;动态分配内存的指针最好不要再次赋值.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Sat, 14 Jul 2018 06:59:28 +0000</pubDate>
        <link>https://github.com/tanhuiya/2018/07/C++%E9%9D%A2%E8%AF%95%E9%A2%98/</link>
        <guid isPermaLink="true">https://github.com/tanhuiya/2018/07/C++%E9%9D%A2%E8%AF%95%E9%A2%98/</guid>
        
        
      </item>
    
      <item>
        <title>Nginx 配置反向代理</title>
        <description>&lt;p&gt;最近要搭个&lt;code class=&quot;highlighter-rouge&quot;&gt;EOS&lt;/code&gt;节点，然后在&lt;code class=&quot;highlighter-rouge&quot;&gt;AWS&lt;/code&gt;租用了个 &lt;code class=&quot;highlighter-rouge&quot;&gt;Ubuntu&lt;/code&gt;服务器，运维大哥呢，只帮我开了三个端口 &lt;code class=&quot;highlighter-rouge&quot;&gt;80,22,443&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;当我用启动eos服务节点时，修改了启动的端口为80，如下
&lt;code class=&quot;highlighter-rouge&quot;&gt;http-server-address = 0.0.0.0:80&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;但是启动起来报错，排查也没发现 &lt;code class=&quot;highlighter-rouge&quot;&gt;80&lt;/code&gt; 端口被占用。后来换 &lt;code class=&quot;highlighter-rouge&quot;&gt;443&lt;/code&gt; 也不行。反正默认的 &lt;code class=&quot;highlighter-rouge&quot;&gt;8888&lt;/code&gt; 端口时可以的。&lt;/p&gt;

&lt;p&gt;两个办法：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;让运维给我开放 &lt;code class=&quot;highlighter-rouge&quot;&gt;8888&lt;/code&gt; 端口。&lt;/li&gt;
  &lt;li&gt;利用 &lt;code class=&quot;highlighter-rouge&quot;&gt;nginx&lt;/code&gt; 做反向代理，将&lt;code class=&quot;highlighter-rouge&quot;&gt;80 &lt;/code&gt;端口代理给本地的 8888 端口。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;最终选择 第二个办法，不是因为它方便。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;主要是为了防止全网扫描定位高防后的服务器，修改默认的 &lt;code class=&quot;highlighter-rouge&quot;&gt;8888&lt;/code&gt; 端口 至全网最大存活数量的端口 &lt;code class=&quot;highlighter-rouge&quot;&gt;80&lt;/code&gt; ，这样可以有效抬高攻击者的定位成本。&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;nginx&quot;&gt;Nginx&lt;/h2&gt;

&lt;h3 id=&quot;安装&quot;&gt;安装&lt;/h3&gt;
&lt;p&gt;这里利用最简单的安装方式&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install nginx&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;启动&quot;&gt;启动&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo /etc/init.d/nginx start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;在浏览器输入ip，看是否nginx已成功启动&lt;/p&gt;

&lt;h3 id=&quot;修改配置&quot;&gt;修改配置&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo vi /etc/nginx/sites-available/default&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;替换 &lt;code class=&quot;highlighter-rouge&quot;&gt;localtion / {***}&lt;/code&gt; 中的内容如下&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    location / {
        proxy_pass http://localhost:8888; 
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;测试&quot;&gt;测试&lt;/h3&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果有上述输出则表示&lt;code class=&quot;highlighter-rouge&quot;&gt;OK&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;重启nginx服务&quot;&gt;重启Nginx服务&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo /etc/init.d/nginx start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;这样就不用指定端口，就访问到对应服务器的&lt;code class=&quot;highlighter-rouge&quot;&gt;8888&lt;/code&gt; 了。&lt;/p&gt;
</description>
        <pubDate>Sat, 23 Jun 2018 06:59:28 +0000</pubDate>
        <link>https://github.com/tanhuiya/2018/06/Nginx%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/</link>
        <guid isPermaLink="true">https://github.com/tanhuiya/2018/06/Nginx%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86/</guid>
        
        
      </item>
    
      <item>
        <title>EOS 搭建网络</title>
        <description>&lt;h2 id=&quot;安装本地环境&quot;&gt;安装本地环境&lt;/h2&gt;

&lt;h3 id=&quot;下载代码&quot;&gt;下载代码&lt;/h3&gt;

&lt;p&gt;下载最新代码，&lt;code class=&quot;highlighter-rouge&quot;&gt;master&lt;/code&gt; 分支即可,&lt;code class=&quot;highlighter-rouge&quot;&gt;--recursive&lt;/code&gt; 会把&lt;code class=&quot;highlighter-rouge&quot;&gt;submodule&lt;/code&gt; 也一起下载下来&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;git clone https://github.com/EOSIO/eos --recursive&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;编译安装&quot;&gt;编译安装&lt;/h3&gt;
&lt;p&gt;切换到eos 目录，执行 eosio_build.sh 脚本&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd eos
./eosio_build.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;最后出现 &lt;code class=&quot;highlighter-rouge&quot;&gt;EOSIO&lt;/code&gt; 几个超大的字母就是&lt;code class=&quot;highlighter-rouge&quot;&gt;OK&lt;/code&gt; 了。&lt;/p&gt;

&lt;h3 id=&quot;验证安装是否成功&quot;&gt;验证安装是否成功&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Linux:&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;~/opt/mongodb/bin/mongod -f ~/opt/mongodb/mongod.conf &amp;amp;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;MacOS:&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/local/bin/mongod -f /usr/local/etc/mongod.conf &amp;amp;&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd build
make test
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;这个过程需要等一段时间。&lt;/p&gt;

&lt;h3 id=&quot;安装可执行文件&quot;&gt;安装可执行文件&lt;/h3&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd build
sudo make install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这个会把一些可执行文件比如&lt;code class=&quot;highlighter-rouge&quot;&gt;nodeos&lt;/code&gt;，&lt;code class=&quot;highlighter-rouge&quot;&gt;cleos&lt;/code&gt; 拷贝到 &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/local&lt;/code&gt; 目录下，这个目录在当前的&lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt;中，所以执行命令起来会比较方便。&lt;/p&gt;

&lt;h2 id=&quot;结构&quot;&gt;结构&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nodeos&lt;/code&gt;： 区块链服务器节点生成组建&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cleos&lt;/code&gt;： 和区块链交互的接口命令&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;keosd&lt;/code&gt;： &lt;code class=&quot;highlighter-rouge&quot;&gt;EOS&lt;/code&gt; 钱包&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;nodeos&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nodeos&lt;/code&gt;&lt;/h2&gt;

&lt;h3 id=&quot;启动单个节点&quot;&gt;启动单个节点&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nodeos&lt;/code&gt;&lt;/strong&gt; 是区块链服务器节点生成组建。&lt;/p&gt;

&lt;p&gt;启动单个区块链服务器节点：&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nodeos -e -p eosio --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin &lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-p&lt;/code&gt; 是这个节点的名称&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;--plugin&lt;/code&gt; 是启动节点时，需要一起使用到的插件服务&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;nodeos 成功运行的话，应该有如下log,即已经开始出块了，&lt;code class=&quot;highlighter-rouge&quot;&gt;signed by eosio [trxs: 0, lib: 0, confirmed: 0]&lt;/code&gt; 表示块里还没有交易。&lt;code class=&quot;highlighter-rouge&quot;&gt;Ctrl-C&lt;/code&gt; 可以停止进程。&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;2243857ms thread-0   http_plugin.cpp:342           add_handler          ] add api url: /v1/history/get_transaction
2243857ms thread-0   net_plugin.cpp:2903           plugin_startup       ] starting listener, max clients is 25
2244008ms thread-0   producer_plugin.cpp:942       produce_block        ] Produced block 000000029ff16f71... #2 @ 2018-06-13T08:37:24.000 signed by eosio [trxs: 0, lib: 0, confirmed: 0]
2244506ms thread-0   producer_plugin.cpp:942       produce_block        ] Produced block 00000003c5c6b8f4... #3 @ 2018-06-13T08:37:24.500 signed by eosio [trxs: 0, lib: 2, confirmed: 0]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;高级设置&quot;&gt;高级设置&lt;/h3&gt;

&lt;p&gt;如果你觉得启动 &lt;strong&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nodeos&lt;/code&gt;&lt;/strong&gt; 的时候，参数太多，记不清。可以将参数填到配置文件&lt;code class=&quot;highlighter-rouge&quot;&gt;config.ini&lt;/code&gt;中。&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;config.ini&lt;/code&gt; 文件不是一开始就有的，当第一次启动nodeos 时，如果没有找到 &lt;code class=&quot;highlighter-rouge&quot;&gt;config.ini&lt;/code&gt;，就会为它创建一个默认的，文件位置如下&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Mac OS: ~/Library/Application Support/eosio/nodeos/config/config.ini
Linux: ~/.local/share/eosio/nodeos/config/config.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在 &lt;code class=&quot;highlighter-rouge&quot;&gt;config.ini&lt;/code&gt; 中添加如下配置:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;enable-stale-production = true
# Enable block production with the testnet producers
producer-name = eosio 
# Load the block producer plugin, so you can produce blocks
plugin = eosio::producer_plugin
# Wallet plugin
plugin = eosio::wallet_api_plugin
# As well as API and HTTP plugins
plugin = eosio::chain_api_plugin
plugin = eosio::http_plugin
# This will be used by the validation step below, to view account history
plugin = eosio::history_api_plugin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;注意：注释掉&lt;code class=&quot;highlighter-rouge&quot;&gt;config.ini &lt;/code&gt;内先前的配置&lt;code class=&quot;highlighter-rouge&quot;&gt;enable-stale-production = false&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;再次启动只需输入 &lt;code class=&quot;highlighter-rouge&quot;&gt;nodeos&lt;/code&gt; 就👌了。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;区块链的数据存放路径如下&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Mac OS: ~/Library/Application Support/eosio/nodeos/data
Linux: ~/.local/share/eosio/nodeos/data
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果重启&lt;code class=&quot;highlighter-rouge&quot;&gt;nodeos&lt;/code&gt; 失败，可以删除之前的&lt;code class=&quot;highlighter-rouge&quot;&gt;data&lt;/code&gt;数据.&lt;/p&gt;

&lt;h2 id=&quot;cleosclient-eos&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cleos(client-eos)&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;前面的&lt;code class=&quot;highlighter-rouge&quot;&gt;nodeos&lt;/code&gt;会在&lt;code class=&quot;highlighter-rouge&quot;&gt;8888&lt;/code&gt;端口开启一个&lt;code class=&quot;highlighter-rouge&quot;&gt;http&lt;/code&gt;服务。 &lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;cleos&lt;/code&gt; 是一个客户端命令行工具，内部其实是封装从终端传进去的参数，然后发送请求给 &lt;code class=&quot;highlighter-rouge&quot;&gt;nodeos&lt;/code&gt;,拿到返回值后，经过处理再输出到终端。&lt;/p&gt;

&lt;h3 id=&quot;查看节点的状态&quot;&gt;查看节点的状态&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cleos get info &lt;/code&gt;&lt;br /&gt;
或者&lt;br /&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;cleos -u http://localhost:8888 get info&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;server_version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;07a67985&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;chain_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;706a7ddd808de9fc2b8879904f3b392256c83104c1d544b38302cc07d9fca477&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;head_block_num&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;节点区块数量&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;last_irreversible_block_num&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;last_irreversible_block_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;00000007e45264c9bc7d24d5c655b20336a6ea4d8fa0adfbaf0120a3874a373f&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;head_block_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0000000890033e629074ecc2c492e2ff483adb46ad942cc0e81dacd7901c9593&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;head_block_time&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2018-06-13T08:37:27&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;head_block_producer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;eosio&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;生产者节点名称&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;virtual_block_cpu_limit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;201403&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;virtual_block_net_limit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1055940&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;block_cpu_limit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;199900&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;block_net_limit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1048576&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;创建钱包&quot;&gt;创建钱包&lt;/h3&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;//创建默认钱包
cleos wallet create 
//创建 jack 的钱包
cleos wallet create -n jack 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;要保存一下钱包的密码，如下：&lt;code class=&quot;highlighter-rouge&quot;&gt;PW5JR33BmijnjWC8Ye8qDoJG7zUdrjk6GZMAjsEuVbG78oDQUFyKz&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Creating wallet: jack
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
&quot;PW5JR33BmijnjWC8Ye8qDoJG7zUdrjk6GZMAjsEuVbG78oDQUFyKz&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;创建key&quot;&gt;创建&lt;code class=&quot;highlighter-rouge&quot;&gt;key&lt;/code&gt;&lt;/h3&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;➜  eos git:(master) ✗cleos create key
Private key: 5KiHiPpgUQmb3RdiV8FqV78xyXkZ4A7oKPfG2aJY9DTxHjXrbcV
Public key: EOS6kQMgyLcR1Y326VtiGBEqbnvH5i3B2wAATcoQ6qqsYQ2KGGCh9
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;将密钥导入钱包&quot;&gt;将密钥导入钱包&lt;/h3&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;➜  eos git:(master) ✗ cleos wallet import -n jack 5KiHiPpgUQmb3RdiV8FqV78xyXkZ4A7oKPfG2aJY9DTxHjXrbcV
imported private key for: EOS6kQMgyLcR1Y326VtiGBEqbnvH5i3B2wAATcoQ6qqsYQ2KGGCh9
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;显示所有的密钥&quot;&gt;显示所有的密钥&lt;/h3&gt;
&lt;p&gt;会显示所有&lt;strong&gt;&lt;em&gt;没有被锁上&lt;/em&gt;&lt;/strong&gt;的钱包的密钥&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;➜  eos git:(master) ✗ cleos wallet keys
[[
    &quot;EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV&quot;,
    &quot;5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3&quot;
  ],[
    &quot;EOS6kQMgyLcR1Y326VtiGBEqbnvH5i3B2wAATcoQ6qqsYQ2KGGCh9&quot;,
    &quot;5KiHiPpgUQmb3RdiV8FqV78xyXkZ4A7oKPfG2aJY9DTxHjXrbcV&quot;
  ]
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;查看钱包列表&quot;&gt;查看钱包列表&lt;/h3&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;➜  eos git:(master) ✗ cleos wallet list
Wallets:
[
  &quot;default&quot;,
  &quot;jack *&quot;
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;目前有&lt;code class=&quot;highlighter-rouge&quot;&gt;default&lt;/code&gt;钱包和&lt;code class=&quot;highlighter-rouge&quot;&gt;jack&lt;/code&gt;钱包， &lt;code class=&quot;highlighter-rouge&quot;&gt;jack&lt;/code&gt;后面的&lt;code class=&quot;highlighter-rouge&quot;&gt;*&lt;/code&gt; 代表这个钱包可用（没有被锁）。&lt;/p&gt;

&lt;h3 id=&quot;创建用户&quot;&gt;创建用户&lt;/h3&gt;

&lt;p&gt;创建用户 &lt;code class=&quot;highlighter-rouge&quot;&gt;jack.token&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;➜  eos git:(master) ✗ cleos create account eosio jack.token \
EOS6kQMgyLcR1Y326VtiGBEqbnvH5i3B2wAATcoQ6qqsYQ2KGGCh9 \
EOS6kQMgyLcR1Y326VtiGBEqbnvH5i3B2wAATcoQ6qqsYQ2KGGCh9

executed transaction: 008185163cfa269f55c8f080aa4281b5b2e192ba0569caa8a41a7aca983d0d4a  200 bytes  128584 us
#         eosio &amp;lt;= eosio::newaccount            {&quot;creator&quot;:&quot;eosio&quot;,&quot;name&quot;:&quot;jack.token&quot;,&quot;owner&quot;:{&quot;threshold&quot;:1,&quot;keys&quot;:[{&quot;key&quot;:&quot;EOS6kQMgyLcR1Y326VtiGB...
3564487ms thread-0   main.cpp:381                  print_result  warning: transaction executed locally, but may not be confirmed by the network yet
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;参数说明
&lt;code class=&quot;highlighter-rouge&quot;&gt;cleos create account [creator] [accountname] [OwnerKey] [ActiveKey]&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;加载bios合约&quot;&gt;加载bios合约&lt;/h3&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cleos set contract eosio build/contracts/eosio.bios -p eosio

Reading WAST/WASM from build/contracts/eosio.bios/eosio.bios.wasm...
Using already assembled WASM...
Publishing contract...
executed transaction: 27065fadf93030fd6289da8f6f86824b7188e8f7ca3cb947e48fafa19bcef1fb  3720 bytes  4449 us
#         eosio &amp;lt;= eosio::setcode               {&quot;account&quot;:&quot;eosio&quot;,&quot;vmtype&quot;:0,&quot;vmversion&quot;:0,&quot;code&quot;:&quot;0061736d0100000001621260037f7e7f0060057f7e7e7e7e...
#         eosio &amp;lt;= eosio::setabi                {&quot;account&quot;:&quot;eosio&quot;,&quot;abi&quot;:&quot;0e656f73696f3a3a6162692f312e30050c6163636f756e745f6e616d65046e616d650f7065...
warning: transaction executed locally, but may not be confirmed by the network yet

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;给account设置contract&quot;&gt;给&lt;code class=&quot;highlighter-rouge&quot;&gt;account&lt;/code&gt;设置&lt;code class=&quot;highlighter-rouge&quot;&gt;contract&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;为账户 &lt;code class=&quot;highlighter-rouge&quot;&gt;jack.token&lt;/code&gt; 设置 &lt;code class=&quot;highlighter-rouge&quot;&gt;eosio.token&lt;/code&gt; 合约&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cleos set contract jack.token build/contracts/eosio.token -p jack.token

Reading WAST/WASM from build/contracts/eosio.token/eosio.token.wasm...
Using already assembled WASM...
Publishing contract...
executed transaction: 3ef8e558d936a7828dfa069323ec29c52031da6af46114f53e777435e15aa1b6  8104 bytes  21033 us
#         eosio &amp;lt;= eosio::setcode               {&quot;account&quot;:&quot;jack.token&quot;,&quot;vmtype&quot;:0,&quot;vmversion&quot;:0,&quot;code&quot;:&quot;0061736d01000000017e1560037f7e7f0060057f7e7...
#         eosio &amp;lt;= eosio::setabi                {&quot;account&quot;:&quot;jack.token&quot;,&quot;abi&quot;:&quot;0e656f73696f3a3a6162692f312e30010c6163636f756e745f6e616d65046e616d650...
warning: transaction executed locally, but may not be confirmed by the network yet

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;查看账户的合约&quot;&gt;查看账户的合约&lt;/h3&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cleos get code jack.token

code hash: 641f336aa1d08526201599c3c0ddb7a646e5ac8f9fd2493f56414d0422a0f957
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;只要&lt;code class=&quot;highlighter-rouge&quot;&gt;hash&lt;/code&gt; 值不为 0，就是已经有合约了。&lt;/p&gt;

&lt;h3 id=&quot;创建代币&quot;&gt;创建代币&lt;/h3&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cleos push action jack.token create '[&quot;eosio&quot;,&quot;1000000000.0000 EOS&quot;,0,0,0]' -p jack.token

executed transaction: b29f5769319dc3b854acec8a7617fd87a15e180fdb3193f13ac03cd82a702e8f  120 bytes  1363 us
#    jack.token &amp;lt;= jack.token::create           {&quot;issuer&quot;:&quot;eosio&quot;,&quot;maximum_supply&quot;:&quot;1000000000.0000 EOS&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-p jack&lt;/code&gt; 代表以&lt;code class=&quot;highlighter-rouge&quot;&gt;jack&lt;/code&gt;的身份执行的，因为这个合约的所有者是&lt;code class=&quot;highlighter-rouge&quot;&gt;jack&lt;/code&gt;。&lt;/p&gt;

&lt;h3 id=&quot;给eosio-发币&quot;&gt;给eosio 发币&lt;/h3&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cleos push action jack.token issue '[&quot;eosio&quot;,&quot;1000000000.0000 EOS&quot;,&quot;issue&quot;]' -p eosio
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;给&lt;code class=&quot;highlighter-rouge&quot;&gt;eosio&lt;/code&gt;发了1000000000.0000 个 EOS&lt;/p&gt;

&lt;h3 id=&quot;转账&quot;&gt;转账&lt;/h3&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cleos push action jack.token transfer '[&quot;eosio&quot;, &quot;jack.token&quot;,&quot;50000.0000 EOS&quot;,&quot;trans&quot;]' -p eosio

executed transaction: 5909733736cf6f55990ee59b3187253e55eaa9a9e5d248ffc7e3c206f6a2accc  136 bytes  2650 us
#    jack.token &amp;lt;= jack.token::transfer         {&quot;from&quot;:&quot;eosio&quot;,&quot;to&quot;:&quot;jack.token&quot;,&quot;quantity&quot;:&quot;50000.0000 EOS&quot;,&quot;memo&quot;:&quot;trans&quot;}
#         eosio &amp;lt;= jack.token::transfer         {&quot;from&quot;:&quot;eosio&quot;,&quot;to&quot;:&quot;jack.token&quot;,&quot;quantity&quot;:&quot;50000.0000 EOS&quot;,&quot;memo&quot;:&quot;trans&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;从&lt;code class=&quot;highlighter-rouge&quot;&gt;eosio&lt;/code&gt;转&lt;code class=&quot;highlighter-rouge&quot;&gt;50000&lt;/code&gt;个&lt;code class=&quot;highlighter-rouge&quot;&gt;EOS&lt;/code&gt;给&lt;code class=&quot;highlighter-rouge&quot;&gt;jack.token&lt;/code&gt;帐户&lt;/p&gt;

&lt;h3 id=&quot;查看余额&quot;&gt;查看余额&lt;/h3&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cleos get currency balance jack.token eosio
999950000.0000 EOS

cleos get currency balance jack.token jack.token
50000.0000 EOS
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Thu, 14 Jun 2018 06:59:28 +0000</pubDate>
        <link>https://github.com/tanhuiya/2018/06/EOS%E7%BD%91%E7%BB%9C%E6%90%AD%E5%BB%BA/</link>
        <guid isPermaLink="true">https://github.com/tanhuiya/2018/06/EOS%E7%BD%91%E7%BB%9C%E6%90%AD%E5%BB%BA/</guid>
        
        
      </item>
    
      <item>
        <title>CocoaPods 多语言实现</title>
        <description>&lt;p&gt;最近公司有需求，所有的服务要走上国际化。
之前做的服务（&lt;code class=&quot;highlighter-rouge&quot;&gt;cocoapods&lt;/code&gt; 私有库）都是只用了中文，借此机会记录一下。&lt;/p&gt;

&lt;h3 id=&quot;step-1&quot;&gt;Step 1&lt;/h3&gt;

&lt;p&gt;在&lt;code class=&quot;highlighter-rouge&quot;&gt;Podfile &lt;/code&gt;中使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;use_frameworks!&lt;/code&gt;. 这样每个私有库的内容会被单独打包进一个framework 内部，而不是全部分散的放在&lt;code class=&quot;highlighter-rouge&quot;&gt;main bundle 内部&lt;/code&gt;。&lt;/p&gt;

&lt;h3 id=&quot;step-2&quot;&gt;Step 2&lt;/h3&gt;

&lt;p&gt;私有库配置文件定义.
在podspec 文件中，指定资源打包的方式 &lt;code class=&quot;highlighter-rouge&quot;&gt;resource_bundles&lt;/code&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;Sample&lt;/code&gt; 如下&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  s.resource_bundles = {
    'PictureBook' =&amp;gt; ['SourceCode/Assets/*']
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如上，&lt;code class=&quot;highlighter-rouge&quot;&gt;SourceCode/Assets/*&lt;/code&gt; 目录下的文件都会被打进&lt;code class=&quot;highlighter-rouge&quot;&gt;PictureBook.bundle&lt;/code&gt; 里。&lt;/p&gt;

&lt;h3 id=&quot;step-3&quot;&gt;Step 3&lt;/h3&gt;

&lt;p&gt;在你私有库开发目录的资源文件目录下，新建 &lt;code class=&quot;highlighter-rouge&quot;&gt;Strings File&lt;/code&gt;, 命名为&lt;code class=&quot;highlighter-rouge&quot;&gt;Localizable&lt;/code&gt;, 这个是默认的名字. 
然后选择&lt;code class=&quot;highlighter-rouge&quot;&gt;Pods&lt;/code&gt; 工程文件，切换到&lt;code class=&quot;highlighter-rouge&quot;&gt;Info&lt;/code&gt; tab 栏，添加 简体中文，默认选中刚才创建的 &lt;code class=&quot;highlighter-rouge&quot;&gt;Localizable.strings&lt;/code&gt; 文件。&lt;/p&gt;

&lt;p&gt;再看&lt;code class=&quot;highlighter-rouge&quot;&gt;Localizable.strings&lt;/code&gt; 文件夹可以展开了，在&lt;code class=&quot;highlighter-rouge&quot;&gt;Localizable.strings(English)&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;Localizable.strings(Chinese(xxx))&lt;/code&gt; 中编写对应的&lt;code class=&quot;highlighter-rouge&quot;&gt;key-value&lt;/code&gt; 值。&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Sample&lt;/code&gt;分别如下&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Localizable.strings(English)&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;test&quot;=&quot;this is test&quot;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Localizable.strings(Chinese(xxx))&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;test&quot;=&quot;这是测试&quot;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;注意最后的 &lt;strong&gt;&lt;em&gt;分号&lt;/em&gt;&lt;/strong&gt; ，如果不加分号会加载不到文字哦 ！&lt;/p&gt;

&lt;h3 id=&quot;step-4&quot;&gt;Step 4&lt;/h3&gt;

&lt;p&gt;代码中调用，不能按通常的方式。
一般的调用方式，程序会在&lt;code class=&quot;highlighter-rouge&quot;&gt;main Bundle&lt;/code&gt; 的根目录下查找语言文件。而我们的语言文件被打包到私有库中（&lt;code class=&quot;highlighter-rouge&quot;&gt;xxxx.framewok&lt;/code&gt;）,该&lt;code class=&quot;highlighter-rouge&quot;&gt;framework &lt;/code&gt;中有二进制程序和&lt;code class=&quot;highlighter-rouge&quot;&gt;xxxx.bundle&lt;/code&gt; 文件，所有的资源文件都会被打包到(&lt;code class=&quot;highlighter-rouge&quot;&gt;xxxx.bundle&lt;/code&gt;)中。&lt;/p&gt;

&lt;p&gt;所以我们要加载资源的时候要指定加载的&lt;code class=&quot;highlighter-rouge&quot;&gt;bundle&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;OC 实现:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//  NSString+Localable.h
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#import &amp;lt;Foundation/Foundation.h&amp;gt;
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;@interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Localable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@property&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nonatomic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;readonly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CI_localizable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@end&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 该类用于定位bundle 位置
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;@interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoUse&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NSObject&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@end&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;//  NSString+Localable.m
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#import &quot;NSString+Localable.h&quot;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@implementation&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoUse&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;@implementation&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Localable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CI_localizable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSArray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bundlePaths&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSBundle&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bundleForClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NoUse&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pathsForResourcesOfType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;bundle&quot;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inDirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bundlePaths&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resourcePath&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bundlePaths&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;firstObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSBundle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resourceBundle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSBundle&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bundleWithPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resourcePath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resourceBundle&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;localizedStringForKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;@end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;调用：&lt;/em&gt;&lt;/strong&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;NSString *retStr = @&quot;test&quot;.CI_localizable&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Swift 实现:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import Foundation
extension String{
    class NoUse {}
    var CI_locale: String {
        let bundlePaths = Bundle(for: NoUse.self).paths(forResourcesOfType: &quot;bundle&quot;, inDirectory: nil)
        guard bundlePaths.count &amp;gt; 0 , let resourcePath = bundlePaths.first else {
            return self
        }
        let resourceBundle = Bundle(path: resourcePath)
        let msg = NSLocalizedString(self, tableName: nil, bundle: resourceBundle!, value: &quot;&quot;, comment: &quot;&quot;)
        return msg
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;调用：&lt;/em&gt;&lt;/strong&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;let retStr = &quot;test&quot;.CI_locale &lt;/code&gt;&lt;/p&gt;

&lt;p&gt;这样就基本&lt;code class=&quot;highlighter-rouge&quot;&gt;OK&lt;/code&gt;了。&lt;/p&gt;
</description>
        <pubDate>Thu, 24 May 2018 06:59:28 +0000</pubDate>
        <link>https://github.com/tanhuiya/2018/05/Cocoapods-%E5%9B%BD%E9%99%85%E5%8C%96/</link>
        <guid isPermaLink="true">https://github.com/tanhuiya/2018/05/Cocoapods-%E5%9B%BD%E9%99%85%E5%8C%96/</guid>
        
        
      </item>
    
      <item>
        <title>Ubuntu 运行 Hyperledger Fabric  网络失败 -- 阿里云服务器</title>
        <description>&lt;h3 id=&quot;环境&quot;&gt;&lt;em&gt;环境&lt;/em&gt;:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;System Version: Ubuntu Linux 14.04 / 16.04 LTS&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Hyperledger Composer version: 0.19.1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;步骤&quot;&gt;&lt;em&gt;步骤&lt;/em&gt;:&lt;/h3&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir ~/fabric-dev-servers &amp;amp;&amp;amp; cd ~/fabric-dev-servers

curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/master/packages/fabric-dev-servers/fabric-dev-servers.tar.gz

tar -xvf fabric-dev-servers.tar.gz
	
cd ~/fabric-dev-servers&amp;amp;&amp;amp;./downloadFabric.sh
	
cd ~/fabric-dev-servers &amp;amp;&amp;amp; ./createPeerAdminCard.sh &amp;amp;&amp;amp; ./startFabric.sh
    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;问题&quot;&gt;&lt;em&gt;问题&lt;/em&gt;:&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;查看该容器 &lt;code class=&quot;highlighter-rouge&quot;&gt;log&lt;/code&gt; ，发现有条警告信息：&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;2018-05-06 01:32:11.118 UTC [couchdb] handleRequest -&amp;gt; WARN 016 Retrying couchdb request in 125ms. Attempt:1  Error:Get http://couchdb:5984/: dial tcp 172.18.0.4:5984: getsockopt: connection refused&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;看错误，是&lt;code class=&quot;highlighter-rouge&quot;&gt;peer0&lt;/code&gt;容器没有能连上&lt;code class=&quot;highlighter-rouge&quot;&gt;couchdb&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;经过一番搜寻，&lt;code class=&quot;highlighter-rouge&quot;&gt;stackoverflow&lt;/code&gt; 上有解决方案说 &lt;code class=&quot;highlighter-rouge&quot;&gt;dns&lt;/code&gt; 解析问题，在 &lt;code class=&quot;highlighter-rouge&quot;&gt;peer0.org1.example.com&lt;/code&gt; 中加入&lt;code class=&quot;highlighter-rouge&quot;&gt;dns_search: .&lt;/code&gt;, &lt;strong&gt;&lt;em&gt;But It does not work&lt;/em&gt;&lt;/strong&gt; 😡😡😡&lt;/p&gt;

&lt;p&gt;那好，我尝试不用&lt;code class=&quot;highlighter-rouge&quot;&gt;couchdb&lt;/code&gt;，用他默认的&lt;code class=&quot;highlighter-rouge&quot;&gt;levelDB&lt;/code&gt;。注释掉 &lt;code class=&quot;highlighter-rouge&quot;&gt;docker-composer.yaml&lt;/code&gt; 里 &lt;code class=&quot;highlighter-rouge&quot;&gt;peer0.org1.com&lt;/code&gt; 连接 &lt;code class=&quot;highlighter-rouge&quot;&gt;couchdb&lt;/code&gt; 的一些依赖以及环境变量
重新执行 &lt;code class=&quot;highlighter-rouge&quot;&gt;./startFabric.sh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;这次peer0还是不能正常启动，依旧出现了报错。报错信息如下&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;fatal error: unexpected signal during runtime execution [signal SIGSEGV: segmentation violation code=0x1 addr=0x63 …&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;经过很长时间的查询，发现最新的阿里云服务器中 &lt;code class=&quot;highlighter-rouge&quot;&gt;golang&lt;/code&gt; 使用&lt;code class=&quot;highlighter-rouge&quot;&gt;cgo resolver&lt;/code&gt;解析dns(宿主机ECS的配置文件变了), 过去OK 的版本使用的是 &lt;code class=&quot;highlighter-rouge&quot;&gt;pure go resolver&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;解决&quot;&gt;&lt;em&gt;解决&lt;/em&gt;:&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;解决方法:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;在&lt;code class=&quot;highlighter-rouge&quot;&gt;docker-compose.yaml&lt;/code&gt;里对&lt;strong&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;peer、orderer、ca、couchdb&lt;/code&gt;&lt;/strong&gt;的环境变量加入&lt;strong&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;GODEBUG=netdns=go&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;再次尝试 &lt;code class=&quot;highlighter-rouge&quot;&gt;./startFabric.sh&lt;/code&gt; ,终于  OK ！！！&lt;br /&gt;
✌️✌️✌️&lt;/p&gt;
</description>
        <pubDate>Sun, 18 Mar 2018 06:59:28 +0000</pubDate>
        <link>https://github.com/tanhuiya/2018/03/Ubuntu-Hyperledger-Fabric-Fail/</link>
        <guid isPermaLink="true">https://github.com/tanhuiya/2018/03/Ubuntu-Hyperledger-Fabric-Fail/</guid>
        
        
      </item>
    
      <item>
        <title>Hyperledger Composer 0.18.1 Timeout Error</title>
        <description>&lt;p&gt;从&lt;code class=&quot;highlighter-rouge&quot;&gt;0.16.x&lt;/code&gt; 更新到 &lt;code class=&quot;highlighter-rouge&quot;&gt;0.18.1 &lt;/code&gt;以后&lt;/p&gt;

&lt;h3 id=&quot;问题&quot;&gt;问题&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;composer network start ... &lt;/code&gt;这步就卡住了，改过&lt;code class=&quot;highlighter-rouge&quot;&gt;connection&lt;/code&gt;配置文件，清过缓存，突然成功让人高兴一下，stop 后删除镜像再跑又不行了。 感觉就像摸奖，跑十次可以成功一次😅。由于是&lt;code class=&quot;highlighter-rouge&quot;&gt;next&lt;/code&gt;版本，网上也没有解决方案，只能自己踩坑了。&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;composer network start ... &lt;/code&gt; 命令，会为每个peer启动一个容器。它的镜像是 &lt;code class=&quot;highlighter-rouge&quot;&gt;hyperledger/fabric-ccenv&lt;/code&gt;, tag 是&lt;code class=&quot;highlighter-rouge&quot;&gt;x86_64-1.1.0-rc1&lt;/code&gt;。 container 名称好像是随便去的，这个容器在成功启动 chaincode 容器一段时间后会自己退出。如下,由于有两个peer，这里会启动两个fabric-ccenv 容器，分别是&lt;code class=&quot;highlighter-rouge&quot;&gt;objective_franklin &lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;compassionate_bell &lt;/code&gt;.下面以&lt;code class=&quot;highlighter-rouge&quot;&gt;compassionate_bell &lt;/code&gt;举例。&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ docker ps
CONTAINER ID        IMAGE                                         COMMAND                  CREATED             STATUS              PORTS                                            NAMES
b6f65e8c905a        hyperledger/fabric-ccenv:x86_64-1.1.0-rc1     &quot;/bin/sh -c 'cp -R /…&quot;   10 seconds ago      Up 1 second                                                          objective_franklin
eaffbbb7aef7        hyperledger/fabric-ccenv:x86_64-1.1.0-rc1     &quot;/bin/sh -c 'cp -R /…&quot;   10 seconds ago      Up 1 second                                                          compassionate_bell
38cc14dab6ef        hyperledger/fabric-tools:x86_64-1.1.0-rc1     &quot;/bin/bash -c './scr…&quot;   51 seconds ago      Up 41 seconds                                                        cli
69b30c1cdb02        hyperledger/fabric-ca:x86_64-1.1.0-rc1        &quot;sh -c 'fabric-ca-se…&quot;   53 seconds ago      Up 43 seconds       0.0.0.0:7054-&amp;gt;7054/tcp                           ca_peerOrg1
2f99be174cdc        hyperledger/fabric-peer:x86_64-1.1.0-rc1      &quot;peer node start&quot;        53 seconds ago      Up 42 seconds       0.0.0.0:8051-&amp;gt;7051/tcp, 0.0.0.0:8053-&amp;gt;7053/tcp   peer1.org1.example.com
c3431f79d07c        hyperledger/fabric-orderer:x86_64-1.1.0-rc1   &quot;orderer&quot;                53 seconds ago      Up 42 seconds       0.0.0.0:7050-&amp;gt;7050/tcp                           orderer.example.com
7f7c5a5c1a05        hyperledger/fabric-peer:x86_64-1.1.0-rc1      &quot;peer node start&quot;        53 seconds ago      Up 43 seconds       0.0.0.0:7051-&amp;gt;7051/tcp, 0.0.0.0:7053-&amp;gt;7053/tcp   peer0.org1.example.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在漫长的等待后，得到一个&lt;code class=&quot;highlighter-rouge&quot;&gt;Timeout error&lt;/code&gt; .&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Error: Error trying to instantiate composer runtime. Error: No valid responses from any peers.
Response from attempted peer comms was an error: Error: REQUEST_TIMEOUT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;timeout&lt;/code&gt; 值是你在&lt;code class=&quot;highlighter-rouge&quot;&gt;connection.json&lt;/code&gt; 里设置的， 默认 45s .&lt;/p&gt;

&lt;p&gt;给官方提&lt;code class=&quot;highlighter-rouge&quot;&gt;issue&lt;/code&gt; ， 官方的回复 &lt;code class=&quot;highlighter-rouge&quot;&gt;you can switch to another internet access point. to create the chaincode image, 0.18.1 will pull the npm modules from remote repository. i have succeeded running composer network start &lt;/code&gt;
好吧，换个网，可能是在中国的原因，所以这招对我来说没什么用。
至少知道了可能是什么问题导致的。&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;fabric-ccenv&lt;/code&gt; 构建的容器中，会使用&lt;code class=&quot;highlighter-rouge&quot;&gt;npm&lt;/code&gt;命令拉取远程仓库，可能是这步卡住了，直接导致了&lt;code class=&quot;highlighter-rouge&quot;&gt;timeout&lt;/code&gt;。
执行 &lt;code class=&quot;highlighter-rouge&quot;&gt;docker logs -f compassionate_bell &lt;/code&gt; 可以看到，确实卡在了&lt;code class=&quot;highlighter-rouge&quot;&gt;npm &lt;/code&gt;命令上. 所以就想到了解决办法 – 更换 npm 源, 但是源是在&lt;code class=&quot;highlighter-rouge&quot;&gt;docker&lt;/code&gt;容器中的…&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;hyperledger/fabric-ccenv:x86_64-1.1.0-rc1&lt;/code&gt; 容器的启动是通过&lt;code class=&quot;highlighter-rouge&quot;&gt;composer network start &lt;/code&gt;命令，所以我不能自己搞个镜像例如&lt;code class=&quot;highlighter-rouge&quot;&gt;hyperledger/fabric-ccenv:other&lt;/code&gt;然后让composer启动。 唯一可行的就是修改&lt;code class=&quot;highlighter-rouge&quot;&gt;hyperledger/fabric-ccenv:x86_64-1.1.0-rc1&lt;/code&gt; 镜像，再用同样的名字覆盖它。&lt;/p&gt;

&lt;h3 id=&quot;首先进入容器&quot;&gt;首先进入容器&lt;/h3&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker exec -it compassionate_bell /bin/bash 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;更换npm源&quot;&gt;更换&lt;code class=&quot;highlighter-rouge&quot;&gt;npm&lt;/code&gt;源&lt;/h3&gt;
&lt;p&gt;网上一搜一堆，例如&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;npm config set registry https://registry.npm.taobao.org
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;换好了再&lt;code class=&quot;highlighter-rouge&quot;&gt;npm config list&lt;/code&gt; 看一下&lt;/p&gt;

&lt;p&gt;然后退出容器&lt;code class=&quot;highlighter-rouge&quot;&gt;exit&lt;/code&gt;。&lt;/p&gt;

&lt;h3 id=&quot;重新提交镜像&quot;&gt;重新提交镜像&lt;/h3&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker commit -a &quot;your name&quot; -m &quot;change npm source&quot; compassionate_bell hyperledger/fabric-ccenv:x86_64-1.1.0-rc1 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;注意最后一个参数一定要和你之前的相同，因为composer 只为启动指定image构建的容器。&lt;/p&gt;

&lt;p&gt;然后 &lt;code class=&quot;highlighter-rouge&quot;&gt;docker images&lt;/code&gt; 会发现镜像&lt;code class=&quot;highlighter-rouge&quot;&gt;hyperledger/fabric-ccenv:x86_64-1.1.0-rc1&lt;/code&gt; 的 &lt;code class=&quot;highlighter-rouge&quot;&gt;CREATED&lt;/code&gt; 是几秒之前&lt;/p&gt;

&lt;h3 id=&quot;重新启动&quot;&gt;重新启动&lt;/h3&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker rm -f compassionate_bell（替换成你自己的）
composer network start ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;记得把connection.json 里的 &lt;code class=&quot;highlighter-rouge&quot;&gt;Timeout&lt;/code&gt; 设置长一点，一般 300 + 吧。
OK，大功告成.希望帮助到大家。&lt;/p&gt;

</description>
        <pubDate>Mon, 12 Mar 2018 06:59:28 +0000</pubDate>
        <link>https://github.com/tanhuiya/2018/03/Hyperledger-Composer-0.18+-Timeout-Error/</link>
        <guid isPermaLink="true">https://github.com/tanhuiya/2018/03/Hyperledger-Composer-0.18+-Timeout-Error/</guid>
        
        
      </item>
    
  </channel>
</rss>
