<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Whisperd</title><link>https://kaichaosun.github.io/index.xml</link><description>Recent content on Whisperd</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Tue, 13 Jan 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://kaichaosun.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>Tauri App Signing &amp; Release Guide</title><link>https://kaichaosun.github.io/post/sign-macos-app/</link><pubDate>Tue, 13 Jan 2026 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/sign-macos-app/</guid><description>This guide covers how to sign and release your Kanban app for macOS, Windows, and Linux.
Quick Start Set up signing certificates (see platform-specific sections below) Add secrets to GitHub repository Push a version tag: git tag v1.0.0 &amp;amp;&amp;amp; git push origin v1.0.0 The GitHub Action will build, sign, and create a draft release macOS Code Signing &amp;amp; Notarization Prerequisites Apple Developer Account ($99/year) Mac computer with Xcode installed Step 1: Create a Developer ID Certificate On your Mac, open Keychain Access</description></item><item><title>Setup Multi-User Environment for lbcd</title><link>https://kaichaosun.github.io/post/lbcd_multi_user/</link><pubDate>Thu, 29 Feb 2024 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/lbcd_multi_user/</guid><description>Prerequisites Install Caddy
Install lbcd
Configuration For Caddyfile
rpc.yourdomain.xyz { basicauth * { user1 hashed-password1 user2 hashed-password2 } reverse_proxy :9245 { header_up Authorization &amp;#34;Basic abcdefg&amp;#34; } } Hashed password is generated with
caddy hash-password -p plain-text-password The Authorization header value Basic abcdefc can be extracted using Postman by setting Authorization -&amp;gt; Basic Auth with username and password.
Post to https://rpc.yourdomain.xyz Body:
{ &amp;#34;version&amp;#34;: &amp;#34;2.0&amp;#34;, &amp;#34;id&amp;#34;: 8337029974246184036, &amp;#34;method&amp;#34;: &amp;#34;getblockcount&amp;#34;, &amp;#34;params&amp;#34;: [] } Start caddy start caddy adapt caddy stop ~/go/bin/lbcd --rpcuser=user --rpcpass=password --notls ## shutdown kill -9 lbcd-pid</description></item><item><title>Javacard quick start</title><link>https://kaichaosun.github.io/post/javacard_quick_start/</link><pubDate>Sat, 20 May 2023 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/javacard_quick_start/</guid><description>Prerequisites Install jdk11, jdk-11.0.19_macos-aarch64_bin.dmg, GlobalPlatformPro not work with jdk8
Set JAVA_HOME in ~/.zshrc (choose yours)
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home Compile and install applet Get the souce code of test applet and javacard sdk,
# clone demo applet git@github.com:devrandom/javacard-helloworld.git # clone javacard sdk git@github.com:martinpaljak/oracle_javacard_sdks.git In javacard-helloworld folder, create file gradle.properties, and add its content,
com.fidesmo.gradle.javacard.home=/path/to/oracle_javacard_sdks/jc304_kit/ Build the applet,
./gradlew convertJavacard -i Operations with Card Get the release or compiled version of GlobalPlatformPro,
java -jar gp.</description></item><item><title>关于新冠，我们做错了什么？</title><link>https://kaichaosun.github.io/post/how_did_we_do_wrong/</link><pubDate>Thu, 14 Apr 2022 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/how_did_we_do_wrong/</guid><description>武汉，西安，上海！
2019年12月新冠病毒出现到现在，国内出现封城行为（居家不能外出）的大大小小的城市不下数十个，个人感触比较深的是最早的武汉，亲身经历的西安，和最近的上海封城。
武汉封城76天 西安封城32天（个别小区会多几天） 上海还在继续 这三个城市分别位于中国的中部、西部和东部，不一样的人和地儿，但封城之后出现的社会问题出奇地一致，我就在反思，到底哪里一致，为什么这么高的一致性，这些问题的本质是在哪儿？
吃饭问题 第一个最严重的，吃饭问题，蔬菜、粮食供应不足，有一些家庭出现了吃不上菜、吃不饱饭的问题（具体多少家庭，没有答案，即使有，数据也是假的）。
为什么三个不同地域的城市，都出现了吃饭问题，可以去指责封城导致物流不通畅，菜市场不开放，封城是导致吃饭问题的直接原因，但它不是问题的本质。我看到的本质是，
社会上大多数的人不关心农业、不关心种地，这些人包括制定政策的人，高技术的人，投机房产、金融衍生品的人，还有所有买面买菜的普通人。
20多年过去了，玉米的价格涨幅不足两倍，大概从4毛左右涨到1块左右（数据是我在2021年秋天在别人收玉米的时候打听来的），我们以为能一直这样榨取农业的价值，就像过去的几百年一样，毕竟“中国人只要吃饱饭就不会闹事”。但是封城了，供应出了问题，我们连个备选方案都没有，是可以去指责政府部门（后面会讨论社会治理问题），但是更应该指责的是我们自己，对农业的漠不关心。那我们到底在关心什么？关心怎么挣更多钱，怎么买房子，怎么让孩子考的更好，怎么让自己过得更爽，怎么让投资回报更高&amp;hellip; 反正都跟农业没关系。
关心挣钱、买房子、过得爽，没有错，错在我们大部分人完全忽视了农业。怎么才算不忽视呢？说实话我也不知道，农业需要被关注，需要更多的人去探索，比如，
每个人都应该具备种地的基本技能并使用它 制定更合理的农产品的定价 用技术提高农产品的生产、流通效率，以及多样化（去中心）的应急方案。 这样，当出现封城、甚至天灾这种突发事件时，我们才能更好的应对，减少普通人的损失。你觉得1942（也有同名电影）和“三年自然灾害”离我们很远吗？ 我不觉得。
买药和看病问题 自从新冠流行，普通的感冒药和退烧药在药店已经买不到，我猜想制定这个政策的人是想强制让大家去医院的发热门诊，这样就能尽早地发现新冠患者。看起来这个政策说的通，执行的效果在没有封城的城市效果看着也不错。
但是封城了，大量的医护去接诊新冠患者，有些护士和医生得了新冠或者作为密切接触者不能出诊，医疗资源开始紧张，出现了小病家里没有药，大病进不了医院大门的现象，西安封城的时候有些人因为就医不及时去世（具体多少人，没有数据，更别提可靠的数据）。
我们指责“持有48（24）小时核酸证明才能进医院”、“任何情况（包括就医）都不能出门”的政策，埋怨医疗机构没有担当，但是指责和埋怨完，现在依然买不到常用的药，你需要去医院，让医生给你开普通的感冒药；正在封城的上海，有些大病患者依然没有得到妥善的治疗。
所以出现买药和看病的问题的根源在，我们没有去争取自己被剥夺的买药和就医的权利！ 国外在新冠流行初期，举行了大量的游行示威行动，才保证了一些基本权利如购药就医。但是国内呢，我们享受着专制和高压带来的平静生活、享受着挣钱和资本对自我人性中贪婪的操控，大部分成年人身体没毛病，不关心买药看病难不难，少部分老人小孩和孕妇没有发声的途径和手段。
我慢慢地明白了，权利只能靠斗争去争取，没有人会心甘情愿地给你。废话说了这么多，怎么斗争，游行示威写在法律里，但是在社会潜规则里却被禁止了，我们怎么做？其实很多人一直在努力，比如西安就医需要核酸证明的规定在封城中期被撤销，上海婴幼儿单独隔离改为父母自愿陪同，等等。但是这些斗争措施往往是在出现问题之后的补救，我们需要更早的去斗争，互相协作的去斗争，比如，
利用社交平台同时、对同一事件发声，发声内容一致、简洁。 关心自己和其他人的权利，而不是当别人的权利被侵害之后，麻木和旁观。 可以使用更严厉的方式斗争，比如拒绝工作。 胆小和怯懦藏在每个人的骨子里，但是为了让自己和家人更好的活着，我们必须克服它。
社会治理问题 社会治理的职能主要是政府在负责，目前大部分地区的政府部门治理能力低效，为什么政府部门低效？不是我们今天要讨论的，我也没有勇气去深入地讨论它。但是还有很多其他的手段可以提高社会的治理，首先我们看看社会治理的低效体现在哪里，
法律没有被严格的遵守，比如没有发出具备法律效力的明文就随随便便封普通人的家门，限制人的行动，甚至妨碍就医。法律在没有征询社会主要意见的时候就随意修改。 医疗保障不足、生活物资储备不足的情况下就大范围的封城，恐慌下，进一步造成新冠的流行和物资的不足。 出现问题，拒不承认错误，还一层一层地掩盖错误，比如一码通崩了怪使用的用户太多。 数据造假。新闻造假。肆意删除反映问题的文章和视频。 列这么多最近看到的社会治理的问题，目的不是去责备，只是想明确一点，我们的社会治理有很多问题，我们要赶紧优化甚至解决它，不然又要回到暗无天日的日子。
首先，一些社会治理的职能从政府部门迁移出来，比如
形成以生活圈为主导的互助小组，应对突发状况时的物资不足 用技术保证反映事实的文章、音频、视频不会被删除，以及它们的可达性（即普通用户可以容易的获取） 制定社会公约，只有在社会达到基本共识之后，才能修改公约 &amp;hellip;&amp;hellip; 同时，改变和优化政府部门的工作方式。这个是不是太难了？我也觉得不可能，但是想想，政府部门的工作人员，也是普通人，他们也有家庭，也想为下一代争取好的生活环境，怎么做呢？
谈论政治，讨论社会治理，就像我们讨论投资理财、明星私生活一样。 用自己的能力，为政府部门提供免费或者低价的咨询和帮助 创作 政策评论、关注选举的视频、文章。 取消政府部门事业编制，统一招聘，可离职、调岗。 总结 社会是一艘大船，有时候会倾斜不稳，但是不能翻，一旦翻船，只有能游到大洋彼岸的人才能生还。
我们这里仅仅讨论了 吃饭问题，买药和看病问题，社会治理问题。新冠下的封城，还暴露了很多其他的问题，比如对新冠病毒的了解太少，国际信息封闭等等。
这些问题出现的根源，在于每个人的 麻木、不作为，至于做什么、怎么做，是每个想在这片土地上生活的人要思考的。
全文，不是为了撇清政府、财团和既得利益者的责任。只是想着换个角度思考这些问题，我们也许能够看到希望。只有改变自己、优化自己的行为，进而影响他人，一点点对才能改进我们的社会。
封城，封住了城市，能打开人心吗？</description></item><item><title>如何理解去中心</title><link>https://kaichaosun.github.io/post/understand_decentralization/</link><pubDate>Wed, 23 Feb 2022 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/understand_decentralization/</guid><description>去中心这个词的使用通常出现在这样的场景下，
去中心的网络，去中心的互联网， 去中心的应用，去中心的金融服务 去中心的教育体制，去中心的治理组织， Decentralized Web，Web 3.0等等。 看似复杂的问题，通过结合自身的经历，找到问题的本质，理解起来会变得很简单。我们就尝试以这种方式来理解 去中心。
我是一个典型的80后，还没出生的时候，计划生育委员会的人就开始堵家里的门，我的母亲独自躲在离家十多公里的偏僻地方，没有邻居，只有一个破旧的小屋子，父亲隔段时间会去探望，如果太频繁，可能会被发现甚至举报。
几个月后，我出生了，我很幸运，见到了十月不太冷的太阳，但是有多少小“人”没能发出第一次动听的哭声呢？
生长在农村，上学是亲人口中我唯一的出路，那时候我还小不懂什么是出路，只知道考不好可能会挨骂，成绩好其他小朋友就愿意和我玩儿。上的学越来越多，视力越来越差，幸好高考没能把我淘汰，不然我可能上不了大学，玩不了 DOTA 这个游戏。
工作之后，和计算机打交道的时候多，和人打交道的时候少，幸好在大部分时间里我喜欢我的工作。
你看，我的生活很普通，和我们讨论的去中心有什么关系呢？
看上去普通的人生里，其实是对 去中心这一理念 最典型的实践，
假设我的父母遵守了计生委每个安排，也许就没有今天的我，这里的计划生育政策就是中心化的，去中心是在明白自己真正需求的同时（我的父母需求就是想要孩子），做出决定，与之周旋对抗，付出代价（我的家庭很多年才能拿出来的罚款）。 上学的场景到现在偶尔还会出现在我的噩梦里，比如重新参加考试、从头开始上学（:cry:）。 回到正题，上中学的时候我们有个读小说的小团体，内容很杂，好一点的小说比如红楼梦、西游记，不受待见的小说比如寻秦记、缥缈之旅（我们的需求是读课本之外的书了解世界），老师（中心化的权威）不让看，我们就偷偷看，一页页撕下来夹在课本中间。 大学是不是就很开放呢？现在回头看，我觉得大学课程内容落后，学生的选择权微弱，部分教师的思想封闭、教书育人的责任心缺位（注意，我并不是说读大学完全没用）。有很多的大学生选择了打游戏，去兼职去实习，不同的方式都打开了对世界的新的理解。 现在工作了依然还有很多东西要学，中心化权威的制约还是无处不在，比如很难获得稳定的国际互联网服务，学习资料被恶意审核。国际“互联网”信息服务和英语才是近代300年中国最有效的学习工具，过去没有互联网的时候是靠人出国搬运信息。 说说和工作相关的，我换了三个专业（土木、电子、软件）、不小于六份工作，有的工作是实习，时间几个月，有的工作好几年，公司里总是有各种中心化的权威，比如师傅、项目组长、老板。我的需求很简单，干喜欢的事情、自由的干事情，而不是996的加班给别人刷业绩，被早晚高峰堵在路上。在没有找到热爱之前，我不停的学习国外优质的信息，参加各种技术社区活动，投简历面试，经历不同的产品，总结自己的想法、认知和不足。 这是我在生活中的一些小事，我做这些事情潜意识里想要达到的目的是，理解自己和世界，打破限制，获得知识、能力和自由。请回想一下，**你是不是也在有意无意地做着一些事情，想要达到相似的目的呢？**我暂且把为了达成此目的所做的事情称为去中心的实践。
有的人可能觉得这和 不守规则、叛逆、爱折腾 很相似，这样的表述是客人对主人（客观对主观）的评价，忽视了 去中心实践 的一个根本原则，从自身的立场出发，明白自己真正的需求。这样的去中心实践会不会更加导致利己主义呢？我的理解是，真的有人不利己吗？一个不利己的人，怎么可能会利他？深刻长远的利己主义即是利他。
现在我们就来给出 去中心 的一个定义，一个我的理解，欢迎你结合自己的经历添加自己的理解，并且分享给身边的人。
到底什么是去中心？ 我们这样来定义它，
一个人从自身的角度，打破权威的限制，触及到更广阔的“天地”（即思想自由和行为自由），这里的“一个人”也可以是具有共同愿景的团体。
那既然，我们已经在追求去中心，并为此付出努力，为什么还要把它放在台面上来讨论。原因很简单，权威不希望被去中心，因为去中心之后把他的利益缩减了。每个人在不同的情景下都可能是权威，比如学校的老师，家里的“一家之主”，公司的老板、项目组长，政府的负责人等等，我们就是这些人，我们会在某个时刻披上权威的外衣，对其他人做出限制，出于善意或者恶意。
我们讨论去中心，是要让更多人意识到它，理解它，当遇到权威限制的时候，明白权威限制的目的，以及如何运用自己的技术、知识在需要的时候打破它。想要打破，通常要“强大的力量”，力量在人的手里，也就是联合具有相同诉求、处于相似处境的人。
如果我们还是像过去一样，对于权威，听之任之，或者只做个人或者小范围的反抗，
我们想要获取信息和知识的途径将会变得异常艰难 培养独立思考、发表自己的看法、施加个人的影响力将会不被允许 “人吃人”的社会规则不会有丝毫改变。 我们讨论去中心，是为了揭露社会规则的灰暗地带，给每个人更多的选择，进而改善我们赖以生存的社会规则。
追求去中心、打破权威，首先要明白自己的基本诉求。通过我们对去中心的定义，它有这些关键词 自身、权威限制、广阔天地，我简单概括出了这些基本诉求，
关注自己和内在，而不是被外界、他人的看法所支配 规则和限制无处不在，这些规则应该对所有人可见，对所有人透明公开；而不是一部分人利用信息的不对称，获取灰色的个人利益，比如 项目招标的规则不透明，被人暗箱操作 政府的权力部门利用不透明的规则，为自己谋私利、行方便 科研、教学的评价规则不透明，导致人浮于事、滥竽充数等等 打破限制，并不是鼓励过激、违法的行为，而是需要在具备法理性的前提下进行，要注意的是法律本身也可能被滥用。 我们所追求的自由和广阔天地，往往是由很多人经过不懈努力所创造的，我们应该对创新包容，参与其中。 任何东西都在变化，当某个东西不再适合某些人，应该允许他们复制这个“东西”，在它的基础上构建新的内容和规则。 实现以上的诉求，靠跟人磨嘴皮子，大概率是没人听的，靠跟人“打架”，大概率会被权威按在地上摩擦。
在这里我想分享一个，以我个人的经历看，大体可行的一种方式来构建一个去中心的世界。</description></item><item><title>Build in Public：创业团队的重要性</title><link>https://kaichaosun.github.io/post/build_team/</link><pubDate>Fri, 11 Feb 2022 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/build_team/</guid><description>Build in Public 中文意思是 将构建产品的过程公开。
公开构建产品的好处是，
从一开始就获取社区的关注，并且逐步积累关注 社区成员更早的提供反馈、需求 帮助招募志同道合的小伙伴 我打算实践这种工作方式。
今天的主题是我所观察到的 创业过程中，团队的重要性以及可能遇到的问题。
你可能经常听到创业这个词，但是不清楚它具体代表了哪些事情，我认为它也是一个“哈姆雷特”，不同的人有不同的解读。
我认为的创业团队可以包括以下这些形式，
独立的开发者、小店经营者 夫妻搭档、几个人的小团队、小生意 几十个人，甚至上百人的“大团队” 如果团队人数更多，划分为小团队、增加团队交互的效率就更加关键，以构建产品的思维来服务其它团队。 创业过程中，团队为什么重要？ 一个成功的能够服务用户的产品，从想法到落地会遇到各种挑战，比如，
当前或者未来预期的某个时间点，判断这一产品是否具有市场 产品的设计是不是符合用户的使用习惯 能否在预期的时间内交付产品 资金是不是足够支撑产品的交付 应对未知的政策、市场等可能存在的风险 更多的挑战和未知会一点点地蹦跶出来，处理这些只能依靠团队成员的智慧和力量。
创始人的能力和责任感是首要的，他们是团队的“发动机”，责任包括
描绘团队的愿景 产品的初始市场判断 重要的产品和技术决策 招募优秀合适的成员和合作伙伴 引入合适、充分的外部资金支持产品研发 团队内外充分的沟通交流 克服困难的性格等等。 创始人如果不能很好的尽到自己的责任，可能出现这些问题，
资金不足，导致产品“流产”或者核心成员流失 联合创始人、核心成员愿景不一致，将产品的内在更改，脱离了市场的需求 团队内沟通不顺畅，执行效率低下，导致产品的交付、可用性、稳定性大打折扣 在早期过多的规划产品的功能，市场判断不合理，导致产品的交付和市场反馈不及时等等 联合创始人、核心成员弥补了团队内的不足，修复“木桶的短板”，他们的责任包括，
对创始人的不作为进行监督，并提供及时的反馈 发挥自身长处，弥补创始人在团队内外的不足 负责产品的主要功能和核心技术，在预期内交付关键组件的责任感 团队文化、架构、成长性的设计者和执行者等等 核心成员的能力缺失，可能会出现的问题有，
产品关键功能无法交付，无法兑现对市场的承诺 创始人能力缺失时，团队陷入危机，导致产品“流产” 团队结构不稳定，成员流失严重 其他非核心成员给团队带来新的血液和基因，带来未来的可能性，他们的责任包括，
提供团队基因外的一些想法，与团队碰撞之后形成新的随机性机会 通过学习和锻炼具备成为核心成员的能力 关注产品和团队的细节，融合不足等等 非核心成员地缺失，可能会出现的问题有，
无法捕捉未来的机会 满足不了团队的更新迭代 产品的用户体验不到位，团队不和谐。 总结，构建产品和团队的过程，具有数不清的挑战，兴奋地探索未知的同时，也要时刻的关注他人。</description></item><item><title>元宇宙会不会把我们从一条人变成一条狗？</title><link>https://kaichaosun.github.io/post/metaverse/</link><pubDate>Fri, 21 Jan 2022 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/metaverse/</guid><description>我们先不说元宇宙，因为太简单，几句话就可以讲清楚。
但是要理解背后的推力，我们就得先聊一聊 人和狗 是不是自由这件事。
我喜欢狗，虽然小时候 在夏天 吃西瓜的时候被咬过几次。
在这里，我们关心的是人和狗是不是各自拥有 行为自由 和 思想自由。
什么是 行为自由？ 人能走路（狗跑的也挺快），走的再远也有尽头。随着交通工具进步，地域隔阂减弱，去哪里、走多远，由每个人按照一定的规则，自己说了算。
在走路的时候中，人还会边听、边看，对感兴趣的内容可以说出自己的看法，甚至发布到可触及的人际网络中获得响应，在响应的作用下，调整自己的行为方式。
比如小时候从村子坐车赶个集市，长大点去城里或者到外地读个书，这些都是在拓展自身的行动范围。那是不是就可以认为这个人拥有了行动（注意不是行为）自由？如果这个人还可以表达自己的看法、接收其他人的反馈，是不是拥有了 行为自由？
我的答案是 不一定，你的呢？
我脑子里 行为自由 的定义是，如果一个人的行为 在对他人不造成伤害的情况下，不应该被 人为地 限制。通过努力可以挣脱规则，但是人为地限制没办法使用固定的方式来挣脱。
现在看看我们身边可爱的狗，
他没有行为自由，因为有根绳子挂在脖子上，在挣脱绳子之前，他被人为地限制，也就没有我们这里所说的 行为自由。（这个绳子不是可以挣脱吗，绳子应该算是规则吧？它不是狗的规则、而是人给狗加的限制，因为挣脱的可能性极低，挣脱的方法是随机的，把脖子勒断你也挣不开铁链子。）
再来看看人，
对于触犯法律的人，没有行为自由。当然，也不是 所有没有触犯法律的人 都有行为自由，尽管在他们身上看不到任何物理的绳子或者监狱。但是，还有一根道德的绳子和一根权力的绳子。
道德的绳子反映了社会里 多数人 对 某种行为 的接受程度。
权力的绳子反映了社会里 少数人 对 某种行为 的接受程度。
比如你喜欢打游戏，想把打游戏变成自己的职业，但是身边的多数人都不接受，他们会劝你好好学习书本知识，找个稳定的工作。这就是道德的绳子，善于进行道德绑架的人，想牢牢的抓住这根绳子，“驯化”其他人。
再比如你想使用优质的国际互联网服务和应用，但是少数拥有权力的人，会封锁你的网络，让你很难去访问这些服务，甚至会颁布法律来阻止。权力的绳子被野心家玩弄，仿佛这根细细的绳子真的能够盖住整个世界。
道德和权力的绳子，反映了社会上每个人的 思想自由 程度。
什么是 思想自由？ 人能思考（狗应该也可以），思考的时候会有边界，也就是所谓的“看不懂”，当你的行为阅历增多、知识体系和深度变广的时候，思考的边界会向外拓展，此时又会出现新的边界，拓展的过程甚至可以叫做思维跃升，直白点说就是，“看看，那是过去的我，像不像个傻子”。有哪些思维跃升的例子呢？
比如地球不是宇宙的中心，现在三岁小孩都能在书上看到地球是围绕太阳在转。可在过去，老祖宗们几千年里都觉得地球才是中心。
并不是所有的思维跃升都能达到推翻“地心说”的地步，比如对 是不是要买学区房 这件事的不同认识就有很多，
第一种认识，为什么要买学区房？孩子上完学找个活儿能养活自己就行。 第二种认识，要买 教学质量好的学区房，这样孩子上学就省心多了，将来可以上个好高中、考上大学，找个工资高又不累的工作。 第三种认识，不管什么学校，先去看看，采光好不好，生源怎么样，交通差不差，没问题就上，不行就想其他办法。 第四种认识，房子的直接价值是 日常居住，为什么承载了其他勾连的用途？ 比如土地财政，优质教育资源。社会上很多问题比如 996加班、创新乏力 等等的直接原因就是房价过高。解决房子问题的关键在于，鼓励社会面的线上教育创新，开放高质量的数字教育资源，上网课这种形式目前看太单一。另外一个是以政府卖地为主的土地财政，如果不卖地，那卖什么，为啥一定要卖，为啥你有权力卖？大家可以想想。 第五六七八种 &amp;hellip; 对于学区房或者其他细小事物认知的拓展，我认为也是思维跃升，并且可能会更重要，因为这些认知不是大众公认的，需要不断的体验、积累知识、反复测试和验证，修改自己的认知。
现在给出我所理解的 思想自由，</description></item><item><title>如何使用 libp2p 进行点对点通信</title><link>https://kaichaosun.github.io/post/substrate_network_libp2p/</link><pubDate>Mon, 08 Feb 2021 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/substrate_network_libp2p/</guid><description>通过本文，你将了解到，
点对点通信的特点； libp2p的基本介绍； 以及Substrate如何使用libp2p实现点对点的通信。 点对点通信 在Web2.0时代，绝大多数互联网应用采用了基于TCP/IP的“客户端-服务器”通信架构，在客户端采集数据并发送给服务器，服务器存储和处理数据，客户端进而获取并使用这些处理后的数据。这种模式支撑了互联网近三十年的蓬勃发展，在给普通用户提供便利的同时，也出现了各种各样的问题，比如：
泄露用户隐私； 贩卖用户数据； 服务商发布没有底线的广告给不明真相的用户造成不可挽回的损失； 不经协商，随意删除用户发布的内容； 垄断市场和定价； 过度利用用户心理，无节制地占据用户的时间； &amp;hellip;&amp;hellip; 客户端-服务器通信模型如下图：
在为以上问题寻找解决方案时，点对点（即peer to peer）的通信机制逐渐走进了技术先驱们的视野。在互联网早期的时候，点对点通信主要用于文件共享，如音乐共享服务Napster和流媒体下载服务BitTorrent。点对点服务更加广泛的应用，还需要一定的治理机制，来处理资源的版权问题和现实世界的监管，这些不是本文的重点，不做过多地介绍。
点对点通信模型如下图：
在点对点的网络里，所有的节点都是对等的，即任何节点都可以存储和处理数据（作为服务端）；也可以发送待处理的数据给网络中的其它节点，获取经过网络处理后的数据（作为客户端）。通过这样的通信机制，可以保证，
网络具备开放性，节点可以自由加入和退出； 不依赖单一服务节点，网络的服务更加可靠、高效； 节点运行的程序代码公开可见，规则更加透明。 根据网络中传输的数据和提供服务的不同，点对点应用出现了不同的应用场景，包括文件存储和读取、数据计算、内容共享、数据交易等服务。在开发这些应用的过程中，可能涉及到的技术要点有：
节点身份，唯一地标识网络中的节点及地址格式；
发现机制，在没有中心化的协调服务存在的情况下，如何发现新的节点；
路由，本地节点无法存储网络中所有节点的信息，通过路由算法查找需要的节点；
多种通信协议比如TCP、UDP、WebSocket、QUIC等等；
加密和认证，保证消息的可靠和安全；
NAT穿透，解决NAT后面的内部IP无法访问的难题；
多路复用以节省资源；
消息订阅，高效的获取更新而不会给网络造成负担；
中继，当需要建立通信的两个节点都无法直接被访问，比如都在NAT网络中，需要通过中继节点传递信息；
&amp;hellip;&amp;hellip;
以上列出的这些技术要点/需求并不会出现在每个点对点应用里，大多数只会使用其中的一部分功能，尽管如此，还是存在严重地重复造轮子的现象。也有一些应用为了避免重复开发，选择了fork已有开源应用的功能代码，这种方式引入了原有应用的技术债，难于定制和扩展。
复杂多变的网络拓扑和膨胀的应用状态导致了点对点应用的开发、推广和普及都极为困难，出现一个高度模块化的点对点通信开发框架也就不足为奇，也就是接下来我们要介绍的libp2p。
Libp2p 介绍 Libp2p是一个开发点对点应用的框架，它最早源于去中心的文件共享服务IPFS，把网络通信相关的内容抽离并重新设计，形成了现在的libp2p，目前比较成熟的几个语言版本包括js-libp2p、go-libp2p、rust-libp2p，并且定义了一套参考规范，不同语言的实现版本只要符合这一规范，就可以实现互通信。
Libp2p提供的核心功能包括，
在节点之间建立安全可复用的网络连接； 可验证的节点身份和可连接的地址。 安全可复用的连接 Libp2p支持的底层（传输层）协议包括TCP/IP、UDP、WebSocket、QUIC等，不同语言版本的实现完成度不尽相同。连接的安全性是通过对传输内容进行加密来保证的，节点的身份也会进行相应的验证。</description></item><item><title>使用 Substrate 部署公开测试网络</title><link>https://kaichaosun.github.io/post/substrate_launch_public_testnet/</link><pubDate>Fri, 17 Jul 2020 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/substrate_launch_public_testnet/</guid><description>通过本文，你会了解到：
如何修改node template，使它能够提供完整的权益证明（Proof of Stake, PoS）功能； Chain Specification的内容，以及如何生成它； 配置和启动公开测试网络等。 添加 PoS 功能 Substrate node template 是一个快速开发Substrate应用链的节点程序，它内置的是权威证明（Proof of Authority, PoA）共识算法，出块算法是 Aura，也就是出块的节点和顺序是固定不变的。一个线上的公开区块链应用，需要实现一定程度的去中心化，并且通过随机出块来保证安全性，Substrate内置的权益证明（PoS）共识算法就是为了满足此类的需求。
使用 Substrate 添加 PoS 共识算法，通常有两种方法，
使用 Substrate node 节点程序，它内置了几乎所有 Substrate 的功能模块，包括由 Babe 和 GRANDPA 组成的 PoS 共识算法； 在 node template 节点程序的基础上，修改或添加所需的功能模块，包括修改出块算法为 BABE，添加用户权益质押（staking）的功能，及治理（governance）相关功能（非必须）等。 也可以使用 substrate-stencil，具体方法参考readme文档。 这里我们以第二种即修改 node template 为例，介绍一下具体的流程，这么做的好处是，通过一步步添加新的功能，熟悉各个模块的作用以及它们之间的关系。
切换 Babe Babe 是Substrate内置的默认出块算法，它的特点是：
出块节点由当前的验证人集合随机产生； 同时存在次级出块节点，如果当前槽（Slot）没有满足要求的随机区块产生，由次级出块节点生产一个区块； 如果长时间不出块比如所有的验证人离线，会导致网络瘫痪，不可恢复。 更多关于Substrate的共识算法，参考官方文档 Advanced - Consensus。
相应的将 Aura 切换为 Babe 的代码修改如下：</description></item><item><title>如何学习区块链技术</title><link>https://kaichaosun.github.io/post/how_to_blockchain/</link><pubDate>Thu, 30 Apr 2020 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/how_to_blockchain/</guid><description>学习区块链技术和任何其它任何技术一样，没有捷径。
我会从两个角度来阐述，
一个是从我个人的经历出发，让大家了解一个普通的开发者怎么融入到区块链的技术领域中；
另一个是我自己的学习方法分享。
角度一：经历 首先要意识到，在学习过程中，你会产生无数次想否定区块链的想法，这很正常，先把学习这个技术的想法放下，做一些你觉得更有意义的工作，在日常工作中再不断来感受区块链的意义。
我个人12年通过Hacker News第一次听到了比特币的名字，由于网络原因，只是下载了客户端软件，无法同步网络，这是我第一次放下。
16年被朋友说服去研究以太坊，我下载了Mist 客户端（它是以太坊智能合约的开发环境和工具），我根据官网的教程写了一些代码，说实话体验非常差，要知道那时候我正在使用Rails这样优秀的开发框架。这是我第二次放下。
然而我却发现了去中心技术这样一个新大陆，没有区块链，没有币，只有“干净”的技术，这些技术包括但不局限于存储相关的IPFS、DAT，社交领域的ScuttleButt、Solid。说实话，这是我第一次感觉到技术的魅力，我几乎每晚都保持着高压的学习，因为白天有日常的工作，只能靠晚上挤出来时间，熬了数不清的夜，辗转反侧，来思考某个技术的特点和意义。
17年底老婆怀孕了，我很开心，但是由于孕吐比较严重，我只能肩负起做饭的重任（做的不好吃，到后面只能买孕妇餐）。我晚上的时间也没有了。这是第三次放下，前面说的各种去中心技术也都放下了。但是我不后悔，因为第二年我有了可爱的孩子。
说了这么多放下，**但是我真的能放下吗？**你一旦了解了去中心的技术，就很难完全的放下，它会充斥在你生活和工作的方面，每一天都在感受它。
19年，宝宝一岁了，我决定做出改变，去追求我认为当前最有意义的事情，毫无疑问就是我们说的以区块链为代表去中心技术。机缘巧合，了解到了Parity 这个区块链领域的技术先行者，获取了一个兼职的机会，到20年又变为全职，这中间遇到很多挑战，这里不再啰嗦。
你可以看到，对于热爱某项技术的人，放弃它其实是非常难的，区块链也是一样。可能有的人会好奇，为什么有那么多人热爱它？我无法完全地了解别人的想法，但从我的经历来看，区块链带给我的不只是技术边界的拓展，更多的是一种或者多种不同的思维方式，让我接触到不同的人，了解了不同地区的文化，更清楚的知道了自己的方向和责任。就和看同一本书，每个人都有自己的体会，我建议大家开始去读，去看别人的体会，自己也多总结。
角度二：方法 每个人的学习方法不同，这里分享我对区块链技术的学习方法，希望能给大家带来帮助。对我个人比较有效的学习方法，是由应用层到底层。我不会一开始就去读比特币或者以太坊的白皮书，或者《Master Bitcoin》这类的书。其实我在学习过程中都有下载，但真的读进去、看明白也是最近一两年才发生的。那对于技术人员或者有一定学习能力的非技术人员，我建议的学习路径是：
浏览不同的区块链项目的网站，产生一个基本的认识。 这么多不同的项目我应该浏览哪一个呢？从比特币、以太坊开始，然后发现不同的其它项目，和相关的查找方法，由于区块链领域良莠不齐，这里不再放过多的细节。个人建议你应该最少看10个不同的国外顶尖项目。如果还需要讨论更细节的内容，可以去添加我的公众号。
对不同的项目有了初步的认识之后，有些爱动手的人应该就要开始折腾了。折腾什么东西呢？ 搭建区块链应用的节点，它会让你对去中心的网络有更深入的了解，也会让你对项目背后的代码产生最基本的认识。
使用钱包工具，它可以让你对去中心的身份系统、密码学产生基本的了解。
使用区块浏览应用，通过它你可以查询账户或者交易的状态。
折腾了上面这些工具之后，我相信你已经了解了某个项目最基本的运行环境和相关的生态，这个时候我相信你已经加入了对应的开发者社区，他们通常活跃在各个聊天工具和论坛上。你会开始和不同的人聊天，聊各自对技术的理解，有哪些还可以完善的地方，你可以提供哪方面的技术，比如UI，前端，服务器端等等。接着，你就可以进行一些比较深入的开发，比如： 学习项目提供的API文档，和区块链节点进行交互，比如创建账户、发送交易等等。
编写自定义的应用，比如钱包、区块浏览应用。可能不存在这样一个需求，即写一个完善的与区块链交互的应用，但最好还是能通过动手，进而对这些工具的代码有大致的理解。
如果仅仅是钱包和区块浏览这样简单的去中心应用，其实给人们带来不了多少改变。将现实生活的问题深入理解，并转化成技术解决方案，需要非常多的领域知识，也只有这样的人才能将区块链技术带入寻常百姓家。已经有很多的区块链应用通过引入智能合约和应用链开发框架，来帮助开发者实现更加复杂的应用场景，满足各种灵活的需求。我建议的两个值得学习的相关技术为，
以太坊Solidity智能合约编程
Substrate区块链开发框架
这里我们不去过多地介绍两者的区别，如果感兴趣，可以订阅下面的知乎专栏了解更多的技术内容。
Substrate区块链开发
如果你不满足于解决生活中的问题，还想要探索代码背后的奥秘，我想你已经迫不及待地想了解这个区块链应用的底层协议和实现。下载源代码，打开项目的白皮书，比特币白皮书（迄今为止应该是最精简的区块链技术教程），然后就开始和代码硬钢吧。这个时候组成一个兴趣小队，互相交流分享，会事半功倍。别忘了你还可以向官方的技术大牛请教，这些人通常都很乐于讨论技术问题。这个过程可能会花费比较多的时间，如果想深入底层技术，这个过程是跳不过去的。同时还要积极地去找bug、提issue、提PR，将学习结果进一步的展现出来。当你对协议和代码有了一定的理解后，你通常会想做这么几件事：
用自己最擅长的语言重写这个区块链应用的协议。</description></item><item><title>理解 Merkle Patricia Trie</title><link>https://kaichaosun.github.io/post/trie/</link><pubDate>Tue, 17 Mar 2020 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/trie/</guid><description>[TOC]
通过本文，你会了解到：
区块链应用为什么使用Merkle Tree的数据结构； Substrate采用的Patricia Merkle Trie的特点和应用。 Merkle Tree介绍 Merkle Tree是一种数据结构，用来验证计算机之间存储和传输数据的一致性，如果不使用这一数据结构，一致性的验证需要消耗大量的存储和网络资源，如比对计算机之间的所有数据；使用Merkle Tree，只需要比对merkle root（根节点）就可以达到相同的效果。整个过程，简单的描述如下：
将数据通过哈希之后放置在叶子节点之中； 将相邻两个数据的哈希值组合在一起，得出一个新的哈希值； 依次类推，直到只有一个节点也就是根节点； 在验证另外的计算机拥有和本机相同的数据时，只需验证其提供的根节点和自己的根节点一致即可。 Merke Tree使用了加密哈希算法来快速验证数据一致性，常用的加密哈希算法有SHA-256，SHA-3，Blake2等，它们可以做到，
相同的输入有相同的输出； 对任意数据可以实现快速计算； 从哈希值无法推断出原信息； 不会碰撞（即不同输入对应相同输出）； 输入即使只有很小的改变，输出也会有极大不同。 在区块链应用Bitcoin网络中，存储的数据为转移Bitcoin的交易，如“Alice发送给Bob 5个比特币”，通过使用Merkle Tree，除了上面提到的验证各个节点之间的数据一致性，还可以用来快速验证一个交易是否属于某个区块。轻节点只需要下载很少的数据就可以验证交易的有效性，例如下图所示，用户要验证交易T(D)在某个区块之中，需要依赖的数据仅仅是HC, HAB, HEFGH, 和 merkle root即HABCDEFGH。
Merkle Patricia Trie原理 Trie Patria Trie也是一种树形的数据结构，也称为Prefix Tree，Radix Tree，或者简称为Trie，最早来源于英文单词 retrieve，可以发音为try，常用的使用场景包括：
搜索引擎的自动补全功能； IP路由等。 Trie的特点是，某节点的key是从根节点到该节点的路径，即不同的key有相同前缀时，它们共享前缀所对应的路径。这种数据结构，可用于快速查找前缀相同的数据，内存开销较少。如以下数据及对应的trie表示为：
key value to 7 tea 3 ted 4 ten 12 A 15 i 11 in 5 inn 9 Substrate使用base-16，即每个节点最多有16个子节点：</description></item><item><title>区块链应用的交易费用设计</title><link>https://kaichaosun.github.io/post/substrate_transaction_weight_and_fees/</link><pubDate>Fri, 21 Feb 2020 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/substrate_transaction_weight_and_fees/</guid><description>[TOC]
通过本文，你将学到：
区块链应用为什么存在交易费用 Substrate 交易费用的组成 如何设计更合理的交易费用 为什么存在交易费用 在传统物联网（web 2.0）时代，使用微信、微博、淘宝等互联网应用时，终端用户不需要直接费用，而是由服务提供方利用用户的个人信息、产生的数据、注意力等来变现，典型的方式有
广告推送； 通过用户数据分析指导商家决策； 甚至直接共享、贩卖用户隐私等。 在使用以上所说的web 2.0服务时，用户数据的所有者是服务提供方。在过去的20年里，虽然我们享受了互联网应用带来的好处，但也时刻“品尝”着隐私泄露、数据主权丢失带来的恶果。
区块链应用将服务的各个组件完全透明化，用户数据的所有权归属于个人，而不是应用的开发者或者任何其他的第三方。用户通过持有私钥掌握着数据，只有持有私钥的人才可以解锁和转移数据，敏感数据往往可以通过加密防止被窃取。
任何区块链应用的出现和流行都离不开这些利益相关方：
开发和运营团队 维护网络正常运行的节点 终端用户 “天下没有免费的晚餐”，终端用户在享受自由的应用服务同时，需要支付相应的服务费用，也就是交易费用，因为服务是由交易触发的。这些费用可以用来激励相关方更加有效的协作，从而提供更优质的服务。
交易费用的另一个目的是在网络和计算资源有限的条件下，高效地调节这些资源的利用率，而不至于被网络中的垃圾交易所浪费。
在不同的应用场景中，对资源消耗的成本估算不尽相同，合理地设计交易费用可以实现参与方的共赢，推动应用的普及。
合理设计交易费用 如前文所述，交易费用的目的主要是：
激励服务提供方即开发团队和节点 调节资源利用率 注：本文不考虑通证的通胀和其它的激励措施。
节点和开发团队对交易费用分成，具体的比例由各方根据实际情况协调，并通过链上治理的方式进行动态的调整。
在区块链网络中，典型的资源和相应的费用设计方式如下：
有限的区块大小，通过计算每笔交易占用的字节数来收取交易费； 有限的区块生成时间，通过计算或者性能测试得出不同交易所消耗的时间； 链上状态的存储资源，通常方式有一次性付费和租赁两种模式。一次性付费发生在交易处理过程中，在开发时对此费用评估。租赁模式还会考虑某个交易占据链上状态的时长，超时之后对相应状态进行清除。 Substrate 交易费用组成 Substrate作为一个通用的区块链应用开发框架，充分考虑了上面提到的各种因素。Substrate设计的交易费用由以下几部分组成：
总费用 = 基本费用 +（字节费用 + 权重费用）*（1 + 动态调节费率）+ 小费 用于支付的货币由transaction-payment模块的Currency类型指定，通常由Balances模块给出。
基本费用 即TransactionBaseFee，是每笔交易（特例请参考下面，通过pays_fee设置无付费的交易）都需支付的费用，定义在transaction-payment模块中，在runtime初始化时进行配置，并可以随着runtime的升级进行更新。基本费用的合理设置，可以有效的减少垃圾交易。
字节费用 在处理区块大小的限制时，Substrate引入了最大区块长度和字节费用，system模块定义了最大区块长度（MaximumBlockLength），transaction-payment模块定义了每字节的费用（TransactionByteFee），总的字节费用为：
字节费用 = 每字节费用 * 字节数 和基本费用相同的是，每字节费用也是配置在可升级的runtime代码中。字节数的计算是按照交易的结构体通过SCALE编码之后的长度，应用开发者无需过多的关注。
最大区块长度：5MB 每字节费用：0.0001 ksm 权重费用 在有限的区块生成时间和链上状态的限制下，权重被用来定义交易产生的计算复杂度即所消耗的计算资源，以及占据的链上状态。system模块定义了区块的总权重（MaximumBlockWeight）。为了保证在网络繁忙的情况下，依然能够实现对区块链应用有效合理的管理，Substrate引入了两种不同级别的交易类型，既 Normal 和 Operational。Normal类型的交易是由网络中的普通用户提交，Operational类型的交易是由网络中的管理员或者管理委员会共同触发。区块资源如长度和总权重按照一定比例在这两种类型的交易中进行分配，这一比例称为可用区块比（AvailableBlockRatio）。</description></item><item><title>Why OO Sucks</title><link>https://kaichaosun.github.io/post/why_oo_sucks/</link><pubDate>Thu, 25 Apr 2019 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/why_oo_sucks/</guid><description>原文为英文，由 Joe Armstrong 撰写。我的翻译如下。
当我第一次接触OOP(Object Oriented Programming, 面向对象编程)概念的时候，就感到十分怀疑，但是又不知道为什么，就是感觉&amp;quot;不对&amp;rdquo;。当OOP变得非常流行(下面会解释原因)，批判OOP就像&amp;rdquo;在教堂诅咒&amp;ldquo;一样会被排斥。OO逐渐成为了主流编程语言必须要有的特性。
随着Erlang变得流行，我们经常被问到&amp;quot;Erlang是面向对象的吗？&amp;quot;。真正的答案当然是&amp;quot;不支持&amp;rdquo;，但是我们并不敢对外这么说，为此我们发明了一系列巧妙的方式来回答这个问题，给大家营造一种Erlang在某种程度上是OO，但又不真的是OO(如果仔细听我们说的，看小字印刷的内容就知道了)。
这个时候，我想到了 IBM 那时的老板在巴黎第七届IEEE Logic 编程会议时, 被问及IBM Prolog为什么添加了一系列面向对象的扩展，回答是：
我们的客户希望使用面向对象的Prolog，所以我们就创造了面向对象的Prolog。
我当时的想法是&amp;quot;这么简单粗暴的回答，没有任何良心上的不安，没有灵魂深处的拷问，也没有想过这是不是正确的事情 …&amp;hellip;&amp;rdquo;
面向对象为什么糟糕 对面向对象的主要反对理由可以回归到面向对象的基本理念，在这里我会简述其中一些基本理念以及我对它们的反对意见。
反对1. 数据结构和函数不应该捆绑在一起 对象将数据和函数绑定在了一个不可分割的单元。我认为这是一个根本性的错误，因为函数和数据属于完全不同的两个世界。为什么这么说呢？
函数的作用是处理一些事情。它们有输入和输出。输入和输出是数据，数据可以被函数所改变。在大多数编程语言里，函数由一系列指令所构建：&amp;ldquo;先干这个，之后再干那个……&amp;quot;。为了理解函数，你必须理解这些事情以何种顺序完成。(在支持延迟计算的函数式编程语言中，这个限制并不严格。) 而数据就静静的待在那里。它们什么都不做。它们本身是声明性的。&amp;ldquo;理解&amp;quot;数据远比&amp;quot;理解&amp;quot;函数简单的多。 为了便于理解，函数通常被当作&amp;quot;黑盒&amp;quot;处理，用来把输入转换成输出。如果我理解了输入和输出，那么我就理解了这个函数。但这不意味着我可以写出这个函数。
通常可以认为函数是计算系统的一些&amp;quot;部件&amp;rdquo;，它们的职责是从一种数据结构转换成另一种数据结构。
函数和数据是完全不同的两类&amp;quot;动物&amp;rdquo;，强行把它们锁在同一个&amp;quot;笼子&amp;quot;里，本身就是不正确的。
反对2. 一切事物都必须是一个对象 想想**&amp;ldquo;时间&amp;rdquo;**，在面向对象编程语言中，&amp;ldquo;时间&amp;quot;必须是一个对象。(在Smalltalk中，甚至&amp;quot;3&amp;quot;都是一个对象)。但是在非面向对象的语言中，&amp;ldquo;时间&amp;quot;只是某种数据类型的实例。例如，在Erlang中，存在各种各样的时间表示形式，通过使用类型声明可以清晰明确地进行指定，如：
-deftype day() = 1..31. -deftype month() = 1..12. -deftype year() = int(). -deftype hour() = 1..24. -deftype minute() = 1..60. -deftype second() = 1..60. -deftype abstime() = {abstime,year(),month(),day(),hour(),min(),sec()}. -deftype hms() = {hms,hour(),min(),sec()}. … 注意：上面的定义不属于任意特定的对象。它们是通用的，系统中的任意的函数（译者：这里的函数并不指代已有签名的那些函数，而是对函数的概指）都可以处理以上数据结构所表示的时间。</description></item><item><title>理解Ethereum智能合约开发</title><link>https://kaichaosun.github.io/post/solidity-basics/</link><pubDate>Thu, 11 Apr 2019 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/solidity-basics/</guid><description>[TOC]
背景知识 为什么是分布式账本？ 从第一台计算机的诞生开始，地球的计算能力就一直在按照摩尔定律 (每隔两年计算能力翻倍)所指示的那样，持续地在增长（近年有放缓）。计算早已经不再是一种稀缺的资源，个人计算机的普及乃至泛滥，也说明了这一现象。
另一方面，我们处在飞速发展的信息社会，各种媒介充斥在生活里的方方面面，每个人在互联网上留下的一切痕迹，统称为数据，也是信息社会最有价值的。如果你看过《西部世界》，你就能够明白数据的力量是有多强大和危险。越来越多的人，意识到这一点，并且不希望自己的数据尤其是私密数据被企业或组织控制。
这些企业包含但不局限于支付宝、微信等等独角兽企业。分布式账本技术去除了对中心化的服务或组织的依赖，通过提供计算资源，每一个计算单元或者节点（简单的说就是一台计算机）共同维护着一个数据库或者账本，数据库中的数据可以被所有人读，但只有数据的拥有人才能进行转移或者处理，甚至可以进一步通过密码学对数据加密存储，只有持有秘钥的数据拥有人才能读取和处理数据。
数据的价值在于流动。不论在什么系统中，交易都是极为重要的，但是交易必须是可控和合理的。任何交易的促成都需要建立在一定的共识基础上。比如中心化的服务支付宝，交易成功的标识是支付宝后台数据库完成价值的转移，并返回成功消息给用户，支付宝是整个交易周期的信任基础。种种原因导致我们并不是百分百地信任支付宝。而去中心化的系统不存在这样的信任中心角色，交易的最终确定是由整个系统基于一定的共识算法完成的，这些算法包括但不局限于工作量证明、权益证明、代理权益证明等。
在分布式账本技术中，我们通过移除信任中心，实现了数据自由；通过开源代码，建立了另一个维度的信任关系。这项技术，还处在很早期的阶段，需要通过减缓交易的完成时间来提高安全性；需要通过花费大量的计算资源来达到彻底的去中心化。
到底什么是智能合约？ 日常生活中充满了各种各样的合约机制，比如房屋租赁合约、银行存取款合约、商务合作合约等等，这些合约的目的都只有一个，就是保证合约的参与方正常履行自己的义务。
智能合约的作用也是同样的，只不过合约的形式发生了改变，不再是纸质签名，而是存储在分布式账本中的代码。
为什么要选择智能合约而不是传统合约形式呢？原因我总结大致有以下几个：
去中心化的合约形式，摆脱了对代理人的依赖，解决了对于代理人的信任问题。 分布式账本这个跨越一切国家和地区的技术，使得自由的全球化经济更进一步发展，智能合约能够方便快速地满足多种行业全球化经济的需要。 智能合约以开源代码的形式展示，使得合约更加可信、透明。 新的组织、文化、工作形式，如远程协作办公，开源社团，需要一个更加灵活地协作方式，这里应用智能合约恰到好处。 正是由于代码运行在公共的分布式账本上，满足条件的合约可以随时执行，永不离线。 合约解决了现实生活中的协作问题，智能合约则将协作的广度和深度推向了另一个高度。
以太坊和Solidity 以太坊 **分布式账本和智能合约的结合，创造了一种新的协作方式。**以太坊作为一个公共的分布式账本，提供了一个可复制的虚拟机环境，用来执行智能合约代码，保证了每个节点执行相同的代码和交易请求会得到相同的结果。
当应用程序的功能由智能合约来提供时，也常被认为是去中心化应用 (DAPP)。DApp前端依然是传统的HTML、CSS、JavaScript “三剑客”，通过发送请求到以太坊节点，上传数据到链上，响应链上的事件如智能合约代码的执行结果。对于DApp的后端，从传统中心化的服务器转变为链上可执行的智能合约，通过执行链上的交易请求完成用户账户或者合约账户状态的改变。
越来越多的领域采用DApp的解决方案，例如：
知识产权保护 金融衍生品交易 去中心化的自治组织 Solidity编程语言 所有上面那些复杂的应用场景，都是用Solidity编写的智能合约来完成的。和大多数高级编程语言类似，Solidity支持面向对象的编程范式，有完善的类型系统，是一种静态编程语言，语法和Javascript很类似。你可以通过交互式编程环境熟悉Solidity的基本用法
基础数据类型 基于按值传递的特性，通常也叫以下类型为值类型。
举例 解释 操作 bool true / false !, &amp;amp;&amp;amp;, ||, ==, != int / uint(8~256) 8 默认是256位 比较，位移，算数加减乘除、取模**，位操作 address 0x7fD0030D3D21d17Fb4056DE319faD67A853b3C20 20字节，也即160位二进制码组成，代表以太坊的地址 transfer, call contract contract MyContract {&amp;hellip;} 合约类，是对函数和数据的封装 new bytes(1~32) &amp;ldquo;foo&amp;rdquo; 定长字节数组 bytes &amp;ldquo;bar&amp;rdquo; 变长字节数组 string &amp;ldquo;this is a string&amp;rdquo; UTF-8字符串 枚举类型 例如：</description></item><item><title>Cheatsheet for Shell Programming</title><link>https://kaichaosun.github.io/post/shell-cheatsheet/</link><pubDate>Sat, 30 Mar 2019 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/shell-cheatsheet/</guid><description>Variables NAME=&amp;#34;John&amp;#34; echo $NAME echo &amp;#34;$NAME&amp;#34; echo &amp;#34;${NAME}!&amp;#34; String NAME=&amp;#34;John&amp;#34; echo &amp;#34;Hi $NAME&amp;#34; #=&amp;gt; Hi John echo &amp;#39;Hi $NAME&amp;#39; #=&amp;gt; Hi $NAME Array Fruits=(&amp;#39;Apple&amp;#39; &amp;#39;Banana&amp;#39; &amp;#39;Orange&amp;#39;) Fruits[0]=&amp;#34;Apple&amp;#34; Fruits[1]=&amp;#34;Banana&amp;#34; Fruits[2]=&amp;#34;Orange&amp;#34; And / Or git commit &amp;amp;&amp;amp; git push git commit || echo &amp;#34;Commit failed&amp;#34; Function get_name() { echo &amp;#34;John&amp;#34; } echo &amp;#34;You are $(get_name)&amp;#34; myfunc() { echo &amp;#34;hello $1&amp;#34; } # Same as above (alternate syntax) function myfunc() { echo &amp;#34;hello $1&amp;#34; } myfunc &amp;#34;John&amp;#34; If else if [[ -z ${APP_ENV} ]]; then echo &amp;#34;The APP_ENV should be set to prod or staging, got: $0&amp;#34; exit -1 fi if [[ -z &amp;#34;$string&amp;#34; ]]; then echo &amp;#34;String is empty&amp;#34; elif [[ -n &amp;#34;$string&amp;#34; ]]; then echo &amp;#34;String is not empty&amp;#34; fi Condition [[ -z STRING ]] # Empty string [[ -n STRING ]] # Not empty string [[ STRING == STRING ]] # Equal [[ STRING !</description></item><item><title>The Tutorial of Manjaro Linux Usage</title><link>https://kaichaosun.github.io/post/master_linux_os/</link><pubDate>Sun, 03 Mar 2019 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/master_linux_os/</guid><description>[TOC]
Install Manjaro Linux Burn image to usb stick: Steps:
Download mankato - GNOME here
Check the hash and compare with the hash provided on the site:
shasum ./manjaro-gnome-18.0.2-stable-x86_64.iso Burn the iso file to USB stick on Linux diskutil list sudo umount /dev/disk2s4 sudo dd if=/path/image.iso of=/dev/rdisk2s4 bs=1m On windows, use rufus with dd mode.
Bios set Insert USB stick Restart pc with F2 into bios，set secure boot to be disable，F10 save and exit Press F12 select start using USB.</description></item><item><title>老宅记忆</title><link>https://kaichaosun.github.io/post/laozhai-jiyi/</link><pubDate>Wed, 06 Feb 2019 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/laozhai-jiyi/</guid><description>时间大概是我遇到过最抽象的概念。
到现在，依然没有搞明白时间于我或者我们的意义。通过观察老宅，希望能明白一些。
说故事，还是得从自己说起，因为感受深刻，记忆详实。时间不必清晰，人物也谈不上典型，故事更是最寻常不过的。
老宅是一块记忆的活化石，记忆是我。
大年三十，是家里最热闹的日子，因为是爷爷的生日，外面混的不论好坏，人得到齐。
中午的伙食，来于长辈的辛劳。
吃席从来是足够复杂的一件事情，成年汉子必须喝酒，不会喝，就得练，酒桌文化我想，也算是中国普及最广的文化了，超越了地区贫富高低。一杯酒，喜乐恩仇。极少数的情况下，我会觉得喝酒有乐趣，大概是没有酒量。但是又须和其他人保持步调一致，这是很易理解的，围绕一张桌的是快三十年的相互了解，一致比不一致要容易太多了。
吃完饭，要去上坟祭祖，拿上鞭炮，汤水，就要出发。一路上，废弃的玉米杆铺路，尘土轻扬，心情松畅。到了跟父辈兄弟沟通最深刻话题的时段了，生与湮灭，落叶归根，大题面前，总能窥见人格的变迁。我从来没见过爷爷的爹，也就是老爷爷，因为没见过，才觉得神秘，才有很多的故事流传于耳畔。记忆碎片里有小时候老奶奶在的日子，阳光、板凳和微笑。
一年的结束和开始，在我的内心，永远是初一这两天。大清早就鞭炮雷动，驱年守岁。拜年，最传统的项目，在记忆里占据了大篇幅。小时候喜欢拜年，因为这是一年中唯一光明正大的挣钱机会。亲戚邻里，奶奶叔叔，进门先高喊，喊的声音大，年气儿才够浓，给压岁钱才会痛快。正经说，拜年不是一件光嘴上寒暄的容易事儿，进堂屋，迎正墙，磕头跪地，单腿双膝，诚意可见。磕了头，一定是敬烟吃糖，一顿寒暄，来去几个回合，内容一共没几句，但是一句不该多，更一句不能少。升了学的，到了年龄还没结婚的，刚结了婚有小孩儿的，一定被抓着手多问几句，这个时候一定不能表现出厌烦，过了年，出门在外，漫无目的的关心仿佛也变成了奢侈品。
年节，过的是一个心气儿，拍着记忆中的老宅，给这个年增加了一点新意。
不经意，看到时间流去。谈笑里，新庙老宅骤雨。</description></item><item><title>Dependency Injection in Scala</title><link>https://kaichaosun.github.io/post/dependency_injection_in_scala/</link><pubDate>Thu, 17 Jan 2019 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/dependency_injection_in_scala/</guid><description>What's Dependency Injection Dependency Injection is also known as DI for short. It is all about the way to integrate code between provider and consumer.
Usually, the provider provides functionalities that encapsulated in a function or an object. The consumer, in the opposite it needs to have a provider to do some work.
Then we say that the consumer dependent on the specific provider. There are two options that we can get this provider:</description></item><item><title>Understand Error Handling in Scala</title><link>https://kaichaosun.github.io/post/error_handling_in_scala/</link><pubDate>Thu, 17 Jan 2019 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/error_handling_in_scala/</guid><description>What's Exception Exception are objects that defined in Java to represent error scenarios. Unhandled exceptions could terminate the program or show default message from http server.
Excpetion hirarchy Since Scala is designed to reuse Java standard or thirdparth library without much effort. It still worth to know the exception hirarachy originated in Java. It will help us deal with error scenarios.
Throwable is the root of exception hirarchy. Exception subclasses represent errors that the program can recover from.</description></item><item><title>Cheatsheet for Common Usage CLI</title><link>https://kaichaosun.github.io/post/common-cli-cheatsheet/</link><pubDate>Wed, 02 Jan 2019 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/common-cli-cheatsheet/</guid><description>Curl Post JSON curl -i -d &amp;#39;{&amp;#34;id&amp;#34;: &amp;#34;111111&amp;#34;,&amp;#34;date&amp;#34;: &amp;#34;2018-04-27T00:00:00+10:00&amp;#34;,&amp;#34;des&amp;#34;: &amp;#34;test&amp;#34;}]&amp;#39; -H &amp;#34;Content-Type: application/json&amp;#34; -X POST https://endpoint curl -i -d &amp;#39;{&amp;#34;a&amp;#34;:&amp;#34;1&amp;#34;,&amp;#34;b&amp;#34;:&amp;#34;2&amp;#34;}&amp;#39; -H &amp;#34;Content-Type: application/json&amp;#34; -X POST https://endpoint Database MySQL SHOW VARIABLES; SELECT FROM_UNIXTIME(1510289234); SELECT NOW(); SELECT UNIX_TIMESTAMP(); MongoDB mongod --dbpath ~/data/mongodb PostgreSQL pg_dump --dbname=postgresql://user:admin@127.0.0.1:5432/database-name --table=my-table --data-only --column-inserts &amp;gt; data.sql Zip / tar zip filename.zip file1 file2 tar -czvf name-of-archive.tar.gz /path/to/directory-or-file -c: Create an archive. -z: Compress the archive with gzip. -v: Display progress in the terminal while creating the archive, also known as “verbose” mode.</description></item><item><title>Understand Monad in Functional Programming</title><link>https://kaichaosun.github.io/post/understand-monad/</link><pubDate>Sat, 13 Oct 2018 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/understand-monad/</guid><description>Why Functional Programming? The facination of doing programming is to solve the exist problems. Revisit the history of software development, at first place we have procedure-oriented programming. As the system becomes bigger, the codebase is so hard to maintain and adding new features. Then a few genius comes out the idea with OOP with the SOLID principles to guide the daily dev work.
If there is one rule in software development, i think that must be no silver bullet.</description></item><item><title>Kubernetes basics</title><link>https://kaichaosun.github.io/post/kubernetes-basics/</link><pubDate>Thu, 21 Jun 2018 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/kubernetes-basics/</guid><description>Background &amp;amp; why kubernetes Micro services Usually we build a single &amp;ldquo;monolith&amp;rdquo; application at first time. As the business grows, the app becomes &amp;ldquo;heavy&amp;rdquo; and hard to maintain:
Improved cost to communicate within different teams; Long enough time to finish the CI pipeline(run the test cases, packages, deployment); Hard to scale; &amp;hellip; So we need to make big application to be small different services depends on a few principles, that's micro services.</description></item><item><title>理解Golang并发编程</title><link>https://kaichaosun.github.io/post/go-channel/</link><pubDate>Sat, 29 Jul 2017 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/go-channel/</guid><description>concurrency vs parallelism 并发和并行是彼此相关的两个概念，并不能完全等价。
在程序中，并发强调的是独立执行的程序的组合；并行强调的是同时执行计算任务[1]。
计算机核心的数量决定了并行计算的能力，大多数人类作为“单核”动物(老顽童小龙女除外)，可以说自己在并发某些任务，如我在听歌写代码，但是不能说这两件事在并行，参考下图：
![concurrency vs parallelism](/static/go-channel/currency vs parallelism.png)
Golang的并发模型源于Communicating Sequential Processes (CSP)，通过提供goroutine和channel来实现并发编程模式。
Goroutine Goroutine由Go运行时创建和管理，是用于调度CPU资源的“最小单元”，和OS的线程相比更轻量[2]:
内存消耗更低只需2kB初始栈空间，而线程初始要1Mb的空间； 由golang的运行时环境创建和销毁，更加廉价，不支持手动管理； 切换效率更高等。 Goroutine和线程的关系如下图所示： ![goroutine vs thread](/static/go-channel/goroutine vs thread.png)
我们可以轻松地创建成百上千的goroutine，而不会降低程序的执行效率。
通过goroutine可以让一个函数和其他的函数并行执行。可以在函数调用前面加上go关键字，方便地创建一个goroutine。
main函数本身也是一个goroutine[3]。
举例如下：
package main import &amp;quot;fmt&amp;quot; func main() { fmt.Println(&amp;quot;begin main goroutine&amp;quot;) go hello() fmt.Println(&amp;quot;end main goroutine&amp;quot;) } func hello() { fmt.Println(&amp;quot;begin hello goroutine&amp;quot;) } 输出：
begin main goroutine end main goroutine 上面的例子中，并不会输出begin hello goroutine，这是因为， 通过使用goroutine，我们不需要等待函数调用的返回结果，而会接着执行下面的代码。
可以在go hello()后面添加：
time.Sleep(1 * time.</description></item><item><title>Golang web 开发</title><link>https://kaichaosun.github.io/post/golang-docker-ci/</link><pubDate>Wed, 05 Jul 2017 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/golang-docker-ci/</guid><description>背景 Web应用长期以来是Ruby、Java、PHP等开发语言的战场。
Ruby可以实现快速原型开发，Ruby On Rails “全能”框架实现“全栈”开发，缺点有大型应用性能差、调试困难； Java 20多年的发展历程，各种第三方库、框架健全，运行效率高， 但是随着应用的功能膨胀，臃肿的get/set方法，JVM占用大量计算机资源、性能调试困难，函数式编程不友好。 PHP，TL;DR 本文实现了一个最小化web应用，以此来了解Golang web的生态，通过使用Docker隔离开发环境， 使用Posgres持久化数据，源代码请参考这里
Why Go? 性能优越 部署简单，只需要将打包好的二进制文件部署到服务器上 内置丰富的标准库，让程序员的生活变得简单美好 静态语言，类型检查 duck typing goroutine将开发人员从并发编程中解放出来 函数作为“一等公民” &amp;hellip; Golang第三方框架选择 Web框架: Gin，性能卓越，API友好，功能完善 ORM: GORM,支持多种主流数据库方言，文档清晰 包管理工具: Glide,类似于Ruby的bundler或者NodeJS中的npm 测试工具: GoConvey,符合BDD测试风格,支持浏览器测试结果的可视化 Testify,提供丰富的断言和Mock功能 数据库migration: migrate 日志工具: Logrus,结构化日志输出，完全兼容标准库的logger Dockerize 开发环境 发布应用 base image Dockerfile如下:
FROM golang:1.8 # 包管理工具 RUN curl https://glide.sh/get | sh # 代码热加载 RUN go get github.</description></item><item><title>理解 Javascript 的几种异步模式</title><link>https://kaichaosun.github.io/post/callback-promise/</link><pubDate>Wed, 05 Apr 2017 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/callback-promise/</guid><description>Javacript 提供了基于回调的异步编程模式，如回调函数，Promise对象，Async Function 等。下面是我在学习过程中总结的 一些特性和使用方式。
Javascript 运行时概念 栈(Stack) 和其他语言一样, 栈保存了函数调用的层次关系, 栈中的每一块叫做一帧(frame), 最上层的那一帧, 代表了最内层的函数, 当函数返回时, 清空帧, 当调用栈中所有的帧清空(即最外层函数返回), 当前执行的代码块结束。 JS调用栈有三个特点:
单线程, 浏览器的JS引擎本身是多线程的, 但是JS的调用栈是单线程的, 一次只能执行一段代码; 同步执行, 在栈中的任务依次执行并返回, 不能在任务之间切换 非阻塞, 在线程繁忙时, 浏览器仍然可以接收事件 堆(Heap) 堆中保存了大量的对象,垃圾收集器定期清理未被引用的对象。
事件队列(event queue) 当调用某些Web APIs时,如DOM事件(如鼠标点击操作)、XMLHttpRequest, setTimeout()等, 会添加callback函数到event queue。
Event loop Event loop将event queue中按照&amp;quot;FIFO&amp;quot;的顺序将callback取出,放入栈中,callback函数返回,清空栈, 循环执行上述步骤。
MDN提供的伪代码实现如下:
while(queue.waitForMessage()) { queue.processNextMessage(); } Callback Callback函数 和其他编程语言(Java, Ruby)不同,在JS中,函数也是对象(Function instanceof Object返回为true)。 函数是JS的&amp;quot;一等公民&amp;rdquo;,通俗的理解是,可以将函数作为参数传给另外一个函数,也可以将一个函数作为另一个函数的返回值。
function bar(cb) { setTimeout(cb,2000); } function foo() { console.</description></item><item><title>Hackday是一种怎样的体验？</title><link>https://kaichaosun.github.io/post/hackday/</link><pubDate>Sat, 07 Jan 2017 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/hackday/</guid><description>加入 Thoughtworks 之后，经历了REA (realestate.com.au) 三次 Hackday，感受很多，我觉得有必要和大家分享一下这么优秀的想法和活动。
什么是 hackday？ Hackday，有时也被叫做 Hackathon，是IT行业一个类似于“百米冲刺”的活动，主要目的在于围绕一个主题，进行软件设计和开发，持续时间不等，可以是一天，也可以是一周，以2~3天为多数。活动范围有企业内部、社区等。
REA的 hackday 长什么样？ 在 REA，协作和创新被视为企业的灵魂，每个季度会举办一次hackday，为期三天，除非有相当紧急的线上问题需要处理，一般来说，大部分人都是能够参与其中的。很难想象一个公司所有人三天里都在搞“飞机”，不干“正事”，但是这不也正体现了一个企业的文化、魄力和产品的稳定性吗？ hackday 流程大致是这样的，
团队内部 brain storm，收集 idea； 投票选出意向参与的项目，分配资源； 公司范围的 Stand up，阐述 idea，并找到目标资源（UX，前端Dev，后端Dev，等等） 团队内部 Kick off，划分 story MVP 功能开发（结对编程），一般为 1.5~2天 制作 Showcase 海报 公司范围 Showcase 拉票，投票 根据项目的情况，少数会进入产品，多数会成为工作生活的小助手，解决工作生活中的痛点。 我参与的 hackday 项目 印象比较深刻的是4个:
CI 监控 REA很多CI跑在 Bamboo 和 Buildkite上，每个平台提供的监控数据和展示层不能整合，其中一次hackday，我们就自己动手去整合两个平台的数据，外加一个数据展示的web页面，加上炫酷的动画，完美~ 并且成功的在最近一次hackday前“卖”给了别的team。
Slack robot 监控红了，build 挂了，总得人来修吧，但是这个人呢，太忙，又或者不知道是自己在值班，怎么办呢，我们就让一个robot定时去拉build的状态，一旦红了，去slack上@他，叫醒他，“嘿，哥们，你不修，你好意思吗?”
奔跑吧，会员卡 每当我走进xx超市、xx火锅，结账那一刻，我是拒绝的，尼玛这么点东西，怎么这么贵？现在好了， 我们搞了VIP会员卡共享的公众号，可以注册登记每个人的会员卡，可以供大家查询使用。虽然还有很多功能需要完善，但是我们已经迈出了一大步，对吗？PS: 公众号还在公司内测，一旦公开第一时间跟大家分享。</description></item><item><title>使用 Hexo 搭建个人博客</title><link>https://kaichaosun.github.io/post/hexo/</link><pubDate>Wed, 04 Jan 2017 00:00:00 +0000</pubDate><guid>https://kaichaosun.github.io/post/hexo/</guid><description>Note: 已经使用Hugo创建博客。
Hexo 是一个博客框架,支持Markdown,通过命令行可以快速部署, 有大量的主题和插件,让你的blog飞起来&amp;hellip;
安装 Hexo sudo npm install -g hexo-cli hexo -v 创建 Github blog project 个人习惯将source和deploy分开,在github上创建一个blog项目(保存源文件)和 xxx.github.io项目(用于部署Github个人主页,xxx为用户名,具体参考Github Pages)
hexo init blog cd blog npm install Run server $ hexo s More info: Server
设置博客页个人信息 我的配置文件 _config.yml
# Site title: Whisperd subtitle: description: make a difference author: kaichao language: timezone: Asia/Shanghai # URL ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' url: https://kaichaosun.</description></item></channel></rss>